Skip to content

Instantly share code, notes, and snippets.

@dundee
Last active November 20, 2018 10:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dundee/f709924db985ccfb62a58a25d675c9c1 to your computer and use it in GitHub Desktop.
Save dundee/f709924db985ccfb62a58a25d675c9c1 to your computer and use it in GitHub Desktop.
Purge old docer images from registry
import argparse
import logging
import re
import subprocess
import sys
try:
import pydor
except ImportError:
print('Plese run:')
print('sudo pip install git+https://github.com/dohnto/pydor')
sys.exit(-1)
TAG_PATTERN = re.compile(r'(?P<major>\d+)\.(?P<minor>\d+)(\.(?P<patch>\d+))?(-(dev|test)(?P<dev>\d+))?')
def confirm():
while True:
res = input('Is it OK? (y/n)')
if res == 'y':
return True
elif res == 'n':
return False
def purge(registry_host, repository_prefix, keep_images=10, use_local_skopeo=False):
api = pydor.API(registry_host, insecure=True)
for repository in api.Catalog():
if not repository.startswith(repository_prefix):
continue
images = {}
for tag in api.Tags(repository):
match = TAG_PATTERN.match(tag)
if not match:
logging.warning('Tag %s of repository %s does not have semantic versioning', tag, repository)
continue
tag_parts = match.groupdict()
tag_parts = {name: int(value) if value else 0 for name, value in tag_parts.items()}
image = '{}/{}:{}'.format(registry_host, repository, tag)
images[(tag_parts['major'], tag_parts['minor'], tag_parts['patch'], tag_parts['dev'])] = image
image_keys = sorted(images.keys())
images_to_delete = image_keys[:-keep_images]
images_to_keep = image_keys[-keep_images:]
print('\033[93m', 'These images will be preserved:', '\033[0m')
print('\n'.join([images[image] for image in images_to_keep]))
print('\033[93m', 'These images will be deleted:', '\033[0m')
print('\n'.join([images[image] for image in images_to_delete]))
if confirm():
image_count = len(images_to_delete)
for i, image in enumerate(images_to_delete):
print(
'Deleting image: ',
'{:>5}/{}'.format(i + 1, image_count),
images[image],
'\r',
end='',
flush=True
)
if use_local_skopeo:
subprocess.check_call([
'skopeo',
'delete',
'--tls-verify=false',
'docker://{}'.format(images[image])
])
else:
subprocess.check_call([
'docker', 'run', 'doc.ker.dev.dszn.cz/tomas.dohnalek:skopeo',
'/go/src/github.com/containers/skopeo/skopeo',
'delete',
'--tls-verify=false',
'docker://{}'.format(images[image])
])
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--keep', default=10, nargs='?', type=int)
parser.add_argument('--registry', default='doc.ker.dev.dszn.cz', nargs='?')
parser.add_argument('--use-local-skopeo', action='store_true')
parser.add_argument('repository', help='prefix of the repository name')
args = parser.parse_args()
purge(args.registry, args.repository, args.keep, args.use_local_skopeo)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment