Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/fog/libvirt/compute.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Compute < Fog::Service
collection :nodes
model :nic
collection :nics
model :tpm

request_path 'fog/libvirt/requests/compute'
request :list_domains
Expand Down
31 changes: 31 additions & 0 deletions lib/fog/libvirt/models/compute/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class Server < Fog::Compute::Server
attribute :guest_agent
attribute :video
attribute :virtio_rng
attribute :tpm
attribute :tpm_device

attribute :state

Expand All @@ -58,6 +60,7 @@ def initialize(attributes={} )
super defaults.merge(attributes)
initialize_nics
initialize_volumes
initialize_tpm
@user_data = attributes.delete(:user_data)
end

Expand Down Expand Up @@ -411,6 +414,22 @@ def to_xml
xml.backend(virtio_rng[:backend_path], :model => virtio_rng.fetch(:backend_model, "random"))
end

if tpm_device
tpm_model_type = tpm_device.model == "spapr-tpm-proxy" ? "spapr-tpm-proxy" : "tpm-#{tpm_device.model}"
xml.tpm(:model => tpm_model_type) do
if tpm_device.type == "passthrough"
xml.backend(:type => tpm_device.type) do
xml.device(:path => tpm_device.passthrough_device_path)
end
else
xml.backend(:type => tpm_device.type, :version => tpm_device.version)
end
if %w[spapr spapr-tpm-proxy].include?(tpm_device.model)
xml.address(:type => tpm_device.par_address_type, :reg => tpm_device.spar_address_reg)
end
end
end

if arch == "s390x"
xml.controller(:type => "scsi", :index => "0", :model => "virtio-scsi")
xml.console(:type => "pty") do
Expand Down Expand Up @@ -504,6 +523,17 @@ def initialize_volumes
end
end

def initialize_tpm
# tpm can be a boolean or hash
if tpm
# convert tpm to empty hash if not a hash value
if !tpm.is_a?(Hash)
tpm = {}
end
self.tpm_device = TPM.new(arch, tpm)
end
end

def create_or_clone_volume
options = {:name => volume_name || default_volume_name}
# Check if a disk template was specified
Expand Down Expand Up @@ -561,6 +591,7 @@ def defaults
:video => {:type => "virtio", :heads => 1},
:virtio_rng => {},
:firmware_features => { "secure-boot" => "no" },
:tpm => false
}
end

Expand Down
97 changes: 97 additions & 0 deletions lib/fog/libvirt/models/compute/tpm.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
require 'fog/core/model'

module Fog
module Libvirt
class Compute
class TPM < Fog::Model
# Currently Qemu only allows for one TPM device

identity :id
attribute :arch
attribute :model
attribute :type
attribute :version
attribute :device_path
attribute :spapr_address_type
attribute :spapr_address_reg

# Types
#
TYPES = ['emulator', 'passthrough'].freeze

# Models
# crb - TCG PC Client Platform TPM Profile (PTP) Specification (2017)
# tis - TCG PC Client Specific TPM Interface Specification (TIS) (2013)
# spapr - Used with pSeries (ppc64)
# spapr-tpm-proxy - Used with pSeries (ppc64), this is only used with 'passthrough' type
#
MODELS_X86_64 = ['crb', 'tis'].freeze
MODELS_PPC64 = ['spapr', 'spapr-tpm-proxy'].freeze
MODELS_ARM64 = ['tis'].freeze
MODELS_S390X = ['tis'].freeze

# Versions
#
VERSIONS = ['1.2', '2.0'].freeze

def initialize(arch = "", attributes = {})
@id = "tpm0"
@arch = arch
super defaults.merge(attributes)
raise Fog::Errors::Error, "#{type} is not a supported TPM type" if new? && !TYPES.include?(type)
raise Fog::Errors::Error, "#{model} is not a supported TPM model" if new? && !supported_models.include?(model)
raise Fog::Errors::Error, "TPM model type crb does not a supported TPM version 1.2" if model == "crb" && version == "1.2"
end

def new?
id.nil?
end

def save
raise Fog::Errors::Error, 'Creating a new TPM device is not yet implemented. Contributions welcome!'
end

def destroy
raise Fog::Errors::Error, 'Destroying a TPM device is not yet implemented. Contributions welcome!'
end

def supported_models
case @arch
when "x86_64"
MODELS_X86_64
when "ppc64" || "ppc64le"
MODELS_PPC64
when "arm" || "aarch64" || "aarch64_be"
MODELS_ARM64
when "s390x"
MODELS_S390X
else
raise Fog::Errors::Error, 'CPU Architecture does not have any supported TPM models!'
end
end

def defaults
case @arch
when "x86_64"
{ :model => "crb", :type => "emulator", :version => "2.0", :passthrough_device_path => "/dev/tpm0" }
when "ppc64" || "ppc64le"
{
:model => "spapr",
:type => "emulator",
:version => "2.0",
:passthrough_device_path => "/dev/tpm0",
:spapr_address_type => "spapr-vio",
:spapr_address_reg => "0x00004000"
}
when "arm" || "aarch64" || "aarch64_be"
{ :model => "tis", :type => "emulator", :version => "2.0", :passthrough_device_path => "/dev/tpm0" }
when "s390x"
{ :model => "tis", :type => "emulator", :version => "2.0", :passthrough_device_path => "/dev/tpm0" }
else
{}
end
end
end
end
end
end