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
7 changes: 5 additions & 2 deletions ansible/action_plugins/merge_configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,12 @@ def read_config(self, source, config):
os.path.join(self._loader._basedir, 'templates'),
os.path.dirname(source),
]
self._templar.environment.loader.searchpath = searchpath
templar = self._templar.copy_with_new_env(searchpath=searchpath)

result = self._templar.template(template_data)
# lstrip_blocks avoids Jinja2 block tags (e.g. {% if %}) leaving
# behind leading whitespace that glues adjacent lines together.
result = templar.template(
template_data, overrides=dict(lstrip_blocks=True))
fakefile = StringIO(result)
config.parse(fakefile)
fakefile.close()
Expand Down
7 changes: 5 additions & 2 deletions ansible/action_plugins/merge_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,12 @@ def read_config(self, source):
os.path.join(self._loader._basedir, 'templates'),
os.path.dirname(source),
]
self._templar.environment.loader.searchpath = searchpath
templar = self._templar.copy_with_new_env(searchpath=searchpath)

template_data = self._templar.template(template_data)
# lstrip_blocks avoids Jinja2 block tags (e.g. {% if %}) leaving
# behind leading whitespace that glues adjacent lines together.
template_data = templar.template(
template_data, overrides=dict(lstrip_blocks=True))
result = yaml.safe_load(template_data)
return result or {}

Expand Down
14 changes: 0 additions & 14 deletions ansible/roles/cinder/tasks/upgrade.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,6 @@
- name: Reload cinder services
ansible.builtin.import_tasks: reload.yml

# TODO(mnasiadka): Remove me in 2026.2
- name: Remove cinderv3 catalog entries
vars:
_cinder_volumev3:
- name: "cinderv3"
type: "volumev3"
description: "Openstack Block Storage (deprecated)"
endpoints: []
state: absent
service_ks_register_auth: "{{ openstack_cinder_auth }}"
service_ks_register_services: "{{ _cinder_volumev3 }}"
ansible.builtin.import_role:
name: service-ks-register

- name: Running Cinder online schema migration
vars:
cinder_api: "{{ cinder_services['cinder-api'] }}"
Expand Down
4 changes: 1 addition & 3 deletions ansible/roles/mariadb/tasks/backup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@
register: container_facts

- name: Taking database backup via Mariabackup - backup type {{ mariadb_backup_type }}
vars:
cmd: "{{ 'kolla_mariadb_backup.sh' if mariadb_backup_target == 'active' else 'kolla_mariadb_backup_replica.sh' }}"
become: true
kolla_container:
action: "start_container"
command: "bash -c 'sudo -E kolla_set_configs && /usr/local/bin/{{ cmd }}'"
command: "bash -c 'sudo -E kolla_set_configs && /usr/local/bin/kolla_mariadb_backup.sh'"
common_options: "{{ docker_common_options }}"
detach: false
# NOTE(mgoddard): Try to use the same image as the MariaDB server container
Expand Down
4 changes: 2 additions & 2 deletions ansible/roles/mariadb/templates/backup.my.cnf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
default-character-set=utf8
user={{ mariadb_backup_database_user }}
password={{ mariadb_backup_database_password }}
host={{ database_address }}
port={{ database_port }}
host={{ api_interface_address }}
port={{ mariadb_port }}
38 changes: 0 additions & 38 deletions ansible/roles/prometheus/tasks/upgrade.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,6 @@
- name: Configure prometheus
ansible.builtin.import_tasks: config.yml

# NOTE(mnasiadka): Remove me in 2025.2
- name: Check for the existence of Prometheus v2 container volume
become: true
ansible.builtin.stat:
path: "{{ container_engine_volumes_path }}/prometheus_v2/_data"
register: prometheus_v2_data

- name: Migrate Prometheus volume
when: prometheus_v2_data.stat.exists
block:
- name: Gracefully stop Prometheus
become: true
kolla_container:
name: "{{ prometheus_services['prometheus-server'].container_name }}"
action: "stop_and_remove_container"
common_options: "{{ docker_common_options }}"
ignore_missing: true

- name: Create new Prometheus v3 volume
become: true
kolla_container:
action: "create_volume"
name: "prometheus_server"
common_options: "{{ docker_common_options }}"

- name: Move _data from old to new volume
become: true
ansible.builtin.command: "mv {{ container_engine_volumes_path }}/prometheus_v2/_data {{ container_engine_volumes_path }}/prometheus_server/"
args:
removes: "{{ container_engine_volumes_path }}/prometheus_v2/_data"

- name: Remove old Prometheus v2 volume
become: true
kolla_container:
action: "remove_volume"
name: "prometheus_v2"
common_options: "{{ docker_common_options }}"

- name: Check prometheus containers
ansible.builtin.import_tasks: check-containers.yml

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
fixes:
- |
Fixes MariaDB backups failing since MariaDB 10.11.19 and 11.4.13.
Mariabackup copied the data directory of ``mariadb_backup_host`` but
connected through the load balancer, which could route it to a different
Galera member. The backup lock then applied to the wrong node. It now
connects to the MariaDB instance on the host it backs up.
upgrade:
- |
``mariadb_backup_target`` no longer has any effect. Backups are always
taken from ``mariadb_backup_host``.
- |
Full backups are now named ``mysqlbackup-<date>.qp.xbc.xbs.gz`` and
incrementals ``incremental-<date>-mysqlbackup-<date>.qp.xbc.xbs.gz``,
matching the restore documentation. Existing backups remain restorable.
41 changes: 41 additions & 0 deletions tests/test_merge_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@

from importlib.machinery import SourceFileLoader
import os
import tempfile

from io import StringIO

from ansible.parsing.dataloader import DataLoader
from ansible.template import Templar
from oslotest import base


Expand Down Expand Up @@ -211,3 +215,40 @@ def test_merge_no_whitespace(self):
parser.write(output)
self.assertEqual(TESTC_NO_WHITESPACE, output.getvalue())
output.close()

def test_read_config_lstrip_blocks(self):
# An indented Jinja2 block tag on its own line must not leak its
# leading whitespace into the following line, or the line gets
# parsed as a continuation of the previous key's value instead of
# a new key.
content = (
"[DEFAULT]\n"
"key1 = value1\n"
" {% if true %}\n"
"key2 = value2\n"
" {% endif %}\n"
"key3 = value3\n"
)
with tempfile.TemporaryDirectory() as tmpdir:
source = os.path.join(tmpdir, 'source.conf')
with open(source, 'w') as f:
f.write(content)

loader = DataLoader()
loader.set_basedir(tmpdir)
action = object.__new__(merge_configs.ActionModule)
action._loader = loader
action._templar = Templar(loader=loader)

config = merge_configs.OverrideConfigParser()
action.read_config(source, config)

output = StringIO()
config.write(output)
self.assertEqual(
"[DEFAULT]\n"
"key1 = value1\n"
"key2 = value2\n"
"key3 = value3\n\n",
output.getvalue())
output.close()
32 changes: 32 additions & 0 deletions tests/test_merge_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@

from importlib.machinery import SourceFileLoader
import os
import tempfile

from ansible.errors import AnsibleModuleError
from ansible.parsing.dataloader import DataLoader
from ansible.template import Templar
from oslotest import base

PROJECT_DIR = os.path.abspath(os.path.join(os. path.dirname(__file__), '../'))
Expand Down Expand Up @@ -174,3 +177,32 @@ def test_merge_nested_extend_lists_mismatch_types(self):
with self.assertRaisesRegex(AnsibleModuleError, "Failure merging key"):
merge_yaml.Utils.update_nested_conf(
initial_conf, extension, extend_lists=True)

def test_read_config_lstrip_blocks(self):
# An indented Jinja2 block tag on its own line must not leak its
# leading whitespace into the following line, or the resulting
# YAML indentation becomes inconsistent with its siblings.
content = (
"foo:\n"
" bar: baz\n"
" {% if true %}\n"
" extra: value\n"
" {% endif %}\n"
" qux: quux\n"
)
with tempfile.TemporaryDirectory() as tmpdir:
source = os.path.join(tmpdir, 'source.yml')
with open(source, 'w') as f:
f.write(content)

loader = DataLoader()
loader.set_basedir(tmpdir)
action = object.__new__(merge_yaml.ActionModule)
action._loader = loader
action._templar = Templar(loader=loader)

result = action.read_config(source)

self.assertEqual(
{'foo': {'bar': 'baz', 'extra': 'value', 'qux': 'quux'}},
result)