-
Notifications
You must be signed in to change notification settings - Fork 72
WIP: Add efi and secureboot support #12
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
base: master
Are you sure you want to change the base?
Conversation
May need to move some of this code in |
- secure boot support is currently limited to redhat derived distros as the ubuntu packages don't provide UefiShell.iso. - Although the upgrading of qemu packages is more suited to the ansible-role-libvirt-host role, we need to know the location of the UEFI firmware images to setup the virtual machines. As we somtimes require custom packages this makes it hard to know upfront what the path will be.
Before this change you would get: K [stackhpc.libvirt-vm : Ensure the VM is undefined] *********************** * An exception occurred during task execution. To see the full traceback, use -vv v. The error was: libvirtError: Requested operation is not valid: cannot delete inactive domain with nvram fatal: [localhost]: FAILED! => {"changed": false, "msg": "Requested operation i s not valid: cannot delete inactive domain with nvram"}
# virsh cli directly. It may be better to detect if dumpxml | ||
# actually contains an nvram element rather than relying on | ||
# boot_firmware having the correct value. | ||
command: virsh -c qemu:///system undefine{% if boot_firmware == 'efi' %} --nvram{% endif %} {{ vm.name }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit clunky :( Looks like it's necessary though
tasks/setup.yml
Outdated
- "{{ ansible_distribution }}.yml" | ||
- "{{ ansible_os_family }}.yml" | ||
skip: true | ||
tags: vars |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably nicer to do this in main.yml.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure if we should make it so the playbooks can be run separately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair point.
tasks/setup.yml
Outdated
# The core team had a a change of heart and it is actually being preserved: | ||
# https://github.com/ansible/ansible/pull/43798 | ||
yum_repository: "{{ item }}" | ||
loop: "{{ libvirt_vm_custom_yum_repos | default({}) }}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: default should be a list
tasks/setup.yml
Outdated
@@ -0,0 +1,31 @@ | |||
--- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This stuff probably belongs in libvirt-host.
tasks/prepare_secure_boot.yml
Outdated
@@ -0,0 +1,59 @@ | |||
--- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
micronit: other task file names use dashes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file could do with a comment to explain what's going on.
tasks/prepare_secure_boot.yml
Outdated
path: "{{ ovmf_enrolled_variables_path }}" | ||
register: generated_ovmf | ||
|
||
- name: Run OVMF vars generator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be good if this role was just provided with a path to this script, which could be installed/cloned by libvirt-host.
vars/Debian.yml
Outdated
- ovmf | ||
|
||
# List of extra packages to install | ||
libvirt_vm_extra_packages: "{{ [] + (libvirt_vm_extra_packages_efi if libvirt_vm_enable_efi_support else []) | unique }}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need the [] +
here?
vars/RedHat.yml
Outdated
|
||
# Packages that are only necessary if you require EFI support | ||
libvirt_vm_extra_packages_efi: | ||
- edk2.git-ovmf-x64 # Official OVMF package doesn't boot (CentOS 7.5) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting OVMF was just proposed for addition to the nova containers in kolla: https://review.openstack.org/608579
include_tasks: prepare_secure_boot.yml | ||
when: | ||
- boot_firmware == "efi" | ||
- libvirt_vm_ovmf_uefi_shell_iso_path is defined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not supported on Debian?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Debian packages don't contain the UEFI shell ISO which contains the EnrollDefaultKeys.efi
binary. WE would either need to build this from source or obtain it by some other means.
vars/RedHat.yml
Outdated
# Packages that are only necessary if you require EFI support | ||
libvirt_vm_extra_packages_efi: | ||
- edk2.git-ovmf-x64 # Official OVMF package doesn't boot (CentOS 7.5) | ||
- qemu-kvm-ev # Need smm support for secure boot |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this require hardware virtualisation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe SMM emulation, which is needed for secure boot, requires either KVM or TCG acceleration to be enabled. So, by enabling TCG we should be able to use secure-boot without KVM - but I will need to test this to be sure.
From the OVMF readme, https://github.com/tianocore/edk2/tree/073891a3e74059e996258e32b56b3f0770c6fe55/OvmfPkg: * The minimum required QEMU machine type is "pc-q35-2.5".
* It seems you cannot specify multiple <loader> elements, instead you must use an nvram element * Ensure the qemu user can read the generated file. This is done by generating the file in a temporary location before transferring ownership to the libvirt_vm_log_owner owner.
This has more general applicability than just setting the owner of the log files.
This matches the existing files.
This requires upstream support in stackhpc.libvirt-host and stackhpc.libvirt-vm, see: - stackhpc/ansible-role-libvirt-vm#12 - stackhpc/ansible-role-libvirt-host#7
…ture The qemu-kvm binary only supports the host architecture. We must therefore use the qemu-system-<architecture> binaries when the target architecture is not the same as the host architecture. Although it may be possible that the host CPU may support acceleration for a foreign architecture, I do not currently know of any chips that support this functionality. For this reason, we default to software emulation.
It seems that the virt module does not take into account changes to the templated vm.xml.j2 file. As such, changes to variables used within this template are not propagated to libvirt i.e the output of virsh dumpxml remains the same before and after the application of define.
This is a requirement for smm and secureboot, see: https://github.com/tianocore/edk2/tree/master/OvmfPkg and can be used with and without kvm.
SMM is requirement for secure boot, see: https://github.com/tianocore/edk2/blob/a8b5750901faa63ff5570634851e648b8e335e5a/OvmfPkg/README
This is so we can use a newer version of qemu if secure boot is enabled. The version shipped in CentOS 7.5 does not support SMM which is a requirement of secure boot.
SMM is a requirement to use the needs-SMM variant and qemu will hang on boot if SMM is disabled.
when: item.stat.exists | ||
- name: Ensure old value stored in detected_libvirt_vm_emulator is cleared | ||
set_fact: | ||
detected_libvirt_vm_emulator: none |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this not set it to the string 'none'? You can set a variable to none via:
detected_libvirt_vm_emulator:
# not creating any newv VMs. | ||
when: >- | ||
(libvirt_vms | selectattr('state', 'defined') | ||
| selectattr('state', 'equalto', 'absent') | list) != libvirt_vms |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we want to do this unconditionally?
libvirt_vm_log_owner: qemu | ||
# This controls ownership of files used by the libvirt qemu process, | ||
# e.g the serial console logs in console_log_path. | ||
libvirt_vm_qemu_user: qemu |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better check this isn't referenced anywhere by consumers of this role.
derived distros as the ubuntu packages don't provide
UefiShell.iso.
to the ansible-role-libvirt-host role, we need to know
the location of the UEFI firmware images to setup the
virtual machines. As we somtimes require custom packages
this makes it hard to know upfront what the path will
be.