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
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
after the pull. However, it assumes that there is only service that needs restarting on updates and
that its called <username>.service so it is not (yet) a drop-in replacement for `podman
auto-update`.
after the pull.
"""
import getpass
import collections
import functools
import json
import subprocess
@ -37,20 +36,25 @@ def podman_pull(image):
if __name__ == "__main__":
containers = podman_ps()
images = set()
units = collections.defaultdict(list)
for container in containers:
labels = container.get("Labels", None)
if labels is None:
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
if autoupdate != "image":
raise ValueError(f"unrecognised autopdate label: {autoupdate}")
images.add(container["Image"])
updated = []
for image in images:
if "PODMAN_SYSTEMD_UNIT" not in labels:
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)
original_digest = inspect["Digest"]
@ -60,9 +64,11 @@ if __name__ == "__main__":
new_digest = inspect["Digest"]
if new_digest != original_digest:
updated.append(image)
updated.add(image)
if updated:
print(f"The following images have been updated: {updated}")
subprocess.run(["systemctl", "--user", "restart", f"{getpass.getuser()}.service"],
check=True)
print(f"The following images have been updated: {', '.join(updated)}")
restart = functools.reduce(lambda x, y: x + y, [units[image] for image in updated])
print(f"The following units will be restarted: {', '.join(restart)}")
subprocess.run(["systemctl", "--user", "restart"] + restart, check=True)