Merge "Use DockerRegistryMirror to proxy requests"

This commit is contained in:
Zuul 2018-11-01 17:42:23 +00:00 committed by Gerrit Code Review
commit 1ee3c59dc7
4 changed files with 171 additions and 106 deletions

View File

@ -77,7 +77,8 @@ class ImageUploadManager(BaseImageManager):
""" """
def __init__(self, config_files=None, def __init__(self, config_files=None,
dry_run=False, cleanup=CLEANUP_FULL): dry_run=False, cleanup=CLEANUP_FULL,
mirrors=None):
if config_files is None: if config_files is None:
config_files = [] config_files = []
super(ImageUploadManager, self).__init__(config_files) super(ImageUploadManager, self).__init__(config_files)
@ -87,13 +88,14 @@ class ImageUploadManager(BaseImageManager):
} }
self.dry_run = dry_run self.dry_run = dry_run
self.cleanup = cleanup self.cleanup = cleanup
self.mirrors = mirrors
def discover_image_tag(self, image, tag_from_label=None, def discover_image_tag(self, image, tag_from_label=None,
username=None, password=None): username=None, password=None):
uploader = self.uploader(DEFAULT_UPLOADER) uploader = self.uploader(DEFAULT_UPLOADER)
return uploader.discover_image_tag( return uploader.discover_image_tag(
image, tag_from_label=tag_from_label, image, tag_from_label=tag_from_label,
username=username, password=password) username=username, password=password, mirrors=self.mirrors)
def uploader(self, uploader): def uploader(self, uploader):
if uploader not in self.uploaders: if uploader not in self.uploaders:
@ -136,7 +138,7 @@ class ImageUploadManager(BaseImageManager):
task = UploadTask( task = UploadTask(
image_name, pull_source, push_destination, image_name, pull_source, push_destination,
append_tag, modify_role, modify_vars, self.dry_run, append_tag, modify_role, modify_vars, self.dry_run,
self.cleanup) self.cleanup, self.mirrors)
uploader.add_upload_task(task) uploader.add_upload_task(task)
for uploader in self.uploaders.values(): for uploader in self.uploaders.values():
@ -221,13 +223,14 @@ class BaseImageUploader(object):
'Modifying image %s failed' % target_image) 'Modifying image %s failed' % target_image)
@classmethod @classmethod
def _images_match(cls, image1, image2, session1=None): def _images_match(cls, image1, image2, session1=None, mirrors=None):
try: try:
image1_digest = cls._image_digest(image1, session=session1) image1_digest = cls._image_digest(image1, session=session1,
mirrors=mirrors)
except Exception: except Exception:
return False return False
try: try:
image2_digest = cls._image_digest(image2) image2_digest = cls._image_digest(image2, mirrors=mirrors)
except Exception: except Exception:
return False return False
@ -237,22 +240,22 @@ class BaseImageUploader(object):
return image1_digest == image2_digest return image1_digest == image2_digest
@classmethod @classmethod
def _image_digest(cls, image, session=None): def _image_digest(cls, image, session=None, mirrors=None):
image_url = cls._image_to_url(image) image_url = cls._image_to_url(image)
insecure = image_url.netloc in cls.insecure_registries insecure = image_url.netloc in cls.insecure_registries
i = cls._inspect(image_url, insecure, session) i = cls._inspect(image_url, insecure, session, mirrors=mirrors)
return i.get('Digest') return i.get('Digest')
@classmethod @classmethod
def _image_labels(cls, image_url, insecure, session=None): def _image_labels(cls, image_url, insecure, session=None, mirrors=None):
i = cls._inspect(image_url, insecure, session) i = cls._inspect(image_url, insecure, session, mirrors=mirrors)
return i.get('Labels', {}) or {} return i.get('Labels', {}) or {}
@classmethod @classmethod
def _image_exists(cls, image, session=None): def _image_exists(cls, image, session=None, mirrors=None):
try: try:
cls._image_digest( cls._image_digest(
image, session=session) image, session=session, mirrors=mirrors)
except ImageNotFoundException: except ImageNotFoundException:
return False return False
else: else:
@ -268,15 +271,11 @@ class BaseImageUploader(object):
stop=tenacity.stop_after_attempt(5) stop=tenacity.stop_after_attempt(5)
) )
def authenticate(cls, image_url, username=None, password=None, def authenticate(cls, image_url, username=None, password=None,
insecure=False): insecure=False, mirrors=None):
image_url = cls._fix_dockerio_url(image_url)
netloc = image_url.netloc
if insecure:
scheme = 'http'
else:
scheme = 'https'
image, tag = image_url.path.split(':') image, tag = image_url.path.split(':')
url = '%s://%s/v2/' % (scheme, netloc) url = cls._build_url(image_url, path='/',
insecure=insecure,
mirrors=mirrors)
session = requests.Session() session = requests.Session()
r = session.get(url, timeout=30) r = session.get(url, timeout=30)
LOG.debug('%s status code %s' % (url, r.status_code)) LOG.debug('%s status code %s' % (url, r.status_code))
@ -308,14 +307,19 @@ class BaseImageUploader(object):
return session return session
@classmethod @classmethod
def _fix_dockerio_url(cls, url): def _build_url(cls, url, path, insecure=False, mirrors=None):
one = 'docker.io' netloc = url.netloc
two = 'registry-1.docker.io' if mirrors and netloc in mirrors:
if url.netloc != one: mirror = mirrors[netloc]
return url return '%sv2%s' % (mirror, path)
return parse.ParseResult(url.scheme, two, else:
url.path, url.params, if insecure:
url.query, url.fragment) scheme = 'http'
else:
scheme = 'https'
if netloc == 'docker.io':
netloc = 'registry-1.docker.io'
return '%s://%s/v2%s' % (scheme, netloc, path)
@classmethod @classmethod
@tenacity.retry( # Retry up to 5 times with jittered exponential backoff @tenacity.retry( # Retry up to 5 times with jittered exponential backoff
@ -326,24 +330,21 @@ class BaseImageUploader(object):
wait=tenacity.wait_random_exponential(multiplier=1, max=10), wait=tenacity.wait_random_exponential(multiplier=1, max=10),
stop=tenacity.stop_after_attempt(5) stop=tenacity.stop_after_attempt(5)
) )
def _inspect(cls, image_url, insecure=False, session=None): def _inspect(cls, image_url, insecure=False, session=None, mirrors=None):
original_image_url = image_url
image_url = cls._fix_dockerio_url(image_url)
parts = {
'netloc': image_url.netloc
}
if insecure:
parts['scheme'] = 'http'
else:
parts['scheme'] = 'https'
image, tag = image_url.path.split(':') image, tag = image_url.path.split(':')
parts['image'] = image parts = {
parts['tag'] = tag 'image': image,
'tag': tag
}
manifest_url = ('%(scheme)s://%(netloc)s/v2' manifest_url = cls._build_url(
'%(image)s/manifests/%(tag)s' % parts) image_url, '%(image)s/manifests/%(tag)s' % parts,
tags_url = ('%(scheme)s://%(netloc)s/v2' insecure, mirrors
'%(image)s/tags/list' % parts) )
tags_url = cls._build_url(
image_url, '%(image)s/tags/list' % parts,
insecure, mirrors
)
manifest_headers = { manifest_headers = {
'Accept': 'application/vnd.docker.distribution.manifest.v2+json' 'Accept': 'application/vnd.docker.distribution.manifest.v2+json'
} }
@ -369,8 +370,9 @@ class BaseImageUploader(object):
config_headers = { config_headers = {
'Accept': manifest['config']['mediaType'] 'Accept': manifest['config']['mediaType']
} }
config_url = ('%(scheme)s://%(netloc)s/v2' config_url = cls._build_url(
'%(image)s/blobs/%(config_digest)s' % parts) image_url, '%(image)s/blobs/%(config_digest)s' % parts,
insecure, mirrors)
config_f = p.submit( config_f = p.submit(
session.get, config_url, headers=config_headers, timeout=30) session.get, config_url, headers=config_headers, timeout=30)
config_r = config_f.result() config_r = config_f.result()
@ -379,7 +381,7 @@ class BaseImageUploader(object):
tags = tags_r.json()['tags'] tags = tags_r.json()['tags']
digest = manifest_r.headers['Docker-Content-Digest'] digest = manifest_r.headers['Docker-Content-Digest']
config = config_r.json() config = config_r.json()
name = '%s%s' % (original_image_url.netloc, image) name = '%s%s' % (image_url.netloc, image)
return { return {
'Name': name, 'Name': name,
@ -445,7 +447,7 @@ class BaseImageUploader(object):
) )
return tag_label return tag_label
def discover_image_tags(self, images, tag_from_label=None): def discover_image_tags(self, images, tag_from_label=None, mirrors=None):
image_urls = [self._image_to_url(i) for i in images] image_urls = [self._image_to_url(i) for i in images]
# prime self.insecure_registries by testing every image # prime self.insecure_registries by testing every image
@ -455,7 +457,7 @@ class BaseImageUploader(object):
discover_args = [] discover_args = []
for image in images: for image in images:
discover_args.append((image, tag_from_label, discover_args.append((image, tag_from_label,
self.insecure_registries)) self.insecure_registries, mirrors))
p = futures.ThreadPoolExecutor(max_workers=16) p = futures.ThreadPoolExecutor(max_workers=16)
versioned_images = {} versioned_images = {}
@ -465,25 +467,28 @@ class BaseImageUploader(object):
return versioned_images return versioned_images
def discover_image_tag(self, image, tag_from_label=None, def discover_image_tag(self, image, tag_from_label=None,
fallback_tag=None, username=None, password=None): fallback_tag=None, username=None, password=None,
mirrors=None):
image_url = self._image_to_url(image) image_url = self._image_to_url(image)
insecure = self.is_insecure_registry(image_url.netloc) insecure = self.is_insecure_registry(image_url.netloc)
session = self.authenticate( session = self.authenticate(
image_url, insecure=insecure, username=username, password=password) image_url, insecure=insecure, username=username, password=password,
i = self._inspect(image_url, insecure, session) mirrors=mirrors)
i = self._inspect(image_url, insecure, session, mirrors=mirrors)
return self._discover_tag_from_inspect(i, image, tag_from_label, return self._discover_tag_from_inspect(i, image, tag_from_label,
fallback_tag) fallback_tag)
def filter_images_with_labels(self, images, labels, def filter_images_with_labels(self, images, labels,
username=None, password=None): username=None, password=None, mirrors=None):
images_with_labels = [] images_with_labels = []
for image in images: for image in images:
url = self._image_to_url(image) url = self._image_to_url(image)
insecure = self.is_insecure_registry(url.netloc) insecure = self.is_insecure_registry(url.netloc)
session = self.authenticate( session = self.authenticate(
url, insecure=insecure, username=username, password=password) url, insecure=insecure, username=username, password=password,
mirrors=mirrors)
image_labels = self._image_labels( image_labels = self._image_labels(
url, insecure=insecure, session=session) url, insecure=insecure, session=session, mirrors=mirrors)
if set(labels).issubset(set(image_labels)): if set(labels).issubset(set(image_labels)):
images_with_labels.append(image) images_with_labels.append(image)
@ -558,17 +563,20 @@ class DockerImageUploader(BaseImageUploader):
if t.modify_role: if t.modify_role:
target_session = self.authenticate( target_session = self.authenticate(
t.target_image_url, insecure=target_insecure) t.target_image_url, insecure=target_insecure,
mirrors=t.mirrors)
if self._image_exists(t.target_image, if self._image_exists(t.target_image,
session=target_session): session=target_session,
mirrors=t.mirrors):
LOG.warning('Skipping upload for modified image %s' % LOG.warning('Skipping upload for modified image %s' %
t.target_image) t.target_image)
return [] return []
else: else:
source_session = self.authenticate( source_session = self.authenticate(
t.source_image_url, insecure=source_insecure) t.source_image_url, insecure=source_insecure,
mirrors=t.mirrors)
if self._images_match(t.source_image, t.target_image, if self._images_match(t.source_image, t.target_image,
session1=source_session): session1=source_session, mirrors=t.mirrors):
LOG.warning('Skipping upload for image %s' % t.image_name) LOG.warning('Skipping upload for image %s' % t.image_name)
return [] return []
@ -689,21 +697,25 @@ class SkopeoImageUploader(BaseImageUploader):
return [] return []
target_session = self.authenticate( target_session = self.authenticate(
t.target_image_url, insecure=target_insecure) t.target_image_url, insecure=target_insecure,
mirrors=t.mirrors)
if t.modify_role and self._image_exists( if t.modify_role and self._image_exists(
t.target_image, target_session): t.target_image, target_session,
mirrors=t.mirrors):
LOG.warning('Skipping upload for modified image %s' % LOG.warning('Skipping upload for modified image %s' %
t.target_image) t.target_image)
return [] return []
source_session = self.authenticate( source_session = self.authenticate(
t.source_image_url, insecure=source_insecure) t.source_image_url, insecure=source_insecure,
mirrors=t.mirrors)
source_inspect = self._inspect( source_inspect = self._inspect(
t.source_image_url, t.source_image_url,
insecure=source_insecure, insecure=source_insecure,
session=source_session) session=source_session,
mirrors=t.mirrors)
source_layers = source_inspect.get('Layers', []) source_layers = source_inspect.get('Layers', [])
self._cross_repo_mount( self._cross_repo_mount(
t.target_image_url, self.image_layers, source_layers, t.target_image_url, self.image_layers, source_layers,
@ -835,7 +847,8 @@ class SkopeoImageUploader(BaseImageUploader):
class UploadTask(object): class UploadTask(object):
def __init__(self, image_name, pull_source, push_destination, def __init__(self, image_name, pull_source, push_destination,
append_tag, modify_role, modify_vars, dry_run, cleanup): append_tag, modify_role, modify_vars, dry_run, cleanup,
mirrors):
self.image_name = image_name self.image_name = image_name
self.pull_source = pull_source self.pull_source = pull_source
self.push_destination = push_destination self.push_destination = push_destination
@ -844,6 +857,7 @@ class UploadTask(object):
self.modify_vars = modify_vars self.modify_vars = modify_vars
self.dry_run = dry_run self.dry_run = dry_run
self.cleanup = cleanup self.cleanup = cleanup
self.mirrors = mirrors
if ':' in image_name: if ':' in image_name:
image = image_name.rpartition(':')[0] image = image_name.rpartition(':')[0]
@ -875,12 +889,13 @@ def upload_task(args):
def discover_tag_from_inspect(args): def discover_tag_from_inspect(args):
image, tag_from_label, insecure_registries = args image, tag_from_label, insecure_registries, mirrors = args
image_url = BaseImageUploader._image_to_url(image) image_url = BaseImageUploader._image_to_url(image)
insecure = image_url.netloc in insecure_registries insecure = image_url.netloc in insecure_registries
session = BaseImageUploader.authenticate(image_url, insecure=insecure) session = BaseImageUploader.authenticate(image_url, insecure=insecure,
mirrors=mirrors)
i = BaseImageUploader._inspect(image_url, insecure=insecure, i = BaseImageUploader._inspect(image_url, insecure=insecure,
session=session) session=session, mirrors=mirrors)
if ':' in image_url.path: if ':' in image_url.path:
# break out the tag from the url to be the fallback tag # break out the tag from the url to be the fallback tag
path = image.rpartition(':') path = image.rpartition(':')

View File

@ -141,6 +141,11 @@ def container_images_prepare_multi(environment, roles_data, dry_run=False,
if not cip: if not cip:
return return
mirrors = {}
mirror = pd.get('DockerRegistryMirror')
if mirror:
mirrors['docker.io'] = mirror
env_params = {} env_params = {}
service_filter = build_service_filter(environment, roles_data) service_filter = build_service_filter(environment, roles_data)
@ -176,6 +181,7 @@ def container_images_prepare_multi(environment, roles_data, dry_run=False,
modify_role=modify_role, modify_role=modify_role,
modify_vars=modify_vars, modify_vars=modify_vars,
modify_only_with_labels=modify_only_with_labels, modify_only_with_labels=modify_only_with_labels,
mirrors=mirrors
) )
env_params.update(prepare_data['image_params']) env_params.update(prepare_data['image_params'])
@ -187,7 +193,8 @@ def container_images_prepare_multi(environment, roles_data, dry_run=False,
uploader = image_uploader.ImageUploadManager( uploader = image_uploader.ImageUploadManager(
[f.name], [f.name],
dry_run=dry_run, dry_run=dry_run,
cleanup=cleanup cleanup=cleanup,
mirrors=mirrors
) )
uploader.upload() uploader.upload()
return env_params return env_params
@ -209,7 +216,8 @@ def container_images_prepare(template_file=DEFAULT_TEMPLATE_FILE,
mapping_args=None, output_env_file=None, mapping_args=None, output_env_file=None,
output_images_file=None, tag_from_label=None, output_images_file=None, tag_from_label=None,
append_tag=None, modify_role=None, append_tag=None, modify_role=None,
modify_vars=None, modify_only_with_labels=None): modify_vars=None, modify_only_with_labels=None,
mirrors=None):
"""Perform container image preparation """Perform container image preparation
:param template_file: path to Jinja2 file containing all image entries :param template_file: path to Jinja2 file containing all image entries
@ -235,6 +243,7 @@ def container_images_prepare(template_file=DEFAULT_TEMPLATE_FILE,
:param modify_vars: dict of variables to pass to modify_role :param modify_vars: dict of variables to pass to modify_role
:param modify_only_with_labels: only modify the container images with the :param modify_only_with_labels: only modify the container images with the
given labels given labels
:param mirrors: dict of registry netloc values to mirror urls
:returns: dict with entries for the supplied output_env_file or :returns: dict with entries for the supplied output_env_file or
output_images_file output_images_file
""" """
@ -269,7 +278,7 @@ def container_images_prepare(template_file=DEFAULT_TEMPLATE_FILE,
if tag_from_label: if tag_from_label:
image_version_tags = uploader.discover_image_tags( image_version_tags = uploader.discover_image_tags(
images, tag_from_label) images, tag_from_label, mirrors=mirrors)
for entry in result: for entry in result:
imagename = entry.get('imagename', '') imagename = entry.get('imagename', '')
image_no_tag = imagename.rpartition(':')[0] image_no_tag = imagename.rpartition(':')[0]
@ -279,7 +288,7 @@ def container_images_prepare(template_file=DEFAULT_TEMPLATE_FILE,
if modify_only_with_labels: if modify_only_with_labels:
images_with_labels = uploader.filter_images_with_labels( images_with_labels = uploader.filter_images_with_labels(
images, modify_only_with_labels) images, modify_only_with_labels, mirrors=mirrors)
params = {} params = {}
modify_append_tag = append_tag modify_append_tag = append_tag

View File

@ -285,63 +285,63 @@ class TestBaseImageUploader(base.TestCase):
self.assertEqual( self.assertEqual(
('docker.io/t/foo', 'a'), ('docker.io/t/foo', 'a'),
image_uploader.discover_tag_from_inspect( image_uploader.discover_tag_from_inspect(
('docker.io/t/foo', 'rdo_version', sr)) ('docker.io/t/foo', 'rdo_version', sr, None))
) )
# templated labels -> tag # templated labels -> tag
self.assertEqual( self.assertEqual(
('docker.io/t/foo', '1.0.0-20180125'), ('docker.io/t/foo', '1.0.0-20180125'),
image_uploader.discover_tag_from_inspect( image_uploader.discover_tag_from_inspect(
('docker.io/t/foo', '{release}-{version}', sr)) ('docker.io/t/foo', '{release}-{version}', sr, None))
) )
# simple label -> tag with fallback # simple label -> tag with fallback
self.assertEqual( self.assertEqual(
('docker.io/t/foo', 'a'), ('docker.io/t/foo', 'a'),
image_uploader.discover_tag_from_inspect( image_uploader.discover_tag_from_inspect(
('docker.io/t/foo:a', 'bar', sr)) ('docker.io/t/foo:a', 'bar', sr, None))
) )
# templated labels -> tag with fallback # templated labels -> tag with fallback
self.assertEqual( self.assertEqual(
('docker.io/t/foo', 'a'), ('docker.io/t/foo', 'a'),
image_uploader.discover_tag_from_inspect( image_uploader.discover_tag_from_inspect(
('docker.io/t/foo:a', '{releases}-{versions}', sr)) ('docker.io/t/foo:a', '{releases}-{versions}', sr, None))
) )
# Invalid template # Invalid template
self.assertRaises( self.assertRaises(
ImageUploaderException, ImageUploaderException,
image_uploader.discover_tag_from_inspect, image_uploader.discover_tag_from_inspect,
('docker.io/t/foo', '{release}-{version', sr) ('docker.io/t/foo', '{release}-{version', sr, None)
) )
# Missing label in template # Missing label in template
self.assertRaises( self.assertRaises(
ImageUploaderException, ImageUploaderException,
image_uploader.discover_tag_from_inspect, image_uploader.discover_tag_from_inspect,
('docker.io/t/foo', '{releases}-{version}', sr) ('docker.io/t/foo', '{releases}-{version}', sr, None)
) )
# no tag_from_label specified # no tag_from_label specified
self.assertRaises( self.assertRaises(
ImageUploaderException, ImageUploaderException,
image_uploader.discover_tag_from_inspect, image_uploader.discover_tag_from_inspect,
('docker.io/t/foo', None, sr) ('docker.io/t/foo', None, sr, None)
) )
# missing RepoTags entry # missing RepoTags entry
self.assertRaises( self.assertRaises(
ImageUploaderException, ImageUploaderException,
image_uploader.discover_tag_from_inspect, image_uploader.discover_tag_from_inspect,
('docker.io/t/foo', 'build_version', sr) ('docker.io/t/foo', 'build_version', sr, None)
) )
# missing Labels entry # missing Labels entry
self.assertRaises( self.assertRaises(
ImageUploaderException, ImageUploaderException,
image_uploader.discover_tag_from_inspect, image_uploader.discover_tag_from_inspect,
('docker.io/t/foo', 'version', sr) ('docker.io/t/foo', 'version', sr, None)
) )
# inspect call failed # inspect call failed
@ -349,7 +349,7 @@ class TestBaseImageUploader(base.TestCase):
self.assertRaises( self.assertRaises(
ImageUploaderException, ImageUploaderException,
image_uploader.discover_tag_from_inspect, image_uploader.discover_tag_from_inspect,
('docker.io/t/foo', 'rdo_version', sr) ('docker.io/t/foo', 'rdo_version', sr, None)
) )
@mock.patch('concurrent.futures.ThreadPoolExecutor') @mock.patch('concurrent.futures.ThreadPoolExecutor')
@ -375,9 +375,9 @@ class TestBaseImageUploader(base.TestCase):
mock_pool.return_value.map.assert_called_once_with( mock_pool.return_value.map.assert_called_once_with(
image_uploader.discover_tag_from_inspect, image_uploader.discover_tag_from_inspect,
[ [
('docker.io/t/foo', 'rdo_release', set()), ('docker.io/t/foo', 'rdo_release', set(), None),
('docker.io/t/bar', 'rdo_release', set()), ('docker.io/t/bar', 'rdo_release', set(), None),
('docker.io/t/baz', 'rdo_release', set()) ('docker.io/t/baz', 'rdo_release', set(), None)
]) ])
@mock.patch('tripleo_common.image.image_uploader.' @mock.patch('tripleo_common.image.image_uploader.'
@ -450,17 +450,38 @@ class TestBaseImageUploader(base.TestCase):
auth(url1).headers['Authorization'] auth(url1).headers['Authorization']
) )
def test_fix_dockerio_url(self): def test_build_url(self):
url1 = urlparse('docker://docker.io/t/nova-api:latest') url1 = urlparse('docker://docker.io/t/nova-api:latest')
url2 = urlparse('docker://registry-1.docker.io/t/nova-api:latest') url2 = urlparse('docker://registry-1.docker.io/t/nova-api:latest')
url3 = urlparse('docker://192.0.2.1:8787/t/nova-api:latest') url3 = urlparse('docker://192.0.2.1:8787/t/nova-api:latest')
fix = image_uploader.BaseImageUploader._fix_dockerio_url build = image_uploader.BaseImageUploader._build_url
# fix urls # fix urls
self.assertEqual(url2, fix(url1)) self.assertEqual(
'https://registry-1.docker.io/v2/',
build(url1, '/')
)
# no change urls # no change urls
self.assertEqual(url2, fix(url2)) self.assertEqual(
self.assertEqual(url3, fix(url3)) 'http://registry-1.docker.io/v2/t/nova-api/manifests/latest',
build(url2, '/t/nova-api/manifests/latest',
insecure=True)
)
self.assertEqual(
'https://192.0.2.1:8787/v2/t/nova-api/tags/list',
build(url3, '/t/nova-api/tags/list')
)
# test mirrors
mirrors = {
'docker.io': 'http://192.0.2.2:8081/registry-1.docker/'
}
self.assertEqual(
'http://192.0.2.2:8081/registry-1.docker/v2/'
't/nova-api/blobs/asdf1234',
build(url1, '/t/nova-api/blobs/asdf1234',
mirrors=mirrors)
)
def test_inspect(self): def test_inspect(self):
req = self.requests req = self.requests
@ -577,7 +598,8 @@ class TestDockerImageUploader(base.TestCase):
None, None,
None, None,
False, False,
'full') 'full',
None)
) )
) )
@ -616,7 +638,8 @@ class TestDockerImageUploader(base.TestCase):
None, None,
None, None,
False, False,
'full') 'full',
None)
) )
) )
@ -669,7 +692,8 @@ class TestDockerImageUploader(base.TestCase):
'add-foo-plugin', 'add-foo-plugin',
{'foo_version': '1.0.1'}, {'foo_version': '1.0.1'},
False, False,
'partial') 'partial',
None)
) )
) )
@ -712,7 +736,8 @@ class TestDockerImageUploader(base.TestCase):
self.uploader.upload_image, image_uploader.UploadTask( self.uploader.upload_image, image_uploader.UploadTask(
image + ':' + tag, None, push_destination, image + ':' + tag, None, push_destination,
append_tag, 'add-foo-plugin', {'foo_version': '1.0.1'}, append_tag, 'add-foo-plugin', {'foo_version': '1.0.1'},
False, 'full') False, 'full',
None)
) )
self.dockermock.assert_called_once_with( self.dockermock.assert_called_once_with(
@ -743,7 +768,8 @@ class TestDockerImageUploader(base.TestCase):
'add-foo-plugin', 'add-foo-plugin',
{'foo_version': '1.0.1'}, {'foo_version': '1.0.1'},
True, True,
'full') 'full',
None)
) )
self.dockermock.assert_not_called() self.dockermock.assert_not_called()
@ -774,7 +800,8 @@ class TestDockerImageUploader(base.TestCase):
'add-foo-plugin', 'add-foo-plugin',
{'foo_version': '1.0.1'}, {'foo_version': '1.0.1'},
False, False,
'full') 'full',
None)
) )
self.dockermock.assert_not_called() self.dockermock.assert_not_called()
@ -894,7 +921,8 @@ class TestSkopeoImageUploader(base.TestCase):
None, None,
None, None,
False, False,
'full') 'full',
None)
) )
) )
mock_popen.assert_called_once_with([ mock_popen.assert_called_once_with([
@ -958,14 +986,15 @@ class TestSkopeoImageUploader(base.TestCase):
'add-foo-plugin', 'add-foo-plugin',
{'foo_version': '1.0.1'}, {'foo_version': '1.0.1'},
False, False,
'partial') 'partial',
None)
) )
) )
mock_inspect.assert_has_calls([ mock_inspect.assert_has_calls([
mock.call(urlparse( mock.call(urlparse(
'docker://docker.io/t/nova-api:latest' 'docker://docker.io/t/nova-api:latest'
), insecure=False, session=mock.ANY) ), insecure=False, mirrors=None, session=mock.ANY)
]) ])
mock_copy.assert_has_calls([ mock_copy.assert_has_calls([
mock.call( mock.call(
@ -1014,7 +1043,7 @@ class TestSkopeoImageUploader(base.TestCase):
self.uploader.upload_image, image_uploader.UploadTask( self.uploader.upload_image, image_uploader.UploadTask(
image + ':' + tag, None, push_destination, image + ':' + tag, None, push_destination,
append_tag, 'add-foo-plugin', {'foo_version': '1.0.1'}, append_tag, 'add-foo-plugin', {'foo_version': '1.0.1'},
False, 'full') False, 'full', None)
) )
mock_copy.assert_called_once_with( mock_copy.assert_called_once_with(
@ -1042,7 +1071,8 @@ class TestSkopeoImageUploader(base.TestCase):
'add-foo-plugin', 'add-foo-plugin',
{'foo_version': '1.0.1'}, {'foo_version': '1.0.1'},
True, True,
'full') 'full',
None)
) )
mock_ansible.assert_not_called() mock_ansible.assert_not_called()
@ -1072,7 +1102,8 @@ class TestSkopeoImageUploader(base.TestCase):
'add-foo-plugin', 'add-foo-plugin',
{'foo_version': '1.0.1'}, {'foo_version': '1.0.1'},
False, False,
'full') 'full',
None)
) )
mock_ansible.assert_not_called() mock_ansible.assert_not_called()

View File

@ -840,6 +840,7 @@ class TestPrepare(base.TestCase):
env = { env = {
'parameter_defaults': { 'parameter_defaults': {
'LocalContainerRegistry': '192.0.2.1', 'LocalContainerRegistry': '192.0.2.1',
'DockerRegistryMirror': 'http://192.0.2.2/reg/',
'ContainerImagePrepare': [{ 'ContainerImagePrepare': [{
'set': mapping_args, 'set': mapping_args,
'tag_from_label': 'foo', 'tag_from_label': 'foo',
@ -896,7 +897,10 @@ class TestPrepare(base.TestCase):
append_tag=mock.ANY, append_tag=mock.ANY,
modify_role=None, modify_role=None,
modify_only_with_labels=None, modify_only_with_labels=None,
modify_vars=None modify_vars=None,
mirrors={
'docker.io': 'http://192.0.2.2/reg/'
}
), ),
mock.call( mock.call(
excludes=['nova', 'neutron'], excludes=['nova', 'neutron'],
@ -911,7 +915,10 @@ class TestPrepare(base.TestCase):
append_tag=mock.ANY, append_tag=mock.ANY,
modify_role='add-foo-plugin', modify_role='add-foo-plugin',
modify_only_with_labels=['kolla_version'], modify_only_with_labels=['kolla_version'],
modify_vars={'foo_version': '1.0.1'} modify_vars={'foo_version': '1.0.1'},
mirrors={
'docker.io': 'http://192.0.2.2/reg/'
}
) )
]) ])
@ -995,7 +1002,8 @@ class TestPrepare(base.TestCase):
append_tag=mock.ANY, append_tag=mock.ANY,
modify_role=None, modify_role=None,
modify_only_with_labels=None, modify_only_with_labels=None,
modify_vars=None modify_vars=None,
mirrors={}
), ),
mock.call( mock.call(
excludes=['nova', 'neutron'], excludes=['nova', 'neutron'],
@ -1010,11 +1018,13 @@ class TestPrepare(base.TestCase):
append_tag=mock.ANY, append_tag=mock.ANY,
modify_role='add-foo-plugin', modify_role='add-foo-plugin',
modify_only_with_labels=['kolla_version'], modify_only_with_labels=['kolla_version'],
modify_vars={'foo_version': '1.0.1'} modify_vars={'foo_version': '1.0.1'},
mirrors={}
) )
]) ])
mock_im.assert_called_once_with(mock.ANY, dry_run=True, cleanup='full') mock_im.assert_called_once_with(mock.ANY, dry_run=True, cleanup='full',
mirrors={})
self.assertEqual( self.assertEqual(
{ {