Merge "Filter container images by deployed services"
This commit is contained in:
commit
930f64cbe7
5
releasenotes/notes/prepare-service-4281d7358be7450a.yaml
Normal file
5
releasenotes/notes/prepare-service-4281d7358be7450a.yaml
Normal 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.
|
@ -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:
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user