diff --git a/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java b/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java index 0a5f1d68951..5d1e56bd773 100644 --- a/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java +++ b/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java @@ -49,6 +49,10 @@ public class TemplateOrVolumePostUploadCommand { String description; + private String defaultMaxAccountSecondaryStorage; + + private long accountId; + public TemplateOrVolumePostUploadCommand(long entityId, String entityUUID, String absolutePath, String checksum, String type, String name, String imageFormat, String dataTo, String dataToRole) { this.entityId = entityId; @@ -176,4 +180,20 @@ public class TemplateOrVolumePostUploadCommand { public void setDescription(String description) { this.description = description; } + + public void setDefaultMaxAccountSecondaryStorage(String defaultMaxAccountSecondaryStorage) { + this.defaultMaxAccountSecondaryStorage = defaultMaxAccountSecondaryStorage; + } + + public String getDefaultMaxAccountSecondaryStorage() { + return defaultMaxAccountSecondaryStorage; + } + + public void setAccountId(long accountId) { + this.accountId = accountId; + } + + public long getAccountId() { + return accountId; + } } diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index d7000f7af58..7e122843473 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -339,6 +339,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic command.setLocalPath(volumeStore.getLocalDownloadPath()); //using the existing max upload size configuration command.setMaxUploadSize(_configDao.getValue(Config.MaxUploadVolumeSize.key())); + command.setDefaultMaxAccountSecondaryStorage(_configDao.getValue(Config.DefaultMaxAccountSecondaryStorage.key())); + command.setAccountId(vol.getAccountId()); Gson gson = new GsonBuilder().create(); String metadata = EncryptionUtil.encodeData(gson.toJson(command), key); response.setMetadata(metadata); diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index 265bc120703..38a145b74c6 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -270,6 +270,8 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase { templateOnStore.getDataStore().getRole().toString()); //using the existing max template size configuration payload.setMaxUploadSize(_configDao.getValue(Config.MaxTemplateAndIsoSize.key())); + payload.setDefaultMaxAccountSecondaryStorage(_configDao.getValue(Config.DefaultMaxAccountSecondaryStorage.key())); + payload.setAccountId(template.getAccountId()); payload.setRemoteEndPoint(ep.getPublicAddr()); payload.setRequiresHvm(template.requiresHvm()); payload.setDescription(template.getDisplayText()); diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 1cd69fc36cd..bedd5c18be3 100755 --- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -48,6 +48,7 @@ import javax.naming.ConfigurationException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.storage.Storage; +import com.cloud.storage.template.TemplateConstants; import com.cloud.utils.EncryptionUtil; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -2633,6 +2634,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S updateStateMapWithError(uuid, errorMessage); throw new InvalidParameterValueException(errorMessage); } + checkSecondaryStorageResourceLimit(cmd, contentLengthInGB); try { String absolutePath = cmd.getAbsolutePath(); uploadEntity = new UploadEntity(uuid, cmd.getEntityId(), UploadEntity.Status.IN_PROGRESS, cmd.getName(), absolutePath); @@ -2663,6 +2665,52 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return uploadEntity; } + private synchronized void checkSecondaryStorageResourceLimit(TemplateOrVolumePostUploadCommand cmd, int contentLengthInGB) { + String rootDir = this.getRootDir(cmd.getDataTo()) + File.separator; + long accountId = cmd.getAccountId(); + + long accountTemplateDirSize = 0; + File accountTemplateDir = new File(rootDir + getTemplatePathForAccount(accountId)); + if(accountTemplateDir.exists()) { + FileUtils.sizeOfDirectory(accountTemplateDir); + } + long accountVolumeDirSize = 0; + File accountVolumeDir = new File(rootDir + getVolumePathForAccount(accountId)); + if(accountVolumeDir.exists()) { + accountVolumeDirSize = FileUtils.sizeOfDirectory(accountVolumeDir); + } + long accountSnapshotDirSize = 0; + File accountSnapshotDir = new File(rootDir + getSnapshotPathForAccount(accountId)); + if(accountSnapshotDir.exists()) { + accountSnapshotDirSize = FileUtils.sizeOfDirectory(accountSnapshotDir); + } + s_logger.debug("accountTemplateDirSize: " + accountTemplateDirSize + " accountSnapshotDirSize: " +accountSnapshotDirSize + " accountVolumeDirSize: " + + accountVolumeDirSize); + + int accountDirSizeInGB = getSizeInGB(accountTemplateDirSize + accountSnapshotDirSize + accountVolumeDirSize); + int defaultMaxAccountSecondaryStorageInGB = Integer.parseInt(cmd.getDefaultMaxAccountSecondaryStorage()); + + if ((accountDirSizeInGB + contentLengthInGB) > defaultMaxAccountSecondaryStorageInGB) { + s_logger.error("accountDirSizeInGb: " + accountDirSizeInGB + " defaultMaxAccountSecondaryStorageInGB: " + defaultMaxAccountSecondaryStorageInGB + " contentLengthInGB:" + + contentLengthInGB); + String errorMessage = "Maximum number of resources of type secondary_storage for account has exceeded"; + updateStateMapWithError(cmd.getEntityUUID(), errorMessage); + throw new InvalidParameterValueException(errorMessage); + } + } + + private String getVolumePathForAccount(long accountId) { + return TemplateConstants.DEFAULT_VOLUME_ROOT_DIR + "/" + accountId; + } + + private String getTemplatePathForAccount(long accountId) { + return TemplateConstants.DEFAULT_TMPLT_ROOT_DIR + "/" + TemplateConstants.DEFAULT_TMPLT_FIRST_LEVEL_DIR + accountId; + } + + private String getSnapshotPathForAccount(long accountId) { + return TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR + "/" + accountId; + } + private boolean isOneTimePostUrlUsed(TemplateOrVolumePostUploadCommand cmd) { String uuid = cmd.getEntityUUID(); String uploadPath = this.getRootDir(cmd.getDataTo()) + File.separator + cmd.getAbsolutePath();