Skip to content

Instantly share code, notes, and snippets.

@neilmillard
Last active May 9, 2022 09:56
Show Gist options
  • Save neilmillard/cb32bf80204e785bd3380a15558115c2 to your computer and use it in GitHub Desktop.
Save neilmillard/cb32bf80204e785bd3380a15558115c2 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import argparse
import os
import re
import requests
def parse_args():
parser = argparse.ArgumentParser(
description="Display a summary of a docker image's key tags and how they relate."
)
parser.add_argument(
"image_name", type=str, help="The name/repo of the image."
)
return parser.parse_args()
def get_docker_api_response(docker_api_path, headers=None):
api_username = os.getenv("API_USERNAME")
api_key = os.getenv("API_KEY")
auth = requests.auth.HTTPBasicAuth(api_username, api_key)
return requests.get(
f"https://dockerhub/api/docker/{docker_api_path}",
auth=auth,
headers=headers,
)
def get_image_tags(image_name):
return get_docker_api_response(f"{image_name}/v2/{image_name}/tags/list").json()[
"tags"
]
def get_image_tag_digest(image_name, image_tag):
docker_content_digest = get_docker_api_response(
f"{image_name}/v2/{image_name}/manifests/{image_tag}",
headers={"Accept": "application/vnd.docker.distribution.manifest.v2+json"},
).headers["Docker-Content-Digest"]
print(f"Digest for {image_name}:{image_tag} is {docker_content_digest}.")
return docker_content_digest
def get_image_tag_summary(image_name, image_tags, experimental_tag_digest, latest_tag_digest):
semantic_version_tags = [tag for tag in image_tags if re.match(r"^\d+.\d+.\d+$", tag)]
semantic_version_tags.sort(key=lambda x: [int(y) for y in x.split(".")])
image_tag_summary = {
"most_recent_sementic_version": semantic_version_tags[-1],
"experimental_version": None,
"latest_version": None,
}
experimental_tag_semantic_version = None
latest_tag_semantic_version = None
for semantic_version_tag in semantic_version_tags[::-1]:
semantic_version_tag_digest = get_image_tag_digest(image_name, semantic_version_tag)
if semantic_version_tag_digest == experimental_tag_digest:
image_tag_summary["experimental_version"] = semantic_version_tag
if semantic_version_tag_digest == latest_tag_digest:
image_tag_summary["latest_version"] = semantic_version_tag
if image_tag_summary["experimental_version"] and image_tag_summary["latest_version"]:
break
return image_tag_summary
def main():
args = parse_args()
image_tags = get_image_tags(args.image_name)
experimental_tag_digest = get_image_tag_digest(args.image_name, "experimental")
latest_tag_digest = get_image_tag_digest(args.image_name, "latest")
print(
get_image_tag_summary(
args.image_name, image_tags, experimental_tag_digest, latest_tag_digest
)
)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment