Filter out disabled services from prepare command

Previously, the `openstack overcloud container image prepare` looked
only at the resource registry -- checking if a resource pointed to
a containerized service -- to determine which images to use without
looking at the list of services that are enabled or not per roles.

This commit introduces a new '--roles-file' option to the  command to
specify the path to the roles file when not using the default.

Closes-Bug: #1714296
Change-Id: I0188df062bd341dcf4791bfa9c9d0f1ad7f9396e
(cherry picked from commit 954ed90435)
This commit is contained in:
Martin André 2017-08-31 17:38:24 +02:00 committed by Alex Schultz
parent 0bd00bba4a
commit d8eeff8301
2 changed files with 75 additions and 7 deletions

View File

@ -74,6 +74,43 @@ class TestContainerImagePrepare(TestPluginV1):
# Get the command object to test
self.cmd = container_image.PrepareImageFiles(self.app, None)
def test_get_enabled_services(self):
temp = tempfile.mkdtemp()
self.addCleanup(shutil.rmtree, temp)
resource_registry = {'parameter_defaults': {
'RoleDisabledViaEnvironmentCount': 0,
'RoleOverwrittenViaEnvironmentServices': [
'OS::TripleO::Services::FromResourceRegistry'
]
}}
roles_file = '/foo/roles_data.yaml'
roles_yaml = '''
- name: EnabledRole
CountDefault: 1
ServicesDefault:
- OS::TripleO::Services::AodhEvaluator
- name: RoleDisabledViaRolesData
CountDefault: 0
ServicesDefault:
- OS::TripleO::Services::AodhApi
- name: RoleDisabledViaEnvironment
CountDefault: 1
ServicesDefault:
- OS::TripleO::Services::Disabled
- name: RoleOverwrittenViaEnvironment
CountDefault: 1
ServicesDefault:
- OS::TripleO::Services::Overwritten
'''
mock_open_context = mock.mock_open(read_data=roles_yaml)
with mock.patch('six.moves.builtins.open', mock_open_context):
enabled_services = self.cmd.get_enabled_services(resource_registry,
roles_file)
mock_open_context.assert_called_once_with(roles_file)
self.assertEqual(set(['OS::TripleO::Services::AodhEvaluator',
'OS::TripleO::Services::FromResourceRegistry']),
enabled_services)
@mock.patch('tripleo_common.image.kolla_builder.KollaImageBuilder')
def test_container_image_prepare_noargs(self, mock_builder):
arglist = []
@ -106,8 +143,7 @@ class TestContainerImagePrepare(TestPluginV1):
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')
aodh_file = os.path.join(temp, 'docker', 'services', 'aodh.yaml')
resource_registry = {'resource_registry': {
'OS::TripleO::Services::AodhEvaluator': aodh_file,

View File

@ -29,6 +29,8 @@ import yaml
from tripleo_common.image import image_uploader
from tripleo_common.image import kolla_builder
from tripleoclient import constants
class UploadImage(command.Command):
"""Push overcloud container images to registries."""
@ -162,6 +164,8 @@ class PrepareImageFiles(command.Command):
template_file = os.path.join(sys.prefix, 'share', 'tripleo-common',
'container-images',
'overcloud_containers.yaml.j2')
roles_file = os.path.join(constants.TRIPLEO_HEAT_TEMPLATES,
constants.OVERCLOUD_ROLES_FILE)
parser.add_argument(
"--template-file",
dest="template_file",
@ -251,6 +255,12 @@ class PrepareImageFiles(command.Command):
help=_("File to write heat environment file which specifies all "
"image parameters. Any existing file will be overwritten."),
)
parser.add_argument(
'--roles-file', '-r', dest='roles_file',
default=roles_file,
help=_('Roles file, overrides the default %s'
) % constants.OVERCLOUD_ROLES_FILE
)
return parser
def write_env_file(self, params, env_file):
@ -266,20 +276,42 @@ class PrepareImageFiles(command.Command):
yaml.safe_dump({'parameter_defaults': params}, f,
default_flow_style=False)
def build_service_filter(self, environment_files):
def get_enabled_services(self, environment, roles_file):
enabled_services = set()
try:
roles_data = yaml.safe_load(open(roles_file).read())
except IOError:
return enabled_services
parameter_defaults = environment.get('parameter_defaults', {})
for role in roles_data:
count = parameter_defaults.get('%sCount' % role['name'],
role.get('CountDefault', 0))
if count > 0:
enabled_services.update(
parameter_defaults.get('%sServices' % role['name'],
role.get('ServicesDefault', [])))
return enabled_services
def build_service_filter(self, environment_files, roles_file):
# Do not filter unless asked for it
if not environment_files:
return None
service_filter = set()
env_files, env = (
template_utils.process_multiple_environments_and_files(
environment_files))
enabled_services = self.get_enabled_services(env, roles_file)
containerized_services = set()
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
containerized_services.add(service)
return containerized_services.intersection(enabled_services)
def take_action(self, parsed_args):
self.log.debug("take_action(%s)" % parsed_args)
@ -291,7 +323,7 @@ class PrepareImageFiles(command.Command):
}
service_filter = self.build_service_filter(
parsed_args.environment_files)
parsed_args.environment_files, parsed_args.roles_file)
def ffunc(entry):
imagename = entry.get('imagename', '')