69 lines
2.3 KiB
Python
69 lines
2.3 KiB
Python
#!/usr/bin/env python3
|
|
|
|
"""This script replaces `podman auto-update`. If a digest in a registry has been updated, `podman
|
|
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`.
|
|
|
|
"""
|
|
|
|
import getpass
|
|
import json
|
|
import subprocess
|
|
|
|
|
|
def podman_ps():
|
|
out = subprocess.run(["podman", "ps", "--format", "json"], capture_output=True, check=True)
|
|
return json.loads(out.stdout)
|
|
|
|
|
|
def podman_image_inspect(image):
|
|
out = subprocess.run(["podman", "image", "inspect", "--format", "json", image],
|
|
capture_output=True, check=True)
|
|
inspect = json.loads(out.stdout)
|
|
assert inspect
|
|
if len(inspect) > 1:
|
|
raise ValueError("podman image inspect returned multiple entries")
|
|
return inspect[0]
|
|
|
|
|
|
def podman_pull(image):
|
|
subprocess.run(["podman", "pull", image], capture_output=True, check=True)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
containers = podman_ps()
|
|
|
|
images = set()
|
|
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"):
|
|
continue
|
|
if autoupdate != "image":
|
|
raise ValueError(f"unrecognised autopdate label: {autoupdate}")
|
|
images.add(container["Image"])
|
|
|
|
updated = []
|
|
for image in images:
|
|
inspect = podman_image_inspect(image)
|
|
original_digest = inspect["Digest"]
|
|
|
|
podman_pull(image)
|
|
|
|
inspect = podman_image_inspect(image)
|
|
new_digest = inspect["Digest"]
|
|
|
|
if new_digest != original_digest:
|
|
updated.append(image)
|
|
|
|
if updated:
|
|
print(f"The following images have been updated: {updated}")
|
|
subprocess.run(["systemctl", "--user", "restart", f"{getpass.getuser()}.service"],
|
|
check=True)
|