Skip to content

Commit 3f087ec

Browse files
committed
Merge remote-tracking branch 'upstream/main' into bnr-object-limits
2 parents be031e2 + 449d3c7 commit 3f087ec

File tree

27 files changed

+2974
-569
lines changed

27 files changed

+2974
-569
lines changed

api/src/main/java/com/cloud/vm/UserVmService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ VirtualMachine migrateVirtualMachine(Long vmId, Host destinationHost) throws Res
469469
VirtualMachine migrateVirtualMachineWithVolume(Long vmId, Host destinationHost, Map<String, String> volumeToPool) throws ResourceUnavailableException,
470470
ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException;
471471

472-
UserVm moveVMToUser(AssignVMCmd moveUserVMCmd) throws ResourceAllocationException, ConcurrentOperationException, ResourceUnavailableException,
472+
UserVm moveVmToUser(AssignVMCmd moveUserVMCmd) throws ResourceAllocationException, ConcurrentOperationException, ResourceUnavailableException,
473473
InsufficientCapacityException;
474474

475475
VirtualMachine vmStorageMigration(Long vmId, StoragePool destPool);

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,11 +1193,6 @@ public class ApiConstants {
11931193
public static final String SHAREDFSVM_MIN_CPU_COUNT = "sharedfsvmmincpucount";
11941194
public static final String SHAREDFSVM_MIN_RAM_SIZE = "sharedfsvmminramsize";
11951195

1196-
public static final String PARAMETER_DESCRIPTION_ACTIVATION_RULE = "Quota tariff's activation rule. It can receive a JS script that results in either " +
1197-
"a boolean or a numeric value: if it results in a boolean value, the tariff value will be applied according to the result; if it results in a numeric value, the " +
1198-
"numeric value will be applied; if the result is neither a boolean nor a numeric value, the tariff will not be applied. If the rule is not informed, the tariff " +
1199-
"value will be applied.";
1200-
12011196
// Object Storage related
12021197
public static final String BUCKET_AVAILABLE = "bucketavaialable";
12031198
public static final String BUCKET_LIMIT = "bucketlimit";
@@ -1208,6 +1203,18 @@ public class ApiConstants {
12081203
public static final String OBJECT_STORAGE_LIMIT = "objectstoragelimit";
12091204
public static final String OBJECT_STORAGE_TOTAL = "objectstoragetotal";
12101205

1206+
public static final String PARAMETER_DESCRIPTION_ACTIVATION_RULE = "Quota tariff's activation rule. It can receive a JS script that results in either " +
1207+
"a boolean or a numeric value: if it results in a boolean value, the tariff value will be applied according to the result; if it results in a numeric value, the " +
1208+
"numeric value will be applied; if the result is neither a boolean nor a numeric value, the tariff will not be applied. If the rule is not informed, the tariff " +
1209+
"value will be applied.";
1210+
public static final String PARAMETER_DESCRIPTION_START_DATE_POSSIBLE_FORMATS = "The recommended format is \"yyyy-MM-dd'T'HH:mm:ssZ\" (e.g.: \"2023-01-01T12:00:00+0100\"); " +
1211+
"however, the following formats are also accepted: \"yyyy-MM-dd HH:mm:ss\" (e.g.: \"2023-01-01 12:00:00\") and \"yyyy-MM-dd\" (e.g.: \"2023-01-01\" - if the time is not " +
1212+
"added, it will be interpreted as \"00:00:00\"). If the recommended format is not used, the date will be considered in the server timezone.";
1213+
1214+
public static final String PARAMETER_DESCRIPTION_END_DATE_POSSIBLE_FORMATS = "The recommended format is \"yyyy-MM-dd'T'HH:mm:ssZ\" (e.g.: \"2023-01-01T12:00:00+0100\"); " +
1215+
"however, the following formats are also accepted: \"yyyy-MM-dd HH:mm:ss\" (e.g.: \"2023-01-01 12:00:00\") and \"yyyy-MM-dd\" (e.g.: \"2023-01-01\" - if the time is not " +
1216+
"added, it will be interpreted as \"23:59:59\"). If the recommended format is not used, the date will be considered in the server timezone.";
1217+
12111218
/**
12121219
* This enum specifies IO Drivers, each option controls specific policies on I/O.
12131220
* Qemu guests support "threads" and "native" options Since 0.8.8 ; "io_uring" is supported Since 6.3.0 (QEMU 5.0).
@@ -1230,14 +1237,6 @@ public String toString() {
12301237
}
12311238
}
12321239

1233-
public static final String PARAMETER_DESCRIPTION_START_DATE_POSSIBLE_FORMATS = "The recommended format is \"yyyy-MM-dd'T'HH:mm:ssZ\" (e.g.: \"2023-01-01T12:00:00+0100\"); " +
1234-
"however, the following formats are also accepted: \"yyyy-MM-dd HH:mm:ss\" (e.g.: \"2023-01-01 12:00:00\") and \"yyyy-MM-dd\" (e.g.: \"2023-01-01\" - if the time is not " +
1235-
"added, it will be interpreted as \"00:00:00\"). If the recommended format is not used, the date will be considered in the server timezone.";
1236-
1237-
public static final String PARAMETER_DESCRIPTION_END_DATE_POSSIBLE_FORMATS = "The recommended format is \"yyyy-MM-dd'T'HH:mm:ssZ\" (e.g.: \"2023-01-01T12:00:00+0100\"); " +
1238-
"however, the following formats are also accepted: \"yyyy-MM-dd HH:mm:ss\" (e.g.: \"2023-01-01 12:00:00\") and \"yyyy-MM-dd\" (e.g.: \"2023-01-01\" - if the time is not " +
1239-
"added, it will be interpreted as \"23:59:59\"). If the recommended format is not used, the date will be considered in the server timezone.";
1240-
12411240
public enum BootType {
12421241
UEFI, BIOS;
12431242

api/src/main/java/org/apache/cloudstack/api/command/admin/vm/AssignVMCmd.java

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -120,27 +120,16 @@ public List<Long> getSecurityGroupIdList() {
120120
@Override
121121
public void execute() {
122122
try {
123-
UserVm userVm = _userVmService.moveVMToUser(this);
124-
if (userVm == null) {
125-
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to move vm");
126-
}
123+
UserVm userVm = _userVmService.moveVmToUser(this);
127124
UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", userVm).get(0);
128125
response.setResponseName(getCommandName());
129126
setResponseObject(response);
130-
} catch (InvalidParameterValueException e){
131-
e.printStackTrace();
132-
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
133127
} catch (Exception e) {
134-
logger.error("Failed to move vm due to: " + e.getStackTrace());
135-
if (e.getMessage() != null) {
136-
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to move vm due to " + e.getMessage());
137-
} else if (e.getCause() != null) {
138-
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to move vm due to " + e.getCause());
139-
} else {
140-
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to move vm");
141-
}
128+
ApiErrorCode errorCode = e instanceof InvalidParameterValueException ? ApiErrorCode.PARAM_ERROR : ApiErrorCode.INTERNAL_ERROR;
129+
String msg = String.format("Failed to move VM [%s].", getVmId());
130+
logger.error(msg, e);
131+
throw new ServerApiException(errorCode, msg);
142132
}
143-
144133
}
145134

146135
@Override

core/src/main/java/com/cloud/agent/api/CheckOnHostCommand.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ public CheckOnHostCommand(Host host) {
3535
}
3636

3737
public CheckOnHostCommand(Host host, boolean reportCheckFailureIfOneStorageIsDown) {
38-
super();
39-
this.host = new HostTO(host);
38+
this(host);
4039
this.reportCheckFailureIfOneStorageIsDown = reportCheckFailureIfOneStorageIsDown;
4140
}
4241

engine/schema/src/main/java/com/cloud/domain/dao/DomainDao.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,7 @@ public interface DomainDao extends GenericDao<DomainVO, Long> {
4242

4343
List<Long> getDomainChildrenIds(String path);
4444

45+
List<Long> getDomainAndChildrenIds(long domainId);
46+
4547
boolean domainIdListContainsAccessibleDomain(String domainIdList, Account caller, Long domainId);
4648
}

engine/schema/src/main/java/com/cloud/domain/dao/DomainDaoImpl.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.sql.PreparedStatement;
2020
import java.sql.ResultSet;
2121
import java.sql.SQLException;
22+
import java.util.ArrayList;
2223
import java.util.HashSet;
2324
import java.util.List;
2425
import java.util.Set;
@@ -238,6 +239,15 @@ public List<Long> getDomainChildrenIds(String path) {
238239
return customSearch(sc, null);
239240
}
240241

242+
@Override
243+
public List<Long> getDomainAndChildrenIds(long domainId) {
244+
DomainVO domain = findById(domainId);
245+
if (domain != null) {
246+
return getDomainChildrenIds(domain.getPath());
247+
}
248+
return new ArrayList<>();
249+
}
250+
241251
@Override
242252
public boolean isChildDomain(Long parentId, Long childId) {
243253
if ((parentId == null) || (childId == null)) {

engine/schema/src/main/java/com/cloud/upgrade/SystemVmTemplateRegistration.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -796,12 +796,16 @@ public void doInTransactionWithoutResult(final TransactionStatus status) {
796796
Long templateId = getRegisteredTemplateId(hypervisorAndTemplateName);
797797
if (templateId != null) {
798798
VMTemplateVO templateVO = vmTemplateDao.findById(templateId);
799-
TemplateDataStoreVO templateDataStoreVO = templateDataStoreDao.findByTemplate(templateId, DataStoreRole.Image);
800-
String installPath = templateDataStoreVO.getInstallPath();
801-
if (validateIfSeeded(storeUrlAndId.first(), installPath, nfsVersion)) {
802-
continue;
803-
} else if (templateVO != null) {
799+
TemplateDataStoreVO templateDataStoreVO = templateDataStoreDao.findByStoreTemplate(storeUrlAndId.second(), templateId);
800+
if (templateDataStoreVO != null) {
801+
String installPath = templateDataStoreVO.getInstallPath();
802+
if (validateIfSeeded(storeUrlAndId.first(), installPath, nfsVersion)) {
803+
continue;
804+
}
805+
}
806+
if (templateVO != null) {
804807
registerTemplate(hypervisorAndTemplateName, storeUrlAndId, templateVO, templateDataStoreVO, filePath);
808+
updateRegisteredTemplateDetails(templateId, hypervisorAndTemplateName);
805809
continue;
806810
}
807811
}
@@ -825,6 +829,11 @@ public void doInTransactionWithoutResult(final TransactionStatus status) {
825829
}
826830

827831
private void updateRegisteredTemplateDetails(Long templateId, Map.Entry<Hypervisor.HypervisorType, String> hypervisorAndTemplateName) {
832+
Pair<Hypervisor.HypervisorType, String> entry = new Pair<>(hypervisorAndTemplateName.getKey(), hypervisorAndTemplateName.getValue());
833+
updateRegisteredTemplateDetails(templateId, entry);
834+
}
835+
836+
private void updateRegisteredTemplateDetails(Long templateId, Pair<Hypervisor.HypervisorType, String> hypervisorAndTemplateName) {
828837
VMTemplateVO templateVO = vmTemplateDao.findById(templateId);
829838
templateVO.setTemplateType(Storage.TemplateType.SYSTEM);
830839
boolean updated = vmTemplateDao.update(templateVO.getId(), templateVO);
@@ -834,11 +843,11 @@ private void updateRegisteredTemplateDetails(Long templateId, Map.Entry<Hypervis
834843
throw new CloudRuntimeException(errMsg);
835844
}
836845

837-
updateSystemVMEntries(templateId, hypervisorAndTemplateName.getKey());
846+
updateSystemVMEntries(templateId, hypervisorAndTemplateName.first());
838847

839848
// Change value of global configuration parameter router.template.* for the corresponding hypervisor and minreq.sysvmtemplate.version for the ACS version
840849
Map<String, String> configParams = new HashMap<>();
841-
configParams.put(RouterTemplateConfigurationNames.get(hypervisorAndTemplateName.getKey()), hypervisorAndTemplateName.getValue());
850+
configParams.put(RouterTemplateConfigurationNames.get(hypervisorAndTemplateName.first()), hypervisorAndTemplateName.second());
842851
configParams.put("minreq.sysvmtemplate.version", getSystemVmTemplateVersion());
843852
updateConfigurationParams(configParams);
844853
}

engine/schema/src/main/resources/META-INF/db/schema-42010to42100.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,10 @@ CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.console_session', 'console_endpoint_
2828

2929
-- Add client_address column to cloud.console_session table
3030
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.console_session', 'client_address', 'VARCHAR(45)');
31+
32+
-- Allow default roles to use quotaCreditsList
33+
INSERT INTO `cloud`.`role_permissions` (uuid, role_id, rule, permission, sort_order)
34+
SELECT uuid(), role_id, 'quotaCreditsList', permission, sort_order
35+
FROM `cloud`.`role_permissions` rp
36+
WHERE rp.rule = 'quotaStatement'
37+
AND NOT EXISTS(SELECT 1 FROM cloud.role_permissions rp_ WHERE rp.role_id = rp_.role_id AND rp_.rule = 'quotaCreditsList');

framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaCreditsDao.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
public interface QuotaCreditsDao extends GenericDao<QuotaCreditsVO, Long> {
2727

28-
List<QuotaCreditsVO> findCredits(long accountId, long domainId, Date startDate, Date endDate);
28+
List<QuotaCreditsVO> findCredits(Long accountId, Long domainId, Date startDate, Date endDate, boolean recursive);
2929

3030
QuotaCreditsVO saveCredits(QuotaCreditsVO credits);
3131

framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaCreditsDaoImpl.java

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,20 @@
1616
//under the License.
1717
package org.apache.cloudstack.quota.dao;
1818

19-
import java.util.Collections;
2019
import java.util.Date;
2120
import java.util.List;
2221

2322
import javax.inject.Inject;
2423

24+
import com.cloud.domain.dao.DomainDao;
25+
import com.cloud.utils.db.Filter;
26+
import com.cloud.utils.db.SearchBuilder;
2527
import org.apache.cloudstack.quota.vo.QuotaBalanceVO;
2628
import org.apache.cloudstack.quota.vo.QuotaCreditsVO;
29+
import org.apache.commons.lang3.ObjectUtils;
2730
import org.springframework.stereotype.Component;
2831

29-
import com.cloud.utils.db.Filter;
3032
import com.cloud.utils.db.GenericDaoBase;
31-
import com.cloud.utils.db.QueryBuilder;
3233
import com.cloud.utils.db.SearchCriteria;
3334
import com.cloud.utils.db.Transaction;
3435
import com.cloud.utils.db.TransactionCallback;
@@ -39,25 +40,36 @@
3940
public class QuotaCreditsDaoImpl extends GenericDaoBase<QuotaCreditsVO, Long> implements QuotaCreditsDao {
4041

4142
@Inject
42-
QuotaBalanceDao _quotaBalanceDao;
43+
DomainDao domainDao;
44+
@Inject
45+
QuotaBalanceDao quotaBalanceDao;
46+
47+
private SearchBuilder<QuotaCreditsVO> quotaCreditsVoSearch;
48+
49+
public QuotaCreditsDaoImpl() {
50+
quotaCreditsVoSearch = createSearchBuilder();
51+
quotaCreditsVoSearch.and("updatedOn", quotaCreditsVoSearch.entity().getUpdatedOn(), SearchCriteria.Op.BETWEEN);
52+
quotaCreditsVoSearch.and("accountId", quotaCreditsVoSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
53+
quotaCreditsVoSearch.and("domainId", quotaCreditsVoSearch.entity().getDomainId(), SearchCriteria.Op.IN);
54+
quotaCreditsVoSearch.done();
55+
}
4356

4457
@Override
45-
public List<QuotaCreditsVO> findCredits(final long accountId, final long domainId, final Date startDate, final Date endDate) {
46-
return Transaction.execute(TransactionLegacy.USAGE_DB, new TransactionCallback<List<QuotaCreditsVO>>() {
47-
@Override
48-
public List<QuotaCreditsVO> doInTransaction(final TransactionStatus status) {
49-
if ((startDate != null) && (endDate != null) && startDate.before(endDate)) {
50-
Filter filter = new Filter(QuotaCreditsVO.class, "updatedOn", true, 0L, Long.MAX_VALUE);
51-
QueryBuilder<QuotaCreditsVO> qb = QueryBuilder.create(QuotaCreditsVO.class);
52-
qb.and(qb.entity().getAccountId(), SearchCriteria.Op.EQ, accountId);
53-
qb.and(qb.entity().getDomainId(), SearchCriteria.Op.EQ, domainId);
54-
qb.and(qb.entity().getUpdatedOn(), SearchCriteria.Op.BETWEEN, startDate, endDate);
55-
return search(qb.create(), filter);
56-
} else {
57-
return Collections.<QuotaCreditsVO> emptyList();
58-
}
59-
}
60-
});
58+
public List<QuotaCreditsVO> findCredits(Long accountId, Long domainId, Date startDate, Date endDate, boolean recursive) {
59+
SearchCriteria<QuotaCreditsVO> sc = quotaCreditsVoSearch.create();
60+
Filter filter = new Filter(QuotaCreditsVO.class, "updatedOn", true, 0L, Long.MAX_VALUE);
61+
62+
sc.setParametersIfNotNull("accountId", accountId);
63+
if (domainId != null) {
64+
List<Long> domainIds = recursive ? domainDao.getDomainAndChildrenIds(domainId) : List.of(domainId);
65+
sc.setParameters("domainId", domainIds.toArray());
66+
}
67+
68+
if (ObjectUtils.allNotNull(startDate, endDate)) {
69+
sc.setParameters("updatedOn", startDate, endDate);
70+
}
71+
72+
return Transaction.execute(TransactionLegacy.USAGE_DB, (TransactionCallback<List<QuotaCreditsVO>>) status -> search(sc, filter));
6173
}
6274

6375
@Override
@@ -68,7 +80,7 @@ public QuotaCreditsVO doInTransaction(final TransactionStatus status) {
6880
persist(credits);
6981
// make an entry in the balance table
7082
QuotaBalanceVO bal = new QuotaBalanceVO(credits);
71-
_quotaBalanceDao.persist(bal);
83+
quotaBalanceDao.persist(bal);
7284
return credits;
7385
}
7486
});

0 commit comments

Comments
 (0)