[libvirt PATCH v2 6/6] ci: util: Add a registry checker for stale images

Erik Skultety eskultet at redhat.com
Tue Mar 16 17:33:00 UTC 2021


This function checks whether there are any stale Docker images in the
registry that can be purged. Since we're pulling available container
images from our GitLab registry with the 'list-images' action, it
could happen that we'd list old (already unsupported) images and make
them available for the user to consume and run a build in them.
Naturally, the build will most likely fail leaving the user confused.

Signed-off-by: Erik Skultety <eskultet at redhat.com>
---
 ci/helper  | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 ci/util.py | 13 +++++++++++++
 2 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/ci/helper b/ci/helper
index 1b7675c58a..dbe3f80555 100755
--- a/ci/helper
+++ b/ci/helper
@@ -136,9 +136,16 @@ class Parser:
         refreshparser = subparsers.add_parser(
             "refresh",
             help="refresh data generated with lcitool",
-            parents=[lcitoolparser],
+            parents=[lcitoolparser, gitlabparser],
             formatter_class=argparse.ArgumentDefaultsHelpFormatter,
         )
+        refreshparser.add_argument(
+            "--check-stale",
+            action="store",
+            choices=["yes", "no"],
+            default="yes",
+            help="check for existence of stale images on the GitLab instance"
+        )
         refreshparser.set_defaults(func=Application.action_refresh)
 
     def parse(self):
@@ -286,10 +293,55 @@ class Application:
             print("Available cross-compiler container images:\n")
             print("\t" + "\n\t".join(cross))
 
+    def _list_stale_images(self):
+        # get list of hosts supported by lcitool
+        lcitool_hosts = self.lcitool_get_hosts()
+
+        # get images from gitlab registry
+        registry_uri = util.get_registry_uri(self.args.namespace,
+                                             self.args.gitlab_uri)
+        images = util.get_registry_images(registry_uri)
+
+        # extract distro names from the list of registry images
+        registry_distros = [util.get_image_distro(i["name"]) for i in images]
+
+        # check for stale images in GitLab registry
+        stale = set(registry_distros) - set(lcitool_hosts)
+        if stale:
+            stale_images = {}
+            for item in stale:
+                for img in images:
+                    if item in img["name"]:
+                        stale_images[img["name"]] = img["id"]
+
+        return stale_images
+
     def action_refresh(self):
+        # refresh Dockerfiles and vars files
         self.refresh_containers()
         self.refresh_cirrus()
 
+        # check for stale images
+        if self.args.check_stale == "yes" and not self.args.quiet:
+            namespace = self.args.namespace
+            gitlab_uri = self.args.gitlab_uri
+
+            stale_images = self._list_stale_images()
+            if stale_images:
+                spacing = "\n" + 4 * " "
+                stale_fmt = [f"{k}: {v}" for k, v in stale_images.items()]
+
+                print(f"""
+The following images are stale and can be purged from the registry:
+{spacing + spacing.join(stale_fmt)}
+
+You can remove the above images over the API with the following code snippet:
+
+    $ for image_id in {' '.join([str(id) for id in stale_images.values()])}; do
+          curl --request DELETE --header "PRIVATE-TOKEN: <access_token>" \\
+          {util.get_registry_uri(namespace, gitlab_uri)}/$image_id
+      done""")
+
     def run(self):
         self.args.func(self)
 
diff --git a/ci/util.py b/ci/util.py
index 8a2d6d8f47..f50c0e6100 100644
--- a/ci/util.py
+++ b/ci/util.py
@@ -37,3 +37,16 @@ def get_registry_images(uri: str) -> Dict[str, str]:
 
     # read the HTTP response and load the JSON part of it
     return json.loads(r.read().decode())
+
+
+def get_image_distro(image_name: str):
+    name_prefix = "ci-"
+    name_suffix = "-cross-"
+
+    distro = image_name[len(name_prefix):]
+
+    index = distro.find(name_suffix)
+    if index > 0:
+        distro = distro[:index]
+
+    return distro
-- 
2.29.2




More information about the libvir-list mailing list