diff --git a/api/src/main/java/com/cloud/configuration/Resource.java b/api/src/main/java/com/cloud/configuration/Resource.java index 76f2930e6150..fefeeb15ef55 100644 --- a/api/src/main/java/com/cloud/configuration/Resource.java +++ b/api/src/main/java/com/cloud/configuration/Resource.java @@ -18,9 +18,10 @@ public interface Resource { - public static final short RESOURCE_UNLIMITED = -1; + short RESOURCE_UNLIMITED = -1; + String UNLIMITED = "Unlimited"; - public enum ResourceType { // Primary and Secondary storage are allocated_storage and not the physical storage. + enum ResourceType { // Primary and Secondary storage are allocated_storage and not the physical storage. user_vm("user_vm", 0, ResourceOwnerType.Account, ResourceOwnerType.Domain), public_ip("public_ip", 1, ResourceOwnerType.Account, ResourceOwnerType.Domain), volume("volume", 2, ResourceOwnerType.Account, ResourceOwnerType.Domain), diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java index 3875d8155c05..8c23d61f6971 100644 --- a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -20,6 +20,7 @@ import javax.inject.Inject; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.dc.VsphereStoragePolicyVO; import com.cloud.dc.dao.VsphereStoragePolicyDao; import com.cloud.service.dao.ServiceOfferingDetailsDao; @@ -28,6 +29,7 @@ import com.cloud.storage.VolumeDetailVO; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDetailsDao; +import com.cloud.user.ResourceLimitService; import com.cloud.vm.VmDetailConstants; import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao; @@ -88,6 +90,8 @@ public class VolumeObject implements VolumeInfo { @Inject ObjectInDataStoreManager objectInStoreMgr; @Inject + ResourceLimitService resourceLimitMgr; + @Inject VMInstanceDao vmInstanceDao; @Inject DiskOfferingDao diskOfferingDao; @@ -678,6 +682,22 @@ protected void updateVolumeInfo(VolumeObjectTO newVolume, VolumeVO volumeVo, boo s_logger.debug(String.format("Updated %s from %s to %s ", volumeVo.getVolumeDescription(), previousValues, newValues)); } + protected void updateResourceCount(VolumeObjectTO newVolume, VolumeVO oldVolume) { + if (newVolume == null || newVolume.getSize() == null || oldVolume == null || oldVolume.getSize() == null) { + return; + } + + long newVolumeSize = newVolume.getSize(); + long oldVolumeSize = oldVolume.getSize(); + if (newVolumeSize != oldVolumeSize) { + if (oldVolumeSize < newVolumeSize) { + resourceLimitMgr.incrementResourceCount(oldVolume.getAccountId(), ResourceType.primary_storage, oldVolume.isDisplayVolume(), newVolumeSize - oldVolumeSize); + } else { + resourceLimitMgr.decrementResourceCount(oldVolume.getAccountId(), ResourceType.primary_storage, oldVolume.isDisplayVolume(), oldVolumeSize - newVolumeSize); + } + } + } + protected void handleProcessEventCopyCmdAnswerNotPrimaryStore(VolumeObjectTO newVolume) { VolumeDataStoreVO volStore = volumeStoreDao.findByStoreVolume(dataStore.getId(), getId()); @@ -709,6 +729,7 @@ protected void handleProcessEventAnswer(CreateObjectAnswer createObjectAnswer, b VolumeObjectTO newVolume = (VolumeObjectTO)createObjectAnswer.getData(); VolumeVO volumeVo = volumeDao.findById(getId()); updateVolumeInfo(newVolume, volumeVo, true, setFormat); + updateResourceCount(newVolume, volumeVo); } protected void handleProcessEventAnswer(DownloadAnswer downloadAnswer) { diff --git a/server/src/main/java/com/cloud/api/query/dao/AccountJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/AccountJoinDaoImpl.java index c980ffd3ab60..790758c627fd 100644 --- a/server/src/main/java/com/cloud/api/query/dao/AccountJoinDaoImpl.java +++ b/server/src/main/java/com/cloud/api/query/dao/AccountJoinDaoImpl.java @@ -34,6 +34,7 @@ import com.cloud.api.query.ViewResponseHelper; import com.cloud.api.query.vo.AccountJoinVO; import com.cloud.api.query.vo.UserAccountJoinVO; +import com.cloud.configuration.Resource; import com.cloud.configuration.Resource.ResourceType; import com.cloud.user.Account; import com.cloud.user.AccountManager; @@ -85,9 +86,9 @@ public AccountResponse newAccountResponse(ResponseView view, EnumSet() { @@ -1112,22 +1122,19 @@ public ResourceCountCheckTask() { protected void runInContext() { s_logger.info("Started resource counters recalculation periodic task."); List domains = _domainDao.findImmediateChildrenForParent(Domain.ROOT_DOMAIN); + List accounts = _accountDao.findActiveAccountsForDomain(Domain.ROOT_DOMAIN); - // recalculateDomainResourceCount will take care of re-calculation of resource counts for sub-domains - // and accounts of the sub-domains also. so just loop through immediate children of root domain - for (Domain domain : domains) { - for (ResourceType type : ResourceCount.ResourceType.values()) { - if (type.supportsOwner(ResourceOwnerType.Domain)) { + for (ResourceType type : ResourceCount.ResourceType.values()) { + if (type.supportsOwner(ResourceOwnerType.Domain)) { + recalculateDomainResourceCount(Domain.ROOT_DOMAIN, type); + for (Domain domain : domains) { recalculateDomainResourceCount(domain.getId(), type); } } - } - // run through the accounts in the root domain - List accounts = _accountDao.findActiveAccountsForDomain(Domain.ROOT_DOMAIN); - for (AccountVO account : accounts) { - for (ResourceType type : ResourceCount.ResourceType.values()) { - if (type.supportsOwner(ResourceOwnerType.Account)) { + if (type.supportsOwner(ResourceOwnerType.Account)) { + // run through the accounts in the root domain + for (AccountVO account : accounts) { recalculateAccountResourceCount(account.getId(), type); } } diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index e6726f6977b8..e5a4aaa5c2b8 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -1439,6 +1439,9 @@ private VolumeVO orchestrateResizeVolume(long volumeId, long currentSize, long n final VolumeVO volumeNow = _volsDao.findById(volumeId); if (currentSize == volumeNow.getSize() && currentSize != newSize) { volume.setSize(newSize); + } else if (volumeNow.getSize() != newSize) { + // consider the updated size as the new size + newSize = volumeNow.getSize(); } _volsDao.update(volume.getId(), volume);