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
This commit is contained in:
Mark Goddard 2020-04-16 12:37:20 +01:00
parent e924c99c52
commit 40e43e235d
10 changed files with 165 additions and 333 deletions

View File

@ -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) }}"

View File

@ -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

26
ansible/kolla-pip.yml Normal file
View File

@ -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)

View File

@ -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

View File

@ -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
<reference/deployment-and-bootstrapping/bootstrap-servers.html>`
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:*

View File

@ -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
<https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#caching-facts>`__,
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
-----------------

View File

@ -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.

View File

@ -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):

View File

@ -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)

View File

@ -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``.