mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-4519: reimplementdestroy-volume to take consideration of on-disk snapshot
This commit is contained in:
parent
a4762b0904
commit
ea13e089b8
|
|
@ -416,14 +416,6 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
|
|||
return tokens[0] + "@" + vCenterIp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Command> finalizeExpunge(VirtualMachine vm) {
|
||||
UnregisterVMCommand unregisterVMCommand = new UnregisterVMCommand(vm.getInstanceName());
|
||||
List<Command> commands = new ArrayList<Command>();
|
||||
commands.add(unregisterVMCommand);
|
||||
return commands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Command> finalizeExpungeNics(VirtualMachine vm, List<NicProfile> nics) {
|
||||
List<Command> commands = new ArrayList<Command>();
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
// under the License.
|
||||
package com.cloud.storage.resource;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.hypervisor.vmware.mo.DatacenterMO;
|
||||
|
|
@ -166,6 +168,40 @@ public class VmwareStorageLayoutHelper {
|
|||
s_logger.info("Fixup folder-synchronization. move " + fileDsFullPath + " -> " + targetPath);
|
||||
ds.moveDatastoreFile(fileDsFullPath, dcMo.getMor(), ds.getMor(), targetPath, dcMo.getMor(), true);
|
||||
}
|
||||
|
||||
public static void moveVolumeToRootFolder(DatacenterMO dcMo, List<String> detachedDisks) throws Exception {
|
||||
if(detachedDisks.size() > 0) {
|
||||
for(String fileFullDsPath : detachedDisks) {
|
||||
DatastoreFile file = new DatastoreFile(fileFullDsPath);
|
||||
|
||||
s_logger.info("Check if we need to move " + fileFullDsPath + " to its root location");
|
||||
DatastoreMO dsMo = new DatastoreMO(dcMo.getContext(), dcMo.findDatastore(file.getDatastoreName()));
|
||||
if(dsMo.getMor() != null) {
|
||||
DatastoreFile targetFile = new DatastoreFile(file.getDatastoreName(), file.getFileName());
|
||||
if(!targetFile.getPath().equalsIgnoreCase(file.getPath())) {
|
||||
s_logger.info("Move " + file.getPath() + " -> " + targetFile.getPath());
|
||||
dsMo.moveDatastoreFile(file.getPath(), dcMo.getMor(), dsMo.getMor(), targetFile.getPath(), dcMo.getMor(), true);
|
||||
|
||||
String pairSrcFilePath = file.getCompanionPath(file.getFileBaseName() + "-flat.vmdk");
|
||||
String pairTargetFilePath = targetFile.getCompanionPath(file.getFileBaseName() + "-flat.vmdk");
|
||||
if(dsMo.fileExists(pairSrcFilePath)) {
|
||||
s_logger.info("Move " + pairSrcFilePath + " -> " + pairTargetFilePath);
|
||||
dsMo.moveDatastoreFile(pairSrcFilePath, dcMo.getMor(), dsMo.getMor(), pairTargetFilePath, dcMo.getMor(), true);
|
||||
}
|
||||
|
||||
pairSrcFilePath = file.getCompanionPath(file.getFileBaseName() + "-delta.vmdk");
|
||||
pairTargetFilePath = targetFile.getCompanionPath(file.getFileBaseName() + "-delta.vmdk");
|
||||
if(dsMo.fileExists(pairSrcFilePath)) {
|
||||
s_logger.info("Move " + pairSrcFilePath + " -> " + pairTargetFilePath);
|
||||
dsMo.moveDatastoreFile(pairSrcFilePath, dcMo.getMor(), dsMo.getMor(), pairTargetFilePath, dcMo.getMor(), true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s_logger.warn("Datastore for " + fileFullDsPath + " no longer exists, we have to skip");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String getTemplateOnSecStorageFilePath(String secStorageMountPoint, String templateRelativeFolderPath,
|
||||
String templateName, String fileExtension) {
|
||||
|
|
@ -227,7 +263,7 @@ public class VmwareStorageLayoutHelper {
|
|||
if(!dsMo.fileExists(fileFullPath))
|
||||
fileFullPath = dsMo.searchFileInSubFolders(fileName, false);
|
||||
if(fileFullPath != null) {
|
||||
dsMo.deleteFile(fileFullPath, dcMo.getMor(), false);
|
||||
dsMo.deleteFile(fileFullPath, dcMo.getMor(), true);
|
||||
} else {
|
||||
s_logger.warn("Unable to locate VMDK file: " + fileName);
|
||||
}
|
||||
|
|
@ -237,7 +273,7 @@ public class VmwareStorageLayoutHelper {
|
|||
if(!dsMo.fileExists(fileFullPath))
|
||||
fileFullPath = dsMo.searchFileInSubFolders(fileName, false);
|
||||
if(fileFullPath != null) {
|
||||
dsMo.deleteFile(fileFullPath, dcMo.getMor(), false);
|
||||
dsMo.deleteFile(fileFullPath, dcMo.getMor(), true);
|
||||
} else {
|
||||
s_logger.warn("Unable to locate VMDK file: " + fileName);
|
||||
}
|
||||
|
|
@ -247,7 +283,7 @@ public class VmwareStorageLayoutHelper {
|
|||
if(!dsMo.fileExists(fileFullPath))
|
||||
fileFullPath = dsMo.searchFileInSubFolders(fileName, false);
|
||||
if(fileFullPath != null) {
|
||||
dsMo.deleteFile(fileFullPath, dcMo.getMor(), false);
|
||||
dsMo.deleteFile(fileFullPath, dcMo.getMor(), true);
|
||||
} else {
|
||||
s_logger.warn("Unable to locate VMDK file: " + fileName);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ import com.cloud.hypervisor.vmware.mo.DatastoreMO;
|
|||
import com.cloud.hypervisor.vmware.mo.HostMO;
|
||||
import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper;
|
||||
import com.cloud.hypervisor.vmware.mo.NetworkDetails;
|
||||
import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfo;
|
||||
import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
|
||||
import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
|
||||
import com.cloud.hypervisor.vmware.resource.VmwareResource;
|
||||
|
|
@ -1308,7 +1309,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||
} else {
|
||||
try{
|
||||
vmMo.unmountToolsInstaller();
|
||||
}catch(Throwable e){
|
||||
} catch(Throwable e){
|
||||
vmMo.detachIso(null);
|
||||
}
|
||||
}
|
||||
|
|
@ -1447,18 +1448,6 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||
s_logger.info("Executing resource DestroyCommand: " + _gson.toJson(cmd));
|
||||
}
|
||||
|
||||
/*
|
||||
* DestroyCommand content example
|
||||
*
|
||||
* {"volume": {"id":5,"name":"Volume1", "mountPoint":"/export/home/kelven/vmware-test/primary",
|
||||
* "path":"6bb8762f-c34c-453c-8e03-26cc246ceec4", "size":0,"type":"DATADISK","resourceType":
|
||||
* "STORAGE_POOL","storagePoolType":"NetworkFilesystem", "poolId":0,"deviceId":0 } }
|
||||
*
|
||||
* {"volume": {"id":1, "name":"i-2-1-KY-ROOT", "mountPoint":"/export/home/kelven/vmware-test/primary",
|
||||
* "path":"i-2-1-KY-ROOT","size":0,"type":"ROOT", "resourceType":"STORAGE_POOL", "storagePoolType":"NetworkFilesystem",
|
||||
* "poolId":0,"deviceId":0 } }
|
||||
*/
|
||||
|
||||
try {
|
||||
VmwareContext context = hostService.getServiceContext(null);
|
||||
VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
|
||||
|
|
@ -1479,6 +1468,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||
ClusterMO clusterMo = new ClusterMO(context, morCluster);
|
||||
|
||||
if (vol.getVolumeType() == Volume.Type.ROOT) {
|
||||
|
||||
String vmName = vol.getVmName();
|
||||
if (vmName != null) {
|
||||
VirtualMachineMO vmMo = clusterMo.findVmOnHyperHost(vmName);
|
||||
|
|
@ -1487,6 +1477,14 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||
s_logger.info("Destroy root volume and VM itself. vmName " + vmName);
|
||||
}
|
||||
|
||||
// Remove all snapshots to consolidate disks for removal
|
||||
vmMo.removeAllSnapshots();
|
||||
|
||||
VirtualMachineDiskInfo diskInfo = null;
|
||||
if(vol.getChainInfo() != null)
|
||||
diskInfo = _gson.fromJson(vol.getChainInfo(), VirtualMachineDiskInfo.class);
|
||||
|
||||
|
||||
HostMO hostMo = vmMo.getRunningHost();
|
||||
List<NetworkDetails> networks = vmMo.getNetworksWithDetails();
|
||||
|
||||
|
|
@ -1494,7 +1492,12 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||
if (this.resource.getVmState(vmMo) != State.Stopped) {
|
||||
vmMo.safePowerOff(_shutdown_waitMs);
|
||||
}
|
||||
vmMo.tearDownDevices(new Class<?>[] { VirtualDisk.class, VirtualEthernetCard.class });
|
||||
|
||||
List<String> detachedDisks = vmMo.detachAllDisksExcept(vol.getPath(), diskInfo != null ? diskInfo.getDiskDeviceBusName() : null);
|
||||
VmwareStorageLayoutHelper.moveVolumeToRootFolder(new DatacenterMO(context, morDc), detachedDisks);
|
||||
|
||||
// let vmMo.destroy to delete volume for us
|
||||
// vmMo.tearDownDevices(new Class<?>[] { VirtualDisk.class, VirtualEthernetCard.class });
|
||||
vmMo.destroy();
|
||||
|
||||
for (NetworkDetails netDetails : networks) {
|
||||
|
|
@ -1506,10 +1509,13 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
if (s_logger.isInfoEnabled())
|
||||
/*
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Destroy volume by original name: " + vol.getPath() + ".vmdk");
|
||||
|
||||
VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, vol.getPath(), new DatacenterMO(context, morDc));
|
||||
}
|
||||
|
||||
VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, vol.getPath(), new DatacenterMO(context, morDc));
|
||||
*/
|
||||
return new Answer(cmd, true, "Success");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -991,13 +991,11 @@ public class VirtualMachineMO extends BaseMO {
|
|||
VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, getScsiDeviceControllerKey(),
|
||||
vmdkDatastorePathChain, morDs, -1, 1);
|
||||
VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
|
||||
//VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
|
||||
VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
|
||||
|
||||
deviceConfigSpec.setDevice(newDisk);
|
||||
deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
|
||||
|
||||
//deviceConfigSpecArray[0] = deviceConfigSpec;
|
||||
reConfigSpec.getDeviceChange().add(deviceConfigSpec);
|
||||
|
||||
ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
|
||||
|
|
@ -1024,13 +1022,11 @@ public class VirtualMachineMO extends BaseMO {
|
|||
VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, controllerKey,
|
||||
vmdkDatastorePathChain, -1, 1);
|
||||
VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
|
||||
//VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
|
||||
VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
|
||||
|
||||
deviceConfigSpec.setDevice(newDisk);
|
||||
deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
|
||||
|
||||
//deviceConfigSpecArray[0] = deviceConfigSpec;
|
||||
reConfigSpec.getDeviceChange().add(deviceConfigSpec);
|
||||
|
||||
ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
|
||||
|
|
@ -1067,7 +1063,6 @@ public class VirtualMachineMO extends BaseMO {
|
|||
List<Pair<String, ManagedObjectReference>> chain = getDiskDatastorePathChain(deviceInfo.first(), true);
|
||||
|
||||
VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
|
||||
//VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
|
||||
VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
|
||||
|
||||
deviceConfigSpec.setDevice(deviceInfo.first());
|
||||
|
|
@ -1076,7 +1071,6 @@ public class VirtualMachineMO extends BaseMO {
|
|||
}
|
||||
deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.REMOVE);
|
||||
|
||||
//deviceConfigSpecArray[0] = deviceConfigSpec;
|
||||
reConfigSpec.getDeviceChange().add(deviceConfigSpec);
|
||||
|
||||
ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
|
||||
|
|
@ -1964,6 +1958,50 @@ public class VirtualMachineMO extends BaseMO {
|
|||
throw new Exception("Unable to find device controller");
|
||||
}
|
||||
|
||||
public List<String> detachAllDisksExcept(String vmdkBaseName, String deviceBusName) throws Exception {
|
||||
List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
|
||||
|
||||
VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
|
||||
List<String> detachedDiskFiles = new ArrayList<String>();
|
||||
|
||||
for(VirtualDevice device : devices) {
|
||||
if(device instanceof VirtualDisk) {
|
||||
VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
|
||||
|
||||
VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)device.getBacking();
|
||||
|
||||
DatastoreFile dsBackingFile = new DatastoreFile(diskBackingInfo.getFileName());
|
||||
String backingBaseName = dsBackingFile.getFileBaseName();
|
||||
String deviceNumbering = getDeviceBusName(devices, device);
|
||||
if(backingBaseName.equalsIgnoreCase(vmdkBaseName) || (deviceBusName != null && deviceBusName.equals(deviceNumbering))) {
|
||||
continue;
|
||||
} else {
|
||||
s_logger.info("Detach " + diskBackingInfo.getFileName() + " from " + getName());
|
||||
|
||||
detachedDiskFiles.add(diskBackingInfo.getFileName());
|
||||
|
||||
deviceConfigSpec.setDevice(device);
|
||||
deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.REMOVE);
|
||||
|
||||
reConfigSpec.getDeviceChange().add(deviceConfigSpec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(detachedDiskFiles.size() > 0) {
|
||||
ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
|
||||
boolean result = _context.getVimClient().waitForTask(morTask);
|
||||
if(result) {
|
||||
_context.waitForTaskProgressDone(morTask);
|
||||
} else {
|
||||
s_logger.warn("Unable to reconfigure the VM to detach disks");
|
||||
throw new Exception("Unable to reconfigure the VM to detach disks");
|
||||
}
|
||||
}
|
||||
|
||||
return detachedDiskFiles;
|
||||
}
|
||||
|
||||
public VirtualDisk[] getAllDiskDevice() throws Exception {
|
||||
List<VirtualDisk> deviceList = new ArrayList<VirtualDisk>();
|
||||
List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
|
||||
|
|
|
|||
Loading…
Reference in New Issue