github.com/vmware/govmomi@v0.51.0/cli/device/pci/add.go (about)

     1  // © Broadcom. All Rights Reserved.
     2  // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
     3  // SPDX-License-Identifier: Apache-2.0
     4  
     5  package pci
     6  
     7  import (
     8  	"context"
     9  	"errors"
    10  	"flag"
    11  	"fmt"
    12  
    13  	"github.com/vmware/govmomi/cli"
    14  	"github.com/vmware/govmomi/cli/flags"
    15  	"github.com/vmware/govmomi/vim25/types"
    16  )
    17  
    18  type add struct {
    19  	*flags.VirtualMachineFlag
    20  }
    21  
    22  func init() {
    23  	cli.Register("device.pci.add", &add{})
    24  }
    25  
    26  func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
    27  	cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
    28  	cmd.VirtualMachineFlag.Register(ctx, f)
    29  }
    30  
    31  func (cmd *add) Description() string {
    32  	return `Add PCI Passthrough device to VM.
    33  
    34  Examples:
    35    govc device.pci.ls -vm $vm
    36    govc device.pci.add -vm $vm $pci_address
    37    govc device.info -vm $vm
    38  
    39  Assuming vm name is helloworld, list command has below output
    40  
    41  $ govc device.pci.ls -vm helloworld
    42  System ID                             Address       Vendor Name Device Name
    43  5b087ce4-ce46-72c0-c7c2-28ac9e22c3c2  0000:60:00.0  Pensando    Ethernet Controller 1
    44  5b087ce4-ce46-72c0-c7c2-28ac9e22c3c2  0000:61:00.0  Pensando    Ethernet Controller 2
    45  
    46  To add only 'Ethernet Controller 1', command should be as below. No output upon success.
    47  
    48  $ govc device.pci.add -vm helloworld 0000:60:00.0
    49  
    50  To add both 'Ethernet Controller 1' and 'Ethernet Controller 2', command should be as below.
    51  No output upon success.
    52  
    53  $ govc device.pci.add -vm helloworld 0000:60:00.0 0000:61:00.0
    54  
    55  $ govc device.info -vm helloworld
    56  ...
    57  Name:               pcipassthrough-13000
    58    Type:             VirtualPCIPassthrough
    59    Label:            PCI device 0
    60    Summary:
    61    Key:              13000
    62    Controller:       pci-100
    63    Unit number:      18
    64  Name:               pcipassthrough-13001
    65    Type:             VirtualPCIPassthrough
    66    Label:            PCI device 1
    67    Summary:
    68    Key:              13001
    69    Controller:       pci-100
    70    Unit number:      19`
    71  }
    72  
    73  func (cmd *add) Usage() string {
    74  	return "PCI_ADDRESS..."
    75  }
    76  
    77  func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
    78  	if len(f.Args()) == 0 {
    79  		return flag.ErrHelp
    80  	}
    81  
    82  	reqDevices := map[string]*types.VirtualMachinePciPassthroughInfo{}
    83  	for _, n := range f.Args() {
    84  		reqDevices[n] = nil
    85  	}
    86  
    87  	vm, err := cmd.VirtualMachine()
    88  	if err != nil {
    89  		return err
    90  	}
    91  	if vm == nil {
    92  		return flag.ErrHelp
    93  	}
    94  
    95  	vmConfigOptions, err := queryConfigTarget(ctx, vm)
    96  	if err != nil {
    97  		return err
    98  	}
    99  
   100  	for _, d := range vmConfigOptions.PciPassthrough {
   101  		info := d.GetVirtualMachinePciPassthroughInfo()
   102  		if info == nil {
   103  			return errors.New("received invalid pci passthrough info")
   104  		}
   105  
   106  		_, ok := reqDevices[info.PciDevice.Id]
   107  		if !ok {
   108  			continue
   109  		}
   110  		reqDevices[info.PciDevice.Id] = info
   111  	}
   112  
   113  	newDevices := []types.BaseVirtualDevice{}
   114  	for id, d := range reqDevices {
   115  		if d == nil {
   116  			return fmt.Errorf("%s is not found in allowed PCI passthrough device list", id)
   117  		}
   118  		device := &types.VirtualPCIPassthrough{}
   119  		device.Backing = &types.VirtualPCIPassthroughDeviceBackingInfo{
   120  			Id: d.PciDevice.Id, DeviceId: fmt.Sprintf("%x", d.PciDevice.DeviceId),
   121  			SystemId: d.SystemId, VendorId: d.PciDevice.VendorId,
   122  		}
   123  		device.Connectable = &types.VirtualDeviceConnectInfo{StartConnected: true, Connected: true}
   124  		newDevices = append(newDevices, device)
   125  	}
   126  
   127  	return vm.AddDevice(ctx, newDevices...)
   128  }