Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrbartman committed Apr 17, 2024
1 parent 4dcd3e8 commit 93078d0
Show file tree
Hide file tree
Showing 4 changed files with 231 additions and 97 deletions.
60 changes: 32 additions & 28 deletions vmupdate/agent/source/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,33 @@
class AgentArgs:
# To avoid code repeating when we want to retrieve arguments
OPTIONS = {
"log": {"action": 'store',
"default": "INFO",
"help": 'Provide logging level. Values: DEBUG, INFO (default) '
'WARNING, ERROR, CRITICAL'},
"no-refresh": {"action": 'store_true',
"help": 'Do not refresh available packages before '
'upgrading'},
"force-upgrade": {"action": 'store_true',
"help": 'Try upgrade even if errors are '
'encountered (like a refresh error)'},
"leave-obsolete": {"action": 'store_true',
"help": 'Do not remove obsolete packages during '
'upgrading'},
("--log",): {"action": 'store',
"default": "INFO",
"help": 'Provide logging level. Values: DEBUG, '
'INFO (default), WARNING, ERROR, CRITICAL'},
("--no-refresh",): {"action": 'store_true',
"help": 'Do not refresh available packages before '
'upgrading'},
("--force-upgrade", "-f"):
{"action": 'store_true',
"help": 'Try upgrade even if errors are '
'encountered (like a refresh error)'},
("--leave-obsolete",): {
"action": 'store_true',
"help": 'Do not remove obsolete packages during upgrading'},
}
EXCLUSIVE_OPTIONS_1 = {
"show-output": {"action": 'store_true',
"help": 'Show output of management commands'},
"quiet": {"action": 'store_true',
"help": 'Do not print anything to stdout'}
("--show-output", "--verbose", "-v"):
{"action": 'store_true',
"help": 'Show output of management commands'},
("--quiet", "-q"): {"action": 'store_true',
"help": 'Do not print anything to stdout'}
}
EXCLUSIVE_OPTIONS_2 = {
"no-progress": {"action": "store_true",
"help": "Do not show upgrading progress."},
"just-print-progress": {"action": "store_true",
"help": argparse.SUPPRESS}
("--no-progress",): {"action": "store_true",
"help": "Do not show upgrading progress."},
("--just-print-progress",): {"action": "store_true",
"help": argparse.SUPPRESS}
}
ALL_OPTIONS = {**OPTIONS, **EXCLUSIVE_OPTIONS_1, **EXCLUSIVE_OPTIONS_2}

Expand All @@ -58,13 +60,13 @@ def add_arguments(parser):
Add common arguments to the parser.
"""
for arg, properties in AgentArgs.OPTIONS.items():
parser.add_argument('--' + arg, **properties)
parser.add_argument(*arg, **properties)
verbosity = parser.add_mutually_exclusive_group()
for arg, properties in AgentArgs.EXCLUSIVE_OPTIONS_1.items():
verbosity.add_argument('--' + arg, **properties)
verbosity.add_argument(*arg, **properties)
progress_reporting = parser.add_mutually_exclusive_group()
for arg, properties in AgentArgs.EXCLUSIVE_OPTIONS_2.items():
progress_reporting.add_argument('--' + arg, **properties)
progress_reporting.add_argument(*arg, **properties)

@staticmethod
def to_cli_args(args):
Expand All @@ -75,10 +77,12 @@ def to_cli_args(args):
args_dict = vars(args)

cli_args = []
for key, value in AgentArgs.ALL_OPTIONS.items():
for keys, value in AgentArgs.ALL_OPTIONS.items():
# keys[0] since first value is used as attribute name in parser
param_name = keys[0][2:].replace("-", "_")
if value["action"] == "store_true":
if args_dict[key.replace("-", "_")]:
cli_args.append("--" + key)
if args_dict[param_name]:
cli_args.append(keys[0])
else:
cli_args.extend(("--" + key, args_dict[key.replace("-", "_")]))
cli_args.extend((keys[0], args_dict[param_name]))
return cli_args
8 changes: 8 additions & 0 deletions vmupdate/agent/source/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ class FinalStatus(Enum):
ERROR = "error"
CANCELLED = "cancelled"
NO_UPDATES = "no updates"
UNKNOWN = "unknown"

@classmethod
def __missing__(cls, key):
return cls.UNKNOWN

def __bool__(self):
return self == FinalStatus.SUCCESS


class StatusInfo:
Expand Down
21 changes: 17 additions & 4 deletions vmupdate/update_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class UpdateManager:
Update multiple qubes simultaneously.
"""

def __init__(self, qubes, args):
def __init__(self, qubes, args, log):
self.qubes = qubes
self.max_concurrency = args.max_concurrency
self.show_output = args.show_output
Expand All @@ -56,13 +56,16 @@ def __init__(self, qubes, args):
self.buffer = ""
self.cleanup = not args.no_cleanup
self.ret_code = 0
self.log = log

def run(self, agent_args):
"""
Run simultaneously `update_qube` for all qubes as separate processes.
"""
self.log.info("Update Manager: New batch of qubes to update")
if not self.qubes:
return 0
self.log.info("Update Manager: No qubes to update, quiting.")
return 0, {q.name: FinalStatus.SUCCESS for q in self.qubes}

show_progress = not self.quiet and not self.no_progress
SimpleTerminalBar.reinit_class()
Expand All @@ -88,10 +91,18 @@ def run(self, agent_args):
progress_bar.feeding()
progress_bar.pool.join()
progress_bar.close()
self.log.info("Update Manager: Finished, collecting success info")

stats = [stat for stat in progress_bar.statuses.values()]
if any(stats) == FinalStatus.ERROR:
self.ret_code = max(self.ret_code, 5)
if any(stats) == FinalStatus.UNKNOWN:
self.ret_code = max(self.ret_code, 6)

if self.buffer:
print(self.buffer)

return self.ret_code
return self.ret_code, progress_bar.statuses

def collect_result(self, result_tuple: Tuple[str, ProcessResult]):
"""
Expand Down Expand Up @@ -182,11 +193,12 @@ def __init__(self, dummy, output, max_concurrency, printer: Optional):
# in pool
signal.signal(signal.SIGINT, signal.SIG_IGN)
self.pool = multiprocessing.Pool(max_concurrency)
# set SIGINT handler to gracefully termination
# set SIGINT handler to graceful termination
signal.signal(signal.SIGINT, self.signal_handler_during_feeding)

self.progresses = {}
self.progress_bars = {}
self.statuses = {}
self.output_class = output
self.print = printer

Expand Down Expand Up @@ -224,6 +236,7 @@ def feeding(self):
if feed.status == Status.DONE:
left_to_finish -= 1
status_name = feed.info.value
self.statuses[feed.qname] = FinalStatus(status_name)
self.progress_bars[feed.qname].set_description(
f"{feed.qname} ({status_name})")
if feed.status == Status.UPDATING:
Expand Down
Loading

0 comments on commit 93078d0

Please sign in to comment.