mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-04-30 02:07:18 +00:00
Compare commits
2 Commits
a8c40a6b87
...
ec0550a275
Author | SHA1 | Date | |
---|---|---|---|
ec0550a275 | |||
df23be9269 |
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 678 KiB After Width: | Height: | Size: 660 KiB |
@ -1,4 +1,4 @@
|
|||||||
.TH AHRIMAN "1" "2023\-02\-20" "ahriman" "Generated Python Manual"
|
.TH AHRIMAN "1" "2023\-03\-06" "ahriman" "Generated Python Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
ahriman
|
ahriman
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Maintainer: Evgeniy Alekseev
|
# Maintainer: Evgeniy Alekseev
|
||||||
|
|
||||||
pkgname='ahriman'
|
pkgname='ahriman'
|
||||||
pkgver=2.7.0
|
pkgver=2.7.1
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="ArcH linux ReposItory MANager"
|
pkgdesc="ArcH linux ReposItory MANager"
|
||||||
arch=('any')
|
arch=('any')
|
||||||
|
@ -55,3 +55,7 @@ class Web(Handler):
|
|||||||
|
|
||||||
application = setup_service(architecture, configuration, spawner)
|
application = setup_service(architecture, configuration, spawner)
|
||||||
run_server(application)
|
run_server(application)
|
||||||
|
|
||||||
|
# terminate spawn process at the last
|
||||||
|
spawner.stop()
|
||||||
|
spawner.join()
|
||||||
|
@ -60,7 +60,7 @@ class Spawn(Thread, LazyLogging):
|
|||||||
self.lock = Lock()
|
self.lock = Lock()
|
||||||
self.active: Dict[str, Process] = {}
|
self.active: Dict[str, Process] = {}
|
||||||
# stupid pylint does not know that it is possible
|
# stupid pylint does not know that it is possible
|
||||||
self.queue: Queue[Tuple[str, bool]] = Queue() # pylint: disable=unsubscriptable-object
|
self.queue: Queue[Tuple[str, bool] | None] = Queue() # pylint: disable=unsubscriptable-object
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def process(callback: Callable[[argparse.Namespace, str], bool], args: argparse.Namespace, architecture: str,
|
def process(callback: Callable[[argparse.Namespace, str], bool], args: argparse.Namespace, architecture: str,
|
||||||
@ -78,55 +78,7 @@ class Spawn(Thread, LazyLogging):
|
|||||||
result = callback(args, architecture)
|
result = callback(args, architecture)
|
||||||
queue.put((process_id, result))
|
queue.put((process_id, result))
|
||||||
|
|
||||||
def key_import(self, key: str, server: Optional[str]) -> None:
|
def _spawn_process(self, command: str, *args: str, **kwargs: str) -> None:
|
||||||
"""
|
|
||||||
import key to service cache
|
|
||||||
|
|
||||||
Args:
|
|
||||||
key(str): key to import
|
|
||||||
server(str): PGP key server
|
|
||||||
"""
|
|
||||||
kwargs = {} if server is None else {"key-server": server}
|
|
||||||
self.spawn_process("service-key-import", key, **kwargs)
|
|
||||||
|
|
||||||
def packages_add(self, packages: Iterable[str], *, now: bool) -> None:
|
|
||||||
"""
|
|
||||||
add packages
|
|
||||||
|
|
||||||
Args:
|
|
||||||
packages(Iterable[str]): packages list to add
|
|
||||||
now(bool): build packages now
|
|
||||||
"""
|
|
||||||
kwargs = {"source": PackageSource.AUR.value} # avoid abusing by building non-aur packages
|
|
||||||
if now:
|
|
||||||
kwargs["now"] = ""
|
|
||||||
self.spawn_process("package-add", *packages, **kwargs)
|
|
||||||
|
|
||||||
def packages_rebuild(self, depends_on: str) -> None:
|
|
||||||
"""
|
|
||||||
rebuild packages which depend on the specified package
|
|
||||||
|
|
||||||
Args:
|
|
||||||
depends_on(str): packages dependency
|
|
||||||
"""
|
|
||||||
self.spawn_process("repo-rebuild", **{"depends-on": depends_on})
|
|
||||||
|
|
||||||
def packages_remove(self, packages: Iterable[str]) -> None:
|
|
||||||
"""
|
|
||||||
remove packages
|
|
||||||
|
|
||||||
Args:
|
|
||||||
packages(Iterable[str]): packages list to remove
|
|
||||||
"""
|
|
||||||
self.spawn_process("package-remove", *packages)
|
|
||||||
|
|
||||||
def packages_update(self, ) -> None:
|
|
||||||
"""
|
|
||||||
run full repository update
|
|
||||||
"""
|
|
||||||
self.spawn_process("repo-update")
|
|
||||||
|
|
||||||
def spawn_process(self, command: str, *args: str, **kwargs: str) -> None:
|
|
||||||
"""
|
"""
|
||||||
spawn external ahriman process with supplied arguments
|
spawn external ahriman process with supplied arguments
|
||||||
|
|
||||||
@ -161,6 +113,54 @@ class Spawn(Thread, LazyLogging):
|
|||||||
with self.lock:
|
with self.lock:
|
||||||
self.active[process_id] = process
|
self.active[process_id] = process
|
||||||
|
|
||||||
|
def key_import(self, key: str, server: Optional[str]) -> None:
|
||||||
|
"""
|
||||||
|
import key to service cache
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key(str): key to import
|
||||||
|
server(str): PGP key server
|
||||||
|
"""
|
||||||
|
kwargs = {} if server is None else {"key-server": server}
|
||||||
|
self._spawn_process("service-key-import", key, **kwargs)
|
||||||
|
|
||||||
|
def packages_add(self, packages: Iterable[str], *, now: bool) -> None:
|
||||||
|
"""
|
||||||
|
add packages
|
||||||
|
|
||||||
|
Args:
|
||||||
|
packages(Iterable[str]): packages list to add
|
||||||
|
now(bool): build packages now
|
||||||
|
"""
|
||||||
|
kwargs = {"source": PackageSource.AUR.value} # avoid abusing by building non-aur packages
|
||||||
|
if now:
|
||||||
|
kwargs["now"] = ""
|
||||||
|
self._spawn_process("package-add", *packages, **kwargs)
|
||||||
|
|
||||||
|
def packages_rebuild(self, depends_on: str) -> None:
|
||||||
|
"""
|
||||||
|
rebuild packages which depend on the specified package
|
||||||
|
|
||||||
|
Args:
|
||||||
|
depends_on(str): packages dependency
|
||||||
|
"""
|
||||||
|
self._spawn_process("repo-rebuild", **{"depends-on": depends_on})
|
||||||
|
|
||||||
|
def packages_remove(self, packages: Iterable[str]) -> None:
|
||||||
|
"""
|
||||||
|
remove packages
|
||||||
|
|
||||||
|
Args:
|
||||||
|
packages(Iterable[str]): packages list to remove
|
||||||
|
"""
|
||||||
|
self._spawn_process("package-remove", *packages)
|
||||||
|
|
||||||
|
def packages_update(self, ) -> None:
|
||||||
|
"""
|
||||||
|
run full repository update
|
||||||
|
"""
|
||||||
|
self._spawn_process("repo-update")
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
"""
|
"""
|
||||||
thread run method
|
thread run method
|
||||||
@ -174,3 +174,9 @@ class Spawn(Thread, LazyLogging):
|
|||||||
if process is not None:
|
if process is not None:
|
||||||
process.terminate() # make sure lol
|
process.terminate() # make sure lol
|
||||||
process.join()
|
process.join()
|
||||||
|
|
||||||
|
def stop(self) -> None:
|
||||||
|
"""
|
||||||
|
gracefully terminate thread
|
||||||
|
"""
|
||||||
|
self.queue.put(None)
|
||||||
|
@ -17,4 +17,4 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
__version__ = "2.7.0"
|
__version__ = "2.7.1"
|
||||||
|
@ -115,7 +115,7 @@ def run_server(application: web.Application) -> None:
|
|||||||
port = configuration.getint("web", "port")
|
port = configuration.getint("web", "port")
|
||||||
unix_socket = create_socket(configuration, application)
|
unix_socket = create_socket(configuration, application)
|
||||||
|
|
||||||
web.run_app(application, host=host, port=port, sock=unix_socket, handle_signals=False,
|
web.run_app(application, host=host, port=port, sock=unix_socket, handle_signals=True,
|
||||||
access_log=logging.getLogger("http"), access_log_class=FilteredAccessLogger)
|
access_log=logging.getLogger("http"), access_log_class=FilteredAccessLogger)
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,14 +28,19 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
|||||||
must run command
|
must run command
|
||||||
"""
|
"""
|
||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
mocker.patch("ahriman.core.spawn.Spawn.start")
|
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
setup_mock = mocker.patch("ahriman.web.web.setup_service")
|
setup_mock = mocker.patch("ahriman.web.web.setup_service")
|
||||||
run_mock = mocker.patch("ahriman.web.web.run_server")
|
run_mock = mocker.patch("ahriman.web.web.run_server")
|
||||||
|
start_mock = mocker.patch("ahriman.core.spawn.Spawn.start")
|
||||||
|
stop_mock = mocker.patch("ahriman.core.spawn.Spawn.stop")
|
||||||
|
join_mock = mocker.patch("ahriman.core.spawn.Spawn.join")
|
||||||
|
|
||||||
Web.run(args, "x86_64", configuration, report=False, unsafe=False)
|
Web.run(args, "x86_64", configuration, report=False, unsafe=False)
|
||||||
setup_mock.assert_called_once_with("x86_64", configuration, pytest.helpers.anyvar(int))
|
setup_mock.assert_called_once_with("x86_64", configuration, pytest.helpers.anyvar(int))
|
||||||
run_mock.assert_called_once_with(pytest.helpers.anyvar(int))
|
run_mock.assert_called_once_with(pytest.helpers.anyvar(int))
|
||||||
|
start_mock.assert_called_once_with()
|
||||||
|
stop_mock.assert_called_once_with()
|
||||||
|
join_mock.assert_called_once_with()
|
||||||
|
|
||||||
|
|
||||||
def test_disallow_auto_architecture_run() -> None:
|
def test_disallow_auto_architecture_run() -> None:
|
||||||
|
@ -36,11 +36,25 @@ def test_process_error(spawner: Spawn) -> None:
|
|||||||
assert spawner.queue.empty()
|
assert spawner.queue.empty()
|
||||||
|
|
||||||
|
|
||||||
|
def test_spawn_process(spawner: Spawn, mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must correctly spawn child process
|
||||||
|
"""
|
||||||
|
start_mock = mocker.patch("multiprocessing.Process.start")
|
||||||
|
|
||||||
|
spawner._spawn_process("add", "ahriman", now="", maybe="?")
|
||||||
|
start_mock.assert_called_once_with()
|
||||||
|
spawner.args_parser.parse_args.assert_called_once_with([
|
||||||
|
"--architecture", spawner.architecture, "--configuration", str(spawner.configuration.path),
|
||||||
|
"add", "ahriman", "--now", "--maybe", "?"
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
def test_key_import(spawner: Spawn, mocker: MockerFixture) -> None:
|
def test_key_import(spawner: Spawn, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must call key import
|
must call key import
|
||||||
"""
|
"""
|
||||||
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn.spawn_process")
|
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn._spawn_process")
|
||||||
spawner.key_import("0xdeadbeaf", None)
|
spawner.key_import("0xdeadbeaf", None)
|
||||||
spawn_mock.assert_called_once_with("service-key-import", "0xdeadbeaf")
|
spawn_mock.assert_called_once_with("service-key-import", "0xdeadbeaf")
|
||||||
|
|
||||||
@ -49,7 +63,7 @@ def test_key_import_with_server(spawner: Spawn, mocker: MockerFixture) -> None:
|
|||||||
"""
|
"""
|
||||||
must call key import with server specified
|
must call key import with server specified
|
||||||
"""
|
"""
|
||||||
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn.spawn_process")
|
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn._spawn_process")
|
||||||
spawner.key_import("0xdeadbeaf", "keyserver.ubuntu.com")
|
spawner.key_import("0xdeadbeaf", "keyserver.ubuntu.com")
|
||||||
spawn_mock.assert_called_once_with("service-key-import", "0xdeadbeaf", **{"key-server": "keyserver.ubuntu.com"})
|
spawn_mock.assert_called_once_with("service-key-import", "0xdeadbeaf", **{"key-server": "keyserver.ubuntu.com"})
|
||||||
|
|
||||||
@ -58,7 +72,7 @@ def test_packages_add(spawner: Spawn, mocker: MockerFixture) -> None:
|
|||||||
"""
|
"""
|
||||||
must call package addition
|
must call package addition
|
||||||
"""
|
"""
|
||||||
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn.spawn_process")
|
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn._spawn_process")
|
||||||
spawner.packages_add(["ahriman", "linux"], now=False)
|
spawner.packages_add(["ahriman", "linux"], now=False)
|
||||||
spawn_mock.assert_called_once_with("package-add", "ahriman", "linux", source="aur")
|
spawn_mock.assert_called_once_with("package-add", "ahriman", "linux", source="aur")
|
||||||
|
|
||||||
@ -67,7 +81,7 @@ def test_packages_add_with_build(spawner: Spawn, mocker: MockerFixture) -> None:
|
|||||||
"""
|
"""
|
||||||
must call package addition with update
|
must call package addition with update
|
||||||
"""
|
"""
|
||||||
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn.spawn_process")
|
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn._spawn_process")
|
||||||
spawner.packages_add(["ahriman", "linux"], now=True)
|
spawner.packages_add(["ahriman", "linux"], now=True)
|
||||||
spawn_mock.assert_called_once_with("package-add", "ahriman", "linux", source="aur", now="")
|
spawn_mock.assert_called_once_with("package-add", "ahriman", "linux", source="aur", now="")
|
||||||
|
|
||||||
@ -76,7 +90,7 @@ def test_packages_rebuild(spawner: Spawn, mocker: MockerFixture) -> None:
|
|||||||
"""
|
"""
|
||||||
must call package rebuild
|
must call package rebuild
|
||||||
"""
|
"""
|
||||||
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn.spawn_process")
|
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn._spawn_process")
|
||||||
spawner.packages_rebuild("python")
|
spawner.packages_rebuild("python")
|
||||||
spawn_mock.assert_called_once_with("repo-rebuild", **{"depends-on": "python"})
|
spawn_mock.assert_called_once_with("repo-rebuild", **{"depends-on": "python"})
|
||||||
|
|
||||||
@ -85,7 +99,7 @@ def test_packages_remove(spawner: Spawn, mocker: MockerFixture) -> None:
|
|||||||
"""
|
"""
|
||||||
must call package removal
|
must call package removal
|
||||||
"""
|
"""
|
||||||
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn.spawn_process")
|
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn._spawn_process")
|
||||||
spawner.packages_remove(["ahriman", "linux"])
|
spawner.packages_remove(["ahriman", "linux"])
|
||||||
spawn_mock.assert_called_once_with("package-remove", "ahriman", "linux")
|
spawn_mock.assert_called_once_with("package-remove", "ahriman", "linux")
|
||||||
|
|
||||||
@ -94,25 +108,11 @@ def test_packages_update(spawner: Spawn, mocker: MockerFixture) -> None:
|
|||||||
"""
|
"""
|
||||||
must call repo update
|
must call repo update
|
||||||
"""
|
"""
|
||||||
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn.spawn_process")
|
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn._spawn_process")
|
||||||
spawner.packages_update()
|
spawner.packages_update()
|
||||||
spawn_mock.assert_called_once_with("repo-update")
|
spawn_mock.assert_called_once_with("repo-update")
|
||||||
|
|
||||||
|
|
||||||
def test_spawn_process(spawner: Spawn, mocker: MockerFixture) -> None:
|
|
||||||
"""
|
|
||||||
must correctly spawn child process
|
|
||||||
"""
|
|
||||||
start_mock = mocker.patch("multiprocessing.Process.start")
|
|
||||||
|
|
||||||
spawner.spawn_process("add", "ahriman", now="", maybe="?")
|
|
||||||
start_mock.assert_called_once_with()
|
|
||||||
spawner.args_parser.parse_args.assert_called_once_with([
|
|
||||||
"--architecture", spawner.architecture, "--configuration", str(spawner.configuration.path),
|
|
||||||
"add", "ahriman", "--now", "--maybe", "?"
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
def test_run(spawner: Spawn, mocker: MockerFixture) -> None:
|
def test_run(spawner: Spawn, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must implement run method
|
must implement run method
|
||||||
@ -145,3 +145,14 @@ def test_run_pop(spawner: Spawn) -> None:
|
|||||||
second.terminate.assert_called_once_with()
|
second.terminate.assert_called_once_with()
|
||||||
second.join.assert_called_once_with()
|
second.join.assert_called_once_with()
|
||||||
assert not spawner.active
|
assert not spawner.active
|
||||||
|
|
||||||
|
|
||||||
|
def test_stop(spawner: Spawn) -> None:
|
||||||
|
"""
|
||||||
|
must gracefully terminate thread
|
||||||
|
"""
|
||||||
|
spawner.start()
|
||||||
|
spawner.stop()
|
||||||
|
spawner.join()
|
||||||
|
|
||||||
|
assert not spawner.is_alive()
|
||||||
|
@ -100,7 +100,7 @@ def test_run(application: web.Application, mocker: MockerFixture) -> None:
|
|||||||
|
|
||||||
run_server(application)
|
run_server(application)
|
||||||
run_application_mock.assert_called_once_with(
|
run_application_mock.assert_called_once_with(
|
||||||
application, host="127.0.0.1", port=port, sock=None, handle_signals=False,
|
application, host="127.0.0.1", port=port, sock=None, handle_signals=True,
|
||||||
access_log=pytest.helpers.anyvar(int), access_log_class=FilteredAccessLogger
|
access_log=pytest.helpers.anyvar(int), access_log_class=FilteredAccessLogger
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ def test_run_with_auth(application_with_auth: web.Application, mocker: MockerFix
|
|||||||
|
|
||||||
run_server(application_with_auth)
|
run_server(application_with_auth)
|
||||||
run_application_mock.assert_called_once_with(
|
run_application_mock.assert_called_once_with(
|
||||||
application_with_auth, host="127.0.0.1", port=port, sock=None, handle_signals=False,
|
application_with_auth, host="127.0.0.1", port=port, sock=None, handle_signals=True,
|
||||||
access_log=pytest.helpers.anyvar(int), access_log_class=FilteredAccessLogger
|
access_log=pytest.helpers.anyvar(int), access_log_class=FilteredAccessLogger
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ def test_run_with_debug(application_with_debug: web.Application, mocker: MockerF
|
|||||||
|
|
||||||
run_server(application_with_debug)
|
run_server(application_with_debug)
|
||||||
run_application_mock.assert_called_once_with(
|
run_application_mock.assert_called_once_with(
|
||||||
application_with_debug, host="127.0.0.1", port=port, sock=None, handle_signals=False,
|
application_with_debug, host="127.0.0.1", port=port, sock=None, handle_signals=True,
|
||||||
access_log=pytest.helpers.anyvar(int), access_log_class=FilteredAccessLogger
|
access_log=pytest.helpers.anyvar(int), access_log_class=FilteredAccessLogger
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -147,6 +147,6 @@ def test_run_with_socket(application: web.Application, mocker: MockerFixture) ->
|
|||||||
run_server(application)
|
run_server(application)
|
||||||
socket_mock.assert_called_once_with(application["configuration"], application)
|
socket_mock.assert_called_once_with(application["configuration"], application)
|
||||||
run_application_mock.assert_called_once_with(
|
run_application_mock.assert_called_once_with(
|
||||||
application, host="127.0.0.1", port=port, sock=42, handle_signals=False,
|
application, host="127.0.0.1", port=port, sock=42, handle_signals=True,
|
||||||
access_log=pytest.helpers.anyvar(int), access_log_class=FilteredAccessLogger
|
access_log=pytest.helpers.anyvar(int), access_log_class=FilteredAccessLogger
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user