CLOUDSTACK-6134:

If volume already exists for the vm - register the vm in the inventory and start it.
This commit is contained in:
Nitin Mehta 2014-02-18 18:24:33 -08:00
parent 24309f6001
commit c969aa2595
2 changed files with 112 additions and 15 deletions

View File

@ -247,6 +247,7 @@ import com.cloud.hypervisor.vmware.mo.HostMO;
import com.cloud.hypervisor.vmware.mo.HostStorageSystemMO; import com.cloud.hypervisor.vmware.mo.HostStorageSystemMO;
import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper; import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper;
import com.cloud.hypervisor.vmware.mo.NetworkDetails; 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.VirtualEthernetCardType;
import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfo; import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfo;
import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfoBuilder; import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfoBuilder;
@ -538,6 +539,33 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
return answer; 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) { private Answer execute(ResizeVolumeCommand cmd) {
String path = cmd.getPath(); String path = cmd.getPath();
String vmName = cmd.getInstanceName(); String vmName = cmd.getInstanceName();
@ -1450,12 +1478,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
assert (vmSpec.getMinSpeed() != null) && (rootDiskDataStoreDetails != null); assert (vmSpec.getMinSpeed() != null) && (rootDiskDataStoreDetails != null);
if (rootDiskDataStoreDetails.second().folderExists(String.format("[%s]", rootDiskDataStoreDetails.second().getName()), vmNameOnVcenter)) { 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"); registerVm(vmNameOnVcenter, dsRootVolumeIsOn);
rootDiskDataStoreDetails.second().deleteFile(String.format("[%s] %s/", rootDiskDataStoreDetails.second().getName(), vmNameOnVcenter), vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
dcMo.getMor(), false); tearDownVm(vmMo);
} }else if (!hyperHost.createBlankVm(vmNameOnVcenter, vmInternalCSName, vmSpec.getCpus(), vmSpec.getMaxSpeed().intValue(),
if (!hyperHost.createBlankVm(vmNameOnVcenter, vmInternalCSName, vmSpec.getCpus(), vmSpec.getMaxSpeed().intValue(),
getReservedCpuMHZ(vmSpec), vmSpec.getLimitCpuUse(), (int)(vmSpec.getMaxRam() / (1024 * 1024)), getReservedMemoryMb(vmSpec), getReservedCpuMHZ(vmSpec), vmSpec.getLimitCpuUse(), (int)(vmSpec.getMaxRam() / (1024 * 1024)), getReservedMemoryMb(vmSpec),
translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs()).value(), rootDiskDataStoreDetails.first(), false)) { translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs()).value(), rootDiskDataStoreDetails.first(), false)) {
throw new Exception("Failed to create VM. vmName: " + vmInternalCSName); 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 @Override
public ManagedObjectReference prepareManagedStorage(VmwareHypervisorHost hyperHost, String iScsiName, public ManagedObjectReference prepareManagedStorage(VmwareHypervisorHost hyperHost, String iScsiName,
String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret, String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret,

View File

@ -190,17 +190,75 @@ public class VirtualMachineMO extends BaseMO {
} }
public boolean powerOn() throws Exception { public boolean powerOn() throws Exception {
if (getResetSafePowerState() == VirtualMachinePowerState.POWERED_ON) if(getResetSafePowerState() == VirtualMachinePowerState.POWERED_ON)
return true; 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); while (!flags[0]) {
if (result) { try {
_context.waitForTaskProgressDone(morTask); VirtualMachineRuntimeInfo runtimeInfo = vmMo.getRuntimeInfo();
return true; VirtualMachineQuestionInfo question = runtimeInfo.getQuestion();
} else { if (question != null) {
s_logger.error("VMware powerOnVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask)); 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; return false;