#!/usr/bin/env python # coding: utf-8 # In[1]: get_ipython().run_line_magic('load_ext', 'watermark') get_ipython().run_line_magic('watermark', "-a 'cs224' -u -d -v -p numpy,pandas") # In[2]: from IPython.display import display, HTML, Markdown from IPython.display import display_html def display_side_by_side(*args): html_str='' for df in args: if type(df) == np.ndarray: df = pd.DataFrame(df) html_str+=df.to_html() html_str = html_str.replace('table','table style="display:inline"') # print(html_str) display_html(html_str,raw=True) CSS = """ .output { flex-direction: row; } """ def display_graphs_side_by_side(*args): html_str='' for g in args: html_str += '' html_str += '
' html_str += g._repr_svg_() html_str += '
' display_html(html_str,raw=True) display(HTML("")) # * [Tools To Deal With Container Images](https://github.com/iximiuz/awesome-container-tinkering/blob/4dd6940e98c1a3571f6612e6075efd2cb1b223bb/IMAGES.md#image-distribution) # * https://github.com/regclient/regclient # * https://github.com/containers/skopeo # In[3]: # regctl image inspect ghcr.io/home-assistant/home-assistant:stable # regctl image manifest ghcr.io/home-assistant/home-assistant:stable # regctl image manifest --format raw-body ghcr.io/home-assistant/home-assistant:stable # regctl artifact tree ghcr.io/home-assistant/home-assistant:stable # regctl registry login # regctl image ratelimit influxdb:latest # { # "Remain": 200, # "Limit": 200, # "Reset": 0, # "Set": true, # "Policies": [ # "200;w=21600" # ] # } # In[4]: import numpy as np, pandas as pd import subprocess, json, re, collections # In[5]: image = 'ghcr.io/home-assistant/home-assistant:stable' image_base = 'ghcr.io/home-assistant/home-assistant' # In[6]: def run_cmd(args, cwd = None, stdin_input=None, decode=True): #out = subprocess.check_output(args, cwd=cwd) if stdin_input is not None: if isinstance(stdin_input, str): stdin_input = str.encode(stdin_input) out = subprocess.run(args, check=True, stdout=subprocess.PIPE, cwd=cwd, input=stdin_input).stdout #text=True, else: out = subprocess.run(args, check=True, stdout=subprocess.PIPE, cwd=cwd).stdout if decode: return out.decode('utf-8') else: return out # In[7]: def get_image_tags(image_ref, pattern=r'^.*$'): cmd = f'regctl tag ls {image_ref}' cmd = [itm for itm in cmd.split(' ') if itm != ''] result = run_cmd(cmd).strip() result = result.split('\n') result = [r for r in result if re.match(pattern, r)] return result # In[8]: get_image_tags(image_base)[-50:] # In[9]: get_image_tags(image_base, pattern=r'^\d\d\d\d\.\d+\.\d+$')[-50:] # In[10]: def get_image_metadata(image_ref, platform='linux/amd64'): cmd = f'regctl image inspect --platform {platform} {image_ref}' cmd = [itm for itm in cmd.split(' ') if itm != ''] result = run_cmd(cmd) result = json.loads(result) return result # In[11]: get_image_metadata(image)['created'] # In[12]: def get_image_manifest(image_ref): cmd = f'regctl image manifest {image_ref}' cmd = [itm for itm in cmd.split(' ') if itm != ''] result1 = run_cmd(cmd).split('\n')[:3] result = [] for r in result1: result += [[_.strip() for _ in r.split(':')]] result_ = result cmd = f'regctl image manifest --format raw-body {image_ref}' cmd = [itm for itm in cmd.split(' ') if itm != ''] result = run_cmd(cmd) result = json.loads(result) return result_ + result['manifests'] # In[13]: r = get_image_manifest(image) r # In[14]: def generate_docker_image_overview(image_ref, tag_pattern=r'^.*$', tag_limit=20): tags = get_image_tags(image_ref, pattern=tag_pattern) tags.reverse() r = [] for tag in tags[:tag_limit]: img_ref = image_ref + ':' + tag meta = get_image_metadata(img_ref) dt = pd.to_datetime(meta['created']) labels = meta['config']['Labels'] manifests = get_image_manifest(img_ref) digest = ':'.join(manifests[2][1:]) platform = '' entry = collections.OrderedDict(tag=tag, dt=dt, digest=digest, platform=platform, labels=json.dumps(labels)) r += [entry] for manifest in manifests[3:]: digest = manifest['digest'] platform = manifest['platform']['os'] + '/' + manifest['platform']['architecture'] entry = collections.OrderedDict(tag=tag, dt=dt, digest=digest, platform=platform, labels=json.dumps(labels)) r += [entry] rdf = pd.DataFrame(r) return rdf # In[15]: get_ipython().run_cell_magic('time', '', "ldf = generate_docker_image_overview(image_base, tag_pattern=r'^\\d\\d\\d\\d\\.\\d+\\.\\d+$', tag_limit=10)\n") # In[16]: ldf # In[17]: # docker image ls --digests # docker image inspect --format '{{json .}}' ghcr.io/home-assistant/home-assistant:stable | jq . # docker image inspect --format '{{json .}}' ghcr.io/home-assistant/home-assistant:stable | jq '.RepoDigests[0]' # In[18]: repo_digest_part = 'd1dadb8e6' # In[19]: ldf[ldf['digest'].str.contains(repo_digest_part)] # In[20]: # list(ldf['digest']) # In[ ]: