CLOUDSTACK-6134: If volume already exists for the vm - register the vm in the inventory and start it.
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/c969aa25 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/c969aa25 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/c969aa25 Branch: refs/heads/ui-restyle Commit: c969aa25956a823acac2b5829c4db1528edd8965 Parents: 24309f6 Author: Nitin Mehta <nitin.me...@citrix.com> Authored: Tue Feb 18 18:24:33 2014 -0800 Committer: Nitin Mehta <nitin.me...@citrix.com> Committed: Tue Feb 18 18:24:33 2014 -0800 ---------------------------------------------------------------------- .../vmware/resource/VmwareResource.java | 51 +++++++++++-- .../hypervisor/vmware/mo/VirtualMachineMO.java | 76 +++++++++++++++++--- 2 files changed, 112 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c969aa25/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 182fe9f..c74a278 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -247,6 +247,7 @@ import com.cloud.hypervisor.vmware.mo.HostMO; import com.cloud.hypervisor.vmware.mo.HostStorageSystemMO; import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper; import com.cloud.hypervisor.vmware.mo.NetworkDetails; +import com.cloud.hypervisor.vmware.mo.TaskMO; import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType; import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfo; import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfoBuilder; @@ -538,6 +539,33 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return answer; } + /** + * Registers the vm to the inventory given the vmx file. + */ + private void registerVm(String vmName, DatastoreMO dsMo) throws Exception{ + + //1st param + VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext()); + ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter(); + DatacenterMO dataCenterMo = new DatacenterMO(getServiceContext(), dcMor); + ManagedObjectReference vmFolderMor = dataCenterMo.getVmFolder(); + + //2nd param + String vmxFilePath = dsMo.searchFileInSubFolders(vmName + ".vmx", false); + + // 5th param + ManagedObjectReference morPool = hyperHost.getHyperHostOwnerResourcePool(); + + ManagedObjectReference morTask = getServiceContext().getService().registerVMTask(vmFolderMor, vmxFilePath, vmName, false, morPool, hyperHost.getMor()); + boolean result = getServiceContext().getVimClient().waitForTask(morTask); + if (!result) { + throw new Exception("Unable to register vm due to " + TaskMO.getTaskFailureInfo(getServiceContext(), morTask)); + } else { + getServiceContext().waitForTaskProgressDone(morTask); + } + + } + private Answer execute(ResizeVolumeCommand cmd) { String path = cmd.getPath(); String vmName = cmd.getInstanceName(); @@ -1450,12 +1478,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa assert (vmSpec.getMinSpeed() != null) && (rootDiskDataStoreDetails != null); if (rootDiskDataStoreDetails.second().folderExists(String.format("[%s]", rootDiskDataStoreDetails.second().getName()), vmNameOnVcenter)) { - s_logger.warn("WARN!!! Folder already exists on datastore for new VM " + vmNameOnVcenter + ", erase it"); - rootDiskDataStoreDetails.second().deleteFile(String.format("[%s] %s/", rootDiskDataStoreDetails.second().getName(), vmNameOnVcenter), - dcMo.getMor(), false); - } - - if (!hyperHost.createBlankVm(vmNameOnVcenter, vmInternalCSName, vmSpec.getCpus(), vmSpec.getMaxSpeed().intValue(), + registerVm(vmNameOnVcenter, dsRootVolumeIsOn); + vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName); + tearDownVm(vmMo); + }else if (!hyperHost.createBlankVm(vmNameOnVcenter, vmInternalCSName, vmSpec.getCpus(), vmSpec.getMaxSpeed().intValue(), getReservedCpuMHZ(vmSpec), vmSpec.getLimitCpuUse(), (int)(vmSpec.getMaxRam() / (1024 * 1024)), getReservedMemoryMb(vmSpec), translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs()).value(), rootDiskDataStoreDetails.first(), false)) { throw new Exception("Failed to create VM. vmName: " + vmInternalCSName); @@ -1767,6 +1793,19 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } + private void tearDownVm(VirtualMachineMO vmMo) throws Exception{ + + if(vmMo == null) return; + + boolean hasSnapshot = false; + hasSnapshot = vmMo.hasSnapshot(); + if (!hasSnapshot) + vmMo.tearDownDevices(new Class<?>[] {VirtualDisk.class, VirtualEthernetCard.class}); + else + vmMo.tearDownDevices(new Class<?>[] {VirtualEthernetCard.class}); + vmMo.ensureScsiDeviceController(); + } + @Override public ManagedObjectReference prepareManagedStorage(VmwareHypervisorHost hyperHost, String iScsiName, String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret, http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c969aa25/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java ---------------------------------------------------------------------- diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java index 99a7425..7fc8836 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java @@ -190,17 +190,75 @@ public class VirtualMachineMO extends BaseMO { } public boolean powerOn() throws Exception { - if (getResetSafePowerState() == VirtualMachinePowerState.POWERED_ON) - return true; + if(getResetSafePowerState() == VirtualMachinePowerState.POWERED_ON) + return true; - ManagedObjectReference morTask = _context.getService().powerOnVMTask(_mor, null); + ManagedObjectReference morTask = _context.getService().powerOnVMTask(_mor, null); + // Monitor VM questions + final Boolean[] flags = {false}; + final VirtualMachineMO vmMo = this; + Future<?> future = MonitorServiceExecutor.submit(new Runnable() { + @Override + public void run() { + s_logger.info("VM Question monitor started..."); - boolean result = _context.getVimClient().waitForTask(morTask); - if (result) { - _context.waitForTaskProgressDone(morTask); - return true; - } else { - s_logger.error("VMware powerOnVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask)); + while (!flags[0]) { + try { + VirtualMachineRuntimeInfo runtimeInfo = vmMo.getRuntimeInfo(); + VirtualMachineQuestionInfo question = runtimeInfo.getQuestion(); + if (question != null) { + s_logger.info("Question id: " + question.getId()); + s_logger.info("Question text: " + question.getText()); + if (question.getMessage() != null) { + for (VirtualMachineMessage msg : question.getMessage()) { + if (s_logger.isInfoEnabled()) { + s_logger.info("msg id: " + msg.getId()); + s_logger.info("msg text: " + msg.getText()); + } + if ("msg.uuid.altered".equalsIgnoreCase(msg.getId())) { + s_logger.info("Found that VM has a pending question that we need to answer programmatically, question id: " + msg.getId() + + ", we will automatically answer as 'moved it' to address out of band HA for the VM"); + vmMo.answerVM(question.getId(), "1"); + break; + } + } + } + + if (s_logger.isTraceEnabled()) + s_logger.trace("These are the choices we can have just in case"); + ChoiceOption choice = question.getChoice(); + if (choice != null) { + for (ElementDescription info : choice.getChoiceInfo()) { + if (s_logger.isTraceEnabled()) { + s_logger.trace("Choice option key: " + info.getKey()); + s_logger.trace("Choice option label: " + info.getLabel()); + } + } + } + } + } catch (Throwable e) { + s_logger.error("Unexpected exception: ", e); + } + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + } + s_logger.info("VM Question monitor stopped"); + } + }); + + try { + boolean result = _context.getVimClient().waitForTask(morTask); + if (result) { + _context.waitForTaskProgressDone(morTask); + return true; + } else { + s_logger.error("VMware powerOnVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask)); + } + } finally { + // make sure to let VM question monitor exit + flags[0] = true; } return false;