-
Notifications
You must be signed in to change notification settings - Fork 73
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?
Changes from all commits
e4e732b
0ed64e7
a90cf1b
97cddf4
3a2f2a8
808573e
0e9b51f
bade36f
1957070
e96b7aa
d960ec0
fdbdbe2
8da41b5
06d3332
ea6989f
547a03d
5bb890d
923bf75
93a9ed7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,8 +16,11 @@ | |
become: yes | ||
|
||
- name: Ensure the VM is undefined | ||
virt: | ||
name: "{{ vm.name }}" | ||
command: undefine | ||
# note(wszumski): the virt module does not seem to support | ||
# removing vms with nvram defined - as a workaround, use the | ||
# 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 commentThe reason will be displayed to describe this comment to others. Learn more. This is a bit clunky :( Looks like it's necessary though |
||
become: yes | ||
when: vm.name in result.list_vms |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
--- | ||
|
||
- name: Detect the KVM emulator binary path | ||
stat: | ||
path: "{{ item }}" | ||
register: kvm_emulator_result | ||
with_items: | ||
- /usr/bin/kvm | ||
- /usr/bin/qemu-kvm | ||
- /usr/libexec/qemu-kvm | ||
|
||
- name: Set a fact containing the KVM emulator binary path | ||
set_fact: | ||
detected_libvirt_vm_emulator: "{{ item.item }}" | ||
with_items: "{{ kvm_emulator_result.results }}" | ||
when: item.stat.exists |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
--- | ||
# This playbook enrolls Platform, Key Exchange, and Signature Database keys | ||
# in the emulated NVRAM. NVRAM is the storage location for persistent | ||
# EFI state. The keys that are installed are as follows: | ||
# | ||
# * Platform Key: Red Hat Secure Boot (PK/KEK key 1)/[email protected]. | ||
# This is a Red Hat controlled key which controls modification to the | ||
# Key Exchange Keys (KEK). | ||
# | ||
# * Key Exchange Keys: | ||
# 1) Microsoft Corporation KEK CA 2011 | ||
# 2) Red Hat Secure Boot (PK/KEK key 1)/[email protected] | ||
# | ||
# The first KEK is used to sign the revocation database obtained from: | ||
# http://www.uefi.org/revocationlistfile. This allows you to use: dbxtool | ||
# to periodically update your local copy of this blacklist. The second gives | ||
# RedHat control over the dbx (Forbidden Signature) and db (Signature) databases. | ||
# This essentially makes your computer trust RedHat and Microsoft signed binaries. | ||
# | ||
# * Signature database (db) keys: | ||
# - Microsoft Windows Production PCA 2011 (for accepting Windows 8, Windows Server 2012 R2, etc boot loaders) | ||
# - Microsoft Corporation UEFI CA 2011 (for verifying the shim binary, and PCI expansion ROMs). | ||
# | ||
# Further signing keys can be enrolled in the shim binary to allow execution of custom binaries. | ||
# | ||
# When a platform key is enrolled, the secure boot mode changes from "setup mode" to "user mode" | ||
# and secure boot is automatically enabled. Secure boot can only be disabled via the EFI setup | ||
# menu - this is accessed by pressing delete when the VM is started. It does not seem possible to | ||
# to control this setting via libvirt or by using a qemu command line option. | ||
# | ||
# TODO: Allow installation of custom keys | ||
|
||
- name: Gather os specific variables | ||
include_vars: "{{ item }}" | ||
with_first_found: | ||
- files: | ||
- "{{ ansible_distribution }}-{{ ansible_distribution_major_version}}.yml" | ||
- "{{ ansible_distribution }}.yml" | ||
- "{{ ansible_os_family }}.yml" | ||
skip: true | ||
tags: vars | ||
|
||
- name: Ensure ovmf generator checkout directory is owned by ansible_user | ||
file: | ||
path: "{{ libvirt_ovmf_vars_generator_checkout_path }}" | ||
owner: "{{ ansible_user }}" | ||
state: directory | ||
become: true | ||
|
||
- name: Clone ovfm-vars generator | ||
git: | ||
repo: 'https://github.com/puiterwijk/qemu-ovmf-secureboot' | ||
dest: "{{ libvirt_ovmf_vars_generator_checkout_path }}" | ||
update: yes | ||
|
||
- name: Get checksum of template OVMF vars | ||
# We need to keep the generated vars in sync with templated version. | ||
# if the OVMF package is updated - we should update a new version with | ||
# the signing keys enrolled. | ||
stat: | ||
path: "{{ libvirt_vm_ovmf_efi_variable_store_path }}" | ||
get_checksum: true | ||
checksum_algorithm: sha256 | ||
register: ovmf_template | ||
|
||
- name: Register destination of generated variables | ||
set_fact: | ||
ovmf_enrolled_variables_path: "\ | ||
{{ libvirt_ovmf_vars_generator_output_path }}/\ | ||
{{ libvirt_ovmf_vars_generator_output_prefix }}\ | ||
{{ ovmf_template.stat.checksum }}" | ||
|
||
- name: Register temporary path to output generated variables | ||
# We don't want to run the generator with elevated privileges | ||
# so use a temporary output before copying into place | ||
set_fact: | ||
ovmf_enrolled_variables_temp_output_path: "\ | ||
{{ libvirt_ovmf_vars_generator_checkout_path}}/\ | ||
{{ libvirt_ovmf_vars_generator_output_prefix }}\ | ||
{{ ovmf_template.stat.checksum }}" | ||
|
||
- name: Check to see if we have generated these vars before | ||
stat: | ||
path: "{{ ovmf_enrolled_variables_path }}" | ||
register: generated_ovmf | ||
|
||
- name: Run OVMF vars generator | ||
command: > | ||
python {{ libvirt_ovmf_vars_generator_checkout_path}}/ovmf-vars-generator | ||
--ovmf-binary {{ libvirt_vm_ovmf_efi_firmware_path }} | ||
--uefi-shell-iso {{ libvirt_vm_ovmf_uefi_shell_iso_path }} | ||
--ovmf-template-vars {{ libvirt_vm_ovmf_efi_variable_store_path }} | ||
--qemu-binary {{ libvirt_vm_emulator }} | ||
{% if libvirt_vm_engine == 'kvm' %}--enable-kvm{% endif %} | ||
--skip-testing | ||
--no-download | ||
{{ ovmf_enrolled_variables_temp_output_path }} | ||
when: not generated_ovmf.stat.exists | ||
|
||
- name: Ensure libvirt qemu can access the variable template | ||
copy: | ||
src: "{{ ovmf_enrolled_variables_temp_output_path }}" | ||
dest: "{{ ovmf_enrolled_variables_path }}" | ||
owner: "{{ libvirt_vm_qemu_user }}" | ||
group: "{{ libvirt_vm_qemu_user }}" | ||
become: true | ||
when: not generated_ovmf.stat.exists |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,12 +9,26 @@ | |
skip: true | ||
tags: vars | ||
|
||
- include_tasks: autodetect.yml | ||
# We include this here as detection depends on the emulation features that | ||
# are requested. We don't need to know the engine and emulator if we're | ||
# 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 commentThe reason will be displayed to describe this comment to others. Learn more. Don't we want to do this unconditionally? |
||
|
||
- name: Set fact containing libvirt emulator | ||
set_fact: | ||
# The detected emulator may change between VM, but always prefer an explictly | ||
# requested emulator | ||
emulator: "{{ libvirt_vm_emulator | default(detected_libvirt_vm_emulator, true) }}" | ||
|
||
- name: Ensure the VM console log directory exists | ||
file: | ||
path: "{{ console_log_path | dirname }}" | ||
state: directory | ||
owner: "{{ libvirt_vm_log_owner }}" | ||
group: "{{ libvirt_vm_log_owner }}" | ||
owner: "{{ libvirt_vm_qemu_user }}" | ||
group: "{{ libvirt_vm_qemu_user }}" | ||
recurse: true | ||
mode: 0770 | ||
when: console_log_enabled | bool | ||
|
@@ -26,6 +40,26 @@ | |
interface: "{{ item }}" | ||
with_items: "{{ interfaces }}" | ||
|
||
- name: Create secure boot template variables | ||
include_tasks: prepare-secure-boot.yml | ||
when: | ||
- boot_firmware == "efi" | ||
- enable_secure_boot | ||
- libvirt_vm_ovmf_uefi_shell_iso_path is defined | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe 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 |
||
|
||
- name: Undefine libvirt machine if already defined | ||
# Otherwise vm.xml.j2 will not be updated when variables are changed | ||
# | ||
# note(wszumski): the virt module does not seem to support | ||
# removing vms with nvram defined - as a workaround, use the | ||
# 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 }} | ||
become: true | ||
register: result | ||
failed_when: result.rc != 0 and "no domain with matching name" not in result.stderr | ||
|
||
- name: Ensure the VM is defined | ||
virt: | ||
name: "{{ vm.name }}" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,16 @@ | ||
--- | ||
|
||
# Who owns the serial console logs in console_log_path | ||
libvirt_vm_log_owner: libvirt-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: libvirt-qemu | ||
|
||
# The environment passed to virt_volume.sh | ||
libvirt_vm_volume_creation_env: {} | ||
|
||
# Path to template OVMF efi variable store. A copy will be created | ||
# for each VM created. | ||
libvirt_vm_ovmf_efi_variable_store_path: /usr/share/OVMF/OVMF_VARS.fd | ||
|
||
# Path to OVMF efi firmware | ||
libvirt_vm_ovmf_efi_firmware_path: /usr/share/OVMF/OVMF_CODE.fd | ||
|
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: