Support configuration of swap

Supports creating and using swap files, or using pre-existing swap
devices.

Story: 2004958
Task: 29390

Change-Id: Iadb540f42036a4a63cdd5b695b82f1504b3a4a28
This commit is contained in:
Mark Goddard 2022-07-27 09:40:35 +01:00
parent 1440acd60e
commit 0c074431d0
24 changed files with 258 additions and 0 deletions

View File

@ -219,3 +219,9 @@ compute_libvirt_ceph_repo_install: true
# Ceph package repository release to install on CentOS and Rocky hosts when
# compute_libvirt_ceph_repo_install is true. Default is 'pacific'.
compute_libvirt_ceph_repo_release: pacific
###############################################################################
# Compute node swap configuration.
# List of swap devices. Each item is a dict containing a 'device' item.
compute_swap: []

View File

@ -183,3 +183,9 @@ controller_firewalld_default_zone:
# - permanent: true
# - state: enabled
controller_firewalld_rules: []
###############################################################################
# Controller node swap configuration.
# List of swap devices. Each item is a dict containing a 'device' item.
controller_swap: []

View File

@ -204,3 +204,9 @@ infra_vm_firewalld_default_zone:
# - permanent: true
# - state: enabled
infra_vm_firewalld_rules: []
###############################################################################
# Infrastructure VM node swap configuration.
# List of swap devices. Each item is a dict containing a 'device' item.
infra_vm_swap: []

View File

@ -122,3 +122,9 @@ monitoring_firewalld_default_zone: "{{ controller_firewalld_default_zone }}"
# - permanent: true
# - state: enabled
monitoring_firewalld_rules: "{{ controller_firewalld_rules }}"
###############################################################################
# Monitoring node swap configuration.
# List of swap devices. Each item is a dict containing a 'device' item.
monitoring_swap: []

View File

@ -143,3 +143,9 @@ seed_firewalld_default_zone:
# - permanent: true
# - state: enabled
seed_firewalld_rules: []
###############################################################################
# Seed node swap configuration.
# List of swap devices. Each item is a dict containing a 'device' item.
seed_swap: []

View File

@ -159,3 +159,9 @@ seed_hypervisor_firewalld_default_zone:
# - permanent: true
# - state: enabled
seed_hypervisor_firewalld_rules: []
###############################################################################
# Seed hypervisor node swap configuration.
# List of swap devices. Each item is a dict containing a 'device' item.
seed_hypervisor_swap: []

View File

@ -173,3 +173,9 @@ storage_firewalld_default_zone:
# - permanent: true
# - state: enabled
storage_firewalld_rules: []
###############################################################################
# Storage node swap configuration.
# List of swap devices. Each item is a dict containing a 'device' item.
storage_swap: []

View File

@ -0,0 +1,6 @@
---
###############################################################################
# Compute node swap configuration.
# List of swap devices. Each item is a dict containing a 'device' item.
swap: "{{ compute_swap }}"

View File

@ -0,0 +1,6 @@
---
###############################################################################
# Controller node swap configuration.
# List of swap devices. Each item is a dict containing a 'device' item.
swap: "{{ controller_swap }}"

View File

@ -0,0 +1,6 @@
---
###############################################################################
# Infrastructure VM node swap configuration.
# List of swap devices. Each item is a dict containing a 'device' item.
swap: "{{ infra_vm_swap }}"

View File

@ -0,0 +1,9 @@
---
###############################################################################
# Monitoring node swap configuration.
# List of swap devices. Each item is a dict containing a 'device' item.
swap: >
{{ controller_swap
if inventory_hostname in groups['controllers'] else
monitoring_swap }}

View File

@ -0,0 +1,6 @@
---
###############################################################################
# Seed hypervisor node swap configuration.
# List of swap devices. Each item is a dict containing a 'device' item.
swap: "{{ seed_hypervisor_swap }}"

View File

@ -0,0 +1,6 @@
---
###############################################################################
# Seed node swap configuration.
# List of swap devices. Each item is a dict containing a 'device' item.
swap: "{{ seed_swap }}"

View File

@ -0,0 +1,6 @@
---
###############################################################################
# Storage node swap configuration.
# List of swap devices. Each item is a dict containing a 'device' item.
swap: "{{ storage_swap }}"

View File

@ -20,6 +20,7 @@
- import_playbook: "mdadm.yml"
- import_playbook: "luks.yml"
- import_playbook: "lvm.yml"
- import_playbook: "swap.yml"
- import_playbook: "docker-devicemapper.yml"
- import_playbook: "kolla-ansible-user.yml"
- import_playbook: "kolla-pip.yml"

View File

@ -0,0 +1,6 @@
---
# List of swap devices. Each item is a dict containing a 'device' item.
swap: []
# Command to use to create a swap file.
swap_file_create_command: "fallocate -l {{ item.size_mb }}MiB {{ item.path }}"

View File

@ -0,0 +1,33 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "List of swap files or devices",
"type": "array",
"items": {
"oneOf": [
{
"description": "Swap file",
"type": "object",
"required": ["path", "size_mb"],
"properties": {
"path": {
"type": "string"
},
"size_mb": {
"type": "integer",
"minimum": 0
}
}
},
{
"description": "Swap device",
"type": "object",
"required": ["device"],
"properties": {
"device": {
"type": "string"
}
}
}
]
}
}

View File

@ -0,0 +1,46 @@
---
- name: Validate swap configuration
ansible.utils.validate:
data: "{{ swap }}"
criteria: "{{ lookup('file', 'schema.json') }}"
# The following two tasks were adapted from
# https://github.com/geerlingguy/ansible-role-swap.
- name: Ensure swap file exists
command:
cmd: "{{ swap_file_create_command }}"
creates: "{{ item.path }}"
register: swap_file_create
loop: "{{ swap }}"
when: item.path is defined
- name: Set permissions on swap file
file:
path: "{{ item.path }}"
owner: root
group: root
mode: 0600
loop: "{{ swap }}"
when: item.path is defined
- name: Ensure swap filesystem is present
filesystem:
dev: "{{ item.device | default(item.path) }}"
fstype: "swap"
loop: "{{ swap }}"
- name: Ensure swap device is present in fstab
mount:
name: "none"
src: "{{ item.device | default(item.path) }}"
fstype: "swap"
state: "present"
loop: "{{ swap }}"
# It does no harm to run this when swap is already active.
- name: Enable swap
command: "/sbin/swapon -a"
when:
- ansible_facts.swaptotal_mb == 0
changed_when: true

11
ansible/swap.yml Normal file
View File

@ -0,0 +1,11 @@
---
- name: Configure swap
hosts: seed-hypervisor:seed:overcloud:infra-vms
become: true
tags:
- swap
tasks:
- name: Include swap role
include_role:
name: swap
when: swap | length > 0

View File

@ -1220,3 +1220,57 @@ applying the change to the seed hypervisor. For example, to install the
libvirt_host_extra_daemon_packages:
- trousers
Swap
====
*tags:*
| ``swap``
Swap files and devices may be configured via the ``swap`` variable. For
convenience, this is mapped to the following variables:
* ``seed_swap``
* ``seed_hypervisor_swap``
* ``infra_vm_swap``
* ``compute_swap``
* ``controller_swap``
* ``monitoring_swap``
* ``storage_swap``
The format is a list, with each item mapping to a dict/map. For a swap device,
the following item should be present:
* ``device``: Absolute path to a swap device.
For a swap file, the following items should be present:
* ``path``: Absolute path to a swap file to create.
* ``size_mb``: Size of the swap file in MiB.
The default value of ``swap`` is an empty list.
Example: enabling swap using a swap partition
---------------------------------------------
The following example defines a swap device using an existing ``/dev/sda3``
partition on controller hosts:
.. code-block:: yaml
:caption: ``controllers.yml``
controller_swap:
- device: /dev/sda3
Example: enabling swap using a swap file
----------------------------------------
The following example defines a 1GiB swap file that will be created at
``/swapfile`` on compute hosts:
.. code-block:: yaml
:caption: ``compute.yml``
compute_swap:
- path: /swapfile
size_mb: 1024

View File

@ -188,5 +188,10 @@ controller_firewalld_rules:
state: disabled
zone: public
# Configure a swap file.
controller_swap:
- path: /swapfile
size_mb: 256
# Generate a password for libvirt SASL authentication.
compute_libvirt_sasl_password: "{% raw %}{{ lookup('password', '/tmp/libvirt-sasl-password') }}{% endraw %}"

View File

@ -302,3 +302,11 @@ def test_firewalld_rules(host):
for expected_line in expected_lines:
assert expected_line in info
assert expected_line in perm_info
def test_swap(host):
swapon = host.check_output("swapon -s")
swapon = swapon.splitlines()
assert len(swapon) > 1
swap_devs = [swap.split()[0] for swap in swapon[1:]]
assert "/swapfile" in swap_devs

View File

@ -0,0 +1,6 @@
---
features:
- |
Adds support for configuring swap files and devices on seed, seed
hypervisor, overcloud and infra VM hosts during ``host configure``
commands.

View File

@ -8,3 +8,4 @@ selinux # MIT
# INI parsing
oslo.config>=5.2.0 # Apache-2.0
paramiko # LGPL
jsonschema<5 # MIT