From 3265cffbd6cefc0dd33f546736360271d044ede1 Mon Sep 17 00:00:00 2001 From: Christopher Palmer-Richez Date: Tue, 12 Nov 2024 20:43:29 -0500 Subject: [PATCH] Work so far on the test vm. This commit does not provide a complete testing setup. We are running into a limitation on ansible-test, where we can't provide a custom inventory file without using the libvirt inventory plugin, but we can't use SELinux with that plugn. We need to switch to a Makefile or something else to generate an inventory file, then we can delegate properly. --- tests/integration/config.yml | 5 +- .../targets/role_uki/tasks/main.yml | 34 ++ .../targets/role_uki/tasks/setup_libvirt.yml | 312 +++++++++--------- .../targets/role_uki/templates/user-data.yml | 2 +- 4 files changed, 193 insertions(+), 160 deletions(-) diff --git a/tests/integration/config.yml b/tests/integration/config.yml index 9904fdf..43dddae 100644 --- a/tests/integration/config.yml +++ b/tests/integration/config.yml @@ -1,2 +1,5 @@ --- -test_image: /var/lib/libvirt/images/Fedora-Server-KVM-40-1.14.x86_64.qcow2 +test_image: /var/lib/libvirt/images/Fedora-Cloud-Base-Generic.x86_64-40-1.14.qcow2 +test_user: tofugarden +ssh_key: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFjZqopqmgB4mFy7CHVXU7Wfq2M2FUfABWpXal3m5UM0 tofugarden@code.chorky.net +test_ansible_python_interpreter: /home/tofugarden/.local/share/python/venvs/ansible/bin/python3.12 diff --git a/tests/integration/targets/role_uki/tasks/main.yml b/tests/integration/targets/role_uki/tasks/main.yml index 319288f..54e809f 100644 --- a/tests/integration/targets/role_uki/tasks/main.yml +++ b/tests/integration/targets/role_uki/tasks/main.yml @@ -7,6 +7,8 @@ vars: ansible_python_interpreter: "{{ test_ansible_python_interpreter }}" ansible.builtin.wait_for: + delay: 10 + sleep: 5 timeout: 180 host: "172.16.199.2" port: 22 @@ -16,6 +18,38 @@ - name: Delegate to the provisioned guest delegate_to: "172.16.199.2" block: + - name: Wait a few seconds to let everything settle + ansible.builtin.pause: + seconds: 5 + + + - name: Send the MOK cert to the test machine + ansible.builtin.copy: + src: "{{ tempdir.path }}/MOK.pem" + dest: /etc/kernel/MOK.pem + mode: "0644" + owner: root + group: root + setype: cert_t + + - name: Send the MOK der cert to the test machine + ansible.builtin.copy: + src: "{{ tempdir.path }}/MOK.der" + dest: /etc/kernel/MOK.der + mode: "0644" + owner: root + group: root + setype: cert_t + + - name: Send the MOK private key to the test machine + ansible.builtin.copy: + src: "{{ tempdir.path }}/MOK.priv" + dest: /etc/kernel/MOK.priv + mode: "0600" + owner: root + group: root + setype: cert_t + - name: Run role vars: ansible_python_interpreter: auto diff --git a/tests/integration/targets/role_uki/tasks/setup_libvirt.yml b/tests/integration/targets/role_uki/tasks/setup_libvirt.yml index 2f65c4f..6a3fcc4 100644 --- a/tests/integration/targets/role_uki/tasks/setup_libvirt.yml +++ b/tests/integration/targets/role_uki/tasks/setup_libvirt.yml @@ -1,161 +1,157 @@ --- -- name: Run this task file on the controller - connection: local - delegate_to: localhost +- name: Include the test_image variable + ansible.builtin.include_vars: + file: testimage.yml + +- name: Get a temporary dir + ansible.builtin.tempfile: + suffix: crichez.secureboot.uki + state: directory + register: tempdir + +- name: Install virt-firmware + ansible.builtin.pip: + name: virt-firmware + version: "24.7" + +- name: Generate a MOK block: - - name: Include the test_image variable - ansible.builtin.include_vars: - file: testimage.yml - - - name: Get a temporary dir - ansible.builtin.tempfile: - suffix: crichez.secureboot.uki - state: directory - register: tempdir - - - name: Install virt-firmware - ansible.builtin.pip: - name: virt-firmware - version: "24.7" - - - name: Generate a MOK - block: - - name: Generate a 2048 bit RSA private key - community.crypto.openssl_privatekey: - path: "{{ tempdir.path }}/MOK.priv" - size: 2048 - type: RSA - mode: "0600" - setype: cert_t - - - name: Generate a self-signed certificate - community.crypto.x509_certificate: - path: "{{ tempdir.path }}/MOK.pem" - privatekey_path: "{{ tempdir.path }}/MOK.priv" - provider: selfsigned - mode: "0644" - setype: cert_t - - - name: Get a DER-encoded version - community.crypto.x509_certificate_convert: - src_path: "{{ tempdir.path }}/MOK.pem" - dest_path: "{{ tempdir.path }}/MOK.der" - format: der - mode: "0644" - setype: cert_t - - - name: Enroll the MOK into a new firmware image file - ansible.builtin.command: - argv: - - virt-fw-vars - - --input - - /usr/share/OVMF/OVMF_VARS.secboot.fd - - --output - - "{{ tempdir.path }}/OVMF_VARS.custom.fd" - - --enroll-redhat - - --secure-boot - - --add-mok - - f0c54306-e762-41a6-8dd4-4901c73e905b - - "{{ tempdir.path }}/MOK.der" - creates: "{{ tempdir.path }}/OVMF_VARS.custom.fd" - - - name: Set permissions on the firmware image file - ansible.builtin.file: - path: "{{ tempdir.path }}/OVMF_VARS.custom.fd" - mode: "0660" - setype: tmp_t - - - name: Write a the cloud-init datasource - become: true - vars: - nocloud_path: "/var/lib/libvirt/images/cloud-init:crichez.secureboot.img" - nocloud_mount: "/mnt/cloud-init:crichez.secureboot" - block: - - name: Create an empty file to write the nocloud image to - community.general.filesize: - mode: "0644" - path: "{{ nocloud_path }}" - size: 2MB - - - name: Write the nocloud image file - ansible.builtin.command: - argv: - - mkfs.vfat - - -n - - cidata - - "{{ nocloud_path }}" - register: mkfs_cmd - changed_when: mkfs_cmd is not failed - - - name: Mount the image file - ansible.posix.mount: - boot: false - fstype: vfat - path: "{{ nocloud_mount }}" - src: "{{ nocloud_path }}" - state: ephemeral - - - name: Write cloud-init metadata - ansible.builtin.template: - src: "meta-data.yml" - dest: "{{ nocloud_mount }}/meta-data" - mode: "0644" - - - name: Write cloud-init network configuration - ansible.builtin.template: - src: "network-config.yml" - dest: "{{ nocloud_mount }}/network-config" - mode: "0644" - - - name: Write cloud-init user data - ansible.builtin.template: - src: "user-data.yml" - dest: "{{ nocloud_mount }}/user-data" - mode: "0644" - - - name: Unmount the image file - ansible.posix.mount: - path: "{{ nocloud_mount }}" - state: unmounted - - - name: Define a new network - community.libvirt.virt_net: - name: "ansible-test:crichez.secureboot" - command: define - xml: "{{ lookup('ansible.builtin.template', 'testnet.xml') }}" - - - name: Create the network - community.libvirt.virt_net: - name: "ansible-test:crichez.secureboot" - command: create - - - name: Ensure the network is started - community.libvirt.virt_net: - name: "ansible-test:crichez.secureboot" - state: active - - - name: Create vm image - become: true + - name: Generate a 2048 bit RSA private key + community.crypto.openssl_privatekey: + path: "{{ tempdir.path }}/MOK.priv" + size: 2048 + type: RSA + mode: "0600" + setype: cert_t + + - name: Generate a self-signed certificate + community.crypto.x509_certificate: + path: "{{ tempdir.path }}/MOK.pem" + privatekey_path: "{{ tempdir.path }}/MOK.priv" + provider: selfsigned + mode: "0644" + setype: cert_t + + - name: Get a DER-encoded version + community.crypto.x509_certificate_convert: + src_path: "{{ tempdir.path }}/MOK.pem" + dest_path: "{{ tempdir.path }}/MOK.der" + format: der + mode: "0644" + setype: cert_t + +- name: Enroll the MOK into a new firmware image file + ansible.builtin.command: + argv: + - virt-fw-vars + - --input + - /usr/share/OVMF/OVMF_VARS.secboot.fd + - --output + - "{{ tempdir.path }}/OVMF_VARS.custom.fd" + - --enroll-redhat + - --secure-boot + - --add-mok + - f0c54306-e762-41a6-8dd4-4901c73e905b + - "{{ tempdir.path }}/MOK.der" + creates: "{{ tempdir.path }}/OVMF_VARS.custom.fd" + +- name: Set permissions on the firmware image file + ansible.builtin.file: + path: "{{ tempdir.path }}/OVMF_VARS.custom.fd" + mode: "0660" + setype: tmp_t + +- name: Write a the cloud-init datasource + become: true + vars: + nocloud_path: "/var/lib/libvirt/images/cloud-init:crichez.secureboot.img" + nocloud_mount: "/mnt/cloud-init:crichez.secureboot" + block: + - name: Create an empty file to write the nocloud image to + community.general.filesize: + mode: "0644" + path: "{{ nocloud_path }}" + size: 2MB + + - name: Write the nocloud image file ansible.builtin.command: - argv: - - qemu-img - - create - - -f - - qcow2 - - -b - - "{{ test_image }}" - - -F - - qcow2 - - "/var/lib/libvirt/images/ansible-test:crichez.secureboot.qcow2" - creates: "/var/lib/libvirt/images/ansible-test:crichez.secureboot.qcow2" - - - name: Define a new virtual machine - community.libvirt.virt: - name: "ansible-test:crichez.secureboot" - command: define - xml: "{{ lookup('ansible.builtin.template', 'testvm.xml') }}" - - - name: Ensure the machine is running - community.libvirt.virt: - name: "ansible-test:crichez.secureboot" - state: running + argv: + - mkfs.vfat + - -n + - cidata + - "{{ nocloud_path }}" + register: mkfs_cmd + changed_when: mkfs_cmd is not failed + + - name: Mount the image file + ansible.posix.mount: + boot: false + fstype: vfat + path: "{{ nocloud_mount }}" + src: "{{ nocloud_path }}" + state: ephemeral + + - name: Write cloud-init metadata + ansible.builtin.template: + src: "meta-data.yml" + dest: "{{ nocloud_mount }}/meta-data" + mode: "0644" + + - name: Write cloud-init network configuration + ansible.builtin.template: + src: "network-config.yml" + dest: "{{ nocloud_mount }}/network-config" + mode: "0644" + + - name: Write cloud-init user data + ansible.builtin.template: + src: "user-data.yml" + dest: "{{ nocloud_mount }}/user-data" + mode: "0644" + + - name: Unmount the image file + ansible.posix.mount: + path: "{{ nocloud_mount }}" + state: unmounted + +- name: Define a new network + community.libvirt.virt_net: + name: "ansible-test:crichez.secureboot" + command: define + xml: "{{ lookup('ansible.builtin.template', 'testnet.xml') }}" + +- name: Create the network + community.libvirt.virt_net: + name: "ansible-test:crichez.secureboot" + command: create + +- name: Ensure the network is started + community.libvirt.virt_net: + name: "ansible-test:crichez.secureboot" + state: active + +- name: Create vm image + become: true + ansible.builtin.command: + argv: + - qemu-img + - create + - -f + - qcow2 + - -b + - "{{ test_image }}" + - -F + - qcow2 + - "/var/lib/libvirt/images/ansible-test:crichez.secureboot.qcow2" + creates: "/var/lib/libvirt/images/ansible-test:crichez.secureboot.qcow2" + +- name: Define a new virtual machine + community.libvirt.virt: + name: "ansible-test:crichez.secureboot" + command: define + xml: "{{ lookup('ansible.builtin.template', 'testvm.xml') }}" + +- name: Ensure the machine is running + community.libvirt.virt: + name: "ansible-test:crichez.secureboot" + state: running diff --git a/tests/integration/targets/role_uki/templates/user-data.yml b/tests/integration/targets/role_uki/templates/user-data.yml index 83d3a9b..57692c5 100644 --- a/tests/integration/targets/role_uki/templates/user-data.yml +++ b/tests/integration/targets/role_uki/templates/user-data.yml @@ -4,4 +4,4 @@ users: - name: "{{ test_user }}" ssh_authorized_keys: - "{{ ssh_key }}" - sudo: ALL=(ALL) ALL + sudo: "ALL=(ALL) NOPASSWD:ALL"