mirror of https://github.com/apache/cloudstack.git
VMware 80u2 and 80u3 updates/fixes (#10586)
* VMware - Ignore disk not found error on cleanup when the VM disk doesn't exists * VMware - Retry powerOn on lock issues * addressed comments * Update CPVM reboot tests - wait for the agent to Disconnect and back Up * Retry moveDatastoreFile when any file access issue while creating volume from snapshot * Update full clone flag when restoring vm using root disk offering with more size than the template size * refactored (mainly,for diskInfo - causing NPE in some cases) * Retry moveDatastoreFile when there is any file access issue
This commit is contained in:
parent
8f8c685d17
commit
90316b2e90
|
|
@ -2042,7 +2042,6 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||||
VirtualMachineDefinedProfileSpec diskProfileSpec = null;
|
VirtualMachineDefinedProfileSpec diskProfileSpec = null;
|
||||||
VirtualMachineDefinedProfileSpec vmProfileSpec = null;
|
VirtualMachineDefinedProfileSpec vmProfileSpec = null;
|
||||||
|
|
||||||
|
|
||||||
DeployAsIsInfoTO deployAsIsInfo = vmSpec.getDeployAsIsInfo();
|
DeployAsIsInfoTO deployAsIsInfo = vmSpec.getDeployAsIsInfo();
|
||||||
boolean deployAsIs = deployAsIsInfo != null;
|
boolean deployAsIs = deployAsIsInfo != null;
|
||||||
|
|
||||||
|
|
@ -2086,7 +2085,6 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualMachineDiskInfoBuilder diskInfoBuilder = null;
|
VirtualMachineDiskInfoBuilder diskInfoBuilder = null;
|
||||||
VirtualDevice[] nicDevices = null;
|
|
||||||
VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
|
VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
|
||||||
DiskControllerType systemVmScsiControllerType = DiskControllerType.lsilogic;
|
DiskControllerType systemVmScsiControllerType = DiskControllerType.lsilogic;
|
||||||
int firstScsiControllerBusNum = 0;
|
int firstScsiControllerBusNum = 0;
|
||||||
|
|
@ -2103,7 +2101,6 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||||
diskDatastores = vmMo.getAllDiskDatastores();
|
diskDatastores = vmMo.getAllDiskDatastores();
|
||||||
diskInfoBuilder = vmMo.getDiskInfoBuilder();
|
diskInfoBuilder = vmMo.getDiskInfoBuilder();
|
||||||
hasSnapshot = vmMo.hasSnapshot();
|
hasSnapshot = vmMo.hasSnapshot();
|
||||||
nicDevices = vmMo.getNicDevices();
|
|
||||||
|
|
||||||
tearDownVmDevices(vmMo, hasSnapshot, deployAsIs);
|
tearDownVmDevices(vmMo, hasSnapshot, deployAsIs);
|
||||||
ensureDiskControllersInternal(vmMo, systemVm, controllerInfo, systemVmScsiControllerType,
|
ensureDiskControllersInternal(vmMo, systemVm, controllerInfo, systemVmScsiControllerType,
|
||||||
|
|
@ -2119,17 +2116,20 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||||
}
|
}
|
||||||
|
|
||||||
takeVmFromOtherHyperHost(hyperHost, vmInternalCSName);
|
takeVmFromOtherHyperHost(hyperHost, vmInternalCSName);
|
||||||
|
vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
|
||||||
|
|
||||||
if (getVmPowerState(vmMo) != PowerState.PowerOff)
|
if (vmMo != null) {
|
||||||
vmMo.safePowerOff(_shutdownWaitMs);
|
if (getVmPowerState(vmMo) != PowerState.PowerOff)
|
||||||
|
vmMo.safePowerOff(_shutdownWaitMs);
|
||||||
|
|
||||||
diskInfoBuilder = vmMo.getDiskInfoBuilder();
|
diskInfoBuilder = vmMo.getDiskInfoBuilder();
|
||||||
hasSnapshot = vmMo.hasSnapshot();
|
hasSnapshot = vmMo.hasSnapshot();
|
||||||
diskDatastores = vmMo.getAllDiskDatastores();
|
diskDatastores = vmMo.getAllDiskDatastores();
|
||||||
|
|
||||||
tearDownVmDevices(vmMo, hasSnapshot, deployAsIs);
|
tearDownVmDevices(vmMo, hasSnapshot, deployAsIs);
|
||||||
ensureDiskControllersInternal(vmMo, systemVm, controllerInfo, systemVmScsiControllerType,
|
ensureDiskControllersInternal(vmMo, systemVm, controllerInfo, systemVmScsiControllerType,
|
||||||
numScsiControllerForSystemVm, firstScsiControllerBusNum, deployAsIs);
|
numScsiControllerForSystemVm, firstScsiControllerBusNum, deployAsIs);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// If a VM with the same name is found in a different cluster in the DC, unregister the old VM and configure a new VM (cold-migration).
|
// If a VM with the same name is found in a different cluster in the DC, unregister the old VM and configure a new VM (cold-migration).
|
||||||
VirtualMachineMO existingVmInDc = dcMo.findVm(vmInternalCSName);
|
VirtualMachineMO existingVmInDc = dcMo.findVm(vmInternalCSName);
|
||||||
|
|
@ -2146,7 +2146,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||||
vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
|
vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
|
||||||
if (vmMo == null) {
|
if (vmMo == null) {
|
||||||
logger.info("Cloned deploy-as-is VM " + vmInternalCSName + " is not in this host, relocating it");
|
logger.info("Cloned deploy-as-is VM " + vmInternalCSName + " is not in this host, relocating it");
|
||||||
vmMo = takeVmFromOtherHyperHost(hyperHost, vmInternalCSName);
|
takeVmFromOtherHyperHost(hyperHost, vmInternalCSName);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DiskTO rootDisk = null;
|
DiskTO rootDisk = null;
|
||||||
|
|
@ -2256,11 +2256,11 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||||
vmConfigSpec.setCpuHotAddEnabled(vmMo.isCpuHotAddSupported(guestOsId) && vmSpec.isEnableDynamicallyScaleVm());
|
vmConfigSpec.setCpuHotAddEnabled(vmMo.isCpuHotAddSupported(guestOsId) && vmSpec.isEnableDynamicallyScaleVm());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!vmMo.isMemoryHotAddSupported(guestOsId) && vmSpec.isEnableDynamicallyScaleVm()){
|
if (!vmMo.isMemoryHotAddSupported(guestOsId) && vmSpec.isEnableDynamicallyScaleVm()) {
|
||||||
logger.warn("hotadd of memory is not supported, dynamic scaling feature can not be applied to vm: " + vmInternalCSName);
|
logger.warn("hotadd of memory is not supported, dynamic scaling feature can not be applied to vm: " + vmInternalCSName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!vmMo.isCpuHotAddSupported(guestOsId) && vmSpec.isEnableDynamicallyScaleVm()){
|
if (!vmMo.isCpuHotAddSupported(guestOsId) && vmSpec.isEnableDynamicallyScaleVm()) {
|
||||||
logger.warn("hotadd of cpu is not supported, dynamic scaling feature can not be applied to vm: " + vmInternalCSName);
|
logger.warn("hotadd of cpu is not supported, dynamic scaling feature can not be applied to vm: " + vmInternalCSName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2593,7 +2593,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||||
|
|
||||||
Map<String, Map<String, String>> iqnToData = new HashMap<>();
|
Map<String, Map<String, String>> iqnToData = new HashMap<>();
|
||||||
|
|
||||||
postDiskConfigBeforeStart(vmMo, vmSpec, sortedDisks, ideControllerKey, scsiControllerKey, iqnToData, hyperHost, context);
|
postDiskConfigBeforeStart(vmMo, vmSpec, sortedDisks, iqnToData, hyperHost, context);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Power-on VM
|
// Power-on VM
|
||||||
|
|
@ -2731,14 +2731,24 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean powerOnVM(final VirtualMachineMO vmMo, final String vmInternalCSName, final String vmNameOnVcenter) throws Exception {
|
private boolean powerOnVM(final VirtualMachineMO vmMo, final String vmInternalCSName, final String vmNameOnVcenter) throws Exception {
|
||||||
int retry = 20;
|
final int retry = 20;
|
||||||
while (retry-- > 0) {
|
int retryAttempt = 0;
|
||||||
|
while (++retryAttempt <= retry) {
|
||||||
try {
|
try {
|
||||||
|
logger.debug(String.format("VM %s, powerOn attempt #%d", vmInternalCSName, retryAttempt));
|
||||||
return vmMo.powerOn();
|
return vmMo.powerOn();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.info(String.format("Got exception while power on VM %s with hostname %s", vmInternalCSName, vmNameOnVcenter), e);
|
logger.info(String.format("Got exception while power on VM %s with hostname %s", vmInternalCSName, vmNameOnVcenter), e);
|
||||||
if (e.getMessage() != null && e.getMessage().contains("File system specific implementation of Ioctl[file] failed")) {
|
if (e.getMessage() != null &&
|
||||||
|
(e.getMessage().contains("File system specific implementation of Ioctl[file] failed") ||
|
||||||
|
e.getMessage().contains("Unable to access file") ||
|
||||||
|
e.getMessage().contains("it is locked"))) {
|
||||||
logger.debug(String.format("Failed to power on VM %s with hostname %s. Retrying", vmInternalCSName, vmNameOnVcenter));
|
logger.debug(String.format("Failed to power on VM %s with hostname %s. Retrying", vmInternalCSName, vmNameOnVcenter));
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
logger.debug(String.format("Waiting to power on VM %s been interrupted: ", vmInternalCSName));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
@ -3292,7 +3302,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||||
|
|
||||||
int getReservedMemoryMb(VirtualMachineTO vmSpec) {
|
int getReservedMemoryMb(VirtualMachineTO vmSpec) {
|
||||||
if (vmSpec.getDetails().get(VMwareGuru.VmwareReserveMemory.key()).equalsIgnoreCase("true")) {
|
if (vmSpec.getDetails().get(VMwareGuru.VmwareReserveMemory.key()).equalsIgnoreCase("true")) {
|
||||||
if(vmSpec.getDetails().get(VmDetailConstants.RAM_RESERVATION) != null){
|
if (vmSpec.getDetails().get(VmDetailConstants.RAM_RESERVATION) != null) {
|
||||||
float reservedMemory = (vmSpec.getMaxRam() * Float.parseFloat(vmSpec.getDetails().get(VmDetailConstants.RAM_RESERVATION)));
|
float reservedMemory = (vmSpec.getMaxRam() * Float.parseFloat(vmSpec.getDetails().get(VmDetailConstants.RAM_RESERVATION)));
|
||||||
return (int) (reservedMemory / ResourceType.bytesToMiB);
|
return (int) (reservedMemory / ResourceType.bytesToMiB);
|
||||||
}
|
}
|
||||||
|
|
@ -3630,18 +3640,18 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||||
|
|
||||||
private VirtualMachineDiskInfo getMatchingExistingDisk(VirtualMachineDiskInfoBuilder diskInfoBuilder, DiskTO vol, VmwareHypervisorHost hyperHost, VmwareContext context)
|
private VirtualMachineDiskInfo getMatchingExistingDisk(VirtualMachineDiskInfoBuilder diskInfoBuilder, DiskTO vol, VmwareHypervisorHost hyperHost, VmwareContext context)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
if (diskInfoBuilder != null) {
|
if (diskInfoBuilder == null) {
|
||||||
VolumeObjectTO volume = (VolumeObjectTO) vol.getData();
|
|
||||||
String chainInfo = volume.getChainInfo();
|
|
||||||
Map<String, String> details = vol.getDetails();
|
|
||||||
boolean isManaged = details != null && Boolean.parseBoolean(details.get(DiskTO.MANAGED));
|
|
||||||
String iScsiName = details.get(DiskTO.IQN);
|
|
||||||
String datastoreUUID = volume.getDataStore().getUuid();
|
|
||||||
|
|
||||||
return getMatchingExistingDiskWithVolumeDetails(diskInfoBuilder, volume.getPath(), chainInfo, isManaged, iScsiName, datastoreUUID, hyperHost, context);
|
|
||||||
} else {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VolumeObjectTO volume = (VolumeObjectTO) vol.getData();
|
||||||
|
String chainInfo = volume.getChainInfo();
|
||||||
|
Map<String, String> details = vol.getDetails();
|
||||||
|
boolean isManaged = details != null && Boolean.parseBoolean(details.get(DiskTO.MANAGED));
|
||||||
|
String iScsiName = details.get(DiskTO.IQN);
|
||||||
|
String datastoreUUID = volume.getDataStore().getUuid();
|
||||||
|
|
||||||
|
return getMatchingExistingDiskWithVolumeDetails(diskInfoBuilder, volume.getPath(), chainInfo, isManaged, iScsiName, datastoreUUID, hyperHost, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDiskController(VirtualMachineMO vmMo, VirtualMachineDiskInfo matchingExistingDisk, DiskTO vol, Pair<String, String> controllerInfo, boolean deployAsIs) throws Exception {
|
private String getDiskController(VirtualMachineMO vmMo, VirtualMachineDiskInfo matchingExistingDisk, DiskTO vol, Pair<String, String> controllerInfo, boolean deployAsIs) throws Exception {
|
||||||
|
|
@ -3666,34 +3676,36 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||||
return VmwareHelper.getControllerBasedOnDiskType(controllerInfo, vol);
|
return VmwareHelper.getControllerBasedOnDiskType(controllerInfo, vol);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void postDiskConfigBeforeStart(VirtualMachineMO vmMo, VirtualMachineTO vmSpec, DiskTO[] sortedDisks, int ideControllerKey,
|
private void postDiskConfigBeforeStart(VirtualMachineMO vmMo, VirtualMachineTO vmSpec, DiskTO[] sortedDisks,
|
||||||
int scsiControllerKey, Map<String, Map<String, String>> iqnToData, VmwareHypervisorHost hyperHost, VmwareContext context) throws Exception {
|
Map<String, Map<String, String>> iqnToData, VmwareHypervisorHost hyperHost, VmwareContext context) throws Exception {
|
||||||
VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
|
VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
|
||||||
|
|
||||||
for (DiskTO vol : sortedDisks) {
|
for (DiskTO vol : sortedDisks) {
|
||||||
if (vol.getType() == Volume.Type.ISO)
|
if (vol.getType() == Volume.Type.ISO)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
VolumeObjectTO volumeTO = (VolumeObjectTO) vol.getData();
|
|
||||||
|
|
||||||
VirtualMachineDiskInfo diskInfo = getMatchingExistingDisk(diskInfoBuilder, vol, hyperHost, context);
|
VirtualMachineDiskInfo diskInfo = getMatchingExistingDisk(diskInfoBuilder, vol, hyperHost, context);
|
||||||
assert (diskInfo != null);
|
if (diskInfo == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
String[] diskChain = diskInfo.getDiskChain();
|
String[] diskChain = diskInfo.getDiskChain();
|
||||||
assert (diskChain.length > 0);
|
if (diskChain.length <= 0) {
|
||||||
|
continue;
|
||||||
Map<String, String> details = vol.getDetails();
|
|
||||||
boolean managed = false;
|
|
||||||
|
|
||||||
if (details != null) {
|
|
||||||
managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DatastoreFile file = new DatastoreFile(diskChain[0]);
|
DatastoreFile file = new DatastoreFile(diskChain[0]);
|
||||||
|
|
||||||
|
boolean managed = false;
|
||||||
|
Map<String, String> details = vol.getDetails();
|
||||||
|
if (details != null) {
|
||||||
|
managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
|
||||||
|
}
|
||||||
|
|
||||||
|
VolumeObjectTO volumeTO = (VolumeObjectTO) vol.getData();
|
||||||
|
|
||||||
if (managed) {
|
if (managed) {
|
||||||
DatastoreFile originalFile = new DatastoreFile(volumeTO.getPath());
|
DatastoreFile originalFile = new DatastoreFile(volumeTO.getPath());
|
||||||
|
|
||||||
if (!file.getFileBaseName().equalsIgnoreCase(originalFile.getFileBaseName())) {
|
if (!file.getFileBaseName().equalsIgnoreCase(originalFile.getFileBaseName())) {
|
||||||
if (logger.isInfoEnabled())
|
if (logger.isInfoEnabled())
|
||||||
logger.info("Detected disk-chain top file change on volume: " + volumeTO.getId() + " " + volumeTO.getPath() + " -> " + diskChain[0]);
|
logger.info("Detected disk-chain top file change on volume: " + volumeTO.getId() + " " + volumeTO.getPath() + " -> " + diskChain[0]);
|
||||||
|
|
@ -3706,7 +3718,6 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||||
}
|
}
|
||||||
|
|
||||||
VolumeObjectTO volInSpec = getVolumeInSpec(vmSpec, volumeTO);
|
VolumeObjectTO volInSpec = getVolumeInSpec(vmSpec, volumeTO);
|
||||||
|
|
||||||
if (volInSpec != null) {
|
if (volInSpec != null) {
|
||||||
if (managed) {
|
if (managed) {
|
||||||
Map<String, String> data = new HashMap<>();
|
Map<String, String> data = new HashMap<>();
|
||||||
|
|
@ -3871,20 +3882,20 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||||
if (diskInfo != null) {
|
if (diskInfo != null) {
|
||||||
logger.info("Found existing disk info from volume path: " + volume.getPath());
|
logger.info("Found existing disk info from volume path: " + volume.getPath());
|
||||||
return dsMo;
|
return dsMo;
|
||||||
} else {
|
}
|
||||||
String chainInfo = volume.getChainInfo();
|
|
||||||
if (chainInfo != null) {
|
String chainInfo = volume.getChainInfo();
|
||||||
VirtualMachineDiskInfo infoInChain = _gson.fromJson(chainInfo, VirtualMachineDiskInfo.class);
|
if (chainInfo != null) {
|
||||||
if (infoInChain != null) {
|
VirtualMachineDiskInfo infoInChain = _gson.fromJson(chainInfo, VirtualMachineDiskInfo.class);
|
||||||
String[] disks = infoInChain.getDiskChain();
|
if (infoInChain != null) {
|
||||||
if (disks.length > 0) {
|
String[] disks = infoInChain.getDiskChain();
|
||||||
for (String diskPath : disks) {
|
if (disks.length > 0) {
|
||||||
DatastoreFile file = new DatastoreFile(diskPath);
|
for (String diskPath : disks) {
|
||||||
diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(file.getFileBaseName(), dsName);
|
DatastoreFile file = new DatastoreFile(diskPath);
|
||||||
if (diskInfo != null) {
|
diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(file.getFileBaseName(), dsName);
|
||||||
logger.info("Found existing disk from chain info: " + diskPath);
|
if (diskInfo != null) {
|
||||||
return dsMo;
|
logger.info("Found existing disk from chain info: " + diskPath);
|
||||||
}
|
return dsMo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4747,7 +4758,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||||
Map<Integer, Long> volumeDeviceKey = new HashMap<>();
|
Map<Integer, Long> volumeDeviceKey = new HashMap<>();
|
||||||
if (cmd instanceof MigrateVolumeCommand) { // Else device keys will be found in relocateVirtualMachine
|
if (cmd instanceof MigrateVolumeCommand) { // Else device keys will be found in relocateVirtualMachine
|
||||||
MigrateVolumeCommand mcmd = (MigrateVolumeCommand) cmd;
|
MigrateVolumeCommand mcmd = (MigrateVolumeCommand) cmd;
|
||||||
addVolumeDiskmapping(vmMo, volumeDeviceKey, mcmd.getVolumePath(), mcmd.getVolumeId());
|
addVolumeDiskMapping(vmMo, volumeDeviceKey, mcmd.getVolumePath(), mcmd.getVolumeId());
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
for (Integer diskId: volumeDeviceKey.keySet()) {
|
for (Integer diskId: volumeDeviceKey.keySet()) {
|
||||||
logger.trace(String.format("Disk to migrate has disk id %d and volumeId %d", diskId, volumeDeviceKey.get(diskId)));
|
logger.trace(String.format("Disk to migrate has disk id %d and volumeId %d", diskId, volumeDeviceKey.get(diskId)));
|
||||||
|
|
@ -4765,9 +4776,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||||
|
|
||||||
Answer createAnswerForCmd(VirtualMachineMO vmMo, List<VolumeObjectTO> volumeObjectToList, Command cmd, Map<Integer, Long> volumeDeviceKey) throws Exception {
|
Answer createAnswerForCmd(VirtualMachineMO vmMo, List<VolumeObjectTO> volumeObjectToList, Command cmd, Map<Integer, Long> volumeDeviceKey) throws Exception {
|
||||||
List<VolumeObjectTO> volumeToList;
|
List<VolumeObjectTO> volumeToList;
|
||||||
VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
|
|
||||||
VirtualDisk[] disks = vmMo.getAllDiskDevice();
|
VirtualDisk[] disks = vmMo.getAllDiskDevice();
|
||||||
Answer answer;
|
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace(String.format("creating answer for %s", cmd.getClass().getSimpleName()));
|
logger.trace(String.format("creating answer for %s", cmd.getClass().getSimpleName()));
|
||||||
}
|
}
|
||||||
|
|
@ -4784,7 +4793,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||||
return new Answer(cmd, false, null);
|
return new Answer(cmd, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addVolumeDiskmapping(VirtualMachineMO vmMo, Map<Integer, Long> volumeDeviceKey, String volumePath, long volumeId) throws Exception {
|
private void addVolumeDiskMapping(VirtualMachineMO vmMo, Map<Integer, Long> volumeDeviceKey, String volumePath, long volumeId) throws Exception {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug(String.format("locating disk for volume (%d) using path %s", volumeId, volumePath));
|
logger.debug(String.format("locating disk for volume (%d) using path %s", volumeId, volumePath));
|
||||||
}
|
}
|
||||||
|
|
@ -4919,7 +4928,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||||
VmwareHypervisorHost dsHost = hyperHostInTargetCluster == null ? hyperHost : hyperHostInTargetCluster;
|
VmwareHypervisorHost dsHost = hyperHostInTargetCluster == null ? hyperHost : hyperHostInTargetCluster;
|
||||||
String targetDsName = cmd.getTargetPool().getUuid();
|
String targetDsName = cmd.getTargetPool().getUuid();
|
||||||
morDestinationDS = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(dsHost, targetDsName);
|
morDestinationDS = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(dsHost, targetDsName);
|
||||||
if(morDestinationDS == null) {
|
if (morDestinationDS == null) {
|
||||||
String msg = "Unable to find the target datastore: " + targetDsName + " on host: " + dsHost.getHyperHostName();
|
String msg = "Unable to find the target datastore: " + targetDsName + " on host: " + dsHost.getHyperHostName();
|
||||||
logger.error(msg);
|
logger.error(msg);
|
||||||
throw new CloudRuntimeException(msg);
|
throw new CloudRuntimeException(msg);
|
||||||
|
|
@ -5886,6 +5895,11 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||||
logger.debug(msg);
|
logger.debug(msg);
|
||||||
return new Answer(cmd, true, msg);
|
return new Answer(cmd, true, msg);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
if (e.getMessage().contains("was not found")) {
|
||||||
|
String msg = String.format("%s - VM [%s] file(s) not found, cleanup not needed .", e.getMessage(), cmd.getVmName());
|
||||||
|
logger.debug(msg);
|
||||||
|
return new Answer(cmd, true, msg);
|
||||||
|
}
|
||||||
return new Answer(cmd, false, createLogMessageException(e, cmd));
|
return new Answer(cmd, false, createLogMessageException(e, cmd));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.vmware.vim25.ManagedObjectReference;
|
||||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||||
import org.apache.cloudstack.framework.config.Configurable;
|
import org.apache.cloudstack.framework.config.Configurable;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
@ -193,7 +194,7 @@ public class VmwareStorageLayoutHelper implements Configurable {
|
||||||
if (ds.fileExists(vmdkFullCloneModeLegacyPair[i])) {
|
if (ds.fileExists(vmdkFullCloneModeLegacyPair[i])) {
|
||||||
LOGGER.info("sync " + vmdkFullCloneModeLegacyPair[i] + "->" + vmdkFullCloneModePair[i]);
|
LOGGER.info("sync " + vmdkFullCloneModeLegacyPair[i] + "->" + vmdkFullCloneModePair[i]);
|
||||||
|
|
||||||
ds.moveDatastoreFile(vmdkFullCloneModeLegacyPair[i], dcMo.getMor(), ds.getMor(), vmdkFullCloneModePair[i], dcMo.getMor(), true);
|
moveDatastoreFile(ds, vmdkFullCloneModeLegacyPair[i], dcMo.getMor(), ds.getMor(), vmdkFullCloneModePair[i], dcMo.getMor(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -201,13 +202,13 @@ public class VmwareStorageLayoutHelper implements Configurable {
|
||||||
if (ds.fileExists(vmdkLinkedCloneModeLegacyPair[i])) {
|
if (ds.fileExists(vmdkLinkedCloneModeLegacyPair[i])) {
|
||||||
LOGGER.info("sync " + vmdkLinkedCloneModeLegacyPair[i] + "->" + vmdkLinkedCloneModePair[i]);
|
LOGGER.info("sync " + vmdkLinkedCloneModeLegacyPair[i] + "->" + vmdkLinkedCloneModePair[i]);
|
||||||
|
|
||||||
ds.moveDatastoreFile(vmdkLinkedCloneModeLegacyPair[i], dcMo.getMor(), ds.getMor(), vmdkLinkedCloneModePair[i], dcMo.getMor(), true);
|
moveDatastoreFile(ds, vmdkLinkedCloneModeLegacyPair[i], dcMo.getMor(), ds.getMor(), vmdkLinkedCloneModePair[i], dcMo.getMor(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ds.fileExists(vmdkLinkedCloneModeLegacyPair[0])) {
|
if (ds.fileExists(vmdkLinkedCloneModeLegacyPair[0])) {
|
||||||
LOGGER.info("sync " + vmdkLinkedCloneModeLegacyPair[0] + "->" + vmdkLinkedCloneModePair[0]);
|
LOGGER.info("sync " + vmdkLinkedCloneModeLegacyPair[0] + "->" + vmdkLinkedCloneModePair[0]);
|
||||||
ds.moveDatastoreFile(vmdkLinkedCloneModeLegacyPair[0], dcMo.getMor(), ds.getMor(), vmdkLinkedCloneModePair[0], dcMo.getMor(), true);
|
moveDatastoreFile(ds, vmdkLinkedCloneModeLegacyPair[0], dcMo.getMor(), ds.getMor(), vmdkLinkedCloneModePair[0], dcMo.getMor(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: we will always return a path
|
// Note: we will always return a path
|
||||||
|
|
@ -242,14 +243,14 @@ public class VmwareStorageLayoutHelper implements Configurable {
|
||||||
String targetPath = getDatastorePathBaseFolderFromVmdkFileName(ds, String.format("%s-%s",vmdkName, linkedCloneExtension));
|
String targetPath = getDatastorePathBaseFolderFromVmdkFileName(ds, String.format("%s-%s",vmdkName, linkedCloneExtension));
|
||||||
|
|
||||||
LOGGER.info("Fixup folder-synchronization. move " + companionFilePath + " -> " + targetPath);
|
LOGGER.info("Fixup folder-synchronization. move " + companionFilePath + " -> " + targetPath);
|
||||||
ds.moveDatastoreFile(companionFilePath, dcMo.getMor(), ds.getMor(), targetPath, dcMo.getMor(), true);
|
moveDatastoreFile(ds, companionFilePath, dcMo.getMor(), ds.getMor(), targetPath, dcMo.getMor(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// move the identity VMDK file the last
|
// move the identity VMDK file the last
|
||||||
String targetPath = getDatastorePathBaseFolderFromVmdkFileName(ds, vmdkName + ".vmdk");
|
String targetPath = getDatastorePathBaseFolderFromVmdkFileName(ds, vmdkName + ".vmdk");
|
||||||
LOGGER.info("Fixup folder-synchronization. move " + fileDsFullPath + " -> " + targetPath);
|
LOGGER.info("Fixup folder-synchronization. move " + fileDsFullPath + " -> " + targetPath);
|
||||||
ds.moveDatastoreFile(fileDsFullPath, dcMo.getMor(), ds.getMor(), targetPath, dcMo.getMor(), true);
|
moveDatastoreFile(ds, fileDsFullPath, dcMo.getMor(), ds.getMor(), targetPath, dcMo.getMor(), true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (folderName != null) {
|
if (folderName != null) {
|
||||||
|
|
@ -287,7 +288,7 @@ public class VmwareStorageLayoutHelper implements Configurable {
|
||||||
DatastoreFile targetFile = new DatastoreFile(file.getDatastoreName(), HypervisorHostHelper.VSPHERE_DATASTORE_BASE_FOLDER, file.getFileName());
|
DatastoreFile targetFile = new DatastoreFile(file.getDatastoreName(), HypervisorHostHelper.VSPHERE_DATASTORE_BASE_FOLDER, file.getFileName());
|
||||||
if (!targetFile.getPath().equalsIgnoreCase(file.getPath())) {
|
if (!targetFile.getPath().equalsIgnoreCase(file.getPath())) {
|
||||||
LOGGER.info("Move " + file.getPath() + " -> " + targetFile.getPath());
|
LOGGER.info("Move " + file.getPath() + " -> " + targetFile.getPath());
|
||||||
dsMo.moveDatastoreFile(file.getPath(), dcMo.getMor(), dsMo.getMor(), targetFile.getPath(), dcMo.getMor(), true);
|
moveDatastoreFile(dsMo, file.getPath(), dcMo.getMor(), dsMo.getMor(), targetFile.getPath(), dcMo.getMor(), true);
|
||||||
|
|
||||||
List<String> vSphereFileExtensions = new ArrayList<>(Arrays.asList(VsphereLinkedCloneExtensions.value().trim().split("\\s*,\\s*")));
|
List<String> vSphereFileExtensions = new ArrayList<>(Arrays.asList(VsphereLinkedCloneExtensions.value().trim().split("\\s*,\\s*")));
|
||||||
// add flat file format to the above list
|
// add flat file format to the above list
|
||||||
|
|
@ -297,7 +298,7 @@ public class VmwareStorageLayoutHelper implements Configurable {
|
||||||
String pairTargetFilePath = targetFile.getCompanionPath(String.format("%s-%s", file.getFileBaseName(), linkedCloneExtension));
|
String pairTargetFilePath = targetFile.getCompanionPath(String.format("%s-%s", file.getFileBaseName(), linkedCloneExtension));
|
||||||
if (dsMo.fileExists(pairSrcFilePath)) {
|
if (dsMo.fileExists(pairSrcFilePath)) {
|
||||||
LOGGER.info("Move " + pairSrcFilePath + " -> " + pairTargetFilePath);
|
LOGGER.info("Move " + pairSrcFilePath + " -> " + pairTargetFilePath);
|
||||||
dsMo.moveDatastoreFile(pairSrcFilePath, dcMo.getMor(), dsMo.getMor(), pairTargetFilePath, dcMo.getMor(), true);
|
moveDatastoreFile(dsMo, pairSrcFilePath, dcMo.getMor(), dsMo.getMor(), pairTargetFilePath, dcMo.getMor(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -429,6 +430,31 @@ public class VmwareStorageLayoutHelper implements Configurable {
|
||||||
return dsMo.searchFileInSubFolders(volumePath + ".vmdk", false, null);
|
return dsMo.searchFileInSubFolders(volumePath + ".vmdk", false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean moveDatastoreFile(final DatastoreMO dsMo, String srcFilePath, ManagedObjectReference morSrcDc, ManagedObjectReference morDestDs,
|
||||||
|
String destFilePath, ManagedObjectReference morDestDc, boolean forceOverwrite) throws Exception {
|
||||||
|
final int retry = 20;
|
||||||
|
int retryAttempt = 0;
|
||||||
|
while (++retryAttempt <= retry) {
|
||||||
|
try {
|
||||||
|
LOGGER.debug(String.format("Move datastore file %s, attempt #%d", srcFilePath, retryAttempt));
|
||||||
|
return dsMo.moveDatastoreFile(srcFilePath, morSrcDc, morDestDs, destFilePath, morDestDc, forceOverwrite);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.info(String.format("Got exception while moving datastore file %s ", srcFilePath), e);
|
||||||
|
if (e.getMessage() != null && e.getMessage().contains("Unable to access file")) {
|
||||||
|
LOGGER.debug(String.format("Failed to move datastore file %s. Retrying", srcFilePath));
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
LOGGER.debug(String.format("Waiting to move datastore file %s been interrupted: ", srcFilePath));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getConfigComponentName() {
|
public String getConfigComponentName() {
|
||||||
return VmwareStorageLayoutHelper.class.getSimpleName();
|
return VmwareStorageLayoutHelper.class.getSimpleName();
|
||||||
|
|
|
||||||
|
|
@ -682,9 +682,9 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||||
String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairManagedDatastorePath(dsMo, null,
|
String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairManagedDatastorePath(dsMo, null,
|
||||||
managedStoragePoolRootVolumeName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, false);
|
managedStoragePoolRootVolumeName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, false);
|
||||||
|
|
||||||
dsMo.moveDatastoreFile(vmwareLayoutFilePair[0], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[0], dcMo.getMor(), true);
|
VmwareStorageLayoutHelper.moveDatastoreFile(dsMo, vmwareLayoutFilePair[0], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[0], dcMo.getMor(), true);
|
||||||
for (int i=1; i<vmwareLayoutFilePair.length; i++) {
|
for (int i=1; i<vmwareLayoutFilePair.length; i++) {
|
||||||
dsMo.moveDatastoreFile(vmwareLayoutFilePair[i], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[i], dcMo.getMor(), true);
|
VmwareStorageLayoutHelper.moveDatastoreFile(dsMo, vmwareLayoutFilePair[i], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[i], dcMo.getMor(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
String folderToDelete = dsMo.getDatastorePath(managedStoragePoolRootVolumeName, true);
|
String folderToDelete = dsMo.getDatastorePath(managedStoragePoolRootVolumeName, true);
|
||||||
|
|
@ -814,7 +814,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||||
existingVm.detachAllDisksAndDestroy();
|
existingVm.detachAllDisksAndDestroy();
|
||||||
}
|
}
|
||||||
logger.info("ROOT Volume from deploy-as-is template, cloning template");
|
logger.info("ROOT Volume from deploy-as-is template, cloning template");
|
||||||
cloneVMFromTemplate(hyperHost, template.getPath(), vmName, primaryStore.getUuid());
|
cloneVMFromTemplate(hyperHost, template, volume, vmName, primaryStore.getUuid());
|
||||||
} else {
|
} else {
|
||||||
logger.info("ROOT Volume from deploy-as-is template, volume already created at this point");
|
logger.info("ROOT Volume from deploy-as-is template, volume already created at this point");
|
||||||
}
|
}
|
||||||
|
|
@ -945,7 +945,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||||
String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, vmdkName, vmdkFileBaseName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, !_fullCloneFlag);
|
String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, vmdkName, vmdkFileBaseName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, !_fullCloneFlag);
|
||||||
|
|
||||||
for (int i = 0; i < vmwareLayoutFilePair.length; i++) {
|
for (int i = 0; i < vmwareLayoutFilePair.length; i++) {
|
||||||
dsMo.moveDatastoreFile(vmwareLayoutFilePair[i], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[i], dcMo.getMor(), true);
|
VmwareStorageLayoutHelper.moveDatastoreFile(dsMo, vmwareLayoutFilePair[i], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[i], dcMo.getMor(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("detach disks from volume-wrapper VM and destroy {}", vmdkName);
|
logger.info("detach disks from volume-wrapper VM and destroy {}", vmdkName);
|
||||||
|
|
@ -1222,10 +1222,10 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||||
// Get VMDK filename
|
// Get VMDK filename
|
||||||
String templateVMDKName = "";
|
String templateVMDKName = "";
|
||||||
File[] files = new File(installFullPath).listFiles();
|
File[] files = new File(installFullPath).listFiles();
|
||||||
if(files != null) {
|
if (files != null) {
|
||||||
for(File file : files) {
|
for(File file : files) {
|
||||||
String fileName = file.getName();
|
String fileName = file.getName();
|
||||||
if(fileName.toLowerCase().startsWith(templateUniqueName) && fileName.toLowerCase().endsWith(".vmdk")) {
|
if (fileName.toLowerCase().startsWith(templateUniqueName) && fileName.toLowerCase().endsWith(".vmdk")) {
|
||||||
templateVMDKName += fileName;
|
templateVMDKName += fileName;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1856,16 +1856,16 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||||
CopyCmdAnswer answer = null;
|
CopyCmdAnswer answer = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if(vmName != null) {
|
if (vmName != null) {
|
||||||
vmMo = hyperHost.findVmOnHyperHost(vmName);
|
vmMo = hyperHost.findVmOnHyperHost(vmName);
|
||||||
if (vmMo == null) {
|
if (vmMo == null) {
|
||||||
if(logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Unable to find owner VM for BackupSnapshotCommand on host " + hyperHost.getHyperHostName() + ", will try within datacenter");
|
logger.debug("Unable to find owner VM for BackupSnapshotCommand on host " + hyperHost.getHyperHostName() + ", will try within datacenter");
|
||||||
}
|
}
|
||||||
vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
|
vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(vmMo == null) {
|
if (vmMo == null) {
|
||||||
dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
|
dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
|
||||||
workerVMName = hostService.getWorkerName(context, cmd, 0, dsMo);
|
workerVMName = hostService.getWorkerName(context, cmd, 0, dsMo);
|
||||||
vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVMName, null);
|
vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVMName, null);
|
||||||
|
|
@ -1899,10 +1899,10 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||||
String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl, _nfsVersion);
|
String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl, _nfsVersion);
|
||||||
String snapshotDir = destSnapshot.getPath() + "/" + snapshotBackupUuid;
|
String snapshotDir = destSnapshot.getPath() + "/" + snapshotBackupUuid;
|
||||||
File[] files = new File(secondaryMountPoint + "/" + snapshotDir).listFiles();
|
File[] files = new File(secondaryMountPoint + "/" + snapshotDir).listFiles();
|
||||||
if(files != null) {
|
if (files != null) {
|
||||||
for(File file : files) {
|
for(File file : files) {
|
||||||
String fileName = file.getName();
|
String fileName = file.getName();
|
||||||
if(fileName.toLowerCase().startsWith(snapshotBackupUuid) && fileName.toLowerCase().endsWith(".vmdk")) {
|
if (fileName.toLowerCase().startsWith(snapshotBackupUuid) && fileName.toLowerCase().endsWith(".vmdk")) {
|
||||||
physicalSize = new File(secondaryMountPoint + "/" + snapshotDir + "/" + fileName).length();
|
physicalSize = new File(secondaryMountPoint + "/" + snapshotDir + "/" + fileName).length();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -3651,7 +3651,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||||
}
|
}
|
||||||
workerVm.tagAsWorkerVM();
|
workerVm.tagAsWorkerVM();
|
||||||
|
|
||||||
if(!primaryDsMo.getDatastoreType().equalsIgnoreCase("VVOL")) {
|
if (!primaryDsMo.getDatastoreType().equalsIgnoreCase("VVOL")) {
|
||||||
HypervisorHostHelper.createBaseFolderInDatastore(primaryDsMo, primaryDsMo.getDataCenterMor());
|
HypervisorHostHelper.createBaseFolderInDatastore(primaryDsMo, primaryDsMo.getDataCenterMor());
|
||||||
workerVm.moveAllVmDiskFiles(primaryDsMo, HypervisorHostHelper.VSPHERE_DATASTORE_BASE_FOLDER, false);
|
workerVm.moveAllVmDiskFiles(primaryDsMo, HypervisorHostHelper.VSPHERE_DATASTORE_BASE_FOLDER, false);
|
||||||
}
|
}
|
||||||
|
|
@ -3811,8 +3811,9 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||||
/**
|
/**
|
||||||
* Return the cloned VM from the template
|
* Return the cloned VM from the template
|
||||||
*/
|
*/
|
||||||
public VirtualMachineMO cloneVMFromTemplate(VmwareHypervisorHost hyperHost, String templateName, String cloneName, String templatePrimaryStoreUuid) {
|
public VirtualMachineMO cloneVMFromTemplate(VmwareHypervisorHost hyperHost, TemplateObjectTO template, VolumeObjectTO volume, String cloneName, String templatePrimaryStoreUuid) {
|
||||||
try {
|
try {
|
||||||
|
String templateName = template.getPath();
|
||||||
VmwareContext context = hyperHost.getContext();
|
VmwareContext context = hyperHost.getContext();
|
||||||
DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
|
DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
|
||||||
VirtualMachineMO templateMo = dcMo.findVm(templateName);
|
VirtualMachineMO templateMo = dcMo.findVm(templateName);
|
||||||
|
|
@ -3826,6 +3827,9 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||||
throw new CloudRuntimeException("Unable to find datastore in vSphere");
|
throw new CloudRuntimeException("Unable to find datastore in vSphere");
|
||||||
}
|
}
|
||||||
logger.info("Cloning VM " + cloneName + " from template " + templateName + " into datastore " + templatePrimaryStoreUuid);
|
logger.info("Cloning VM " + cloneName + " from template " + templateName + " into datastore " + templatePrimaryStoreUuid);
|
||||||
|
if (template.getSize() != null) {
|
||||||
|
_fullCloneFlag = volume.getSize() > template.getSize() ? true : _fullCloneFlag;
|
||||||
|
}
|
||||||
if (!_fullCloneFlag) {
|
if (!_fullCloneFlag) {
|
||||||
createVMLinkedClone(templateMo, dcMo, cloneName, morDatastore, morPool, null);
|
createVMLinkedClone(templateMo, dcMo, cloneName, morDatastore, morPool, null);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -8394,6 +8394,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||||
|
|
||||||
getRootVolumeSizeForVmRestore(newVol, template, userVm, diskOffering, details, true);
|
getRootVolumeSizeForVmRestore(newVol, template, userVm, diskOffering, details, true);
|
||||||
volumeMgr.saveVolumeDetails(newVol.getDiskOfferingId(), newVol.getId());
|
volumeMgr.saveVolumeDetails(newVol.getDiskOfferingId(), newVol.getId());
|
||||||
|
newVol = _volsDao.findById(newVol.getId());
|
||||||
|
|
||||||
// 1. Save usage event and update resource count for user vm volumes
|
// 1. Save usage event and update resource count for user vm volumes
|
||||||
try {
|
try {
|
||||||
|
|
@ -8493,7 +8494,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||||
|
|
||||||
Long getRootVolumeSizeForVmRestore(Volume vol, VMTemplateVO template, UserVmVO userVm, DiskOffering diskOffering, Map<String, String> details, boolean update) {
|
Long getRootVolumeSizeForVmRestore(Volume vol, VMTemplateVO template, UserVmVO userVm, DiskOffering diskOffering, Map<String, String> details, boolean update) {
|
||||||
VolumeVO resizedVolume = (VolumeVO) vol;
|
VolumeVO resizedVolume = (VolumeVO) vol;
|
||||||
|
|
||||||
Long size = null;
|
Long size = null;
|
||||||
if (template != null && template.getSize() != null) {
|
if (template != null && template.getSize() != null) {
|
||||||
UserVmDetailVO vmRootDiskSizeDetail = userVmDetailsDao.findDetail(userVm.getId(), VmDetailConstants.ROOT_DISK_SIZE);
|
UserVmDetailVO vmRootDiskSizeDetail = userVmDetailsDao.findDetail(userVm.getId(), VmDetailConstants.ROOT_DISK_SIZE);
|
||||||
|
|
|
||||||
|
|
@ -988,6 +988,9 @@ class TestSSVMs(cloudstackTestCase):
|
||||||
|
|
||||||
# Private IP Address of System VMs are allowed to change after reboot - CLOUDSTACK-7745
|
# Private IP Address of System VMs are allowed to change after reboot - CLOUDSTACK-7745
|
||||||
|
|
||||||
|
# Agent in Up state for a while after reboot, wait for the agent to Disconnect and back Up.
|
||||||
|
time.sleep(60)
|
||||||
|
|
||||||
# Wait for the agent to be up
|
# Wait for the agent to be up
|
||||||
self.waitForSystemVMAgent(cpvm_response.name)
|
self.waitForSystemVMAgent(cpvm_response.name)
|
||||||
|
|
||||||
|
|
@ -1103,6 +1106,9 @@ class TestSSVMs(cloudstackTestCase):
|
||||||
"Check whether CPVM is running or not"
|
"Check whether CPVM is running or not"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Agent in Up state for a while after reboot, wait for the agent to Disconnect and back Up.
|
||||||
|
time.sleep(60)
|
||||||
|
|
||||||
# Wait for the agent to be up
|
# Wait for the agent to be up
|
||||||
self.waitForSystemVMAgent(cpvm_response.name)
|
self.waitForSystemVMAgent(cpvm_response.name)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2332,7 +2332,7 @@ public class VirtualMachineMO extends BaseMO {
|
||||||
vmdkDescriptor = getVmdkFileInfo(fileItem.first());
|
vmdkDescriptor = getVmdkFileInfo(fileItem.first());
|
||||||
|
|
||||||
logger.info("Move VM disk file " + srcFile.getPath() + " to " + destFile.getPath());
|
logger.info("Move VM disk file " + srcFile.getPath() + " to " + destFile.getPath());
|
||||||
srcDsMo.moveDatastoreFile(fileItem.first(), dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true);
|
moveDatastoreFile(srcDsMo, fileItem.first(), dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true);
|
||||||
|
|
||||||
if (vmdkDescriptor != null) {
|
if (vmdkDescriptor != null) {
|
||||||
String vmdkBaseFileName = vmdkDescriptor.first().getBaseFileName();
|
String vmdkBaseFileName = vmdkDescriptor.first().getBaseFileName();
|
||||||
|
|
@ -2340,13 +2340,38 @@ public class VirtualMachineMO extends BaseMO {
|
||||||
destFile = new DatastoreFile(destDsMo.getName(), destDsDir, vmdkBaseFileName);
|
destFile = new DatastoreFile(destDsMo.getName(), destDsDir, vmdkBaseFileName);
|
||||||
|
|
||||||
logger.info("Move VM disk file " + baseFilePath + " to " + destFile.getPath());
|
logger.info("Move VM disk file " + baseFilePath + " to " + destFile.getPath());
|
||||||
srcDsMo.moveDatastoreFile(baseFilePath, dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true);
|
moveDatastoreFile(srcDsMo, baseFilePath, dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean moveDatastoreFile(final DatastoreMO dsMo, String srcFilePath, ManagedObjectReference morSrcDc, ManagedObjectReference morDestDs,
|
||||||
|
String destFilePath, ManagedObjectReference morDestDc, boolean forceOverwrite) throws Exception {
|
||||||
|
final int retry = 20;
|
||||||
|
int retryAttempt = 0;
|
||||||
|
while (++retryAttempt <= retry) {
|
||||||
|
try {
|
||||||
|
logger.debug(String.format("Move datastore file %s, attempt #%d", srcFilePath, retryAttempt));
|
||||||
|
return dsMo.moveDatastoreFile(srcFilePath, morSrcDc, morDestDs, destFilePath, morDestDc, forceOverwrite);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.info(String.format("Got exception while moving datastore file %s ", srcFilePath), e);
|
||||||
|
if (e.getMessage() != null && e.getMessage().contains("Unable to access file")) {
|
||||||
|
logger.debug(String.format("Failed to move datastore file %s. Retrying", srcFilePath));
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
logger.debug(String.format("Waiting to move datastore file %s been interrupted: ", srcFilePath));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public int getPvScsiDeviceControllerKeyNoException() throws Exception {
|
public int getPvScsiDeviceControllerKeyNoException() throws Exception {
|
||||||
List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
|
List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
|
||||||
getDynamicProperty(_mor, "config.hardware.device");
|
getDynamicProperty(_mor, "config.hardware.device");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue