From deb3a596bed59e9b0b12561a28b5f50fc6a7607c Mon Sep 17 00:00:00 2001 From: kshivakumar Date: Thu, 9 Mar 2023 21:42:54 -0600 Subject: [PATCH] feat: add support for dynamic directpath i/o Adding support for vSphere Dynamic DirectPath I/O. --- .../builder/vsphere-clone/README.md | 5 +- .../components/builder/vsphere-iso/README.md | 5 +- builder/vsphere/clone/config.hcl2spec.go | 2 + builder/vsphere/common/step_hardware.go | 21 +++- .../vsphere/common/step_hardware.hcl2spec.go | 99 ++++++++++++------- builder/vsphere/common/step_hardware_test.go | 7 ++ builder/vsphere/driver/vm.go | 70 +++++++++++++ builder/vsphere/iso/config.hcl2spec.go | 2 + .../common/HardwareConfig-not-required.mdx | 5 +- ...IPassthroughAllowedDevice-not-required.mdx | 11 +++ 10 files changed, 188 insertions(+), 39 deletions(-) create mode 100644 docs-partials/builder/vsphere/common/PCIPassthroughAllowedDevice-not-required.mdx diff --git a/.web-docs/components/builder/vsphere-clone/README.md b/.web-docs/components/builder/vsphere-clone/README.md index f3a7019c..10899a20 100644 --- a/.web-docs/components/builder/vsphere-clone/README.md +++ b/.web-docs/components/builder/vsphere-clone/README.md @@ -738,7 +738,10 @@ wget http://{{ .HTTPIP }}:{{ .HTTPPort }}/foo/bar/preseed.cfg - `displays` (int32) - Number of video displays. See [vSphere documentation](https://docs.vmware.com/en/VMware-vSphere/7.0/com.vmware.vsphere.vm_admin.doc/GUID-789C3913-1053-4850-A0F0-E29C3D32B6DA.html) for supported maximums. Defaults to 1. -- `vgpu_profile` (string) - vGPU profile for accelerated graphics. See [NVIDIA GRID vGPU documentation](https://docs.nvidia.com/grid/latest/grid-vgpu-user-guide/index.html#configure-vmware-vsphere-vm-with-vgpu) +- `pci_passthrough_allowed_device` ([]PCIPassthroughAllowedDevice) - Configure Dynamic DirectPath I/O PCI Passthrough for virtual machine. See [vSphere documentation](https://docs.vmware.com/en/VMware-vSphere/7.0/com.vmware.vsphere.vm_admin.doc/GUID-5B3CAB26-5D06-4A99-92A0-3A04C69CE64B.html) + +- `vgpu_profile` (string) - vGPU profile for accelerated graphics. + vGPU profile for accelerated graphics. See [NVIDIA GRID vGPU documentation](https://docs.nvidia.com/grid/latest/grid-vgpu-user-guide/index.html#configure-vmware-vsphere-vm-with-vgpu) for examples of profile names. Defaults to none. - `NestedHV` (bool) - Enable nested hardware virtualization for VM. Defaults to `false`. diff --git a/.web-docs/components/builder/vsphere-iso/README.md b/.web-docs/components/builder/vsphere-iso/README.md index 34652e7c..13002cd1 100644 --- a/.web-docs/components/builder/vsphere-iso/README.md +++ b/.web-docs/components/builder/vsphere-iso/README.md @@ -395,7 +395,10 @@ wget http://{{ .HTTPIP }}:{{ .HTTPPort }}/foo/bar/preseed.cfg - `displays` (int32) - Number of video displays. See [vSphere documentation](https://docs.vmware.com/en/VMware-vSphere/7.0/com.vmware.vsphere.vm_admin.doc/GUID-789C3913-1053-4850-A0F0-E29C3D32B6DA.html) for supported maximums. Defaults to 1. -- `vgpu_profile` (string) - vGPU profile for accelerated graphics. See [NVIDIA GRID vGPU documentation](https://docs.nvidia.com/grid/latest/grid-vgpu-user-guide/index.html#configure-vmware-vsphere-vm-with-vgpu) +- `pci_passthrough_allowed_device` ([]PCIPassthroughAllowedDevice) - Configure Dynamic DirectPath I/O PCI Passthrough for virtual machine. See [vSphere documentation](https://docs.vmware.com/en/VMware-vSphere/7.0/com.vmware.vsphere.vm_admin.doc/GUID-5B3CAB26-5D06-4A99-92A0-3A04C69CE64B.html) + +- `vgpu_profile` (string) - vGPU profile for accelerated graphics. + vGPU profile for accelerated graphics. See [NVIDIA GRID vGPU documentation](https://docs.nvidia.com/grid/latest/grid-vgpu-user-guide/index.html#configure-vmware-vsphere-vm-with-vgpu) for examples of profile names. Defaults to none. - `NestedHV` (bool) - Enable nested hardware virtualization for VM. Defaults to `false`. diff --git a/builder/vsphere/clone/config.hcl2spec.go b/builder/vsphere/clone/config.hcl2spec.go index 41916013..24a08c72 100644 --- a/builder/vsphere/clone/config.hcl2spec.go +++ b/builder/vsphere/clone/config.hcl2spec.go @@ -61,6 +61,7 @@ type FlatConfig struct { MemoryHotAddEnabled *bool `mapstructure:"RAM_hot_plug" cty:"RAM_hot_plug" hcl:"RAM_hot_plug"` VideoRAM *int64 `mapstructure:"video_ram" cty:"video_ram" hcl:"video_ram"` Displays *int32 `mapstructure:"displays" cty:"displays" hcl:"displays"` + AllowedDevices []common.FlatPCIPassthroughAllowedDevice `mapstructure:"pci_passthrough_allowed_device" cty:"pci_passthrough_allowed_device" hcl:"pci_passthrough_allowed_device"` VGPUProfile *string `mapstructure:"vgpu_profile" cty:"vgpu_profile" hcl:"vgpu_profile"` NestedHV *bool `mapstructure:"NestedHV" cty:"NestedHV" hcl:"NestedHV"` Firmware *string `mapstructure:"firmware" cty:"firmware" hcl:"firmware"` @@ -211,6 +212,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "RAM_hot_plug": &hcldec.AttrSpec{Name: "RAM_hot_plug", Type: cty.Bool, Required: false}, "video_ram": &hcldec.AttrSpec{Name: "video_ram", Type: cty.Number, Required: false}, "displays": &hcldec.AttrSpec{Name: "displays", Type: cty.Number, Required: false}, + "pci_passthrough_allowed_device": &hcldec.BlockListSpec{TypeName: "pci_passthrough_allowed_device", Nested: hcldec.ObjectSpec((*common.FlatPCIPassthroughAllowedDevice)(nil).HCL2Spec())}, "vgpu_profile": &hcldec.AttrSpec{Name: "vgpu_profile", Type: cty.String, Required: false}, "NestedHV": &hcldec.AttrSpec{Name: "NestedHV", Type: cty.Bool, Required: false}, "firmware": &hcldec.AttrSpec{Name: "firmware", Type: cty.String, Required: false}, diff --git a/builder/vsphere/common/step_hardware.go b/builder/vsphere/common/step_hardware.go index 7b676437..df891da7 100644 --- a/builder/vsphere/common/step_hardware.go +++ b/builder/vsphere/common/step_hardware.go @@ -2,19 +2,27 @@ // SPDX-License-Identifier: MPL-2.0 //go:generate packer-sdc struct-markdown -//go:generate packer-sdc mapstructure-to-hcl2 -type HardwareConfig +//go:generate packer-sdc mapstructure-to-hcl2 -type HardwareConfig,PCIPassthroughAllowedDevice package common import ( "context" "fmt" + "reflect" "github.com/hashicorp/packer-plugin-sdk/multistep" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" "github.com/hashicorp/packer-plugin-vsphere/builder/vsphere/driver" ) +type PCIPassthroughAllowedDevice struct { + DeviceId string `mapstructure:"device_id"` + VendorId string `mapstructure:"vendor_id"` + SubVendorId string `mapstructure:"sub_vendor_id"` + SubDeviceId string `mapstructure:"sub_device_id"` +} + type HardwareConfig struct { // Number of CPU cores. CPUs int32 `mapstructure:"CPUs"` @@ -41,6 +49,9 @@ type HardwareConfig struct { // Number of video displays. See [vSphere documentation](https://docs.vmware.com/en/VMware-vSphere/7.0/com.vmware.vsphere.vm_admin.doc/GUID-789C3913-1053-4850-A0F0-E29C3D32B6DA.html) // for supported maximums. Defaults to 1. Displays int32 `mapstructure:"displays"` + // Configure Dynamic DirectPath I/O PCI Passthrough for virtual machine. See [vSphere documentation](https://docs.vmware.com/en/VMware-vSphere/7.0/com.vmware.vsphere.vm_admin.doc/GUID-5B3CAB26-5D06-4A99-92A0-3A04C69CE64B.html) + AllowedDevices []PCIPassthroughAllowedDevice `mapstructure:"pci_passthrough_allowed_device"` + // vGPU profile for accelerated graphics. // vGPU profile for accelerated graphics. See [NVIDIA GRID vGPU documentation](https://docs.nvidia.com/grid/latest/grid-vgpu-user-guide/index.html#configure-vmware-vsphere-vm-with-vgpu) // for examples of profile names. Defaults to none. VGPUProfile string `mapstructure:"vgpu_profile"` @@ -86,9 +97,14 @@ func (s *StepConfigureHardware) Run(_ context.Context, state multistep.StateBag) ui := state.Get("ui").(packersdk.Ui) vm := state.Get("vm").(driver.VirtualMachine) - if *s.Config != (HardwareConfig{}) { + if !reflect.DeepEqual(*s.Config, HardwareConfig{}) { ui.Say("Customizing hardware...") + var allowedDevices []driver.PCIPassthroughAllowedDevice + for _, device := range s.Config.AllowedDevices { + allowedDevices = append(allowedDevices, driver.PCIPassthroughAllowedDevice(device)) + } + err := vm.Configure(&driver.HardwareConfig{ CPUs: s.Config.CPUs, CpuCores: s.Config.CpuCores, @@ -102,6 +118,7 @@ func (s *StepConfigureHardware) Run(_ context.Context, state multistep.StateBag) MemoryHotAddEnabled: s.Config.MemoryHotAddEnabled, VideoRAM: s.Config.VideoRAM, Displays: s.Config.Displays, + AllowedDevices: allowedDevices, VGPUProfile: s.Config.VGPUProfile, Firmware: s.Config.Firmware, ForceBIOSSetup: s.Config.ForceBIOSSetup, diff --git a/builder/vsphere/common/step_hardware.hcl2spec.go b/builder/vsphere/common/step_hardware.hcl2spec.go index 1b3f0f7f..a4c9dc51 100644 --- a/builder/vsphere/common/step_hardware.hcl2spec.go +++ b/builder/vsphere/common/step_hardware.hcl2spec.go @@ -10,23 +10,24 @@ import ( // FlatHardwareConfig is an auto-generated flat version of HardwareConfig. // Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. type FlatHardwareConfig struct { - CPUs *int32 `mapstructure:"CPUs" cty:"CPUs" hcl:"CPUs"` - CpuCores *int32 `mapstructure:"cpu_cores" cty:"cpu_cores" hcl:"cpu_cores"` - CPUReservation *int64 `mapstructure:"CPU_reservation" cty:"CPU_reservation" hcl:"CPU_reservation"` - CPULimit *int64 `mapstructure:"CPU_limit" cty:"CPU_limit" hcl:"CPU_limit"` - CpuHotAddEnabled *bool `mapstructure:"CPU_hot_plug" cty:"CPU_hot_plug" hcl:"CPU_hot_plug"` - RAM *int64 `mapstructure:"RAM" cty:"RAM" hcl:"RAM"` - RAMReservation *int64 `mapstructure:"RAM_reservation" cty:"RAM_reservation" hcl:"RAM_reservation"` - RAMReserveAll *bool `mapstructure:"RAM_reserve_all" cty:"RAM_reserve_all" hcl:"RAM_reserve_all"` - MemoryHotAddEnabled *bool `mapstructure:"RAM_hot_plug" cty:"RAM_hot_plug" hcl:"RAM_hot_plug"` - VideoRAM *int64 `mapstructure:"video_ram" cty:"video_ram" hcl:"video_ram"` - Displays *int32 `mapstructure:"displays" cty:"displays" hcl:"displays"` - VGPUProfile *string `mapstructure:"vgpu_profile" cty:"vgpu_profile" hcl:"vgpu_profile"` - NestedHV *bool `mapstructure:"NestedHV" cty:"NestedHV" hcl:"NestedHV"` - Firmware *string `mapstructure:"firmware" cty:"firmware" hcl:"firmware"` - ForceBIOSSetup *bool `mapstructure:"force_bios_setup" cty:"force_bios_setup" hcl:"force_bios_setup"` - VTPMEnabled *bool `mapstructure:"vTPM" cty:"vTPM" hcl:"vTPM"` - VirtualPrecisionClock *string `mapstructure:"precision_clock" cty:"precision_clock" hcl:"precision_clock"` + CPUs *int32 `mapstructure:"CPUs" cty:"CPUs" hcl:"CPUs"` + CpuCores *int32 `mapstructure:"cpu_cores" cty:"cpu_cores" hcl:"cpu_cores"` + CPUReservation *int64 `mapstructure:"CPU_reservation" cty:"CPU_reservation" hcl:"CPU_reservation"` + CPULimit *int64 `mapstructure:"CPU_limit" cty:"CPU_limit" hcl:"CPU_limit"` + CpuHotAddEnabled *bool `mapstructure:"CPU_hot_plug" cty:"CPU_hot_plug" hcl:"CPU_hot_plug"` + RAM *int64 `mapstructure:"RAM" cty:"RAM" hcl:"RAM"` + RAMReservation *int64 `mapstructure:"RAM_reservation" cty:"RAM_reservation" hcl:"RAM_reservation"` + RAMReserveAll *bool `mapstructure:"RAM_reserve_all" cty:"RAM_reserve_all" hcl:"RAM_reserve_all"` + MemoryHotAddEnabled *bool `mapstructure:"RAM_hot_plug" cty:"RAM_hot_plug" hcl:"RAM_hot_plug"` + VideoRAM *int64 `mapstructure:"video_ram" cty:"video_ram" hcl:"video_ram"` + Displays *int32 `mapstructure:"displays" cty:"displays" hcl:"displays"` + AllowedDevices []FlatPCIPassthroughAllowedDevice `mapstructure:"pci_passthrough_allowed_device" cty:"pci_passthrough_allowed_device" hcl:"pci_passthrough_allowed_device"` + VGPUProfile *string `mapstructure:"vgpu_profile" cty:"vgpu_profile" hcl:"vgpu_profile"` + NestedHV *bool `mapstructure:"NestedHV" cty:"NestedHV" hcl:"NestedHV"` + Firmware *string `mapstructure:"firmware" cty:"firmware" hcl:"firmware"` + ForceBIOSSetup *bool `mapstructure:"force_bios_setup" cty:"force_bios_setup" hcl:"force_bios_setup"` + VTPMEnabled *bool `mapstructure:"vTPM" cty:"vTPM" hcl:"vTPM"` + VirtualPrecisionClock *string `mapstructure:"precision_clock" cty:"precision_clock" hcl:"precision_clock"` } // FlatMapstructure returns a new FlatHardwareConfig. @@ -41,23 +42,53 @@ func (*HardwareConfig) FlatMapstructure() interface{ HCL2Spec() map[string]hclde // The decoded values from this spec will then be applied to a FlatHardwareConfig. func (*FlatHardwareConfig) HCL2Spec() map[string]hcldec.Spec { s := map[string]hcldec.Spec{ - "CPUs": &hcldec.AttrSpec{Name: "CPUs", Type: cty.Number, Required: false}, - "cpu_cores": &hcldec.AttrSpec{Name: "cpu_cores", Type: cty.Number, Required: false}, - "CPU_reservation": &hcldec.AttrSpec{Name: "CPU_reservation", Type: cty.Number, Required: false}, - "CPU_limit": &hcldec.AttrSpec{Name: "CPU_limit", Type: cty.Number, Required: false}, - "CPU_hot_plug": &hcldec.AttrSpec{Name: "CPU_hot_plug", Type: cty.Bool, Required: false}, - "RAM": &hcldec.AttrSpec{Name: "RAM", Type: cty.Number, Required: false}, - "RAM_reservation": &hcldec.AttrSpec{Name: "RAM_reservation", Type: cty.Number, Required: false}, - "RAM_reserve_all": &hcldec.AttrSpec{Name: "RAM_reserve_all", Type: cty.Bool, Required: false}, - "RAM_hot_plug": &hcldec.AttrSpec{Name: "RAM_hot_plug", Type: cty.Bool, Required: false}, - "video_ram": &hcldec.AttrSpec{Name: "video_ram", Type: cty.Number, Required: false}, - "displays": &hcldec.AttrSpec{Name: "displays", Type: cty.Number, Required: false}, - "vgpu_profile": &hcldec.AttrSpec{Name: "vgpu_profile", Type: cty.String, Required: false}, - "NestedHV": &hcldec.AttrSpec{Name: "NestedHV", Type: cty.Bool, Required: false}, - "firmware": &hcldec.AttrSpec{Name: "firmware", Type: cty.String, Required: false}, - "force_bios_setup": &hcldec.AttrSpec{Name: "force_bios_setup", Type: cty.Bool, Required: false}, - "vTPM": &hcldec.AttrSpec{Name: "vTPM", Type: cty.Bool, Required: false}, - "precision_clock": &hcldec.AttrSpec{Name: "precision_clock", Type: cty.String, Required: false}, + "CPUs": &hcldec.AttrSpec{Name: "CPUs", Type: cty.Number, Required: false}, + "cpu_cores": &hcldec.AttrSpec{Name: "cpu_cores", Type: cty.Number, Required: false}, + "CPU_reservation": &hcldec.AttrSpec{Name: "CPU_reservation", Type: cty.Number, Required: false}, + "CPU_limit": &hcldec.AttrSpec{Name: "CPU_limit", Type: cty.Number, Required: false}, + "CPU_hot_plug": &hcldec.AttrSpec{Name: "CPU_hot_plug", Type: cty.Bool, Required: false}, + "RAM": &hcldec.AttrSpec{Name: "RAM", Type: cty.Number, Required: false}, + "RAM_reservation": &hcldec.AttrSpec{Name: "RAM_reservation", Type: cty.Number, Required: false}, + "RAM_reserve_all": &hcldec.AttrSpec{Name: "RAM_reserve_all", Type: cty.Bool, Required: false}, + "RAM_hot_plug": &hcldec.AttrSpec{Name: "RAM_hot_plug", Type: cty.Bool, Required: false}, + "video_ram": &hcldec.AttrSpec{Name: "video_ram", Type: cty.Number, Required: false}, + "displays": &hcldec.AttrSpec{Name: "displays", Type: cty.Number, Required: false}, + "pci_passthrough_allowed_device": &hcldec.BlockListSpec{TypeName: "pci_passthrough_allowed_device", Nested: hcldec.ObjectSpec((*FlatPCIPassthroughAllowedDevice)(nil).HCL2Spec())}, + "vgpu_profile": &hcldec.AttrSpec{Name: "vgpu_profile", Type: cty.String, Required: false}, + "NestedHV": &hcldec.AttrSpec{Name: "NestedHV", Type: cty.Bool, Required: false}, + "firmware": &hcldec.AttrSpec{Name: "firmware", Type: cty.String, Required: false}, + "force_bios_setup": &hcldec.AttrSpec{Name: "force_bios_setup", Type: cty.Bool, Required: false}, + "vTPM": &hcldec.AttrSpec{Name: "vTPM", Type: cty.Bool, Required: false}, + "precision_clock": &hcldec.AttrSpec{Name: "precision_clock", Type: cty.String, Required: false}, + } + return s +} + +// FlatPCIPassthroughAllowedDevice is an auto-generated flat version of PCIPassthroughAllowedDevice. +// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. +type FlatPCIPassthroughAllowedDevice struct { + DeviceId *string `mapstructure:"device_id" cty:"device_id" hcl:"device_id"` + VendorId *string `mapstructure:"vendor_id" cty:"vendor_id" hcl:"vendor_id"` + SubVendorId *string `mapstructure:"sub_vendor_id" cty:"sub_vendor_id" hcl:"sub_vendor_id"` + SubDeviceId *string `mapstructure:"sub_device_id" cty:"sub_device_id" hcl:"sub_device_id"` +} + +// FlatMapstructure returns a new FlatPCIPassthroughAllowedDevice. +// FlatPCIPassthroughAllowedDevice is an auto-generated flat version of PCIPassthroughAllowedDevice. +// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up. +func (*PCIPassthroughAllowedDevice) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } { + return new(FlatPCIPassthroughAllowedDevice) +} + +// HCL2Spec returns the hcl spec of a PCIPassthroughAllowedDevice. +// This spec is used by HCL to read the fields of PCIPassthroughAllowedDevice. +// The decoded values from this spec will then be applied to a FlatPCIPassthroughAllowedDevice. +func (*FlatPCIPassthroughAllowedDevice) HCL2Spec() map[string]hcldec.Spec { + s := map[string]hcldec.Spec{ + "device_id": &hcldec.AttrSpec{Name: "device_id", Type: cty.String, Required: false}, + "vendor_id": &hcldec.AttrSpec{Name: "vendor_id", Type: cty.String, Required: false}, + "sub_vendor_id": &hcldec.AttrSpec{Name: "sub_vendor_id", Type: cty.String, Required: false}, + "sub_device_id": &hcldec.AttrSpec{Name: "sub_device_id", Type: cty.String, Required: false}, } return s } diff --git a/builder/vsphere/common/step_hardware_test.go b/builder/vsphere/common/step_hardware_test.go index b2089307..158fc5b4 100644 --- a/builder/vsphere/common/step_hardware_test.go +++ b/builder/vsphere/common/step_hardware_test.go @@ -213,6 +213,12 @@ func basicStepConfigureHardware() *StepConfigureHardware { } func driverHardwareConfigFromConfig(config *HardwareConfig) *driver.HardwareConfig { + + var allowedDevices []driver.PCIPassthroughAllowedDevice + for _, device := range config.AllowedDevices { + allowedDevices = append(allowedDevices, driver.PCIPassthroughAllowedDevice(device)) + } + return &driver.HardwareConfig{ CPUs: config.CPUs, CpuCores: config.CpuCores, @@ -225,6 +231,7 @@ func driverHardwareConfigFromConfig(config *HardwareConfig) *driver.HardwareConf CpuHotAddEnabled: config.CpuHotAddEnabled, MemoryHotAddEnabled: config.MemoryHotAddEnabled, VideoRAM: config.VideoRAM, + AllowedDevices: allowedDevices, VGPUProfile: config.VGPUProfile, Firmware: config.Firmware, ForceBIOSSetup: config.ForceBIOSSetup, diff --git a/builder/vsphere/driver/vm.go b/builder/vsphere/driver/vm.go index 24835b18..3f6f8d72 100644 --- a/builder/vsphere/driver/vm.go +++ b/builder/vsphere/driver/vm.go @@ -10,6 +10,7 @@ import ( "log" "net" "reflect" + "strconv" "strings" "time" @@ -92,6 +93,13 @@ type CloneConfig struct { StorageConfig StorageConfig } +type PCIPassthroughAllowedDevice struct { + DeviceId string + VendorId string + SubVendorId string + SubDeviceId string +} + type HardwareConfig struct { CPUs int32 CpuCores int32 @@ -105,6 +113,7 @@ type HardwareConfig struct { MemoryHotAddEnabled bool VideoRAM int64 Displays int32 + AllowedDevices []PCIPassthroughAllowedDevice VGPUProfile string Firmware string ForceBIOSSetup bool @@ -617,6 +626,15 @@ func (vm *VirtualMachineDriver) Configure(config *HardwareConfig) error { confSpec.DeviceChange = append(confSpec.DeviceChange, spec) } + if len(config.AllowedDevices) > 0 { + VirtualPCIPassthroughAllowedDevice := newVirtualPCIPassthroughAllowedDevice(config.AllowedDevices) + spec := &types.VirtualDeviceConfigSpec{ + Device: &VirtualPCIPassthroughAllowedDevice, + Operation: types.VirtualDeviceConfigSpecOperationAdd, + } + confSpec.DeviceChange = append(confSpec.DeviceChange, spec) + } + efiSecureBootEnabled := false firmware := config.Firmware @@ -1065,6 +1083,58 @@ func findNetwork(network string, host string, d *VCenterDriver) (object.NetworkR return nil, fmt.Errorf("Couldn't find network; 'host' and 'network' not specified. At least one of the two must be specified.") } +func newVirtualPCIPassthroughAllowedDevice(devices []PCIPassthroughAllowedDevice) types.VirtualPCIPassthrough { + allowedDevices := make([]types.VirtualPCIPassthroughAllowedDevice, len(devices)) + for i, device := range devices { + deviceId, err := strconv.ParseInt(device.DeviceId, 16, 32) + if err != nil { + // handle error, for example: + log.Printf("Error parsing DeviceId: %v\n", err) + continue + } + vendorId, err := strconv.ParseUint(device.VendorId, 16, 32) + if err != nil { + log.Printf("Error parsing VendorId: %v\n", err) + continue + } + subVendorId, err := strconv.ParseUint(device.SubVendorId, 16, 32) + if err != nil { + log.Printf("Error parsing SubVendorId: %v\n", err) + continue + } + subDeviceId, err := strconv.ParseUint(device.SubDeviceId, 16, 32) + if err != nil { + log.Printf("Error parsing SubDeviceId: %v\n", err) + continue + } + + allowedDevices[i] = types.VirtualPCIPassthroughAllowedDevice{ + DeviceId: int32(deviceId), + VendorId: int32(vendorId), + SubVendorId: int32(subVendorId), + SubDeviceId: int32(subDeviceId), + } + + log.Printf("Adding Pci Dynamic IO Passthrough device with device_id '%s',vendor_id '%s',subsystem_id '%s',subsystem_vendor_id '%s'", + device.DeviceId, + device.VendorId, + device.SubDeviceId, + device.SubVendorId) + } + + return types.VirtualPCIPassthrough{ + VirtualDevice: types.VirtualDevice{ + DeviceInfo: &types.Description{ + Summary: "", + Label: fmt.Sprintf("New PCI Allowed device"), + }, + Backing: &types.VirtualPCIPassthroughDynamicBackingInfo{ + AllowedDevice: allowedDevices, + }, + }, + } +} + func newVGPUProfile(vGPUProfile string) types.VirtualPCIPassthrough { return types.VirtualPCIPassthrough{ VirtualDevice: types.VirtualDevice{ diff --git a/builder/vsphere/iso/config.hcl2spec.go b/builder/vsphere/iso/config.hcl2spec.go index 1c27b356..ae8e139b 100644 --- a/builder/vsphere/iso/config.hcl2spec.go +++ b/builder/vsphere/iso/config.hcl2spec.go @@ -59,6 +59,7 @@ type FlatConfig struct { MemoryHotAddEnabled *bool `mapstructure:"RAM_hot_plug" cty:"RAM_hot_plug" hcl:"RAM_hot_plug"` VideoRAM *int64 `mapstructure:"video_ram" cty:"video_ram" hcl:"video_ram"` Displays *int32 `mapstructure:"displays" cty:"displays" hcl:"displays"` + AllowedDevices []common.FlatPCIPassthroughAllowedDevice `mapstructure:"pci_passthrough_allowed_device" cty:"pci_passthrough_allowed_device" hcl:"pci_passthrough_allowed_device"` VGPUProfile *string `mapstructure:"vgpu_profile" cty:"vgpu_profile" hcl:"vgpu_profile"` NestedHV *bool `mapstructure:"NestedHV" cty:"NestedHV" hcl:"NestedHV"` Firmware *string `mapstructure:"firmware" cty:"firmware" hcl:"firmware"` @@ -211,6 +212,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "RAM_hot_plug": &hcldec.AttrSpec{Name: "RAM_hot_plug", Type: cty.Bool, Required: false}, "video_ram": &hcldec.AttrSpec{Name: "video_ram", Type: cty.Number, Required: false}, "displays": &hcldec.AttrSpec{Name: "displays", Type: cty.Number, Required: false}, + "pci_passthrough_allowed_device": &hcldec.BlockListSpec{TypeName: "pci_passthrough_allowed_device", Nested: hcldec.ObjectSpec((*common.FlatPCIPassthroughAllowedDevice)(nil).HCL2Spec())}, "vgpu_profile": &hcldec.AttrSpec{Name: "vgpu_profile", Type: cty.String, Required: false}, "NestedHV": &hcldec.AttrSpec{Name: "NestedHV", Type: cty.Bool, Required: false}, "firmware": &hcldec.AttrSpec{Name: "firmware", Type: cty.String, Required: false}, diff --git a/docs-partials/builder/vsphere/common/HardwareConfig-not-required.mdx b/docs-partials/builder/vsphere/common/HardwareConfig-not-required.mdx index e5b2c27c..6f9149f1 100644 --- a/docs-partials/builder/vsphere/common/HardwareConfig-not-required.mdx +++ b/docs-partials/builder/vsphere/common/HardwareConfig-not-required.mdx @@ -25,7 +25,10 @@ - `displays` (int32) - Number of video displays. See [vSphere documentation](https://docs.vmware.com/en/VMware-vSphere/7.0/com.vmware.vsphere.vm_admin.doc/GUID-789C3913-1053-4850-A0F0-E29C3D32B6DA.html) for supported maximums. Defaults to 1. -- `vgpu_profile` (string) - vGPU profile for accelerated graphics. See [NVIDIA GRID vGPU documentation](https://docs.nvidia.com/grid/latest/grid-vgpu-user-guide/index.html#configure-vmware-vsphere-vm-with-vgpu) +- `pci_passthrough_allowed_device` ([]PCIPassthroughAllowedDevice) - Configure Dynamic DirectPath I/O PCI Passthrough for virtual machine. See [vSphere documentation](https://docs.vmware.com/en/VMware-vSphere/7.0/com.vmware.vsphere.vm_admin.doc/GUID-5B3CAB26-5D06-4A99-92A0-3A04C69CE64B.html) + +- `vgpu_profile` (string) - vGPU profile for accelerated graphics. + vGPU profile for accelerated graphics. See [NVIDIA GRID vGPU documentation](https://docs.nvidia.com/grid/latest/grid-vgpu-user-guide/index.html#configure-vmware-vsphere-vm-with-vgpu) for examples of profile names. Defaults to none. - `NestedHV` (bool) - Enable nested hardware virtualization for VM. Defaults to `false`. diff --git a/docs-partials/builder/vsphere/common/PCIPassthroughAllowedDevice-not-required.mdx b/docs-partials/builder/vsphere/common/PCIPassthroughAllowedDevice-not-required.mdx new file mode 100644 index 00000000..83b5fba7 --- /dev/null +++ b/docs-partials/builder/vsphere/common/PCIPassthroughAllowedDevice-not-required.mdx @@ -0,0 +1,11 @@ + + +- `device_id` (string) - Device Id + +- `vendor_id` (string) - Vendor Id + +- `sub_vendor_id` (string) - Sub Vendor Id + +- `sub_device_id` (string) - Sub Device Id + +