Skip to content

Commit

Permalink
fix hashicorp#1265 support vGPU
Browse files Browse the repository at this point in the history
Original implementation of PciPassthrough can't be use for vGPU because it's link to host systemId
  • Loading branch information
aarnaud committed Mar 31, 2021
1 parent d558be4 commit 8326641
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1060,3 +1060,61 @@ func PciPassthroughApplyOperation(d *schema.ResourceData, c *govmomi.Client, l o
}
return applyConfig.VirtualDevice, applyConfig.Spec, nil
}

// SharedPciPassthroughApplyOperation checks for changes in a virtual machine's
// Shared PCI passthrough device and creates config specs to apply apply to the
// virtual machine.
func SharedPciPassthroughApplyOperation(d *schema.ResourceData, c *govmomi.Client, l object.VirtualDeviceList) (object.VirtualDeviceList, []types.BaseVirtualDeviceConfigSpec, error) {
old, new := d.GetChange("shared_pci_device_id")
oldDevId := old.(string)
newDevId := new.(string)

var specs []types.BaseVirtualDeviceConfigSpec
if oldDevId == newDevId {
return l, specs, nil
}

vm, err := virtualmachine.FromUUID(c, d.Id())
if err != nil {
return nil, nil, err
}
vprops, err := virtualmachine.Properties(vm)
if err != nil {
return nil, nil, err
}
// This will only find a device for delete operations.
for _, vmDevP := range vprops.Config.Hardware.Device {
if vmDev, ok := vmDevP.(*types.VirtualPCIPassthrough); ok {
if vmDev.Backing.(*types.VirtualPCIPassthroughVmiopBackingInfo).Vgpu == oldDevId {
dspec, err := object.VirtualDeviceList{vmDev}.ConfigSpec(types.VirtualDeviceConfigSpecOperationRemove)
if err != nil {
return nil, nil, err
}
specs = append(specs, dspec...)

l = applyDeviceChange(l, dspec)
d.Set("reboot_required", true)
}
}
}

if newDevId != "" {
dev := &types.VirtualPCIPassthrough{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Backing: &types.VirtualPCIPassthroughVmiopBackingInfo{
Vgpu: newDevId,
},
},
}
dspec, err := object.VirtualDeviceList{dev}.ConfigSpec(types.VirtualDeviceConfigSpecOperationAdd)
if err != nil {
return nil, nil, err
}
specs = append(specs, dspec...)
l = applyDeviceChange(l, dspec)
d.Set("reboot_required", true)
}

return l, specs, nil
}
28 changes: 26 additions & 2 deletions vsphere/resource_vsphere_virtual_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,12 @@ func resourceVSphereVirtualMachine() *schema.Resource {
Description: "A list of PCI passthrough devices",
Elem: &schema.Schema{Type: schema.TypeString},
},
"shared_pci_device_id": {
Type: schema.TypeString,
Optional: true,
Description: "Id of Shared PCI passthrough device, 'grid_rtx8000-8q'",
Elem: &schema.Schema{Type: schema.TypeString},
},
"clone": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -504,8 +510,20 @@ func resourceVSphereVirtualMachineRead(d *schema.ResourceData, meta interface{})
var pciDevs []string
for _, dev := range vprops.Config.Hardware.Device {
if pci, ok := dev.(*types.VirtualPCIPassthrough); ok {
devId := pci.Backing.(*types.VirtualPCIPassthroughDeviceBackingInfo).Id
pciDevs = append(pciDevs, devId)
if pciBacking, ok := pci.Backing.(*types.VirtualPCIPassthroughDeviceBackingInfo); ok {
devId := pciBacking.Id
pciDevs = append(pciDevs, devId)
} else {
if pciBacking, ok := pci.Backing.(*types.VirtualPCIPassthroughVmiopBackingInfo); ok {
err = d.Set("shared_pci_device_id", pciBacking.Vgpu)
if err != nil {
return err
}
} else {
log.Printf("[WARN] Ignoring VM %q VirtualPCIPassthrough device with backing type of %T",
vm.InventoryPath, pci.Backing)
}
}
}
}
err = d.Set("pci_device_id", pciDevs)
Expand Down Expand Up @@ -1838,6 +1856,12 @@ func applyVirtualDevices(d *schema.ResourceData, c *govmomi.Client, l object.Vir
return nil, err
}
spec = virtualdevice.AppendDeviceChangeSpec(spec, delta...)
// Shared PCI passthrough device
l, delta, err = virtualdevice.SharedPciPassthroughApplyOperation(d, c, l)
if err != nil {
return nil, err
}
spec = virtualdevice.AppendDeviceChangeSpec(spec, delta...)
log.Printf("[DEBUG] %s: Final device list: %s", resourceVSphereVirtualMachineIDString(d), virtualdevice.DeviceListString(l))
log.Printf("[DEBUG] %s: Final device change spec: %s", resourceVSphereVirtualMachineIDString(d), virtualdevice.DeviceChangeString(spec))
return spec, nil
Expand Down
2 changes: 2 additions & 0 deletions website/docs/r/virtual_machine.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,8 @@ external disks on virtual machines that are assigned to datastore clusters.
more details.
* `pci_device_id` - (Optional) List of host PCI device IDs to create PCI
passthroughs for.
* `shared_pci_device_id` - (Optional) Shared PCI device ID to create PCI
passthroughs for.

[virtual-machine-hardware-compatibility]: https://kb.vmware.com/s/article/2007240

Expand Down

0 comments on commit 8326641

Please sign in to comment.