From: cel@kernel.org
To: Luis Chamberlain <mcgrof@kernel.org>,
Daniel Gomez <da.gomez@kernel.org>,
Scott Mayhew <smayhew@redhat.com>
Cc: <kdevops@lists.linux.dev>, Chuck Lever <chuck.lever@oracle.com>
Subject: [RFC PATCH 3/3] Experimental: Add a separate install_linux role
Date: Tue, 22 Apr 2025 11:49:06 -0400 [thread overview]
Message-ID: <20250422154906.526319-4-cel@kernel.org> (raw)
In-Reply-To: <20250422154906.526319-1-cel@kernel.org>
From: Chuck Lever <chuck.lever@oracle.com>
Add a role that can grab the artifacts in workflows/linux/artifacts
and install them on all guests/instances.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
playbooks/install_linux.yml | 4 +
playbooks/roles/install_linux/README.md | 136 ++++++++++++
.../roles/install_linux/defaults/main.yml | 43 ++++
.../tasks/install-deps/debian/main.yml | 44 ++++
.../tasks/install-deps/redhat/main.yml | 76 +++++++
.../tasks/install-deps/suse/main.yml | 31 +++
playbooks/roles/install_linux/tasks/main.yml | 142 +++++++++++++
.../tasks/update-grub/debian.yml | 8 +
.../tasks/update-grub/install.yml | 196 ++++++++++++++++++
.../install_linux/tasks/update-grub/main.yml | 15 ++
.../tasks/update-grub/redhat.yml | 36 ++++
.../install_linux/tasks/update-grub/suse.yml | 11 +
workflows/linux/Makefile | 8 +
13 files changed, 750 insertions(+)
create mode 100644 playbooks/install_linux.yml
create mode 100644 playbooks/roles/install_linux/README.md
create mode 100644 playbooks/roles/install_linux/defaults/main.yml
create mode 100644 playbooks/roles/install_linux/tasks/install-deps/debian/main.yml
create mode 100644 playbooks/roles/install_linux/tasks/install-deps/redhat/main.yml
create mode 100644 playbooks/roles/install_linux/tasks/install-deps/suse/main.yml
create mode 100644 playbooks/roles/install_linux/tasks/main.yml
create mode 100644 playbooks/roles/install_linux/tasks/update-grub/debian.yml
create mode 100644 playbooks/roles/install_linux/tasks/update-grub/install.yml
create mode 100644 playbooks/roles/install_linux/tasks/update-grub/main.yml
create mode 100644 playbooks/roles/install_linux/tasks/update-grub/redhat.yml
create mode 100644 playbooks/roles/install_linux/tasks/update-grub/suse.yml
diff --git a/playbooks/install_linux.yml b/playbooks/install_linux.yml
new file mode 100644
index 000000000000..273ef4512f81
--- /dev/null
+++ b/playbooks/install_linux.yml
@@ -0,0 +1,4 @@
+---
+- hosts: all
+ roles:
+ - role: install_linux
diff --git a/playbooks/roles/install_linux/README.md b/playbooks/roles/install_linux/README.md
new file mode 100644
index 000000000000..0b440d2130b0
--- /dev/null
+++ b/playbooks/roles/install_linux/README.md
@@ -0,0 +1,136 @@
+bootlinux
+=========
+
+The ansible bootlinux lets you get, build and install Linux. It also lets you
+apply custom patches, remove kernels, etc. Anything you have to do with regards
+to generic kernel development. The defaults it will track one of the latest
+stable kernels that are still supported, using the linux stable git tree.
+
+Requirements
+------------
+
+You are expected to have an extra partition
+
+Role Variables
+--------------
+
+ * infer_uid_and_group: defaults to False, if set to True, then we will ignore
+ the passed on data_user and data_group and instead try to infer this by
+ inspecting the `whoami` and getent on the logged in target system we are
+ provisioning. So if user sam is running able on a host, targetting a system
+ called foofighter and logging into that system using username pincho,
+ then the data_user will be set overwritten and set to pincho. We will then
+ also lookup for pincho's default group id and use that for data_group.
+ This is useful if you are targetting a slew of systems and don't really
+ want to deal with the complexities of the username and group, and the
+ default target username you use to ssh into a system suffices to use as
+ a base. This is set to False to remain compatible with old users of
+ this role.
+ * data_path: where to place the git trees we clone under
+ * data_user: the user to assign permissions to
+ * data_group: the group to assign permissions to
+
+ * data_device: the target device to use for the data partition
+ * data_fstype: the filesystem to store the data parition under
+ * data_label: the label to use
+ * data_fs_opts: the filesystem options to use, you want to ensure to add the
+ label
+
+ * target_linux_admin_name: your developer name
+ * target_linux_admin_email: your email
+ * target_linux_git: the git tree to clone, by default this is the linux-stable
+ tree
+ * target_linux_tree: the name of the tree
+ * target_linux_dir_path: where to place the tree on the target system
+
+ * target_linux_ref : the actual tag as used on linux, so v4.19.62
+ * target_linux_extra_patch: if defined an extra patch to apply with git
+ am prior to compilation
+ * target_linux_config: the configuration file to use
+ * make: the make command to use
+ * target_linux_make_cmd: the actual full make command and its arguments
+ * target_linux_make_install_cmd: the install command
+
+Dependencies
+------------
+
+None.
+
+Example Playbook
+----------------
+
+Below is an example playbook, say a bootlinux.yml file:
+
+```
+---
+- hosts: all
+ roles:
+ - role: bootlinux
+```
+
+Custom runs
+===========
+
+Say you want to boot compile a vanilla kernel and you have created a new
+section under the hosts file called [dev], with a subset of the [all] section.
+You can compile say a vanilla kernel v4.19.58 with an extra set of patches we'd
+`git am` for you on top by using the following:
+
+```
+cd ansible
+ansible-playbook -i hosts -l dev --extra-vars "target_linux_extra_patch=pend-v4.19.58-fixes-20190716-v2.patch" bootlinux.yml
+```
+
+You'd place the `pend-v4.19.58-fixes-20190716-v2.patch` file on the directory
+`ansible/roles/bootlinux/templates/`.
+
+Now say you wantd to be explicit about a tag of Linux you'd want to use:
+
+```
+ansible-playbook -i hosts -l dev --extra-vars "target_linux_ref=v4.19.21 "target_linux_extra_patch=try-v4.19.20-fixes-20190716-v1.patch" bootlinux.yml
+```
+
+To uninstall a kernel:
+
+```
+ansible-playbook -i hosts -l dev --tags uninstall-linux --extra-vars "uninstall_kernel_ver=4.19.58+" bootlinux.yml
+```
+
+To ensure you can get the grub prompt:
+
+```bash
+ansible-playbook -i hosts --tags console,vars,manual-update-grub playbooks/bootlinux.yml
+```
+
+The ansible bootlinux role relies on the create_partition role to create a data
+partition where we can stuff code, and compile it. To test that aspect of
+the bootlinux role you can run:
+
+```
+ansible-playbook -i hosts -l baseline --tags data_partition,partition bootlinux.yml
+```
+
+To reboot all hosts:
+
+```bash
+ansible-playbook -i hosts bootlinux.yml --tags reboot
+```
+
+For further examples refer to one of this role's users, the
+[https://github.com/mcgrof/kdevops](kdevops) project or the
+[https://github.com/mcgrof/oscheck](oscheck) project from where
+this code originally came from.
+
+# TODO
+
+## Avoiding carrying linux-next configs
+
+It seems a waste of space to be adding configurations for linux-next for all
+tags. It seems easier to just look for the latest linux-next and try that.
+We just symlink linux-next files when we really need to, and when something
+really needs a new config, we then just add a new file.
+
+License
+-------
+
+copyleft-next-0.3.1
diff --git a/playbooks/roles/install_linux/defaults/main.yml b/playbooks/roles/install_linux/defaults/main.yml
new file mode 100644
index 000000000000..43edb3cafd79
--- /dev/null
+++ b/playbooks/roles/install_linux/defaults/main.yml
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier copyleft-next-0.3.1
+---
+kdevops_bootlinux: False
+infer_uid_and_group: False
+
+data_path: "/data"
+data_user: "vagrant"
+data_group: "vagrant"
+
+data_device: "/dev/disk/by-id/nvme-QEMU_NVMe_Ctrl_kdevops0"
+data_fstype: "xfs"
+data_label: "data"
+data_fs_opts: "-L {{ disk_setup_label }}"
+
+# Linux target defaults
+target_linux_admin_name: "Hacker Amanda"
+target_linux_admin_email: "devnull@kernel.org"
+target_linux_git: "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git"
+target_linux_shallow_depth: 0
+target_linux_tree: "linux-stable"
+target_linux_dir_path: "{{ data_path }}/{{ target_linux_tree }}"
+kdevops_baseline_and_dev: False
+
+target_linux_ref: "v4.19.133"
+target_linux_delta_file:
+target_linux_config: "config-{{ target_linux_ref }}"
+make: "make"
+# Once ansible v2.10 becomes available we can move on to using
+# ansible_processor_nproc but that was merged in 2020:
+# The commit is 34db57a47f875d11c4068567b9ec7ace174ec4cf
+# introduce fact "ansible_processor_nproc": number of usable vcpus #66569
+# https://github.com/ansible/ansible/pull/66569
+target_linux_make_cmd: "{{ make }} -j{{ ansible_processor_vcpus }}"
+target_linux_make_install_cmd: "{{ target_linux_make_cmd }} modules_install install"
+
+uninstall_kernel_enable: False
+
+build_artifacts_dir: "{{ topdir_path }}/workflows/linux/artifacts/"
+
+kdevops_workflow_enable_cxl: False
+
+bootlinux_cxl_test: False
+bootlinux_tree_set_by_cli: False
diff --git a/playbooks/roles/install_linux/tasks/install-deps/debian/main.yml b/playbooks/roles/install_linux/tasks/install-deps/debian/main.yml
new file mode 100644
index 000000000000..51b216e47b06
--- /dev/null
+++ b/playbooks/roles/install_linux/tasks/install-deps/debian/main.yml
@@ -0,0 +1,44 @@
+---
+# Install dependencies for building linux on Debian
+
+- name: Update apt cache
+ become: yes
+ become_method: sudo
+ apt:
+ update_cache: yes
+ tags: linux
+
+# apt-get build-dep does not capture all requirements
+- name: Install Linux kernel build dependencies
+ become: yes
+ become_method: sudo
+ apt:
+ name:
+ - bison
+ - flex
+ - git
+ - gcc
+ - make
+ - gawk
+ - bc
+ - dump
+ - indent
+ - sed
+ - libssl-dev
+ - libelf-dev
+ - liburcu-dev
+ - xfsprogs
+ - e2fsprogs
+ - btrfs-progs
+ - ntfs-3g
+ - mdadm
+ - rpcbind
+ - portmap
+ - hwinfo
+ - open-iscsi
+ - python3-pip
+ - zstd
+ - libncurses-dev
+ - b4
+ state: present
+ tags: linux
diff --git a/playbooks/roles/install_linux/tasks/install-deps/redhat/main.yml b/playbooks/roles/install_linux/tasks/install-deps/redhat/main.yml
new file mode 100644
index 000000000000..57a340979fcd
--- /dev/null
+++ b/playbooks/roles/install_linux/tasks/install-deps/redhat/main.yml
@@ -0,0 +1,76 @@
+---
+- name: Enable installation of packages from EPEL
+ ansible.builtin.include_role:
+ name: epel-release
+ when:
+ - ansible_distribution != "Fedora"
+
+- name: Install packages we care about
+ become: true
+ become_method: ansible.builtin.sudo
+ ansible.builtin.dnf:
+ update_cache: true
+ name: "{{ packages }}"
+ retries: 3
+ delay: 5
+ register: result
+ until: result is succeeded
+ vars:
+ packages:
+ - bison
+ - flex
+ - git-core
+ - e2fsprogs
+ - xfsprogs
+ - xfsdump
+ - lvm2
+ - gcc
+ - make
+ - gawk
+ - bc
+ - dump
+ - libtool
+ - psmisc
+ - sed
+ - vim
+ - fio
+ - libaio-devel
+ - diffutils
+ - net-tools
+ - ncurses-devel
+ - xfsprogs
+ - e2fsprogs
+ - elfutils-libelf-devel
+ - ntfs-3g
+ - mdadm
+ - rpcbind
+ - portmap
+ - hwinfo
+ - iscsi-initiator-utils
+ - openssl
+ - openssl-devel
+ - dwarves
+ - userspace-rcu
+ - zstd
+
+- name: Install btrfs-progs
+ become: true
+ become_method: ansible.builtin.sudo
+ ansible.builtin.dnf:
+ update_cache: true
+ name: "{{ packages }}"
+ retries: 3
+ delay: 5
+ register: result
+ until: result is succeeded
+ vars:
+ packages:
+ - btrfs-progs
+ when: ansible_distribution == 'Fedora'
+
+- name: Remove packages that mess with initramfs
+ become: true
+ become_method: ansible.builtin.sudo
+ ansible.builtin.dnf:
+ state: absent
+ name: dracut-config-generic
diff --git a/playbooks/roles/install_linux/tasks/install-deps/suse/main.yml b/playbooks/roles/install_linux/tasks/install-deps/suse/main.yml
new file mode 100644
index 000000000000..204a181b8237
--- /dev/null
+++ b/playbooks/roles/install_linux/tasks/install-deps/suse/main.yml
@@ -0,0 +1,31 @@
+---
+- name: Install Linux kernel build dependencies for SUSE sources
+ become: yes
+ become_method: sudo
+ zypper:
+ name:
+ - bison
+ - flex
+ - git-core
+ - gcc
+ - make
+ - gawk
+ - bc
+ - dump
+ - sed
+ - libopenssl-devel
+ - libelf-devel
+ - liburcu8
+ - diffutils
+ - net-tools
+ - ncurses-devel
+ - xfsprogs
+ - e2fsprogs
+ - btrfsprogs
+ - ntfs-3g
+ - mdadm
+ - rpcbind
+ - portmap
+ - hwinfo
+ - open-iscsi
+ disable_recommends: no
diff --git a/playbooks/roles/install_linux/tasks/main.yml b/playbooks/roles/install_linux/tasks/main.yml
new file mode 100644
index 000000000000..a0da4c110f6e
--- /dev/null
+++ b/playbooks/roles/install_linux/tasks/main.yml
@@ -0,0 +1,142 @@
+---
+- name: Include optional extra_vars
+ ansible.builtin.include_vars:
+ file: "{{ item }}"
+ with_first_found:
+ - files:
+ - "../extra_vars.yml"
+ - "../extra_vars.yaml"
+ - "../extra_vars.json"
+ skip: true
+ failed_when: false
+ tags: vars
+
+- name: Debian-specific set up
+ ansible.builtin.import_tasks: install-deps/debian/main.yml
+ when:
+ - ansible_os_family == "Debian"
+
+- name: Suse-specific set up
+ ansible.builtin.import_tasks: install-deps/suse/main.yml
+ when:
+ - ansible_os_family == "Suse"
+
+- name: Red Hat-specific set up
+ ansible.builtin.import_tasks: install-deps/redhat/main.yml
+ when:
+ - ansible_os_family == "RedHat"
+
+# We use "console serial" so to enable real consoles to be
+# preferred first, and fallback to the serial as secondary
+# option. This let's us work with hardware serial consoles
+# say on IPMIs and virtual guests ('virsh console').
+- name: Ensure we can get the GRUB prompt on reboot
+ become: true
+ become_flags: 'su - -c'
+ become_method: ansible.builtin.sudo
+ ansible.builtin.lineinfile:
+ path: /etc/default/grub
+ regexp: '^GRUB_TERMINAL='
+ line: GRUB_TERMINAL="console serial"
+ tags:
+ - linux
+ - git
+ - config
+ - console
+
+- name: Update the boot GRUB file
+ ansible.builtin.import_tasks: update-grub/main.yml
+ tags:
+ - linux
+ - uninstall-linux
+ - manual-update-grub
+ - console
+
+- name: Ensure DEFAULTDEBUG is set
+ become: true
+ become_flags: 'su - -c'
+ become_method: ansible.builtin.sudo
+ register: grub_default_saved_cmd
+ ansible.builtin.lineinfile:
+ path: /etc/sysconfig/kernel
+ regexp: '^DEFAULTDEBUG='
+ line: DEFAULTDEBUG=yes
+ when:
+ - ansible_os_family == "RedHat"
+ tags:
+ - linux
+ - git
+ - config
+ - saved
+
+- name: Install the built kernel RPMs on the target nodes
+ when:
+ - ansible_os_family == "RedHat"
+ tags:
+ - linux
+ - install-linux
+ block:
+ - name: Find the kernel build artifacts on the control host
+ delegate_to: localhost
+ ansible.builtin.find:
+ paths: "{{ build_artifacts_dir }}"
+ patterns: "*.rpm"
+ file_type: file
+ recurse: true
+ register: found_rpms
+
+ - name: Upload the kernel build artifacts to the target nodes
+ ansible.builtin.copy:
+ src: "{{ item.path }}"
+ dest: "/tmp"
+ mode: "u=rw,g=r,o=r"
+ loop: "{{ found_rpms.files }}"
+ loop_control:
+ label: "Uploading {{ item.path }}"
+
+ - name: Initialize list of packages to install
+ ansible.builtin.set_fact:
+ packages: []
+
+ - name: Build a list of packages to install
+ ansible.builtin.set_fact:
+ packages: "{{ packages + ['/tmp/' + item.path | basename ] }}"
+ loop: "{{ found_rpms.files }}"
+ loop_control:
+ label: "Adding {{ item.path }}"
+
+ - name: Install the kernel build artifacts on the target nodes
+ become: true
+ become_method: ansible.builtin.sudo
+ ansible.builtin.dnf:
+ name: "{{ packages }}"
+ state: present
+ disable_gpg_check: true
+
+- name: Set the default kernel on the target nodes
+ ansible.builtin.import_tasks: update-grub/install.yml
+ tags:
+ - linux
+ - git
+ - config
+ - saved
+
+- name: Reboot the target nodes into Linux {{ target_linux_tree }}
+ become: true
+ become_method: ansible.builtin.sudo
+ ansible.builtin.reboot:
+ tags:
+ - linux
+ - reboot
+
+- name: Refresh facts
+ ansible.builtin.gather_facts:
+
+- name: Check the uname on the target nodes
+ ansible.builtin.debug:
+ msg: "Target kernel {{ target_linux_ref }}; Running kernel {{ ansible_kernel }}"
+ tags:
+ - linux
+ - git
+ - config
+ - uname
diff --git a/playbooks/roles/install_linux/tasks/update-grub/debian.yml b/playbooks/roles/install_linux/tasks/update-grub/debian.yml
new file mode 100644
index 000000000000..3c7deea2161a
--- /dev/null
+++ b/playbooks/roles/install_linux/tasks/update-grub/debian.yml
@@ -0,0 +1,8 @@
+- name: Run update-grub
+ become: yes
+ become_flags: 'su - -c'
+ become_method: sudo
+ command: "update-grub"
+ register: grub_update
+ changed_when: "grub_update.rc == 0"
+ tags: [ 'linux', 'manual-update-grub', 'console' ]
diff --git a/playbooks/roles/install_linux/tasks/update-grub/install.yml b/playbooks/roles/install_linux/tasks/update-grub/install.yml
new file mode 100644
index 000000000000..17966af58210
--- /dev/null
+++ b/playbooks/roles/install_linux/tasks/update-grub/install.yml
@@ -0,0 +1,196 @@
+# There is slightly confusing user-experience and not complete documentation
+# about the requirements for using grub-set-default in light of the fact that
+# most Linux distributions use sub-menus. You need to use GRUB_DEFAULT=saved
+# there is a few caveats with its use which are not well documented anywhere
+# and I'm pretty sure tons of people are running into these issues.
+#
+# I'll document them here for posterity and so to justify the approach used
+# in kdevops to ensure we do boot the correct kernel.
+#
+# Some users erroneously claim that you also need GRUB_SAVEDEFAULT=true when
+# using GRUB_DEFAULT=saved but this is not true. The issue with using
+# GRUB_DEFAULT=saved which causes confusion is that most distributions
+# today use submenus folks do not take these into account when using
+# grub-set-default and the documentation about grub-set-default is not
+# clear about this requirement.
+#
+# Sadly, if you use a bogus kernel grub-set-default will not complain. For
+# example since most distributions use submenus, if you install a new kernel you
+# may end up in a situation as follows:
+#
+# menuentry 'Debian GNU/Linux' ... {
+# ...
+# }
+# submenu 'Advanced options for Debian GNU/Linux' ... {
+# menuentry 'Debian GNU/Linux, with Linux 5.16.0-4-amd64' ... {
+# ...
+# }
+# menuentry 'Debian GNU/Linux, with Linux 5.16.0-4-amd64 (recovery mode)' ... {
+# ...
+# }
+# menuentry 'Debian GNU/Linux, with Linux 5.10.105' ... {
+# ...
+# }
+# ... etc ...
+# }
+#
+# So under this scheme the 5.10.105 kernel is actually "1>2" and so if
+# you used:
+#
+# grub-set-default 3
+#
+# This would not return an error and you would expect it to work. This
+# is a bug in grub-set-default, it should return an error. The correct
+# way to set this with submenus would be:
+#
+# grub-set-default "1>2"
+#
+# However doing the reverse mapping is something which can get complicated
+# and there is no upstream GRUB2 support to do this for you. We can simplify
+# this problem instead by disabling the submenus, with GRUB_DISABLE_SUBMENU=y,
+# making the menu flat and then just querying for the linear mapping using
+# ansible using awk | grep and tail.
+#
+# So for instance, using GRUB_DISABLE_SUBMENU=y results in the following
+# options:
+#
+# vagrant@kdevops-xfs-nocrc ~ $ awk -F\' '/menuentry / {print $2}' /boot/grub/grub.cfg | awk '{print NR-1" ... "$0}'
+# 0 ... Debian GNU/Linux, with Linux 5.16.0-4-amd64
+# 1 ... Debian GNU/Linux, with Linux 5.16.0-4-amd64 (recovery mode)
+# 2 ... Debian GNU/Linux, with Linux 5.10.105
+# 3 ... Debian GNU/Linux, with Linux 5.10.105 (recovery mode)
+# 4 ... Debian GNU/Linux, with Linux 5.10.0-5-amd64
+# 5 ... Debian GNU/Linux, with Linux 5.10.0-5-amd64 (recovery mode)
+#
+# We have a higher degree of confidence with this structure when looking
+# for "5.10.105" that its respective boot entry 2 is the correct one. So we'd
+# now just use:
+#
+# grub-set-default 2
+- name: Ensure we have GRUB_DEFAULT=saved
+ become: true
+ become_flags: 'su - -c'
+ become_method: ansible.builtin.sudo
+ ansible.builtin.lineinfile:
+ path: /etc/default/grub
+ regexp: '^GRUB_DEFAULT='
+ line: GRUB_DEFAULT=saved
+ register: grub_default_saved_cmd
+ tags:
+ - linux
+ - git
+ - config
+ - saved
+
+- name: Use GRUB_DISABLE_SUBMENU=y to enable grub-set-default use with one digit
+ become: true
+ become_flags: 'su - -c'
+ become_method: ansible.builtin.sudo
+ register: grub_disable_submenu_cmd
+ ansible.builtin.lineinfile:
+ path: /etc/default/grub
+ regexp: '^GRUB_DISABLE_SUBMENU='
+ line: GRUB_DISABLE_SUBMENU=y
+ tags:
+ - linux
+ - git
+ - config
+ - saved
+
+- name: Update your boot GRUB file if necessary to ensure GRUB flat earth
+ ansible.builtin.import_tasks: update-grub/main.yml
+ tags:
+ - linux
+ - uninstall-linux
+ - manual-update-grub
+ - console
+
+- name: Read the artifacts release file
+ delegate_to: localhost
+ vars:
+ release_file: "{{ topdir_path }}/workflows/linux/artifacts/kernel.release"
+ ansible.builtin.set_fact:
+ kernelrelease: "{{ lookup('file', release_file) }}"
+
+- name: Show kernel release information
+ ansible.builtin.debug:
+ var: kernelrelease
+
+- name: Construct command line to determine default kernel ID
+ ansible.builtin.set_fact:
+ determine_default_kernel_id: >-
+ awk -F\' '/menuentry / {print $2}'
+ /boot/grub/grub.cfg | awk '{print NR-1" ... "$0}' |
+ grep {{ kernelrelease }} | head -1 | awk '{print $1}'
+ when:
+ - ansible_os_family != 'RedHat' or ansible_distribution_major_version | int < 8
+
+- name: Construct command line to determine default kernel ID for RHEL >= 8
+ ansible.builtin.set_fact:
+ determine_default_kernel_id: >-
+ for f in $(ls -1 /boot/loader/entries/*.conf); do
+ cat $f;
+ done | grep title | awk '{ gsub("title ", "", $0); print }' | grep '{{ kernelrelease }}';
+ when:
+ - ansible_os_family == "RedHat" and ansible_distribution_major_version | int >= 8
+
+# If this fails then grub-set-default won't be run, and the assumption here
+# is either you do the work to enhance the heuristic or live happy with the
+# assumption that grub2's default of picking the latest kernel is the best
+# option.
+- name: Try to find your target kernel's GRUB boot entry number now that the menu is flattened for {{ target_linux_ref }} using inferred KERNELRELEASE {{ kernelrelease}}
+ become: true
+ become_flags: 'su - -c'
+ become_method: ansible.builtin.sudo
+ vars:
+ target_kernel: "{{ target_linux_ref | replace('v', '') }}"
+ ansible.builtin.shell: " {{ determine_default_kernel_id }} "
+ register: grub_boot_number_cmd
+ tags:
+ - linux
+ - git
+ - config
+ - saved
+
+- name: Obtain command to set default kernel to boot
+ ansible.builtin.set_fact:
+ grub_set_default_boot_kernel: grub-set-default
+ when:
+ - ansible_os_family != "RedHat" or ansible_distribution_major_version | int < 8
+
+- name: Obtain command to set default kernel to boot for RHEL >= 8
+ ansible.builtin.set_fact:
+ grub_set_default_boot_kernel: grub2-set-default
+ when:
+ - ansible_os_family == "RedHat" and ansible_distribution_major_version | int >= 8
+
+- name: Set the target kernel to be booted by default
+ become: true
+ become_flags: 'su - -c'
+ become_method: ansible.builtin.sudo
+ vars:
+ target_boot_entry: "{{ grub_boot_number_cmd.stdout_lines.0 }}"
+ ansible.builtin.command: "{{ grub_set_default_boot_kernel }} \"{{ target_boot_entry }}\""
+ when:
+ - grub_boot_number_cmd.rc == 0
+ - grub_boot_number_cmd.stdout != ""
+ tags:
+ - linux
+ - git
+ - config
+ - saved
+
+- name: Itemize kernel and GRUB entry we just selected
+ vars:
+ target_kernel: "{{ target_linux_ref | replace('v', '') }}"
+ target_boot_entry: "{{ grub_boot_number_cmd.stdout_lines.0 }}"
+ ansible.builtin.debug:
+ msg: "{{ target_kernel }} determined to be {{ target_boot_entry }} on the GRUB2 flat menu. Ran: grub-set-default {{ target_boot_entry }}"
+ when:
+ - grub_boot_number_cmd.rc == 0
+ - grub_boot_number_cmd.stdout != ""
+ tags:
+ - linux
+ - git
+ - config
+ - saved
diff --git a/playbooks/roles/install_linux/tasks/update-grub/main.yml b/playbooks/roles/install_linux/tasks/update-grub/main.yml
new file mode 100644
index 000000000000..a565e0ac26ac
--- /dev/null
+++ b/playbooks/roles/install_linux/tasks/update-grub/main.yml
@@ -0,0 +1,15 @@
+---
+- name: Debian-specific grub update
+ ansible.builtin.import_tasks: debian.yml
+ when:
+ - ansible_os_family == "Debian"
+
+- name: Red Hat-specific grub update
+ ansible.builtin.import_tasks: redhat.yml
+ when:
+ - ansible_os_family == "RedHat"
+
+- name: Suse-specific grub update
+ ansible.builtin.import_tasks: suse.yml
+ when:
+ - ansible_os_family == "Suse"
diff --git a/playbooks/roles/install_linux/tasks/update-grub/redhat.yml b/playbooks/roles/install_linux/tasks/update-grub/redhat.yml
new file mode 100644
index 000000000000..11a92f34bab6
--- /dev/null
+++ b/playbooks/roles/install_linux/tasks/update-grub/redhat.yml
@@ -0,0 +1,36 @@
+- name: Disable Grub menu auto-hide
+ become: true
+ become_flags: 'su - -c'
+ become_method: ansible.builtin.sudo
+ ansible.builtin.command: "grub2-editenv - unset menu_auto_hide"
+ register: grub_edit
+ changed_when: "grub_edit.rc == 0"
+
+- name: Determine if system was booted using UEFI
+ ansible.builtin.stat:
+ path: "/sys/firmware/efi/efivars"
+ register: efi_boot
+
+- name: Use /etc/grub2.cfg as the grub configuration file
+ ansible.builtin.set_fact:
+ grub_config_file: "/etc/grub2.cfg"
+ when:
+ - not efi_boot.stat.exists
+
+- name: Use /etc/grub2-efi.cfg as the configuration file
+ ansible.builtin.set_fact:
+ grub_config_file: "/etc/grub2-efi.cfg"
+ when:
+ - efi_boot.stat.exists
+
+- name: Run update-grub
+ become: true
+ become_flags: 'su - -c'
+ become_method: ansible.builtin.sudo
+ ansible.builtin.command: "grub2-mkconfig -o {{ grub_config_file }}"
+ register: grub_update
+ changed_when: "grub_update.rc == 0"
+ tags:
+ - linux
+ - manual-update-grub
+ - console
diff --git a/playbooks/roles/install_linux/tasks/update-grub/suse.yml b/playbooks/roles/install_linux/tasks/update-grub/suse.yml
new file mode 100644
index 000000000000..1cb1fdc55f58
--- /dev/null
+++ b/playbooks/roles/install_linux/tasks/update-grub/suse.yml
@@ -0,0 +1,11 @@
+- name: Run update-grub
+ become: true
+ become_flags: 'su - -c'
+ become_method: ansible.builtin.sudo
+ ansible.builtin.command: "update-bootloader --refresh"
+ register: grub_update
+ changed_when: "grub_update.rc == 0"
+ tags:
+ - linux
+ - manual-update-grub
+ - console
diff --git a/workflows/linux/Makefile b/workflows/linux/Makefile
index bb7441e71fda..06722d5903b3 100644
--- a/workflows/linux/Makefile
+++ b/workflows/linux/Makefile
@@ -85,6 +85,7 @@ linux-help-menu:
@echo "linux-grub-setup - Ensures the appropriate target kernel is set to boot"
@echo "linux-reboot - Reboot guests"
@echo "linux-packages - Clones, builds, and packages a Linux kernel"
+ @echo "linux-artifacts - Installs artifacts generated by 'linux-packages'"
@echo "uname - Prints current running kernel"
PHONY += linux-help-end
@@ -166,6 +167,13 @@ linux-packages:
$(KDEVOPS_PLAYBOOKS_DIR)/build_linux.yml \
--extra-vars="$(BOOTLINUX_ARGS)" $(LIMIT_HOSTS)
+PHONY += linux-artifacts
+linux-artifacts:
+ $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ -i $(KDEVOPS_HOSTFILE) \
+ $(KDEVOPS_PLAYBOOKS_DIR)/install_linux.yml \
+ --extra-vars="$(BOOTLINUX_ARGS)" $(LIMIT_HOSTS)
+
PHONY += uname
uname:
$(Q)ansible all -i hosts -b -m command -a "uname -r" -o \
--
2.49.0
next prev parent reply other threads:[~2025-04-22 15:49 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-22 15:49 [RFC PATCH 0/3] Build once, test everywhere cel
2025-04-22 15:49 ` [RFC PATCH 1/3] Add a guest/instance for building the test kernel cel
2025-04-22 15:49 ` [RFC PATCH 2/3] playbooks: Add a build_linux role cel
2025-04-22 15:49 ` cel [this message]
2025-04-23 5:27 ` [RFC PATCH 0/3] Build once, test everywhere Luis Chamberlain
2025-04-23 12:34 ` Daniel Gomez
2025-04-23 13:36 ` Chuck Lever
2025-04-23 17:28 ` Daniel Gomez
2025-04-24 13:51 ` Chuck Lever
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250422154906.526319-4-cel@kernel.org \
--to=cel@kernel.org \
--cc=chuck.lever@oracle.com \
--cc=da.gomez@kernel.org \
--cc=kdevops@lists.linux.dev \
--cc=mcgrof@kernel.org \
--cc=smayhew@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox