mirror of
				https://github.com/arcan1s/ahriman.git
				synced 2025-10-31 13:53:41 +00:00 
			
		
		
		
	add daemon subcommand
This command emulates default systemd timer and can be useful in docker container in order to run 24/7
This commit is contained in:
		| @ -82,6 +82,7 @@ def _parser() -> argparse.ArgumentParser: | |||||||
|     subparsers = parser.add_subparsers(title="command", help="command to run", dest="command", required=True) |     subparsers = parser.add_subparsers(title="command", help="command to run", dest="command", required=True) | ||||||
|  |  | ||||||
|     _set_aur_search_parser(subparsers) |     _set_aur_search_parser(subparsers) | ||||||
|  |     _set_daemon_parser(subparsers) | ||||||
|     _set_help_parser(subparsers) |     _set_help_parser(subparsers) | ||||||
|     _set_help_commands_unsafe_parser(subparsers) |     _set_help_commands_unsafe_parser(subparsers) | ||||||
|     _set_key_import_parser(subparsers) |     _set_key_import_parser(subparsers) | ||||||
| @ -141,6 +142,28 @@ def _set_aur_search_parser(root: SubParserAction) -> argparse.ArgumentParser: | |||||||
|     return parser |     return parser | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def _set_daemon_parser(root: SubParserAction) -> argparse.ArgumentParser: | ||||||
|  |     """ | ||||||
|  |     add parser for daemon subcommand | ||||||
|  |  | ||||||
|  |     Args: | ||||||
|  |         root(SubParserAction): subparsers for the commands | ||||||
|  |  | ||||||
|  |     Returns: | ||||||
|  |         argparse.ArgumentParser: created argument parser | ||||||
|  |     """ | ||||||
|  |     parser = root.add_parser("daemon", help="run application as daemon", | ||||||
|  |                              description="start process which periodically will run update process", | ||||||
|  |                              formatter_class=_formatter) | ||||||
|  |     parser.add_argument("-i", "--interval", help="interval between runs in seconds", type=int, default=60 * 60 * 12) | ||||||
|  |     parser.add_argument("--no-aur", help="do not check for AUR updates. Implies --no-vcs", action="store_true") | ||||||
|  |     parser.add_argument("--no-local", help="do not check local packages for updates", action="store_true") | ||||||
|  |     parser.add_argument("--no-manual", help="do not include manual updates", action="store_true") | ||||||
|  |     parser.add_argument("--no-vcs", help="do not check VCS packages", action="store_true") | ||||||
|  |     parser.set_defaults(handler=handlers.Daemon, dry_run=False, exit_code=False, package=[]) | ||||||
|  |     return parser | ||||||
|  |  | ||||||
|  |  | ||||||
| def _set_help_parser(root: SubParserAction) -> argparse.ArgumentParser: | def _set_help_parser(root: SubParserAction) -> argparse.ArgumentParser: | ||||||
|     """ |     """ | ||||||
|     add parser for listing help subcommand |     add parser for listing help subcommand | ||||||
|  | |||||||
| @ -22,6 +22,7 @@ from ahriman.application.handlers.handler import Handler | |||||||
| from ahriman.application.handlers.add import Add | from ahriman.application.handlers.add import Add | ||||||
| from ahriman.application.handlers.backup import Backup | from ahriman.application.handlers.backup import Backup | ||||||
| from ahriman.application.handlers.clean import Clean | from ahriman.application.handlers.clean import Clean | ||||||
|  | from ahriman.application.handlers.daemon import Daemon | ||||||
| from ahriman.application.handlers.dump import Dump | from ahriman.application.handlers.dump import Dump | ||||||
| from ahriman.application.handlers.help import Help | from ahriman.application.handlers.help import Help | ||||||
| from ahriman.application.handlers.key_import import KeyImport | from ahriman.application.handlers.key_import import KeyImport | ||||||
|  | |||||||
							
								
								
									
										51
									
								
								src/ahriman/application/handlers/daemon.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/ahriman/application/handlers/daemon.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | |||||||
|  | # | ||||||
|  | # Copyright (c) 2021-2022 ahriman team. | ||||||
|  | # | ||||||
|  | # This file is part of ahriman | ||||||
|  | # (see https://github.com/arcan1s/ahriman). | ||||||
|  | # | ||||||
|  | # This program is free software: you can redistribute it and/or modify | ||||||
|  | # it under the terms of the GNU General Public License as published by | ||||||
|  | # the Free Software Foundation, either version 3 of the License, or | ||||||
|  | # (at your option) any later version. | ||||||
|  | # | ||||||
|  | # This program is distributed in the hope that it will be useful, | ||||||
|  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | # GNU General Public License for more details. | ||||||
|  | # | ||||||
|  | # You should have received a copy of the GNU General Public License | ||||||
|  | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | # | ||||||
|  | import argparse | ||||||
|  | import threading | ||||||
|  |  | ||||||
|  | from typing import Type | ||||||
|  |  | ||||||
|  | from ahriman.application.handlers import Handler | ||||||
|  | from ahriman.core.configuration import Configuration | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class Daemon(Handler): | ||||||
|  |     """ | ||||||
|  |     daemon packages handler | ||||||
|  |     """ | ||||||
|  |  | ||||||
|  |     @classmethod | ||||||
|  |     def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, | ||||||
|  |             configuration: Configuration, no_report: bool, unsafe: bool) -> None: | ||||||
|  |         """ | ||||||
|  |         callback for command line | ||||||
|  |  | ||||||
|  |         Args: | ||||||
|  |             args(argparse.Namespace): command line args | ||||||
|  |             architecture(str): repository architecture | ||||||
|  |             configuration(Configuration): configuration instance | ||||||
|  |             no_report(bool): force disable reporting | ||||||
|  |             unsafe(bool): if set no user check will be performed before path creation | ||||||
|  |         """ | ||||||
|  |         from ahriman.application.handlers import Update | ||||||
|  |         Update.run(args, architecture, configuration, no_report, unsafe) | ||||||
|  |         timer = threading.Timer(args.interval, Daemon.run, (args, architecture, configuration, no_report, unsafe)) | ||||||
|  |         timer.start() | ||||||
|  |         timer.join() | ||||||
							
								
								
									
										40
									
								
								tests/ahriman/application/handlers/test_handler_daemon.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								tests/ahriman/application/handlers/test_handler_daemon.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | |||||||
|  | import argparse | ||||||
|  |  | ||||||
|  | from pytest_mock import MockerFixture | ||||||
|  |  | ||||||
|  | from ahriman.application.handlers import Daemon | ||||||
|  | from ahriman.core.configuration import Configuration | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def _default_args(args: argparse.Namespace) -> argparse.Namespace: | ||||||
|  |     """ | ||||||
|  |     default arguments for these test cases | ||||||
|  |  | ||||||
|  |     Args: | ||||||
|  |         args(argparse.Namespace): command line arguments fixture | ||||||
|  |  | ||||||
|  |     Returns: | ||||||
|  |         argparse.Namespace: generated arguments for these test cases | ||||||
|  |     """ | ||||||
|  |     args.interval = 60 * 60 * 12 | ||||||
|  |     args.no_aur = False | ||||||
|  |     args.no_local = False | ||||||
|  |     args.no_manual = False | ||||||
|  |     args.no_vcs = False | ||||||
|  |     return args | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: | ||||||
|  |     """ | ||||||
|  |     must run command | ||||||
|  |     """ | ||||||
|  |     args = _default_args(args) | ||||||
|  |     run_mock = mocker.patch("ahriman.application.handlers.Update.run") | ||||||
|  |     start_mock = mocker.patch("threading.Timer.start") | ||||||
|  |     join_mock = mocker.patch("threading.Timer.join") | ||||||
|  |  | ||||||
|  |     Daemon.run(args, "x86_64", configuration, True, False) | ||||||
|  |     Daemon._SHOULD_RUN = False | ||||||
|  |     run_mock.assert_called_once_with(args, "x86_64", configuration, True, False) | ||||||
|  |     start_mock.assert_called_once_with() | ||||||
|  |     join_mock.assert_called_once_with() | ||||||
| @ -65,6 +65,26 @@ def test_subparsers_aur_search_architecture(parser: argparse.ArgumentParser) -> | |||||||
|     assert args.architecture == [""] |     assert args.architecture == [""] | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def test_subparsers_daemon(parser: argparse.ArgumentParser) -> None: | ||||||
|  |     """ | ||||||
|  |     daemon command must imply dry run, exit code and package | ||||||
|  |     """ | ||||||
|  |     args = parser.parse_args(["daemon"]) | ||||||
|  |     assert not args.dry_run | ||||||
|  |     assert not args.exit_code | ||||||
|  |     assert args.package == [] | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def test_subparsers_daemon_option_interval(parser: argparse.ArgumentParser) -> None: | ||||||
|  |     """ | ||||||
|  |     daemon command must convert interval option to int instance | ||||||
|  |     """ | ||||||
|  |     args = parser.parse_args(["daemon"]) | ||||||
|  |     assert isinstance(args.interval, int) | ||||||
|  |     args = parser.parse_args(["daemon", "--interval", "10"]) | ||||||
|  |     assert isinstance(args.interval, int) | ||||||
|  |  | ||||||
|  |  | ||||||
| def test_subparsers_help(parser: argparse.ArgumentParser) -> None: | def test_subparsers_help(parser: argparse.ArgumentParser) -> None: | ||||||
|     """ |     """ | ||||||
|     help command must imply architecture list, lock, no-report, quiet, unsafe and parser |     help command must imply architecture list, lock, no-report, quiet, unsafe and parser | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user