diff --git a/README.md b/README.md index f882bd0..ad3e562 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,9 @@ These are the variables that can be passed to the role: |----------|-------------|------| | `nbde_client_provider` | `clevis`| identifies the provider for the `nbde_client` role. We currently support `clevis`.| | `nbde_client_bindings` | | a list containing binding configurations, which include e.g. devices and slots. | -| `nbde_client_early_boot` | `true` | by default nbde_client will configure the initrd to unlock the volume. This may need to be disabled if the managed host is using static IP addressing, or if the volume should be unlocked by clevis-luks-askpass | +| `nbde_client_early_boot` | `true` | by default nbde_client will configure the initrd to unlock the volume. This may need to be disabled if the volume should be unlocked by clevis-luks-askpass. For managed hosts with static IP addressing, prefer `nbde_client_extra_dracut_settings` instead of disabling early boot. | | `nbde_client_secure_logging` | `true` | If true, suppress potentially sensitive output from tasks that handle credentials, secrets, and other sensitive data. Set to false for debugging issues with credential handling or secret management, but be aware this may expose sensitive information in logs. | +| `nbde_client_extra_dracut_settings` | `[]` | a list of extra dracut configuration lines written to `/etc/dracut.conf.d/nbde_client.conf` in addition to the role's implicit platform settings. Use this for static IP early-boot networking and other custom dracut options. Requires `nbde_client_early_boot: true` (the default); the role fails if early boot is disabled. | ### nbde_client_bindings @@ -57,6 +58,24 @@ nbde_client_bindings: - http://server2.example.com ``` +### nbde_client_extra_dracut_settings + +`nbde_client_extra_dracut_settings` is a list of strings. Each string is written +as a line in `/etc/dracut.conf.d/nbde_client.conf`, after the implicit +platform-specific settings from `__nbde_client_dracut_settings`. + +This is useful for NBDE clients that use static IP addressing and need network +configuration available during early boot. For example: + +```yaml +nbde_client_extra_dracut_settings: + - kernel_cmdline+=" ip=192.0.2.10::192.0.2.1:255.255.255.0::ens3:none nameserver=192.0.2.100 " +``` + +**Note:** You cannot set `nbde_client_early_boot: false` when using +`nbde_client_extra_dracut_settings`. Extra dracut settings are only written when +early boot is enabled. The role fails if both are set this way. + ## Example Playbooks ### Example 1: high availability diff --git a/defaults/main.yml b/defaults/main.yml index 220496d..8b7040a 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -23,4 +23,10 @@ nbde_client_early_boot: true nbde_client_bindings: [] nbde_client_secure_logging: true +# Extra lines written to /etc/dracut.conf.d/nbde_client.conf in addition to +# the platform-specific __nbde_client_dracut_settings. Each list item is a +# full dracut configuration line, for example: +# - kernel_cmdline+=" ip=192.0.2.10::192.0.2.1:255.255.255.0::ens3:none nameserver=192.0.2.100 " +nbde_client_extra_dracut_settings: [] + # vim:set ts=2 sw=2 et: diff --git a/tasks/main-clevis.yml b/tasks/main-clevis.yml index 2dc6a5e..196cdab 100644 --- a/tasks/main-clevis.yml +++ b/tasks/main-clevis.yml @@ -22,6 +22,7 @@ owner: root mode: '0444' when: nbde_client_early_boot | bool + notify: Handle nbde_client update initramfs - name: Check whether devices are at the desired state when: diff --git a/tasks/main.yml b/tasks/main.yml index e6462d9..79fa9da 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,5 +1,16 @@ # SPDX-License-Identifier: MIT --- +- name: Fail when extra dracut settings are set but early boot is disabled + fail: + msg: >- + nbde_client_extra_dracut_settings requires nbde_client_early_boot + to be true. nbde_client_extra_dracut_settings has + {{ nbde_client_extra_dracut_settings | length }} entries, but + nbde_client_early_boot is false so they will not be written. + when: + - not nbde_client_early_boot + - nbde_client_extra_dracut_settings | length > 0 + # Set up internal variables. - name: Set version specific variables include_tasks: set_vars.yml diff --git a/templates/nbde_client.conf b/templates/nbde_client.conf index 620ca83..6c3b1e5 100644 --- a/templates/nbde_client.conf +++ b/templates/nbde_client.conf @@ -1,6 +1,6 @@ # nbde_client dracut config {{ ansible_managed | comment }} {{ "system_role:nbde_client" | comment(prefix="", postfix="") }} -{% for line in __nbde_client_dracut_settings %} +{% for line in __nbde_client_dracut_settings + nbde_client_extra_dracut_settings %} {{ line }} {% endfor %} diff --git a/tests/tests_default_vars.yml b/tests/tests_default_vars.yml index e1a4ed4..5a63a88 100644 --- a/tests/tests_default_vars.yml +++ b/tests/tests_default_vars.yml @@ -14,5 +14,6 @@ that: - nbde_client_provider is defined - nbde_client_bindings is defined + - nbde_client_extra_dracut_settings is defined # vim:set ts=2 sw=2 et: diff --git a/tests/tests_extra_dracut_settings.yml b/tests/tests_extra_dracut_settings.yml new file mode 100644 index 0000000..b10506d --- /dev/null +++ b/tests/tests_extra_dracut_settings.yml @@ -0,0 +1,111 @@ +# Generated by: Cursor using models Cursor Grok 4.5, Composer 2.5, Sonnet 5 +--- +- name: Test nbde_client_extra_dracut_settings + hosts: all + vars: + __nbde_client_test_extra_dracut_line: >- + kernel_cmdline+=" ip=192.0.2.10::192.0.2.1:255.255.255.0::ens3:none nameserver=192.0.2.100 " + nbde_client_extra_dracut_settings: + - "{{ __nbde_client_test_extra_dracut_line }}" + + tasks: + - name: Run the test + block: + - name: Use nbde_client role + include_tasks: tasks/run_role_with_clear_facts.yml + vars: + __sr_public: true + + - name: Read generated dracut config + slurp: + src: /etc/dracut.conf.d/nbde_client.conf + register: __nbde_client_dracut_conf + + - name: Decode dracut config content + set_fact: + __nbde_client_dracut_conf_content: "{{ + __nbde_client_dracut_conf.content | b64decode }}" + + - name: Verify extra dracut setting is present + assert: + that: + - __nbde_client_test_extra_dracut_line in + __nbde_client_dracut_conf_content + fail_msg: >- + Expected /etc/dracut.conf.d/nbde_client.conf to contain + {{ __nbde_client_test_extra_dracut_line }}. Content was: + {{ __nbde_client_dracut_conf_content }} + + - name: Verify implicit dracut settings are present + assert: + that: + - item in __nbde_client_dracut_conf_content + fail_msg: >- + Expected /etc/dracut.conf.d/nbde_client.conf to contain + implicit setting {{ item }}. Content was: + {{ __nbde_client_dracut_conf_content }} + loop: "{{ __nbde_client_dracut_settings }}" + + - name: Use nbde_client role again for idempotency + include_tasks: tasks/run_role_with_clear_facts.yml + vars: + __sr_public: true + + - name: Re-read generated dracut config + slurp: + src: /etc/dracut.conf.d/nbde_client.conf + register: __nbde_client_dracut_conf_again + + - name: Verify dracut config is unchanged after second run + assert: + that: + - __nbde_client_dracut_conf.content == + __nbde_client_dracut_conf_again.content + fail_msg: Dracut config changed on second role run + + - name: Run the role with early boot disabled + vars: + nbde_client_early_boot: false + nbde_client_extra_dracut_settings: + - >- + kernel_cmdline+=" ip=192.0.2.10::192.0.2.1:255.255.255.0::ens3:none + nameserver=192.0.2.100 " + block: + - name: Use nbde_client role with conflicting settings + include_tasks: tasks/run_role_with_clear_facts.yml + + - name: Fail if the role did not reject conflicting settings + fail: + msg: >- + Role should fail when nbde_client_early_boot is false and + nbde_client_extra_dracut_settings is set + + rescue: + - name: Assert the early boot conflict error message + assert: + that: + - >- + 'nbde_client_extra_dracut_settings requires + nbde_client_early_boot' in ansible_failed_result.msg + fail_msg: >- + Unexpected failure: + {{ ansible_failed_result.msg | default(ansible_failed_result) }} + + always: + - name: Clean up generated dracut config + file: + path: /etc/dracut.conf.d/nbde_client.conf + state: absent + tags: + - tests::cleanup + + - name: Run the role with no settings to clean up + include_tasks: tasks/run_role_with_clear_facts.yml + vars: + nbde_client_extra_dracut_settings: [] + nbde_client_early_boot: true + nbde_client_bindings: [] + tags: + - tests::cleanup + +# vim:set ts=2 sw=2 et: