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

WIP: Add efi and secureboot support #12

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open

WIP: Add efi and secureboot support #12

wants to merge 19 commits into from

Conversation

jovial
Copy link
Contributor

@jovial jovial commented Oct 5, 2018

  • 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.

@jovial
Copy link
Contributor Author

jovial commented Oct 5, 2018

May need to move some of this code in ansible-role-libvirt-host. How can we workaround the problem that the EFI firmware path may change if we install a different package. One solution would be to copy these files to a standard location.

- 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 }}
Copy link
Member

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
Copy link
Member

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.

Copy link
Contributor Author

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.

Copy link
Member

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({}) }}"
Copy link
Member

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 @@
---
Copy link
Member

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.

@@ -0,0 +1,59 @@
---
Copy link
Member

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

Copy link
Member

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.

path: "{{ ovmf_enrolled_variables_path }}"
register: generated_ovmf

- name: Run OVMF vars generator
Copy link
Member

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 }}"
Copy link
Member

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)
Copy link
Member

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
Copy link
Member

Choose a reason for hiding this comment

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

Not supported on Debian?

Copy link
Contributor Author

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
Copy link
Member

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?

Copy link
Contributor Author

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.
jovial added a commit to jovial/tenks that referenced this pull request Oct 22, 2018
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.
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
Copy link
Member

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
Copy link
Member

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
Copy link
Member

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.

@markgoddard markgoddard mentioned this pull request Feb 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants