-
Notifications
You must be signed in to change notification settings - Fork 1.3k
vmware: Add force parameter to iso attach/detach operations #4907
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c88c3d6
5180d19
8ce9d62
4c227a3
b5a2482
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -54,6 +54,10 @@ public class AttachIsoCmd extends BaseAsyncCmd implements UserCmd { | |
| required = true, description = "the ID of the virtual machine") | ||
| protected Long virtualMachineId; | ||
|
|
||
| @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, | ||
| description = "If true, ejects existing ISO before attaching on VMware. Default: false", since = "4.15.1") | ||
| protected Boolean forced; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO this is not needed. In case there an existing ISO it can be ejected by detachIso setting forced = true
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's true @nvazquez. However, this has been done in cases where we have a configdrive iso- under such cases, we can't do a detach operation.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for clarifying @Pearl1594 |
||
|
|
||
| ///////////////////////////////////////////////////// | ||
| /////////////////// Accessors /////////////////////// | ||
| ///////////////////////////////////////////////////// | ||
|
|
@@ -66,6 +70,10 @@ public Long getVirtualMachineId() { | |
| return virtualMachineId; | ||
| } | ||
|
|
||
| public Boolean isForced() { | ||
| return forced != null; | ||
| } | ||
|
|
||
| ///////////////////////////////////////////////////// | ||
| /////////////// API Implementation/////////////////// | ||
| ///////////////////////////////////////////////////// | ||
|
|
@@ -98,7 +106,7 @@ public String getEventDescription() { | |
| @Override | ||
| public void execute() { | ||
| CallContext.current().setEventDetails("Vm Id: " + getVirtualMachineId() + " ISO ID: " + getId()); | ||
| boolean result = _templateService.attachIso(id, virtualMachineId); | ||
| boolean result = _templateService.attachIso(id, virtualMachineId, isForced()); | ||
| if (result) { | ||
| UserVm userVm = _responseGenerator.findUserVmById(virtualMachineId); | ||
| if (userVm != null) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2019,35 +2019,7 @@ protected StartAnswer execute(StartCommand cmd) { | |
| if (volIso != null) { | ||
| for (DiskTO vol : disks) { | ||
| if (vol.getType() == Volume.Type.ISO) { | ||
|
|
||
| TemplateObjectTO iso = (TemplateObjectTO) vol.getData(); | ||
|
|
||
| if (iso.getPath() != null && !iso.getPath().isEmpty()) { | ||
| DataStoreTO imageStore = iso.getDataStore(); | ||
| if (!(imageStore instanceof NfsTO)) { | ||
| s_logger.debug("unsupported protocol"); | ||
| throw new Exception("unsupported protocol"); | ||
| } | ||
| NfsTO nfsImageStore = (NfsTO) imageStore; | ||
| String isoPath = nfsImageStore.getUrl() + File.separator + iso.getPath(); | ||
| Pair<String, ManagedObjectReference> isoDatastoreInfo = getIsoDatastoreInfo(hyperHost, isoPath); | ||
| assert (isoDatastoreInfo != null); | ||
| assert (isoDatastoreInfo.second() != null); | ||
|
|
||
| deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec(); | ||
| Pair<VirtualDevice, Boolean> isoInfo = | ||
| VmwareHelper.prepareIsoDevice(vmMo, isoDatastoreInfo.first(), isoDatastoreInfo.second(), true, true, ideUnitNumber++, i + 1); | ||
| deviceConfigSpecArray[i].setDevice(isoInfo.first()); | ||
| if (isoInfo.second()) { | ||
| if (s_logger.isDebugEnabled()) | ||
| s_logger.debug("Prepare ISO volume at new device " + _gson.toJson(isoInfo.first())); | ||
| deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD); | ||
| } else { | ||
| if (s_logger.isDebugEnabled()) | ||
| s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first())); | ||
| deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.EDIT); | ||
| } | ||
| } | ||
| configureIso(hyperHost, vmMo, vol, deviceConfigSpecArray, ideUnitNumber++, i); | ||
| i++; | ||
| } | ||
| } | ||
|
|
@@ -2075,8 +2047,16 @@ protected StartAnswer execute(StartCommand cmd) { | |
| // | ||
| // Setup ROOT/DATA disk devices | ||
| // | ||
| if (multipleIsosAtached(sortedDisks) && deployAsIs) { | ||
| sortedDisks = getDisks(sortedDisks); | ||
| } | ||
|
|
||
| for (DiskTO vol : sortedDisks) { | ||
| if (vol.getType() == Volume.Type.ISO) { | ||
| if (deployAsIs) { | ||
| configureIso(hyperHost, vmMo, vol, deviceConfigSpecArray, ideUnitNumber++, i); | ||
| i++; | ||
| } | ||
| continue; | ||
| } | ||
|
|
||
|
|
@@ -2457,6 +2437,46 @@ protected StartAnswer execute(StartCommand cmd) { | |
| } | ||
| } | ||
|
|
||
| private boolean multipleIsosAtached(DiskTO[] sortedDisks) { | ||
| return Arrays.stream(sortedDisks).filter(disk -> disk.getType() == Volume.Type.ISO).count() > 1; | ||
| } | ||
|
|
||
| private DiskTO[] getDisks(DiskTO[] sortedDisks) { | ||
| return Arrays.stream(sortedDisks).filter(vol -> ((vol.getPath() != null && | ||
| vol.getPath().contains("configdrive"))) || (vol.getType() != Volume.Type.ISO)).toArray(DiskTO[]::new); | ||
| } | ||
| private void configureIso(VmwareHypervisorHost hyperHost, VirtualMachineMO vmMo, DiskTO vol, | ||
| VirtualDeviceConfigSpec[] deviceConfigSpecArray, int ideUnitNumber, int i) throws Exception { | ||
| TemplateObjectTO iso = (TemplateObjectTO) vol.getData(); | ||
|
|
||
| if (iso.getPath() != null && !iso.getPath().isEmpty()) { | ||
| DataStoreTO imageStore = iso.getDataStore(); | ||
| if (!(imageStore instanceof NfsTO)) { | ||
| s_logger.debug("unsupported protocol"); | ||
| throw new Exception("unsupported protocol"); | ||
| } | ||
| NfsTO nfsImageStore = (NfsTO) imageStore; | ||
| String isoPath = nfsImageStore.getUrl() + File.separator + iso.getPath(); | ||
| Pair<String, ManagedObjectReference> isoDatastoreInfo = getIsoDatastoreInfo(hyperHost, isoPath); | ||
| assert (isoDatastoreInfo != null); | ||
| assert (isoDatastoreInfo.second() != null); | ||
|
|
||
| deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec(); | ||
| Pair<VirtualDevice, Boolean> isoInfo = | ||
| VmwareHelper.prepareIsoDevice(vmMo, isoDatastoreInfo.first(), isoDatastoreInfo.second(), true, true, ideUnitNumber, i + 1); | ||
| deviceConfigSpecArray[i].setDevice(isoInfo.first()); | ||
| if (isoInfo.second()) { | ||
| if (s_logger.isDebugEnabled()) | ||
| s_logger.debug("Prepare ISO volume at new device " + _gson.toJson(isoInfo.first())); | ||
| deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD); | ||
| } else { | ||
| if (s_logger.isDebugEnabled()) | ||
| s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first())); | ||
| deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.EDIT); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private String mapAdapterType(String adapterStringFromOVF) { | ||
| if (StringUtils.isBlank(adapterStringFromOVF) || adapterStringFromOVF.equalsIgnoreCase(VirtualEthernetCardType.E1000.toString())) { | ||
| return VirtualEthernetCardType.E1000.toString(); | ||
|
|
@@ -5382,7 +5402,7 @@ protected AttachIsoAnswer execute(AttachIsoCommand cmd) { | |
| "Failed to unmount vmware-tools installer ISO as the corresponding CDROM device is locked by VM. Please unmount the CDROM device inside the VM and ret-try."); | ||
| } | ||
| } catch (Throwable e) { | ||
| vmMo.detachIso(null); | ||
| vmMo.detachIso(null, cmd.isForce()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cmd.isForced() here
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @sureshanaparti isForce() is a function of AttachIsoCommand(not AttachCommand), that already existed, and I'm just calling that. |
||
| } | ||
| } | ||
|
|
||
|
|
@@ -5411,7 +5431,7 @@ protected AttachIsoAnswer execute(AttachIsoCommand cmd) { | |
| String isoDatastorePath = String.format("[%s] %s%s", storeName, isoStorePathFromRoot, isoFileName); | ||
|
|
||
| if (cmd.isAttach()) { | ||
| vmMo.attachIso(isoDatastorePath, morSecondaryDs, true, false, cmd.getDeviceKey()); | ||
| vmMo.attachIso(isoDatastorePath, morSecondaryDs, true, false, cmd.getDeviceKey(), cmd.isForce()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cmd.isForced() here
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @sureshanaparti isForce() is a function of AttachIsoCommand(not AttachCommand), that already existed, and I'm just calling that.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK @Pearl1594 |
||
| return new AttachIsoAnswer(cmd); | ||
| } else { | ||
| int key = vmMo.detachIso(isoDatastorePath, cmd.isForce()); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1150,7 +1150,7 @@ public boolean templateIsDeleteable(long templateId) { | |
|
|
||
| @Override | ||
| @ActionEvent(eventType = EventTypes.EVENT_ISO_DETACH, eventDescription = "detaching ISO", async = true) | ||
| public boolean detachIso(long vmId) { | ||
| public boolean detachIso(long vmId, boolean forced) { | ||
| Account caller = CallContext.current().getCallingAccount(); | ||
| Long userId = CallContext.current().getCallingUserId(); | ||
|
|
||
|
|
@@ -1178,7 +1178,7 @@ public boolean detachIso(long vmId) { | |
| throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running."); | ||
| } | ||
|
|
||
| boolean result = attachISOToVM(vmId, userId, isoId, false); // attach=false | ||
| boolean result = attachISOToVM(vmId, userId, isoId, false, forced); // attach=false | ||
| // => detach | ||
| if (result) { | ||
| return result; | ||
|
|
@@ -1189,7 +1189,7 @@ public boolean detachIso(long vmId) { | |
|
|
||
| @Override | ||
| @ActionEvent(eventType = EventTypes.EVENT_ISO_ATTACH, eventDescription = "attaching ISO", async = true) | ||
| public boolean attachIso(long isoId, long vmId) { | ||
| public boolean attachIso(long isoId, long vmId, boolean forced) { | ||
| Account caller = CallContext.current().getCallingAccount(); | ||
| Long userId = CallContext.current().getCallingUserId(); | ||
|
|
||
|
|
@@ -1231,7 +1231,7 @@ public boolean attachIso(long isoId, long vmId) { | |
| if ("vmware-tools.iso".equals(iso.getName()) && vm.getHypervisorType() != Hypervisor.HypervisorType.VMware) { | ||
| throw new InvalidParameterValueException("Cannot attach VMware tools drivers to incompatible hypervisor " + vm.getHypervisorType()); | ||
| } | ||
| boolean result = attachISOToVM(vmId, userId, isoId, true); | ||
| boolean result = attachISOToVM(vmId, userId, isoId, true, forced); | ||
| if (result) { | ||
| return result; | ||
| } else { | ||
|
|
@@ -1270,7 +1270,7 @@ public TemplateInfo prepareIso(long isoId, long dcId, Long hostId, Long poolId) | |
| } | ||
| } | ||
|
|
||
| private boolean attachISOToVM(long vmId, long isoId, boolean attach) { | ||
| private boolean attachISOToVM(long vmId, long isoId, boolean attach, boolean forced) { | ||
| UserVmVO vm = _userVmDao.findById(vmId); | ||
|
|
||
| if (vm == null) { | ||
|
|
@@ -1302,19 +1302,21 @@ private boolean attachISOToVM(long vmId, long isoId, boolean attach) { | |
|
|
||
| Command cmd = null; | ||
| if (attach) { | ||
| cmd = new AttachCommand(disk, vmName, vmTO.getDetails()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi all,
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @slavkap I think this got reverted while rebasing the code. Thanks for pointing it out. This would need to be fixed.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, @Pearl1594, for the answer! I could push a fix for this, but it has to be on 4.15.2 (when it's open) or on 4.16? |
||
| cmd = new AttachCommand(disk, vmName); | ||
| ((AttachCommand)cmd).setForced(forced); | ||
| } else { | ||
| cmd = new DettachCommand(disk, vmName, vmTO.getDetails()); | ||
| cmd = new DettachCommand(disk, vmName); | ||
| ((DettachCommand)cmd).setForced(forced); | ||
| } | ||
| Answer a = _agentMgr.easySend(vm.getHostId(), cmd); | ||
| return (a != null && a.getResult()); | ||
| } | ||
|
|
||
| private boolean attachISOToVM(long vmId, long userId, long isoId, boolean attach) { | ||
| private boolean attachISOToVM(long vmId, long userId, long isoId, boolean attach, boolean forced) { | ||
| UserVmVO vm = _userVmDao.findById(vmId); | ||
| VMTemplateVO iso = _tmpltDao.findById(isoId); | ||
|
|
||
| boolean success = attachISOToVM(vmId, isoId, attach); | ||
| boolean success = attachISOToVM(vmId, isoId, attach, forced); | ||
| if (success && attach) { | ||
| vm.setIsoId(iso.getId()); | ||
| _userVmDao.update(vmId, vm); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.