From 40e43e235d9e23931a304683a722db5902f12188 Mon Sep 17 00:00:00 2001 From: Mark Goddard Date: Thu, 16 Apr 2020 12:37:20 +0100 Subject: [PATCH] Run kolla-ansible bootstrap-servers as kolla user Previously, Kayobe used Kolla Ansible's bootstrap-servers command to create a user account and Python virtual environment for Kolla Ansible. In order to do this it used the Kayobe Ansible user and Python interpreter. This causes problems for Ansible fact caching, which needs separate caches for Kayobe and Kolla Ansible, since the different users and Python interpreters used result in different facts. Bootstrapping servers with the Kayobe user and interpreter resulted in the Kolla Ansible fact cache being populated with Kayobe's user and interpreter. This change disables user creation during Kolla Ansible's bootstrap-servers command, instead creating the user and virtual environment in Kayobe prior to running the command. This allows the bootstrap-servers command to be executed using the normal Kolla Ansible user and interpreter, which results in the correct facts being gathered. The downside here is some duplication of code and configuration, but a nice side effect is that we no longer need to dump configuration in the CLI for host configure in order to fetch the Ansible user and interpreter. Change-Id: I85670be7242bc436f73c689f027670b0938ba031 Story: 2007492 Task: 39444 --- ansible/group_vars/all/kolla | 7 +- ansible/kolla-ansible-user.yml | 47 ++++ ansible/kolla-pip.yml | 26 ++ .../kolla-ansible/templates/globals.yml.j2 | 24 +- doc/source/configuration/hosts.rst | 10 +- doc/source/configuration/kolla-ansible.rst | 17 ++ etc/kayobe/kolla.yml | 4 + kayobe/cli/commands.py | 94 +------ kayobe/tests/unit/cli/test_commands.py | 249 +----------------- ...otstrap-servers-user-8cb5114de1dd10ec.yaml | 20 ++ 10 files changed, 165 insertions(+), 333 deletions(-) create mode 100644 ansible/kolla-ansible-user.yml create mode 100644 ansible/kolla-pip.yml create mode 100644 releasenotes/notes/bootstrap-servers-user-8cb5114de1dd10ec.yaml diff --git a/ansible/group_vars/all/kolla b/ansible/group_vars/all/kolla index e1fb3e6b7..8279fb80b 100644 --- a/ansible/group_vars/all/kolla +++ b/ansible/group_vars/all/kolla @@ -337,6 +337,10 @@ kolla_ansible_group: kolla # Ansible. kolla_ansible_become: false +# Whether to create a user account, configure passwordless sudo and authorise +# an SSH key for Kolla Ansible. Default is 'true'. +kolla_ansible_create_user: true + ############################################################################### # Kolla feature flag configuration. @@ -402,8 +406,7 @@ kolla_ansible_default_custom_passwords: bifrost_ssh_key: private_key: "{{ lookup('file', ssh_private_key_path) }}" public_key: "{{ lookup('file', ssh_public_key_path) }}" - # SSH key authorized by kolla user on Kolla hosts during - # kolla-ansible bootstrap-servers. + # SSH key authorized by kolla user on Kolla hosts. kolla_ssh_key: private_key: "{{ lookup('file', ssh_private_key_path) }}" public_key: "{{ lookup('file', ssh_public_key_path) }}" diff --git a/ansible/kolla-ansible-user.yml b/ansible/kolla-ansible-user.yml new file mode 100644 index 000000000..e9802d872 --- /dev/null +++ b/ansible/kolla-ansible-user.yml @@ -0,0 +1,47 @@ +--- +- name: Ensure the Kolla Ansible user account exists + hosts: seed:overcloud + gather_facts: false + tags: + - kolla-ansible + - kolla-ansible-user + vars: + # kolla_overcloud_inventory_top_level_group_map looks like: + # kolla_overcloud_inventory_top_level_group_map: + # control: + # groups: + # - controllers + hosts_in_kolla_inventory: >- + {{ kolla_overcloud_inventory_top_level_group_map.values() | + map(attribute='groups') | flatten | unique | union(['seed']) | join(':') }} + tasks: + - block: + - name: Ensure the Kolla Ansible user account exists + include_role: + name: singleplatform-eng.users + apply: + become: True + vars: + groups_to_create: + - name: docker + - name: "{{ kolla_ansible_group }}" + - name: sudo + users: + - username: "{{ kolla_ansible_user }}" + group: "{{ kolla_ansible_group }}" + groups: + - docker + - sudo + append: True + ssh_key: + - "{{ kolla_ansible_custom_passwords.kolla_ssh_key.public_key }}" + + - name: Ensure the Kolla Ansible user has passwordless sudo + copy: + content: "{{ kolla_ansible_user }} ALL=(ALL) NOPASSWD: ALL" + dest: "/etc/sudoers.d/kolla-ansible-users" + mode: 0640 + become: True + when: + - inventory_hostname in query('inventory_hostnames', hosts_in_kolla_inventory) + - kolla_ansible_create_user | bool diff --git a/ansible/kolla-pip.yml b/ansible/kolla-pip.yml new file mode 100644 index 000000000..54c08bdd3 --- /dev/null +++ b/ansible/kolla-pip.yml @@ -0,0 +1,26 @@ +--- +- name: Configure local PyPi mirror for Kolla Ansible + hosts: seed:overcloud + gather_facts: false + tags: + - kolla-ansible + - kolla-pip + - pip + vars: + # kolla_overcloud_inventory_top_level_group_map looks like: + # kolla_overcloud_inventory_top_level_group_map: + # control: + # groups: + # - controllers + hosts_in_kolla_inventory: >- + {{ kolla_overcloud_inventory_top_level_group_map.values() | + map(attribute='groups') | flatten | unique | union(['seed']) | join(':') }} + ansible_python_interpreter: /usr/libexec/platform-python + tasks: + - import_role: + name: pip + vars: + pip_applicable_users: + - "{{ kolla_ansible_user }}" + when: + - inventory_hostname in query('inventory_hostnames', hosts_in_kolla_inventory) diff --git a/ansible/roles/kolla-ansible/templates/globals.yml.j2 b/ansible/roles/kolla-ansible/templates/globals.yml.j2 index 6bc96d479..ad02b68be 100644 --- a/ansible/roles/kolla-ansible/templates/globals.yml.j2 +++ b/ansible/roles/kolla-ansible/templates/globals.yml.j2 @@ -48,12 +48,6 @@ kolla_external_vip_address: "{{ kolla_external_vip_address }}" # kolla_external_vip_address. kolla_external_fqdn: "{{ kolla_external_fqdn }}" -# User account to use for Kolla SSH access. -kolla_user: "{{ kolla_ansible_user }}" - -# Primary group of Kolla SSH user. -kolla_group: "{{ kolla_ansible_group }}" - ################ # Docker options ################ @@ -549,6 +543,10 @@ bifrost_install_type: source grafana_admin_username: "{{ grafana_local_admin_user_name }}" {% endif %} +######################################### +# Bootstrap-servers - Host Configuration +######################################### + {% if kolla_selinux_state is not none %} selinux_state: {{ kolla_selinux_state }} {% endif %} @@ -559,6 +557,20 @@ install_epel: {{ kolla_ansible_install_epel | bool }} enable_host_ntp: {{ kolla_enable_host_ntp | bool }} {% endif %} +# Kayobe performs creation of the Kolla Ansible user account, so there is no +# need for Kolla Ansible to repeat this. +create_kolla_user: false + +# User account to use for Kolla SSH access. +kolla_user: "{{ kolla_ansible_user }}" + +# Primary group of Kolla SSH user. +kolla_group: "{{ kolla_ansible_group }}" + +{% if kolla_ansible_target_venv %} +virtualenv: {{ kolla_ansible_target_venv }} +{% endif %} + {% if kolla_extra_globals %} ####################### # Extra configuration diff --git a/doc/source/configuration/hosts.rst b/doc/source/configuration/hosts.rst index 08ea2158e..b0be9fd36 100644 --- a/doc/source/configuration/hosts.rst +++ b/doc/source/configuration/hosts.rst @@ -720,16 +720,18 @@ Kolla-Ansible bootstrap-servers =============================== Kolla Ansible provides some host configuration functionality via the -``bootstrap-servers`` command, which may be leveraged by Kayobe. Due to the -bootstrapping nature of the command, Kayobe uses ``kayobe_ansible_user`` to -execute it, and uses the Kayobe remote Python virtual environment (or the -system Python interpreter if no virtual environment is in use). +``bootstrap-servers`` command, which may be leveraged by Kayobe. See the :kolla-ansible-doc:`Kolla Ansible documentation ` for more information on the functions performed by this command, and how to configure it. +Note that from the Ussuri release, Kayobe creates a user account for Kolla +Ansible rather than this being done by Kolla Ansible during +``bootstrap-servers``. See :ref:`configuration-kolla-ansible-user-creation` for +details. + Kolla-Ansible Remote Virtual Environment ======================================== *tags:* diff --git a/doc/source/configuration/kolla-ansible.rst b/doc/source/configuration/kolla-ansible.rst index 6e235b211..23e0a3ab9 100644 --- a/doc/source/configuration/kolla-ansible.rst +++ b/doc/source/configuration/kolla-ansible.rst @@ -174,6 +174,23 @@ The variable ``kolla_ansible_target_venv`` configures the use of a virtual environment on the remote hosts. The default configuration should work in most cases. +.. _configuration-kolla-ansible-user-creation: + +User account creation +--------------------- + +Since the Ussuri release, Kayobe creates a user account for Kolla Ansible +rather than this being done during Kolla Ansible's ``bootstrap-servers`` +command. This workflow is more compatible with `Ansible fact caching +`__, +but does mean that Kolla Ansible's ``create_kolla_user`` variable cannot be +used to disable creation of the user account. Instead, set +``kolla_ansible_create_user`` to ``false``. + +``kolla_ansible_create_user`` + Whether to create a user account, configure passwordless sudo and authorise + an SSH key for Kolla Ansible. Default is ``true``. + OpenStack Logging ----------------- diff --git a/etc/kayobe/kolla.yml b/etc/kayobe/kolla.yml index f5eb9a999..56327aa51 100644 --- a/etc/kayobe/kolla.yml +++ b/etc/kayobe/kolla.yml @@ -172,6 +172,10 @@ # Ansible. Default is 'false'. #kolla_ansible_become: +# Whether to create a user account, configure passwordless sudo and authorise +# an SSH key for Kolla Ansible. Default is 'true'. +#kolla_ansible_create_user: + ############################################################################### # Kolla feature flag configuration. diff --git a/kayobe/cli/commands.py b/kayobe/cli/commands.py index 751234a7a..42e35d7ad 100644 --- a/kayobe/cli/commands.py +++ b/kayobe/cli/commands.py @@ -516,23 +516,6 @@ class SeedHostConfigure(KollaAnsibleMixin, KayobeAnsibleMixin, VaultMixin, def take_action(self, parsed_args): self.app.LOG.debug("Configuring seed host OS") - # Query some kayobe ansible variables. - # Explicitly request the dump-config tag to ensure this play runs even - # if the user specified tags. - hostvars = self.run_kayobe_config_dump(parsed_args, hosts="seed", - tags="dump-config") - if not hostvars: - self.app.LOG.error("No hosts in the seed group") - sys.exit(1) - hostvars = list(hostvars.values())[0] - ansible_user = hostvars.get("kayobe_ansible_user") - if not ansible_user: - self.app.LOG.error("Could not determine kayobe_ansible_user " - "variable for seed host") - sys.exit(1) - python_interpreter = hostvars.get("ansible_python_interpreter") - kolla_target_venv = hostvars.get("kolla_ansible_target_venv") - # Allocate IP addresses. playbooks = _build_playbook_list("ip-allocation") self.run_kayobe_playbooks(parsed_args, playbooks, limit="seed") @@ -546,38 +529,19 @@ class SeedHostConfigure(KollaAnsibleMixin, KayobeAnsibleMixin, VaultMixin, playbooks += _build_playbook_list( "users", "yum", "dnf", "dev-tools", "disable-selinux", "network", "sysctl", "ip-routing", "snat", "disable-glean", "ntp", "mdadm", - "lvm", "docker-devicemapper") + "lvm", "docker-devicemapper", "kolla-ansible-user", "kolla-pip", + "kolla-target-venv") self.run_kayobe_playbooks(parsed_args, playbooks, limit="seed") self.generate_kolla_ansible_config(parsed_args, service_config=False) # Run kolla-ansible bootstrap-servers. - # This command should be run as the kayobe ansible user because at this - # point the kolla user may not exist. - extra_vars = {"ansible_user": ansible_user} - if python_interpreter: - # Use the kayobe virtualenv, as this is the executing user. - extra_vars["ansible_python_interpreter"] = python_interpreter - elif kolla_target_venv: - # Override the kolla-ansible virtualenv, use the system python - # instead. - extra_vars["ansible_python_interpreter"] = "/usr/bin/python" - if kolla_target_venv: - # Specify a virtualenv in which to install python packages. - extra_vars["virtualenv"] = kolla_target_venv - self.run_kolla_ansible_seed(parsed_args, "bootstrap-servers", - extra_vars=extra_vars) - - # Re-run the Pip role after we've bootstrapped the Kolla user - extra_vars = {} - kolla_ansible_user = hostvars.get("kolla_ansible_user") - extra_vars["pip_applicable_users"] = [kolla_ansible_user] + self.run_kolla_ansible_seed(parsed_args, "bootstrap-servers") # Run final kayobe playbooks. playbooks = _build_playbook_list( - "pip", "kolla-target-venv", "kolla-host", "docker") - self.run_kayobe_playbooks(parsed_args, playbooks, - extra_vars=extra_vars, limit="seed") + "kolla-host", "docker") + self.run_kayobe_playbooks(parsed_args, playbooks, limit="seed") # Optionally, deploy a Docker Registry. playbooks = _build_playbook_list("docker-registry") @@ -916,23 +880,6 @@ class OvercloudHostConfigure(KollaAnsibleMixin, KayobeAnsibleMixin, VaultMixin, def take_action(self, parsed_args): self.app.LOG.debug("Configuring overcloud host OS") - # Query some kayobe ansible variables. - # Explicitly request the dump-config tag to ensure this play runs even - # if the user specified tags. - hostvars = self.run_kayobe_config_dump(parsed_args, hosts="overcloud", - tags="dump-config") - if not hostvars: - self.app.LOG.error("No hosts in the overcloud group") - sys.exit(1) - hostvars = list(hostvars.values())[0] - ansible_user = hostvars.get("kayobe_ansible_user") - if not ansible_user: - self.app.LOG.error("Could not determine kayobe_ansible_user " - "variable for overcloud hosts") - sys.exit(1) - python_interpreter = hostvars.get("ansible_python_interpreter") - kolla_target_venv = hostvars.get("kolla_ansible_target_venv") - # Allocate IP addresses. playbooks = _build_playbook_list("ip-allocation") self.run_kayobe_playbooks(parsed_args, playbooks, limit="overcloud") @@ -946,40 +893,19 @@ class OvercloudHostConfigure(KollaAnsibleMixin, KayobeAnsibleMixin, VaultMixin, playbooks += _build_playbook_list( "users", "yum", "dnf", "dev-tools", "disable-selinux", "network", "sysctl", "disable-glean", "disable-cloud-init", "ntp", "mdadm", - "lvm", "docker-devicemapper") + "lvm", "docker-devicemapper", "kolla-ansible-user", "kolla-pip", + "kolla-target-venv") self.run_kayobe_playbooks(parsed_args, playbooks, limit="overcloud") self.generate_kolla_ansible_config(parsed_args, service_config=False) # Kolla-ansible bootstrap-servers. - # The kolla-ansible bootstrap-servers command should be run as the - # kayobe ansible user because at this point the kolla user may not - # exist. - extra_vars = {"ansible_user": ansible_user} - if python_interpreter: - # Use the kayobe virtualenv, as this is the executing user. - extra_vars["ansible_python_interpreter"] = python_interpreter - elif kolla_target_venv: - # Override the kolla-ansible virtualenv, use the system python - # instead. - extra_vars["ansible_python_interpreter"] = "/usr/bin/python" - if kolla_target_venv: - # Specify a virtualenv in which to install python packages. - extra_vars["virtualenv"] = kolla_target_venv - self.run_kolla_ansible_overcloud(parsed_args, "bootstrap-servers", - extra_vars=extra_vars) - - # Re-run the Pip role after we've bootstrapped the Kolla user - extra_vars = {} - kolla_ansible_user = hostvars.get("kolla_ansible_user") - extra_vars["pip_applicable_users"] = [kolla_ansible_user] + self.run_kolla_ansible_overcloud(parsed_args, "bootstrap-servers") # Further kayobe playbooks. playbooks = _build_playbook_list( - "pip", "kolla-target-venv", "kolla-host", - "docker", "swift-block-devices") - self.run_kayobe_playbooks(parsed_args, playbooks, - extra_vars=extra_vars, limit="overcloud") + "kolla-host", "docker", "swift-block-devices") + self.run_kayobe_playbooks(parsed_args, playbooks, limit="overcloud") class OvercloudHostPackageUpdate(KayobeAnsibleMixin, VaultMixin, Command): diff --git a/kayobe/tests/unit/cli/test_commands.py b/kayobe/tests/unit/cli/test_commands.py index 1242b17c9..93fce7853 100644 --- a/kayobe/tests/unit/cli/test_commands.py +++ b/kayobe/tests/unit/cli/test_commands.py @@ -461,28 +461,18 @@ class TestCase(unittest.TestCase): ] self.assertEqual(expected_calls, mock_run.call_args_list) - @mock.patch.object(commands.KayobeAnsibleMixin, - "run_kayobe_config_dump") @mock.patch.object(commands.KayobeAnsibleMixin, "run_kayobe_playbooks") @mock.patch.object(commands.KollaAnsibleMixin, "run_kolla_ansible_seed") - def test_seed_host_configure(self, mock_kolla_run, mock_run, mock_dump): + def test_seed_host_configure(self, mock_kolla_run, mock_run): command = commands.SeedHostConfigure(TestApp(), []) parser = command.get_parser("test") parsed_args = parser.parse_args([]) - mock_dump.return_value = { - "seed": {"kayobe_ansible_user": "stack"} - } result = command.run(parsed_args) self.assertEqual(0, result) - expected_calls = [ - mock.call(mock.ANY, hosts="seed", tags="dump-config") - ] - self.assertEqual(expected_calls, mock_dump.call_args_list) - expected_calls = [ mock.call( mock.ANY, @@ -514,6 +504,11 @@ class TestCase(unittest.TestCase): utils.get_data_files_path("ansible", "lvm.yml"), utils.get_data_files_path("ansible", "docker-devicemapper.yml"), + utils.get_data_files_path( + "ansible", "kolla-ansible-user.yml"), + utils.get_data_files_path("ansible", "kolla-pip.yml"), + utils.get_data_files_path( + "ansible", "kolla-target-venv.yml"), ], limit="seed", ), @@ -526,14 +521,10 @@ class TestCase(unittest.TestCase): mock.call( mock.ANY, [ - utils.get_data_files_path("ansible", "pip.yml"), - utils.get_data_files_path( - "ansible", "kolla-target-venv.yml"), utils.get_data_files_path("ansible", "kolla-host.yml"), utils.get_data_files_path("ansible", "docker.yml"), ], limit="seed", - extra_vars={'pip_applicable_users': [None]}, ), mock.call( mock.ANY, @@ -551,109 +542,6 @@ class TestCase(unittest.TestCase): mock.call( mock.ANY, "bootstrap-servers", - extra_vars={"ansible_user": "stack"}, - ), - ] - self.assertEqual(expected_calls, mock_kolla_run.call_args_list) - - @mock.patch.object(commands.KayobeAnsibleMixin, - "run_kayobe_config_dump") - @mock.patch.object(commands.KayobeAnsibleMixin, - "run_kayobe_playbooks") - @mock.patch.object(commands.KollaAnsibleMixin, - "run_kolla_ansible_seed") - def test_seed_host_configure_kayobe_venv(self, mock_kolla_run, mock_run, - mock_dump): - command = commands.SeedHostConfigure(TestApp(), []) - parser = command.get_parser("test") - parsed_args = parser.parse_args([]) - mock_dump.return_value = { - "seed": { - "ansible_python_interpreter": "/kayobe/venv/bin/python", - "kayobe_ansible_user": "stack", - } - } - - result = command.run(parsed_args) - self.assertEqual(0, result) - - expected_calls = [ - mock.call( - mock.ANY, - "bootstrap-servers", - extra_vars={ - "ansible_python_interpreter": "/kayobe/venv/bin/python", - "ansible_user": "stack", - }, - ), - ] - self.assertEqual(expected_calls, mock_kolla_run.call_args_list) - - @mock.patch.object(commands.KayobeAnsibleMixin, - "run_kayobe_config_dump") - @mock.patch.object(commands.KayobeAnsibleMixin, - "run_kayobe_playbooks") - @mock.patch.object(commands.KollaAnsibleMixin, - "run_kolla_ansible_seed") - def test_seed_host_configure_kolla_venv(self, mock_kolla_run, mock_run, - mock_dump): - command = commands.SeedHostConfigure(TestApp(), []) - parser = command.get_parser("test") - parsed_args = parser.parse_args([]) - mock_dump.return_value = { - "seed": { - "kayobe_ansible_user": "stack", - "kolla_ansible_target_venv": "/kolla/venv/bin/python", - } - } - - result = command.run(parsed_args) - self.assertEqual(0, result) - - expected_calls = [ - mock.call( - mock.ANY, - "bootstrap-servers", - extra_vars={ - "ansible_python_interpreter": "/usr/bin/python", - "ansible_user": "stack", - "virtualenv": "/kolla/venv/bin/python", - }, - ), - ] - self.assertEqual(expected_calls, mock_kolla_run.call_args_list) - - @mock.patch.object(commands.KayobeAnsibleMixin, - "run_kayobe_config_dump") - @mock.patch.object(commands.KayobeAnsibleMixin, - "run_kayobe_playbooks") - @mock.patch.object(commands.KollaAnsibleMixin, - "run_kolla_ansible_seed") - def test_seed_host_configure_both_venvs(self, mock_kolla_run, mock_run, - mock_dump): - command = commands.SeedHostConfigure(TestApp(), []) - parser = command.get_parser("test") - parsed_args = parser.parse_args([]) - mock_dump.return_value = { - "seed": { - "ansible_python_interpreter": "/kayobe/venv/bin/python", - "kayobe_ansible_user": "stack", - "kolla_ansible_target_venv": "/kolla/venv/bin/python", - } - } - - result = command.run(parsed_args) - self.assertEqual(0, result) - - expected_calls = [ - mock.call( - mock.ANY, - "bootstrap-servers", - extra_vars={ - "ansible_python_interpreter": "/kayobe/venv/bin/python", - "ansible_user": "stack", - "virtualenv": "/kolla/venv/bin/python", - }, ), ] self.assertEqual(expected_calls, mock_kolla_run.call_args_list) @@ -1088,29 +976,18 @@ class TestCase(unittest.TestCase): ] self.assertEqual(expected_calls, mock_run.call_args_list) - @mock.patch.object(commands.KayobeAnsibleMixin, - "run_kayobe_config_dump") @mock.patch.object(commands.KayobeAnsibleMixin, "run_kayobe_playbooks") @mock.patch.object(commands.KollaAnsibleMixin, "run_kolla_ansible_overcloud") - def test_overcloud_host_configure(self, mock_kolla_run, mock_run, - mock_dump): + def test_overcloud_host_configure(self, mock_kolla_run, mock_run): command = commands.OvercloudHostConfigure(TestApp(), []) parser = command.get_parser("test") parsed_args = parser.parse_args([]) - mock_dump.return_value = { - "controller0": {"kayobe_ansible_user": "stack"} - } result = command.run(parsed_args) self.assertEqual(0, result) - expected_calls = [ - mock.call(mock.ANY, hosts="overcloud", tags="dump-config") - ] - self.assertEqual(expected_calls, mock_dump.call_args_list) - expected_calls = [ mock.call( mock.ANY, @@ -1142,6 +1019,11 @@ class TestCase(unittest.TestCase): utils.get_data_files_path("ansible", "lvm.yml"), utils.get_data_files_path("ansible", "docker-devicemapper.yml"), + utils.get_data_files_path( + "ansible", "kolla-ansible-user.yml"), + utils.get_data_files_path("ansible", "kolla-pip.yml"), + utils.get_data_files_path( + "ansible", "kolla-target-venv.yml"), ], limit="overcloud", ), @@ -1154,16 +1036,12 @@ class TestCase(unittest.TestCase): mock.call( mock.ANY, [ - utils.get_data_files_path("ansible", "pip.yml"), - utils.get_data_files_path( - "ansible", "kolla-target-venv.yml"), utils.get_data_files_path("ansible", "kolla-host.yml"), utils.get_data_files_path("ansible", "docker.yml"), utils.get_data_files_path( "ansible", "swift-block-devices.yml"), ], limit="overcloud", - extra_vars={"pip_applicable_users": [None]}, ), ] self.assertEqual(expected_calls, mock_run.call_args_list) @@ -1172,109 +1050,6 @@ class TestCase(unittest.TestCase): mock.call( mock.ANY, "bootstrap-servers", - extra_vars={"ansible_user": "stack"}, - ), - ] - self.assertEqual(expected_calls, mock_kolla_run.call_args_list) - - @mock.patch.object(commands.KayobeAnsibleMixin, - "run_kayobe_config_dump") - @mock.patch.object(commands.KayobeAnsibleMixin, - "run_kayobe_playbooks") - @mock.patch.object(commands.KollaAnsibleMixin, - "run_kolla_ansible_overcloud") - def test_overcloud_host_configure_kayobe_venv(self, mock_kolla_run, - mock_run, mock_dump): - command = commands.OvercloudHostConfigure(TestApp(), []) - parser = command.get_parser("test") - parsed_args = parser.parse_args([]) - mock_dump.return_value = { - "controller0": { - "ansible_python_interpreter": "/kayobe/venv/bin/python", - "kayobe_ansible_user": "stack", - } - } - - result = command.run(parsed_args) - self.assertEqual(0, result) - - expected_calls = [ - mock.call( - mock.ANY, - "bootstrap-servers", - extra_vars={ - "ansible_python_interpreter": "/kayobe/venv/bin/python", - "ansible_user": "stack", - } - ), - ] - self.assertEqual(expected_calls, mock_kolla_run.call_args_list) - - @mock.patch.object(commands.KayobeAnsibleMixin, - "run_kayobe_config_dump") - @mock.patch.object(commands.KayobeAnsibleMixin, - "run_kayobe_playbooks") - @mock.patch.object(commands.KollaAnsibleMixin, - "run_kolla_ansible_overcloud") - def test_overcloud_host_configure_kolla_venv(self, mock_kolla_run, - mock_run, mock_dump): - command = commands.OvercloudHostConfigure(TestApp(), []) - parser = command.get_parser("test") - parsed_args = parser.parse_args([]) - mock_dump.return_value = { - "controller0": { - "kayobe_ansible_user": "stack", - "kolla_ansible_target_venv": "/kolla/venv/bin/python", - } - } - - result = command.run(parsed_args) - self.assertEqual(0, result) - - expected_calls = [ - mock.call( - mock.ANY, - "bootstrap-servers", - extra_vars={ - "ansible_python_interpreter": "/usr/bin/python", - "ansible_user": "stack", - "virtualenv": "/kolla/venv/bin/python", - } - ), - ] - self.assertEqual(expected_calls, mock_kolla_run.call_args_list) - - @mock.patch.object(commands.KayobeAnsibleMixin, - "run_kayobe_config_dump") - @mock.patch.object(commands.KayobeAnsibleMixin, - "run_kayobe_playbooks") - @mock.patch.object(commands.KollaAnsibleMixin, - "run_kolla_ansible_overcloud") - def test_overcloud_host_configure_both_venvs(self, mock_kolla_run, - mock_run, mock_dump): - command = commands.OvercloudHostConfigure(TestApp(), []) - parser = command.get_parser("test") - parsed_args = parser.parse_args([]) - mock_dump.return_value = { - "controller0": { - "ansible_python_interpreter": "/kayobe/venv/bin/python", - "kayobe_ansible_user": "stack", - "kolla_ansible_target_venv": "/kolla/venv/bin/python", - } - } - - result = command.run(parsed_args) - self.assertEqual(0, result) - - expected_calls = [ - mock.call( - mock.ANY, - "bootstrap-servers", - extra_vars={ - "ansible_python_interpreter": "/kayobe/venv/bin/python", - "ansible_user": "stack", - "virtualenv": "/kolla/venv/bin/python", - } ), ] self.assertEqual(expected_calls, mock_kolla_run.call_args_list) diff --git a/releasenotes/notes/bootstrap-servers-user-8cb5114de1dd10ec.yaml b/releasenotes/notes/bootstrap-servers-user-8cb5114de1dd10ec.yaml new file mode 100644 index 000000000..db32c9a75 --- /dev/null +++ b/releasenotes/notes/bootstrap-servers-user-8cb5114de1dd10ec.yaml @@ -0,0 +1,20 @@ +--- +upgrade: + - | + The ``kolla-ansible bootstrap-servers`` command is used by Kayobe during + the ``kayobe seed host configure`` and ``kayobe overcloud host configure`` + tasks. In previous releases it was executed as the Kayobe Ansible user + (``kayobe_ansible_user``) and using the remote Kayobe Python interpreter + (``ansible_python_interpreter``) since it was responsible for creation of + the Kolla Ansible user account (``kolla_ansible_user``) and Python virtual + environment (``kolla_ansible_target_venv``). This mix of environments + causes problems for Ansible fact caching. To avoid this issue, Kayobe is + now responsible for creation of the Kolla Ansible user and Python virtual + environment, and ``kolla-ansible bootstrap-servers`` is run using the + normal Kolla Ansible user and remote Python interpreter. + + Previously it was possible to avoid creation of the user account during + ``kolla-ansible bootstrap-servers`` by setting ``create_kolla_user`` to + ``false`` in ``${KAYOBE_CONFIG_PATH}/kolla/globals.yml``. The same may now + be achieved by setting ``kolla_ansible_create_user`` to ``false`` in + ``${KAYOBE_CONFIG_PATH}/kolla.yml``.