Skip to content

Commit 06ee2fe

Browse files
GutoVeroneziDaan Hoogland
authored andcommitted
Implement/fix limit validation for secondary storage
1 parent e0ef3a6 commit 06ee2fe

7 files changed

Lines changed: 158 additions & 423 deletions

File tree

plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ public VMTemplateVO create(TemplateProfile profile) {
106106
}
107107
}
108108

109-
_resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
110109
return template;
111110
}
112111

server/src/main/java/com/cloud/storage/ImageStoreUploadMonitorImpl.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
import javax.naming.ConfigurationException;
2727

2828
import com.cloud.agent.api.to.OVFInformationTO;
29+
import com.cloud.exception.ResourceAllocationException;
30+
import com.cloud.resourcelimit.CheckedReservation;
31+
import com.cloud.user.Account;
32+
import com.cloud.user.dao.AccountDao;
2933
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
3034
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
3135
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
@@ -37,6 +41,7 @@
3741
import org.apache.cloudstack.framework.config.ConfigKey;
3842
import org.apache.cloudstack.framework.config.Configurable;
3943
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
44+
import org.apache.cloudstack.reservation.dao.ReservationDao;
4045
import org.apache.cloudstack.storage.command.UploadStatusAnswer;
4146
import org.apache.cloudstack.storage.command.UploadStatusAnswer.UploadStatus;
4247
import org.apache.cloudstack.storage.command.UploadStatusCommand;
@@ -117,6 +122,10 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
117122
private TemplateJoinDao templateJoinDao;
118123
@Inject
119124
private DeployAsIsHelper deployAsIsHelper;
125+
@Inject
126+
private ReservationDao reservationDao;
127+
@Inject
128+
private AccountDao accountDao;
120129

121130
private long _nodeId;
122131
private ScheduledExecutorService _executor = null;
@@ -436,8 +445,23 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
436445
break;
437446
}
438447
}
448+
449+
Account owner = accountDao.findById(template.getAccountId());
450+
long templateSize = answer.getVirtualSize();
451+
452+
try (CheckedReservation secondaryStorageReservation = new CheckedReservation(owner, Resource.ResourceType.secondary_storage, null, null, templateSize, reservationDao, _resourceLimitMgr)) {
453+
_resourceLimitMgr.incrementResourceCount(owner.getId(), Resource.ResourceType.secondary_storage, templateSize);
454+
} catch (ResourceAllocationException e) {
455+
tmpTemplateDataStore.setDownloadState(VMTemplateStorageResourceAssoc.Status.UPLOAD_ERROR);
456+
tmpTemplateDataStore.setState(State.Failed);
457+
stateMachine.transitTo(tmpTemplate, VirtualMachineTemplate.Event.OperationFailed, null, _templateDao);
458+
msg = String.format("Upload of template [%s] failed because its owner [%s] does not have enough secondary storage space available.", template.getUuid(), owner.getUuid());
459+
logger.warn(msg);
460+
sendAlert = true;
461+
break;
462+
}
463+
439464
stateMachine.transitTo(tmpTemplate, VirtualMachineTemplate.Event.OperationSucceeded, null, _templateDao);
440-
_resourceLimitMgr.incrementResourceCount(template.getAccountId(), Resource.ResourceType.secondary_storage, answer.getVirtualSize());
441465
//publish usage event
442466
String etype = EventTypes.EVENT_TEMPLATE_CREATE;
443467
if (tmpTemplate.getFormat() == Storage.ImageFormat.ISO) {

server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
108108
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
109109
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
110+
import org.apache.cloudstack.utils.bytescale.ByteScaleUtils;
110111
import org.apache.cloudstack.utils.identity.ManagementServerNode;
111112
import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
112113
import org.apache.cloudstack.utils.jsinterpreter.TagAsRuleHelper;
@@ -522,7 +523,7 @@ public GetUploadParamsResponse doInTransaction(TransactionStatus status) throws
522523
Account account = _accountDao.findById(accountId);
523524
Domain domain = domainDao.findById(account.getDomainId());
524525

525-
command.setDefaultMaxSecondaryStorageInGB(_resourceLimitMgr.findCorrectResourceLimitForAccountAndDomain(account, domain, ResourceType.secondary_storage, null));
526+
command.setDefaultMaxSecondaryStorageInGB(ByteScaleUtils.bytesToGibibytes(_resourceLimitMgr.findCorrectResourceLimitForAccountAndDomain(account, domain, ResourceType.secondary_storage, null)));
526527
command.setAccountId(accountId);
527528
Gson gson = new GsonBuilder().create();
528529
String metadata = EncryptionUtil.encodeData(gson.toJson(command), key);

server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,8 @@
3737
import org.apache.cloudstack.annotation.dao.AnnotationDao;
3838
import org.apache.cloudstack.api.ApiCommandResourceType;
3939
import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
40-
import org.apache.cloudstack.api.command.user.iso.GetUploadParamsForIsoCmd;
4140
import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
4241
import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
43-
import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplateCmd;
4442
import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
4543
import org.apache.cloudstack.context.CallContext;
4644
import org.apache.cloudstack.direct.download.DirectDownloadManager;
@@ -66,6 +64,7 @@
6664
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
6765
import org.apache.cloudstack.storage.heuristics.HeuristicRuleHelper;
6866
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
67+
import org.apache.cloudstack.utils.bytescale.ByteScaleUtils;
6968
import org.apache.cloudstack.utils.security.DigestHelper;
7069
import org.apache.commons.collections.CollectionUtils;
7170

@@ -217,19 +216,6 @@ public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationExce
217216
profile.setSize(templateSize);
218217
}
219218
profile.setUrl(url);
220-
// Check that the resource limit for secondary storage won't be exceeded
221-
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(cmd.getEntityOwnerId()),
222-
ResourceType.secondary_storage,
223-
UriUtils.getRemoteSize(url, followRedirects));
224-
return profile;
225-
}
226-
227-
@Override
228-
public TemplateProfile prepare(GetUploadParamsForIsoCmd cmd) throws ResourceAllocationException {
229-
TemplateProfile profile = super.prepare(cmd);
230-
231-
// Check that the resource limit for secondary storage won't be exceeded
232-
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(cmd.getEntityOwnerId()), ResourceType.secondary_storage);
233219
return profile;
234220
}
235221

@@ -247,19 +233,7 @@ public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocatio
247233
profile.setSize(templateSize);
248234
}
249235
profile.setUrl(url);
250-
// Check that the resource limit for secondary storage won't be exceeded
251-
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(cmd.getEntityOwnerId()),
252-
ResourceType.secondary_storage,
253-
UriUtils.getRemoteSize(url, followRedirects));
254-
return profile;
255-
}
256-
257-
@Override
258-
public TemplateProfile prepare(GetUploadParamsForTemplateCmd cmd) throws ResourceAllocationException {
259-
TemplateProfile profile = super.prepare(cmd);
260236

261-
// Check that the resource limit for secondary storage won't be exceeded
262-
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(cmd.getEntityOwnerId()), ResourceType.secondary_storage);
263237
return profile;
264238
}
265239

@@ -287,7 +261,6 @@ public VMTemplateVO create(TemplateProfile profile) {
287261
persistDirectDownloadTemplate(template.getId(), profile.getSize());
288262
}
289263

290-
_resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
291264
return template;
292265
}
293266

@@ -434,7 +407,7 @@ public List<TemplateOrVolumePostUploadCommand> doInTransaction(TransactionStatus
434407
if(payloads.isEmpty()) {
435408
throw new CloudRuntimeException("unable to find zone or an image store with enough capacity");
436409
}
437-
_resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
410+
438411
return payloads;
439412
}
440413
});
@@ -477,7 +450,7 @@ private void postUploadAllocation(List<DataStore> imageStores, VMTemplateVO temp
477450
Account account = _accountDao.findById(accountId);
478451
Domain domain = _domainDao.findById(account.getDomainId());
479452

480-
payload.setDefaultMaxSecondaryStorageInGB(_resourceLimitMgr.findCorrectResourceLimitForAccountAndDomain(account, domain, ResourceType.secondary_storage, null));
453+
payload.setDefaultMaxSecondaryStorageInGB(ByteScaleUtils.bytesToGibibytes(_resourceLimitMgr.findCorrectResourceLimitForAccountAndDomain(account, domain, ResourceType.secondary_storage, null)));
481454
payload.setAccountId(accountId);
482455
payload.setRemoteEndPoint(ep.getPublicAddr());
483456
payload.setRequiresHvm(template.requiresHvm());
@@ -543,8 +516,8 @@ protected Void createTemplateAsyncCallBack(AsyncCallbackDispatcher<HypervisorTem
543516
UsageEventUtils.publishUsageEvent(etype, template.getAccountId(), -1, template.getId(), template.getName(), null, null, physicalSize,
544517
template.getSize(), VirtualMachineTemplate.class.getName(), template.getUuid());
545518
}
546-
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.secondary_storage, template.getSize());
547519
}
520+
_resourceLimitMgr.recalculateResourceCount(accountId, tmplt.getDomainId(), ResourceType.secondary_storage.getOrdinal());
548521
}
549522

550523
return null;

server/src/main/java/com/cloud/template/TemplateAdapterBase.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151

5252
import com.cloud.api.ApiDBUtils;
5353
import com.cloud.configuration.Config;
54-
import com.cloud.configuration.Resource.ResourceType;
5554
import com.cloud.dc.DataCenterVO;
5655
import com.cloud.dc.dao.DataCenterDao;
5756
import com.cloud.domain.dao.DomainDao;
@@ -227,8 +226,6 @@ public TemplateProfile prepare(boolean isIso, long userId, String name, String d
227226
throw new IllegalArgumentException("Unable to find user with id " + userId);
228227
}
229228

230-
_resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.template);
231-
232229
// If a zoneId is specified, make sure it is valid
233230
if (zoneIdList != null) {
234231
for (Long zoneId :zoneIdList) {

0 commit comments

Comments
 (0)