Skip to content

Commit 62273ec

Browse files
committed
tools update: add --no-reboot and --parallel to speedup the updates
Allow the update command to optionally skip rebooting hosts after package updates (--no-reboot) and to update the master and secondary hosts concurrently (--parallel). Both are disabled by default. It's the responsibility of the user to determine if using them is safe. Signed-off-by: Gaëtan Lehmann <gaetan.lehmann@vates.tech>
1 parent ce2c156 commit 62273ec

2 files changed

Lines changed: 55 additions & 27 deletions

File tree

lib/tools/cli.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def _command_update(args: argparse.Namespace) -> None:
2020
else:
2121
inventory = into_inventory(args.hosts, args.repos, args.hosting_pool, disabled_repositories=args.disablerepos)
2222

23-
update_pools(inventory)
23+
update_pools(inventory, reboot=args.reboot, parallel=args.parallel)
2424

2525

2626
def _command_clean(args: argparse.Namespace) -> None:
@@ -76,6 +76,19 @@ def cli() -> None:
7676
type=HostAddress,
7777
help="Address (hostname|ip) of hosting pool's master host (nested context)",
7878
)
79+
subparser_cmd_update.add_argument(
80+
"--no-reboot",
81+
action="store_false",
82+
dest="reboot",
83+
default=True,
84+
help="Don't reboot after update operation",
85+
)
86+
subparser_cmd_update.add_argument(
87+
"--parallel",
88+
action="store_true",
89+
default=False,
90+
help="Update the master and secondary hosts at the same time",
91+
)
7992
subparser_cmd_update.set_defaults(func=_command_update)
8093

8194
# subparser - command: clean

lib/tools/tasks/update.py

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def _check_consistency(packages: dict[Host, set[str]]) -> None:
6161
lines.append(f" [{h}] additional packages:\n{_format_packages(sorted(extra_pkgs))}")
6262
logger.warning("\n".join(lines))
6363

64-
def update_pools(inventory: Inventory) -> None:
64+
def update_pools(inventory: Inventory, reboot: bool = True, parallel: bool = False) -> None:
6565
"""Updates hosts in pool(s).
6666
6767
.. note::
@@ -72,6 +72,10 @@ def update_pools(inventory: Inventory) -> None:
7272
7373
:param dict inventory:
7474
Each host (key) holds its own config data (values, eg: `enablerepos`).
75+
:param bool reboot:
76+
Choose to reboot or not after update (default: True).
77+
:param bool parallel:
78+
Update the master and secondary hosts at the same time (default: False).
7579
"""
7680
logger.debug(f"Inventory: {inventory}")
7781
inventory_hosts = inventory["hosts"]
@@ -95,44 +99,55 @@ def update_pools(inventory: Inventory) -> None:
9599

96100
# update master hosts
97101
with ThreadPoolExecutor() as executor:
98-
future_masters = {executor.submit(
102+
future_hosts = {executor.submit(
99103
p.master.update,
100104
inventory_hosts[p.master.hostname_or_ip]["repositories"],
101105
disablerepos=inventory_hosts[p.master.hostname_or_ip]["disabled_repositories"],
106+
reboot=reboot,
102107
): p.master for p in pools}
103-
for future in as_completed(future_masters):
104-
future_master = future_masters[future]
108+
if parallel:
109+
# update other hosts at the same time as the master hosts
110+
for p in pools:
111+
# omit first item because it is the pool's master
112+
for h in p.hosts[1:]:
113+
# repos are the same as for the master host
114+
repos = inventory_hosts[p.master.hostname_or_ip]["repositories"]
115+
disablerepos = inventory_hosts[p.master.hostname_or_ip]["disabled_repositories"]
116+
future_hosts[executor.submit(h.update, repos, disablerepos=disablerepos, reboot=reboot)] = h
117+
for future in as_completed(future_hosts):
118+
updated_host = future_hosts[future]
105119
try:
106120
future.result()
107121
except Exception as exc:
108-
logger.error(f"Updating pool has failed! The master {future_master} cannot be updated.")
122+
logger.error(f"Updating pool has failed! The host {updated_host} cannot be updated.")
109123
logger.info(
110124
"*** Due to previous error, the pool updating task will stop. "
111125
"Waiting for running updates to finish if any. ***"
112126
)
113127
raise exc
114128

115-
# update other hosts
116-
with ThreadPoolExecutor() as executor:
117-
future_other_hosts = {}
118-
for p in pools:
119-
# omit first item because it is the pool's master
120-
for h in p.hosts[1:]:
121-
# repos are the same as for the master host
122-
repos = inventory_hosts[p.master.hostname_or_ip]["repositories"]
123-
disablerepos = inventory_hosts[p.master.hostname_or_ip]["disabled_repositories"]
124-
future_other_hosts[executor.submit(h.update, repos, disablerepos=disablerepos)] = h
125-
for future in as_completed(future_other_hosts):
126-
other_host = future_other_hosts[future]
127-
try:
128-
future.result()
129-
except Exception as exc:
130-
logger.error(f"Updating pool has failed! The host {other_host} cannot be updated.")
131-
logger.info(
132-
"*** Due to previous error, the pool updating task will stop. "
133-
"Waiting for running updates to finish if any. ***"
134-
)
135-
raise exc
129+
if not parallel:
130+
# update other hosts
131+
with ThreadPoolExecutor() as executor:
132+
future_other_hosts = {}
133+
for p in pools:
134+
# omit first item because it is the pool's master
135+
for h in p.hosts[1:]:
136+
# repos are the same as for the master host
137+
repos = inventory_hosts[p.master.hostname_or_ip]["repositories"]
138+
disablerepos = inventory_hosts[p.master.hostname_or_ip]["disabled_repositories"]
139+
future_other_hosts[executor.submit(h.update, repos, disablerepos=disablerepos, reboot=reboot)] = h
140+
for future in as_completed(future_other_hosts):
141+
other_host = future_other_hosts[future]
142+
try:
143+
future.result()
144+
except Exception as exc:
145+
logger.error(f"Updating pool has failed! The host {other_host} cannot be updated.")
146+
logger.info(
147+
"*** Due to previous error, the pool updating task will stop. "
148+
"Waiting for running updates to finish if any. ***"
149+
)
150+
raise exc
136151

137152
after_packages = _capture_packages(pools)
138153
_report_updated(before_packages, after_packages)

0 commit comments

Comments
 (0)