diff --git a/tripleoclient/tests/test_utils.py b/tripleoclient/tests/test_utils.py index 1d7ad563a..cd9bf2aa3 100644 --- a/tripleoclient/tests/test_utils.py +++ b/tripleoclient/tests/test_utils.py @@ -2197,7 +2197,7 @@ class TestProhibitedOverrides(base.TestCommand): class TestParseContainerImagePrepare(TestCase): fake_env = {'parameter_defaults': {'ContainerImagePrepare': - [{'push_destination': True, 'set': + [{'push_destination': 'foo.com', 'set': {'ceph_image': 'ceph', 'ceph_namespace': 'quay.io:443/ceph', 'ceph_tag': 'latest'}}], @@ -2218,6 +2218,22 @@ class TestParseContainerImagePrepare(TestCase): cfgfile.name) self.assertEqual(reg_actual, reg_expected) + def test_parse_container_image_prepare_push_dest(self): + key = 'ContainerImagePrepare' + keys = ['ceph_namespace', 'ceph_image', 'ceph_tag'] + push_sub_keys = ['ceph_namespace'] + reg_expected = {'ceph_image': 'ceph', + 'ceph_namespace': 'foo.com/ceph', + 'ceph_tag': 'latest', + 'push_destination_boolean': True} + with tempfile.NamedTemporaryFile(mode='w') as cfgfile: + yaml.safe_dump(self.fake_env, cfgfile) + reg_actual = \ + utils.parse_container_image_prepare(key, keys, + cfgfile.name, + push_sub_keys) + self.assertEqual(reg_actual, reg_expected) + def test_parse_container_image_prepare_credentials(self): key = 'ContainerImageRegistryCredentials' keys = ['quay.io:443/ceph'] diff --git a/tripleoclient/tests/v2/overcloud_ceph/test_overcloud_ceph.py b/tripleoclient/tests/v2/overcloud_ceph/test_overcloud_ceph.py index a581f07eb..224ecf222 100644 --- a/tripleoclient/tests/v2/overcloud_ceph/test_overcloud_ceph.py +++ b/tripleoclient/tests/v2/overcloud_ceph/test_overcloud_ceph.py @@ -44,6 +44,7 @@ class TestOvercloudCephDeploy(fakes.FakePlaybookExecution): arglist = ['deployed-metal.yaml', '--yes', '--stack', 'overcloud', '--skip-user-create', + '--skip-hosts-config', '--cephadm-ssh-user', 'jimmy', '--output', 'deployed-ceph.yaml', '--container-namespace', 'quay.io/ceph', diff --git a/tripleoclient/utils.py b/tripleoclient/utils.py index e720be9fe..26060570f 100644 --- a/tripleoclient/utils.py +++ b/tripleoclient/utils.py @@ -69,6 +69,7 @@ from tenacity import retry from tenacity.stop import stop_after_attempt, stop_after_delay from tenacity.wait import wait_fixed +from tripleo_common.image import image_uploader from tripleo_common.image import kolla_builder from tripleo_common.utils import heat as tc_heat_utils from tripleo_common.utils import stack as stack_utils @@ -2910,7 +2911,8 @@ def check_prohibited_overrides(protected_overrides, user_environments): def parse_container_image_prepare(tht_key='ContainerImagePrepare', - keys=[], source=None): + keys=[], source=None, + push_sub_keys=[]): """Extracts key/value pairs from list of keys in source file If keys=[foo,bar] and source is the following, then return {foo: 1, bar: 2} @@ -2918,6 +2920,7 @@ def parse_container_image_prepare(tht_key='ContainerImagePrepare', parameter_defaults: ContainerImagePrepare: - tag_from_label: grault + push_destination: quux.com set: foo: 1 bar: 2 @@ -2925,6 +2928,10 @@ def parse_container_image_prepare(tht_key='ContainerImagePrepare', ContainerImageRegistryCredentials: 'quay.io': {'quay_username': 'quay_password'} + If push_destination tag is present as above and push_sub_keys + contains 'namespace', then the returned dictionary d will + contain d['namespace'] = 'quux.com/garply'. + Alternatively, if tht_key='ContainerImageRegistryCredentials' and keys=['quay.io/garply'] for the above, then return the following: @@ -2937,6 +2944,7 @@ def parse_container_image_prepare(tht_key='ContainerImagePrepare', :param tht_key: string of a THT parameter (only 2 options) :param keys: list of keys to extract :param source: (string) path to container_image_prepare_defaults.yaml + :param push_sub_keys: list of keys to have substitutions if push_desination :return: dictionary """ @@ -2956,12 +2964,33 @@ def parse_container_image_prepare(tht_key='ContainerImagePrepare', if tht_key == 'ContainerImagePrepare': try: + push = '' tag_list = images['parameter_defaults'][tht_key] for key in keys: for tag in tag_list: + if 'push_destination' in tag: + # substitute discovered registry + # if push_destination is set to true + if isinstance(tag['push_destination'], bool) and \ + tag['push_destination']: + push = image_uploader.get_undercloud_registry() + if len(push_sub_keys) > 0: + image_map['push_destination_boolean'] = True + elif isinstance(tag['push_destination'], str): + push = tag['push_destination'] + if len(push_sub_keys) > 0: + image_map['push_destination_boolean'] = True + elif len(push_sub_keys) > 0: + image_map['push_destination_boolean'] = False if 'set' in tag: if key in tag['set']: image_map[key] = tag['set'][key] + if len(push) > 0 and key in push_sub_keys: + # replace the host portion of the imagename + # with the push_destination, since that is + # where they will be uploaded to + image = image_map[key].partition('/')[2] + image_map[key] = '/'.join((push, image)) except KeyError: raise RuntimeError( "The expected parameter_defaults and %s are not " diff --git a/tripleoclient/v2/overcloud_ceph.py b/tripleoclient/v2/overcloud_ceph.py index 7cbcaf28f..9cc881803 100644 --- a/tripleoclient/v2/overcloud_ceph.py +++ b/tripleoclient/v2/overcloud_ceph.py @@ -95,6 +95,19 @@ class OvercloudCephDeploy(command.Command): "This user is necessary to deploy but " "may be created in a separate step via " "'openstack overcloud ceph user enable'.")) + parser.add_argument('--skip-hosts-config', default=False, + action='store_true', + help=_("Do not update /etc/hosts on deployed " + "servers. By default this is configured " + "so overcloud nodes can reach each other " + "and the undercloud by name.")) + parser.add_argument('--skip-container-registry-config', default=False, + action='store_true', + help=_("Do not update " + "/etc/containers/registries.conf on " + "deployed servers. By default this is " + "configured so overcloud nodes can pull " + "containers from the undercloud registry.")) parser = arg_parse_common(parser) parser.add_argument('--roles-data', help=_( @@ -330,11 +343,14 @@ class OvercloudCephDeploy(command.Command): os.path.abspath(parsed_args.crush_hierarchy) # optional container vars to pass to playbook keys = ['ceph_namespace', 'ceph_image', 'ceph_tag'] + push_sub_keys = ['ceph_namespace'] key = 'ContainerImagePrepare' container_dict = \ oooutils.parse_container_image_prepare(key, keys, parsed_args. - container_image_prepare) + container_image_prepare, + push_sub_keys) + extra_vars['tripleo_cephadm_container_ns'] = \ parsed_args.container_namespace or \ container_dict['ceph_namespace'] @@ -378,16 +394,75 @@ class OvercloudCephDeploy(command.Command): extra_vars['tripleo_cephadm_registry_username'] = \ parsed_args.registry_username - if parsed_args.skip_user_create: - skip_tags = 'cephadm_ssh_user' - else: - skip_tags = '' - if parsed_args.cephadm_ssh_user: extra_vars["tripleo_cephadm_ssh_user"] = \ parsed_args.cephadm_ssh_user - # call the playbook + skip_tags = [] + if parsed_args.skip_user_create: + skip_tags.append('cephadm_ssh_user') + + if not parsed_args.skip_hosts_config: + # call playbook to set /etc/hosts + uc_host_list = [oooutils.get_undercloud_host_entry()] + ctlplane_map = oooutils.get_ctlplane_attrs() + short_name = oooutils.get_hostname(short=True) + long_name = oooutils.get_hostname(short=False) + dns_domain = long_name.replace(short_name+'.', '') + hosts_extra_vars = dict( + tripleo_hosts_entries_undercloud_hosts_entries=uc_host_list, + tripleo_hosts_entries_overcloud_hosts_entries=[], + tripleo_hosts_entries_vip_hosts_entries=[], + tripleo_hosts_entries_extra_hosts_entries=[], + tripleo_stack_name=parsed_args.stack, + hostname_resolve_network=ctlplane_map['network']['name'], + cloud_domain=dns_domain, + ) + self.log.debug("Adding undercloud host entry " + "to overcloud /etc/hosts. (%s)" + % hosts_extra_vars) + with oooutils.TempDirs() as tmp: + oooutils.run_ansible_playbook( + playbook='cli-hosts-file-config.yaml', + inventory=inventory, + workdir=tmp, + playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS, + verbosity=oooutils.playbook_verbosity(self=self), + reproduce_command=False, + extra_vars=hosts_extra_vars, + ) + else: + self.log.debug("Not updating /etc/hosts because " + "--skip-hosts-config was used.") + + if not parsed_args.skip_container_registry_config and \ + container_dict.get('push_destination_boolean', False): + # call playbook to set /etc/containers/registries.conf + ns = container_dict.get('ceph_namespace', '').partition('/')[0] + if ns: + reg_extra_vars = dict(tripleo_podman_insecure_registries=[ns]) + self.log.debug("Adding %s as a container registry." % ns) + with oooutils.TempDirs() as tmp: + oooutils.run_ansible_playbook( + playbook='cli-container-registry-config.yaml', + inventory=inventory, + workdir=tmp, + playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS, + verbosity=oooutils.playbook_verbosity(self=self), + extra_vars=reg_extra_vars, + reproduce_command=False, + ) + else: + self.log.debug("Not updating container regsitry. " + "ceph_namespace is empty.") + else: + self.log.debug("Not updating container regsitry. " + "Either container_image_prepare_defaults.yaml " + "or file from --container-image-prepare " + "is not setting push_destination. Or " + "--skip-container-registry-config was used.") + + # call playbook to deploy ceph with oooutils.TempDirs() as tmp: oooutils.run_ansible_playbook( playbook='cli-deployed-ceph.yaml', @@ -397,7 +472,7 @@ class OvercloudCephDeploy(command.Command): verbosity=oooutils.playbook_verbosity(self=self), extra_vars=extra_vars, reproduce_command=False, - skip_tags=skip_tags, + skip_tags=','.join(skip_tags), )