Merge "Define the interface for multi arch image prepare"
This commit is contained in:
commit
6087a692f8
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
If the `AdditionalArchitectures` parameter has entries then the container
|
||||||
|
image prepare will prepare images for all architectures instead of just
|
||||||
|
the default one. A new boolean field `multi_arch` can also be set in
|
||||||
|
`ContainerImagePrepare` entries to determine the multi arch behaviour for
|
||||||
|
images in that entry. If any entry sets a `multi_arch` value then
|
||||||
|
`AdditionalArchitectures` is ignored.
|
@ -109,7 +109,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, registry_credentials=None):
|
mirrors=None, registry_credentials=None,
|
||||||
|
multi_arch=False):
|
||||||
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)
|
||||||
@ -126,6 +127,7 @@ class ImageUploadManager(BaseImageManager):
|
|||||||
self.validate_registry_credentials(registry_credentials)
|
self.validate_registry_credentials(registry_credentials)
|
||||||
for uploader in self.uploaders.values():
|
for uploader in self.uploaders.values():
|
||||||
uploader.registry_credentials = registry_credentials
|
uploader.registry_credentials = registry_credentials
|
||||||
|
self.multi_arch = multi_arch
|
||||||
|
|
||||||
def validate_registry_credentials(self, creds_data):
|
def validate_registry_credentials(self, creds_data):
|
||||||
if not isinstance(creds_data, dict):
|
if not isinstance(creds_data, dict):
|
||||||
@ -189,12 +191,13 @@ class ImageUploadManager(BaseImageManager):
|
|||||||
append_tag = item.get('modify_append_tag')
|
append_tag = item.get('modify_append_tag')
|
||||||
modify_role = item.get('modify_role')
|
modify_role = item.get('modify_role')
|
||||||
modify_vars = item.get('modify_vars')
|
modify_vars = item.get('modify_vars')
|
||||||
|
multi_arch = item.get('multi_arch', self.multi_arch)
|
||||||
|
|
||||||
uploader = self.uploader(uploader)
|
uploader = self.uploader(uploader)
|
||||||
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, multi_arch)
|
||||||
uploader.add_upload_task(task)
|
uploader.add_upload_task(task)
|
||||||
|
|
||||||
for uploader in self.uploaders.values():
|
for uploader in self.uploaders.values():
|
||||||
@ -1645,7 +1648,8 @@ class PythonImageUploader(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,
|
||||||
|
multi_arch):
|
||||||
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
|
||||||
@ -1654,6 +1658,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.multi_arch = multi_arch
|
||||||
|
|
||||||
if ':' in image_name:
|
if ':' in image_name:
|
||||||
image = image_name.rpartition(':')[0]
|
image = image_name.rpartition(':')[0]
|
||||||
|
@ -157,6 +157,7 @@ def container_images_prepare_multi(environment, roles_data, dry_run=False,
|
|||||||
mirrors['docker.io'] = mirror
|
mirrors['docker.io'] = mirror
|
||||||
|
|
||||||
creds = pd.get('ContainerImageRegistryCredentials')
|
creds = pd.get('ContainerImageRegistryCredentials')
|
||||||
|
multi_arch = len(pd.get('AdditionalArchitectures', []))
|
||||||
|
|
||||||
env_params = {}
|
env_params = {}
|
||||||
service_filter = build_service_filter(environment, roles_data)
|
service_filter = build_service_filter(environment, roles_data)
|
||||||
@ -178,6 +179,10 @@ def container_images_prepare_multi(environment, roles_data, dry_run=False,
|
|||||||
modify_append_tag = cip_entry.get('modify_append_tag',
|
modify_append_tag = cip_entry.get('modify_append_tag',
|
||||||
time.strftime(
|
time.strftime(
|
||||||
'-modified-%Y%m%d%H%M%S'))
|
'-modified-%Y%m%d%H%M%S'))
|
||||||
|
if multi_arch and 'multi_arch' in cip_entry:
|
||||||
|
# individual entry sets multi_arch,
|
||||||
|
# so set global multi_arch to False
|
||||||
|
multi_arch = False
|
||||||
|
|
||||||
prepare_data = container_images_prepare(
|
prepare_data = container_images_prepare(
|
||||||
excludes=cip_entry.get('excludes'),
|
excludes=cip_entry.get('excludes'),
|
||||||
@ -194,7 +199,8 @@ def container_images_prepare_multi(environment, roles_data, dry_run=False,
|
|||||||
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,
|
mirrors=mirrors,
|
||||||
registry_credentials=creds
|
registry_credentials=creds,
|
||||||
|
multi_arch=multi_arch
|
||||||
)
|
)
|
||||||
env_params.update(prepare_data['image_params'])
|
env_params.update(prepare_data['image_params'])
|
||||||
|
|
||||||
@ -208,7 +214,8 @@ def container_images_prepare_multi(environment, roles_data, dry_run=False,
|
|||||||
dry_run=dry_run,
|
dry_run=dry_run,
|
||||||
cleanup=cleanup,
|
cleanup=cleanup,
|
||||||
mirrors=mirrors,
|
mirrors=mirrors,
|
||||||
registry_credentials=creds
|
registry_credentials=creds,
|
||||||
|
multi_arch=multi_arch
|
||||||
)
|
)
|
||||||
uploader.upload()
|
uploader.upload()
|
||||||
return env_params
|
return env_params
|
||||||
@ -231,7 +238,8 @@ def container_images_prepare(template_file=DEFAULT_TEMPLATE_FILE,
|
|||||||
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, registry_credentials=None):
|
mirrors=None, registry_credentials=None,
|
||||||
|
multi_arch=False):
|
||||||
"""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
|
||||||
@ -263,6 +271,8 @@ def container_images_prepare(template_file=DEFAULT_TEMPLATE_FILE,
|
|||||||
The value is a single-entry dict where the
|
The value is a single-entry dict where the
|
||||||
username is the key and the password is the
|
username is the key and the password is the
|
||||||
value.
|
value.
|
||||||
|
:param multi_arch: boolean whether to prepare every architecture of
|
||||||
|
each image
|
||||||
: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
|
||||||
"""
|
"""
|
||||||
@ -293,7 +303,10 @@ def container_images_prepare(template_file=DEFAULT_TEMPLATE_FILE,
|
|||||||
filter=ffunc, **mapping_args)
|
filter=ffunc, **mapping_args)
|
||||||
|
|
||||||
manager = image_uploader.ImageUploadManager(
|
manager = image_uploader.ImageUploadManager(
|
||||||
mirrors=mirrors, registry_credentials=registry_credentials)
|
mirrors=mirrors,
|
||||||
|
registry_credentials=registry_credentials,
|
||||||
|
multi_arch=multi_arch
|
||||||
|
)
|
||||||
uploader = manager.uploader('python')
|
uploader = manager.uploader('python')
|
||||||
images = [i.get('imagename', '') for i in result]
|
images = [i.get('imagename', '') for i in result]
|
||||||
|
|
||||||
|
@ -857,7 +857,8 @@ class TestSkopeoImageUploader(base.TestCase):
|
|||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
False,
|
False,
|
||||||
'full')
|
'full',
|
||||||
|
False)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
mock_popen.assert_called_once_with([
|
mock_popen.assert_called_once_with([
|
||||||
@ -921,7 +922,8 @@ class TestSkopeoImageUploader(base.TestCase):
|
|||||||
'add-foo-plugin',
|
'add-foo-plugin',
|
||||||
{'foo_version': '1.0.1'},
|
{'foo_version': '1.0.1'},
|
||||||
False,
|
False,
|
||||||
'partial')
|
'partial',
|
||||||
|
False)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -981,7 +983,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', False)
|
||||||
)
|
)
|
||||||
|
|
||||||
mock_copy.assert_called_once_with(
|
mock_copy.assert_called_once_with(
|
||||||
@ -1009,7 +1011,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',
|
||||||
|
False)
|
||||||
)
|
)
|
||||||
|
|
||||||
mock_ansible.assert_not_called()
|
mock_ansible.assert_not_called()
|
||||||
@ -1039,7 +1042,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',
|
||||||
|
False)
|
||||||
)
|
)
|
||||||
|
|
||||||
mock_ansible.assert_not_called()
|
mock_ansible.assert_not_called()
|
||||||
@ -1149,7 +1153,8 @@ class TestPythonImageUploader(base.TestCase):
|
|||||||
modify_role=None,
|
modify_role=None,
|
||||||
modify_vars=None,
|
modify_vars=None,
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
cleanup='full'
|
cleanup='full',
|
||||||
|
multi_arch=False
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@ -1241,7 +1246,8 @@ class TestPythonImageUploader(base.TestCase):
|
|||||||
modify_role=None,
|
modify_role=None,
|
||||||
modify_vars=None,
|
modify_vars=None,
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
cleanup='full'
|
cleanup='full',
|
||||||
|
multi_arch=False
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@ -1307,7 +1313,8 @@ class TestPythonImageUploader(base.TestCase):
|
|||||||
modify_role=None,
|
modify_role=None,
|
||||||
modify_vars=None,
|
modify_vars=None,
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
cleanup='full'
|
cleanup='full',
|
||||||
|
multi_arch=False
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@ -1372,7 +1379,8 @@ class TestPythonImageUploader(base.TestCase):
|
|||||||
modify_role=None,
|
modify_role=None,
|
||||||
modify_vars=None,
|
modify_vars=None,
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
cleanup='full'
|
cleanup='full',
|
||||||
|
multi_arch=False
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@ -1471,7 +1479,8 @@ class TestPythonImageUploader(base.TestCase):
|
|||||||
modify_role='add-foo-plugin',
|
modify_role='add-foo-plugin',
|
||||||
modify_vars={'foo_version': '1.0.1'},
|
modify_vars={'foo_version': '1.0.1'},
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
cleanup='full'
|
cleanup='full',
|
||||||
|
multi_arch=False
|
||||||
)
|
)
|
||||||
|
|
||||||
source_url = urlparse(
|
source_url = urlparse(
|
||||||
|
@ -1104,7 +1104,8 @@ class TestPrepare(base.TestCase):
|
|||||||
},
|
},
|
||||||
registry_credentials={
|
registry_credentials={
|
||||||
'docker.io': {'my_username': 'my_password'}
|
'docker.io': {'my_username': 'my_password'}
|
||||||
}
|
},
|
||||||
|
multi_arch=False
|
||||||
),
|
),
|
||||||
mock.call(
|
mock.call(
|
||||||
excludes=['nova', 'neutron'],
|
excludes=['nova', 'neutron'],
|
||||||
@ -1125,7 +1126,8 @@ class TestPrepare(base.TestCase):
|
|||||||
},
|
},
|
||||||
registry_credentials={
|
registry_credentials={
|
||||||
'docker.io': {'my_username': 'my_password'}
|
'docker.io': {'my_username': 'my_password'}
|
||||||
}
|
},
|
||||||
|
multi_arch=False
|
||||||
)
|
)
|
||||||
])
|
])
|
||||||
|
|
||||||
@ -1211,7 +1213,8 @@ class TestPrepare(base.TestCase):
|
|||||||
modify_only_with_labels=None,
|
modify_only_with_labels=None,
|
||||||
modify_vars=None,
|
modify_vars=None,
|
||||||
mirrors={},
|
mirrors={},
|
||||||
registry_credentials=None
|
registry_credentials=None,
|
||||||
|
multi_arch=False
|
||||||
),
|
),
|
||||||
mock.call(
|
mock.call(
|
||||||
excludes=['nova', 'neutron'],
|
excludes=['nova', 'neutron'],
|
||||||
@ -1228,12 +1231,14 @@ class TestPrepare(base.TestCase):
|
|||||||
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={},
|
mirrors={},
|
||||||
registry_credentials=None
|
registry_credentials=None,
|
||||||
|
multi_arch=False
|
||||||
)
|
)
|
||||||
])
|
])
|
||||||
|
|
||||||
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={}, registry_credentials=None)
|
mirrors={}, registry_credentials=None,
|
||||||
|
multi_arch=False)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user