mirror of
				https://github.com/arcan1s/ahriman.git
				synced 2025-10-31 05:43: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) | ||||
|  | ||||
|     _set_aur_search_parser(subparsers) | ||||
|     _set_daemon_parser(subparsers) | ||||
|     _set_help_parser(subparsers) | ||||
|     _set_help_commands_unsafe_parser(subparsers) | ||||
|     _set_key_import_parser(subparsers) | ||||
| @ -141,6 +142,28 @@ def _set_aur_search_parser(root: SubParserAction) -> argparse.ArgumentParser: | ||||
|     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: | ||||
|     """ | ||||
|     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.backup import Backup | ||||
| 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.help import Help | ||||
| 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 == [""] | ||||
|  | ||||
|  | ||||
| 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: | ||||
|     """ | ||||
|     help command must imply architecture list, lock, no-report, quiet, unsafe and parser | ||||
|  | ||||
		Reference in New Issue
	
	Block a user