Added TPM Device support

Added TPM device support to include switching out the TPM device on
reboot if necessary.

The following options were added:

* tpm_model - Defaults to 'tpm-tis'
* tpm_type  - Defaults to 'passthrough'
* tpm_path  - Must be specified, other options are ignored if this is
              not specified. Most users will set this to /dev/tpm0.

For additional information on using a TPM with Libvirt see the following:

* http://wiki.qemu.org/Features/TPM
* https://libvirt.org/formatdomain.html#elementsTpm
This commit is contained in:
Trevor Vaughan 2016-01-06 09:48:20 -05:00
parent 9d331d2ed6
commit ecb1339312
5 changed files with 88 additions and 1 deletions

View File

@ -211,7 +211,9 @@ end
* `nic_adapter_count` - Defaults to '8'. Only use case for increasing this count is for VMs that virtualize switches such as Cumulus Linux. Max value for Cumulus Linux VMs is 33.
* `uuid` - Force a domain UUID. Defaults to autogenerated value by libvirt if not set.
* `suspend_mode` - What is done on vagrant suspend. Possible values: 'pause', 'managedsave'. Pause mode executes a la `virsh suspend`, which just pauses execution of a VM, not freeing resources. Managed save mode does a la `virsh managedsave` which frees resources suspending a domain.
* `tpm_model` - The model of the TPM to which you wish to connect.
* `tpm_type` - The type of TPM device to which you are connecting.
* `tpm_path` - The path to the TPM device on the host system.
Specific domain settings can be set for each domain separately in multi-VM
@ -268,6 +270,9 @@ On vagrant reload the following domain specific attributes are updated in define
* `keymap` - Updated.
* `video_type` - Updated.
* `video_vram` - Updated.
* `tpm_model` - Updated.
* `tpm_type` - Updated.
* `tpm_path` - Updated.
## Networks
@ -653,6 +658,32 @@ Vagrant.configure("2") do |config|
end
```
## TPM Devices
Modern versions of Libvirt support connecting to TPM devices on the host
system. This allows you to enable Trusted Boot Extensions, among other
features, on your guest VMs.
In general, you will only need to modify the `tpm_path` variable in your guest
configuration. However, advanced usage, such as the application of a Software
TPM, may require modifying the `tpm_model` and `tpm_type` variables.
The TPM options will only be used if you specify a TPM path. Declarations of
any TPM options without specifying a path will result in those options being
ignored.
Here is an example of using the TPM options:
```ruby
Vagrant.configure("2") do |config|
config.vm.provider :libvirt do |libvirt|
libvirt.tpm_model = 'tpm-tis'
libvirt.tpm_type = 'passthrough'
libvirt.tpm_path = '/dev/tpm0'
end
end
```
## Box Format
You can view an example box in the [example_box/directory](https://github.com/pradels/vagrant-libvirt/tree/master/example_box). That directory also contains instructions on how to build a box.

View File

@ -59,6 +59,10 @@ module VagrantPlugins
@keymap = config.keymap
@kvm_hidden = config.kvm_hidden
@tpm_model = config.tpm_model
@tpm_type = config.tpm_type
@tpm_path = config.tpm_path
# Boot order
@boot_order = config.boot_order
@ -164,6 +168,7 @@ module VagrantPlugins
env[:ui].info(" -- Video Type: #{@video_type}")
env[:ui].info(" -- Video VRAM: #{@video_vram}")
env[:ui].info(" -- Keymap: #{@keymap}")
env[:ui].info(" -- TPM Path: #{@tpm_path}")
@boot_order.each do |device|
env[:ui].info(" -- Boot device: #{device}")

View File

@ -155,6 +155,35 @@ module VagrantPlugins
end
end
#TPM
if config.tpm_path
raise Errors::FogCreateServerError, "The TPM Path must be fully qualified" unless config.tpm_path[0].chr == '/'
tpm = REXML::XPath.first(xml_descr,'/domain/devices/tpm')
if tpm.nil?
descr_changed = true
tpm = REXML::Element.new('tpm', REXML::XPath.first(xml_descr,'/domain/devices/tpm/model'))
tpm.attributes['model'] = config.tpm_model
tpm_backend_type = tpm.add_element('backend')
tpm_backend_type.attributes['type'] = config.tpm_type
tpm_device_path = tpm_backend_type.add_element('device')
tpm_device_path.attributes['path'] = config.tpm_path
else
if tpm.attributes['model'] != config.tpm_model
descr_changed = true
tpm.attributes['model'] = config.tpm_model
end
if tpm.elements['backend'].attributes['type'] != config.tpm_type
descr_changed = true
tpm.elements['backend'].attributes['type'] = config.tpm_type
end
if tpm.elements['backend'].elements['device'].attributes['path'] != config.tpm_path
descr_changed = true
tpm.elements['backend'].elements['device'].attributes['path'] = config.tpm_path
end
end
end
# Video device
video = REXML::XPath.first(xml_descr,'/domain/devices/video/model')
if video.attributes['type'] != config.video_type || video.attributes['vram'] != config.video_vram

View File

@ -80,6 +80,12 @@ module VagrantPlugins
attr_accessor :keymap
attr_accessor :kvm_hidden
# Sets the information for connecting to a host TPM device
# Only supports socket-based TPMs
attr_accessor :tpm_model
attr_accessor :tpm_type
attr_accessor :tpm_path
# Sets the max number of NICs that can be created
# Default set to 8. Don't change the default unless you know
# what are doing
@ -143,6 +149,10 @@ module VagrantPlugins
@keymap = UNSET_VALUE
@kvm_hidden = UNSET_VALUE
@tpm_model = UNSET_VALUE
@tpm_type = UNSET_VALUE
@tpm_path = UNSET_VALUE
@nic_adapter_count = UNSET_VALUE
# Boot order
@ -404,6 +414,9 @@ module VagrantPlugins
@video_vram = 9216 if @video_vram == UNSET_VALUE
@keymap = 'en-us' if @keymap == UNSET_VALUE
@kvm_hidden = false if @kvm_hidden == UNSET_VALUE
@tpm_model = 'tpm-tis' if @tpm_model == UNSET_VALUE
@tpm_type = 'passthrough' if @tpm_type == UNSET_VALUE
@tpm_path = nil if @tpm_path == UNSET_VALUE
@nic_adapter_count = 8 if @nic_adapter_count == UNSET_VALUE
# Boot order

View File

@ -122,5 +122,14 @@
</source>
</hostdev>
<% end %>
<% if @tpm_path -%>
<%# TPM Device -%>
<tpm model='<%= @tpm_model %>'>
<backend type='<%= @tpm_type %>'>
<device path='<%= @tpm_path %>'/>
</backend>
</tpm>
<% end -%>
</devices>
</domain>