From 0c074431d032a04e7faf8e2f0758dc1321f49d32 Mon Sep 17 00:00:00 2001 From: Mark Goddard Date: Wed, 27 Jul 2022 09:40:35 +0100 Subject: [PATCH] Support configuration of swap Supports creating and using swap files, or using pre-existing swap devices. Story: 2004958 Task: 29390 Change-Id: Iadb540f42036a4a63cdd5b695b82f1504b3a4a28 --- ansible/inventory/group_vars/all/compute | 6 +++ ansible/inventory/group_vars/all/controllers | 6 +++ ansible/inventory/group_vars/all/infra-vms | 6 +++ ansible/inventory/group_vars/all/monitoring | 6 +++ ansible/inventory/group_vars/all/seed | 6 +++ .../inventory/group_vars/all/seed-hypervisor | 6 +++ ansible/inventory/group_vars/all/storage | 6 +++ ansible/inventory/group_vars/compute/swap | 6 +++ ansible/inventory/group_vars/controllers/swap | 6 +++ ansible/inventory/group_vars/infra-vms/swap | 6 +++ ansible/inventory/group_vars/monitoring/swap | 9 ++++ .../inventory/group_vars/seed-hypervisor/swap | 6 +++ ansible/inventory/group_vars/seed/swap | 6 +++ ansible/inventory/group_vars/storage/swap | 6 +++ ansible/overcloud-host-configure.yml | 1 + ansible/roles/swap/defaults/main.yml | 6 +++ ansible/roles/swap/files/schema.json | 33 ++++++++++++ ansible/roles/swap/tasks/main.yml | 46 ++++++++++++++++ ansible/swap.yml | 11 ++++ doc/source/configuration/reference/hosts.rst | 54 +++++++++++++++++++ .../overrides.yml.j2 | 5 ++ .../tests/test_overcloud_host_configure.py | 8 +++ releasenotes/notes/swap-522826f1706a4dc4.yaml | 6 +++ requirements.txt | 1 + 24 files changed, 258 insertions(+) create mode 100644 ansible/inventory/group_vars/compute/swap create mode 100644 ansible/inventory/group_vars/controllers/swap create mode 100644 ansible/inventory/group_vars/infra-vms/swap create mode 100644 ansible/inventory/group_vars/monitoring/swap create mode 100644 ansible/inventory/group_vars/seed-hypervisor/swap create mode 100644 ansible/inventory/group_vars/seed/swap create mode 100644 ansible/inventory/group_vars/storage/swap create mode 100644 ansible/roles/swap/defaults/main.yml create mode 100644 ansible/roles/swap/files/schema.json create mode 100644 ansible/roles/swap/tasks/main.yml create mode 100644 ansible/swap.yml create mode 100644 releasenotes/notes/swap-522826f1706a4dc4.yaml diff --git a/ansible/inventory/group_vars/all/compute b/ansible/inventory/group_vars/all/compute index d07d6d211..b53434708 100644 --- a/ansible/inventory/group_vars/all/compute +++ b/ansible/inventory/group_vars/all/compute @@ -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: [] diff --git a/ansible/inventory/group_vars/all/controllers b/ansible/inventory/group_vars/all/controllers index 17c32078a..e4cbe8b9f 100644 --- a/ansible/inventory/group_vars/all/controllers +++ b/ansible/inventory/group_vars/all/controllers @@ -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: [] diff --git a/ansible/inventory/group_vars/all/infra-vms b/ansible/inventory/group_vars/all/infra-vms index 745347f84..b111488b4 100644 --- a/ansible/inventory/group_vars/all/infra-vms +++ b/ansible/inventory/group_vars/all/infra-vms @@ -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: [] diff --git a/ansible/inventory/group_vars/all/monitoring b/ansible/inventory/group_vars/all/monitoring index b3c4c7219..6752ee34b 100644 --- a/ansible/inventory/group_vars/all/monitoring +++ b/ansible/inventory/group_vars/all/monitoring @@ -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: [] diff --git a/ansible/inventory/group_vars/all/seed b/ansible/inventory/group_vars/all/seed index fc51d908f..54a91c7a6 100644 --- a/ansible/inventory/group_vars/all/seed +++ b/ansible/inventory/group_vars/all/seed @@ -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: [] diff --git a/ansible/inventory/group_vars/all/seed-hypervisor b/ansible/inventory/group_vars/all/seed-hypervisor index dc3c652fa..ddab558d0 100644 --- a/ansible/inventory/group_vars/all/seed-hypervisor +++ b/ansible/inventory/group_vars/all/seed-hypervisor @@ -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: [] diff --git a/ansible/inventory/group_vars/all/storage b/ansible/inventory/group_vars/all/storage index 15919365e..c7066096f 100644 --- a/ansible/inventory/group_vars/all/storage +++ b/ansible/inventory/group_vars/all/storage @@ -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: [] diff --git a/ansible/inventory/group_vars/compute/swap b/ansible/inventory/group_vars/compute/swap new file mode 100644 index 000000000..4e00d65ca --- /dev/null +++ b/ansible/inventory/group_vars/compute/swap @@ -0,0 +1,6 @@ +--- +############################################################################### +# Compute node swap configuration. + +# List of swap devices. Each item is a dict containing a 'device' item. +swap: "{{ compute_swap }}" diff --git a/ansible/inventory/group_vars/controllers/swap b/ansible/inventory/group_vars/controllers/swap new file mode 100644 index 000000000..e3187377c --- /dev/null +++ b/ansible/inventory/group_vars/controllers/swap @@ -0,0 +1,6 @@ +--- +############################################################################### +# Controller node swap configuration. + +# List of swap devices. Each item is a dict containing a 'device' item. +swap: "{{ controller_swap }}" diff --git a/ansible/inventory/group_vars/infra-vms/swap b/ansible/inventory/group_vars/infra-vms/swap new file mode 100644 index 000000000..6227eb7c4 --- /dev/null +++ b/ansible/inventory/group_vars/infra-vms/swap @@ -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 }}" diff --git a/ansible/inventory/group_vars/monitoring/swap b/ansible/inventory/group_vars/monitoring/swap new file mode 100644 index 000000000..8c3ce975b --- /dev/null +++ b/ansible/inventory/group_vars/monitoring/swap @@ -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 }} diff --git a/ansible/inventory/group_vars/seed-hypervisor/swap b/ansible/inventory/group_vars/seed-hypervisor/swap new file mode 100644 index 000000000..2f0e3e00a --- /dev/null +++ b/ansible/inventory/group_vars/seed-hypervisor/swap @@ -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 }}" diff --git a/ansible/inventory/group_vars/seed/swap b/ansible/inventory/group_vars/seed/swap new file mode 100644 index 000000000..a896ec4b3 --- /dev/null +++ b/ansible/inventory/group_vars/seed/swap @@ -0,0 +1,6 @@ +--- +############################################################################### +# Seed node swap configuration. + +# List of swap devices. Each item is a dict containing a 'device' item. +swap: "{{ seed_swap }}" diff --git a/ansible/inventory/group_vars/storage/swap b/ansible/inventory/group_vars/storage/swap new file mode 100644 index 000000000..d6b12301a --- /dev/null +++ b/ansible/inventory/group_vars/storage/swap @@ -0,0 +1,6 @@ +--- +############################################################################### +# Storage node swap configuration. + +# List of swap devices. Each item is a dict containing a 'device' item. +swap: "{{ storage_swap }}" diff --git a/ansible/overcloud-host-configure.yml b/ansible/overcloud-host-configure.yml index d43c711e9..412b37ae4 100644 --- a/ansible/overcloud-host-configure.yml +++ b/ansible/overcloud-host-configure.yml @@ -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" diff --git a/ansible/roles/swap/defaults/main.yml b/ansible/roles/swap/defaults/main.yml new file mode 100644 index 000000000..0519a0708 --- /dev/null +++ b/ansible/roles/swap/defaults/main.yml @@ -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 }}" diff --git a/ansible/roles/swap/files/schema.json b/ansible/roles/swap/files/schema.json new file mode 100644 index 000000000..38e98b410 --- /dev/null +++ b/ansible/roles/swap/files/schema.json @@ -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" + } + } + } + ] + } +} diff --git a/ansible/roles/swap/tasks/main.yml b/ansible/roles/swap/tasks/main.yml new file mode 100644 index 000000000..a4dd79f2f --- /dev/null +++ b/ansible/roles/swap/tasks/main.yml @@ -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 diff --git a/ansible/swap.yml b/ansible/swap.yml new file mode 100644 index 000000000..5402e38ef --- /dev/null +++ b/ansible/swap.yml @@ -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 diff --git a/doc/source/configuration/reference/hosts.rst b/doc/source/configuration/reference/hosts.rst index c231b8f65..1c7681e80 100644 --- a/doc/source/configuration/reference/hosts.rst +++ b/doc/source/configuration/reference/hosts.rst @@ -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 diff --git a/playbooks/kayobe-overcloud-host-configure-base/overrides.yml.j2 b/playbooks/kayobe-overcloud-host-configure-base/overrides.yml.j2 index dbc9ce064..d7da2b6af 100644 --- a/playbooks/kayobe-overcloud-host-configure-base/overrides.yml.j2 +++ b/playbooks/kayobe-overcloud-host-configure-base/overrides.yml.j2 @@ -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 %}" diff --git a/playbooks/kayobe-overcloud-host-configure-base/tests/test_overcloud_host_configure.py b/playbooks/kayobe-overcloud-host-configure-base/tests/test_overcloud_host_configure.py index d2ff5c5aa..1cb62f883 100644 --- a/playbooks/kayobe-overcloud-host-configure-base/tests/test_overcloud_host_configure.py +++ b/playbooks/kayobe-overcloud-host-configure-base/tests/test_overcloud_host_configure.py @@ -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 diff --git a/releasenotes/notes/swap-522826f1706a4dc4.yaml b/releasenotes/notes/swap-522826f1706a4dc4.yaml new file mode 100644 index 000000000..5f88d3d27 --- /dev/null +++ b/releasenotes/notes/swap-522826f1706a4dc4.yaml @@ -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. diff --git a/requirements.txt b/requirements.txt index c02408183..107802870 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,3 +8,4 @@ selinux # MIT # INI parsing oslo.config>=5.2.0 # Apache-2.0 paramiko # LGPL +jsonschema<5 # MIT