mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge remote-tracking branch 'origin/4.17'
Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
commit
3d8ea4f3b3
@ -436,7 +436,7 @@ public interface ManagementService {
|
|||||||
*/
|
*/
|
||||||
Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForMigrationOfVolume(Long volumeId);
|
Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForMigrationOfVolume(Long volumeId);
|
||||||
|
|
||||||
Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForMigrationOfVolumeInternal(Long volumeId, Long newDiskOfferingId, Long newSize, Long newMinIops, Long newMaxIops, boolean keepSourceStoragePool, boolean bypassStorageTypeCheck);
|
Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForSystemMigrationOfVolume(Long volumeId, Long newDiskOfferingId, Long newSize, Long newMinIops, Long newMaxIops, boolean keepSourceStoragePool, boolean bypassStorageTypeCheck);
|
||||||
|
|
||||||
String[] listEventTypes();
|
String[] listEventTypes();
|
||||||
|
|
||||||
|
|||||||
@ -524,7 +524,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||||||
@Override
|
@Override
|
||||||
public void allocate(final String vmInstanceName, final VirtualMachineTemplate template, final ServiceOffering serviceOffering,
|
public void allocate(final String vmInstanceName, final VirtualMachineTemplate template, final ServiceOffering serviceOffering,
|
||||||
final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks, final DeploymentPlan plan, final HypervisorType hyperType) throws InsufficientCapacityException {
|
final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks, final DeploymentPlan plan, final HypervisorType hyperType) throws InsufficientCapacityException {
|
||||||
DiskOffering diskOffering = _diskOfferingDao.findById(serviceOffering.getId());
|
DiskOffering diskOffering = _diskOfferingDao.findById(serviceOffering.getDiskOfferingId());
|
||||||
allocate(vmInstanceName, template, serviceOffering, new DiskOfferingInfo(diskOffering), new ArrayList<>(), networks, plan, hyperType, null, null);
|
allocate(vmInstanceName, template, serviceOffering, new DiskOfferingInfo(diskOffering), new ArrayList<>(), networks, plan, hyperType, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3526,7 +3526,7 @@ public abstract class CitrixResourceBase extends ServerResourceBase implements S
|
|||||||
} else if (param.matches("vbd_.*_write")) {
|
} else if (param.matches("vbd_.*_write")) {
|
||||||
vmStatsAnswer.setDiskWriteKBs(vmStatsAnswer.getDiskWriteKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES);
|
vmStatsAnswer.setDiskWriteKBs(vmStatsAnswer.getDiskWriteKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES);
|
||||||
} else if (param.contains("memory_internal_free")) {
|
} else if (param.contains("memory_internal_free")) {
|
||||||
vmStatsAnswer.setIntFreeMemoryKBs(vmStatsAnswer.getIntFreeMemoryKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES);
|
vmStatsAnswer.setIntFreeMemoryKBs(vmStatsAnswer.getIntFreeMemoryKBs() + getDataAverage(dataNode, col, numRows));
|
||||||
} else if (param.contains("memory_target")) {
|
} else if (param.contains("memory_target")) {
|
||||||
vmStatsAnswer.setTargetMemoryKBs(vmStatsAnswer.getTargetMemoryKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES);
|
vmStatsAnswer.setTargetMemoryKBs(vmStatsAnswer.getTargetMemoryKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES);
|
||||||
} else if (param.contains("memory")) {
|
} else if (param.contains("memory")) {
|
||||||
|
|||||||
@ -120,7 +120,7 @@ public class DomainChecker extends AdapterBase implements SecurityChecker {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
private void checkPublicTemplateAccess(VirtualMachineTemplate template, Account owner, Account caller){
|
private void checkPublicTemplateAccess(VirtualMachineTemplate template, Account owner, Account caller){
|
||||||
if (!QueryService.SharePublicTemplatesWithOtherDomains.valueIn(owner.getDomainId()) ||
|
if (QueryService.SharePublicTemplatesWithOtherDomains.valueIn(owner.getDomainId()) ||
|
||||||
caller.getDomainId() == owner.getDomainId() ||
|
caller.getDomainId() == owner.getDomainId() ||
|
||||||
_domainDao.isChildDomain(owner.getDomainId(), caller.getDomainId())) {
|
_domainDao.isChildDomain(owner.getDomainId(), caller.getDomainId())) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -1552,7 +1552,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
@Override
|
@Override
|
||||||
public Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForMigrationOfVolume(final Long volumeId) {
|
public Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForMigrationOfVolume(final Long volumeId) {
|
||||||
|
|
||||||
Pair<List<? extends StoragePool>, List<? extends StoragePool>> allPoolsAndSuitablePoolsPair = listStoragePoolsForMigrationOfVolumeInternal(volumeId, null, null, null, null, false, true);
|
Pair<List<? extends StoragePool>, List<? extends StoragePool>> allPoolsAndSuitablePoolsPair = listStoragePoolsForMigrationOfVolumeInternal(volumeId, null, null, null, null, false, true, false);
|
||||||
List<? extends StoragePool> allPools = allPoolsAndSuitablePoolsPair.first();
|
List<? extends StoragePool> allPools = allPoolsAndSuitablePoolsPair.first();
|
||||||
List<? extends StoragePool> suitablePools = allPoolsAndSuitablePoolsPair.second();
|
List<? extends StoragePool> suitablePools = allPoolsAndSuitablePoolsPair.second();
|
||||||
List<StoragePool> avoidPools = new ArrayList<>();
|
List<StoragePool> avoidPools = new ArrayList<>();
|
||||||
@ -1568,13 +1568,20 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
return new Pair<List<? extends StoragePool>, List<? extends StoragePool>>(allPools, suitablePools);
|
return new Pair<List<? extends StoragePool>, List<? extends StoragePool>>(allPools, suitablePools);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForMigrationOfVolumeInternal(final Long volumeId, Long newDiskOfferingId, Long newSize, Long newMinIops, Long newMaxIops, boolean keepSourceStoragePool, boolean bypassStorageTypeCheck) {
|
@Override
|
||||||
final Account caller = getCaller();
|
public Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForSystemMigrationOfVolume(final Long volumeId, Long newDiskOfferingId, Long newSize, Long newMinIops, Long newMaxIops, boolean keepSourceStoragePool, boolean bypassStorageTypeCheck) {
|
||||||
if (!_accountMgr.isRootAdmin(caller.getId())) {
|
return listStoragePoolsForMigrationOfVolumeInternal(volumeId, newDiskOfferingId, newSize, newMinIops, newMaxIops, keepSourceStoragePool, bypassStorageTypeCheck, true);
|
||||||
if (s_logger.isDebugEnabled()) {
|
}
|
||||||
s_logger.debug("Caller is not a root admin, permission denied to migrate the volume");
|
|
||||||
|
public Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForMigrationOfVolumeInternal(final Long volumeId, Long newDiskOfferingId, Long newSize, Long newMinIops, Long newMaxIops, boolean keepSourceStoragePool, boolean bypassStorageTypeCheck, boolean bypassAccountCheck) {
|
||||||
|
if (!bypassAccountCheck) {
|
||||||
|
final Account caller = getCaller();
|
||||||
|
if (!_accountMgr.isRootAdmin(caller.getId())) {
|
||||||
|
if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("Caller is not a root admin, permission denied to migrate the volume");
|
||||||
|
}
|
||||||
|
throw new PermissionDeniedException("No permission to migrate volume, only root admin can migrate a volume");
|
||||||
}
|
}
|
||||||
throw new PermissionDeniedException("No permission to migrate volume, only root admin can migrate a volume");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final VolumeVO volume = _volumeDao.findById(volumeId);
|
final VolumeVO volume = _volumeDao.findById(volumeId);
|
||||||
|
|||||||
@ -96,6 +96,7 @@ import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToSt
|
|||||||
import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
|
import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.collections.MapUtils;
|
import org.apache.commons.collections.MapUtils;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
@ -1803,14 +1804,14 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentSize != newSize || newMaxIops != volume.getMaxIops() || newMinIops != volume.getMinIops()) {
|
if (currentSize != newSize || !compareEqualsIncludingNullOrZero(newMaxIops, volume.getMaxIops()) || !compareEqualsIncludingNullOrZero(newMinIops, volume.getMinIops())) {
|
||||||
volumeResizeRequired = true;
|
volumeResizeRequired = true;
|
||||||
validateVolumeReadyStateAndHypervisorChecks(volume, currentSize, newSize);
|
validateVolumeReadyStateAndHypervisorChecks(volume, currentSize, newSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
StoragePoolVO existingStoragePool = _storagePoolDao.findById(volume.getPoolId());
|
StoragePoolVO existingStoragePool = _storagePoolDao.findById(volume.getPoolId());
|
||||||
|
|
||||||
Pair<List<? extends StoragePool>, List<? extends StoragePool>> poolsPair = managementService.listStoragePoolsForMigrationOfVolumeInternal(volume.getId(), newDiskOffering.getId(), newSize, newMinIops, newMaxIops, true, false);
|
Pair<List<? extends StoragePool>, List<? extends StoragePool>> poolsPair = managementService.listStoragePoolsForSystemMigrationOfVolume(volume.getId(), newDiskOffering.getId(), newSize, newMinIops, newMaxIops, true, false);
|
||||||
List<? extends StoragePool> suitableStoragePools = poolsPair.second();
|
List<? extends StoragePool> suitableStoragePools = poolsPair.second();
|
||||||
|
|
||||||
if (!suitableStoragePools.stream().anyMatch(p -> (p.getId() == existingStoragePool.getId()))) {
|
if (!suitableStoragePools.stream().anyMatch(p -> (p.getId() == existingStoragePool.getId()))) {
|
||||||
@ -1859,6 +1860,21 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to compare long values, in miniops and maxiops a or b can be null or 0.
|
||||||
|
* Use this method to treat 0 and null as same
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* @param b
|
||||||
|
* @return true if a and b are equal excluding 0 and null values.
|
||||||
|
*/
|
||||||
|
private boolean compareEqualsIncludingNullOrZero(Long a, Long b) {
|
||||||
|
a = ObjectUtils.defaultIfNull(a, 0L);
|
||||||
|
b = ObjectUtils.defaultIfNull(b, 0L);
|
||||||
|
|
||||||
|
return a.equals(b);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the new disk offering is the same than current offering, and the respective Service offering is a custom (constraint or unconstraint) offering.
|
* Returns true if the new disk offering is the same than current offering, and the respective Service offering is a custom (constraint or unconstraint) offering.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -318,8 +318,10 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso
|
|||||||
private void informStoragePoolForVmTags(long vmId, String key, String value) {
|
private void informStoragePoolForVmTags(long vmId, String key, String value) {
|
||||||
List<VolumeVO> volumeVos = volumeDao.findByInstance(vmId);
|
List<VolumeVO> volumeVos = volumeDao.findByInstance(vmId);
|
||||||
for (VolumeVO volume : volumeVos) {
|
for (VolumeVO volume : volumeVos) {
|
||||||
DataStore dataStore = dataStoreMgr.getDataStore(volume.getPoolId(), DataStoreRole.Primary);
|
Long poolId = volume.getPoolId();
|
||||||
|
DataStore dataStore = retrieveDatastore(poolId);
|
||||||
if (dataStore == null || !(dataStore.getDriver() instanceof PrimaryDataStoreDriver)) {
|
if (dataStore == null || !(dataStore.getDriver() instanceof PrimaryDataStoreDriver)) {
|
||||||
|
s_logger.info(String.format("No data store found for VM %d with pool ID %d.", vmId, poolId));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
PrimaryDataStoreDriver dataStoreDriver = (PrimaryDataStoreDriver) dataStore.getDriver();
|
PrimaryDataStoreDriver dataStoreDriver = (PrimaryDataStoreDriver) dataStore.getDriver();
|
||||||
@ -328,4 +330,11 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected DataStore retrieveDatastore(Long poolId) {
|
||||||
|
if (poolId == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return dataStoreMgr.getDataStore(poolId, DataStoreRole.Primary);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,9 +47,12 @@ import com.cloud.utils.Pair;
|
|||||||
*/
|
*/
|
||||||
public interface UserVmManager extends UserVmService {
|
public interface UserVmManager extends UserVmService {
|
||||||
String EnableDynamicallyScaleVmCK = "enable.dynamic.scale.vm";
|
String EnableDynamicallyScaleVmCK = "enable.dynamic.scale.vm";
|
||||||
|
String AllowDiskOfferingChangeDuringScaleVmCK = "allow.diskoffering.change.during.scale.vm";
|
||||||
String AllowUserExpungeRecoverVmCK ="allow.user.expunge.recover.vm";
|
String AllowUserExpungeRecoverVmCK ="allow.user.expunge.recover.vm";
|
||||||
ConfigKey<Boolean> EnableDynamicallyScaleVm = new ConfigKey<Boolean>("Advanced", Boolean.class, EnableDynamicallyScaleVmCK, "false",
|
ConfigKey<Boolean> EnableDynamicallyScaleVm = new ConfigKey<Boolean>("Advanced", Boolean.class, EnableDynamicallyScaleVmCK, "false",
|
||||||
"Enables/Disables dynamically scaling a vm", true, ConfigKey.Scope.Zone);
|
"Enables/Disables dynamically scaling a vm", true, ConfigKey.Scope.Zone);
|
||||||
|
ConfigKey<Boolean> AllowDiskOfferingChangeDuringScaleVm = new ConfigKey<Boolean>("Advanced", Boolean.class, AllowDiskOfferingChangeDuringScaleVmCK, "false",
|
||||||
|
"Determines whether to allow or disallow disk offering change for root volume during scaling of a stopped or running vm", true, ConfigKey.Scope.Zone);
|
||||||
ConfigKey<Boolean> AllowUserExpungeRecoverVm = new ConfigKey<Boolean>("Advanced", Boolean.class, AllowUserExpungeRecoverVmCK, "false",
|
ConfigKey<Boolean> AllowUserExpungeRecoverVm = new ConfigKey<Boolean>("Advanced", Boolean.class, AllowUserExpungeRecoverVmCK, "false",
|
||||||
"Determines whether users can expunge or recover their vm", true, ConfigKey.Scope.Account);
|
"Determines whether users can expunge or recover their vm", true, ConfigKey.Scope.Account);
|
||||||
ConfigKey<Boolean> DisplayVMOVFProperties = new ConfigKey<Boolean>("Advanced", Boolean.class, "vm.display.ovf.properties", "false",
|
ConfigKey<Boolean> DisplayVMOVFProperties = new ConfigKey<Boolean>("Advanced", Boolean.class, "vm.display.ovf.properties", "false",
|
||||||
|
|||||||
@ -1296,7 +1296,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
|
|
||||||
// resize and migrate the root volume if required
|
// resize and migrate the root volume if required
|
||||||
DiskOfferingVO newDiskOffering = _diskOfferingDao.findById(newServiceOffering.getDiskOfferingId());
|
DiskOfferingVO newDiskOffering = _diskOfferingDao.findById(newServiceOffering.getDiskOfferingId());
|
||||||
changeDiskOfferingForRootVolume(vmId, newDiskOffering, customParameters);
|
changeDiskOfferingForRootVolume(vmId, newDiskOffering, customParameters, vmInstance.getDataCenterId());
|
||||||
|
|
||||||
_itMgr.upgradeVmDb(vmId, newServiceOffering, currentServiceOffering);
|
_itMgr.upgradeVmDb(vmId, newServiceOffering, currentServiceOffering);
|
||||||
|
|
||||||
@ -2066,7 +2066,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
|
|
||||||
// #3 resize or migrate the root volume if required
|
// #3 resize or migrate the root volume if required
|
||||||
DiskOfferingVO newDiskOffering = _diskOfferingDao.findById(newServiceOffering.getDiskOfferingId());
|
DiskOfferingVO newDiskOffering = _diskOfferingDao.findById(newServiceOffering.getDiskOfferingId());
|
||||||
changeDiskOfferingForRootVolume(vmId, newDiskOffering, customParameters);
|
changeDiskOfferingForRootVolume(vmId, newDiskOffering, customParameters, vmInstance.getDataCenterId());
|
||||||
|
|
||||||
// #4 scale the vm now
|
// #4 scale the vm now
|
||||||
vmInstance = _vmInstanceDao.findById(vmId);
|
vmInstance = _vmInstanceDao.findById(vmId);
|
||||||
@ -2109,7 +2109,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void changeDiskOfferingForRootVolume(Long vmId, DiskOfferingVO newDiskOffering, Map<String, String> customParameters) throws ResourceAllocationException {
|
private void changeDiskOfferingForRootVolume(Long vmId, DiskOfferingVO newDiskOffering, Map<String, String> customParameters, Long zoneId) throws ResourceAllocationException {
|
||||||
|
|
||||||
|
if (!AllowDiskOfferingChangeDuringScaleVm.valueIn(zoneId)) {
|
||||||
|
if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug(String.format("Changing the disk offering of the root volume during the compute offering change operation is disabled. Please check the setting [%s].", AllowDiskOfferingChangeDuringScaleVm.key()));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
List<VolumeVO> vols = _volsDao.findReadyAndAllocatedRootVolumesByInstance(vmId);
|
List<VolumeVO> vols = _volsDao.findReadyAndAllocatedRootVolumesByInstance(vmId);
|
||||||
|
|
||||||
@ -7985,7 +7992,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConfigKey<?>[] getConfigKeys() {
|
public ConfigKey<?>[] getConfigKeys() {
|
||||||
return new ConfigKey<?>[] {EnableDynamicallyScaleVm, AllowUserExpungeRecoverVm, VmIpFetchWaitInterval, VmIpFetchTrialMax,
|
return new ConfigKey<?>[] {EnableDynamicallyScaleVm, AllowDiskOfferingChangeDuringScaleVm, AllowUserExpungeRecoverVm, VmIpFetchWaitInterval, VmIpFetchTrialMax,
|
||||||
VmIpFetchThreadPoolMax, VmIpFetchTaskWorkers, AllowDeployVmIfGivenHostFails, EnableAdditionalVmConfig, DisplayVMOVFProperties,
|
VmIpFetchThreadPoolMax, VmIpFetchTaskWorkers, AllowDeployVmIfGivenHostFails, EnableAdditionalVmConfig, DisplayVMOVFProperties,
|
||||||
KvmAdditionalConfigAllowList, XenServerAdditionalConfigAllowList, VmwareAdditionalConfigAllowList};
|
KvmAdditionalConfigAllowList, XenServerAdditionalConfigAllowList, VmwareAdditionalConfigAllowList};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -794,7 +794,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
LOGGER.debug(String.format("Volume %s needs to be migrated", volumeVO.getUuid()));
|
LOGGER.debug(String.format("Volume %s needs to be migrated", volumeVO.getUuid()));
|
||||||
Pair<List<? extends StoragePool>, List<? extends StoragePool>> poolsPair = managementService.listStoragePoolsForMigrationOfVolumeInternal(profile.getVolumeId(), null, null, null, null, false, true);
|
Pair<List<? extends StoragePool>, List<? extends StoragePool>> poolsPair = managementService.listStoragePoolsForSystemMigrationOfVolume(profile.getVolumeId(), null, null, null, null, false, true);
|
||||||
if (CollectionUtils.isEmpty(poolsPair.first()) && CollectionUtils.isEmpty(poolsPair.second())) {
|
if (CollectionUtils.isEmpty(poolsPair.first()) && CollectionUtils.isEmpty(poolsPair.second())) {
|
||||||
cleanupFailedImportVM(vm);
|
cleanupFailedImportVM(vm);
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("VM import failed for unmanaged vm: %s during volume ID: %s migration as no suitable pool(s) found", userVm.getInstanceName(), volumeVO.getUuid()));
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("VM import failed for unmanaged vm: %s during volume ID: %s migration as no suitable pool(s) found", userVm.getInstanceName(), volumeVO.getUuid()));
|
||||||
|
|||||||
@ -25,6 +25,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@ -123,4 +124,10 @@ public class TaggedResourceManagerImplTest extends TestCase {
|
|||||||
Mockito.doThrow(PermissionDeniedException.class).when(accountManager).checkAccess(caller, null, false, owner);
|
Mockito.doThrow(PermissionDeniedException.class).when(accountManager).checkAccess(caller, null, false, owner);
|
||||||
taggedResourceManagerImplSpy.checkTagsDeletePermission(List.of(resourceTag1, resourceTag2), caller);
|
taggedResourceManagerImplSpy.checkTagsDeletePermission(List.of(resourceTag1, resourceTag2), caller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRetrieveDataStoreNullPoolId() {
|
||||||
|
DataStore dataStore = taggedResourceManagerImplSpy.retrieveDatastore(null);
|
||||||
|
Assert.assertNull(dataStore);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1002,7 +1002,7 @@ class CsRemoteAccessVpn(CsDataBag):
|
|||||||
|
|
||||||
secret = CsFile(vpnsecretfilte)
|
secret = CsFile(vpnsecretfilte)
|
||||||
secret.empty()
|
secret.empty()
|
||||||
secret.addeq("%s : PSK \"%s\"" % (left, psk))
|
secret.addeq(": PSK \"%s\"" % (psk))
|
||||||
secret.commit()
|
secret.commit()
|
||||||
|
|
||||||
xl2tpdconf = CsFile(xl2tpdconffile)
|
xl2tpdconf = CsFile(xl2tpdconffile)
|
||||||
|
|||||||
@ -25,10 +25,13 @@ from marvin.lib.base import (Account,
|
|||||||
Host,
|
Host,
|
||||||
VirtualMachine,
|
VirtualMachine,
|
||||||
ServiceOffering,
|
ServiceOffering,
|
||||||
|
DiskOffering,
|
||||||
Template,
|
Template,
|
||||||
Configurations)
|
Configurations,
|
||||||
|
Volume)
|
||||||
from marvin.lib.common import (get_zone,
|
from marvin.lib.common import (get_zone,
|
||||||
get_template,
|
get_template,
|
||||||
|
get_test_template,
|
||||||
get_domain)
|
get_domain)
|
||||||
from nose.plugins.attrib import attr
|
from nose.plugins.attrib import attr
|
||||||
from marvin.sshClient import SshClient
|
from marvin.sshClient import SshClient
|
||||||
@ -54,7 +57,7 @@ class TestScaleVm(cloudstackTestCase):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Get Zone, Domain and templates
|
# Get Zone, Domain and templates
|
||||||
domain = get_domain(cls.apiclient)
|
cls.domain = get_domain(cls.apiclient)
|
||||||
cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
|
cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
|
||||||
cls.services['mode'] = cls.zone.networktype
|
cls.services['mode'] = cls.zone.networktype
|
||||||
|
|
||||||
@ -73,14 +76,19 @@ class TestScaleVm(cloudstackTestCase):
|
|||||||
isdynamicallyscalable='true'
|
isdynamicallyscalable='true'
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
cls.template = Template.register(
|
cls.template = get_test_template(
|
||||||
cls.apiclient,
|
cls.apiclient,
|
||||||
cls.services["CentOS7template"],
|
cls.zone.id,
|
||||||
zoneid=cls.zone.id
|
cls.hypervisor
|
||||||
)
|
)
|
||||||
cls._cleanup.append(cls.template)
|
if cls.template == FAILED:
|
||||||
cls.template.download(cls.apiclient)
|
assert False, "get_test_template() failed to return template\
|
||||||
time.sleep(60)
|
with hypervisor %s" % cls.hypervisor
|
||||||
|
cls.template = Template.update(
|
||||||
|
cls.template,
|
||||||
|
cls.apiclient,
|
||||||
|
isdynamicallyscalable='true'
|
||||||
|
)
|
||||||
|
|
||||||
# Set Zones and disk offerings
|
# Set Zones and disk offerings
|
||||||
cls.services["small"]["zoneid"] = cls.zone.id
|
cls.services["small"]["zoneid"] = cls.zone.id
|
||||||
@ -90,7 +98,7 @@ class TestScaleVm(cloudstackTestCase):
|
|||||||
cls.account = Account.create(
|
cls.account = Account.create(
|
||||||
cls.apiclient,
|
cls.apiclient,
|
||||||
cls.services["account"],
|
cls.services["account"],
|
||||||
domainid=domain.id
|
domainid=cls.domain.id
|
||||||
)
|
)
|
||||||
cls._cleanup.append(cls.account)
|
cls._cleanup.append(cls.account)
|
||||||
|
|
||||||
@ -124,37 +132,6 @@ class TestScaleVm(cloudstackTestCase):
|
|||||||
dynamicscalingenabled=False
|
dynamicscalingenabled=False
|
||||||
)
|
)
|
||||||
|
|
||||||
# create a virtual machine
|
|
||||||
cls.virtual_machine = VirtualMachine.create(
|
|
||||||
cls.apiclient,
|
|
||||||
cls.services["small"],
|
|
||||||
accountid=cls.account.name,
|
|
||||||
domainid=cls.account.domainid,
|
|
||||||
serviceofferingid=cls.small_offering.id,
|
|
||||||
mode=cls.services["mode"]
|
|
||||||
)
|
|
||||||
|
|
||||||
# create a virtual machine which cannot be dynamically scalable
|
|
||||||
cls.virtual_machine_with_service_offering_dynamic_scaling_disabled = VirtualMachine.create(
|
|
||||||
cls.apiclient,
|
|
||||||
cls.services["small"],
|
|
||||||
accountid=cls.account.name,
|
|
||||||
domainid=cls.account.domainid,
|
|
||||||
serviceofferingid=cls.small_offering_dynamic_scaling_disabled.id,
|
|
||||||
mode=cls.services["mode"]
|
|
||||||
)
|
|
||||||
|
|
||||||
# create a virtual machine which cannot be dynamically scalable
|
|
||||||
cls.virtual_machine_not_dynamically_scalable = VirtualMachine.create(
|
|
||||||
cls.apiclient,
|
|
||||||
cls.services["small"],
|
|
||||||
accountid=cls.account.name,
|
|
||||||
domainid=cls.account.domainid,
|
|
||||||
serviceofferingid=cls.small_offering.id,
|
|
||||||
mode=cls.services["mode"],
|
|
||||||
dynamicscalingenabled=False
|
|
||||||
)
|
|
||||||
|
|
||||||
cls._cleanup = [
|
cls._cleanup = [
|
||||||
cls.small_offering,
|
cls.small_offering,
|
||||||
cls.big_offering,
|
cls.big_offering,
|
||||||
@ -170,6 +147,11 @@ class TestScaleVm(cloudstackTestCase):
|
|||||||
name="enable.dynamic.scale.vm",
|
name="enable.dynamic.scale.vm",
|
||||||
value="false"
|
value="false"
|
||||||
)
|
)
|
||||||
|
Configurations.update(
|
||||||
|
cls.apiclient,
|
||||||
|
name="allow.diskOffering.change.during.scale.vm",
|
||||||
|
value="false"
|
||||||
|
)
|
||||||
super(TestScaleVm,cls).tearDownClass()
|
super(TestScaleVm,cls).tearDownClass()
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -177,6 +159,7 @@ class TestScaleVm(cloudstackTestCase):
|
|||||||
self.apiclient = self.testClient.getApiClient()
|
self.apiclient = self.testClient.getApiClient()
|
||||||
self.dbclient = self.testClient.getDbConnection()
|
self.dbclient = self.testClient.getDbConnection()
|
||||||
self.cleanup = []
|
self.cleanup = []
|
||||||
|
self.services["disk_offering"]["disksize"] = 2
|
||||||
|
|
||||||
if self.unsupportedHypervisor:
|
if self.unsupportedHypervisor:
|
||||||
self.skipTest("Skipping test because unsupported hypervisor\
|
self.skipTest("Skipping test because unsupported hypervisor\
|
||||||
@ -199,6 +182,9 @@ class TestScaleVm(cloudstackTestCase):
|
|||||||
|
|
||||||
return ssh_client
|
return ssh_client
|
||||||
|
|
||||||
|
def is_host_xcpng8(self, hostname):
|
||||||
|
return type(hostname) == list and len(hostname) > 0 and 'XCP-ng 8' in hostname[0]
|
||||||
|
|
||||||
@attr(hypervisor="xenserver")
|
@attr(hypervisor="xenserver")
|
||||||
@attr(tags=["advanced", "basic"], required_hardware="false")
|
@attr(tags=["advanced", "basic"], required_hardware="false")
|
||||||
def test_01_scale_vm(self):
|
def test_01_scale_vm(self):
|
||||||
@ -216,6 +202,17 @@ class TestScaleVm(cloudstackTestCase):
|
|||||||
# scaling is not
|
# scaling is not
|
||||||
# guaranteed until tools are installed, vm rebooted
|
# guaranteed until tools are installed, vm rebooted
|
||||||
|
|
||||||
|
# create a virtual machine
|
||||||
|
self.virtual_machine = VirtualMachine.create(
|
||||||
|
self.apiclient,
|
||||||
|
self.services["small"],
|
||||||
|
accountid=self.account.name,
|
||||||
|
domainid=self.account.domainid,
|
||||||
|
serviceofferingid=self.small_offering.id,
|
||||||
|
mode=self.services["mode"]
|
||||||
|
)
|
||||||
|
self.cleanup.append(self.virtual_machine)
|
||||||
|
|
||||||
# If hypervisor is Vmware, then check if
|
# If hypervisor is Vmware, then check if
|
||||||
# the vmware tools are installed and the process is running
|
# the vmware tools are installed and the process is running
|
||||||
# Vmware tools are necessary for scale VM operation
|
# Vmware tools are necessary for scale VM operation
|
||||||
@ -227,6 +224,7 @@ class TestScaleVm(cloudstackTestCase):
|
|||||||
if not "running" in result:
|
if not "running" in result:
|
||||||
self.skipTest("Skipping scale VM operation because\
|
self.skipTest("Skipping scale VM operation because\
|
||||||
VMware tools are not installed on the VM")
|
VMware tools are not installed on the VM")
|
||||||
|
res = None
|
||||||
if self.hypervisor.lower() != 'simulator':
|
if self.hypervisor.lower() != 'simulator':
|
||||||
hostid = self.virtual_machine.hostid
|
hostid = self.virtual_machine.hostid
|
||||||
host = Host.list(
|
host = Host.list(
|
||||||
@ -251,14 +249,27 @@ class TestScaleVm(cloudstackTestCase):
|
|||||||
self.apiclient,
|
self.apiclient,
|
||||||
isdynamicallyscalable='true')
|
isdynamicallyscalable='true')
|
||||||
|
|
||||||
|
if self.is_host_xcpng8(res):
|
||||||
|
self.debug("Only scaling for CPU for XCP-ng 8")
|
||||||
|
offering_data = self.services["service_offerings"]["big"]
|
||||||
|
offering_data["cpunumber"] = 2
|
||||||
|
offering_data["memory"] = self.virtual_machine.memory
|
||||||
|
self.bigger_offering = ServiceOffering.create(
|
||||||
|
self.apiclient,
|
||||||
|
offering_data
|
||||||
|
)
|
||||||
|
self.cleanup.append(self.bigger_offering)
|
||||||
|
else:
|
||||||
|
self.bigger_offering = self.big_offering
|
||||||
|
|
||||||
self.debug("Scaling VM-ID: %s to service offering: %s and state %s" % (
|
self.debug("Scaling VM-ID: %s to service offering: %s and state %s" % (
|
||||||
self.virtual_machine.id,
|
self.virtual_machine.id,
|
||||||
self.big_offering.id,
|
self.bigger_offering.id,
|
||||||
self.virtual_machine.state
|
self.virtual_machine.state
|
||||||
))
|
))
|
||||||
|
|
||||||
cmd = scaleVirtualMachine.scaleVirtualMachineCmd()
|
cmd = scaleVirtualMachine.scaleVirtualMachineCmd()
|
||||||
cmd.serviceofferingid = self.big_offering.id
|
cmd.serviceofferingid = self.bigger_offering.id
|
||||||
cmd.id = self.virtual_machine.id
|
cmd.id = self.virtual_machine.id
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -297,11 +308,11 @@ class TestScaleVm(cloudstackTestCase):
|
|||||||
offering %s and the response says %s" %
|
offering %s and the response says %s" %
|
||||||
(self.virtual_machine.id,
|
(self.virtual_machine.id,
|
||||||
self.virtual_machine.serviceofferingid,
|
self.virtual_machine.serviceofferingid,
|
||||||
self.big_offering.id,
|
self.bigger_offering.id,
|
||||||
vm_response.serviceofferingid))
|
vm_response.serviceofferingid))
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
vm_response.serviceofferingid,
|
vm_response.serviceofferingid,
|
||||||
self.big_offering.id,
|
self.bigger_offering.id,
|
||||||
"Check service offering of the VM"
|
"Check service offering of the VM"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -313,7 +324,7 @@ class TestScaleVm(cloudstackTestCase):
|
|||||||
return
|
return
|
||||||
|
|
||||||
@attr(tags=["advanced", "basic"], required_hardware="false")
|
@attr(tags=["advanced", "basic"], required_hardware="false")
|
||||||
def test_02_scale_vm(self):
|
def test_02_scale_vm_negative_offering_disable_scaling(self):
|
||||||
"""Test scale virtual machine which is created from a service offering for which dynamicscalingenabled is false. Scaling operation should fail.
|
"""Test scale virtual machine which is created from a service offering for which dynamicscalingenabled is false. Scaling operation should fail.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -325,6 +336,17 @@ class TestScaleVm(cloudstackTestCase):
|
|||||||
# scaling is not
|
# scaling is not
|
||||||
# guaranteed until tools are installed, vm rebooted
|
# guaranteed until tools are installed, vm rebooted
|
||||||
|
|
||||||
|
# create a virtual machine which cannot be dynamically scalable
|
||||||
|
self.virtual_machine_with_service_offering_dynamic_scaling_disabled = VirtualMachine.create(
|
||||||
|
self.apiclient,
|
||||||
|
self.services["small"],
|
||||||
|
accountid=self.account.name,
|
||||||
|
domainid=self.account.domainid,
|
||||||
|
serviceofferingid=self.small_offering_dynamic_scaling_disabled.id,
|
||||||
|
mode=self.services["mode"]
|
||||||
|
)
|
||||||
|
self.cleanup.append(self.virtual_machine_with_service_offering_dynamic_scaling_disabled)
|
||||||
|
|
||||||
# If hypervisor is Vmware, then check if
|
# If hypervisor is Vmware, then check if
|
||||||
# the vmware tools are installed and the process is running
|
# the vmware tools are installed and the process is running
|
||||||
# Vmware tools are necessary for scale VM operation
|
# Vmware tools are necessary for scale VM operation
|
||||||
@ -368,7 +390,7 @@ class TestScaleVm(cloudstackTestCase):
|
|||||||
self.debug("Scaling VM-ID: %s to service offering: %s for which dynamic scaling is disabled and VM state %s" % (
|
self.debug("Scaling VM-ID: %s to service offering: %s for which dynamic scaling is disabled and VM state %s" % (
|
||||||
self.virtual_machine_with_service_offering_dynamic_scaling_disabled.id,
|
self.virtual_machine_with_service_offering_dynamic_scaling_disabled.id,
|
||||||
self.big_offering_dynamic_scaling_disabled.id,
|
self.big_offering_dynamic_scaling_disabled.id,
|
||||||
self.virtual_machine.state
|
self.virtual_machine_with_service_offering_dynamic_scaling_disabled.state
|
||||||
))
|
))
|
||||||
|
|
||||||
cmd = scaleVirtualMachine.scaleVirtualMachineCmd()
|
cmd = scaleVirtualMachine.scaleVirtualMachineCmd()
|
||||||
@ -388,7 +410,7 @@ class TestScaleVm(cloudstackTestCase):
|
|||||||
self.debug("Scaling VM-ID: %s to service offering: %s for which dynamic scaling is enabled and VM state %s" % (
|
self.debug("Scaling VM-ID: %s to service offering: %s for which dynamic scaling is enabled and VM state %s" % (
|
||||||
self.virtual_machine_with_service_offering_dynamic_scaling_disabled.id,
|
self.virtual_machine_with_service_offering_dynamic_scaling_disabled.id,
|
||||||
self.big_offering.id,
|
self.big_offering.id,
|
||||||
self.virtual_machine.state
|
self.virtual_machine_with_service_offering_dynamic_scaling_disabled.state
|
||||||
))
|
))
|
||||||
|
|
||||||
cmd = scaleVirtualMachine.scaleVirtualMachineCmd()
|
cmd = scaleVirtualMachine.scaleVirtualMachineCmd()
|
||||||
@ -408,7 +430,7 @@ class TestScaleVm(cloudstackTestCase):
|
|||||||
return
|
return
|
||||||
|
|
||||||
@attr(tags=["advanced", "basic"], required_hardware="false")
|
@attr(tags=["advanced", "basic"], required_hardware="false")
|
||||||
def test_03_scale_vm(self):
|
def test_03_scale_vm_negative_vm_disable_scaling(self):
|
||||||
"""Test scale virtual machine which is not dynamically scalable to a service offering. Scaling operation should fail.
|
"""Test scale virtual machine which is not dynamically scalable to a service offering. Scaling operation should fail.
|
||||||
"""
|
"""
|
||||||
# Validate the following
|
# Validate the following
|
||||||
@ -422,6 +444,18 @@ class TestScaleVm(cloudstackTestCase):
|
|||||||
# scaling is not
|
# scaling is not
|
||||||
# guaranteed until tools are installed, vm rebooted
|
# guaranteed until tools are installed, vm rebooted
|
||||||
|
|
||||||
|
# create a virtual machine which cannot be dynamically scalable
|
||||||
|
self.virtual_machine_not_dynamically_scalable = VirtualMachine.create(
|
||||||
|
self.apiclient,
|
||||||
|
self.services["small"],
|
||||||
|
accountid=self.account.name,
|
||||||
|
domainid=self.account.domainid,
|
||||||
|
serviceofferingid=self.small_offering.id,
|
||||||
|
mode=self.services["mode"],
|
||||||
|
dynamicscalingenabled=False
|
||||||
|
)
|
||||||
|
self.cleanup.append(self.virtual_machine_not_dynamically_scalable)
|
||||||
|
|
||||||
# If hypervisor is Vmware, then check if
|
# If hypervisor is Vmware, then check if
|
||||||
# the vmware tools are installed and the process is running
|
# the vmware tools are installed and the process is running
|
||||||
# Vmware tools are necessary for scale VM operation
|
# Vmware tools are necessary for scale VM operation
|
||||||
@ -463,7 +497,7 @@ class TestScaleVm(cloudstackTestCase):
|
|||||||
self.debug("Scaling VM-ID: %s to service offering: %s for which dynamic scaling is enabled and VM state %s" % (
|
self.debug("Scaling VM-ID: %s to service offering: %s for which dynamic scaling is enabled and VM state %s" % (
|
||||||
self.virtual_machine_not_dynamically_scalable.id,
|
self.virtual_machine_not_dynamically_scalable.id,
|
||||||
self.big_offering.id,
|
self.big_offering.id,
|
||||||
self.virtual_machine.state
|
self.virtual_machine_not_dynamically_scalable.state
|
||||||
))
|
))
|
||||||
|
|
||||||
cmd = scaleVirtualMachine.scaleVirtualMachineCmd()
|
cmd = scaleVirtualMachine.scaleVirtualMachineCmd()
|
||||||
@ -481,3 +515,386 @@ class TestScaleVm(cloudstackTestCase):
|
|||||||
self.fail("Expected an exception to be thrown, failing")
|
self.fail("Expected an exception to be thrown, failing")
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@attr(hypervisor="xenserver")
|
||||||
|
@attr(tags=["advanced", "basic"], required_hardware="false")
|
||||||
|
def test_04_scale_vm_with_user_account(self):
|
||||||
|
"""Test scale virtual machine under useraccount
|
||||||
|
"""
|
||||||
|
# Validate the following
|
||||||
|
# Create a user Account and create a VM in it.
|
||||||
|
# Scale up the vm and see if it scales to the new svc offering
|
||||||
|
|
||||||
|
# Create an user account
|
||||||
|
self.userAccount = Account.create(
|
||||||
|
self.apiclient,
|
||||||
|
self.services["account"],
|
||||||
|
admin=False,
|
||||||
|
domainid=self.domain.id
|
||||||
|
)
|
||||||
|
|
||||||
|
self.cleanup.append(self.userAccount)
|
||||||
|
# Create user api client of the user account
|
||||||
|
self.userapiclient = self.testClient.getUserApiClient(
|
||||||
|
UserName=self.userAccount.name,
|
||||||
|
DomainName=self.userAccount.domain
|
||||||
|
)
|
||||||
|
|
||||||
|
# create a virtual machine
|
||||||
|
self.virtual_machine_in_user_account = VirtualMachine.create(
|
||||||
|
self.userapiclient,
|
||||||
|
self.services["small"],
|
||||||
|
accountid=self.userAccount.name,
|
||||||
|
domainid=self.userAccount.domainid,
|
||||||
|
serviceofferingid=self.small_offering.id,
|
||||||
|
mode=self.services["mode"]
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.hypervisor.lower() == "vmware":
|
||||||
|
sshClient = self.virtual_machine_in_user_account.get_ssh_client()
|
||||||
|
result = str(
|
||||||
|
sshClient.execute("service vmware-tools status")).lower()
|
||||||
|
self.debug("and result is: %s" % result)
|
||||||
|
if not "running" in result:
|
||||||
|
self.skipTest("Skipping scale VM operation because\
|
||||||
|
VMware tools are not installed on the VM")
|
||||||
|
res = None
|
||||||
|
if self.hypervisor.lower() != 'simulator':
|
||||||
|
list_vm_response = VirtualMachine.list(
|
||||||
|
self.apiclient,
|
||||||
|
id=self.virtual_machine_in_user_account.id
|
||||||
|
)[0]
|
||||||
|
hostid = list_vm_response.hostid
|
||||||
|
host = Host.list(
|
||||||
|
self.apiclient,
|
||||||
|
zoneid=self.zone.id,
|
||||||
|
hostid=hostid,
|
||||||
|
type='Routing'
|
||||||
|
)[0]
|
||||||
|
|
||||||
|
try:
|
||||||
|
username = self.hostConfig["username"]
|
||||||
|
password = self.hostConfig["password"]
|
||||||
|
ssh_client = self.get_ssh_client(host.ipaddress, username, password)
|
||||||
|
res = ssh_client.execute("hostnamectl | grep 'Operating System' | cut -d':' -f2")
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if 'XenServer' in res[0]:
|
||||||
|
self.skipTest("Skipping test for XenServer as it's License does not allow scaling")
|
||||||
|
|
||||||
|
self.virtual_machine_in_user_account.update(
|
||||||
|
self.userapiclient,
|
||||||
|
isdynamicallyscalable='true')
|
||||||
|
|
||||||
|
if self.is_host_xcpng8(res):
|
||||||
|
self.debug("Only scaling for CPU for XCP-ng 8")
|
||||||
|
offering_data = self.services["service_offerings"]["big"]
|
||||||
|
offering_data["cpunumber"] = 2
|
||||||
|
offering_data["memory"] = self.virtual_machine_in_user_account.memory
|
||||||
|
self.bigger_offering = ServiceOffering.create(
|
||||||
|
self.apiclient,
|
||||||
|
offering_data
|
||||||
|
)
|
||||||
|
self.cleanup.append(self.bigger_offering)
|
||||||
|
else:
|
||||||
|
self.bigger_offering = self.big_offering
|
||||||
|
|
||||||
|
self.debug("Scaling VM-ID: %s to service offering: %s and state %s" % (
|
||||||
|
self.virtual_machine_in_user_account.id,
|
||||||
|
self.bigger_offering.id,
|
||||||
|
self.virtual_machine_in_user_account.state
|
||||||
|
))
|
||||||
|
|
||||||
|
cmd = scaleVirtualMachine.scaleVirtualMachineCmd()
|
||||||
|
cmd.serviceofferingid = self.bigger_offering.id
|
||||||
|
cmd.id = self.virtual_machine_in_user_account.id
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.userapiclient.scaleVirtualMachine(cmd)
|
||||||
|
except Exception as e:
|
||||||
|
if "LicenceRestriction" in str(e):
|
||||||
|
self.skipTest("Your XenServer License does not allow scaling")
|
||||||
|
else:
|
||||||
|
self.fail("Scaling failed with the following exception: " + str(e))
|
||||||
|
|
||||||
|
list_vm_response = VirtualMachine.list(
|
||||||
|
self.userapiclient,
|
||||||
|
id=self.virtual_machine_in_user_account.id
|
||||||
|
)
|
||||||
|
|
||||||
|
vm_response = list_vm_response[0]
|
||||||
|
|
||||||
|
self.debug(
|
||||||
|
"Scaling VM-ID: %s from service offering: %s to new service\
|
||||||
|
offering %s and the response says %s" %
|
||||||
|
(self.virtual_machine_in_user_account.id,
|
||||||
|
self.virtual_machine_in_user_account.serviceofferingid,
|
||||||
|
self.bigger_offering.id,
|
||||||
|
vm_response.serviceofferingid))
|
||||||
|
self.assertEqual(
|
||||||
|
vm_response.serviceofferingid,
|
||||||
|
self.bigger_offering.id,
|
||||||
|
"Check service offering of the VM"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
vm_response.state,
|
||||||
|
'Running',
|
||||||
|
"Check the state of VM"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
@attr(hypervisor="xenserver")
|
||||||
|
@attr(tags=["advanced", "basic"], required_hardware="false")
|
||||||
|
def test_05_scale_vm_dont_allow_disk_offering_change(self):
|
||||||
|
"""Test scale virtual machine with disk offering changes
|
||||||
|
"""
|
||||||
|
# Validate the following two cases
|
||||||
|
|
||||||
|
# 1
|
||||||
|
# create serviceoffering1 with diskoffering1
|
||||||
|
# create serviceoffering2 with diskoffering2
|
||||||
|
# create a VM with serviceoffering1
|
||||||
|
# Scale up the vm to serviceoffering2
|
||||||
|
# Check disk offering of root volume to be diskoffering1 since setting allow.diskOffering.change.during.scale.vm is false
|
||||||
|
|
||||||
|
# 2
|
||||||
|
# create serviceoffering3 with diskoffering3
|
||||||
|
# update setting allow.diskOffering.change.during.scale.vm to true
|
||||||
|
# scale up the VM to serviceoffering3
|
||||||
|
# Check disk offering of root volume to be diskoffering3 since setting allow.diskOffering.change.during.scale.vm is true
|
||||||
|
|
||||||
|
self.disk_offering1 = DiskOffering.create(
|
||||||
|
self.apiclient,
|
||||||
|
self.services["disk_offering"],
|
||||||
|
)
|
||||||
|
self._cleanup.append(self.disk_offering1)
|
||||||
|
offering_data = {
|
||||||
|
'displaytext': 'ServiceOffering1WithDiskOffering1',
|
||||||
|
'cpuspeed': 500,
|
||||||
|
'cpunumber': 1,
|
||||||
|
'name': 'ServiceOffering1WithDiskOffering1',
|
||||||
|
'memory': 512,
|
||||||
|
'diskofferingid': self.disk_offering1.id
|
||||||
|
}
|
||||||
|
|
||||||
|
self.ServiceOffering1WithDiskOffering1 = ServiceOffering.create(
|
||||||
|
self.apiclient,
|
||||||
|
offering_data,
|
||||||
|
)
|
||||||
|
self._cleanup.append(self.ServiceOffering1WithDiskOffering1)
|
||||||
|
|
||||||
|
# create a virtual machine
|
||||||
|
self.virtual_machine_test = VirtualMachine.create(
|
||||||
|
self.apiclient,
|
||||||
|
self.services["small"],
|
||||||
|
accountid=self.account.name,
|
||||||
|
domainid=self.account.domainid,
|
||||||
|
serviceofferingid=self.ServiceOffering1WithDiskOffering1.id,
|
||||||
|
mode=self.services["mode"]
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.hypervisor.lower() == "vmware":
|
||||||
|
sshClient = self.virtual_machine_test.get_ssh_client()
|
||||||
|
result = str(
|
||||||
|
sshClient.execute("service vmware-tools status")).lower()
|
||||||
|
self.debug("and result is: %s" % result)
|
||||||
|
if not "running" in result:
|
||||||
|
self.skipTest("Skipping scale VM operation because\
|
||||||
|
VMware tools are not installed on the VM")
|
||||||
|
res = None
|
||||||
|
if self.hypervisor.lower() != 'simulator':
|
||||||
|
hostid = self.virtual_machine_test.hostid
|
||||||
|
host = Host.list(
|
||||||
|
self.apiclient,
|
||||||
|
zoneid=self.zone.id,
|
||||||
|
hostid=hostid,
|
||||||
|
type='Routing'
|
||||||
|
)[0]
|
||||||
|
|
||||||
|
try:
|
||||||
|
username = self.hostConfig["username"]
|
||||||
|
password = self.hostConfig["password"]
|
||||||
|
ssh_client = self.get_ssh_client(host.ipaddress, username, password)
|
||||||
|
res = ssh_client.execute("hostnamectl | grep 'Operating System' | cut -d':' -f2")
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if 'XenServer' in res[0]:
|
||||||
|
self.skipTest("Skipping test for XenServer as it's License does not allow scaling")
|
||||||
|
|
||||||
|
self.virtual_machine_test.update(
|
||||||
|
self.apiclient,
|
||||||
|
isdynamicallyscalable='true')
|
||||||
|
|
||||||
|
self.disk_offering2 = DiskOffering.create(
|
||||||
|
self.apiclient,
|
||||||
|
self.services["disk_offering"],
|
||||||
|
)
|
||||||
|
self._cleanup.append(self.disk_offering2)
|
||||||
|
offering_data = {
|
||||||
|
'displaytext': 'ServiceOffering2WithDiskOffering2',
|
||||||
|
'cpuspeed': 1000,
|
||||||
|
'cpunumber': 2,
|
||||||
|
'name': 'ServiceOffering2WithDiskOffering2',
|
||||||
|
'memory': 1024,
|
||||||
|
'diskofferingid': self.disk_offering2.id
|
||||||
|
}
|
||||||
|
if self.is_host_xcpng8(res):
|
||||||
|
self.debug("Only scaling for CPU for XCP-ng 8")
|
||||||
|
offering_data["memory"] = self.virtual_machine_test.memory
|
||||||
|
|
||||||
|
self.ServiceOffering2WithDiskOffering2 = ServiceOffering.create(
|
||||||
|
self.apiclient,
|
||||||
|
offering_data,
|
||||||
|
)
|
||||||
|
self._cleanup.append(self.ServiceOffering2WithDiskOffering2)
|
||||||
|
|
||||||
|
self.debug("Scaling VM-ID: %s to service offering: %s and state %s" % (
|
||||||
|
self.virtual_machine_test.id,
|
||||||
|
self.ServiceOffering2WithDiskOffering2.id,
|
||||||
|
self.virtual_machine_test.state
|
||||||
|
))
|
||||||
|
|
||||||
|
cmd = scaleVirtualMachine.scaleVirtualMachineCmd()
|
||||||
|
cmd.serviceofferingid = self.ServiceOffering2WithDiskOffering2.id
|
||||||
|
cmd.id = self.virtual_machine_test.id
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.apiclient.scaleVirtualMachine(cmd)
|
||||||
|
except Exception as e:
|
||||||
|
if "LicenceRestriction" in str(e):
|
||||||
|
self.skipTest("Your XenServer License does not allow scaling")
|
||||||
|
else:
|
||||||
|
self.fail("Scaling failed with the following exception: " + str(e))
|
||||||
|
|
||||||
|
list_vm_response = VirtualMachine.list(
|
||||||
|
self.apiclient,
|
||||||
|
id=self.virtual_machine_test.id
|
||||||
|
)
|
||||||
|
|
||||||
|
vm_response = list_vm_response[0]
|
||||||
|
|
||||||
|
self.debug(
|
||||||
|
"Scaling VM-ID: %s from service offering: %s to new service\
|
||||||
|
offering %s and the response says %s" %
|
||||||
|
(self.virtual_machine_test.id,
|
||||||
|
self.virtual_machine_test.serviceofferingid,
|
||||||
|
self.ServiceOffering2WithDiskOffering2.id,
|
||||||
|
vm_response.serviceofferingid))
|
||||||
|
|
||||||
|
vm_response = list_vm_response[0]
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
vm_response.serviceofferingid,
|
||||||
|
self.ServiceOffering2WithDiskOffering2.id,
|
||||||
|
"Check service offering of the VM"
|
||||||
|
)
|
||||||
|
|
||||||
|
volume_response = Volume.list(
|
||||||
|
self.apiclient,
|
||||||
|
virtualmachineid=self.virtual_machine_test.id,
|
||||||
|
listall=True
|
||||||
|
)[0]
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
volume_response.diskofferingid,
|
||||||
|
self.disk_offering1.id,
|
||||||
|
"Check disk offering of the VM, this should not change since allow.diskOffering.change.during.scale.vm is false"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Do same scale vm operation with allow.diskOffering.change.during.scale.vm value to true
|
||||||
|
if self.hypervisor.lower() in ['simulator']:
|
||||||
|
self.debug("Simulator doesn't support changing disk offering, volume resize")
|
||||||
|
return
|
||||||
|
disk_offering_data = self.services["disk_offering"]
|
||||||
|
if self.hypervisor.lower() in ['xenserver']:
|
||||||
|
self.debug("For hypervisor %s, do not resize volume and just change try to change the disk offering")
|
||||||
|
volume_response = Volume.list(
|
||||||
|
self.apiclient,
|
||||||
|
virtualmachineid=self.virtual_machine_test.id,
|
||||||
|
listall=True
|
||||||
|
)[0]
|
||||||
|
disk_offering_data["disksize"] = int(volume_response.size / (1024 ** 3))
|
||||||
|
self.disk_offering3 = DiskOffering.create(
|
||||||
|
self.apiclient,
|
||||||
|
disk_offering_data,
|
||||||
|
)
|
||||||
|
self._cleanup.append(self.disk_offering3)
|
||||||
|
offering_data = {
|
||||||
|
'displaytext': 'ServiceOffering3WithDiskOffering3',
|
||||||
|
'cpuspeed': 1500,
|
||||||
|
'cpunumber': 2,
|
||||||
|
'name': 'ServiceOffering3WithDiskOffering3',
|
||||||
|
'memory': 1024,
|
||||||
|
'diskofferingid': self.disk_offering3.id
|
||||||
|
}
|
||||||
|
if self.is_host_xcpng8(res):
|
||||||
|
self.debug("Only scaling for CPU for XCP-ng 8")
|
||||||
|
offering_data["memory"] = vm_response.memory
|
||||||
|
|
||||||
|
self.ServiceOffering3WithDiskOffering3 = ServiceOffering.create(
|
||||||
|
self.apiclient,
|
||||||
|
offering_data,
|
||||||
|
)
|
||||||
|
self._cleanup.append(self.ServiceOffering3WithDiskOffering3)
|
||||||
|
|
||||||
|
Configurations.update(
|
||||||
|
self.apiclient,
|
||||||
|
name="allow.diskOffering.change.during.scale.vm",
|
||||||
|
value="true"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.debug("Scaling VM-ID: %s to service offering: %s and state %s" % (
|
||||||
|
self.virtual_machine_test.id,
|
||||||
|
self.ServiceOffering3WithDiskOffering3.id,
|
||||||
|
self.virtual_machine_test.state
|
||||||
|
))
|
||||||
|
|
||||||
|
cmd = scaleVirtualMachine.scaleVirtualMachineCmd()
|
||||||
|
cmd.serviceofferingid = self.ServiceOffering3WithDiskOffering3.id
|
||||||
|
cmd.id = self.virtual_machine_test.id
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.apiclient.scaleVirtualMachine(cmd)
|
||||||
|
except Exception as e:
|
||||||
|
if "LicenceRestriction" in str(e):
|
||||||
|
self.skipTest("Your XenServer License does not allow scaling")
|
||||||
|
else:
|
||||||
|
self.fail("Scaling failed with the following exception: " + str(e))
|
||||||
|
|
||||||
|
list_vm_response = VirtualMachine.list(
|
||||||
|
self.apiclient,
|
||||||
|
id=self.virtual_machine_test.id
|
||||||
|
)
|
||||||
|
|
||||||
|
vm_response = list_vm_response[0]
|
||||||
|
|
||||||
|
self.debug(
|
||||||
|
"Scaling VM-ID: %s from service offering: %s to new service\
|
||||||
|
offering %s and the response says %s" %
|
||||||
|
(self.virtual_machine_test.id,
|
||||||
|
self.virtual_machine_test.serviceofferingid,
|
||||||
|
self.ServiceOffering3WithDiskOffering3.id,
|
||||||
|
vm_response.serviceofferingid))
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
vm_response.serviceofferingid,
|
||||||
|
self.ServiceOffering3WithDiskOffering3.id,
|
||||||
|
"Check service offering of the VM"
|
||||||
|
)
|
||||||
|
|
||||||
|
volume_response = Volume.list(
|
||||||
|
self.apiclient,
|
||||||
|
virtualmachineid=self.virtual_machine_test.id,
|
||||||
|
listall=True
|
||||||
|
)[0]
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
volume_response.diskofferingid,
|
||||||
|
self.disk_offering3.id,
|
||||||
|
"Check disk offering of the VM, this should change since allow.diskOffering.change.during.scale.vm is true"
|
||||||
|
)
|
||||||
|
|
||||||
|
return
|
||||||
|
|||||||
@ -103,7 +103,8 @@ export default {
|
|||||||
wrapperCol: { span: 12 }
|
wrapperCol: { span: 12 }
|
||||||
},
|
},
|
||||||
validStatus: '',
|
validStatus: '',
|
||||||
validMessage: ''
|
validMessage: '',
|
||||||
|
formModel: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user