From af58284560938f1320296d5e735c8e96175d95cb Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Tue, 8 Feb 2022 13:29:35 +0530 Subject: [PATCH] server,config: respect storage.max.volume.size and make it dynamic (#5857) * server,config: respect storage.max.volume.size and make it dynamic Fixes #5830 * fix test * size change * fix check * server: donot include ISO size while checking volume sizes * revert size check * refactor Signed-off-by: Abhishek Kumar Co-authored-by: sureshanaparti <12028987+sureshanaparti@users.noreply.github.com> --- .../com/cloud/storage/VolumeApiService.java | 2 ++ .../service/VolumeOrchestrationService.java | 7 ++++ .../orchestration/VolumeOrchestrator.java | 25 +++++++------- .../java/com/cloud/configuration/Config.java | 18 +++++----- .../ConfigurationManagerImpl.java | 18 +++++----- .../cloud/storage/VolumeApiServiceImpl.java | 18 +++++----- .../java/com/cloud/vm/UserVmManagerImpl.java | 33 ++++++++++++------- .../com/cloud/vm/UserVmManagerImplTest.java | 23 ++++++++----- 8 files changed, 82 insertions(+), 62 deletions(-) diff --git a/api/src/main/java/com/cloud/storage/VolumeApiService.java b/api/src/main/java/com/cloud/storage/VolumeApiService.java index 6087ece3610..f7543b7ddfb 100644 --- a/api/src/main/java/com/cloud/storage/VolumeApiService.java +++ b/api/src/main/java/com/cloud/storage/VolumeApiService.java @@ -152,4 +152,6 @@ public interface VolumeApiService { Volume destroyVolume(long volumeId, Account caller, boolean expunge, boolean forceExpunge); Volume recoverVolume(long volumeId); + + boolean validateVolumeSizeInBytes(long size); } diff --git a/engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java index c6b96bca3e6..aefe4e47498 100644 --- a/engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java +++ b/engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java @@ -75,6 +75,13 @@ public interface VolumeOrchestrationService { true ); + ConfigKey MaxVolumeSize = new ConfigKey("Storage", + Long.class, + "storage.max.volume.size", + "2000", + "The maximum size for a volume (in GB).", + true); + VolumeInfo moveVolume(VolumeInfo volume, long destPoolDcId, Long destPoolPodId, Long destPoolClusterId, HypervisorType dataDiskHyperType) throws ConcurrentOperationException, StorageUnavailableException; diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java index d88e17d98ec..9c1e998459d 100644 --- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java +++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java @@ -18,10 +18,12 @@ */ package org.apache.cloudstack.engine.orchestration; +import static com.cloud.storage.resource.StorageProcessor.REQUEST_TEMPLATE_RELOAD; import static com.cloud.utils.NumbersUtil.toHumanReadableSize; import java.util.ArrayList; import java.util.Comparator; +import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -35,14 +37,6 @@ import java.util.stream.Collectors; import javax.inject.Inject; import javax.naming.ConfigurationException; -import com.cloud.agent.api.to.DatadiskTO; -import com.cloud.utils.StringUtils; -import com.cloud.vm.SecondaryStorageVmVO; -import com.cloud.vm.UserVmDetailVO; -import com.cloud.vm.VMInstanceVO; -import com.cloud.vm.VmDetailConstants; -import com.cloud.vm.dao.SecondaryStorageVmDao; -import com.cloud.vm.dao.UserVmDetailsDao; import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd; import org.apache.cloudstack.api.command.admin.volume.MigrateVolumeCmdByAdmin; import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd; @@ -84,11 +78,12 @@ import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; -import org.apache.commons.collections.MapUtils; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; import org.apache.log4j.Logger; import com.cloud.agent.api.to.DataTO; +import com.cloud.agent.api.to.DatadiskTO; import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.manager.allocator.PodAllocator; @@ -139,6 +134,7 @@ import com.cloud.user.Account; import com.cloud.user.ResourceLimitService; import com.cloud.uservm.UserVm; import com.cloud.utils.Pair; +import com.cloud.utils.StringUtils; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.EntityManager; @@ -150,21 +146,24 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.utils.fsm.StateMachine2; import com.cloud.vm.DiskProfile; +import com.cloud.vm.SecondaryStorageVmVO; import com.cloud.vm.UserVmCloneSettingVO; +import com.cloud.vm.UserVmDetailVO; import com.cloud.vm.UserVmVO; +import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfileImpl; +import com.cloud.vm.VmDetailConstants; import com.cloud.vm.VmWorkAttachVolume; import com.cloud.vm.VmWorkMigrateVolume; import com.cloud.vm.VmWorkSerializer; import com.cloud.vm.VmWorkTakeVolumeSnapshot; +import com.cloud.vm.dao.SecondaryStorageVmDao; import com.cloud.vm.dao.UserVmCloneSettingDao; import com.cloud.vm.dao.UserVmDao; - -import static com.cloud.storage.resource.StorageProcessor.REQUEST_TEMPLATE_RELOAD; -import java.util.Date; +import com.cloud.vm.dao.UserVmDetailsDao; public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrationService, Configurable { @@ -1749,8 +1748,6 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati return true; } - public static final ConfigKey MaxVolumeSize = new ConfigKey(Long.class, "storage.max.volume.size", "Storage", "2000", "The maximum size for a volume (in GB).", true); - public static final ConfigKey RecreatableSystemVmEnabled = new ConfigKey(Boolean.class, "recreate.systemvm.enabled", "Advanced", "false", "If true, will recreate system vm root disk whenever starting system vm", true); diff --git a/server/src/main/java/com/cloud/configuration/Config.java b/server/src/main/java/com/cloud/configuration/Config.java index 17418d809f6..45f6ced7c41 100644 --- a/server/src/main/java/com/cloud/configuration/Config.java +++ b/server/src/main/java/com/cloud/configuration/Config.java @@ -16,6 +16,15 @@ // under the License. package com.cloud.configuration; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.StringTokenizer; + +import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; +import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; +import org.apache.cloudstack.framework.config.ConfigKey; + import com.cloud.agent.AgentManager; import com.cloud.consoleproxy.ConsoleProxyManager; import com.cloud.ha.HighAvailabilityManager; @@ -29,14 +38,6 @@ import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.template.TemplateManager; import com.cloud.vm.UserVmManager; import com.cloud.vm.snapshot.VMSnapshotManager; -import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; -import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; -import org.apache.cloudstack.framework.config.ConfigKey; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.StringTokenizer; /** * @deprecated use the more dynamic ConfigKey @@ -144,7 +145,6 @@ public enum Config { "60000", "The interval (in milliseconds) when storage stats (per host) are retrieved from agents.", null), - MaxVolumeSize("Storage", ManagementServer.class, Integer.class, "storage.max.volume.size", "2000", "The maximum size for a volume (in GB).", null), StorageCacheReplacementLRUTimeInterval( "Storage", ManagementServer.class, diff --git a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java index 1bcc3d994a7..e5347c4dcc2 100755 --- a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java @@ -43,7 +43,6 @@ import java.util.Vector; import javax.inject.Inject; import javax.naming.ConfigurationException; -import com.googlecode.ipv6.IPv6Address; import org.apache.cloudstack.acl.SecurityChecker; import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroupService; @@ -85,6 +84,7 @@ import org.apache.cloudstack.config.ApiServiceConfiguration; import org.apache.cloudstack.config.Configuration; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; +import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.config.ConfigDepot; @@ -271,6 +271,7 @@ import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; import com.google.common.base.Strings; import com.google.common.collect.Sets; +import com.googlecode.ipv6.IPv6Address; public class ConfigurationManagerImpl extends ManagerBase implements ConfigurationManager, ConfigurationService, Configurable { public static final Logger s_logger = Logger.getLogger(ConfigurationManagerImpl.class); @@ -422,7 +423,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @Inject protected DataCenterLinkLocalIpAddressDao _linkLocalIpAllocDao; - private int _maxVolumeSizeInGb = Integer.parseInt(Config.MaxVolumeSize.getDefaultValue()); private long _defaultPageSize = Long.parseLong(Config.DefaultPageSize.getDefaultValue()); private static final String DOMAIN_NAME_PATTERN = "^((?!-)[A-Za-z0-9-]{1,63}(? configValuesForValidation; @@ -478,9 +478,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @Override public boolean configure(final String name, final Map params) throws ConfigurationException { - final String maxVolumeSizeInGbString = _configDao.getValue(Config.MaxVolumeSize.key()); - _maxVolumeSizeInGb = NumbersUtil.parseInt(maxVolumeSizeInGbString, Integer.parseInt(Config.MaxVolumeSize.getDefaultValue())); - final String defaultPageSizeString = _configDao.getValue(Config.DefaultPageSize.key()); _defaultPageSize = NumbersUtil.parseLong(defaultPageSizeString, Long.parseLong(Config.DefaultPageSize.getDefaultValue())); @@ -2943,6 +2940,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati if (rootDiskSizeInGiB != null && rootDiskSizeInGiB <= 0L) { throw new InvalidParameterValueException(String.format("The Root disk size is of %s GB but it must be greater than 0.", rootDiskSizeInGiB)); } else if (rootDiskSizeInGiB != null) { + long maxVolumeSizeInGb = VolumeOrchestrationService.MaxVolumeSize.value(); + if (rootDiskSizeInGiB > maxVolumeSizeInGb) { + throw new InvalidParameterValueException(String.format("The maximum size for a disk is %d GB.", maxVolumeSizeInGb)); + } long rootDiskSizeInBytes = rootDiskSizeInGiB * GiB_TO_BYTES; offering.setDiskSize(rootDiskSizeInBytes); } @@ -3264,10 +3265,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength, final Integer hypervisorSnapshotReserve, String cacheMode, final Map details, final Long storagePolicyID) { long diskSize = 0;// special case for custom disk offerings + long maxVolumeSizeInGb = VolumeOrchestrationService.MaxVolumeSize.value(); if (numGibibytes != null && numGibibytes <= 0) { - throw new InvalidParameterValueException("Please specify a disk size of at least 1 Gb."); - } else if (numGibibytes != null && numGibibytes > _maxVolumeSizeInGb) { - throw new InvalidParameterValueException("The maximum size for a disk is " + _maxVolumeSizeInGb + " Gb."); + throw new InvalidParameterValueException("Please specify a disk size of at least 1 GB."); + } else if (numGibibytes != null && numGibibytes > maxVolumeSizeInGb) { + throw new InvalidParameterValueException(String.format("The maximum size for a disk is %d GB.", maxVolumeSizeInGb)); } final ProvisioningType typedProvisioningType = ProvisioningType.getProvisioningType(provisioningType); diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index 35de68b43e0..5912ff99271 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -311,7 +311,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic public static final ConfigKey AllowUserExpungeRecoverVolume = new ConfigKey("Advanced", Boolean.class, "allow.user.expunge.recover.volume", "true", "Determines whether users can expunge or recover their volume", true, ConfigKey.Scope.Account); - private long _maxVolumeSizeInGb; private final StateMachine2 _volStateMachine; private static final Set STATES_VOLUME_CANNOT_BE_DESTROYED = new HashSet<>(Arrays.asList(Volume.State.Destroy, Volume.State.Expunging, Volume.State.Expunged, Volume.State.Allocated)); @@ -730,9 +729,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic maxIops = diskOffering.getMaxIops(); } - if (!validateVolumeSizeRange(size)) {// convert size from mb to gb - // for validation - throw new InvalidParameterValueException("Invalid size for custom volume creation: " + size + " ,max volume size is:" + _maxVolumeSizeInGb); + if (!validateVolumeSizeInBytes(size)) { + throw new InvalidParameterValueException(String.format("Invalid size for custom volume creation: %s, max volume size is: %s GB", NumbersUtil.toReadableSize(size), VolumeOrchestrationService.MaxVolumeSize.value())); } } @@ -886,11 +884,13 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic }); } - public boolean validateVolumeSizeRange(long size) { + @Override + public boolean validateVolumeSizeInBytes(long size) { + long maxVolumeSize = VolumeOrchestrationService.MaxVolumeSize.value(); if (size < 0 || (size > 0 && size < (1024 * 1024 * 1024))) { throw new InvalidParameterValueException("Please specify a size of at least 1 GB."); - } else if (size > (_maxVolumeSizeInGb * 1024 * 1024 * 1024)) { - throw new InvalidParameterValueException("Requested volume size is " + size + ", but the maximum size allowed is " + _maxVolumeSizeInGb + " GB."); + } else if (size > (maxVolumeSize * 1024 * 1024 * 1024)) { + throw new InvalidParameterValueException(String.format("Requested volume size is %s, but the maximum size allowed is %d GB.", NumbersUtil.toReadableSize(size), maxVolumeSize)); } return true; @@ -1117,7 +1117,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic } } - if (!validateVolumeSizeRange(newSize)) { + if (!validateVolumeSizeInBytes(newSize)) { throw new InvalidParameterValueException("Requested size out of range"); } @@ -3534,8 +3534,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic @Override public boolean configure(String name, Map params) { - String maxVolumeSizeInGbString = _configDao.getValue(Config.MaxVolumeSize.toString()); - _maxVolumeSizeInGb = NumbersUtil.parseLong(maxVolumeSizeInGbString, 2000); supportingDefaultHV = _hypervisorCapabilitiesDao.getHypervisorsWithDefaultEntries(); return true; } diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 64ddda1c4e5..58ea4e9175e 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.vm; +import static com.cloud.configuration.ConfigurationManagerImpl.VM_USERDATA_MAX_LENGTH; import static com.cloud.utils.NumbersUtil.toHumanReadableSize; import java.io.IOException; @@ -26,6 +27,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; @@ -50,8 +52,6 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; -import com.cloud.network.router.CommandSetupHelper; -import com.cloud.network.router.NetworkHelper; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; @@ -117,6 +117,7 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.apache.cloudstack.utils.bytescale.ByteScaleUtils; import org.apache.commons.codec.binary.Base64; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; @@ -247,6 +248,8 @@ import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.element.UserDataServiceProvider; import com.cloud.network.guru.NetworkGuru; import com.cloud.network.lb.LoadBalancingRulesManager; +import com.cloud.network.router.CommandSetupHelper; +import com.cloud.network.router.NetworkHelper; import com.cloud.network.router.VpcVirtualNetworkApplianceManager; import com.cloud.network.rules.FirewallManager; import com.cloud.network.rules.FirewallRuleVO; @@ -355,10 +358,6 @@ import com.cloud.vm.dao.VMInstanceDao; import com.cloud.vm.snapshot.VMSnapshotManager; import com.cloud.vm.snapshot.VMSnapshotVO; import com.cloud.vm.snapshot.dao.VMSnapshotDao; -import java.util.HashSet; -import org.apache.cloudstack.utils.bytescale.ByteScaleUtils; - -import static com.cloud.configuration.ConfigurationManagerImpl.VM_USERDATA_MAX_LENGTH; public class UserVmManagerImpl extends ManagerBase implements UserVmManager, VirtualMachineGuru, UserVmService, Configurable { private static final Logger s_logger = Logger.getLogger(UserVmManagerImpl.class); @@ -3831,11 +3830,15 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir // check if account/domain is with in resource limits to create a new vm boolean isIso = Storage.ImageFormat.ISO == template.getFormat(); - long size = configureCustomRootDiskSize(customParameters, template, hypervisorType, offering); + long volumesSize = configureCustomRootDiskSize(customParameters, template, hypervisorType, offering); if (diskOfferingId != null) { + long size = 0; DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId); - if (diskOffering != null && diskOffering.isCustomized()) { + if (diskOffering == null) { + throw new InvalidParameterValueException("Specified disk offering cannot be found"); + } + if (diskOffering.isCustomized()) { if (diskSize == null) { throw new InvalidParameterValueException("This disk offering requires a custom size specified"); } @@ -3845,16 +3848,19 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir throw new InvalidParameterValueException("VM Creation failed. Volume size: " + diskSize + "GB is out of allowed range. Max: " + customDiskOfferingMaxSize + " Min:" + customDiskOfferingMinSize); } - size += diskSize * GiB_TO_BYTES; + size = diskSize * GiB_TO_BYTES; + } else { + size = diskOffering.getDiskSize(); } - size += _diskOfferingDao.findById(diskOfferingId).getDiskSize(); + _volumeService.validateVolumeSizeInBytes(size); + volumesSize += size; } if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) { resourceLimitCheck(owner, isDisplayVm, new Long(offering.getCpu()), new Long(offering.getRamSize())); } _resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, (isIso || diskOfferingId == null ? 1 : 2)); - _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, size); + _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumesSize); // verify security group ids if (securityGroupIdList != null) { @@ -4177,6 +4183,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir DiskOfferingVO diskOffering = _diskOfferingDao.findById(serviceOffering.getId()); long rootDiskSizeInBytes = diskOffering.getDiskSize(); if (rootDiskSizeInBytes > 0) { //if the size at DiskOffering is not zero then the Service Offering had it configured, it holds priority over the User custom size + _volumeService.validateVolumeSizeInBytes(rootDiskSizeInBytes); long rootDiskSizeInGiB = rootDiskSizeInBytes / GiB_TO_BYTES; customParameters.put(VmDetailConstants.ROOT_DISK_SIZE, String.valueOf(rootDiskSizeInGiB)); return rootDiskSizeInBytes; @@ -4187,7 +4194,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir if (rootDiskSize <= 0) { throw new InvalidParameterValueException("Root disk size should be a positive number."); } - return rootDiskSize * GiB_TO_BYTES; + rootDiskSize *= GiB_TO_BYTES; + _volumeService.validateVolumeSizeInBytes(rootDiskSize); + return rootDiskSize; } else { // For baremetal, size can be 0 (zero) Long templateSize = _templateDao.findById(template.getId()).getSize(); diff --git a/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java b/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java index a9821094f06..c9460c3400f 100644 --- a/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java +++ b/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java @@ -33,15 +33,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import com.cloud.configuration.Resource; -import com.cloud.hypervisor.Hypervisor; -import com.cloud.storage.DiskOfferingVO; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.DiskOfferingDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.user.ResourceLimitService; -import com.cloud.user.dao.AccountDao; import org.apache.cloudstack.api.BaseCmd.HTTPMethod; import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd; import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd; @@ -59,25 +50,35 @@ import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; import org.powermock.core.classloader.annotations.PrepareForTest; +import com.cloud.configuration.Resource; import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.DataCenterDao; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.hypervisor.Hypervisor; import com.cloud.network.NetworkModel; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkVO; import com.cloud.offering.ServiceOffering; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.GuestOSVO; import com.cloud.storage.Storage; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.VolumeApiService; +import com.cloud.storage.VolumeVO; +import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.GuestOSDao; +import com.cloud.storage.dao.VMTemplateDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; +import com.cloud.user.ResourceLimitService; import com.cloud.user.UserVO; +import com.cloud.user.dao.AccountDao; import com.cloud.uservm.UserVm; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.UserVmDao; @@ -155,6 +156,9 @@ public class UserVmManagerImplTest { @Mock ResourceLimitService resourceLimitMgr; + @Mock + VolumeApiService volumeApiService; + private long vmId = 1l; private static final long GiB_TO_BYTES = 1024 * 1024 * 1024; @@ -480,6 +484,7 @@ public class UserVmManagerImplTest { Mockito.when(diskfferingVo.getDiskSize()).thenReturn(offeringRootDiskSize); + Mockito.when(volumeApiService.validateVolumeSizeInBytes(Mockito.anyLong())).thenReturn(true); long rootDiskSize = userVmManagerImpl.configureCustomRootDiskSize(customParameters, template, Hypervisor.HypervisorType.KVM, offering); Assert.assertEquals(expectedRootDiskSize, rootDiskSize);