import shutil
import subprocess
import sys
+import textwrap
import util
refreshparser = subparsers.add_parser(
"refresh",
help="refresh data generated with lcitool",
- parents=[lcitoolparser],
+ parents=[lcitoolparser, gitlabparser],
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
refreshparser.add_argument(
default=False,
help="refresh data silently"
)
+ 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):
self.generate_vars(host)
+ def check_stale_images(self):
+ namespace = self.args.namespace
+ gitlab_uri = self.args.gitlab_uri
+ registry_uri = util.get_registry_uri(namespace, gitlab_uri)
+ lcitool_hosts = self.lcitool_get_hosts()
+
+ stale_images = util.get_registry_stale_images(registry_uri,
+ lcitool_hosts)
+ if stale_images:
+ spacing = "\n" + 4 * " "
+ stale_fmt = [f"{k} (ID: {v})" for k, v in stale_images.items()]
+ stale_details = spacing.join(stale_fmt)
+ stale_ids = ' '.join([str(id) for id in stale_images.values()])
+ registry_uri = util.get_registry_uri(namespace, gitlab_uri)
+
+ msg = textwrap.dedent(f"""
+ The following images are stale and can be purged from the registry:
+
+ STALE_DETAILS
+
+ You can delete the images listed above using this shell snippet:
+
+ $ for image_id in {stale_ids}; do
+ curl --request DELETE --header "PRIVATE-TOKEN: <access_token>" \\
+ {registry_uri}/$image_id;
+ done
+
+ You can generate a personal access token here:
+
+ {gitlab_uri}/-/profile/personal_access_tokens
+ """)
+ print(msg.replace("STALE_DETAILS", stale_details))
+
def action_build(self):
self.make_run(f"ci-build@{self.args.target}")
self.refresh_containers()
self.refresh_cirrus()
+ if self.args.check_stale == "yes" and not self.args.quiet:
+ self.check_stale_images()
+
def run(self):
self.args.func(self)
# read the HTTP response and load the JSON part of it
return json.loads(r.read().decode())
+
+
+def get_image_distro(image_name: str) -> str:
+ """
+ Extract the name of the distro in the GitLab image registry name, e.g.
+ ci-debian-9-cross-mipsel --> debian-9
+
+ :param image_name: name of the GitLab registry image
+ :return: distro name as a string
+ """
+ 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
+
+
+def get_registry_stale_images(registry_uri: str,
+ supported_distros: List[str]) -> Dict[str, int]:
+ """
+ Check the GitLab image registry for images that we no longer support and
+ which should be deleted.
+
+ :param uri: URI pointing to a GitLab instance's image registry
+ :param supported_distros: list of hosts supported by lcitool
+ :return: dictionary formatted as: {<gitlab_image_name>: <gitlab_image_id>}
+ """
+
+ images = get_registry_images(registry_uri)
+
+ stale_images = {}
+ for img in images:
+ if get_image_distro(img["name"]) not in supported_distros:
+ stale_images[img["name"]] = img["id"]
+
+ return stale_images