X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=build%2Fdownload%2Fdocker_downloader.py;h=9897325d807afd3eb7ddb9f6205b465b688a0a60;hb=HEAD;hp=d83f682cdc1dbbd347b9860246fa0b535de8660a;hpb=fb03eebcbc670415cdb37861452f0ed4bd65696a;p=oom%2Foffline-installer.git diff --git a/build/download/docker_downloader.py b/build/download/docker_downloader.py index d83f682c..9897325d 100755 --- a/build/download/docker_downloader.py +++ b/build/download/docker_downloader.py @@ -3,7 +3,7 @@ # COPYRIGHT NOTICE STARTS HERE -# Copyright 2019 © Samsung Electronics Co., Ltd. +# Copyright 2022 © Samsung Electronics Co., Ltd. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -36,14 +36,19 @@ log = logging.getLogger(__name__) class DockerDownloader(ConcurrentDownloader): - def __init__(self, save, *list_args, workers=3): + def __init__(self, save, *list_args, mirror=None, mirror_exclude=[], workers=3): + """ + :param mirror: private repository mirror address (ip:port) + """ self._save = save + self._mirror = mirror + self._mirror_exclude = mirror_exclude try: # big timeout in case of massive images like pnda-mirror-container:5.0.0 (11.4GB) - self._docker_client = docker.client.DockerClient(version='auto', timeout=300) + self._docker_client = docker.from_env(timeout=300) except docker.errors.DockerException as err: log.exception( - 'Error creating docker client. Check if is docker installed and running' + 'Error creating docker client. Check if docker is installed and running' ' or if you have right permissions.') raise err self._pulled_images = set(itertools.chain.from_iterable((image.tags for image @@ -153,7 +158,28 @@ class DockerDownloader(ConcurrentDownloader): if ':' not in image_name.rsplit('/')[-1]: image_name = '{}:latest'.format(image_name) try: - image = self._docker_client.images.pull(image_name) + if self._mirror: + # if docker mirroring repository is set + image_name_split = image_name.split('/') + if (len(image_name_split) > 1) \ + and (image_name_split[0].find(".")) >= 0 \ + and not (image_name.startswith('docker.io/')) \ + and not (image_name.startswith(self._mirror)) \ + and (image_name_split[0] not in self._mirror_exclude): + # if image originates from private registry and its name does not start with 'docker.io' + # and it does not originate from excluded registry + # and docker mirror name differs from private registry name + # -> download image from docker mirror and retag it to its original name + mirrored_image_name = self._mirror + "/" + '/'.join(image_name_split[1:]) + img = self._docker_client.images.pull(mirrored_image_name) + self._docker_client.images.model.tag(img, image_name) + # untag the image pulled from mirror + self._docker_client.images.remove(mirrored_image_name) + image = self._docker_client.images.get(image_name) + else: + image = self._docker_client.images.pull(image_name) + else: + image = self._docker_client.images.pull(image_name) log.info('Image {} pulled'.format(image_name)) return image except docker.errors.APIError as err: @@ -168,8 +194,7 @@ class DockerDownloader(ConcurrentDownloader): :param image_name: name of the image from list """ dst = '{}/{}'.format(output_dir, self._image_filename(image_name)) - if not os.path.exists(output_dir): - os.makedirs(output_dir) + os.makedirs(output_dir, exist_ok=True) try: with open(dst, 'wb') as f: for chunk in image.save(named=self.image_registry_name(image_name)): @@ -206,6 +231,13 @@ def run_cli(): help='Save images (without it only pull is executed)') parser.add_argument('--output-dir', '-o', default=os.getcwd(), help='Download destination') + parser.add_argument('--private-registry-mirror', default=None, metavar='HOST:PORT', + help='Address of docker mirroring repository that caches images' + ' from private registries to get those images from') + parser.add_argument('--private-registry-exclude', action='append', default=[], metavar='REGISTRY_NAME', + help='The name of a private registry to exclude when using --private-registry-mirror.' + ' Images that originate from excluded registry will not be' + ' pulled from mirroring repository. This option can be used multiple times.') parser.add_argument('--check', '-c', action='store_true', default=False, help='Check what is missing. No download.' 'Use with combination with -s to check saved images as well.') @@ -221,7 +253,7 @@ def run_cli(): else: logging.basicConfig(stream=sys.stdout, level=logging.INFO, format='%(message)s') - downloader = DockerDownloader(args.save, [args.file_list, args.output_dir], workers=args.workers) + downloader = DockerDownloader(args.save, [args.image_list, args.output_dir], mirror=args.private_registry_mirror, mirror_exclude=args.private_registry_exclude, workers=args.workers) if args.check: log.info('Check mode. No download will be executed.')