Skip to content

Commit 90e72b1

Browse files
Pearl1594Pearl Dsilva
andauthored
vmware: Create template from detached data-disks on VMWare (#4294)
Creation of templates from detached data disks results in a Null Pointer Exception on VMWare, as it expects the volume to be attached to a VM. To fix this behavior and make it consistent with other hypervisors, creation of the template from the volume in case not attached to a VM is facilitated by creating a worker VM, attaching the disk to the worker VM, creating the template from it, and then destroying the VM. Co-authored-by: Pearl Dsilva <pearl.dsilva@shapeblue.com>
1 parent 82b6971 commit 90e72b1

1 file changed

Lines changed: 41 additions & 20 deletions

File tree

plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,31 +1186,43 @@ public Answer createTemplateFromVolume(CopyCommand cmd) {
11861186
String volumePath = volume.getPath();
11871187

11881188
String details = null;
1189-
1189+
VirtualMachineMO vmMo = null;
1190+
VirtualMachineMO workerVmMo = null;
11901191
VmwareContext context = hostService.getServiceContext(cmd);
11911192
try {
11921193
VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
1193-
1194-
VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(volume.getVmName());
1195-
if (vmMo == null) {
1196-
if (s_logger.isDebugEnabled()) {
1197-
s_logger.debug("Unable to find the owner VM for CreatePrivateTemplateFromVolumeCommand on host " + hyperHost.getHyperHostName() +
1198-
", try within datacenter");
1199-
}
1200-
vmMo = hyperHost.findVmOnPeerHyperHost(volume.getVmName());
1201-
1194+
if (volume.getVmName() == null) {
1195+
ManagedObjectReference secMorDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, volume.getDataStore().getUuid());
1196+
DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), secMorDs);
1197+
workerVmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, "workervm"+volume.getUuid());
1198+
if (workerVmMo == null) {
1199+
throw new Exception("Unable to find created worker VM");
1200+
}
1201+
vmMo = workerVmMo;
1202+
String vmdkDataStorePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, volumePath + ".vmdk");
1203+
vmMo.attachDisk(new String[] {vmdkDataStorePath}, secMorDs);
1204+
} else {
1205+
vmMo = hyperHost.findVmOnHyperHost(volume.getVmName());
12021206
if (vmMo == null) {
1203-
// This means either the volume is on a zone wide storage pool or VM is deleted by external entity.
1204-
// Look for the VM in the datacenter.
1205-
ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
1206-
DatacenterMO dcMo = new DatacenterMO(context, dcMor);
1207-
vmMo = dcMo.findVm(volume.getVmName());
1208-
}
1207+
if (s_logger.isDebugEnabled()) {
1208+
s_logger.debug("Unable to find the owner VM for CreatePrivateTemplateFromVolumeCommand on host " + hyperHost.getHyperHostName() +
1209+
", try within datacenter");
1210+
}
1211+
vmMo = hyperHost.findVmOnPeerHyperHost(volume.getVmName());
12091212

1210-
if (vmMo == null) {
1211-
String msg = "Unable to find the owner VM for volume operation. vm: " + volume.getVmName();
1212-
s_logger.error(msg);
1213-
throw new Exception(msg);
1213+
if (vmMo == null) {
1214+
// This means either the volume is on a zone wide storage pool or VM is deleted by external entity.
1215+
// Look for the VM in the datacenter.
1216+
ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
1217+
DatacenterMO dcMo = new DatacenterMO(context, dcMor);
1218+
vmMo = dcMo.findVm(volume.getVmName());
1219+
}
1220+
1221+
if (vmMo == null) {
1222+
String msg = "Unable to find the owner VM for volume operation. vm: " + volume.getVmName();
1223+
s_logger.error(msg);
1224+
throw new Exception(msg);
1225+
}
12141226
}
12151227
}
12161228

@@ -1234,6 +1246,15 @@ public Answer createTemplateFromVolume(CopyCommand cmd) {
12341246

12351247
details = "create template from volume exception: " + VmwareHelper.getExceptionMessage(e);
12361248
return new CopyCmdAnswer(details);
1249+
} finally {
1250+
try {
1251+
if (volume.getVmName() == null && workerVmMo != null) {
1252+
workerVmMo.detachAllDisks();
1253+
workerVmMo.destroy();
1254+
}
1255+
} catch (Throwable e) {
1256+
s_logger.error("Failed to destroy worker VM created for detached volume");
1257+
}
12371258
}
12381259
}
12391260

0 commit comments

Comments
 (0)