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
}
Example #3
0
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
}
Example #7
0
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
	}
}
Example #9
0
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
}
Example #10
0
File: util.go Project: jak-atx/vic
// 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)
}
Example #13
0
File: util.go Project: jak-atx/vic
// 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
}