Perform multiple container image prepares and merge result

Given the full heat environment and roles data, perform multiple image
prepare operations. The data to drive the multiple prepares is taken
from the ContainerImagePrepare parameter in the provided environment.
If push_destination is specified, uploads will be performed during the
preparation.

This will be used by undercloud install and workflow driven image
prepare

Change-Id: Ife6b6eb753272e3b074cf14669642af140986fc4
Blueprint: container-prepare-workflow
This commit is contained in:
Steve Baker
2018-03-21 12:06:23 +13:00
committed by Emilien Macchi
parent 4c4b39577d
commit 3651884d8b
2 changed files with 137 additions and 0 deletions

View File

@@ -20,6 +20,7 @@ import os
import re
import subprocess
import sys
import tempfile
import yaml
from tripleo_common.image import base
@@ -83,6 +84,57 @@ def build_service_filter(environment, roles_data):
return containerized_services.intersection(enabled_services)
def container_images_prepare_multi(environment, roles_data):
"""Perform multiple container image prepares and merge result
Given the full heat environment and roles data, perform multiple image
prepare operations. The data to drive the multiple prepares is taken from
the ContainerImagePrepare parameter in the provided environment. If
push_destination is specified, uploads will be performed during the
preparation.
:param environment: Heat environment for deployment
:param roles_data: Roles file data used to filter services
:returns: dict containing merged container image parameters from all
prepare operations
"""
pd = environment.get('parameter_defaults', {})
cip = pd.get('ContainerImagePrepare')
if not cip:
return
env_params = {}
service_filter = build_service_filter(environment, roles_data)
for cip_entry in cip:
mapping_args = cip_entry.get('set')
push_destination = cip_entry.get('push_destination')
pull_source = cip_entry.get('pull_source')
prepare_data = container_images_prepare(
excludes=cip_entry.get('excludes'),
service_filter=service_filter,
pull_source=pull_source,
push_destination=push_destination,
mapping_args=mapping_args,
output_env_file='image_params',
output_images_file='upload_data',
tag_from_label=cip_entry.get('tag_from_label'),
)
env_params.update(prepare_data['image_params'])
if push_destination or pull_source:
with tempfile.NamedTemporaryFile(mode='w') as f:
yaml.safe_dump({
'container_images': prepare_data['upload_data']
}, f)
uploader = image_uploader.ImageUploadManager(
[f.name], verbose=True)
uploader.upload()
return env_params
def container_images_prepare_defaults():
"""Return default dict for prepare substitutions

View File

@@ -649,3 +649,88 @@ class TestPrepare(base.TestCase):
}
])
)
@mock.patch('tripleo_common.image.kolla_builder.container_images_prepare')
@mock.patch('tripleo_common.image.image_uploader.ImageUploadManager',
autospec=True)
def test_container_images_prepare_multi(self, mock_im, mock_cip):
mapping_args = {
'namespace': 't',
'name_prefix': '',
'name_suffix': '',
'tag': 'l',
}
env = {
'parameter_defaults': {
'ContainerImagePrepare': [{
'set': mapping_args,
'tag_from_label': 'foo',
}, {
'set': mapping_args,
'tag_from_label': 'bar',
'excludes': ['nova', 'neutron'],
'push_destination': '192.0.2.1:8787'
}]
}
}
roles_data = []
mock_cip.side_effect = [
{
'image_params': {
'FooImage': 't/foo:latest',
'BarImage': 't/bar:latest',
'BazImage': 't/baz:latest',
'BinkImage': 't/bink:latest'
},
'upload_data': []
}, {
'image_params': {
'BarImage': 't/bar:1.0',
'BazImage': 't/baz:1.0'
},
'upload_data': [{
'imagename': 't/bar:1.0',
'push_destination': '192.0.2.1:8787'
}, {
'imagename': 't/baz:1.0',
'push_destination': '192.0.2.1:8787'
}]
},
]
image_params = kb.container_images_prepare_multi(env, roles_data)
mock_cip.assert_has_calls([
mock.call(
excludes=None,
mapping_args=mapping_args,
output_env_file='image_params',
output_images_file='upload_data',
pull_source=None,
push_destination=None,
service_filter=set([]),
tag_from_label='foo'
),
mock.call(
excludes=['nova', 'neutron'],
mapping_args=mapping_args,
output_env_file='image_params',
output_images_file='upload_data',
pull_source=None,
push_destination='192.0.2.1:8787',
service_filter=set([]),
tag_from_label='bar'
)
])
mock_im.assert_called_once()
self.assertEqual(
{
'BarImage': 't/bar:1.0',
'BazImage': 't/baz:1.0',
'BinkImage': 't/bink:latest',
'FooImage': 't/foo:latest'
},
image_params
)