|
#!/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() |