CLOUDSTACK-1156: Limit Primary and Secondary storage for domain/accounts

Addition of two new resource types i.e. Primary and Secondary storage space in the existing pool of
    resource types.
    Added methods to set the limits on these resources using updateResourceLimit
    API command and to get a count using updateResourceCount. Also added calls in the
    Templates, Volumes, Snapshots life cycle to check these limits and to increment/decrement the new
    resource types

    Resource Name          :: Resource type number
        Primary Storage               10
        Secondary Storage             11

    Also added jUnit Tests for the same.
Reviewed by : nitin mehta<nitin.mehta@citrix.com>
This commit is contained in:
Sanjay Tripathi 2013-03-29 11:21:10 +05:30 committed by Nitin Mehta
parent d6e11f25ac
commit 18695276f7
32 changed files with 934 additions and 249 deletions

View File

@ -20,7 +20,7 @@ public interface Resource {
public static final short RESOURCE_UNLIMITED = -1;
public enum ResourceType {
public 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),
@ -30,11 +30,14 @@ public interface Resource {
network("network", 6, ResourceOwnerType.Account, ResourceOwnerType.Domain),
vpc("vpc", 7, ResourceOwnerType.Account, ResourceOwnerType.Domain),
cpu("cpu", 8, ResourceOwnerType.Account, ResourceOwnerType.Domain),
memory("memory", 9, ResourceOwnerType.Account, ResourceOwnerType.Domain);
memory("memory", 9, ResourceOwnerType.Account, ResourceOwnerType.Domain),
primary_storage("primary_storage", 10, ResourceOwnerType.Account, ResourceOwnerType.Domain),
secondary_storage("secondary_storage", 11, ResourceOwnerType.Account, ResourceOwnerType.Domain);
private String name;
private ResourceOwnerType[] supportedOwners;
private int ordinal;
public static final long bytesToGiB = 1024 * 1024 * 1024;
ResourceType(String name, int ordinal, ResourceOwnerType... supportedOwners) {
this.name = name;

View File

@ -59,9 +59,10 @@ public interface VolumeApiService {
* @param cmd
* the API command wrapping the criteria
* @return the volume object
* @throws ResourceAllocationException
*/
Volume resizeVolume(ResizeVolumeCmd cmd);
Volume resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationException;
Volume migrateVolume(MigrateVolumeCmd cmd) throws ConcurrentOperationException;
/**

View File

@ -53,7 +53,7 @@ public class UpdateResourceCountCmd extends BaseCmd {
required=true, description="If account parameter specified then updates resource counts for a specified account in this domain else update resource counts for all accounts & child domains in specified domain.")
private Long domainId;
@Parameter(name=ApiConstants.RESOURCE_TYPE, type=CommandType.INTEGER, description= "Type of resource to update. If specifies valid values are 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9. If not specified will update all resource counts" +
@Parameter(name=ApiConstants.RESOURCE_TYPE, type=CommandType.INTEGER, description= "Type of resource to update. If specifies valid values are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 and 11. If not specified will update all resource counts" +
"0 - Instance. Number of instances a user can create. " +
"1 - IP. Number of public IP addresses a user can own. " +
"2 - Volume. Number of disk volumes a user can create." +
@ -63,7 +63,9 @@ public class UpdateResourceCountCmd extends BaseCmd {
"6 - Network. Number of guest network a user can create." +
"7 - VPC. Number of VPC a user can create." +
"8 - CPU. Total number of CPU cores a user can use." +
"9 - Memory. Total Memory (in MB) a user can use." )
"9 - Memory. Total Memory (in MB) a user can use." +
"10 - PrimaryStorage. Total primary storage space (in GiB) a user can use." +
"11 - SecondaryStorage. Total secondary storage space (in GiB) a user can use." )
private Integer resourceType;
@Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.UUID, entityType = ProjectResponse.class,

View File

@ -54,7 +54,7 @@ public class UpdateResourceLimitCmd extends BaseCmd {
@Parameter(name=ApiConstants.MAX, type=CommandType.LONG, description=" Maximum resource limit.")
private Long max;
@Parameter(name=ApiConstants.RESOURCE_TYPE, type=CommandType.INTEGER, required=true, description="Type of resource to update. Values are 0, 1, 2, 3, 4, 6, 7, 8 and 9. 0 - Instance. Number of instances a user can create. " +
@Parameter(name=ApiConstants.RESOURCE_TYPE, type=CommandType.INTEGER, required=true, description="Type of resource to update. Values are 0, 1, 2, 3, 4, 6, 7, 8, 9, 10 and 11. 0 - Instance. Number of instances a user can create. " +
"1 - IP. Number of public IP addresses a user can own. " +
"2 - Volume. Number of disk volumes a user can create." +
"3 - Snapshot. Number of snapshots a user can create." +
@ -62,7 +62,9 @@ public class UpdateResourceLimitCmd extends BaseCmd {
"6 - Network. Number of guest network a user can create." +
"7 - VPC. Number of VPC a user can create." +
"8 - CPU. Total number of CPU cores a user can use." +
"9 - Memory. Total Memory (in MB) a user can use." )
"9 - Memory. Total Memory (in MB) a user can use." +
"10 - PrimaryStorage. Total primary storage space (in GiB) a user can use." +
"11 - SecondaryStorage. Total secondary storage space (in GiB) a user can use." )
private Integer resourceType;
/////////////////////////////////////////////////////

View File

@ -30,6 +30,7 @@ import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.projects.Project;
import com.cloud.storage.Volume;
import com.cloud.user.Account;
@ -131,7 +132,7 @@ public class ResizeVolumeCmd extends BaseAsyncCmd {
}
@Override
public void execute(){
public void execute() throws ResourceAllocationException{
UserContext.current().setEventDetails("Volume Id: " + getEntityId() + " to size " + getSize() + "G");
Volume volume = _volumeService.resizeVolume(this);
if (volume != null) {

View File

@ -132,24 +132,42 @@ public class AccountResponse extends BaseResponse {
@SerializedName("vpcavailable") @Param(description="the total number of vpcs available to be created for this account", since="4.0.0")
private String vpcAvailable;
@SerializedName("cpulimit") @Param(description="the total number of cpu cores the account can own", since="4.1.0")
@SerializedName("cpulimit") @Param(description="the total number of cpu cores the account can own", since="4.2.0")
private String cpuLimit;
@SerializedName("cputotal") @Param(description="the total number of cpu cores owned by account", since="4.1.0")
@SerializedName("cputotal") @Param(description="the total number of cpu cores owned by account", since="4.2.0")
private Long cpuTotal;
@SerializedName("cpuavailable") @Param(description="the total number of cpu cores available to be created for this account", since="4.1.0")
@SerializedName("cpuavailable") @Param(description="the total number of cpu cores available to be created for this account", since="4.2.0")
private String cpuAvailable;
@SerializedName("memorylimit") @Param(description="the total memory (in MB) the account can own", since="4.1.0")
@SerializedName("memorylimit") @Param(description="the total memory (in MB) the account can own", since="4.2.0")
private String memoryLimit;
@SerializedName("memorytotal") @Param(description="the total memory (in MB) owned by account", since="4.1.0")
@SerializedName("memorytotal") @Param(description="the total memory (in MB) owned by account", since="4.2.0")
private Long memoryTotal;
@SerializedName("memoryavailable") @Param(description="the total memory (in MB) available to be created for this account", since="4.1.0")
@SerializedName("memoryavailable") @Param(description="the total memory (in MB) available to be created for this account", since="4.2.0")
private String memoryAvailable;
@SerializedName("primarystoragelimit") @Param(description="the total primary storage space (in GiB) the account can own", since="4.2.0")
private String primaryStorageLimit;
@SerializedName("primarystoragetotal") @Param(description="the total primary storage space (in GiB) owned by account", since="4.2.0")
private Long primaryStorageTotal;
@SerializedName("primarystorageavailable") @Param(description="the total primary storage space (in GiB) available to be used for this account", since="4.2.0")
private String primaryStorageAvailable;
@SerializedName("secondarystoragelimit") @Param(description="the total secondary storage space (in GiB) the account can own", since="4.2.0")
private String secondaryStorageLimit;
@SerializedName("secondarystoragetotal") @Param(description="the total secondary storage space (in GiB) owned by account", since="4.2.0")
private Long secondaryStorageTotal;
@SerializedName("secondarystorageavailable") @Param(description="the total secondary storage space (in GiB) available to be used for this account", since="4.2.0")
private String secondaryStorageAvailable;
@SerializedName(ApiConstants.STATE) @Param(description="the state of the account")
private String state;
@ -336,6 +354,30 @@ public class AccountResponse extends BaseResponse {
this.memoryAvailable = memoryAvailable;
}
public void setPrimaryStorageLimit(String primaryStorageLimit) {
this.primaryStorageLimit = primaryStorageLimit;
}
public void setPrimaryStorageTotal(Long primaryStorageTotal) {
this.primaryStorageTotal = primaryStorageTotal;
}
public void setPrimaryStorageAvailable(String primaryStorageAvailable) {
this.primaryStorageAvailable = primaryStorageAvailable;
}
public void setSecondaryStorageLimit(String secondaryStorageLimit) {
this.secondaryStorageLimit = secondaryStorageLimit;
}
public void setSecondaryStorageTotal(Long secondaryStorageTotal) {
this.secondaryStorageTotal = secondaryStorageTotal;
}
public void setSecondaryStorageAvailable(String secondaryStorageAvailable) {
this.secondaryStorageAvailable = secondaryStorageAvailable;
}
public void setDefaultZone(String defaultZoneId) {
this.defaultZoneId = defaultZoneId;
}

View File

@ -40,7 +40,7 @@ public class ResourceCountResponse extends BaseResponse implements ControlledEnt
@SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name for which resource count's are updated")
private String domainName;
@SerializedName(ApiConstants.RESOURCE_TYPE) @Param(description="resource type. Values include 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. See the resourceType parameter for more information on these values.")
@SerializedName(ApiConstants.RESOURCE_TYPE) @Param(description="resource type. Values include 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11. See the resourceType parameter for more information on these values.")
private String resourceType;
@SerializedName("resourcecount") @Param(description="resource count")

View File

@ -36,7 +36,7 @@ public class ResourceLimitResponse extends BaseResponse implements ControlledEnt
@SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name of the resource limit")
private String domainName;
@SerializedName(ApiConstants.RESOURCE_TYPE) @Param(description="resource type. Values include 0, 1, 2, 3, 4, 6, 7, 8, 9. See the resourceType parameter for more information on these values.")
@SerializedName(ApiConstants.RESOURCE_TYPE) @Param(description="resource type. Values include 0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11. See the resourceType parameter for more information on these values.")
private String resourceType;
@SerializedName("max") @Param(description="the maximum number of the resource. A -1 means the resource currently has no limit.")

View File

@ -50,6 +50,7 @@ import com.cloud.storage.VMTemplateZoneVO;
import com.cloud.template.TemplateAdapter;
import com.cloud.template.TemplateAdapterBase;
import com.cloud.user.Account;
import com.cloud.utils.UriUtils;
import com.cloud.utils.db.DB;
import com.cloud.utils.exception.CloudRuntimeException;
@ -82,7 +83,11 @@ public class BareMetalTemplateAdapter extends TemplateAdapterBase implements Tem
throw new CloudRuntimeException("Please add PXE server before adding baremetal template in zone " + profile.getZoneId());
}
}
// Check that the resource limit for secondary storage won't be exceeded
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(cmd.getEntityOwnerId()),
ResourceType.secondary_storage, UriUtils.getRemoteSize(profile.getUrl()));
return profile;
}
@ -133,6 +138,8 @@ public class BareMetalTemplateAdapter extends TemplateAdapterBase implements Tem
}
_resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
_resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.secondary_storage,
UriUtils.getRemoteSize(profile.getUrl()));
return template;
}
@ -205,8 +212,10 @@ public class BareMetalTemplateAdapter extends TemplateAdapterBase implements Tem
s_logger.debug("Failed to acquire lock when deleting template with ID: " + templateId);
success = false;
} else if (_tmpltDao.remove(templateId)) {
// Decrement the number of templates
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template);
// Decrement the number of templates and total secondary storage space used by the account.
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template);
_resourceLimitMgr.recalculateResourceCount(accountId, template.getDomainId(),
ResourceType.secondary_storage.getOrdinal());
}
} finally {

View File

@ -802,7 +802,8 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager {
(alertType != AlertManager.ALERT_TYPE_CONSOLE_PROXY) &&
(alertType != AlertManager.ALERT_TYPE_SSVM) &&
(alertType != AlertManager.ALERT_TYPE_STORAGE_MISC) &&
(alertType != AlertManager.ALERT_TYPE_MANAGMENT_NODE)) {
(alertType != AlertManager.ALERT_TYPE_MANAGMENT_NODE) &&
(alertType != AlertManager.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED)) {
alert = _alertDao.getLastAlert(alertType, dataCenterId, podId, clusterId);
}

View File

@ -16,10 +16,32 @@
// under the License.
package com.cloud.api;
import com.cloud.api.query.ViewResponseHelper;
import com.cloud.api.query.vo.*;
import com.cloud.api.response.ApiResponseSerializer;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TimeZone;
import javax.inject.Inject;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.api.ApiConstants.HostDetails;
import org.apache.cloudstack.api.ApiConstants.VMDetails;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.ResponseGenerator;
import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
import org.apache.cloudstack.api.response.AccountResponse;
import org.apache.cloudstack.api.response.AsyncJobResponse;
import org.apache.cloudstack.api.response.AutoScalePolicyResponse;
import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse;
@ -30,6 +52,7 @@ import org.apache.cloudstack.api.response.ClusterResponse;
import org.apache.cloudstack.api.response.ConditionResponse;
import org.apache.cloudstack.api.response.ConfigurationResponse;
import org.apache.cloudstack.api.response.ControlledEntityResponse;
import org.apache.cloudstack.api.response.ControlledViewEntityResponse;
import org.apache.cloudstack.api.response.CounterResponse;
import org.apache.cloudstack.api.response.CreateCmdResponse;
import org.apache.cloudstack.api.response.DiskOfferingResponse;
@ -39,10 +62,10 @@ import org.apache.cloudstack.api.response.EventResponse;
import org.apache.cloudstack.api.response.ExtractResponse;
import org.apache.cloudstack.api.response.FirewallResponse;
import org.apache.cloudstack.api.response.FirewallRuleResponse;
import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse;
import org.apache.cloudstack.api.response.GuestOSResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse;
import org.apache.cloudstack.api.response.ControlledViewEntityResponse;
import org.apache.cloudstack.api.response.IPAddressResponse;
import org.apache.cloudstack.api.response.InstanceGroupResponse;
import org.apache.cloudstack.api.response.IpForwardingRuleResponse;
@ -56,6 +79,7 @@ import org.apache.cloudstack.api.response.NetworkACLResponse;
import org.apache.cloudstack.api.response.NetworkOfferingResponse;
import org.apache.cloudstack.api.response.NetworkResponse;
import org.apache.cloudstack.api.response.NicResponse;
import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
import org.apache.cloudstack.api.response.PodResponse;
import org.apache.cloudstack.api.response.PrivateGatewayResponse;
@ -63,10 +87,12 @@ import org.apache.cloudstack.api.response.ProjectAccountResponse;
import org.apache.cloudstack.api.response.ProjectInvitationResponse;
import org.apache.cloudstack.api.response.ProjectResponse;
import org.apache.cloudstack.api.response.ProviderResponse;
import org.apache.cloudstack.api.response.RegionResponse;
import org.apache.cloudstack.api.response.RemoteAccessVpnResponse;
import org.apache.cloudstack.api.response.ResourceCountResponse;
import org.apache.cloudstack.api.response.ResourceLimitResponse;
import org.apache.cloudstack.api.response.ResourceTagResponse;
import org.apache.cloudstack.api.response.S3Response;
import org.apache.cloudstack.api.response.SecurityGroupResponse;
import org.apache.cloudstack.api.response.SecurityGroupRuleResponse;
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
@ -90,6 +116,7 @@ import org.apache.cloudstack.api.response.TrafficTypeResponse;
import org.apache.cloudstack.api.response.UsageRecordResponse;
import org.apache.cloudstack.api.response.UserResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.api.response.VMSnapshotResponse;
import org.apache.cloudstack.api.response.VirtualRouterProviderResponse;
import org.apache.cloudstack.api.response.VlanIpRangeResponse;
import org.apache.cloudstack.api.response.VolumeResponse;
@ -97,37 +124,86 @@ import org.apache.cloudstack.api.response.VpcOfferingResponse;
import org.apache.cloudstack.api.response.VpcResponse;
import org.apache.cloudstack.api.response.VpnUsersResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.api.response.S3Response;
import org.apache.cloudstack.region.Region;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.usage.Usage;
import org.apache.cloudstack.usage.UsageService;
import org.apache.cloudstack.usage.UsageTypes;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.api.query.ViewResponseHelper;
import com.cloud.api.query.vo.AccountJoinVO;
import com.cloud.api.query.vo.AsyncJobJoinVO;
import com.cloud.api.query.vo.ControlledViewEntity;
import com.cloud.api.query.vo.DataCenterJoinVO;
import com.cloud.api.query.vo.DiskOfferingJoinVO;
import com.cloud.api.query.vo.DomainRouterJoinVO;
import com.cloud.api.query.vo.EventJoinVO;
import com.cloud.api.query.vo.HostJoinVO;
import com.cloud.api.query.vo.InstanceGroupJoinVO;
import com.cloud.api.query.vo.ProjectAccountJoinVO;
import com.cloud.api.query.vo.ProjectInvitationJoinVO;
import com.cloud.api.query.vo.ProjectJoinVO;
import com.cloud.api.query.vo.ResourceTagJoinVO;
import com.cloud.api.query.vo.SecurityGroupJoinVO;
import com.cloud.api.query.vo.ServiceOfferingJoinVO;
import com.cloud.api.query.vo.StoragePoolJoinVO;
import com.cloud.api.query.vo.UserAccountJoinVO;
import com.cloud.api.query.vo.UserVmJoinVO;
import com.cloud.api.query.vo.VolumeJoinVO;
import com.cloud.api.response.ApiResponseSerializer;
import com.cloud.async.AsyncJob;
import com.cloud.capacity.Capacity;
import com.cloud.capacity.CapacityVO;
import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity;
import com.cloud.configuration.Configuration;
import com.cloud.configuration.Resource.ResourceOwnerType;
import com.cloud.configuration.Resource.ResourceType;
import com.cloud.configuration.ResourceCount;
import com.cloud.configuration.ResourceLimit;
import com.cloud.dao.EntityManager;
import com.cloud.dc.*;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.HostPodVO;
import com.cloud.dc.Pod;
import com.cloud.dc.StorageNetworkIpRange;
import com.cloud.dc.Vlan;
import com.cloud.dc.Vlan.VlanType;
import com.cloud.dc.VlanVO;
import com.cloud.domain.Domain;
import com.cloud.event.Event;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.hypervisor.HypervisorCapabilities;
import com.cloud.network.*;
import com.cloud.network.IpAddress;
import com.cloud.network.Network;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.Provider;
import com.cloud.network.Network.Service;
import com.cloud.network.NetworkProfile;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.as.*;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.PhysicalNetworkServiceProvider;
import com.cloud.network.PhysicalNetworkTrafficType;
import com.cloud.network.RemoteAccessVpn;
import com.cloud.network.Site2SiteCustomerGateway;
import com.cloud.network.Site2SiteVpnConnection;
import com.cloud.network.Site2SiteVpnGateway;
import com.cloud.network.VirtualRouterProvider;
import com.cloud.network.VpnUser;
import com.cloud.network.as.AutoScalePolicy;
import com.cloud.network.as.AutoScaleVmGroup;
import com.cloud.network.as.AutoScaleVmProfile;
import com.cloud.network.as.AutoScaleVmProfileVO;
import com.cloud.network.as.Condition;
import com.cloud.network.as.ConditionVO;
import com.cloud.network.as.Counter;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.router.VirtualRouter;
import com.cloud.network.rules.*;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.FirewallRuleVO;
import com.cloud.network.rules.HealthCheckPolicy;
@ -156,12 +232,25 @@ import com.cloud.server.Criteria;
import com.cloud.server.ResourceTag;
import com.cloud.server.ResourceTag.TaggedResourceType;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.storage.*;
import com.cloud.storage.DiskOfferingVO;
import com.cloud.storage.GuestOS;
import com.cloud.storage.GuestOSCategoryVO;
import com.cloud.storage.S3;
import com.cloud.storage.Snapshot;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.Storage.TemplateType;
import com.cloud.storage.StoragePool;
import com.cloud.storage.Swift;
import com.cloud.storage.UploadVO;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateS3VO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateSwiftVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.Volume;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.snapshot.SnapshotPolicy;
import com.cloud.storage.snapshot.SnapshotSchedule;
import com.cloud.template.VirtualMachineTemplate;
@ -179,40 +268,10 @@ import com.cloud.vm.Nic;
import com.cloud.vm.NicProfile;
import com.cloud.vm.NicVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.NicSecondaryIp;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.Type;
import com.cloud.vm.dao.NicSecondaryIpVO;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.api.ApiConstants.HostDetails;
import org.apache.cloudstack.api.ApiConstants.VMDetails;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.ResponseGenerator;
import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
import org.apache.cloudstack.api.response.*;
import org.apache.cloudstack.region.Region;
import org.apache.cloudstack.usage.Usage;
import org.apache.cloudstack.usage.UsageService;
import org.apache.cloudstack.usage.UsageTypes;
import com.cloud.vm.VmStats;
import com.cloud.vm.dao.UserVmData;
import com.cloud.vm.dao.UserVmData.NicData;
import com.cloud.vm.dao.UserVmData.SecurityGroupData;
import com.cloud.vm.snapshot.VMSnapshot;
import org.apache.cloudstack.api.ResponseGenerator;
import org.apache.cloudstack.api.response.VMSnapshotResponse;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import java.text.DecimalFormat;
import java.util.*;
import javax.inject.Inject;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import com.cloud.vm.snapshot.VMSnapshot;
@Component
public class ApiResponseHelper implements ResponseGenerator {
@ -290,7 +349,11 @@ public class ApiResponseHelper implements ResponseGenerator {
populateDomain(resourceLimitResponse, accountTemp.getDomainId());
}
resourceLimitResponse.setResourceType(Integer.valueOf(limit.getType().getOrdinal()).toString());
resourceLimitResponse.setMax(limit.getMax());
if(limit.getType() == ResourceType.primary_storage || limit.getType() == ResourceType.secondary_storage) {
resourceLimitResponse.setMax((long) Math.ceil(limit.getMax()/ResourceType.bytesToGiB));
} else {
resourceLimitResponse.setMax(limit.getMax());
}
resourceLimitResponse.setObjectName("resourcelimit");
return resourceLimitResponse;

View File

@ -175,6 +175,24 @@ public class AccountJoinDaoImpl extends GenericDaoBase<AccountJoinVO, Long> impl
accountResponse.setMemoryTotal(memoryTotal);
accountResponse.setMemoryAvailable(memoryAvail);
//get resource limits for primary storage space and convert it from Bytes to GiB
long primaryStorageLimit = ApiDBUtils.findCorrectResourceLimit(account.getPrimaryStorageLimit(), account.getType(), ResourceType.primary_storage);
String primaryStorageLimitDisplay = (accountIsAdmin || primaryStorageLimit == -1) ? "Unlimited" : String.valueOf(primaryStorageLimit / ResourceType.bytesToGiB);
long primaryStorageTotal = (account.getPrimaryStorageTotal() == null) ? 0 : (account.getPrimaryStorageTotal() / ResourceType.bytesToGiB);
String primaryStorageAvail = (accountIsAdmin || primaryStorageLimit == -1) ? "Unlimited" : String.valueOf((primaryStorageLimit / ResourceType.bytesToGiB) - primaryStorageTotal);
accountResponse.setPrimaryStorageLimit(primaryStorageLimitDisplay);
accountResponse.setPrimaryStorageTotal(primaryStorageTotal);
accountResponse.setPrimaryStorageAvailable(primaryStorageAvail);
//get resource limits for secondary storage space and convert it from Bytes to GiB
long secondaryStorageLimit = ApiDBUtils.findCorrectResourceLimit(account.getSecondaryStorageLimit(), account.getType(), ResourceType.secondary_storage);
String secondaryStorageLimitDisplay = (accountIsAdmin || secondaryStorageLimit == -1) ? "Unlimited" : String.valueOf(secondaryStorageLimit / ResourceType.bytesToGiB);
long secondaryStorageTotal = (account.getSecondaryStorageTotal() == null) ? 0 : (account.getSecondaryStorageTotal() / ResourceType.bytesToGiB);
String secondaryStorageAvail = (accountIsAdmin || secondaryStorageLimit == -1) ? "Unlimited" : String.valueOf((secondaryStorageLimit / ResourceType.bytesToGiB) - secondaryStorageTotal);
accountResponse.setSecondaryStorageLimit(secondaryStorageLimitDisplay);
accountResponse.setSecondaryStorageTotal(secondaryStorageTotal);
accountResponse.setSecondaryStorageAvailable(secondaryStorageAvail);
// adding all the users for an account as part of the response obj
List<UserAccountJoinVO> usersForAccount = ApiDBUtils.findUserViewByAccountId(account.getId());
List<UserResponse> userResponses = ViewResponseHelper.createUserResponse(usersForAccount.toArray(new UserAccountJoinVO[usersForAccount.size()]));

View File

@ -162,6 +162,20 @@ public class AccountJoinVO extends BaseViewVO implements InternalIdentity, Ident
@Column(name="memoryTotal")
private Long memoryTotal;
@Column(name="primaryStorageLimit")
private Long primaryStorageLimit;
@Column(name="primaryStorageTotal")
private Long primaryStorageTotal;
@Column(name="secondaryStorageLimit")
private Long secondaryStorageLimit;
@Column(name="secondaryStorageTotal")
private Long secondaryStorageTotal;
@Column(name="job_id")
private long jobId;
@ -478,6 +492,7 @@ public class AccountJoinVO extends BaseViewVO implements InternalIdentity, Ident
this.cpuTotal = cpuTotal;
}
public Long getMemoryTotal() {
return memoryTotal;
}
@ -488,6 +503,25 @@ public class AccountJoinVO extends BaseViewVO implements InternalIdentity, Ident
}
public Long getPrimaryStorageTotal() {
return primaryStorageTotal;
}
public void setPrimaryStorageTotal(Long primaryStorageTotal) {
this.primaryStorageTotal = primaryStorageTotal;
}
public Long getSecondaryStorageTotal() {
return secondaryStorageTotal;
}
public void setSecondaryStorageTotal(Long secondaryStorageTotal) {
this.secondaryStorageTotal = secondaryStorageTotal;
}
public Long getVmLimit() {
return vmLimit;
}
@ -588,6 +622,26 @@ public class AccountJoinVO extends BaseViewVO implements InternalIdentity, Ident
}
public Long getPrimaryStorageLimit() {
return primaryStorageLimit;
}
public void setPrimaryStorageLimit(Long primaryStorageLimit) {
this.primaryStorageLimit = primaryStorageLimit;
}
public Long getSecondaryStorageLimit() {
return secondaryStorageLimit;
}
public void setSecondaryStorageLimit(Long secondaryStorageLimit) {
this.secondaryStorageLimit = secondaryStorageLimit;
}
public long getJobId() {
return jobId;
}

View File

@ -323,7 +323,8 @@ public enum Config {
DefaultMaxAccountVpcs("Account Defaults", ManagementServer.class, Long.class, "max.account.vpcs", "20", "The default maximum number of vpcs that can be created for an account", null),
DefaultMaxAccountCpus("Account Defaults", ManagementServer.class, Long.class, "max.account.cpus", "40", "The default maximum number of cpu cores that can be used for an account", null),
DefaultMaxAccountMemory("Account Defaults", ManagementServer.class, Long.class, "max.account.memory", "40960", "The default maximum memory (in MB) that can be used for an account", null),
DefaultMaxAccountPrimayStorage("Account Defaults", ManagementServer.class, Long.class, "max.account.primary.storage", "200", "The default maximum primary storage space (in GiB) that can be used for an account", null),
DefaultMaxAccountSecondaryStorage("Account Defaults", ManagementServer.class, Long.class, "max.account.secondary.storage", "400", "The default maximum secondary storage space (in GiB) that can be used for an account", null),
ResourceCountCheckInterval("Advanced", ManagementServer.class, Long.class, "resourcecount.check.interval", "0", "Time (in seconds) to wait before retrying resource count check task. Default is 0 which is to never run the task", "Seconds"),
DirectAgentLoadSize("Advanced", ManagementServer.class, Integer.class, "direct.agent.load.size", "16", "The number of direct agents to load each time", null),
@ -349,6 +350,8 @@ public enum Config {
DefaultMaxProjectVpcs("Project Defaults", ManagementServer.class, Long.class, "max.project.vpcs", "20", "The default maximum number of vpcs that can be created for a project", null),
DefaultMaxProjectCpus("Project Defaults", ManagementServer.class, Long.class, "max.project.cpus", "40", "The default maximum number of cpu cores that can be used for a project", null),
DefaultMaxProjectMemory("Project Defaults", ManagementServer.class, Long.class, "max.project.memory", "40960", "The default maximum memory (in MB) that can be used for a project", null),
DefaultMaxProjectPrimayStorage("Project Defaults", ManagementServer.class, Long.class, "max.project.primary.storage", "200", "The default maximum primary storage space (in GiB) that can be used for an project", null),
DefaultMaxProjectSecondaryStorage("Project Defaults", ManagementServer.class, Long.class, "max.project.secondary.storage", "400", "The default maximum secondary storage space (in GiB) that can be used for an project", null),
ProjectInviteRequired("Project Defaults", ManagementServer.class, Boolean.class, "project.invite.required", "false", "If invitation confirmation is required when add account to project. Default value is false", null),
ProjectInvitationExpirationTime("Project Defaults", ManagementServer.class, Long.class, "project.invite.timeout", "86400", "Invitation expiration time (in seconds). Default is 1 day - 86400 seconds", null),

View File

@ -61,8 +61,12 @@ import com.cloud.projects.dao.ProjectAccountDao;
import com.cloud.projects.dao.ProjectDao;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateHostDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.dao.VolumeDaoImpl.SumCount;
import com.cloud.user.Account;
@ -135,6 +139,10 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
private VpcDao _vpcDao;
@Inject
private ServiceOfferingDao _serviceOfferingDao;
@Inject
private VMTemplateHostDao _vmTemplateHostDao;
protected GenericSearchBuilder<VMTemplateHostVO, SumCount> templateSizeSearch;
protected SearchBuilder<ResourceCountVO> ResourceCountSearch;
ScheduledExecutorService _rcExecutor;
@ -164,6 +172,15 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
ResourceCountSearch.and("domainId", ResourceCountSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
ResourceCountSearch.done();
templateSizeSearch = _vmTemplateHostDao.createSearchBuilder(SumCount.class);
templateSizeSearch.select("sum", Func.SUM, templateSizeSearch.entity().getSize());
templateSizeSearch.and("downloadState", templateSizeSearch.entity().getDownloadState(), Op.EQ);
templateSizeSearch.and("destroyed", templateSizeSearch.entity().getDestroyed(), Op.EQ);
SearchBuilder<VMTemplateVO> join1 = _vmTemplateDao.createSearchBuilder();
join1.and("accountId", join1.entity().getAccountId(), Op.EQ);
templateSizeSearch.join("templates", join1, templateSizeSearch.entity().getTemplateId(), join1.entity().getId(), JoinBuilder.JoinType.INNER);
templateSizeSearch.done();
_resourceCountCheckInterval = NumbersUtil.parseInt(_configDao.getValue(Config.ResourceCountCheckInterval.key()), 0);
if (_resourceCountCheckInterval > 0) {
_rcExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("ResourceCountChecker"));
@ -178,6 +195,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
projectResourceLimitMap.put(Resource.ResourceType.vpc, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectVpcs.key())));
projectResourceLimitMap.put(Resource.ResourceType.cpu, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectCpus.key())));
projectResourceLimitMap.put(Resource.ResourceType.memory, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectMemory.key())));
projectResourceLimitMap.put(Resource.ResourceType.primary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectPrimayStorage.key())));
projectResourceLimitMap.put(Resource.ResourceType.secondary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectSecondaryStorage.key())));
accountResourceLimitMap.put(Resource.ResourceType.public_ip, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountPublicIPs.key())));
accountResourceLimitMap.put(Resource.ResourceType.snapshot, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountSnapshots.key())));
@ -188,6 +207,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
accountResourceLimitMap.put(Resource.ResourceType.vpc, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountVpcs.key())));
accountResourceLimitMap.put(Resource.ResourceType.cpu, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountCpus.key())));
accountResourceLimitMap.put(Resource.ResourceType.memory, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountMemory.key())));
accountResourceLimitMap.put(Resource.ResourceType.primary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountPrimayStorage.key())));
accountResourceLimitMap.put(Resource.ResourceType.secondary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountSecondaryStorage.key())));
return true;
}
@ -246,6 +267,10 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
value = accountResourceLimitMap.get(type);
}
if (value != null) {
// convert the value from GiB to bytes in case of primary or secondary storage.
if (type == ResourceType.primary_storage || type == ResourceType.secondary_storage) {
value = value * ResourceType.bytesToGiB;
}
return value;
}
}
@ -276,6 +301,9 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
value = accountResourceLimitMap.get(type);
}
if (value != null) {
if (type == ResourceType.primary_storage || type == ResourceType.secondary_storage) {
value = value * ResourceType.bytesToGiB;
}
return value;
}
}
@ -548,6 +576,11 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
}
}
//Convert max storage size from GiB to bytes
if (resourceType == ResourceType.primary_storage || resourceType == ResourceType.secondary_storage) {
max = max * ResourceType.bytesToGiB;
}
ResourceOwnerType ownerType = null;
Long ownerId = null;
@ -789,6 +822,10 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
newCount = countCpusForAccount(accountId);
} else if (type == Resource.ResourceType.memory) {
newCount = calculateMemoryForAccount(accountId);
} else if (type == Resource.ResourceType.primary_storage) {
newCount = _volumeDao.primaryStorageUsedForAccount(accountId);
} else if (type == Resource.ResourceType.secondary_storage) {
newCount = calculateSecondaryStorageForAccount(accountId);
} else {
throw new InvalidParameterValueException("Unsupported resource type " + type);
}
@ -847,6 +884,23 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
}
}
public long calculateSecondaryStorageForAccount(long accountId) {
long totalVolumesSize = _volumeDao.secondaryStorageUsedForAccount(accountId);
long totalSnapshotsSize = _snapshotDao.secondaryStorageUsedForAccount(accountId);
long totalTemplatesSize = 0;
SearchCriteria<SumCount> sc = templateSizeSearch.create();
sc.setParameters("downloadState", Status.DOWNLOADED);
sc.setParameters("destroyed", false);
sc.setJoinParameters("templates", "accountId", accountId);
List<SumCount> templates = _vmTemplateHostDao.customSearch(sc, null);
if (templates != null) {
totalTemplatesSize = templates.get(0).sum;
}
return totalVolumesSize + totalSnapshotsSize + totalTemplatesSize;
}
@Override
public long getResourceCount(Account account, ResourceType type) {
return _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type);

View File

@ -61,7 +61,8 @@ public interface VolumeManager extends VolumeApiService {
VolumeVO createVolume(CreateVolumeCmd cmd);
VolumeVO resizeVolume(ResizeVolumeCmd cmd);
VolumeVO resizeVolume(ResizeVolumeCmd cmd)
throws ResourceAllocationException;
boolean deleteVolume(long volumeId, Account caller)
throws ConcurrentOperationException;

View File

@ -146,6 +146,7 @@ import com.cloud.uservm.UserVm;
import com.cloud.utils.EnumUtils;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.UriUtils;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.JoinBuilder;
@ -469,6 +470,10 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
}
validateUrl(url);
// Check that the resource limit for secondary storage won't be exceeded
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.secondary_storage,
UriUtils.getRemoteSize(url));
return false;
}
@ -736,6 +741,8 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
// decrement it
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(),
ResourceType.volume);
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage,
UriUtils.getRemoteSize(url));
txn.commit();
return volume;
@ -906,6 +913,10 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
_accountMgr.checkAccess(caller, null, true, snapshotCheck);
}
// Check that the resource limit for primary storage won't be exceeded
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.primary_storage,
new Long(size));
// Verify that zone exists
DataCenterVO zone = _dcDao.findById(zoneId);
if (zone == null) {
@ -974,6 +985,8 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
// decrement it
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(),
ResourceType.volume);
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage,
new Long(volume.getSize()));
txn.commit();
@ -1006,6 +1019,8 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
+ " as volume failed to create on the backend");
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(),
ResourceType.volume);
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage,
new Long(volume.getSize()));
}
}
}
@ -1013,7 +1028,8 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_RESIZE, eventDescription = "resizing volume", async = true)
public VolumeVO resizeVolume(ResizeVolumeCmd cmd) {
public VolumeVO resizeVolume(ResizeVolumeCmd cmd)
throws ResourceAllocationException {
Long newSize = null;
boolean shrinkOk = cmd.getShrinkOk();
@ -1149,6 +1165,12 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
+ " would shrink the volume, need to sign off by supplying the shrinkok parameter with value of true");
}
if (!shrinkOk) {
/* Check resource limit for this account on primary storage resource */
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()),
ResourceType.primary_storage, new Long(newSize - currentSize));
}
/*
* get a list of hosts to send the commands to, try the system the
* associated vm is running on first, then the last known place it ran.
@ -1176,27 +1198,35 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
ResizeVolumePayload payload = new ResizeVolumePayload(newSize, shrinkOk, instanceName, hosts);
try {
VolumeInfo vol = this.volFactory.getVolume(volume.getId());
VolumeInfo vol = this.volFactory.getVolume(volume.getId());
vol.addPayload(payload);
AsyncCallFuture<VolumeApiResult> future = this.volService.resize(vol);
future.get();
volume = _volsDao.findById(volume.getId());
if (newDiskOffering != null) {
volume.setDiskOfferingId(cmd.getNewDiskOfferingId());
}
_volsDao.update(volume.getId(), volume);
AsyncCallFuture<VolumeApiResult> future = this.volService.resize(vol);
future.get();
volume = _volsDao.findById(volume.getId());
if (newDiskOffering != null) {
volume.setDiskOfferingId(cmd.getNewDiskOfferingId());
}
_volsDao.update(volume.getId(), volume);
/* Update resource count for the account on primary storage resource */
if (!shrinkOk) {
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage,
new Long(newSize - currentSize));
} else {
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage,
new Long(currentSize - newSize));
}
return volume;
} catch (InterruptedException e) {
s_logger.debug("failed get resize volume result", e);
} catch (ExecutionException e) {
s_logger.debug("failed get resize volume result", e);
} catch (Exception e) {
s_logger.debug("failed get resize volume result", e);
}
return volume;
} catch (InterruptedException e) {
s_logger.debug("failed get resize volume result", e);
} catch (ExecutionException e) {
s_logger.debug("failed get resize volume result", e);
} catch (Exception e) {
s_logger.debug("failed get resize volume result", e);
}
return null;
}
@ -1243,9 +1273,19 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
VMInstanceVO vmInstance = this._vmInstanceDao.findById(instanceId);
if (instanceId == null
|| (vmInstance.getType().equals(VirtualMachine.Type.User))) {
// Decrement the resource count for volumes belonging user VM's only
// Decrement the resource count for volumes and primary storage belonging user VM's only
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(),
ResourceType.volume);
/* If volume is in primary storage, decrement primary storage count else decrement secondary
storage count (in case of upload volume). */
if (volume.getFolder() != null) {
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage,
new Long(volume.getSize()));
} else {
_resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(),
ResourceType.secondary_storage.getOrdinal());
}
// Log usage event for volumes belonging user VM's only
UsageEventVO usageEvent = new UsageEventVO(
EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(),
@ -1317,6 +1357,8 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(),
ResourceType.volume);
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage,
new Long(vol.getSize()));
}
return toDiskProfile(vol, offering);
}
@ -1364,6 +1406,8 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(),
ResourceType.volume);
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage,
new Long(vol.getSize()));
}
return toDiskProfile(vol, offering);
}
@ -1435,6 +1479,13 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
vol = copyVolume(rootDiskPool
, volume, vm, rootDiskTmplt, dcVO,
pod, diskVO, svo, rootDiskHyperType);
if (vol != null) {
// Moving of Volume is successful, decrement the volume resource count from secondary for an account and increment it into primary storage under same account.
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(),
ResourceType.secondary_storage, new Long(volume.getSize()));
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(),
ResourceType.primary_storage, new Long(volume.getSize()));
}
}
return vol;
}

View File

@ -40,7 +40,15 @@ public interface SnapshotDao extends GenericDao<SnapshotVO, Long>, StateDao<Snap
List<SnapshotVO> listByHostId(Filter filter, long hostId);
List<SnapshotVO> listByHostId(long hostId);
public Long countSnapshotsForAccount(long accountId);
List<SnapshotVO> listByInstanceId(long instanceId, Snapshot.State... status);
List<SnapshotVO> listByStatus(long volumeId, Snapshot.State... status);
List<SnapshotVO> listByInstanceId(long instanceId, Snapshot.State... status);
List<SnapshotVO> listByStatus(long volumeId, Snapshot.State... status);
List<SnapshotVO> listAllByStatus(Snapshot.State... status);
/**
* Gets the Total Secondary Storage space (in bytes) used by snapshots allocated for an account
*
* @param account
* @return total Secondary Storage space allocated
*/
long secondaryStorageUsedForAccount(long accountId);
}

View File

@ -35,15 +35,20 @@ import com.cloud.storage.Snapshot.Type;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.Volume;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.VolumeDaoImpl.SumCount;
import com.cloud.tags.dao.ResourceTagDao;
import com.cloud.tags.dao.ResourceTagsDaoImpl;
import com.cloud.utils.db.*;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.JoinBuilder.JoinType;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Func;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.Transaction;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.dao.VMInstanceDao;
import com.cloud.vm.dao.VMInstanceDaoImpl;
@Component
@Local (value={SnapshotDao.class})
@ -53,19 +58,19 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
private static final String UPDATE_SNAPSHOT_VERSION = "UPDATE snapshots SET version = ? WHERE volume_id = ? AND version = ?";
private static final String GET_SECHOST_ID = "SELECT sechost_id FROM snapshots where volume_id = ? AND backup_snap_id IS NOT NULL AND sechost_id IS NOT NULL LIMIT 1";
private static final String UPDATE_SECHOST_ID = "UPDATE snapshots SET sechost_id = ? WHERE data_center_id = ?";
private SearchBuilder<SnapshotVO> VolumeIdSearch;
private SearchBuilder<SnapshotVO> VolumeIdTypeSearch;
private SearchBuilder<SnapshotVO> ParentIdSearch;
private SearchBuilder<SnapshotVO> backupUuidSearch;
private SearchBuilder<SnapshotVO> backupUuidSearch;
private SearchBuilder<SnapshotVO> VolumeIdVersionSearch;
private SearchBuilder<SnapshotVO> HostIdSearch;
private SearchBuilder<SnapshotVO> AccountIdSearch;
private SearchBuilder<SnapshotVO> InstanceIdSearch;
private SearchBuilder<SnapshotVO> StatusSearch;
private GenericSearchBuilder<SnapshotVO, Long> CountSnapshotsByAccount;
private GenericSearchBuilder<SnapshotVO, SumCount> secondaryStorageSearch;
@Inject ResourceTagDao _tagsDao;
@Inject protected VMInstanceDao _instanceDao;
@Inject protected VolumeDao _volumeDao;
@ -187,23 +192,29 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
CountSnapshotsByAccount.and("removed", CountSnapshotsByAccount.entity().getRemoved(), SearchCriteria.Op.NULL);
CountSnapshotsByAccount.done();
InstanceIdSearch = createSearchBuilder();
InstanceIdSearch = createSearchBuilder();
InstanceIdSearch.and("status", InstanceIdSearch.entity().getState(), SearchCriteria.Op.IN);
SearchBuilder<VMInstanceVO> instanceSearch = _instanceDao.createSearchBuilder();
instanceSearch.and("instanceId", instanceSearch.entity().getId(), SearchCriteria.Op.EQ);
SearchBuilder<VolumeVO> volumeSearch = _volumeDao.createSearchBuilder();
volumeSearch.and("state", volumeSearch.entity().getState(), SearchCriteria.Op.EQ);
volumeSearch.join("instanceVolumes", instanceSearch, instanceSearch.entity().getId(), volumeSearch.entity().getInstanceId(), JoinType.INNER);
InstanceIdSearch.join("instanceSnapshots", volumeSearch, volumeSearch.entity().getId(), InstanceIdSearch.entity().getVolumeId(), JoinType.INNER);
InstanceIdSearch.done();
SearchBuilder<VMInstanceVO> instanceSearch = _instanceDao.createSearchBuilder();
instanceSearch.and("instanceId", instanceSearch.entity().getId(), SearchCriteria.Op.EQ);
SearchBuilder<VolumeVO> volumeSearch = _volumeDao.createSearchBuilder();
volumeSearch.and("state", volumeSearch.entity().getState(), SearchCriteria.Op.EQ);
volumeSearch.join("instanceVolumes", instanceSearch, instanceSearch.entity().getId(), volumeSearch.entity().getInstanceId(), JoinType.INNER);
InstanceIdSearch.join("instanceSnapshots", volumeSearch, volumeSearch.entity().getId(), InstanceIdSearch.entity().getVolumeId(), JoinType.INNER);
InstanceIdSearch.done();
secondaryStorageSearch = createSearchBuilder(SumCount.class);
secondaryStorageSearch.select("sum", Func.SUM, secondaryStorageSearch.entity().getSize());
secondaryStorageSearch.and("accountId", secondaryStorageSearch.entity().getAccountId(), Op.EQ);
secondaryStorageSearch.and("isRemoved", secondaryStorageSearch.entity().getRemoved(), Op.NULL);
secondaryStorageSearch.done();
}
@Override
@Override
public Long getSecHostId(long volumeId) {
Transaction txn = Transaction.currentTxn();
PreparedStatement pstmt = null;
String sql = GET_SECHOST_ID;
@ -331,4 +342,16 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
txn.commit();
return true;
}
@Override
public long secondaryStorageUsedForAccount(long accountId) {
SearchCriteria<SumCount> sc = secondaryStorageSearch.create();
sc.setParameters("accountId", accountId);
List<SumCount> storageSpace = customSearch(sc, null);
if (storageSpace != null) {
return storageSpace.get(0).sum;
} else {
return 0;
}
}
}

View File

@ -27,50 +27,66 @@ import com.cloud.utils.db.GenericDao;
import com.cloud.utils.fsm.StateDao;
public interface VolumeDao extends GenericDao<VolumeVO, Long>, StateDao<Volume.State, Volume.Event, Volume> {
List<VolumeVO> findDetachedByAccount(long accountId);
List<VolumeVO> findDetachedByAccount(long accountId);
List<VolumeVO> findByAccount(long accountId);
Pair<Long, Long> getCountAndTotalByPool(long poolId);
Pair<Long, Long> getNonDestroyedCountAndTotalByPool(long poolId);
List<VolumeVO> findByInstance(long id);
List<VolumeVO> findByInstanceAndType(long id, Volume.Type vType);
List<VolumeVO> findByInstanceIdDestroyed(long vmId);
List<VolumeVO> findByAccountAndPod(long accountId, long podId);
List<VolumeVO> findByTemplateAndZone(long templateId, long zoneId);
void deleteVolumesByInstance(long instanceId);
void attachVolume(long volumeId, long vmId, long deviceId);
void detachVolume(long volumeId);
boolean isAnyVolumeActivelyUsingTemplateOnPool(long templateId, long poolId);
List<VolumeVO> findCreatedByInstance(long id);
List<VolumeVO> findByPoolId(long poolId);
List<VolumeVO> findByInstanceAndDeviceId(long instanceId, long deviceId);
List<VolumeVO> findByInstanceAndDeviceId(long instanceId, long deviceId);
List<VolumeVO> findUsableVolumesForInstance(long instanceId);
Long countAllocatedVolumesForAccount(long accountId);
HypervisorType getHypervisorType(long volumeId);
List<VolumeVO> listVolumesToBeDestroyed();
ImageFormat getImageFormat(Long volumeId);
List<VolumeVO> findReadyRootVolumesByInstance(long instanceId);
List<Long> listPoolIdsByVolumeCount(long dcId, Long podId, Long clusterId, long accountId);
/**
* Gets the Total Primary Storage space allocated for an account
*
* @param account
* @return total Primary Storage space (in bytes) used
*/
long primaryStorageUsedForAccount(long accountId);
/**
* Gets the Total Secondary Storage space used by volumes allocated for an account
*
* @param account
* @return total Secondary Storage space (in bytes) used
*/
long secondaryStorageUsedForAccount(long accountId);
}

View File

@ -38,7 +38,6 @@ import com.cloud.storage.Volume.State;
import com.cloud.storage.Volume.Type;
import com.cloud.storage.VolumeVO;
import com.cloud.tags.dao.ResourceTagDao;
import com.cloud.tags.dao.ResourceTagsDaoImpl;
import com.cloud.utils.Pair;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
@ -62,8 +61,10 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
protected final SearchBuilder<VolumeVO> InstanceStatesSearch;
protected final SearchBuilder<VolumeVO> AllFieldsSearch;
protected GenericSearchBuilder<VolumeVO, Long> CountByAccount;
protected GenericSearchBuilder<VolumeVO, SumCount> primaryStorageSearch;
protected GenericSearchBuilder<VolumeVO, SumCount> secondaryStorageSearch;
@Inject ResourceTagDao _tagsDao;
protected static final String SELECT_VM_SQL = "SELECT DISTINCT instance_id from volumes v where v.host_id = ? and v.mirror_state = ?";
protected static final String SELECT_HYPERTYPE_FROM_VOLUME = "SELECT c.hypervisor_type from volumes v, storage_pool s, cluster c where v.pool_id = s.id and s.cluster_id = c.id and v.id = ?";
@ -298,8 +299,22 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
CountByAccount = createSearchBuilder(Long.class);
CountByAccount.select(null, Func.COUNT, null);
CountByAccount.and("account", CountByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
CountByAccount.and("state", CountByAccount.entity().getState(), SearchCriteria.Op.NIN);
CountByAccount.and("state", CountByAccount.entity().getState(), SearchCriteria.Op.NIN);
CountByAccount.done();
primaryStorageSearch = createSearchBuilder(SumCount.class);
primaryStorageSearch.select("sum", Func.SUM, primaryStorageSearch.entity().getSize());
primaryStorageSearch.and("accountId", primaryStorageSearch.entity().getAccountId(), Op.EQ);
primaryStorageSearch.and("path", primaryStorageSearch.entity().getPath(), Op.NNULL);
primaryStorageSearch.and("isRemoved", primaryStorageSearch.entity().getRemoved(), Op.NULL);
primaryStorageSearch.done();
secondaryStorageSearch = createSearchBuilder(SumCount.class);
secondaryStorageSearch.select("sum", Func.SUM, secondaryStorageSearch.entity().getSize());
secondaryStorageSearch.and("accountId", secondaryStorageSearch.entity().getAccountId(), Op.EQ);
secondaryStorageSearch.and("path", secondaryStorageSearch.entity().getPath(), Op.NULL);
secondaryStorageSearch.and("isRemoved", secondaryStorageSearch.entity().getRemoved(), Op.NULL);
secondaryStorageSearch.done();
}
@Override @DB(txn=false)
@ -316,9 +331,34 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
SearchCriteria<Long> sc = CountByAccount.create();
sc.setParameters("account", accountId);
sc.setParameters("state", Volume.State.Destroy);
return customSearch(sc, null).get(0);
return customSearch(sc, null).get(0);
}
@Override
public long primaryStorageUsedForAccount(long accountId) {
SearchCriteria<SumCount> sc = primaryStorageSearch.create();
sc.setParameters("accountId", accountId);
List<SumCount> storageSpace = customSearch(sc, null);
if (storageSpace != null) {
return storageSpace.get(0).sum;
} else {
return 0;
}
}
@Override
public long secondaryStorageUsedForAccount(long accountId) {
SearchCriteria<SumCount> sc = secondaryStorageSearch.create();
sc.setParameters("accountId", accountId);
List<SumCount> storageSpace = customSearch(sc, null);
if (storageSpace != null) {
return storageSpace.get(0).sum;
} else {
return 0;
}
}
public static class SumCount {
public long sum;
public long count;

View File

@ -22,6 +22,8 @@ import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import javax.inject.Inject;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
@ -36,28 +38,31 @@ import com.cloud.agent.api.StartupSecondaryStorageCommand;
import com.cloud.agent.api.StartupStorageCommand;
import com.cloud.agent.api.storage.DownloadAnswer;
import com.cloud.agent.api.storage.DownloadCommand;
import com.cloud.agent.api.storage.DownloadProgressCommand;
import com.cloud.agent.api.storage.DownloadCommand.ResourceType;
import com.cloud.agent.api.storage.DownloadProgressCommand;
import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType;
import com.cloud.alert.AlertManager;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.ConnectionException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.storage.Storage;
import com.cloud.storage.StorageManager;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeHostVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.Volume.Event;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateHostDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.dao.VolumeHostDao;
import com.cloud.storage.download.DownloadState.DownloadEvent;
import com.cloud.user.AccountManager;
import com.cloud.user.ResourceLimitService;
import com.cloud.utils.UriUtils;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.fsm.NoTransitionException;
/**
* Monitor progress of template download to a single storage server
@ -119,6 +124,9 @@ public class DownloadListener implements Listener {
private StorageManager _storageMgr;
private VMTemplateHostDao vmTemplateHostDao;
private VMTemplateDao _vmTemplateDao;
private ResourceLimitService _resourceLimitMgr;
private AccountManager _accountMgr;
private AlertManager _alertMgr;
private final DownloadMonitorImpl downloadMonitor;
@ -137,7 +145,7 @@ public class DownloadListener implements Listener {
private Long templateHostId;
private Long volumeHostId;
public DownloadListener(HostVO ssAgent, HostVO host, VMTemplateVO template, Timer _timer, VMTemplateHostDao dao, Long templHostId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VMTemplateDao templateDao) {
public DownloadListener(HostVO ssAgent, HostVO host, VMTemplateVO template, Timer _timer, VMTemplateHostDao dao, Long templHostId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VMTemplateDao templateDao, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr) {
this.ssAgent = ssAgent;
this.sserver = host;
this.template = template;
@ -151,10 +159,13 @@ public class DownloadListener implements Listener {
this.timeoutTask = new TimeoutTask(this);
this.timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL);
this._vmTemplateDao = templateDao;
this._resourceLimitMgr = _resourceLimitMgr;
this._accountMgr = _accountMgr;
this._alertMgr = _alertMgr;
updateDatabase(Status.NOT_DOWNLOADED, "");
}
public DownloadListener(HostVO ssAgent, HostVO host, VolumeVO volume, Timer _timer, VolumeHostDao dao, Long volHostId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VolumeDao volumeDao, StorageManager storageMgr) {
public DownloadListener(HostVO ssAgent, HostVO host, VolumeVO volume, Timer _timer, VolumeHostDao dao, Long volHostId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VolumeDao volumeDao, StorageManager storageMgr, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr) {
this.ssAgent = ssAgent;
this.sserver = host;
this.volume = volume;
@ -169,6 +180,9 @@ public class DownloadListener implements Listener {
this.timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL);
this._volumeDao = volumeDao;
this._storageMgr = storageMgr;
this._resourceLimitMgr = _resourceLimitMgr;
this._accountMgr = _accountMgr;
this._alertMgr = _alertMgr;
updateDatabase(Status.NOT_DOWNLOADED, "");
}
@ -332,6 +346,24 @@ public class DownloadListener implements Listener {
templateDaoBuilder.setChecksum(answer.getCheckSum());
_vmTemplateDao.update(template.getId(), templateDaoBuilder);
}
if (answer.getTemplateSize() > 0) {
//long hostId = vmTemplateHostDao.findByTemplateId(template.getId()).getHostId();
long accountId = template.getAccountId();
try {
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId),
com.cloud.configuration.Resource.ResourceType.secondary_storage,
answer.getTemplateSize() - UriUtils.getRemoteSize(template.getUrl()));
} catch (ResourceAllocationException e) {
s_logger.warn(e.getMessage());
_alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, sserver.getDataCenterId(),
null, e.getMessage(), e.getMessage());
} finally {
_resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId).getDomainId(),
com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
}
}
} else {
VolumeHostVO updateBuilder = volumeHostDao.createForUpdate();
updateBuilder.setDownloadPercent(answer.getDownloadPct());
@ -351,6 +383,22 @@ public class DownloadListener implements Listener {
updateVolume.setSize(answer.getTemplateSize());
_volumeDao.update(volume.getId(), updateVolume);
if (answer.getTemplateSize() > 0) {
try {
String url = volumeHostDao.findByVolumeId(volume.getId()).getDownloadUrl();
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()),
com.cloud.configuration.Resource.ResourceType.secondary_storage,
answer.getTemplateSize() - UriUtils.getRemoteSize(url));
} catch (ResourceAllocationException e) {
s_logger.warn(e.getMessage());
_alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(),
volume.getPodId(), e.getMessage(), e.getMessage());
} finally {
_resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(),
com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
}
}
/*if (answer.getCheckSum() != null) {
VMTemplateVO templateDaoBuilder = _vmTemplateDao.createForUpdate();
templateDaoBuilder.setChecksum(answer.getCheckSum());

View File

@ -64,6 +64,7 @@ import com.cloud.event.UsageEventUtils;
import com.cloud.event.dao.UsageEventDao;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
@ -97,7 +98,9 @@ import com.cloud.storage.template.TemplateConstants;
import com.cloud.storage.template.TemplateInfo;
import com.cloud.template.TemplateManager;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.ResourceLimitService;
import com.cloud.utils.UriUtils;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.JoinBuilder;
@ -177,6 +180,8 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
protected ResourceLimitService _resourceLimitMgr;
@Inject
protected UserVmDao _userVmDao;
@Inject
protected AccountManager _accountMgr;
private Boolean _sslCopy = new Boolean(false);
private String _copyAuthPasswd;
@ -289,7 +294,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
s_logger.warn("There is no secondary storage VM for secondary storage host " + destServer.getName());
return false;
}
DownloadListener dl = new DownloadListener(ssAhost, destServer, template, _timer, _vmTemplateHostDao, destTmpltHost.getId(), this, dcmd, _templateDao);
DownloadListener dl = new DownloadListener(ssAhost, destServer, template, _timer, _vmTemplateHostDao, destTmpltHost.getId(), this, dcmd, _templateDao, _resourceLimitMgr, _alertMgr, _accountMgr);
if (downloadJobExists) {
dl.setCurrState(destTmpltHost.getDownloadState());
}
@ -376,7 +381,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
s_logger.warn("There is no secondary storage VM for secondary storage host " + sserver.getName());
return;
}
DownloadListener dl = new DownloadListener(ssAhost, sserver, template, _timer, _vmTemplateHostDao, vmTemplateHost.getId(), this, dcmd, _templateDao);
DownloadListener dl = new DownloadListener(ssAhost, sserver, template, _timer, _vmTemplateHostDao, vmTemplateHost.getId(), this, dcmd, _templateDao, _resourceLimitMgr, _alertMgr, _accountMgr);
if (downloadJobExists) {
dl.setCurrState(vmTemplateHost.getDownloadState());
}
@ -465,7 +470,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
return;
}
DownloadListener dl = new DownloadListener(ssvm, sserver, volume, _timer, _volumeHostDao, volumeHost.getId(),
this, dcmd, _volumeDao, _storageMgr);
this, dcmd, _volumeDao, _storageMgr, _resourceLimitMgr, _alertMgr, _accountMgr);
if (downloadJobExists) {
dl.setCurrState(volumeHost.getDownloadState());
@ -561,18 +566,21 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
else{
s_logger.warn("Failed to get size for volume" + volume.getName());
}
String eventType = EventTypes.EVENT_VOLUME_UPLOAD;
String eventType = EventTypes.EVENT_VOLUME_UPLOAD;
if(volume.getAccountId() != Account.ACCOUNT_ID_SYSTEM){
UsageEventUtils.publishUsageEvent(eventType, volume.getAccountId(), host.getDataCenterId(),
volume.getId(), volume.getName(), null, 0l, size, volume.getClass().getName(), volume.getUuid());
}
}else if (dnldStatus == Status.DOWNLOAD_ERROR || dnldStatus == Status.ABANDONED || dnldStatus == Status.UNKNOWN){
//Decrement the volume count
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), com.cloud.configuration.Resource.ResourceType.volume);
//Decrement the volume and secondary storage space count
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(),
com.cloud.configuration.Resource.ResourceType.volume);
_resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(),
com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
}
txn.commit();
txn.commit();
}
@Override
public void handleSysTemplateDownload(HostVO host) {
List<HypervisorType> hypers = _resourceMgr.listAvailHypervisorInZone(host.getId(), host.getDataCenterId());
@ -748,6 +756,22 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
volume.setSize(volInfo.getSize());
_volumeDao.update(volumeHost.getVolumeId(), volume);
}
if (volInfo.getSize() > 0) {
try {
String url = _volumeHostDao.findByVolumeId(volume.getId()).getDownloadUrl();
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()),
com.cloud.configuration.Resource.ResourceType.secondary_storage,
volInfo.getSize() - UriUtils.getRemoteSize(url));
} catch (ResourceAllocationException e) {
s_logger.warn(e.getMessage());
_alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(),
volume.getPodId(), e.getMessage(), e.getMessage());
} finally {
_resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(),
com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
}
}
}
continue;
}
@ -857,6 +881,22 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
tmpltHost.setSize(tmpltInfo.getSize());
tmpltHost.setPhysicalSize(tmpltInfo.getPhysicalSize());
tmpltHost.setLastUpdated(new Date());
if (tmpltInfo.getSize() > 0) {
long accountId = tmplt.getAccountId();
try {
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId),
com.cloud.configuration.Resource.ResourceType.secondary_storage,
tmpltInfo.getSize() - UriUtils.getRemoteSize(tmplt.getUrl()));
} catch (ResourceAllocationException e) {
s_logger.warn(e.getMessage());
_alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, ssHost.getDataCenterId(),
null, e.getMessage(), e.getMessage());
} finally {
_resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId).getDomainId(),
com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
}
}
}
_vmTemplateHostDao.update(tmpltHost.getId(), tmpltHost);
} else {

View File

@ -123,20 +123,8 @@ import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.dao.UserVmDao;
import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotPolicyCmd;
import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotPoliciesCmd;
import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotPoliciesCmd;
import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd;
import org.apache.log4j.Logger;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
import java.util.*;
import com.cloud.vm.snapshot.VMSnapshot;
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
@Component
@Local(value = { SnapshotManager.class, SnapshotService.class })
public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, SnapshotService {
@ -209,6 +197,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
private int _totalRetries;
private int _pauseInterval;
private int _backupsnapshotwait;
Boolean backup;
protected SearchBuilder<SnapshotVO> PolicySnapshotSearch;
protected SearchBuilder<SnapshotPolicyVO> PoliciesForSnapSearch;
@ -307,16 +296,21 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid());
}
_resourceLimitMgr.incrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
_resourceLimitMgr.incrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
}
Boolean backup = Boolean.parseBoolean(this._configDao.getValue(Config.BackupSnapshotAferTakingSnapshot.toString()));
if (backup) {
this.backupSnapshot(snapshotId);
}
} catch(Exception e) {
s_logger.debug("Failed to create snapshot", e);
throw new CloudRuntimeException("Failed to create snapshot", e);
s_logger.debug("Failed to create snapshot", e);
if (backup) {
_resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.secondary_storage,
new Long(volume.getSize()));
} else {
_resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.primary_storage,
new Long(volume.getSize()));
}
throw new CloudRuntimeException("Failed to create snapshot", e);
}
return snapshot;
@ -539,7 +533,9 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
snapshotCheck.getDataCenterId(), snapshotId, snapshotCheck.getName(), null, null, 0L,
snapshotCheck.getClass().getName(), snapshotCheck.getUuid());
}
_resourceLimitMgr.decrementResourceCount(snapshotCheck.getAccountId(), ResourceType.snapshot);
_resourceLimitMgr.decrementResourceCount(snapshotCheck.getAccountId(), ResourceType.snapshot);
_resourceLimitMgr.decrementResourceCount(snapshotCheck.getAccountId(), ResourceType.secondary_storage,
new Long(snapshotCheck.getSize()));
}
return result;
} catch (Exception e) {
@ -745,6 +741,8 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
if (_snapshotDao.expunge(snapshot.getId())) {
if (snapshot.getRecurringType() == Type.MANUAL) {
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.snapshot);
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.secondary_storage,
new Long(snapshot.getSize()));
}
// Log event after successful deletion
@ -995,23 +993,29 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
ClusterVO cluster = _clusterDao.findById(storagePoolVO.getClusterId());
if (cluster != null && cluster.getHypervisorType() == HypervisorType.Ovm) {
throw new InvalidParameterValueException("Ovm won't support taking snapshot");
throw new InvalidParameterValueException("Ovm won't support taking snapshot");
}
// Verify permissions
_accountMgr.checkAccess(caller, null, true, volume);
Type snapshotType = getSnapshotType(policyId);
Account owner = _accountMgr.getAccount(volume.getAccountId());
try{
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.snapshot);
} catch (ResourceAllocationException e){
if (snapshotType != Type.MANUAL){
String msg = "Snapshot resource limit exceeded for account id : " + owner.getId() + ". Failed to create recurring snapshots";
s_logger.warn(msg);
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, msg,
"Snapshot resource limit exceeded for account id : " + owner.getId() + ". Failed to create recurring snapshots; please use updateResourceLimit to increase the limit");
}
throw e;
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.snapshot);
if (backup) {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.secondary_storage, new Long(volume.getSize()));
} else {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, new Long(volume.getSize()));
}
} catch (ResourceAllocationException e) {
if (snapshotType != Type.MANUAL){
String msg = "Snapshot resource limit exceeded for account id : " + owner.getId() + ". Failed to create recurring snapshots";
s_logger.warn(msg);
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, msg,
"Snapshot resource limit exceeded for account id : " + owner.getId() + ". Failed to create recurring snapshots; please use updateResourceLimit to increase the limit");
}
throw e;
}
// Determine the name for this snapshot
@ -1034,6 +1038,13 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
if (snapshot == null) {
throw new CloudRuntimeException("Failed to create snapshot for volume: "+volumeId);
}
if (backup) {
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage,
new Long(volume.getSize()));
} else {
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage,
new Long(volume.getSize()));
}
return snapshot;
}
@ -1042,6 +1053,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
String value = _configDao.getValue(Config.BackupSnapshotWait.toString());
_backupsnapshotwait = NumbersUtil.parseInt(value, Integer.parseInt(Config.BackupSnapshotWait.getDefaultValue()));
backup = Boolean.parseBoolean(this._configDao.getValue(Config.BackupSnapshotAferTakingSnapshot.toString()));
Type.HOURLY.setMax(NumbersUtil.parseInt(_configDao.getValue("snapshot.max.hourly"), HOURLYMAX));
Type.DAILY.setMax(NumbersUtil.parseInt(_configDao.getValue("snapshot.max.daily"), DAILYMAX));

View File

@ -39,7 +39,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.ImageService;
import org.apache.cloudstack.framework.async.AsyncCallFuture;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
@ -61,20 +60,11 @@ import com.cloud.storage.VMTemplateZoneVO;
import com.cloud.storage.download.DownloadMonitor;
import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.user.Account;
import com.cloud.utils.UriUtils;
import com.cloud.utils.db.DB;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.UserVmVO;
import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
import org.apache.log4j.Logger;
import javax.ejb.Local;
import java.net.*;
import java.util.List;
@Local(value=TemplateAdapter.class)
public class HypervisorTemplateAdapter extends TemplateAdapterBase implements TemplateAdapter {
private final static Logger s_logger = Logger.getLogger(HypervisorTemplateAdapter.class);
@ -134,6 +124,9 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te
}
profile.setUrl(validateUrl(url));
// Check that the resource limit for secondary storage won't be exceeded
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(cmd.getEntityOwnerId()),
ResourceType.secondary_storage, UriUtils.getRemoteSize(url));
return profile;
}
@ -160,6 +153,9 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te
}
profile.setUrl(validateUrl(url));
// Check that the resource limit for secondary storage won't be exceeded
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(cmd.getEntityOwnerId()),
ResourceType.secondary_storage, UriUtils.getRemoteSize(url));
return profile;
}
@ -183,10 +179,11 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te
s_logger.debug("create template Failed", e);
throw new CloudRuntimeException("create template Failed", e);
}
_resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
_resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
_resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.secondary_storage,
UriUtils.getRemoteSize(profile.getUrl()));
return template;
}
}
@Override @DB
public boolean delete(TemplateProfile profile) {
@ -294,8 +291,10 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te
s_logger.debug("Failed to acquire lock when deleting template with ID: " + templateId);
success = false;
} else if (_tmpltDao.remove(templateId)) {
// Decrement the number of templates
// Decrement the number of templates and total secondary storage space used by the account
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template);
_resourceLimitMgr.recalculateResourceCount(accountId, account.getDomainId(),
ResourceType.secondary_storage.getOrdinal());
}
} finally {

View File

@ -893,16 +893,19 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
@Override
@DB
public boolean copy(long userId, VMTemplateVO template, HostVO srcSecHost, DataCenterVO srcZone, DataCenterVO dstZone) throws StorageUnavailableException, ResourceAllocationException {
List<HostVO> dstSecHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(dstZone.getId());
long tmpltId = template.getId();
List<HostVO> dstSecHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(dstZone.getId());
long tmpltId = template.getId();
long dstZoneId = dstZone.getId();
if (dstSecHosts == null || dstSecHosts.isEmpty() ) {
throw new StorageUnavailableException("Destination zone is not ready", DataCenter.class, dstZone.getId());
}
if (dstSecHosts == null || dstSecHosts.isEmpty() ) {
throw new StorageUnavailableException("Destination zone is not ready", DataCenter.class, dstZone.getId());
}
AccountVO account = _accountDao.findById(template.getAccountId());
VMTemplateHostVO srcTmpltHost = _tmpltHostDao.findByHostTemplate(srcSecHost.getId(), tmpltId);
_resourceLimitMgr.checkResourceLimit(account, ResourceType.template);
// Event details
_resourceLimitMgr.checkResourceLimit(account, ResourceType.secondary_storage, new Long(srcTmpltHost.getSize()));
// Event details
String copyEventType;
String createEventType;
if (template.getFormat().equals(ImageFormat.ISO)){
@ -912,12 +915,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
copyEventType = EventTypes.EVENT_TEMPLATE_COPY;
createEventType = EventTypes.EVENT_TEMPLATE_CREATE;
}
Transaction txn = Transaction.currentTxn();
txn.start();
VMTemplateHostVO srcTmpltHost = _tmpltHostDao.findByHostTemplate(srcSecHost.getId(), tmpltId);
for ( HostVO dstSecHost : dstSecHosts ) {
VMTemplateHostVO dstTmpltHost = null;
try {
@ -948,7 +949,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
} finally {
txn.commit();
}
if(_downloadMonitor.copyTemplate(template, srcSecHost, dstSecHost) ) {
_tmpltDao.addTemplateToZone(template, dstZoneId);
@ -1711,6 +1712,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
VMTemplateVO privateTemplate = null;
Long accountId = null;
SnapshotVO snapshot = null;
VolumeVO volume = null;
try {
TemplateInfo tmplInfo = this.tmplFactory.getTemplate(templateId);
@ -1725,6 +1727,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
SnapshotInfo snapInfo = this.snapshotFactory.getSnapshot(snapshotId);
future = this.imageSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store.get(0));
} else if (volumeId != null) {
volume = _volumeDao.findById(volumeId);
VolumeInfo volInfo = this.volFactory.getVolume(volumeId);
future = this.imageSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store.get(0));
} else {
@ -1757,7 +1760,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
s_logger.debug("Failed to create template", e);
throw new CloudRuntimeException("Failed to create template", e);
}
} finally {
/*if (snapshot != null && snapshot.getSwiftId() != null
&& secondaryStorageURL != null && zoneId != null
@ -1773,8 +1776,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
// decrement resource count
if (accountId != null) {
_resourceLimitMgr.decrementResourceCount(accountId,
ResourceType.template);
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template);
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.secondary_storage,
new Long(volume != null ? volume.getSize() : snapshot.getSize()));
}
txn.commit();
}
@ -1854,6 +1858,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
HypervisorType hyperType;
VolumeVO volume = null;
SnapshotVO snapshot = null;
VMTemplateVO privateTemplate = null;
if (volumeId != null) { // create template from volume
volume = this._volumeDao.findById(volumeId);
@ -1879,7 +1884,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
}
hyperType = this._volumeDao.getHypervisorType(volumeId);
} else { // create template from snapshot
SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
snapshot = _snapshotDao.findById(snapshotId);
if (snapshot == null) {
throw new InvalidParameterValueException(
"Failed to create private template record, unable to find snapshot "
@ -1911,8 +1916,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
hyperType = snapshot.getHypervisorType();
}
_resourceLimitMgr.checkResourceLimit(templateOwner,
ResourceType.template);
_resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.template);
_resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.secondary_storage,
new Long(volume != null ? volume.getSize() : snapshot.getSize()));
if (!isAdmin || featured == null) {
featured = Boolean.FALSE;
@ -1973,8 +1979,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
this._templateDetailsDao.persist(template.getId(), cmd.getDetails());
}
_resourceLimitMgr.incrementResourceCount(templateOwner.getId(),
ResourceType.template);
_resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.template);
_resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.secondary_storage,
new Long(volume != null ? volume.getSize() : snapshot.getSize()));
}
if (template != null) {

View File

@ -3571,8 +3571,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
DataCenterVO zone = _dcDao.findById(vm.getDataCenterId());
// Get serviceOffering for Virtual Machine
// Get serviceOffering and Volumes for Virtual Machine
ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getServiceOfferingId());
List<VolumeVO> volumes = _volsDao.findByInstance(cmd.getVmId());
//Remove vm from instance group
removeInstanceFromInstanceGroup(cmd.getVmId());
@ -3580,9 +3581,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
// VV 2: check if account/domain is with in resource limits to create a new vm
resourceLimitCheck(newAccount, new Long(offering.getCpu()), new Long(offering.getRamSize()));
// VV 3: check if volumes are with in resource limits
// VV 3: check if volumes and primary storage space are with in resource limits
_resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.volume,
_volsDao.findByInstance(cmd.getVmId()).size());
Long totalVolumesSize = (long) 0;
for (VolumeVO volume : volumes) {
totalVolumesSize += volume.getSize();
}
_resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.primary_storage, totalVolumesSize);
// VV 4: Check if new owner can use the vm template
VirtualMachineTemplate template = _templateDao.findById(vm
@ -3614,14 +3620,17 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
_vmDao.persist(vm);
// OS 2: update volume
List<VolumeVO> volumes = _volsDao.findByInstance(cmd.getVmId());
for (VolumeVO volume : volumes) {
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(),
volume.getDataCenterId(), volume.getId(), volume.getName(), Volume.class.getName(), volume.getUuid());
_resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.volume);
_resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.primary_storage,
new Long(volume.getSize()));
volume.setAccountId(newAccount.getAccountId());
_volsDao.persist(volume);
_resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.volume);
_resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.primary_storage,
new Long(volume.getSize()));
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(),
volume.getDataCenterId(), volume.getId(), volume.getName(),
volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(),

View File

@ -16,8 +16,6 @@
// under the License.
package com.cloud.resourcelimit;
import javax.inject.Inject;
import junit.framework.TestCase;
import org.apache.log4j.Logger;
@ -72,11 +70,23 @@ public class ResourceLimitManagerImplTest extends TestCase{
// update resource Limit for a domain for resource_type = 8 (CPU)
resourceLimitServiceCall(null, (long) 1, 8, (long) 40);
// update resource Limit for an account for resource_type = 9 (Memory)
// update resource Limit for an account for resource_type = 9 (Memory (in MiB))
resourceLimitServiceCall((long) 1, (long) 1, 9, (long) 4096);
// update resource Limit for a domain for resource_type = 9 (Memory)
// update resource Limit for a domain for resource_type = 9 (Memory (in MiB))
resourceLimitServiceCall(null, (long) 1, 9, (long) 10240);
// update resource Limit for an account for resource_type = 10 (Primary storage (in GiB))
resourceLimitServiceCall((long) 1, (long) 1, 10, (long) 200);
// update resource Limit for a domain for resource_type = 10 (Primary storage (in GiB))
resourceLimitServiceCall(null, (long) 1, 10, (long) 200);
// update resource Limit for an account for resource_type = 11 (Secondary storage (in GiB))
resourceLimitServiceCall((long) 1, (long) 1, 10, (long) 400);
// update resource Limit for a domain for resource_type = 11 (Secondary storage (in GiB))
resourceLimitServiceCall(null, (long) 1, 10, (long) 400);
}
private void resourceLimitServiceCall(Long accountId, Long domainId, Integer resourceType, Long max) {

View File

@ -132,6 +132,14 @@ public class MockResourceLimitManagerImpl extends ManagerBase implements Resourc
return 0;
}
/* (non-Javadoc)
* @see com.cloud.user.ResourceLimitService#calculateSecondaryStorageForAccount(long)
*/
public long calculateSecondaryStorageForAccount(long accountId) {
// TODO Auto-generated method stub
return 0;
}
/* (non-Javadoc)
* @see com.cloud.user.ResourceLimitService#getResourceCount(com.cloud.user.Account, com.cloud.configuration.Resource.ResourceType)
*/

View File

@ -263,14 +263,6 @@ CREATE TABLE `cloud`.`region` (
INSERT INTO `cloud`.`region` values ('1','Local','http://localhost:8080/client/');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Account Defaults', 'DEFAULT', 'management-server', 'max.account.cpus', '40', 'The default maximum number of cpu cores that can be used for an account');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Account Defaults', 'DEFAULT', 'management-server', 'max.account.memory', '40960', 'The default maximum memory (in MB) that can be used for an account');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Project Defaults', 'DEFAULT', 'management-server', 'max.project.cpus', '40', 'The default maximum number of cpu cores that can be used for a project');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Project Defaults', 'DEFAULT', 'management-server', 'max.project.memory', '40960', 'The default maximum memory (in MB) that can be used for a project');
ALTER TABLE `cloud_usage`.`account` ADD COLUMN `region_id` int unsigned NOT NULL DEFAULT '1';
CREATE TABLE `cloud`.`nicira_nvp_router_map` (
@ -1293,10 +1285,6 @@ CREATE VIEW `cloud`.`account_view` AS
projectcount.count projectTotal,
networklimit.max networkLimit,
networkcount.count networkTotal,
cpulimit.max cpuLimit,
cpucount.count cpuTotal,
memorylimit.max memoryLimit,
memorycount.count memoryTotal,
async_job.id job_id,
async_job.uuid job_uuid,
async_job.job_status job_status,
@ -1365,18 +1353,6 @@ CREATE VIEW `cloud`.`account_view` AS
`cloud`.`resource_count` networkcount ON account.id = networkcount.account_id
and networkcount.type = 'network'
left join
`cloud`.`resource_limit` cpulimit ON account.id = cpulimit.account_id
and cpulimit.type = 'cpu'
left join
`cloud`.`resource_count` cpucount ON account.id = cpucount.account_id
and cpucount.type = 'cpu'
left join
`cloud`.`resource_limit` memorylimit ON account.id = memorylimit.account_id
and memorylimit.type = 'memory'
left join
`cloud`.`resource_count` memorycount ON account.id = memorycount.account_id
and memorycount.type = 'memory'
left join
`cloud`.`async_job` ON async_job.instance_id = account.id
and async_job.instance_type = 'Account'
and async_job.job_status = 0;

View File

@ -202,7 +202,6 @@ CREATE VIEW `cloud`.`event_view` AS
left join
`cloud`.`event` eve ON event.start_id = eve.id;
ALTER TABLE `cloud`.`region` ADD COLUMN `gslb_service_enabled` tinyint(1) unsigned NOT NULL DEFAULT 1 COMMENT 'Is GSLB service enalbed in the Region';
ALTER TABLE `cloud`.`external_load_balancer_devices` ADD COLUMN `is_gslb_provider` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if load balancer appliance is acting as gslb service provider in the zone';
@ -239,3 +238,155 @@ CREATE TABLE `cloud`.`global_load_balancer_lb_rule_map` (
CONSTRAINT `fk_gslb_rule_id` FOREIGN KEY(`gslb_rule_id`) REFERENCES `global_load_balancing_rules`(`id`) ON DELETE CASCADE,
CONSTRAINT `fk_lb_rule_id` FOREIGN KEY(`lb_rule_id`) REFERENCES `load_balancing_rules`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Account Defaults', 'DEFAULT', 'management-server', 'max.account.cpus', '40', 'The default maximum number of cpu cores that can be used for an account');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Account Defaults', 'DEFAULT', 'management-server', 'max.account.memory', '40960', 'The default maximum memory (in MiB) that can be used for an account');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Account Defaults', 'DEFAULT', 'management-server', 'max.account.primary.storage', '200', 'The default maximum primary storage space (in GiB) that can be used for an account');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Account Defaults', 'DEFAULT', 'management-server', 'max.account.secondary.storage', '400', 'The default maximum secondary storage space (in GiB) that can be used for an account');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Project Defaults', 'DEFAULT', 'management-server', 'max.project.cpus', '40', 'The default maximum number of cpu cores that can be used for a project');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Project Defaults', 'DEFAULT', 'management-server', 'max.project.memory', '40960', 'The default maximum memory (in MiB) that can be used for a project');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Project Defaults', 'DEFAULT', 'management-server', 'max.project.primary.storage', '200', 'The default maximum primary storage space (in GiB) that can be used for a project');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Project Defaults', 'DEFAULT', 'management-server', 'max.project.secondary.storage', '400', 'The default maximum secondary storage space (in GiB) that can be used for a project');
DROP VIEW IF EXISTS `cloud`.`account_view`;
CREATE VIEW `cloud`.`account_view` AS
select
account.id,
account.uuid,
account.account_name,
account.type,
account.state,
account.removed,
account.cleanup_needed,
account.network_domain,
domain.id domain_id,
domain.uuid domain_uuid,
domain.name domain_name,
domain.path domain_path,
data_center.id data_center_id,
data_center.uuid data_center_uuid,
data_center.name data_center_name,
account_netstats_view.bytesReceived,
account_netstats_view.bytesSent,
vmlimit.max vmLimit,
vmcount.count vmTotal,
runningvm.vmcount runningVms,
stoppedvm.vmcount stoppedVms,
iplimit.max ipLimit,
ipcount.count ipTotal,
free_ip_view.free_ip ipFree,
volumelimit.max volumeLimit,
volumecount.count volumeTotal,
snapshotlimit.max snapshotLimit,
snapshotcount.count snapshotTotal,
templatelimit.max templateLimit,
templatecount.count templateTotal,
vpclimit.max vpcLimit,
vpccount.count vpcTotal,
projectlimit.max projectLimit,
projectcount.count projectTotal,
networklimit.max networkLimit,
networkcount.count networkTotal,
cpulimit.max cpuLimit,
cpucount.count cpuTotal,
memorylimit.max memoryLimit,
memorycount.count memoryTotal,
primary_storage_limit.max primaryStorageLimit,
primary_storage_count.count primaryStorageTotal,
secondary_storage_limit.max secondaryStorageLimit,
secondary_storage_count.count secondaryStorageTotal,
async_job.id job_id,
async_job.uuid job_uuid,
async_job.job_status job_status,
async_job.account_id job_account_id
from
`cloud`.`free_ip_view`,
`cloud`.`account`
inner join
`cloud`.`domain` ON account.domain_id = domain.id
left join
`cloud`.`data_center` ON account.default_zone_id = data_center.id
left join
`cloud`.`account_netstats_view` ON account.id = account_netstats_view.account_id
left join
`cloud`.`resource_limit` vmlimit ON account.id = vmlimit.account_id
and vmlimit.type = 'user_vm'
left join
`cloud`.`resource_count` vmcount ON account.id = vmcount.account_id
and vmcount.type = 'user_vm'
left join
`cloud`.`account_vmstats_view` runningvm ON account.id = runningvm.account_id
and runningvm.state = 'Running'
left join
`cloud`.`account_vmstats_view` stoppedvm ON account.id = stoppedvm.account_id
and stoppedvm.state = 'Stopped'
left join
`cloud`.`resource_limit` iplimit ON account.id = iplimit.account_id
and iplimit.type = 'public_ip'
left join
`cloud`.`resource_count` ipcount ON account.id = ipcount.account_id
and ipcount.type = 'public_ip'
left join
`cloud`.`resource_limit` volumelimit ON account.id = volumelimit.account_id
and volumelimit.type = 'volume'
left join
`cloud`.`resource_count` volumecount ON account.id = volumecount.account_id
and volumecount.type = 'volume'
left join
`cloud`.`resource_limit` snapshotlimit ON account.id = snapshotlimit.account_id
and snapshotlimit.type = 'snapshot'
left join
`cloud`.`resource_count` snapshotcount ON account.id = snapshotcount.account_id
and snapshotcount.type = 'snapshot'
left join
`cloud`.`resource_limit` templatelimit ON account.id = templatelimit.account_id
and templatelimit.type = 'template'
left join
`cloud`.`resource_count` templatecount ON account.id = templatecount.account_id
and templatecount.type = 'template'
left join
`cloud`.`resource_limit` vpclimit ON account.id = vpclimit.account_id
and vpclimit.type = 'vpc'
left join
`cloud`.`resource_count` vpccount ON account.id = vpccount.account_id
and vpccount.type = 'vpc'
left join
`cloud`.`resource_limit` projectlimit ON account.id = projectlimit.account_id
and projectlimit.type = 'project'
left join
`cloud`.`resource_count` projectcount ON account.id = projectcount.account_id
and projectcount.type = 'project'
left join
`cloud`.`resource_limit` networklimit ON account.id = networklimit.account_id
and networklimit.type = 'network'
left join
`cloud`.`resource_count` networkcount ON account.id = networkcount.account_id
and networkcount.type = 'network'
left join
`cloud`.`resource_limit` cpulimit ON account.id = cpulimit.account_id
and cpulimit.type = 'cpu'
left join
`cloud`.`resource_count` cpucount ON account.id = cpucount.account_id
and cpucount.type = 'cpu'
left join
`cloud`.`resource_limit` memorylimit ON account.id = memorylimit.account_id
and memorylimit.type = 'memory'
left join
`cloud`.`resource_count` memorycount ON account.id = memorycount.account_id
and memorycount.type = 'memory'
left join
`cloud`.`resource_limit` primary_storage_limit ON account.id = primary_storage_limit.account_id
and primary_storage_limit.type = 'primary_storage'
left join
`cloud`.`resource_count` primary_storage_count ON account.id = primary_storage_count.account_id
and primary_storage_count.type = 'primary_storage'
left join
`cloud`.`resource_limit` secondary_storage_limit ON account.id = secondary_storage_limit.account_id
and secondary_storage_limit.type = 'secondary_storage'
left join
`cloud`.`resource_count` secondary_storage_count ON account.id = secondary_storage_count.account_id
and secondary_storage_count.type = 'secondary_storage'
left join
`cloud`.`async_job` ON async_job.instance_id = account.id
and async_job.instance_type = 'Account'
and async_job.job_status = 0;

View File

@ -17,10 +17,14 @@
package com.cloud.utils;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import javax.net.ssl.HttpsURLConnection;
import com.cloud.utils.exception.CloudRuntimeException;
public class UriUtils {
@ -78,4 +82,33 @@ public class UriUtils {
// no need to do URL component encoding
return url;
}
// Get the size of a file from URL response header.
public static Long getRemoteSize(String url) {
Long remoteSize = (long) 0;
HttpURLConnection httpConn = null;
HttpsURLConnection httpsConn = null;
try {
URI uri = new URI(url);
if(uri.getScheme().equalsIgnoreCase("http")) {
httpConn = (HttpURLConnection) uri.toURL().openConnection();
remoteSize = Long.parseLong(httpConn.getHeaderField("content-length"));
}
else if(uri.getScheme().equalsIgnoreCase("https")) {
httpsConn = (HttpsURLConnection) uri.toURL().openConnection();
remoteSize = Long.parseLong(httpsConn.getHeaderField("content-length"));
}
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Invalid URL " + url);
} catch (IOException e) {
throw new IllegalArgumentException("Unable to establish connection with URL " + url);
} finally {
if (httpConn != null) {
httpConn.disconnect();
} else if (httpsConn != null) {
httpsConn.disconnect();
}
}
return remoteSize;
}
}