func delVNIC(ui packer.Ui, f *find.Finder, ctx context.Context, vm *object.VirtualMachine) error { ui.Say("Deleting NIC ") devicelst, err := vm.Device(ctx) if err != nil { return err } for _, device := range devicelst { switch device.(type) { case *types.VirtualVmxnet3: ui.Message(fmt.Sprintf("Removing NIC %s\n", device.GetVirtualDevice().DeviceInfo)) err := vm.RemoveDevice(ctx, device) if err != nil { return err } return nil case *types.VirtualE1000: ui.Message(fmt.Sprintf("Removing NIC %s\n", device.GetVirtualDevice().DeviceInfo)) err := vm.RemoveDevice(ctx, device) if err != nil { return err } return nil default: fmt.Printf("Type %s\n", reflect.TypeOf(device).Elem()) fmt.Printf("Device info %s\n", device.GetVirtualDevice().DeviceInfo) } } return nil } //
// buildVMRelocateSpec builds VirtualMachineRelocateSpec to set a place for a new VirtualMachine. func buildVMRelocateSpec(rp *object.ResourcePool, ds *object.Datastore, vm *object.VirtualMachine) (types.VirtualMachineRelocateSpec, error) { var key int devices, err := vm.Device(context.TODO()) if err != nil { return types.VirtualMachineRelocateSpec{}, err } for _, d := range devices { if devices.Type(d) == "disk" { key = d.GetVirtualDevice().Key } } rpr := rp.Reference() dsr := ds.Reference() return types.VirtualMachineRelocateSpec{ Datastore: &dsr, Pool: &rpr, Disk: []types.VirtualMachineRelocateSpecDiskLocator{ types.VirtualMachineRelocateSpecDiskLocator{ Datastore: dsr, DiskBackingInfo: &types.VirtualDiskFlatVer2BackingInfo{ DiskMode: "persistent", ThinProvisioned: types.NewBool(false), EagerlyScrub: types.NewBool(true), }, DiskId: key, }, }, }, nil }
func (vmh *VMHost) getMACAddressOfVM(vm *object.VirtualMachine) (string, error) { vmDeviceList, err := vm.Device(context.TODO()) if err != nil { return "", errors.New("Cannot read VM VirtualDevices") } return vmDeviceList.PrimaryMacAddress(), nil }
// buildVMRelocateSpec builds VirtualMachineRelocateSpec to set a place for a new VirtualMachine. func buildVMRelocateSpec(finder *find.Finder, rp *object.ResourcePool, ds *object.Datastore, vm *object.VirtualMachine, linked bool) (types.VirtualMachineRelocateSpec, error) { var key int var parent *types.VirtualDiskFlatVer2BackingInfo devices, err := vm.Device(context.TODO()) if err != nil { return types.VirtualMachineRelocateSpec{}, err } for _, d := range devices { if devices.Type(d) == "disk" { vd := d.GetVirtualDevice() parent = vd.Backing.(*types.VirtualDiskFlatVer2BackingInfo) key = vd.Key } } rpr := rp.Reference() relocateSpec := types.VirtualMachineRelocateSpec{} // Treat linked clones a bit differently. if linked { parentDs := strings.SplitN(parent.FileName[1:], "]", 2) parentDsObj, err := finder.Datastore(context.TODO(), parentDs[0]) if err != nil { return types.VirtualMachineRelocateSpec{}, err } parentDbObjRef := parentDsObj.Reference() relocateSpec = types.VirtualMachineRelocateSpec{ Datastore: &parentDbObjRef, Pool: &rpr, DiskMoveType: "createNewChildDiskBacking", } } else { dsr := ds.Reference() relocateSpec = types.VirtualMachineRelocateSpec{ Datastore: &dsr, Pool: &rpr, Disk: []types.VirtualMachineRelocateSpecDiskLocator{ types.VirtualMachineRelocateSpecDiskLocator{ Datastore: dsr, DiskId: key, DiskBackingInfo: &types.VirtualDiskFlatVer2BackingInfo{ DiskMode: "persistent", ThinProvisioned: types.NewBool(false), EagerlyScrub: types.NewBool(true), }, }, }, } } return relocateSpec, nil }
// addHardDisk adds a new Hard Disk to the VirtualMachine. func addHardDisk(vm *object.VirtualMachine, size, iops int64, diskType string, datastore *object.Datastore, diskPath string, controller_type string) error { devices, err := vm.Device(context.TODO()) if err != nil { return err } log.Printf("[DEBUG] vm devices: %#v\n", devices) controller, err := devices.FindDiskController(controller_type) if err != nil { return err } log.Printf("[DEBUG] disk controller: %#v\n", controller) // TODO Check if diskPath & datastore exist // If diskPath is not specified, pass empty string to CreateDisk() if diskPath == "" { return fmt.Errorf("[ERROR] addHardDisk - No path proided") } else { // TODO Check if diskPath & datastore exist diskPath = fmt.Sprintf("[%v] %v", datastore.Name(), diskPath) } log.Printf("[DEBUG] addHardDisk - diskPath: %v", diskPath) disk := devices.CreateDisk(controller, datastore.Reference(), diskPath) existing := devices.SelectByBackingInfo(disk.Backing) log.Printf("[DEBUG] disk: %#v\n", disk) if len(existing) == 0 { disk.CapacityInKB = int64(size * 1024 * 1024) if iops != 0 { disk.StorageIOAllocation = &types.StorageIOAllocationInfo{ Limit: iops, } } backing := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo) if diskType == "eager_zeroed" { // eager zeroed thick virtual disk backing.ThinProvisioned = types.NewBool(false) backing.EagerlyScrub = types.NewBool(true) } else if diskType == "thin" { // thin provisioned virtual disk backing.ThinProvisioned = types.NewBool(true) } log.Printf("[DEBUG] addHardDisk: %#v\n", disk) log.Printf("[DEBUG] addHardDisk capacity: %#v\n", disk.CapacityInKB) return vm.AddDevice(context.TODO(), disk) } else { log.Printf("[DEBUG] addHardDisk: Disk already present.\n") return nil } }
// buildStoragePlacementSpecClone builds StoragePlacementSpec for clone action. func buildStoragePlacementSpecClone(c *govmomi.Client, f *object.DatacenterFolders, vm *object.VirtualMachine, rp *object.ResourcePool, storagePod object.StoragePod) types.StoragePlacementSpec { vmr := vm.Reference() vmfr := f.VmFolder.Reference() rpr := rp.Reference() spr := storagePod.Reference() var o mo.VirtualMachine err := vm.Properties(context.TODO(), vmr, []string{"datastore"}, &o) if err != nil { return types.StoragePlacementSpec{} } ds := object.NewDatastore(c.Client, o.Datastore[0]) log.Printf("[DEBUG] findDatastore: datastore: %#v\n", ds) devices, err := vm.Device(context.TODO()) if err != nil { return types.StoragePlacementSpec{} } var key int for _, d := range devices.SelectByType((*types.VirtualDisk)(nil)) { key = d.GetVirtualDevice().Key log.Printf("[DEBUG] findDatastore: virtual devices: %#v\n", d.GetVirtualDevice()) } sps := types.StoragePlacementSpec{ Type: "clone", Vm: &vmr, PodSelectionSpec: types.StorageDrsPodSelectionSpec{ StoragePod: &spr, }, CloneSpec: &types.VirtualMachineCloneSpec{ Location: types.VirtualMachineRelocateSpec{ Disk: []types.VirtualMachineRelocateSpecDiskLocator{ types.VirtualMachineRelocateSpecDiskLocator{ Datastore: ds.Reference(), DiskBackingInfo: &types.VirtualDiskFlatVer2BackingInfo{}, DiskId: key, }, }, Pool: &rpr, }, PowerOn: false, Template: false, }, CloneName: "dummy", Folder: &vmfr, } return sps }
func (cmd *create) addDevices(vm *object.VirtualMachine) error { devices, err := vm.Device(context.TODO()) if err != nil { return err } var add []types.BaseVirtualDevice if cmd.disk != "" { controller, err := devices.FindDiskController(cmd.controller) if err != nil { return err } disk := devices.CreateDisk(controller, cmd.Datastore.Path(cmd.disk)) if cmd.link { disk = devices.ChildDisk(disk) } add = append(add, disk) } if cmd.iso != "" { ide, err := devices.FindIDEController("") if err != nil { return err } cdrom, err := devices.CreateCdrom(ide) if err != nil { return err } add = append(add, devices.InsertIso(cdrom, cmd.Datastore.Path(cmd.iso))) } netdev, err := cmd.NetworkFlag.Device() if err != nil { return err } add = append(add, netdev) return vm.AddDevice(context.TODO(), add...) }
// addHardDisk adds a new Hard Disk to the VirtualMachine. func addHardDisk(vm *object.VirtualMachine, size, iops int64, diskType string) error { devices, err := vm.Device(context.TODO()) if err != nil { return err } log.Printf("[DEBUG] vm devices: %#v\n", devices) controller, err := devices.FindDiskController("scsi") if err != nil { return err } log.Printf("[DEBUG] disk controller: %#v\n", controller) disk := devices.CreateDisk(controller, "") existing := devices.SelectByBackingInfo(disk.Backing) log.Printf("[DEBUG] disk: %#v\n", disk) if len(existing) == 0 { disk.CapacityInKB = int64(size * 1024 * 1024) if iops != 0 { disk.StorageIOAllocation = &types.StorageIOAllocationInfo{ Limit: iops, } } backing := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo) // if diskType == "eager_zeroed" { // // eager zeroed thick virtual disk // backing.ThinProvisioned = types.NewBool(false) // backing.EagerlyScrub = types.NewBool(true) // } else if diskType == "thin" { // // thin provisioned virtual disk // backing.ThinProvisioned = types.NewBool(true) // } backing.ThinProvisioned = types.NewBool(true) log.Printf("[DEBUG] addHardDisk: %#v\n", disk) log.Printf("[DEBUG] addHardDisk: %#v\n", disk.CapacityInKB) return vm.AddDevice(context.TODO(), disk) } else { log.Printf("[DEBUG] addHardDisk: Disk already present.\n") return nil } }
func (vmh *VMHost) DetachRDM(vm *object.VirtualMachine, deviceNAA string) error { scsiLuns, err := vmh.GetSCSILuns() if err != nil { return err } mapSDI := make(map[string]*types.ScsiLun) for _, d := range scsiLuns { mapSDI[d.Uuid] = d } devices, err := vm.Device(context.TODO()) if err != nil { return err } for _, device := range devices { device2 := device.(types.BaseVirtualDevice).GetVirtualDevice() if device2.Backing != nil { elem := reflect.ValueOf(device2.Backing).Elem() lunUuid := elem.FieldByName("LunUuid") if lunUuid.Kind() == reflect.Invalid { continue } if sd, ok := mapSDI[lunUuid.String()]; ok && strings.Contains(sd.CanonicalName, deviceNAA) { deviceName := devices.Name(device) newDevice := devices.Find(deviceName) if newDevice == nil { return fmt.Errorf("device '%s' not found", deviceName) } if err = vm.RemoveDevice(context.TODO(), newDevice); err != nil { return err } break } } } return nil }
// Find the disk by name attached to the given vm. func findDisk(ctx context.Context, vm *object.VirtualMachine, name string) (*types.VirtualDisk, error) { defer trace.End(trace.Begin(vm.String())) log.Debugf("Looking for attached disk matching filename %s", name) devices, err := vm.Device(ctx) if err != nil { return nil, fmt.Errorf("Failed to refresh devices for vm: %s", errors.ErrorStack(err)) } candidates := devices.Select(func(device types.BaseVirtualDevice) bool { db := device.GetVirtualDevice().Backing if db == nil { return false } backing, ok := device.GetVirtualDevice().Backing.(*types.VirtualDiskFlatVer2BackingInfo) if !ok { return false } log.Debugf("backing file name %s", backing.VirtualDeviceFileBackingInfo.FileName) match := strings.HasSuffix(backing.VirtualDeviceFileBackingInfo.FileName, name) if match { log.Debugf("Found candidate disk for %s at %s", name, backing.VirtualDeviceFileBackingInfo.FileName) } return match }) if len(candidates) == 0 { log.Warnf("No disks match name: %s", name) return nil, os.ErrNotExist } if len(candidates) > 1 { return nil, errors.Errorf("Too many disks match name: %s", name) } return candidates[0].(*types.VirtualDisk), nil }
// buildVMRelocateSpec builds VirtualMachineRelocateSpec to set a place for a new VirtualMachine. func buildVMRelocateSpec(rp *object.ResourcePool, ds *object.Datastore, vm *object.VirtualMachine, linkedClone bool, initType string) (types.VirtualMachineRelocateSpec, error) { var key int var moveType string if linkedClone { moveType = "createNewChildDiskBacking" } else { moveType = "moveAllDiskBackingsAndDisallowSharing" } log.Printf("[DEBUG] relocate type: [%s]", moveType) devices, err := vm.Device(context.TODO()) if err != nil { return types.VirtualMachineRelocateSpec{}, err } for _, d := range devices { if devices.Type(d) == "disk" { key = d.GetVirtualDevice().Key } } isThin := initType == "thin" rpr := rp.Reference() dsr := ds.Reference() return types.VirtualMachineRelocateSpec{ Datastore: &dsr, Pool: &rpr, DiskMoveType: moveType, Disk: []types.VirtualMachineRelocateSpecDiskLocator{ types.VirtualMachineRelocateSpecDiskLocator{ Datastore: dsr, DiskBackingInfo: &types.VirtualDiskFlatVer2BackingInfo{ DiskMode: "persistent", ThinProvisioned: types.NewBool(isThin), EagerlyScrub: types.NewBool(!isThin), }, DiskId: key, }, }, }, nil }
// addCdrom adds a new virtual cdrom drive to the VirtualMachine and attaches an image (ISO) to it from a datastore path. func addCdrom(vm *object.VirtualMachine, datastore, path string) error { devices, err := vm.Device(context.TODO()) if err != nil { return err } log.Printf("[DEBUG] vm devices: %#v", devices) controller, err := devices.FindIDEController("") if err != nil { return err } log.Printf("[DEBUG] ide controller: %#v", controller) c, err := devices.CreateCdrom(controller) if err != nil { return err } c = devices.InsertIso(c, fmt.Sprintf("[%s] %s", datastore, path)) log.Printf("[DEBUG] addCdrom: %#v", c) return vm.AddDevice(context.TODO(), c) }
// ensures that a paravirtual scsi controller is present and determines the // base path of disks attached to it returns a handle to the controller and a // format string, with a single decimal for the disk unit number which will // result in the /dev/disk/by-path path func verifyParavirtualScsiController(ctx context.Context, vm *object.VirtualMachine) (*types.ParaVirtualSCSIController, string, error) { devices, err := vm.Device(ctx) if err != nil { log.Errorf("vmware driver failed to retrieve device list for VM %s: %s", vm, errors.ErrorStack(err)) return nil, "", errors.Trace(err) } controller, ok := devices.PickController((*types.ParaVirtualSCSIController)(nil)).(*types.ParaVirtualSCSIController) if controller == nil || !ok { err = errors.Errorf("vmware driver failed to find a paravirtual SCSI controller - ensure setup ran correctly") log.Error(err.Error()) return nil, "", errors.Trace(err) } // build the base path // first we determine which label we're looking for (requires VMW hardware version >=10) targetLabel := fmt.Sprintf("SCSI%d", controller.BusNumber) log.Debugf("Looking for scsi controller with label %s", targetLabel) pciBase := "/sys/bus/pci/devices" pciBus, err := os.Open(pciBase) if err != nil { log.Errorf("Failed to open %s for reading: %s", pciBase, errors.ErrorStack(err)) return controller, "", errors.Trace(err) } defer pciBus.Close() pciDevices, err := pciBus.Readdirnames(0) if err != nil { log.Errorf("Failed to read contents of %s: %s", pciBase, errors.ErrorStack(err)) return controller, "", errors.Trace(err) } var buf = make([]byte, len(targetLabel)) var controllerName string for _, n := range pciDevices { nlabel := fmt.Sprintf("%s/%s/label", pciBase, n) flabel, err := os.Open(nlabel) if err != nil { if !os.IsNotExist(err) { log.Errorf("Unable to read label from %s: %s", nlabel, errors.ErrorStack(err)) } continue } defer flabel.Close() _, err = flabel.Read(buf) if err != nil { log.Errorf("Unable to read label from %s: %s", nlabel, errors.ErrorStack(err)) continue } if targetLabel == string(buf) { // we've found our controller controllerName = n log.Debugf("Found pvscsi controller directory: %s", controllerName) break } } if controllerName == "" { err := errors.Errorf("Failed to locate pvscsi controller directory") log.Errorf(err.Error()) return controller, "", errors.Trace(err) } formatString := fmt.Sprintf("/dev/disk/by-path/pci-%s-scsi-0:0:%%d:0", controllerName) log.Debugf("Disk location format: %s", formatString) return controller, formatString, nil }
// findDatastore finds Datastore object. func findDatastore(c *govmomi.Client, f *object.DatacenterFolders, vm *object.VirtualMachine, rp *object.ResourcePool, name string) (*object.Datastore, error) { var datastore *object.Datastore s := object.NewSearchIndex(c.Client) ref, err := s.FindChild(context.TODO(), f.DatastoreFolder, name) if err != nil { return nil, err } log.Printf("[DEBUG] findDatastore: reference: %#v", ref) mor := ref.Reference() if mor.Type == "StoragePod" { storagePod := object.NewFolder(c.Client, mor) vmr := vm.Reference() vmfr := f.VmFolder.Reference() rpr := rp.Reference() spr := storagePod.Reference() var o mo.VirtualMachine err := vm.Properties(context.TODO(), vmr, []string{"datastore"}, &o) if err != nil { return nil, err } ds := object.NewDatastore(c.Client, o.Datastore[0]) log.Printf("[DEBUG] findDatastore: datastore: %#v\n", ds) devices, err := vm.Device(context.TODO()) if err != nil { return nil, err } var key int for _, d := range devices.SelectByType((*types.VirtualDisk)(nil)) { key = d.GetVirtualDevice().Key log.Printf("[DEBUG] findDatastore: virtual devices: %#v\n", d.GetVirtualDevice()) } sps := types.StoragePlacementSpec{ Type: "clone", Vm: &vmr, PodSelectionSpec: types.StorageDrsPodSelectionSpec{ StoragePod: &spr, }, CloneSpec: &types.VirtualMachineCloneSpec{ Location: types.VirtualMachineRelocateSpec{ Disk: []types.VirtualMachineRelocateSpecDiskLocator{ types.VirtualMachineRelocateSpecDiskLocator{ Datastore: ds.Reference(), DiskBackingInfo: &types.VirtualDiskFlatVer2BackingInfo{}, DiskId: key, }, }, Pool: &rpr, }, PowerOn: false, Template: false, }, CloneName: "dummy", Folder: &vmfr, } log.Printf("[DEBUG] findDatastore: StoragePlacementSpec: %#v\n", sps) srm := object.NewStorageResourceManager(c.Client) rds, err := srm.RecommendDatastores(context.TODO(), sps) if err != nil { return nil, err } log.Printf("[DEBUG] findDatastore: recommendDatastores: %#v\n", rds) spa := rds.Recommendations[0].Action[0].(*types.StoragePlacementAction) datastore = object.NewDatastore(c.Client, spa.Destination) } else { datastore = object.NewDatastore(c.Client, mor) } log.Printf("[DEBUG] findDatastore: datastore: %#v", datastore) return datastore, nil }