Skip to content

Commit

Permalink
feat(vm): Add support for setting the VM TPM State device (#743)
Browse files Browse the repository at this point in the history
* feat(vm): add support for setting the vm tpm state

Signed-off-by: Rui Lopes <[email protected]>

* feat(vm): add encoding / unmarshalling for CustomTPMState

Signed-off-by: Pavel Boldyrev <[email protected]>

* feat(vm): fix typos

Signed-off-by: Rui Lopes <[email protected]>

* feat(vm): fix vmGetTPMState

Signed-off-by: Pavel Boldyrev <[email protected]>

* feat(docs): add the vm tpm_state documentation

Signed-off-by: Rui Lopes <[email protected]>

* feat(docs): add the vm tpm_state example

Signed-off-by: Rui Lopes <[email protected]>

---------

Signed-off-by: Rui Lopes <[email protected]>
Signed-off-by: Pavel Boldyrev <[email protected]>
Co-authored-by: Pavel Boldyrev <[email protected]>
  • Loading branch information
rgl and bpg authored Dec 5, 2023
1 parent d1f2093 commit 66bba2a
Show file tree
Hide file tree
Showing 4 changed files with 285 additions and 1 deletion.
9 changes: 9 additions & 0 deletions docs/resources/virtual_environment_vm.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ resource "proxmox_virtual_environment_vm" "ubuntu_vm" {
type = "l26"
}
tpm_state {
version = "v2.0"
}
serial_device {}
}
Expand Down Expand Up @@ -287,6 +291,11 @@ output "ubuntu_vm_public_key" {
distribution-specific and Microsoft Standard keys enrolled, if used with
EFI type=`4m`. Ignored for VMs with cpu.architecture=`aarch64` (defaults
to `false`).
- `tpm_state` - (Optional) The TPM state device.
- `datastore_id` (Optional) The identifier for the datastore to create
the disk in (defaults to `local-lvm`).
- `version` (Optional) TPM state device version. Can be `v1.2` or `v2.0`.
(defaults to `v2.0`).
- `hostpci` - (Optional) A host PCI device mapping (multiple blocks supported).
- `device` - (Required) The PCI device name for Proxmox, in form
of `hostpciX` where `X` is a sequential number from 0 to 3.
Expand Down
5 changes: 5 additions & 0 deletions example/resource_virtual_environment_vm.tf
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ resource "proxmox_virtual_environment_vm" "example_template" {
type = "4m"
}

tpm_state {
datastore_id = local.datastore_id
version = "v2.0"
}

# disk {
# datastore_id = local.datastore_id
# file_id = proxmox_virtual_environment_file.ubuntu_cloud_image.id
Expand Down
50 changes: 50 additions & 0 deletions proxmox/nodes/vms/vms_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,12 @@ func (r CustomStorageDevice) IsOwnedBy(vmID int) bool {
// CustomStorageDevices handles QEMU SATA device parameters.
type CustomStorageDevices map[string]CustomStorageDevice

// CustomTPMState handles QEMU TPM state parameters.
type CustomTPMState struct {
FileVolume string `json:"file" url:"file"`
Version *string `json:"version,omitempty" url:"version,omitempty"`
}

// CustomUSBDevice handles QEMU USB device parameters.
type CustomUSBDevice struct {
HostDevice *string `json:"host" url:"host"`
Expand Down Expand Up @@ -349,6 +355,7 @@ type CreateRequestBody struct {
Tags *string `json:"tags,omitempty" url:"tags,omitempty"`
Template *types.CustomBool `json:"template,omitempty" url:"template,omitempty,int"`
TimeDriftFixEnabled *types.CustomBool `json:"tdf,omitempty" url:"tdf,omitempty,int"`
TPMState *CustomTPMState `json:"tpmstate0,omitempty" url:"tpmstate0,omitempty"`
USBDevices CustomUSBDevices `json:"usb,omitempty" url:"usb,omitempty"`
VGADevice *CustomVGADevice `json:"vga,omitempty" url:"vga,omitempty"`
VirtualCPUCount *int `json:"vcpus,omitempty" url:"vcpus,omitempty"`
Expand Down Expand Up @@ -517,6 +524,7 @@ type GetResponseData struct {
Tags *string `json:"tags,omitempty"`
Template *types.CustomBool `json:"template,omitempty"`
TimeDriftFixEnabled *types.CustomBool `json:"tdf,omitempty"`
TPMState *CustomTPMState `json:"tpmstate0,omitempty"`
USBDevice0 *CustomUSBDevice `json:"usb0,omitempty"`
USBDevice1 *CustomUSBDevice `json:"usb1,omitempty"`
USBDevice2 *CustomUSBDevice `json:"usb2,omitempty"`
Expand Down Expand Up @@ -1233,6 +1241,21 @@ func (r CustomStorageDevices) EncodeValues(_ string, v *url.Values) error {
return nil
}

// EncodeValues converts a CustomTPMState struct to a URL vlaue.
func (r CustomTPMState) EncodeValues(key string, v *url.Values) error {
values := []string{
fmt.Sprintf("file=%s", r.FileVolume),
}

if r.Version != nil {
values = append(values, fmt.Sprintf("version=%s", *r.Version))
}

v.Add(key, strings.Join(values, ","))

return nil
}

// EncodeValues converts a CustomUSBDevice struct to a URL vlaue.
func (r CustomUSBDevice) EncodeValues(key string, v *url.Values) error {
if r.HostDevice == nil && r.Mapping == nil {
Expand Down Expand Up @@ -1707,6 +1730,33 @@ func (r *CustomPCIDevice) UnmarshalJSON(b []byte) error {
return nil
}

// UnmarshalJSON converts a CustomTPMState string to an object.
func (r *CustomTPMState) UnmarshalJSON(b []byte) error {
var s string

if err := json.Unmarshal(b, &s); err != nil {
return fmt.Errorf("failed to unmarshal CustomTPMState: %w", err)
}

pairs := strings.Split(s, ",")

for _, p := range pairs {
v := strings.Split(strings.TrimSpace(p), "=")
if len(v) == 1 {
r.FileVolume = v[0]
} else if len(v) == 2 {
switch v[0] {
case "file":
r.FileVolume = v[1]
case "version":
r.Version = &v[1]
}
}
}

return nil
}

// UnmarshalJSON converts a CustomUSBDevice string to an object.
func (r *CustomUSBDevice) UnmarshalJSON(b []byte) error {
var s string
Expand Down
Loading

0 comments on commit 66bba2a

Please sign in to comment.