func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error { vm, err := cmd.VirtualMachine() if err != nil { return err } if vm == nil { return flag.ErrHelp } devices, err := vm.Device(context.TODO()) if err != nil { return err } d, err := devices.CreateSCSIController(cmd.controller) if err != nil { return err } c := d.(types.BaseVirtualSCSIController).GetVirtualSCSIController() c.HotAddRemove = &cmd.hotAddRemove c.SharedBus = types.VirtualSCSISharing(cmd.sharedBus) err = vm.AddDevice(context.TODO(), d) if err != nil { return err } // output name of device we just created devices, err = vm.Device(context.TODO()) if err != nil { return err } devices = devices.SelectByType(d) name := devices.Name(devices[len(devices)-1]) fmt.Println(name) return nil }
// Attaches given virtual disk volume to the compute running kubelet. func (vs *VSphere) AttachDisk(vmDiskPath string, nodeName k8stypes.NodeName) (diskID string, diskUUID string, err error) { // Create context ctx, cancel := context.WithCancel(context.Background()) defer cancel() // Create vSphere client c, err := vsphereLogin(vs.cfg, ctx) if err != nil { return "", "", err } defer c.Logout(ctx) // Find virtual machine to attach disk to var vSphereInstance string if nodeName == "" { vSphereInstance = vs.localInstanceID nodeName = vmNameToNodeName(vSphereInstance) } else { vSphereInstance = nodeNameToVMName(nodeName) } // Get VM device list vm, vmDevices, ds, dc, err := getVirtualMachineDevices(vs.cfg, ctx, c, vSphereInstance) if err != nil { return "", "", err } attached, _ := checkDiskAttached(vmDiskPath, vmDevices, dc, c) if attached { diskID, _ = getVirtualDiskID(vmDiskPath, vmDevices, dc, c) diskUUID, _ = getVirtualDiskUUIDByPath(vmDiskPath, dc, c) return diskID, diskUUID, nil } var diskControllerType = vs.cfg.Disk.SCSIControllerType // find SCSI controller of particular type from VM devices allSCSIControllers := getSCSIControllers(vmDevices) scsiControllersOfRequiredType := getSCSIControllersOfType(vmDevices, diskControllerType) scsiController := getAvailableSCSIController(scsiControllersOfRequiredType) var newSCSICreated = false var newSCSIController types.BaseVirtualDevice // creating a scsi controller as there is none found of controller type defined if scsiController == nil { if len(allSCSIControllers) >= SCSIControllerLimit { // we reached the maximum number of controllers we can attach return "", "", fmt.Errorf("SCSI Controller Limit of %d has been reached, cannot create another SCSI controller", SCSIControllerLimit) } glog.V(4).Infof("Creating a SCSI controller of %v type", diskControllerType) newSCSIController, err := vmDevices.CreateSCSIController(diskControllerType) if err != nil { runtime.HandleError(fmt.Errorf("error creating new SCSI controller: %v", err)) return "", "", err } configNewSCSIController := newSCSIController.(types.BaseVirtualSCSIController).GetVirtualSCSIController() hotAndRemove := true configNewSCSIController.HotAddRemove = &hotAndRemove configNewSCSIController.SharedBus = types.VirtualSCSISharing(types.VirtualSCSISharingNoSharing) // add the scsi controller to virtual machine err = vm.AddDevice(context.TODO(), newSCSIController) if err != nil { glog.V(3).Infof("cannot add SCSI controller to vm - %v", err) // attempt clean up of scsi controller if vmDevices, err := vm.Device(ctx); err == nil { cleanUpController(newSCSIController, vmDevices, vm, ctx) } return "", "", err } // verify scsi controller in virtual machine vmDevices, err = vm.Device(ctx) if err != nil { // cannot cleanup if there is no device list return "", "", err } scsiController = getSCSIController(vmDevices, vs.cfg.Disk.SCSIControllerType) if scsiController == nil { glog.Errorf("cannot find SCSI controller in VM") // attempt clean up of scsi controller cleanUpController(newSCSIController, vmDevices, vm, ctx) return "", "", fmt.Errorf("cannot find SCSI controller in VM") } newSCSICreated = true } disk := vmDevices.CreateDisk(scsiController, ds.Reference(), vmDiskPath) unitNumber, err := getNextUnitNumber(vmDevices, scsiController) if err != nil { glog.Errorf("cannot attach disk to VM, limit reached - %v.", err) return "", "", err } *disk.UnitNumber = unitNumber backing := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo) backing.DiskMode = string(types.VirtualDiskModeIndependent_persistent) // Attach disk to the VM err = vm.AddDevice(ctx, disk) if err != nil { glog.Errorf("cannot attach disk to the vm - %v", err) if newSCSICreated { cleanUpController(newSCSIController, vmDevices, vm, ctx) } return "", "", err } vmDevices, err = vm.Device(ctx) if err != nil { if newSCSICreated { cleanUpController(newSCSIController, vmDevices, vm, ctx) } return "", "", err } devices := vmDevices.SelectByType(disk) if len(devices) < 1 { if newSCSICreated { cleanUpController(newSCSIController, vmDevices, vm, ctx) } return "", "", ErrNoDevicesFound } // get new disk id newDevice := devices[len(devices)-1] deviceName := devices.Name(newDevice) // get device uuid diskUUID, err = getVirtualDiskUUID(newDevice) if err != nil { if newSCSICreated { cleanUpController(newSCSIController, vmDevices, vm, ctx) } vs.DetachDisk(deviceName, nodeName) return "", "", err } return deviceName, diskUUID, nil }
// Attaches given virtual disk volume to the compute running kubelet. func (vs *VSphere) AttachDisk(vmDiskPath string, nodeName string) (diskID string, diskUUID string, err error) { // Create context ctx, cancel := context.WithCancel(context.Background()) defer cancel() // Create vSphere client c, err := vsphereLogin(vs.cfg, ctx) if err != nil { return "", "", err } defer c.Logout(ctx) // Find virtual machine to attach disk to var vSphereInstance string if nodeName == "" { vSphereInstance = vs.localInstanceID } else { vSphereInstance = nodeName } // Get VM device list vm, vmDevices, ds, err := getVirtualMachineDevices(vs.cfg, ctx, c, vSphereInstance) if err != nil { return "", "", err } var diskControllerType = vs.cfg.Disk.SCSIControllerType // find SCSI controller of particular type from VM devices var diskController = getSCSIController(vmDevices, diskControllerType) var newSCSICreated = false var newSCSIController types.BaseVirtualDevice // creating a scsi controller as there is none found of controller type defined if diskController == nil { glog.V(4).Infof("Creating a SCSI controller of %v type", diskControllerType) newSCSIController, err := vmDevices.CreateSCSIController(diskControllerType) if err != nil { runtime.HandleError(fmt.Errorf("error creating new SCSI controller: %v", err)) return "", "", err } configNewSCSIController := newSCSIController.(types.BaseVirtualSCSIController).GetVirtualSCSIController() hotAndRemove := true configNewSCSIController.HotAddRemove = &hotAndRemove configNewSCSIController.SharedBus = types.VirtualSCSISharing(types.VirtualSCSISharingNoSharing) // add the scsi controller to virtual machine err = vm.AddDevice(context.TODO(), newSCSIController) if err != nil { glog.V(3).Infof("cannot add SCSI controller to vm - %v", err) // attempt clean up of scsi controller if vmDevices, err := vm.Device(ctx); err == nil { cleanUpController(newSCSIController, vmDevices, vm, ctx) } return "", "", err } // verify scsi controller in virtual machine vmDevices, err = vm.Device(ctx) if err != nil { //cannot cleanup if there is no device list return "", "", err } diskController = getSCSIController(vmDevices, vs.cfg.Disk.SCSIControllerType) if diskController == nil { glog.Errorf("cannot find SCSI controller in VM - %v", err) // attempt clean up of scsi controller cleanUpController(newSCSIController, vmDevices, vm, ctx) return "", "", err } newSCSICreated = true } disk := vmDevices.CreateDisk(diskController, ds.Reference(), vmDiskPath) backing := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo) backing.DiskMode = string(types.VirtualDiskModeIndependent_persistent) // Attach disk to the VM err = vm.AddDevice(ctx, disk) if err != nil { glog.Errorf("cannot attach disk to the vm - %v", err) if newSCSICreated { cleanUpController(newSCSIController, vmDevices, vm, ctx) } return "", "", err } vmDevices, err = vm.Device(ctx) if err != nil { if newSCSICreated { cleanUpController(newSCSIController, vmDevices, vm, ctx) } return "", "", err } devices := vmDevices.SelectByType(disk) if len(devices) < 1 { if newSCSICreated { cleanUpController(newSCSIController, vmDevices, vm, ctx) } return "", "", ErrNoDevicesFound } // get new disk id newDevice := devices[len(devices)-1] deviceName := devices.Name(newDevice) // get device uuid diskUUID, err = getVirtualDiskUUID(newDevice) if err != nil { if newSCSICreated { cleanUpController(newSCSIController, vmDevices, vm, ctx) } vs.DetachDisk(deviceName, vSphereInstance) return "", "", err } return deviceName, diskUUID, nil }