Last active
November 20, 2018 10:02
-
-
Save dundee/f709924db985ccfb62a58a25d675c9c1 to your computer and use it in GitHub Desktop.
Purge old docer images from registry
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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