From 08ae3286c750c4581f436020ba310bd0f9be4b02 Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Fri, 3 May 2019 14:11:54 -0600 Subject: [PATCH] Define the interface for multi arch image prepare 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. This change defines the interface for supporting multi-arch prepare operations, a later change in this series will implement the support. Blueprint: multiarch-support Change-Id: Ia7b33ab6bec0fabc8632e58807e749b6e2a8c9a3 --- .../multi_arch_image-3c3730cbba95be19.yaml | 9 ++++++ tripleo_common/image/image_uploader.py | 11 +++++-- tripleo_common/image/kolla_builder.py | 21 +++++++++++--- .../tests/image/test_image_uploader.py | 29 ++++++++++++------- .../tests/image/test_kolla_builder.py | 15 ++++++---- 5 files changed, 63 insertions(+), 22 deletions(-) create mode 100644 releasenotes/notes/multi_arch_image-3c3730cbba95be19.yaml diff --git a/releasenotes/notes/multi_arch_image-3c3730cbba95be19.yaml b/releasenotes/notes/multi_arch_image-3c3730cbba95be19.yaml new file mode 100644 index 000000000..7511239dc --- /dev/null +++ b/releasenotes/notes/multi_arch_image-3c3730cbba95be19.yaml @@ -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. \ No newline at end of file diff --git a/tripleo_common/image/image_uploader.py b/tripleo_common/image/image_uploader.py index 63bf63512..0f9b041bb 100644 --- a/tripleo_common/image/image_uploader.py +++ b/tripleo_common/image/image_uploader.py @@ -109,7 +109,8 @@ class ImageUploadManager(BaseImageManager): def __init__(self, config_files=None, dry_run=False, cleanup=CLEANUP_FULL, - mirrors=None, registry_credentials=None): + mirrors=None, registry_credentials=None, + multi_arch=False): if config_files is None: config_files = [] super(ImageUploadManager, self).__init__(config_files) @@ -126,6 +127,7 @@ class ImageUploadManager(BaseImageManager): self.validate_registry_credentials(registry_credentials) for uploader in self.uploaders.values(): uploader.registry_credentials = registry_credentials + self.multi_arch = multi_arch def validate_registry_credentials(self, creds_data): if not isinstance(creds_data, dict): @@ -189,12 +191,13 @@ class ImageUploadManager(BaseImageManager): append_tag = item.get('modify_append_tag') modify_role = item.get('modify_role') modify_vars = item.get('modify_vars') + multi_arch = item.get('multi_arch', self.multi_arch) uploader = self.uploader(uploader) task = UploadTask( image_name, pull_source, push_destination, append_tag, modify_role, modify_vars, self.dry_run, - self.cleanup) + self.cleanup, multi_arch) uploader.add_upload_task(task) for uploader in self.uploaders.values(): @@ -1645,7 +1648,8 @@ class PythonImageUploader(BaseImageUploader): class UploadTask(object): 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.pull_source = pull_source self.push_destination = push_destination @@ -1654,6 +1658,7 @@ class UploadTask(object): self.modify_vars = modify_vars self.dry_run = dry_run self.cleanup = cleanup + self.multi_arch = multi_arch if ':' in image_name: image = image_name.rpartition(':')[0] diff --git a/tripleo_common/image/kolla_builder.py b/tripleo_common/image/kolla_builder.py index 75790fda2..f07703504 100644 --- a/tripleo_common/image/kolla_builder.py +++ b/tripleo_common/image/kolla_builder.py @@ -151,6 +151,7 @@ def container_images_prepare_multi(environment, roles_data, dry_run=False, mirrors['docker.io'] = mirror creds = pd.get('ContainerImageRegistryCredentials') + multi_arch = len(pd.get('AdditionalArchitectures', [])) env_params = {} service_filter = build_service_filter(environment, roles_data) @@ -172,6 +173,10 @@ def container_images_prepare_multi(environment, roles_data, dry_run=False, modify_append_tag = cip_entry.get('modify_append_tag', time.strftime( '-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( excludes=cip_entry.get('excludes'), @@ -188,7 +193,8 @@ def container_images_prepare_multi(environment, roles_data, dry_run=False, modify_vars=modify_vars, modify_only_with_labels=modify_only_with_labels, mirrors=mirrors, - registry_credentials=creds + registry_credentials=creds, + multi_arch=multi_arch ) env_params.update(prepare_data['image_params']) @@ -202,7 +208,8 @@ def container_images_prepare_multi(environment, roles_data, dry_run=False, dry_run=dry_run, cleanup=cleanup, mirrors=mirrors, - registry_credentials=creds + registry_credentials=creds, + multi_arch=multi_arch ) uploader.upload() return env_params @@ -225,7 +232,8 @@ def container_images_prepare(template_file=DEFAULT_TEMPLATE_FILE, output_images_file=None, tag_from_label=None, append_tag=None, modify_role=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 :param template_file: path to Jinja2 file containing all image entries @@ -257,6 +265,8 @@ def container_images_prepare(template_file=DEFAULT_TEMPLATE_FILE, The value is a single-entry dict where the username is the key and the password is the value. + :param multi_arch: boolean whether to prepare every architecture of + each image :returns: dict with entries for the supplied output_env_file or output_images_file """ @@ -287,7 +297,10 @@ def container_images_prepare(template_file=DEFAULT_TEMPLATE_FILE, filter=ffunc, **mapping_args) manager = image_uploader.ImageUploadManager( - mirrors=mirrors, registry_credentials=registry_credentials) + mirrors=mirrors, + registry_credentials=registry_credentials, + multi_arch=multi_arch + ) uploader = manager.uploader('python') images = [i.get('imagename', '') for i in result] diff --git a/tripleo_common/tests/image/test_image_uploader.py b/tripleo_common/tests/image/test_image_uploader.py index 38daf2158..173ab77bc 100644 --- a/tripleo_common/tests/image/test_image_uploader.py +++ b/tripleo_common/tests/image/test_image_uploader.py @@ -857,7 +857,8 @@ class TestSkopeoImageUploader(base.TestCase): None, None, False, - 'full') + 'full', + False) ) ) mock_popen.assert_called_once_with([ @@ -921,7 +922,8 @@ class TestSkopeoImageUploader(base.TestCase): 'add-foo-plugin', {'foo_version': '1.0.1'}, False, - 'partial') + 'partial', + False) ) ) @@ -981,7 +983,7 @@ class TestSkopeoImageUploader(base.TestCase): self.uploader.upload_image, image_uploader.UploadTask( image + ':' + tag, None, push_destination, append_tag, 'add-foo-plugin', {'foo_version': '1.0.1'}, - False, 'full') + False, 'full', False) ) mock_copy.assert_called_once_with( @@ -1009,7 +1011,8 @@ class TestSkopeoImageUploader(base.TestCase): 'add-foo-plugin', {'foo_version': '1.0.1'}, True, - 'full') + 'full', + False) ) mock_ansible.assert_not_called() @@ -1039,7 +1042,8 @@ class TestSkopeoImageUploader(base.TestCase): 'add-foo-plugin', {'foo_version': '1.0.1'}, False, - 'full') + 'full', + False) ) mock_ansible.assert_not_called() @@ -1149,7 +1153,8 @@ class TestPythonImageUploader(base.TestCase): modify_role=None, modify_vars=None, dry_run=False, - cleanup='full' + cleanup='full', + multi_arch=False ) self.assertEqual( @@ -1241,7 +1246,8 @@ class TestPythonImageUploader(base.TestCase): modify_role=None, modify_vars=None, dry_run=False, - cleanup='full' + cleanup='full', + multi_arch=False ) self.assertEqual( @@ -1307,7 +1313,8 @@ class TestPythonImageUploader(base.TestCase): modify_role=None, modify_vars=None, dry_run=False, - cleanup='full' + cleanup='full', + multi_arch=False ) self.assertEqual( @@ -1372,7 +1379,8 @@ class TestPythonImageUploader(base.TestCase): modify_role=None, modify_vars=None, dry_run=False, - cleanup='full' + cleanup='full', + multi_arch=False ) self.assertEqual( @@ -1471,7 +1479,8 @@ class TestPythonImageUploader(base.TestCase): modify_role='add-foo-plugin', modify_vars={'foo_version': '1.0.1'}, dry_run=False, - cleanup='full' + cleanup='full', + multi_arch=False ) source_url = urlparse( diff --git a/tripleo_common/tests/image/test_kolla_builder.py b/tripleo_common/tests/image/test_kolla_builder.py index 68dd5fcb5..795c00518 100644 --- a/tripleo_common/tests/image/test_kolla_builder.py +++ b/tripleo_common/tests/image/test_kolla_builder.py @@ -1104,7 +1104,8 @@ class TestPrepare(base.TestCase): }, registry_credentials={ 'docker.io': {'my_username': 'my_password'} - } + }, + multi_arch=False ), mock.call( excludes=['nova', 'neutron'], @@ -1125,7 +1126,8 @@ class TestPrepare(base.TestCase): }, registry_credentials={ 'docker.io': {'my_username': 'my_password'} - } + }, + multi_arch=False ) ]) @@ -1211,7 +1213,8 @@ class TestPrepare(base.TestCase): modify_only_with_labels=None, modify_vars=None, mirrors={}, - registry_credentials=None + registry_credentials=None, + multi_arch=False ), mock.call( excludes=['nova', 'neutron'], @@ -1228,12 +1231,14 @@ class TestPrepare(base.TestCase): modify_only_with_labels=['kolla_version'], modify_vars={'foo_version': '1.0.1'}, mirrors={}, - registry_credentials=None + registry_credentials=None, + multi_arch=False ) ]) 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( {