Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion ansible/library/kolla_toolbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,10 @@ def main(self) -> None:
try:
self._push_private_data_dir(kolla_toolbox, pdd, user)

exec_user = user or 'ansible'
runner_env = {}
if exec_user == 'ansible':
runner_env['HOME'] = _PDD_BASEDIR
if self.module._diff:
runner_env['ANSIBLE_DIFF_MODE'] = '1'

Expand All @@ -391,7 +394,7 @@ def main(self) -> None:
['/opt/ansible/bin/ansible-runner', 'run', pdd,
'--playbook', 'main.json',
'--rotate-artifacts', '1'],
user=user,
user=exec_user,
environment=runner_env
)
# exit 2 = task failed/unreachable; handled via event below.
Expand Down
2 changes: 1 addition & 1 deletion ansible/roles/barbican/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ barbican_api_healthcheck_test:
- >-
healthcheck_curl {{
'https' if barbican_enable_tls_backend | bool else 'http' }}://{{
api_interface_address | put_address_in_context('url') }}:{{ barbican_api_listen_port }}/healthcheck"
api_interface_address | put_address_in_context('url') }}:{{ barbican_api_listen_port }}/healthcheck
barbican_api_healthcheck_timeout: "{{ default_container_healthcheck_timeout }}"
barbican_api_healthcheck:
interval: "{{ barbican_api_healthcheck_interval }}"
Expand Down
44 changes: 44 additions & 0 deletions ansible/roles/nova-cell/tasks/version-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,47 @@
success_msg: >
Libvirt version check successful: target {{ new_version }} >= current {{ current_version }}.
when: libvirt_version_current_results is not skipped

- name: Check nova_libvirt image provides the libvirt start script
when: enable_nova_libvirt_container | bool and (groups[service.group] | length) > 0
vars:
service_name: "nova-libvirt"
service: "{{ nova_cell_services[service_name] }}"
tags: nova-libvirt-script-check
block:
- name: Look for kolla_nova_libvirt_start in the nova_libvirt image
become: true
kolla_container:
action: "start_container"
command: "ls /usr/local/bin/kolla_nova_libvirt_start"
common_options: "{{ docker_common_options }}"
container_engine: "{{ kolla_container_engine }}"
detach: false
environment:
KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}"
image: "{{ service.image }}"
name: "nova_libvirt_script_check"
restart_policy: oneshot
remove_on_exit: true
register: nova_libvirt_script_check
failed_when: false
check_mode: false
run_once: true
delegate_to: "{{ groups[service.group] | first }}"

- name: Assert the nova_libvirt image is recent enough
run_once: true
delegate_to: "{{ groups[service.group] | first }}"
ansible.builtin.assert:
that:
- "'/usr/local/bin/kolla_nova_libvirt_start' in (nova_libvirt_script_check.stdout | default(''))"
fail_msg: >
The nova_libvirt image '{{ service.image }}' does not contain
/usr/local/bin/kolla_nova_libvirt_start, which this version of
Kolla-Ansible needs to launch libvirtd alongside virtlogd. This
almost always means the container image has not been updated to
match the upgraded Kolla-Ansible code. Pull or build a current
nova-libvirt image before deploying. If you intend to keep using
an older image, skip the tag 'nova-libvirt-script-check'.
success_msg: >
nova_libvirt image provides kolla_nova_libvirt_start.
2 changes: 1 addition & 1 deletion ansible/roles/nova-cell/templates/nova-libvirt.json.j2
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"command": "/usr/sbin/libvirtd --listen",
"command": "/usr/local/bin/kolla_nova_libvirt_start",
"config_files": [
{
"source": "{{ container_config_directory }}/libvirtd.conf",
Expand Down
2 changes: 1 addition & 1 deletion ansible/roles/nova-cell/templates/qemu.conf.j2
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
stdio_handler = "file"
stdio_handler = "logd"

user = "nova"
group = "nova"
Expand Down
6 changes: 6 additions & 0 deletions releasenotes/notes/bug-2157639-93e313f168b18133.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
fixes:
- |
Fixed a stray trailing quote in the ``barbican_api`` healthcheck
command that caused containers to be falsely reported as unhealthy.
`LP#2157639 <https://launchpad.net/bugs/2157639>`__
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
upgrade:
- |
A deploy-time check now verifies that the ``nova_libvirt`` image contains
the ``/usr/local/bin/kolla_nova_libvirt_start`` helper before deploying.
This helper launches ``libvirtd`` alongside ``virtlogd`` and is required
by current Kolla-Ansible. If you upgrade Kolla-Ansible but continue to
use an older ``nova_libvirt`` image that predates the helper, the deploy
now fails fast with an explanatory message instead of leaving the
container unable to start. Pull or build a matching ``nova_libvirt``
image, or skip the ``nova-libvirt-script-check`` tag to bypass the check.
13 changes: 13 additions & 0 deletions releasenotes/notes/nova-libvirt-virtlogd-0b77f24764dcecfc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
features:
- |
The ``nova_libvirt`` container now runs ``virtlogd`` as a sidecar
alongside ``libvirtd``, and ``qemu.conf`` is configured with
``stdio_handler = "logd"`` so that libvirt routes instance console
chardevs through ``virtlogd``. This allows guest console logs to be
rotated according to ``/etc/libvirt/virtlogd.conf`` (by default 2MB
per file with 3 backups), instead of growing without bound as they
did when ``stdio_handler`` was set to ``"file"``.

Note that existing instances must be hard rebooted to pick up the
new console handler, as the chardev mode is fixed at qemu launch.
60 changes: 60 additions & 0 deletions tests/test_kolla_toolbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,66 @@ def test_fail_json_when_ansible_runner_not_found(self):
self.fake_ktbw.main)
self.assertIn('ansible-runner', error.result['msg'])

def test_runner_exec_uses_ansible_user_when_no_user_param(self):
"""user=None must exec ansible-runner as 'ansible', not as root.

Podman serialises user=None as null in ExecCreate; some daemon
versions interpret null as UID 0 (root), which breaks openstacksdk
lookups because HOME becomes /root instead of /var/lib/ansible.
"""
self.mock_ansible_module.params['user'] = None

with mock.patch.object(self.fake_ktbw, '_push_private_data_dir'), \
mock.patch.object(self.fake_ktbw, '_parse_runner_result',
return_value={'changed': False}):
self.fake_ktbw.main()

# call[0]=check_runner, call[1]=ansible-runner, call[2]=cleanup
runner_call = self.mock_container.exec_run.call_args_list[1]
self.assertEqual('ansible', runner_call.kwargs.get('user'))

def test_runner_exec_sets_home_to_pdd_basedir_for_ansible_user(self):
"""HOME must be set to _PDD_BASEDIR to finds clouds.yaml."""
self.mock_ansible_module.params['user'] = None

with mock.patch.object(self.fake_ktbw, '_push_private_data_dir'), \
mock.patch.object(self.fake_ktbw, '_parse_runner_result',
return_value={'changed': False}):
self.fake_ktbw.main()

runner_call = self.mock_container.exec_run.call_args_list[1]
env = runner_call.kwargs.get('environment', {})
self.assertEqual(kolla_toolbox._PDD_BASEDIR, env.get('HOME'))

def test_runner_exec_uses_explicit_user_param(self):
"""When user='rabbitmq', ansible-runner must exec as 'rabbitmq'."""
self.mock_ansible_module.params['user'] = 'rabbitmq'

with mock.patch.object(self.fake_ktbw, '_push_private_data_dir'), \
mock.patch.object(self.fake_ktbw, '_parse_runner_result',
return_value={'changed': False}):
self.fake_ktbw.main()

runner_call = self.mock_container.exec_run.call_args_list[1]
self.assertEqual('rabbitmq', runner_call.kwargs.get('user'))

def test_runner_exec_no_home_override_for_non_ansible_user(self):
"""HOME must not be overridden for non-ansible users.

Forcing HOME=/var/lib/ansible when running as rabbitmq causes
PermissionError because rabbitmq cannot write to ansible's home.
"""
self.mock_ansible_module.params['user'] = 'rabbitmq'

with mock.patch.object(self.fake_ktbw, '_push_private_data_dir'), \
mock.patch.object(self.fake_ktbw, '_parse_runner_result',
return_value={'changed': False}):
self.fake_ktbw.main()

runner_call = self.mock_container.exec_run.call_args_list[1]
env = runner_call.kwargs.get('environment', {})
self.assertNotIn('HOME', env)


class TestModuleInteraction(TestKollaToolboxModule):
"""Class focused on testing user input data from playbook."""
Expand Down