Add script to re-tag plugin
parent
ef789c0f4b
commit
4a4110649d
@ -0,0 +1,81 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
import dxf
|
||||||
|
|
||||||
|
MTYPE_PLUGIN_CONFIG = 'application/vnd.docker.plugin.v1+json'
|
||||||
|
MTYPE_LAYER = 'application/vnd.docker.image.rootfs.diff.tar.gzip'
|
||||||
|
MTYPE_MANIFEST = 'application/vnd.docker.distribution.manifest.v2+json'
|
||||||
|
MTYPE_MANIFEST_LIST = 'application/vnd.docker.distribution.manifest.list.v2+json'
|
||||||
|
|
||||||
|
class Platform:
|
||||||
|
def __init__(self, s):
|
||||||
|
self.buildx = s
|
||||||
|
|
||||||
|
split = s.split('/')
|
||||||
|
if len(split) < 2:
|
||||||
|
raise Exception('Invalid platform format')
|
||||||
|
|
||||||
|
self.dirname = '_'.join(split)
|
||||||
|
|
||||||
|
self.os = split[0]
|
||||||
|
self.architecture = split[1]
|
||||||
|
|
||||||
|
self.variant = None
|
||||||
|
if len(split) > 3:
|
||||||
|
raise Exception('Invalid platform format')
|
||||||
|
elif len(split) == 3:
|
||||||
|
self.variant = split[2]
|
||||||
|
elif self.architecture == 'arm64':
|
||||||
|
# Weird exception? (seen in alpine images)
|
||||||
|
self.variant = 'v8'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def manifest(self):
|
||||||
|
d = {
|
||||||
|
'os': self.os,
|
||||||
|
'architecture': self.architecture,
|
||||||
|
}
|
||||||
|
if self.variant is not None:
|
||||||
|
d['variant'] = self.variant
|
||||||
|
|
||||||
|
return d
|
||||||
|
|
||||||
|
def tag(self, t):
|
||||||
|
if self.variant is not None:
|
||||||
|
return f'{t}-{self.os}-{self.architecture}-{self.variant}'
|
||||||
|
return f'{t}-{self.os}-{self.architecture}'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'Platform(os={self.os}, architecture={self.architecture}, variant={self.variant})'
|
||||||
|
def __repr__(self):
|
||||||
|
return str(self)
|
||||||
|
|
||||||
|
def dxf_auth(reg: dxf.DXF, res):
|
||||||
|
reg.authenticate(username=os.getenv('REGISTRY_USERNAME'), password=os.getenv('REGISTRY_PASSWORD'), response=res)
|
||||||
|
|
||||||
|
class DXF(dxf.DXF):
|
||||||
|
def set_manifest(self, alias, manifest_json, mime=MTYPE_MANIFEST):
|
||||||
|
"""
|
||||||
|
Give a name (alias) to a manifest.
|
||||||
|
|
||||||
|
:param alias: Alias name
|
||||||
|
:type alias: str
|
||||||
|
|
||||||
|
:param manifest_json: A V2 Schema 2 manifest JSON string
|
||||||
|
:type digests: list
|
||||||
|
"""
|
||||||
|
self._request('put',
|
||||||
|
'manifests/' + alias,
|
||||||
|
data=manifest_json,
|
||||||
|
headers={'Content-Type': mime})
|
||||||
|
|
||||||
|
def push_manifest(self, manifest_dict, ref=None, mime=MTYPE_MANIFEST):
|
||||||
|
mf = json.dumps(manifest_dict, sort_keys=True).encode('utf-8')
|
||||||
|
size = len(mf)
|
||||||
|
digest = dxf.hash_bytes(mf)
|
||||||
|
|
||||||
|
if ref is None:
|
||||||
|
ref = digest
|
||||||
|
|
||||||
|
self.set_manifest(ref, mf, mime=mime)
|
||||||
|
return size, digest
|
@ -0,0 +1,38 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
from docker_image import reference
|
||||||
|
|
||||||
|
from common import *
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description='Re-tag an existing multiarch plugin')
|
||||||
|
parser.add_argument('image', help='existing image (registry/image:tag)')
|
||||||
|
parser.add_argument('tag', help='new tag')
|
||||||
|
parser.add_argument('-p', '--platforms', default='linux/amd64', help='buildx platforms')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
platforms = [Platform(p) for p in args.platforms.split(',')]
|
||||||
|
|
||||||
|
ref = reference.Reference.parse(args.image)
|
||||||
|
hostname, repo = ref.split_hostname()
|
||||||
|
without_tag = ref['name']
|
||||||
|
|
||||||
|
old_tag = ref['tag']
|
||||||
|
new_tag = args.tag
|
||||||
|
|
||||||
|
reg = DXF(hostname, repo, auth=dxf_auth)
|
||||||
|
|
||||||
|
for p in platforms:
|
||||||
|
mf = reg.get_manifest(p.tag(old_tag))
|
||||||
|
|
||||||
|
print(f'Re-tagging {without_tag}:{p.tag(old_tag)} as {without_tag}:{p.tag(new_tag)}')
|
||||||
|
reg.set_manifest(p.tag(new_tag), mf, mime=MTYPE_MANIFEST)
|
||||||
|
|
||||||
|
print(f'Re-tagging {args.image} as {without_tag}:{new_tag}')
|
||||||
|
mf = reg.get_manifest(old_tag)
|
||||||
|
reg.set_manifest(new_tag, mf, mime=MTYPE_MANIFEST_LIST)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Loading…
Reference in New Issue