From e362d4199774cfb90067b0165d2be5498b697dff Mon Sep 17 00:00:00 2001 From: tigro Date: Wed, 21 Aug 2024 17:09:01 +0300 Subject: [PATCH] Added unified_boot role --- ansible/gencloud.yml | 2 + ansible/roles/unified_boot/README.md | 44 +++++++ ansible/roles/unified_boot/defaults/main.yaml | 2 + ansible/roles/unified_boot/meta/main.yaml | 11 ++ ansible/roles/unified_boot/tasks/main.yaml | 115 ++++++++++++++++++ .../unified_boot/templates/grub_cfg_main.j2 | 25 ++++ .../unified_boot/templates/grub_cfg_stub.j2 | 4 + msvsphere-8-gencloud.pkr.hcl | 6 +- msvsphere-8-yandexcloud.pkr.hcl | 6 +- 9 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 ansible/roles/unified_boot/README.md create mode 100644 ansible/roles/unified_boot/defaults/main.yaml create mode 100644 ansible/roles/unified_boot/meta/main.yaml create mode 100644 ansible/roles/unified_boot/tasks/main.yaml create mode 100644 ansible/roles/unified_boot/templates/grub_cfg_main.j2 create mode 100644 ansible/roles/unified_boot/templates/grub_cfg_stub.j2 diff --git a/ansible/gencloud.yml b/ansible/gencloud.yml index 5043682..d49c3fc 100644 --- a/ansible/gencloud.yml +++ b/ansible/gencloud.yml @@ -4,5 +4,7 @@ become: true roles: + - role: unified_boot + when: is_unified_boot is defined - gencloud_guest - cleanup_vm diff --git a/ansible/roles/unified_boot/README.md b/ansible/roles/unified_boot/README.md new file mode 100644 index 0000000..8bd14dd --- /dev/null +++ b/ansible/roles/unified_boot/README.md @@ -0,0 +1,44 @@ +Unify Bootloader Configuration +========= + +Unify bootloader configuration to support BIOS and UEFI boot at the same time. + +Requirements +------------ + +None + +Role Variables +-------------- + +None + +Dependencies +------------ + +None + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - name: AlmaLinux Generic Cloud + hosts: all + become: true + + roles: + - role: unified_boot + when: is_unified_boot is defined + - gencloud_guest + - cleanup_vm + +License +------- + +GPL-3.0-only + +Author Information +------------------ + +Cloud Special Interest Group (Cloud SIG) of AlmaLinux OS Foundation diff --git a/ansible/roles/unified_boot/defaults/main.yaml b/ansible/roles/unified_boot/defaults/main.yaml new file mode 100644 index 0000000..037b4d7 --- /dev/null +++ b/ansible/roles/unified_boot/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +unified_boot_kernel_opts: console=tty0 console=ttyS0,115200n8 no_timer_check biosdevname=0 net.ifnames=0 diff --git a/ansible/roles/unified_boot/meta/main.yaml b/ansible/roles/unified_boot/meta/main.yaml new file mode 100644 index 0000000..ce8acb0 --- /dev/null +++ b/ansible/roles/unified_boot/meta/main.yaml @@ -0,0 +1,11 @@ +--- +galaxy_info: + author: AlmaLinux OS Cloud SIG + description: Unify bootloader configuration for BIOS and UEFI support + company: AlmaLinux OS Foundation + license: GPL-3.0-only + min_ansible_version: 2.13.9 + galaxy_tags: + - unifiedboot + - bios + - uefi diff --git a/ansible/roles/unified_boot/tasks/main.yaml b/ansible/roles/unified_boot/tasks/main.yaml new file mode 100644 index 0000000..c33682c --- /dev/null +++ b/ansible/roles/unified_boot/tasks/main.yaml @@ -0,0 +1,115 @@ +--- +# We do this as a part on kickstart files +# - name: Install GRUB for BIOS +# ansible.builtin.dnf: +# name: grub2-pc +# state: present + +# - name: Find root disk +# ansible.builtin.command: +# cmd: grub2-probe --target=disk /boot/grub2 +# register: root_disk +# changed_when: false +# +# - name: Install GRUB for BIOS +# ansible.builtin.command: +# cmd: grub2-install --target=i386-pc {{ root_disk.stdout }} +# creates: /boot/grub2/i386-pc + +- name: Get UUID of boot partition + ansible.builtin.command: + cmd: grub2-probe --target=fs_uuid /boot/grub2 + register: boot_uuid + changed_when: false + +- name: Get UUID of root partition + ansible.builtin.command: + cmd: findmnt -n -o UUID / + register: root_uuid + changed_when: false + +- name: Generate GRUB2 stub configuration + ansible.builtin.template: + src: grub_cfg_stub.j2 + dest: /boot/efi/EFI/almalinux/grub.cfg + mode: "0700" + +- name: Generate GRUB2 main configuration + ansible.builtin.template: + src: grub_cfg_main.j2 + dest: /boot/grub2/grub.cfg + mode: "0600" + +- name: Remove symlink of GRUB2 environment block + ansible.builtin.file: + path: /boot/grub2/grubenv + state: absent + +- name: Remove old GRUB2 environment block on ESP + ansible.builtin.file: + path: /boot/efi/EFI/almalinux/grubenv + state: absent + +- name: Get version of installed kernel # noqa: command-instead-of-module + ansible.builtin.command: + cmd: rpm -qa --queryformat "%{VERSION}-%{RELEASE}.%{ARCH}" kernel + register: kernel_ver + changed_when: false + +- name: Read machine ID + ansible.builtin.slurp: + src: /etc/machine-id + register: machine_id_base64 + +- name: Store machine ID + ansible.builtin.set_fact: + machine_id: "{{ machine_id_base64['content'] | b64decode | trim }}" + +- name: Remove old GRUB2 environment block + ansible.builtin.file: + path: /boot/grub2/grubenv + state: absent + +# The kernelopts is only needed for AlmaLinux OS 8 +- name: Generate new GRUB2 environment block + ansible.builtin.command: + cmd: > + grub2-editenv -v - set + kernelopts="root=UUID={{ root_uuid.stdout }} + {{ unified_boot_kernel_opts }}" + saved_entry={{ machine_id }}-{{ kernel_ver.stdout }} + creates: /boot/grub2/grubenv + +- name: Set permissions of new GRUB2 environment block + ansible.builtin.file: + path: /boot/grub2/grubenv + owner: root + group: root + mode: "0600" + +# Test if the size of GRUB2 environment block is correct +- name: Get size of GRUB2 environment block + ansible.builtin.stat: + path: /boot/grub2/grubenv + register: grubenv + +- name: Check if file size of GRUB2 environment block is 1024 bytes + ansible.builtin.assert: + that: + - grubenv.stat.size == 1024 + fail_msg: The file size of GRUB2 environment block is not 1024 bytes + success_msg: The file size of GRUB2 environment block is 1024 bytes + +# Test if grubby is able to identify absolute path of default kernel +- name: Get absolute path of default kernel using grubby + ansible.builtin.command: + cmd: grubby --default-kernel + register: default_kernel_path + changed_when: false + +- name: Check if grubby can correctly identify the default kernel + ansible.builtin.assert: + that: + - default_kernel_path.stdout == "/boot/vmlinuz-" ~ kernel_ver.stdout + fail_msg: Grubby could not found the absolute path of default kernel + success_msg: Grubby correctly identify the absolute path of default kernel diff --git a/ansible/roles/unified_boot/templates/grub_cfg_main.j2 b/ansible/roles/unified_boot/templates/grub_cfg_main.j2 new file mode 100644 index 0000000..618dc17 --- /dev/null +++ b/ansible/roles/unified_boot/templates/grub_cfg_main.j2 @@ -0,0 +1,25 @@ +set timeout=0 + +# load the grubenv file +load_env + +# selection of the next boot entry via variables 'next_entry' and +# `saved_entry` present in the 'grubenv' file. Both variables are +# set by grub tools, like grub2-reboot, grub2-set-default + +if [ "${next_entry}" ] ; then + set default="${next_entry}" + set next_entry= + save_env next_entry + set boot_once=true +else + set default="${saved_entry}" +fi + +search --no-floppy --set=root --fs-uuid {{ boot_uuid.stdout }} +set boot=${root} +function load_video { + insmod all_video +} +${serial}${terminal_input}${terminal_output} +blscfg diff --git a/ansible/roles/unified_boot/templates/grub_cfg_stub.j2 b/ansible/roles/unified_boot/templates/grub_cfg_stub.j2 new file mode 100644 index 0000000..ea67a25 --- /dev/null +++ b/ansible/roles/unified_boot/templates/grub_cfg_stub.j2 @@ -0,0 +1,4 @@ +search --no-floppy --fs-uuid --set=dev {{ boot_uuid.stdout }} +set prefix=($dev)/grub2 +export $prefix +configfile $prefix/grub.cfg diff --git a/msvsphere-8-gencloud.pkr.hcl b/msvsphere-8-gencloud.pkr.hcl index 4f958eb..be7d894 100644 --- a/msvsphere-8-gencloud.pkr.hcl +++ b/msvsphere-8-gencloud.pkr.hcl @@ -47,8 +47,12 @@ build { ansible_env_vars = [ "ANSIBLE_PIPELINING=True", "ANSIBLE_REMOTE_TEMP=/tmp", + "ANSIBLE_SCP_EXTRA_ARGS=-O", "ANSIBLE_SSH_ARGS='-o ControlMaster=no -o ControlPersist=180s -o ServerAliveInterval=120s -o TCPKeepAlive=yes -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedKeyTypes=+ssh-rsa'" ] - extra_arguments = ["--scp-extra-args", "'-O'"] + extra_arguments = [ + "--extra-vars", + "is_unified_boot=true", + ] } } diff --git a/msvsphere-8-yandexcloud.pkr.hcl b/msvsphere-8-yandexcloud.pkr.hcl index 62c3376..2ce34c8 100644 --- a/msvsphere-8-yandexcloud.pkr.hcl +++ b/msvsphere-8-yandexcloud.pkr.hcl @@ -47,8 +47,12 @@ build { ansible_env_vars = [ "ANSIBLE_PIPELINING=True", "ANSIBLE_REMOTE_TEMP=/tmp", + "ANSIBLE_SCP_EXTRA_ARGS=-O", "ANSIBLE_SSH_ARGS='-o ControlMaster=no -o ControlPersist=180s -o ServerAliveInterval=120s -o TCPKeepAlive=yes -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedKeyTypes=+ssh-rsa'" ] - extra_arguments = ["--scp-extra-args", "'-O'"] + extra_arguments = [ + "--extra-vars", + "is_unified_boot=true", + ] } }