diff --git a/README.md b/README.md index 22b9d56..2a055a9 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/lib/vagrant-libvirt/action/create_domain.rb b/lib/vagrant-libvirt/action/create_domain.rb index af0e183..deecf86 100644 --- a/lib/vagrant-libvirt/action/create_domain.rb +++ b/lib/vagrant-libvirt/action/create_domain.rb @@ -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}") diff --git a/lib/vagrant-libvirt/action/start_domain.rb b/lib/vagrant-libvirt/action/start_domain.rb index 289416e..0a99404 100644 --- a/lib/vagrant-libvirt/action/start_domain.rb +++ b/lib/vagrant-libvirt/action/start_domain.rb @@ -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 diff --git a/lib/vagrant-libvirt/config.rb b/lib/vagrant-libvirt/config.rb index 4254a8f..27bfbea 100644 --- a/lib/vagrant-libvirt/config.rb +++ b/lib/vagrant-libvirt/config.rb @@ -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 diff --git a/lib/vagrant-libvirt/templates/domain.xml.erb b/lib/vagrant-libvirt/templates/domain.xml.erb index 2eec6ec..27499f2 100644 --- a/lib/vagrant-libvirt/templates/domain.xml.erb +++ b/lib/vagrant-libvirt/templates/domain.xml.erb @@ -122,5 +122,14 @@ <% end %> + + <% if @tpm_path -%> + <%# TPM Device -%> + + + + + + <% end -%>