diff --git a/etc/kayobe/ansible/growroot.yml b/etc/kayobe/ansible/growroot.yml new file mode 100644 index 000000000..6bfe63e41 --- /dev/null +++ b/etc/kayobe/ansible/growroot.yml @@ -0,0 +1,79 @@ +--- +# Custom playbook to grow the partition and LVM PV of the root VG. This allows +# for expansion of LVs in that VG. This may be used as a pre-overcloud host +# configure hook. +# +# Variables: +# * growroot_group: Host pattern against which to target the playbook. Default +# is 'overcloud'. +# * growroot_vg: Name of the VG containing the PV to grow. Default is 'rootvg'. + +- name: Grow root PV + hosts: "{{ growroot_group | default('overcloud') }}" + # Avoid using facts because this may be used as a pre overcloud host + # configure hook, and we don't want to populate the fact cache (if one is in + # use) with the bootstrap user's context. + gather_facts: false + tags: + - growroot + vars: + ansible_user: "{{ bootstrap_user }}" + # We can't assume that a virtualenv exists at this point, so use the system + # python interpreter. + ansible_python_interpreter: /usr/bin/python3 + # Work around no known_hosts entry on first boot. + ansible_ssh_common_args: "-o StrictHostKeyChecking=no" + # Name of the LVM VG containing the root PV. + growroot_vg: "rootvg" + # Don't assume facts are present. + os_family: "{{ ansible_facts.os_family | default('Debian' if os_distribution == 'ubuntu' else 'RedHat') }}" + + tasks: + - name: Check if growpart is installed + shell: + cmd: type growpart + changed_when: false + failed_when: false + register: growpart_check + become: true + + - name: Ensure growpart is installed + package: + name: "{% if os_family == 'RedHat' %}cloud-utils-growpart{% else %}cloud-guest-utils{% endif %}" + state: present + cache_valid_time: "{{ apt_cache_valid_time if os_family == 'Debian' else omit }}" + update_cache: "{{ True if os_family == 'Debian' else omit }}" + become: True + when: growpart_check.rc != 0 + + - name: Get root PV device + command: "pvs --select vg_name={{ growroot_vg }} --reportformat json" + register: pvs + become: True + changed_when: False + + - name: Fail if root PV device not found + fail: + msg: > + Expected LVM physical volume devices not found in volume group {{ growroot_vg }} + when: (pvs.stdout | from_json).report[0].pv | length == 0 + + - name: Grow partition + command: "growpart {{ disk }} {{ part_num }}" + vars: + pv: "{{ pvs.stdout | from_json }}" + disk_tmp: "{{ pv.report[0].pv[0].pv_name[:-1] }}" + disk: "{{ disk_tmp[:-1] if disk_tmp[-1] == 'p' else disk_tmp }}" + part_num: "{{ pv.report[0].pv[0].pv_name[-1] }}" + become: True + failed_when: "growpart.rc != 0 and 'NOCHANGE' not in growpart.stdout" + changed_when: "'NOCHANGE' not in growpart.stdout" + register: growpart + + - name: Grow LVM PV + command: "pvresize {{ disk }}" + vars: + pv: "{{ pvs.stdout | from_json }}" + disk: "{{ pv.report[0].pv[0].pv_name }}" + become: True + when: "'NOCHANGE' not in growpart.stdout" diff --git a/etc/kayobe/ansible/swap.yml b/etc/kayobe/ansible/swap.yml new file mode 100644 index 000000000..e47397212 --- /dev/null +++ b/etc/kayobe/ansible/swap.yml @@ -0,0 +1,35 @@ +--- +# Custom playbook to configure a swap device. This may be used as a +# post-overcloud host configure hook. +# +# Variables: +# * swap_group: Host pattern against which to target the playbook. Default is +# 'overcloud'. +# * swap_device: Name of the swap device to configure. Default is +# '/dev/rootvg/lv_swap'. + +- name: Configure swap + hosts: "{{ swap_group | default('overcloud') }}" + tags: + - swap + vars: + swap_device: "/dev/rootvg/lv_swap" + become: true + tasks: + - name: Ensure swap filesystem is present + filesystem: + fstype: "swap" + dev: "{{ swap_device }}" + + - name: Ensure swap device present in fstab + mount: + name: "none" + src: "{{ swap_device }}" + fstype: "swap" + state: "present" + + # It does no harm to run this when swap is already active + - name: Enable swap devices + command: "/sbin/swapon -a" + when: + - ansible_facts.swaptotal_mb == 0 diff --git a/etc/kayobe/inventory/group_vars/all/stackhpc-lvm b/etc/kayobe/inventory/group_vars/all/stackhpc-lvm new file mode 100644 index 000000000..8d710ba0d --- /dev/null +++ b/etc/kayobe/inventory/group_vars/all/stackhpc-lvm @@ -0,0 +1,150 @@ +--- +############################################################################### +# StackHPC LVM Volume Group (VG) configuration. + +# StackHPC rootvg VG. +# This VG contains a set of LVs that conform to the CIS partition benchmarks. +# This layout is compatible with the overcloud DIB host image configuration in +# stackhpc-overcloud-dib.yml. This may be used as an item in one of the +# *_lvm_groups variables. +# Example: +# controller_lvm_groups: +# - "{{ stackhpc_lvm_group_rootvg }}" +stackhpc_lvm_group_rootvg: + vgname: rootvg + disks: "{{ stackhpc_lvm_group_rootvg_disks }}" + create: true + lvnames: "{{ stackhpc_lvm_group_rootvg_lvs_default + stackhpc_lvm_group_rootvg_lvs_extra }}" + +# List of disks to include in the rootvg VG. +stackhpc_lvm_group_rootvg_disks: + - /dev/disk/by-partlabel/root + +# List of default LVs to include in the rootvg VG. +stackhpc_lvm_group_rootvg_lvs_default: + - "{{ stackhpc_lvm_lv_swap }}" + - "{{ stackhpc_lvm_lv_root }}" + - "{{ stackhpc_lvm_lv_tmp }}" + - "{{ stackhpc_lvm_lv_var }}" + - "{{ stackhpc_lvm_lv_var_tmp }}" + - "{{ stackhpc_lvm_lv_log }}" + - "{{ stackhpc_lvm_lv_audit }}" + - "{{ stackhpc_lvm_lv_home }}" + +# List of extra LVs to include in the rootvg VG. +stackhpc_lvm_group_rootvg_lvs_extra: [] + +############################################################################### +# StackHPC LVM Logical Volume (LV) configuration. + +# StackHPC LVM lv_swap LV size. +stackhpc_lvm_lv_swap_size: 16g + +# StackHPC LVM lv_root LV size. +stackhpc_lvm_lv_root_size: 50g + +# StackHPC LVM lv_tmp LV size. +stackhpc_lvm_lv_tmp_size: 10g + +# StackHPC LVM lv_var LV size. +stackhpc_lvm_lv_var_size: 20g + +# StackHPC LVM lv_var_tmp LV size. +stackhpc_lvm_lv_var_tmp_size: 2g + +# StackHPC LVM lv_log LV size. +stackhpc_lvm_lv_log_size: 20g + +# StackHPC LVM lv_audit LV size. +stackhpc_lvm_lv_audit_size: 10g + +# StackHPC LVM lv_home LV size. +stackhpc_lvm_lv_home_size: 10g + +# StackHPC LVM lv_docker LV size. +stackhpc_lvm_lv_docker_size: 100%FREE + +# StackHPC LVM lv_swap LV. +stackhpc_lvm_lv_swap: + lvname: lv_swap + size: "{{ stackhpc_lvm_lv_swap_size }}" + create: true + mount: false + +# StackHPC LVM lv_root LV. +stackhpc_lvm_lv_root: + lvname: lv_root + size: "{{ stackhpc_lvm_lv_root_size }}" + create: true + filesystem: ext4 + mount: true + mntp: / + +# StackHPC LVM lv_tmp LV. +stackhpc_lvm_lv_tmp: + lvname: lv_tmp + size: "{{ stackhpc_lvm_lv_tmp_size }}" + create: true + filesystem: ext4 + mount: true + mntp: /tmp + +# StackHPC LVM lv_var LV. +stackhpc_lvm_lv_var: + lvname: lv_var + size: "{{ stackhpc_lvm_lv_var_size }}" + create: true + filesystem: ext4 + mount: true + mntp: /var + +# StackHPC LVM lv_var_tmp LV. +stackhpc_lvm_lv_var_tmp: + lvname: lv_var_tmp + size: "{{ stackhpc_lvm_lv_var_tmp_size }}" + create: true + filesystem: ext4 + mount: true + mntp: /var/tmp + +# StackHPC LVM lv_log LV. +stackhpc_lvm_lv_log: + lvname: lv_log + size: "{{ stackhpc_lvm_lv_log_size }}" + create: true + filesystem: ext4 + mount: true + mntp: /var/log + +# StackHPC LVM lv_audit LV. +stackhpc_lvm_lv_audit: + lvname: lv_audit + size: "{{ stackhpc_lvm_lv_audit_size }}" + create: true + filesystem: ext4 + mount: true + mntp: /var/log/audit + +# StackHPC LVM lv_home LV. +stackhpc_lvm_lv_home: + lvname: lv_home + size: "{{ stackhpc_lvm_lv_home_size }}" + create: true + filesystem: ext4 + mount: true + mntp: /home + +# StackHPC LVM lv_docker LV. +# NOTE: This is not included in the rootvg by default, but may be added via +# stackhpc_lvm_group_rootvg_lvs_extra. +# Example: +# stackhpc_lvm_group_rootvg_lvs_extra: +# - "{{ stackhpc_lvm_lv_docker }}" +# Alternatively, this may reside in a separate VG. +stackhpc_lvm_lv_docker: + lvname: lv_docker + size: "{{ stackhpc_lvm_lv_docker_size }}" + create: true + filesystem: ext4 + mount: true + mntp: /var/lib/docker diff --git a/etc/kayobe/overcloud-dib.yml b/etc/kayobe/overcloud-dib.yml index 3d69f8eb1..78fff9471 100644 --- a/etc/kayobe/overcloud-dib.yml +++ b/etc/kayobe/overcloud-dib.yml @@ -10,6 +10,10 @@ # is {{ os_distribution == 'rocky' }}. This will change in a future release. #overcloud_dib_build_host_images: +# List of additional host packages to install. +overcloud_dib_host_packages_extra: + - "{% if 'ubuntu-minimal' in overcloud_dib_host_images | map(attribute='elements') | flatten | list %}debootstrap{% endif %}" + # List of overcloud host disk images to build. Each element is a dict defining # an image in a format accepted by the stackhpc.os-images role. Default is to # build an image named "deployment_image" configured with the overcloud_dib_* @@ -64,7 +68,11 @@ # List of additional git repositories containing Diskimage Builder (DIB) # elements. See stackhpc.os-images role for usage. Default is empty. -#overcloud_dib_git_elements_extra: +overcloud_dib_git_elements_extra: + - repo: "https://github.com/stackhpc/stackhpc-image-elements" + local: "{{ source_checkout_path }}/stackhpc-image-elememts" + version: "v1.4.0" + elements_path: "elements" # List of git repositories containing Diskimage Builder (DIB) elements. See # stackhpc.os-images role for usage. Default is a combination of diff --git a/etc/kayobe/stackhpc-overcloud-dib.yml b/etc/kayobe/stackhpc-overcloud-dib.yml new file mode 100644 index 000000000..84fffbc0f --- /dev/null +++ b/etc/kayobe/stackhpc-overcloud-dib.yml @@ -0,0 +1,215 @@ +--- +# StackHPC overcloud host disk image configuration. + +############################################################################### +# Diskimage-builder configuration for overcloud host disk images. + +# StackHPC overcloud host disk image Diskimage Builder recipe. This may be used +# as an item in the overcloud_dib_host_images list when +# overcloud_dib_build_host_images is true. +# Example: +# overcloud_dib_host_images: +# - "{{ stackhpc_overcloud_dib_host_image }}" +stackhpc_overcloud_dib_host_image: + name: "{{ stackhpc_overcloud_dib_name }}" + elements: "{{ stackhpc_overcloud_dib_elements }}" + env: "{{ stackhpc_overcloud_dib_env_vars }}" + packages: "{{ stackhpc_overcloud_dib_packages }}" + +# StackHPC overcloud DIB image name. +stackhpc_overcloud_dib_name: "deployment_image" + +# StackHPC overcloud DIB image elements. +stackhpc_overcloud_dib_elements: + - "{{ os_distribution }}-{% if os_distribution == 'rocky' %}container{% else %}minimal{% endif %}" + - "cloud-init-datasources" + - "{% if os_distribution in ['centos', 'rocky'] %}disable-selinux{% endif %}" + - "enable-serial-console" + - "vm" + - "block-device-efi" + - "cloud-init" + - "{% if os_distribution in ['centos', 'rocky'] %}dracut-regenerate{% endif %}" + - "{% if os_distribution == 'ubuntu' %}lvm{% endif %}" + - "openssh-server" + - "{% if os_distribution == 'ubuntu' %}sudoers{% endif %}" + +# StackHPC overcloud DIB image environment variables. +stackhpc_overcloud_dib_env_vars: + DIB_BLOCK_DEVICE_CONFIG: "{{ stackhpc_overcloud_dib_block_device_config_uefi_lvm }}" + DIB_BOOTLOADER_DEFAULT_CMDLINE: "nofb nomodeset gfxpayload=text net.ifnames=1 rd.auto" + DIB_CLOUD_INIT_DATASOURCES: "ConfigDrive" + DIB_CONTAINERFILE_RUNTIME: "docker" + DIB_CONTAINERFILE_NETWORK_DRIVER: "host" + # NOTE: Not currently syncing Ubuntu packages, since the on_demand mirror in + # Ark does not work if the upstream mirror pulls packages (which it does + # sometimes). + # DIB_DISTRIBUTION_MIRROR: "{{ stackhpc_repo_ubuntu_focal_url if os_distribution == 'ubuntu' else '' }}" + DIB_DRACUT_ENABLED_MODULES_DEFAULT_CONFIG: "{{ stackhpc_overcloud_dib_dracut_enabled_modules_default_config }}" + DIB_RELEASE: "{{ overcloud_dib_os_release }}" + DIB_SUDOERS_FILENAME: "no-fqdn" + # Avoid DNS queries during sudo commands, since we might not always have working DNS. + DIB_SUDOERS_CONFIG: | + Defaults !fqdn + # FIXME: Support templating repo files. + # DIB_YUM_MINIMAL_BOOTSTRAP_REPOS: /path/to/dir/containing/dib-mirror-*.repo + YUM: dnf + +# StackHPC overcloud DIB image packages. +stackhpc_overcloud_dib_packages: + - "logrotate" + - "net-tools" + +# StackHPC overcloud DIB image block device configuration. +# This image layout conforms to the CIS partition benchmarks. +# This configuration builds a UEFI-compatible image with 3 partitions. +# * p0: EFI ESP bootloader +# * p1: EFI BSP +# * p2: LVM PV (rootpv) +# The rootpv PV is in the rootvg VG, and has the following LVs: +# * lv_root -> / +# * lv_tmp -> /tmp +# * lv_var -> /var +# * lv_var_tmp -> /var/tmp +# * lv_log -> /var/log +# * lv_audit -> /var/log/audit +# * lv_home -> /home +stackhpc_overcloud_dib_block_device_config_uefi_lvm: | + - local_loop: + name: image0 + size: 20GiB + - partitioning: + base: image0 + label: gpt + partitions: + - name: ESP + type: 'EF00' + size: 550MiB + mkfs: + type: vfat + mount: + mount_point: /boot/efi + fstab: + options: "defaults" + fsck-passno: 2 + - name: BSP + type: 'EF02' + size: 8MiB + - name: root + type: '8E00' + flags: [ boot ] + size: 100% + - lvm: + name: lvm + base: [ root ] + pvs: + - name: rootpv + base: root + options: [ "--force" ] + vgs: + - name: rootvg + base: [ "rootpv" ] + options: [ "--force" ] + lvs: + - name: lv_root + base: rootvg + size: 5G + - name: lv_tmp + base: rootvg + size: 1G + - name: lv_var + base: rootvg + size: 1G + - name: lv_var_tmp + base: rootvg + size: 1G + - name: lv_log + base: rootvg + size: 1G + - name: lv_audit + base: rootvg + size: 128M + - name: lv_home + base: rootvg + size: 128M + - mkfs: + name: fs_root + base: lv_root + type: ext4 + label: "rootfs" + mount: + mount_point: / + fstab: + options: "defaults" + fsck-passno: 1 + - mkfs: + name: fs_tmp + base: lv_tmp + type: ext4 + label: "tmpfs" + mount: + mount_point: /tmp + fstab: + options: "rw,noexec,nosuid,nodev" + fsck-passno: 2 + - mkfs: + name: fs_var + base: lv_var + type: ext4 + label: "varfs" + mount: + mount_point: /var + fstab: + options: "defaults" + fsck-passno: 2 + - mkfs: + name: fs_var_tmp + base: lv_var_tmp + type: ext4 + label: "vartmpfs" + mount: + mount_point: /var/tmp + fstab: + options: "rw,noexec,nosuid,nodev" + fsck-passno: 2 + - mkfs: + name: fs_log + base: lv_log + type: ext4 + label: "logfs" + mount: + mount_point: /var/log + fstab: + options: "defaults" + fsck-passno: 2 + - mkfs: + name: fs_audit + base: lv_audit + type: ext4 + label: "auditfs" + mount: + mount_point: /var/log/audit + fstab: + options: "defaults" + fsck-passno: 2 + - mkfs: + name: fs_home + base: lv_home + type: ext4 + label: "homefs" + mount: + mount_point: /home + fstab: + options: "rw,nodev" + fsck-passno: 2 + +# StackHPC overcloud DIB image Dracut module configuration. +stackhpc_overcloud_dib_dracut_enabled_modules_default_config: | + - name: crypt + packages: + - cryptsetup + - name: lvm + packages: + - lvm2 + - name: mdraid + packages: + - mdraid diff --git a/releasenotes/notes/lvm-3c785770722f768a.yaml b/releasenotes/notes/lvm-3c785770722f768a.yaml new file mode 100644 index 000000000..5818c3e23 --- /dev/null +++ b/releasenotes/notes/lvm-3c785770722f768a.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Adds a standard LVM configuration that is compatible with the new overcloud + host image. diff --git a/releasenotes/notes/overcloud-dib-938eac005662a2cb.yaml b/releasenotes/notes/overcloud-dib-938eac005662a2cb.yaml new file mode 100644 index 000000000..c8178302a --- /dev/null +++ b/releasenotes/notes/overcloud-dib-938eac005662a2cb.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + Adds a standard overcloud Diskimage Builder (DIB) host image configuration.