#!/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 += g._repr_svg_()
html_str += ' | '
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[ ]: