Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Initialize a bootloader role #71

Merged
merged 1 commit into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
247 changes: 209 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,66 +6,237 @@ An Ansible role for bootloader and kernel command line management.

## Requirements

Any pre-requisites that may not be covered by Ansible itself or the role should
be mentioned here. For instance, if the role uses the EC2 module, it may be a
good idea to mention in this section that the `boto` package is required.
None

## Role Variables

A description of all input variables (i.e. variables that are defined in
`defaults/main.yml`) for the role should go here as these form an API of the
role.
### bootloader_gather_facts

Variables that are not intended as input, like variables defined in
`vars/main.yml`, variables that are read from other roles and/or the global
scope (ie. hostvars, group vars, etc.) can be also mentioned here but keep in
mind that as these are probably not part of the role API they may change during
the lifetime.
Whether to gather `bootloader_facts` that contain bot information for all kernels.

Example of setting the variables:
Default: `false`

Type: `bool`

### bootloader_settings
spetrosi marked this conversation as resolved.
Show resolved Hide resolved

With this variable, list kernels and their command line parameters that you want to set.

Required keys:

1. `kernel` - with this, specify the kernel to update settings for.
You can specify one or more kernels using the following criteria, you can use only single criteria at a time:

* `kernel_path` - a specific kernel path, can be a list of paths
* `kernel_index` - a specific kernel index, can be a list of indexes
* `kernel_title` - a specific kernel title, can be a list of titles
* `DEFAULT` - to update the default entry
* `ALL` - to update all of the entries

2. `options` - with this, specify settings to update

* `name` - The name of the setting. `name` is omitted when using `replaced`.
* `value` - The value for the setting. You must omit `value` if the setting has no value, e.g. `quiet`.
* `state` - `present` (default) or `absent`. The value `absent` means to remove a setting with `name` name - name must be provided.
* `previous` - Optional - the only value is `replaced` - this is used to specify that the previous settings should be replaced with the given settings.

Example:

```yaml
bootloader_foo: "oof"
bootloader_bar: "baz"
bootloader_settings:
- kernel:
kernel_path: /boot/vmlinuz-0-rescue-1
options:
- name: console
value: tty0
state: present
- previous: replaced
- kernel:
kernel_index: [1, 2, 3]
options:
- name: print-fatal-signals
value: 1
- kernel:
kernel_title: Red Hat Enterprise Linux (4.1.1.1.el8.x86_64) 8
options:
- name: no_timer_check
- kernel:
kernel_path: /boot/vmlinuz-0-rescue-1
options:
- name: console
value: tty0
- name: print-fatal-signals
value: 1
- name: no_timer_check
state: present
- previous: replaced
- kernel: ALL
options:
- name: debug
state: present
- kernel: DEFAULT
options:
- name: quiet
state: present
```

Default: `{}`

Type: `dict`

### bootloader_timeout

With this variable, you can customize the loading time of the GRUB bootloader.

Default: `5`

Type: `int`

### bootloader_password

With this variable, you can protect boot parameters with a password.

__WARNING__: Changing bootloader password is not idempotent.

Boot loader username is always `root`.

This should come from vault.

If unset, current configuration is not touched.

Default: `null`

Type: `string`

### bootloader_remove_password

By setting this variable to `true`, you can remove bootloader password.

Default: `false`

Type: `bool`

### bootloader_reboot_ok

If `true`, if the role detects that something was changed that requires a reboot to take effect, the role will reboot the managed host.

If `false`, it is up to you to determine when to reboot the managed host.

The role will returns the variable `bootloader_reboot_required` (see below) with a value of `true` to indicate that some change has occurred which needs a reboot to take effect.

Default: `false`

Type: `bool`

### Variables Exported by the Role

This section is optional. Some roles may export variables for playbooks to
use later. These are analogous to "return values" in Ansible modules. For
example, if a role performs some action that will require a system reboot, but
the user wants to defer the reboot, the role might set a variable like
`bootloader_reboot_needed: true` that the playbook can use to reboot at a more
convenient time.
The role exports the following variables:

Example:
#### bootloader_reboot_needed

`bootloader_reboot_needed` - default `false` - if `true`, this means
a reboot is needed to apply the changes made by the role
Default `false` - if `true`, this means a reboot is needed to apply the changes made by the role

## Example Playbook
#### bootloader_facts

Including an example of how to use your role (for instance, with variables
passed in as parameters) is always nice for users too:
Contains boot information for all kernels.

The role returns this variable when you set `bootloader_gather_facts: true`.

For example:

```yaml
"bootloader_facts": [
{
"args": "ro rootflags=subvol=root rd.luks.uuid=luks-9da1fdf5-14ac-49fd-a388-8b1ee48f3df1 rhgb quiet",
"id": "luks-9da1fdf5-14ac-49fd-a388-8b1ee48f3df1 rhgb quiet",
"index": "3",
"initrd": "/boot/initramfs-0-rescue-c44543d15b2c4e898912c2497f734e67.img",
"kernel": "/boot/vmlinuz-0-rescue-c44543d15b2c4e898912c2497f734e67",
"root": "UUID=65c70529-e9ad-4778-9001-18fe8c525285",
"title": "Fedora Linux (0-rescue-c44543d15b2c4e898912c2497f734e67) 36 (Workstation Edition)",
"default": True
},
{
"args": "ro rootflags=subvol=root rd.luks.uuid=luks-9da1fdf5-14ac-49fd-a388-8b1ee48f3df1 rhgb quiet $tuned_params",
"id": "luks-9da1fdf5-14ac-49fd-a388-8b1ee48f3df1 rhgb quiet $tuned_params",
"index": "2",
"initrd": "/boot/initramfs-6.3.12-100.fc37.x86_64.img $tuned_initrd",
"kernel": "/boot/vmlinuz-6.3.12-100.fc37.x86_64",
"root": "UUID=65c70529-e9ad-4778-9001-18fe8c525285",
"title": "Fedora Linux (6.3.12-100.fc37.x86_64) 37 (Workstation Edition)",
"default": False
},
{
"args": "ro rootflags=subvol=root rd.luks.uuid=luks-9da1fdf5-14ac-49fd-a388-8b1ee48f3df1 rhgb quiet $tuned_params",
"id": "luks-9da1fdf5-14ac-49fd-a388-8b1ee48f3df1 rhgb quiet $tuned_params",
"index": "1",
"initrd": "/boot/initramfs-6.4.15-100.fc37.x86_64.img $tuned_initrd",
"kernel": "/boot/vmlinuz-6.4.15-100.fc37.x86_64",
"root": "UUID=65c70529-e9ad-4778-9001-18fe8c525285",
"title": "Fedora Linux (6.4.15-100.fc37.x86_64) 37 (Workstation Edition)",
"default": False
},
{
"args": "ro rootflags=subvol=root rd.luks.uuid=luks-9da1fdf5-14ac-49fd-a388-8b1ee48f3df1 rhgb quiet $tuned_params",
"id": "luks-9da1fdf5-14ac-49fd-a388-8b1ee48f3df1 rhgb quiet $tuned_params",
"index": "0",
"initrd": "/boot/initramfs-6.5.7-100.fc37.x86_64.img $tuned_initrd",
"kernel": "/boot/vmlinuz-6.5.7-100.fc37.x86_64",
"root": "UUID=65c70529-e9ad-4778-9001-18fe8c525285",
"title": "Fedora Linux (6.5.7-100.fc37.x86_64) 37 (Workstation Edition)",
"default": False
}
]
```

## Example Playbook

```yaml
- hosts: all
vars:
bootloader_foo: "foo foo!"
bootloader_bar: "progress bar"

bootloader_settings:
- kernel:
kernel_path: /boot/vmlinuz-0-rescue-1
options:
- name: console
value: tty0
state: present
- previous: replaced
- kernel:
kernel_index: [1, 2, 3]
options:
- name: print-fatal-signals
value: 1
- kernel:
kernel_title: Red Hat Enterprise Linux (4.1.1.1.el8.x86_64) 8
options:
- name: no_timer_check
- kernel:
kernel_path: /boot/vmlinuz-0-rescue-1
options:
- name: console
value: tty0
- name: print-fatal-signals
value: 1
- name: no_timer_check
state: present
- previous: replaced
- kernel: ALL
options:
- name: debug
state: present
- kernel: DEFAULT
spetrosi marked this conversation as resolved.
Show resolved Hide resolved
options:
- name: quiet
state: present
bootloader_timeout: 5
bootloader_password: null
bootloader_remove_password: false
bootloader_reboot_ok: true
roles:
- linux-system-roles.bootloader
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have some examples of that show the kernel command line before running the role, and what the command line looks like after running the role will various parameters e.g.

before
args="rhgb quiet"

with parameters as above will result in
args="rhgb quiet crashkernel=auto no_timer_check debug rd.lvm.lv resume"

with parameters as above with `previous: replaced` will result in
args="quiet crashkernel=auto no_timer_check debug rd.lvm.lv resume"

most people using this role will be familiar with grubby other tools that let you edit the kernel command line in a similar format, so having examples like that should help.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WIll do


More examples can be provided in the [`examples/`](examples) directory. These
can be useful especially for documentation.

## License

Whenever possible, please prefer MIT.

## Author Information

An optional section for the role authors to include contact information, or a
website (HTML is not allowed).
MIT
14 changes: 8 additions & 6 deletions defaults/main.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# SPDX-License-Identifier: MIT
---
# Here is the right place to put the role's input variables.
# This file also serves as a documentation for such a variables.
bootloader_settings: []
bootloader_timeout: 5

# Examples of role input variables:
bootloader_foo: "foo"
bootloader_bar: "bar"
bootloader_password: null
bootloader_remove_password: false

bootloader_reboot_ok: false

bootloader_gather_facts: false
8 changes: 0 additions & 8 deletions examples/simple.yml

This file was deleted.

28 changes: 21 additions & 7 deletions handlers/main.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
# SPDX-License-Identifier: MIT
---
# Put handlers for tasks here.
# EL 7 workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1152027
- name: Fix default kernel boot parameters
shell: |-
set -o pipefail
grubby --info=DEFAULT | awk '/^args/ {print $0}'
cat {{ __bootloader_default_grub }}
eval $(grubby --info=DEFAULT | awk '/^args/ {print $0}')
sed -i -e "s|^GRUB_CMDLINE_LINUX=.*|GRUB_CMDLINE_LINUX=\"$args\"|" \
{{ __bootloader_default_grub }}
cat {{ __bootloader_default_grub }}
changed_when: true
when: >-
(ansible_distribution in ['CentOS', 'RedHat'] and
ansible_facts.distribution_major_version is version('7', '=')) or
ansible_distribution == 'Fedora'

# Example:
- name: Bootloader handler to restart services
service:
name: "{{ item }}"
state: restarted
loop: "{{ __bootloader_services }}"
- name: Rebuild grub config
command: grub2-mkconfig -o {{ __bootloader_grub_conf }}
changed_when: true

- name: Reboot system
include_tasks: tasks/reboot.yml
Loading
Loading