diff --git a/builder/vsphere/clone/config.hcl2spec.go b/builder/vsphere/clone/config.hcl2spec.go index 0cda209fa..e2a7609e1 100644 --- a/builder/vsphere/clone/config.hcl2spec.go +++ b/builder/vsphere/clone/config.hcl2spec.go @@ -43,6 +43,7 @@ type FlatConfig struct { RAMReserveAll *bool `mapstructure:"RAM_reserve_all" cty:"RAM_reserve_all"` MemoryHotAddEnabled *bool `mapstructure:"RAM_hot_plug" cty:"RAM_hot_plug"` VideoRAM *int64 `mapstructure:"video_ram" cty:"video_ram"` + VGPUProfile *string `mapstructure:"vgpu_profile" cty:"vgpu_profile"` NestedHV *bool `mapstructure:"NestedHV" cty:"NestedHV"` Firmware *string `mapstructure:"firmware" cty:"firmware"` ConfigParams map[string]string `mapstructure:"configuration_parameters" cty:"configuration_parameters"` @@ -142,6 +143,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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}, + "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}, "configuration_parameters": &hcldec.AttrSpec{Name: "configuration_parameters", Type: cty.Map(cty.String), Required: false}, diff --git a/builder/vsphere/common/step_hardware.go b/builder/vsphere/common/step_hardware.go index 449f5bcd0..27aba446e 100644 --- a/builder/vsphere/common/step_hardware.go +++ b/builder/vsphere/common/step_hardware.go @@ -34,6 +34,9 @@ type HardwareConfig struct { MemoryHotAddEnabled bool `mapstructure:"RAM_hot_plug"` // Amount of video memory in MB. VideoRAM int64 `mapstructure:"video_ram"` + // 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"` // Enable nested hardware virtualization for VM. Defaults to `false`. NestedHV bool `mapstructure:"NestedHV"` // Set the Firmware for virtual machine. Supported values: `bios`, `efi`, `efi-secure` or empty string to keep as in template. Defaults to empty string. @@ -77,6 +80,7 @@ func (s *StepConfigureHardware) Run(_ context.Context, state multistep.StateBag) CpuHotAddEnabled: s.Config.CpuHotAddEnabled, MemoryHotAddEnabled: s.Config.MemoryHotAddEnabled, VideoRAM: s.Config.VideoRAM, + VGPUProfile: s.Config.VGPUProfile, Firmware: s.Config.Firmware, }) if err != nil { diff --git a/builder/vsphere/common/step_hardware.hcl2spec.go b/builder/vsphere/common/step_hardware.hcl2spec.go index 9eb600d8a..b5950afe2 100644 --- a/builder/vsphere/common/step_hardware.hcl2spec.go +++ b/builder/vsphere/common/step_hardware.hcl2spec.go @@ -19,6 +19,7 @@ type FlatHardwareConfig struct { RAMReserveAll *bool `mapstructure:"RAM_reserve_all" cty:"RAM_reserve_all"` MemoryHotAddEnabled *bool `mapstructure:"RAM_hot_plug" cty:"RAM_hot_plug"` VideoRAM *int64 `mapstructure:"video_ram" cty:"video_ram"` + VGPUProfile *string `mapstructure:"vgpu_profile" cty:"vgpu_profile"` NestedHV *bool `mapstructure:"NestedHV" cty:"NestedHV"` Firmware *string `mapstructure:"firmware" cty:"firmware"` } @@ -45,6 +46,7 @@ func (*FlatHardwareConfig) HCL2Spec() map[string]hcldec.Spec { "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}, + "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/driver/vm.go b/builder/vsphere/driver/vm.go index 6df99b987..b29ab9d55 100644 --- a/builder/vsphere/driver/vm.go +++ b/builder/vsphere/driver/vm.go @@ -48,6 +48,7 @@ type HardwareConfig struct { CpuHotAddEnabled bool MemoryHotAddEnabled bool VideoRAM int64 + VGPUProfile string Firmware string } @@ -381,6 +382,31 @@ func (vm *VirtualMachine) Configure(config *HardwareConfig) error { } confSpec.DeviceChange = append(confSpec.DeviceChange, spec) } + if config.VGPUProfile != "" { + devices, err := vm.vm.Device(vm.driver.ctx) + if err != nil { + return err + } + + pciDevices := devices.SelectByType((*types.VirtualPCIPassthrough)(nil)) + vGPUDevices := pciDevices.SelectByBackingInfo((*types.VirtualPCIPassthroughVmiopBackingInfo)(nil)) + var operation types.VirtualDeviceConfigSpecOperation + if len(vGPUDevices) > 1 { + return err + } else if len(pciDevices) == 1 { + operation = types.VirtualDeviceConfigSpecOperationEdit + } else if len(pciDevices) == 0 { + operation = types.VirtualDeviceConfigSpecOperationAdd + } + + vGPUProfile := newVGPUProfile(config.VGPUProfile) + spec := &types.VirtualDeviceConfigSpec{ + Device: &vGPUProfile, + Operation: operation, + } + log.Printf("Adding vGPU device with profile '%s'", config.VGPUProfile) + confSpec.DeviceChange = append(confSpec.DeviceChange, spec) + } if config.Firmware == "efi-secure" || config.Firmware == "efi" { confSpec.Firmware = "efi" @@ -625,6 +651,20 @@ func addNetwork(d *Driver, devices object.VirtualDeviceList, config *CreateConfi return devices, nil } +func newVGPUProfile(vGPUProfile string) types.VirtualPCIPassthrough { + return types.VirtualPCIPassthrough{ + VirtualDevice: types.VirtualDevice{ + DeviceInfo: &types.Description{ + Summary: "", + Label: fmt.Sprintf("New vGPU %v PCI device", vGPUProfile), + }, + Backing: &types.VirtualPCIPassthroughVmiopBackingInfo{ + Vgpu: vGPUProfile, + }, + }, + } +} + func (vm *VirtualMachine) AddCdrom(controllerType string, isoPath string) error { devices, err := vm.vm.Device(vm.driver.ctx) if err != nil { diff --git a/builder/vsphere/iso/config.hcl2spec.go b/builder/vsphere/iso/config.hcl2spec.go index 17120f42a..34375612b 100644 --- a/builder/vsphere/iso/config.hcl2spec.go +++ b/builder/vsphere/iso/config.hcl2spec.go @@ -54,6 +54,7 @@ type FlatConfig struct { RAMReserveAll *bool `mapstructure:"RAM_reserve_all" cty:"RAM_reserve_all"` MemoryHotAddEnabled *bool `mapstructure:"RAM_hot_plug" cty:"RAM_hot_plug"` VideoRAM *int64 `mapstructure:"video_ram" cty:"video_ram"` + VGPUProfile *string `mapstructure:"vgpu_profile" cty:"vgpu_profile"` NestedHV *bool `mapstructure:"NestedHV" cty:"NestedHV"` ConfigParams map[string]string `mapstructure:"configuration_parameters" cty:"configuration_parameters"` ISOChecksum *string `mapstructure:"iso_checksum" required:"true" cty:"iso_checksum"` @@ -179,6 +180,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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}, + "vgpu_profile": &hcldec.AttrSpec{Name: "vgpu_profile", Type: cty.String, Required: false}, "NestedHV": &hcldec.AttrSpec{Name: "NestedHV", Type: cty.Bool, Required: false}, "configuration_parameters": &hcldec.AttrSpec{Name: "configuration_parameters", Type: cty.Map(cty.String), Required: false}, "iso_checksum": &hcldec.AttrSpec{Name: "iso_checksum", Type: cty.String, Required: false}, diff --git a/website/pages/partials/builder/vsphere/common/HardwareConfig-not-required.mdx b/website/pages/partials/builder/vsphere/common/HardwareConfig-not-required.mdx index 4e309a7d6..c8daea1bb 100644 --- a/website/pages/partials/builder/vsphere/common/HardwareConfig-not-required.mdx +++ b/website/pages/partials/builder/vsphere/common/HardwareConfig-not-required.mdx @@ -21,6 +21,9 @@ - `video_ram` (int64) - Amount of video memory in MB. +- `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) + for examples of profile names. Defaults to none. + - `NestedHV` (bool) - Enable nested hardware virtualization for VM. Defaults to `false`. - `firmware` (string) - Set the Firmware for virtual machine. Supported values: `bios`, `efi`, `efi-secure` or empty string to keep as in template. Defaults to empty string.