Merge "Filter container images by deployed services"

This commit is contained in:
Jenkins 2017-08-21 09:13:07 +00:00 committed by Gerrit Code Review
commit 930f64cbe7
3 changed files with 65 additions and 5 deletions

View File

@ -0,0 +1,5 @@
---
features:
- The "openstack overcloud container image prepare" command can now filter
the image list by the containerized services being deployed. This is done by
specifying the heat environment files which enable containerized services.

View File

@ -97,13 +97,23 @@ class TestContainerImagePrepare(TestPluginV1):
)
@mock.patch('tripleo_common.image.kolla_builder.KollaImageBuilder')
def test_container_image_prepare(self, mock_builder):
@mock.patch('heatclient.common.template_utils.'
'process_multiple_environments_and_files')
def test_container_image_prepare(self, pmef, mock_builder):
temp = tempfile.mkdtemp()
self.addCleanup(shutil.rmtree, temp)
images_file = os.path.join(temp, 'overcloud_containers.yaml')
env_file = os.path.join(temp, 'containers_env.yaml')
tmpl_file = os.path.join(temp, 'overcloud_containers.yaml.j2')
aodh_file = os.path.join(temp, 'docker', 'services',
'overcloud_containers.yaml.j2')
resource_registry = {'resource_registry': {
'OS::TripleO::Services::AodhEvaluator': aodh_file,
'OS::TripleO::Services::AodhApi': aodh_file
}}
pmef.return_value = None, resource_registry
arglist = [
'--template-file',
@ -126,6 +136,8 @@ class TestContainerImagePrepare(TestPluginV1):
'ceph_image=mydaemon',
'--set',
'ceph_tag=mytag',
'-e',
'environment/docker.yaml'
]
self.cmd.app.command_options = arglist
verifylist = []
@ -133,9 +145,16 @@ class TestContainerImagePrepare(TestPluginV1):
cift.return_value = [{
'imagename': 'tripleo/os-aodh-apifoo:passed-ci',
'params': ['DockerAodhApiImage', 'DockerAodhConfigImage'],
'services': [
'OS::TripleO::Services::AodhApi',
'OS::TripleO::Services::AodhEvaluator',
],
}, {
'imagename': 'tripleo/os-heat-apifoo:passed-ci',
'params': ['DockerHeatApiImage'],
'imagename': 'tripleo/os-aodh-evaluatorfoo:passed-ci',
'params': ['DockerAodhEvaluatorImage'],
'services': [
'OS::TripleO::Services::AodhEvaluator',
],
}]
mock_builder.return_value.container_images_from_template = cift
@ -145,6 +164,7 @@ class TestContainerImagePrepare(TestPluginV1):
self.cmd.take_action(parsed_args)
mock_builder.assert_called_once_with([tmpl_file])
pmef.assert_called_once_with(['environment/docker.yaml'])
cift.assert_called_once_with(
filter=mock.ANY,
name_prefix='os-',
@ -159,14 +179,15 @@ class TestContainerImagePrepare(TestPluginV1):
'container_images': [{
'imagename': 'tripleo/os-aodh-apifoo:passed-ci',
}, {
'imagename': 'tripleo/os-heat-apifoo:passed-ci',
'imagename': 'tripleo/os-aodh-evaluatorfoo:passed-ci',
}]
}
env_data = {
'parameter_defaults': {
'DockerAodhApiImage': 'tripleo/os-aodh-apifoo:passed-ci',
'DockerAodhConfigImage': 'tripleo/os-aodh-apifoo:passed-ci',
'DockerHeatApiImage': 'tripleo/os-heat-apifoo:passed-ci',
'DockerAodhEvaluatorImage':
'tripleo/os-aodh-evaluatorfoo:passed-ci'
}
}
with open(images_file) as f:

View File

@ -21,6 +21,7 @@ import re
import sys
import tempfile
from heatclient.common import template_utils
from osc_lib.command import command
from osc_lib import exceptions as oscexc
from osc_lib.i18n import _
@ -243,6 +244,14 @@ class PrepareImageFiles(command.Command):
help=_("File to write resulting image entries to, as well as "
"stdout. Any existing file will be overwritten."),
)
parser.add_argument(
'--service-environment-file', '-e', metavar='<file path>',
action='append', dest='environment_files',
help=_('Environment files specifying which services are '
'containerized. Entries will be filtered to only contain '
'images used by containerized services. (Can be specified '
'more than once.)')
)
parser.add_argument(
"--env-file",
dest="env_file",
@ -277,6 +286,21 @@ class PrepareImageFiles(command.Command):
yaml.safe_dump({'parameter_defaults': params}, f,
default_flow_style=False)
def build_service_filter(self, environment_files):
if not environment_files:
return None
service_filter = set()
env_files, env = (
template_utils.process_multiple_environments_and_files(
environment_files))
for service, env_path in env.get('resource_registry', {}).items():
# Use the template path to determine if it represents a
# containerized service
if '/docker/services/' in env_path:
service_filter.add(service)
return service_filter
def take_action(self, parsed_args):
self.log.debug("take_action(%s)" % parsed_args)
subs = {
@ -287,11 +311,19 @@ class PrepareImageFiles(command.Command):
}
self.parse_set_values(subs, parsed_args.set)
service_filter = self.build_service_filter(
parsed_args.environment_files)
def ffunc(entry):
imagename = entry.get('imagename', '')
for p in parsed_args.excludes:
if re.search(p, imagename):
return None
if service_filter is not None:
# check the entry is for a service being deployed
image_services = set(entry.get('services', []))
if not service_filter.intersection(image_services):
return None
if parsed_args.pull_source:
entry['pull_source'] = parsed_args.pull_source
if parsed_args.push_destination:
@ -307,6 +339,8 @@ class PrepareImageFiles(command.Command):
if 'params' in entry:
for p in entry.pop('params'):
params[p] = imagename
if 'services' in entry:
del(entry['services'])
if parsed_args.env_file:
self.write_env_file(params, parsed_args.env_file)