mirror of https://github.com/apache/cloudstack.git
Add xenserver.create.full.clone global setting
Adds a StoragePool-scoped boolean ConfigKey mirroring vmware.create.full.clone so XenServer-backed VMs can be deployed as full VDI copies (VDI.copy) instead of always using linked clones (VDI.clone). Default false preserves today's behavior. The per-pool flag flows into the existing PrimaryDataStoreTO.fullCloneFlag through a new dispatch method addFullCloneAndDiskprovisiongStrictnessFlagOnDest that switches on hypervisor type.
This commit is contained in:
parent
a4a52c9665
commit
06c6651d36
|
|
@ -195,6 +195,14 @@ public interface StorageManager extends StorageService {
|
|||
true,
|
||||
ConfigKey.Scope.StoragePool,
|
||||
null);
|
||||
ConfigKey<Boolean> XenserverCreateCloneFull = new ConfigKey<>(Boolean.class,
|
||||
"xenserver.create.full.clone",
|
||||
"Storage",
|
||||
"false",
|
||||
"If set to true, creates VMs as full clones on XenServer hypervisor (uses VDI.copy instead of VDI.clone, removing the linked-clone parent relationship).",
|
||||
true,
|
||||
ConfigKey.Scope.StoragePool,
|
||||
null);
|
||||
ConfigKey<Boolean> VmwareAllowParallelExecution = new ConfigKey<>(Boolean.class,
|
||||
"vmware.allow.parallel.command.execution",
|
||||
"Advanced",
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||
srcForCopy = cacheData = cacheMgr.createCacheObject(srcData, destScope);
|
||||
}
|
||||
|
||||
CopyCommand cmd = new CopyCommand(srcForCopy.getTO(), addFullCloneAndDiskprovisiongStrictnessFlagOnVMwareDest(destData.getTO()), primaryStorageDownloadWait,
|
||||
CopyCommand cmd = new CopyCommand(srcForCopy.getTO(), addFullCloneAndDiskprovisiongStrictnessFlagOnDest(destData.getTO()), primaryStorageDownloadWait,
|
||||
VirtualMachineManager.ExecuteInSequence.value());
|
||||
EndPoint ep = destHost != null ? RemoteHostEndPoint.getHypervisorHostEndPoint(destHost) : selector.select(srcForCopy, destData);
|
||||
if (ep == null) {
|
||||
|
|
@ -253,6 +253,43 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||
return dataTO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds {@code 'xenserver.create.full.clone'} value for a given primary storage, whose HV is XenServer, on datastore's {@code fullCloneFlag} field
|
||||
* @param dataTO Dest data store TO
|
||||
* @return dataTO including fullCloneFlag, if provided
|
||||
*/
|
||||
protected DataTO addFullCloneAndDiskprovisiongStrictnessFlagOnXenServerDest(DataTO dataTO) {
|
||||
if (dataTO != null && dataTO.getHypervisorType().equals(Hypervisor.HypervisorType.XenServer)){
|
||||
DataStoreTO dataStoreTO = dataTO.getDataStore();
|
||||
if (dataStoreTO != null && dataStoreTO instanceof PrimaryDataStoreTO){
|
||||
PrimaryDataStoreTO primaryDataStoreTO = (PrimaryDataStoreTO) dataStoreTO;
|
||||
primaryDataStoreTO.setFullCloneFlag(StorageManager.XenserverCreateCloneFull.valueIn(primaryDataStoreTO.getId()));
|
||||
}
|
||||
}
|
||||
return dataTO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches to the per-hypervisor {@code addFullCloneAndDiskprovisiongStrictnessFlagOn*Dest} helper
|
||||
* based on {@code dataTO.getHypervisorType()}. Returns {@code dataTO} unchanged for hypervisors
|
||||
* that do not have a full-clone toggle.
|
||||
* @param dataTO Dest data store TO
|
||||
* @return dataTO including fullCloneFlag, if provided
|
||||
*/
|
||||
protected DataTO addFullCloneAndDiskprovisiongStrictnessFlagOnDest(DataTO dataTO) {
|
||||
if (dataTO == null) {
|
||||
return dataTO;
|
||||
}
|
||||
switch (dataTO.getHypervisorType()) {
|
||||
case VMware:
|
||||
return addFullCloneAndDiskprovisiongStrictnessFlagOnVMwareDest(dataTO);
|
||||
case XenServer:
|
||||
return addFullCloneAndDiskprovisiongStrictnessFlagOnXenServerDest(dataTO);
|
||||
default:
|
||||
return dataTO;
|
||||
}
|
||||
}
|
||||
|
||||
protected Answer copyObject(DataObject srcData, DataObject destData) {
|
||||
return copyObject(srcData, destData, null);
|
||||
}
|
||||
|
|
@ -309,7 +346,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||
ep = selector.select(srcData, volObj);
|
||||
}
|
||||
|
||||
CopyCommand cmd = new CopyCommand(srcData.getTO(), addFullCloneAndDiskprovisiongStrictnessFlagOnVMwareDest(volObj.getTO()), _createVolumeFromSnapshotWait, VirtualMachineManager.ExecuteInSequence.value());
|
||||
CopyCommand cmd = new CopyCommand(srcData.getTO(), addFullCloneAndDiskprovisiongStrictnessFlagOnDest(volObj.getTO()), _createVolumeFromSnapshotWait, VirtualMachineManager.ExecuteInSequence.value());
|
||||
|
||||
Answer answer = null;
|
||||
if (ep == null) {
|
||||
|
|
@ -332,7 +369,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||
}
|
||||
|
||||
protected Answer cloneVolume(DataObject template, DataObject volume) {
|
||||
CopyCommand cmd = new CopyCommand(template.getTO(), addFullCloneAndDiskprovisiongStrictnessFlagOnVMwareDest(volume.getTO()), 0, VirtualMachineManager.ExecuteInSequence.value());
|
||||
CopyCommand cmd = new CopyCommand(template.getTO(), addFullCloneAndDiskprovisiongStrictnessFlagOnDest(volume.getTO()), 0, VirtualMachineManager.ExecuteInSequence.value());
|
||||
try {
|
||||
EndPoint ep = selector.select(volume, anyVolumeRequiresEncryption(volume));
|
||||
Answer answer = null;
|
||||
|
|
@ -416,7 +453,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||
|
||||
objOnImageStore.processEvent(Event.CopyingRequested);
|
||||
|
||||
CopyCommand cmd = new CopyCommand(objOnImageStore.getTO(), addFullCloneAndDiskprovisiongStrictnessFlagOnVMwareDest(destData.getTO()), _copyvolumewait, VirtualMachineManager.ExecuteInSequence.value());
|
||||
CopyCommand cmd = new CopyCommand(objOnImageStore.getTO(), addFullCloneAndDiskprovisiongStrictnessFlagOnDest(destData.getTO()), _copyvolumewait, VirtualMachineManager.ExecuteInSequence.value());
|
||||
EndPoint ep = selector.select(objOnImageStore, destData, encryptionRequired);
|
||||
if (ep == null) {
|
||||
String errMsg = String.format(NO_REMOTE_ENDPOINT_WITH_ENCRYPTION, encryptionRequired);
|
||||
|
|
@ -660,7 +697,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||
ep = selector.select(srcData, destData);
|
||||
}
|
||||
|
||||
CopyCommand cmd = new CopyCommand(srcData.getTO(), addFullCloneAndDiskprovisiongStrictnessFlagOnVMwareDest(destData.getTO()), _createprivatetemplatefromsnapshotwait, VirtualMachineManager.ExecuteInSequence.value());
|
||||
CopyCommand cmd = new CopyCommand(srcData.getTO(), addFullCloneAndDiskprovisiongStrictnessFlagOnDest(destData.getTO()), _createprivatetemplatefromsnapshotwait, VirtualMachineManager.ExecuteInSequence.value());
|
||||
Answer answer = null;
|
||||
if (ep == null) {
|
||||
logger.error(NO_REMOTE_ENDPOINT_SSVM);
|
||||
|
|
@ -698,7 +735,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||
Scope selectedScope = pickCacheScopeForCopy(srcData, destData);
|
||||
cacheData = cacheMgr.getCacheObject(srcData, selectedScope);
|
||||
|
||||
CopyCommand cmd = new CopyCommand(srcData.getTO(), addFullCloneAndDiskprovisiongStrictnessFlagOnVMwareDest(destData.getTO()), _backupsnapshotwait, VirtualMachineManager.ExecuteInSequence.value());
|
||||
CopyCommand cmd = new CopyCommand(srcData.getTO(), addFullCloneAndDiskprovisiongStrictnessFlagOnDest(destData.getTO()), _backupsnapshotwait, VirtualMachineManager.ExecuteInSequence.value());
|
||||
cmd.setCacheTO(cacheData.getTO());
|
||||
cmd.setOptions(options);
|
||||
EndPoint ep = selector.select(srcData, destData, encryptionRequired);
|
||||
|
|
@ -709,7 +746,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||
answer = ep.sendMessage(cmd);
|
||||
}
|
||||
} else {
|
||||
addFullCloneAndDiskprovisiongStrictnessFlagOnVMwareDest(destData.getTO());
|
||||
addFullCloneAndDiskprovisiongStrictnessFlagOnDest(destData.getTO());
|
||||
CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait, VirtualMachineManager.ExecuteInSequence.value());
|
||||
cmd.setOptions(options);
|
||||
EndPoint ep = selector.select(srcData, destData, StorageAction.BACKUPSNAPSHOT, encryptionRequired);
|
||||
|
|
|
|||
|
|
@ -101,6 +101,14 @@ public class AncientDataMotionStrategyTest {
|
|||
verify(dataStoreTO).setFullCloneFlag(FULL_CLONE_FLAG);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddFullCloneFlagOnXenServerDest() throws IllegalAccessException, NoSuchFieldException {
|
||||
overrideDefaultConfigValue(StorageManager.XenserverCreateCloneFull, String.valueOf(FULL_CLONE_FLAG));
|
||||
when(dataTO.getHypervisorType()).thenReturn(HypervisorType.XenServer);
|
||||
strategy.addFullCloneAndDiskprovisiongStrictnessFlagOnXenServerDest(dataTO);
|
||||
verify(dataStoreTO).setFullCloneFlag(FULL_CLONE_FLAG);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddFullCloneFlagOnNotVmwareDest(){
|
||||
verify(dataStoreTO, never()).setFullCloneFlag(any(Boolean.class));
|
||||
|
|
|
|||
|
|
@ -859,12 +859,19 @@ public class XenServerStorageProcessor implements StorageProcessor {
|
|||
final DataTO srcData = cmd.getSrcTO();
|
||||
final DataTO destData = cmd.getDestTO();
|
||||
final VolumeObjectTO volume = (VolumeObjectTO) destData;
|
||||
final DataStoreTO destStore = volume.getDataStore();
|
||||
final boolean fullClone = destStore instanceof PrimaryDataStoreTO
|
||||
&& Boolean.TRUE.equals(((PrimaryDataStoreTO) destStore).isFullCloneFlag());
|
||||
VDI vdi = null;
|
||||
try {
|
||||
VDI tmpltvdi = null;
|
||||
|
||||
tmpltvdi = getVDIbyUuid(conn, srcData.getPath());
|
||||
vdi = tmpltvdi.createClone(conn, new HashMap<String, String>());
|
||||
if (fullClone) {
|
||||
vdi = tmpltvdi.copy(conn, tmpltvdi.getSR(conn));
|
||||
} else {
|
||||
vdi = tmpltvdi.createClone(conn, new HashMap<String, String>());
|
||||
}
|
||||
Long virtualSize = vdi.getVirtualSize(conn);
|
||||
if (volume.getSize() > virtualSize) {
|
||||
logger.debug("Overriding provided Template's size with new size " + toHumanReadableSize(volume.getSize()) + " for volume: " + volume.getName());
|
||||
|
|
|
|||
|
|
@ -4616,6 +4616,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||
SecStorageVMAutoScaleDown,
|
||||
MountDisabledStoragePool,
|
||||
VmwareCreateCloneFull,
|
||||
XenserverCreateCloneFull,
|
||||
VmwareAllowParallelExecution,
|
||||
DataStoreDownloadFollowRedirects,
|
||||
AllowVolumeReSizeBeyondAllocation,
|
||||
|
|
|
|||
Loading…
Reference in New Issue