Implement GRUB modification process

In some cases it might be required to supply extra kernel options
through GRUB modification. Good example of that is enablement
of hugepages [1].

Adding variable `openstack_host_grub_options` should allow to
manage GRUB-related options reliably and out-of-the-box.

[1] https://docs.openstack.org/nova/latest/admin/huge-pages.html#enabling-huge-pages-on-the-host

Change-Id: I148ed1760d841dd99bc1e075b6200d6d7e835530
Signed-off-by: Dmitriy Rabotyagov <dmitriy.rabotyagov@cleura.com>
This commit is contained in:
Dmitriy Rabotyagov
2025-06-06 14:41:09 +02:00
parent b85c6abfbb
commit afaadb53ff
9 changed files with 89 additions and 0 deletions

View File

@@ -66,6 +66,17 @@ openstack_host_blacklist_kernel_modules: []
# Command to update initramfs
openstack_host_initramfs_command: "{{ _openstack_host_initramfs_command | default('true') }}"
# Custom options to define in GRUB_CMDLINE_LINUX_DEFAULT
# openstack_host_custom_grub_options:
# - key: hugepagesz
# value: 2MB
# - key: nomodeset
# - key: gfxpayload
# value: text
# state: absent
openstack_host_custom_grub_options: {}
openstack_host_update_grub_command: "{{ _openstack_host_update_grub_command }}"
# Overridable package list is composed of the old override
# named user_package_list and the standard defaults _openstack_hosts_package_list
openstack_hosts_package_list: "{{ _openstack_hosts_package_list + (user_package_list | default([])) }}"

View File

@@ -16,6 +16,9 @@
- name: Update initramfs # noqa: no-changed-when
ansible.builtin.command: "{{ openstack_host_initramfs_command }}"
- name: Update GRUB # noqa: no-changed-when
ansible.builtin.command: "{{ openstack_host_update_grub_command }}"
- name: Restart sysstat
ansible.builtin.service:
name: "sysstat"

View File

@@ -0,0 +1,6 @@
---
features:
- |
For ``openstack_hosts`` role implemented variable
``openstack_host_custom_grub_options`` which allows to modify ``GRUB_CMDLINE_LINUX_DEFAULT``
with arbitrary parameters or remove existing parameters from it.

View File

@@ -113,6 +113,11 @@
with_items: "{{ openstack_kernel_options + openstack_user_kernel_options }}"
failed_when: false
- name: Configure GRUB
ansible.builtin.include_tasks: openstack_grub.yml
when:
- openstack_host_custom_grub_options | length > 0
- name: Configure sysstat
ansible.builtin.include_tasks: openstack_sysstat.yml
when:

60
tasks/openstack_grub.yml Normal file
View File

@@ -0,0 +1,60 @@
---
# Copyright 2025, Cleura AB.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
- name: Fetch current GRUB parameters
ansible.builtin.shell: . /etc/default/grub && echo ${GRUB_CMDLINE_LINUX_DEFAULT}
register: _openstack_grub_default
changed_when: false
- name: Update GRUB options
ansible.builtin.lineinfile:
path: /etc/default/grub
regex: '^GRUB_CMDLINE_LINUX_DEFAULT='
line: 'GRUB_CMDLINE_LINUX_DEFAULT="{{ _openstack_resulting_grub_record }}"'
backup: true
mode: '0644'
owner: root
group: root
notify:
- Update GRUB
vars:
# Create list of dicts from the parsed grub parameters, ie:
# [{'key': 'console', 'value': 'tty0'}]
_openstack_current_grub: >-
{{
_openstack_grub_default.stdout | split(' ') | map('split', '=') | map('zip', ['key', 'value']) | map('map', 'reverse') | map('community.general.dict')
}}
# Fetch list of user-provided records which have `state: absent`
_openstack_absent_grub_records: >-
{{
openstack_host_custom_grub_options | selectattr('state', 'defined') | selectattr('state', 'eq', 'absent') | ansible.utils.remove_keys(target='state')
}}
# Remove records which should be removed from the list
_openstack_filtered_custom_grub: >-
{{
openstack_host_custom_grub_options | selectattr('state', 'defined') | rejectattr('state', 'eq', 'absent') +
openstack_host_custom_grub_options | selectattr('state', 'undefined')
}}
# Combine the result back from dict to GRUB parameters
_openstack_resulting_grub_record: |-
{% set grub = [] %}
{% for record in (_openstack_current_grub + _openstack_filtered_custom_grub) | unique | reject('in', _openstack_absent_grub_records) %}
{% if 'value' in record %}
{% set _ = grub.append(record['key'] ~ '=' ~ record['value']) %}
{% else %}
{% set _ = grub.append(record['key']) %}
{% endif %}
{% endfor %}
{{ grub | join(' ') }}

View File

@@ -19,6 +19,7 @@ openstack_host_sysstat_file: /etc/default/sysstat
openstack_host_sysstat_cron_file: /etc/cron.d/sysstat
openstack_host_cron_template: sysstat.cron.debian.j2
_openstack_host_initramfs_command: /usr/sbin/update-initramfs -u
_openstack_host_update_grub_command: grub-mkconfig -o /boot/grub/grub.cfg
## Kernel modules loaded on hosts
openstack_host_kernel_modules:

View File

@@ -19,6 +19,7 @@ openstack_host_sysstat_file: /etc/sysconfig/sysstat
openstack_host_sysstat_cron_file: /etc/cron.d/sysstat
openstack_host_cron_template: sysstat.cron.redhat.j2
_openstack_host_initramfs_command: /bin/dracut -f
_openstack_host_update_grub_command: grub2-mkconfig -o /boot/grub2/grub.cfg
openstack_host_sysstat_cron_mode: "0600"

View File

@@ -19,6 +19,7 @@ openstack_host_sysstat_file: /etc/sysconfig/sysstat
openstack_host_sysstat_cron_file: /etc/cron.d/sysstat
openstack_host_cron_template: sysstat.cron.redhat.j2
_openstack_host_initramfs_command: /bin/dracut -f
_openstack_host_update_grub_command: grub2-mkconfig -o /boot/grub2/grub.cfg
openstack_host_sysstat_cron_mode: "0600"

View File

@@ -19,6 +19,7 @@ openstack_host_sysstat_file: /etc/default/sysstat
openstack_host_sysstat_cron_file: /etc/cron.d/sysstat
openstack_host_cron_template: sysstat.cron.debian.j2
_openstack_host_initramfs_command: /usr/sbin/update-initramfs -u
_openstack_host_update_grub_command: grub-mkconfig -o /boot/grub/grub.cfg
## Kernel modules loaded on hosts
openstack_host_kernel_modules: