Restart services selectively during auto-update

This commit is contained in:
Wojciech Kozlowski 2023-11-11 15:55:15 +01:00
parent d59d7dc176
commit edceb1bd0b

View File

@ -4,13 +4,12 @@
pull` may not necessarily pull the image for quite some time. However, `auto-update` will still try pull` may not necessarily pull the image for quite some time. However, `auto-update` will still try
every day, but since it doesn't check if the new digest has actually been pulled it will restart the every day, but since it doesn't check if the new digest has actually been pulled it will restart the
service again and again. This script attempts to solve the problem by explicitly checking the digest service again and again. This script attempts to solve the problem by explicitly checking the digest
after the pull. However, it assumes that there is only service that needs restarting on updates and after the pull.
that its called <username>.service so it is not (yet) a drop-in replacement for `podman
auto-update`.
""" """
import getpass import collections
import functools
import json import json
import subprocess import subprocess
@ -37,20 +36,25 @@ def podman_pull(image):
if __name__ == "__main__": if __name__ == "__main__":
containers = podman_ps() containers = podman_ps()
images = set() units = collections.defaultdict(list)
for container in containers: for container in containers:
labels = container.get("Labels", None) labels = container.get("Labels", None)
if labels is None: if labels is None:
continue continue
autoupdate = labels.get("io.containers.autoupdate", None)
if (autoupdate is None) or (autoupdate == "disabled"): autoupdate = labels.get("io.containers.autoupdate", "disabled")
if autoupdate == "disabled":
continue continue
if autoupdate != "image": if autoupdate != "image":
raise ValueError(f"unrecognised autopdate label: {autoupdate}") raise ValueError(f"unrecognised autopdate label: {autoupdate}")
images.add(container["Image"])
updated = [] if "PODMAN_SYSTEMD_UNIT" not in labels:
for image in images: raise ValueError(
f"container {container['Names'][0]} does not have \"PODMAN_SYSTEMD_UNIT\" label")
units[container["Image"]].append(labels["PODMAN_SYSTEMD_UNIT"])
updated = set()
for image in units.keys():
inspect = podman_image_inspect(image) inspect = podman_image_inspect(image)
original_digest = inspect["Digest"] original_digest = inspect["Digest"]
@ -60,9 +64,11 @@ if __name__ == "__main__":
new_digest = inspect["Digest"] new_digest = inspect["Digest"]
if new_digest != original_digest: if new_digest != original_digest:
updated.append(image) updated.add(image)
if updated: if updated:
print(f"The following images have been updated: {updated}") print(f"The following images have been updated: {', '.join(updated)}")
subprocess.run(["systemctl", "--user", "restart", f"{getpass.getuser()}.service"], restart = functools.reduce(lambda x, y: x + y, [units[image] for image in updated])
check=True)
print(f"The following units will be restarted: {', '.join(restart)}")
subprocess.run(["systemctl", "--user", "restart"] + restart, check=True)