Merge branch 'main' of https://github.com/apache/cloudstack into nsx-integration

This commit is contained in:
Pearl Dsilva 2023-09-06 10:32:51 -04:00
commit 2cccd53944
21 changed files with 147 additions and 172 deletions

View File

@ -22,29 +22,27 @@ public interface Resource {
String UNLIMITED = "Unlimited";
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),
snapshot("snapshot", 3, ResourceOwnerType.Account, ResourceOwnerType.Domain),
template("template", 4, ResourceOwnerType.Account, ResourceOwnerType.Domain),
project("project", 5, ResourceOwnerType.Account, ResourceOwnerType.Domain),
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),
primary_storage("primary_storage", 10, ResourceOwnerType.Account, ResourceOwnerType.Domain),
secondary_storage("secondary_storage", 11, ResourceOwnerType.Account, ResourceOwnerType.Domain);
user_vm("user_vm", 0),
public_ip("public_ip", 1),
volume("volume", 2),
snapshot("snapshot", 3),
template("template", 4),
project("project", 5),
network("network", 6),
vpc("vpc", 7),
cpu("cpu", 8),
memory("memory", 9),
primary_storage("primary_storage", 10),
secondary_storage("secondary_storage", 11);
private String name;
private ResourceOwnerType[] supportedOwners;
private int ordinal;
public static final long bytesToKiB = 1024;
public static final long bytesToMiB = bytesToKiB * 1024;
public static final long bytesToGiB = bytesToMiB * 1024;
ResourceType(String name, int ordinal, ResourceOwnerType... supportedOwners) {
ResourceType(String name, int ordinal) {
this.name = name;
this.supportedOwners = supportedOwners;
this.ordinal = ordinal;
}
@ -52,25 +50,6 @@ public interface Resource {
return name;
}
public ResourceOwnerType[] getSupportedOwners() {
return supportedOwners;
}
public boolean supportsOwner(ResourceOwnerType ownerType) {
boolean success = false;
if (supportedOwners != null) {
int length = supportedOwners.length;
for (int i = 0; i < length; i++) {
if (supportedOwners[i].getName().equalsIgnoreCase(ownerType.getName())) {
success = true;
break;
}
}
}
return success;
}
public int getOrdinal() {
return ordinal;
}

View File

@ -31,18 +31,18 @@ public abstract class AbstractGetUploadParamsCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(AbstractGetUploadParamsCmd.class.getName());
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the volume/template")
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the volume/template/iso")
private String name;
@Parameter(name = ApiConstants.FORMAT, type = CommandType.STRING, required = true, description = "the format for the volume/template. Possible values include QCOW2, OVA, "
@Parameter(name = ApiConstants.FORMAT, type = CommandType.STRING, required = true, description = "the format for the volume/template/iso. Possible values include QCOW2, OVA, "
+ "and VHD.")
private String format;
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "the ID of the zone the volume/template is "
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "the ID of the zone the volume/template/iso is "
+ "to be hosted on")
private Long zoneId;
@Parameter(name = ApiConstants.CHECKSUM, type = CommandType.STRING, description = "the checksum value of this volume/template " + ApiConstants.CHECKSUM_PARAMETER_PREFIX_DESCRIPTION)
@Parameter(name = ApiConstants.CHECKSUM, type = CommandType.STRING, description = "the checksum value of this volume/template/iso " + ApiConstants.CHECKSUM_PARAMETER_PREFIX_DESCRIPTION)
private String checksum;
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "an optional accountName. Must be used with domainId.")
@ -52,7 +52,7 @@ public abstract class AbstractGetUploadParamsCmd extends BaseCmd {
+ "domainId must also be used.")
private Long domainId;
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Upload volume/template for the project")
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Upload volume/template/iso for the project")
private Long projectId;
public String getName() {

View File

@ -28,7 +28,6 @@ import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.GetUploadParamsResponse;
import org.apache.cloudstack.api.response.GuestOSResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.context.CallContext;
import com.cloud.exception.ConcurrentOperationException;
@ -37,15 +36,13 @@ import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
@APICommand(name = GetUploadParamsForIsoCmd.APINAME,
@APICommand(name = "getUploadParamsForIso",
description = "upload an existing ISO into the CloudStack cloud.",
responseObject = GetUploadParamsResponse.class, since = "4.13",
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User},
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class GetUploadParamsForIsoCmd extends AbstractGetUploadParamsCmd {
public static final String APINAME = "getUploadParamsForIso";
private static final String s_name = "postuploadisoresponse";
/////////////////////////////////////////////////////
@ -73,19 +70,12 @@ public class GetUploadParamsForIsoCmd extends AbstractGetUploadParamsCmd {
@Parameter(name = ApiConstants.IS_EXTRACTABLE, type = BaseCmd.CommandType.BOOLEAN, description = "true if the ISO or its derivatives are extractable; default is false")
private Boolean extractable;
@Parameter(name = ApiConstants.NAME, type = BaseCmd.CommandType.STRING, required = true, description = "the name of the ISO")
private String isoName;
@Parameter(name = ApiConstants.OS_TYPE_ID,
type = BaseCmd.CommandType.UUID,
entityType = GuestOSResponse.class,
description = "the ID of the OS type that best represents the OS of this ISO. If the ISO is bootable this parameter needs to be passed")
private Long osTypeId;
@Parameter(name=ApiConstants.ZONE_ID, type= BaseCmd.CommandType.UUID, entityType = ZoneResponse.class,
required=true, description="the ID of the zone you wish to register the ISO to.")
protected Long zoneId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -110,17 +100,10 @@ public class GetUploadParamsForIsoCmd extends AbstractGetUploadParamsCmd {
return extractable;
}
public String getIsoName() {
return isoName;
}
public Long getOsTypeId() {
return osTypeId;
}
public Long getZoneId() {
return zoneId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
@ -134,7 +117,7 @@ public class GetUploadParamsForIsoCmd extends AbstractGetUploadParamsCmd {
response.setResponseName(getCommandName());
setResponseObject(response);
} catch (ResourceAllocationException | MalformedURLException e) {
s_logger.error("Exception while registering template", e);
s_logger.error("Exception while registering ISO", e);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Exception while registering ISO: " + e.getMessage());
}
}

View File

@ -323,8 +323,8 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG
customparameterMap.put(getBootType().toString(), getBootMode().toString());
}
if (rootdisksize != null && !customparameterMap.containsKey("rootdisksize")) {
customparameterMap.put("rootdisksize", rootdisksize.toString());
if (rootdisksize != null && !customparameterMap.containsKey(VmDetailConstants.ROOT_DISK_SIZE)) {
customparameterMap.put(VmDetailConstants.ROOT_DISK_SIZE, rootdisksize.toString());
}
IoDriverPolicy ioPolicy = getIoDriverPolicy();

2
debian/rules vendored
View File

@ -135,7 +135,7 @@ override_dh_auto_install:
install -D systemvm/dist/* $(DESTDIR)/usr/share/$(PACKAGE)-common/vms/
# We need jasypt for cloud-install-sys-tmplt, so this is a nasty hack to get it into the right place
install -D agent/target/dependencies/jasypt-1.9.3.jar $(DESTDIR)/usr/share/$(PACKAGE)-common/lib
install -D utils/target/cloud-utils-$(VERSION).jar $(DESTDIR)/usr/share/$(PACKAGE)-common/lib/$(PACKAGE)-utils.jar
install -D utils/target/cloud-utils-$(VERSION)-SHADED.jar $(DESTDIR)/usr/share/$(PACKAGE)-common/lib/$(PACKAGE)-utils.jar
# cloudstack-python
mkdir -p $(DESTDIR)/usr/share/pyshared

View File

@ -36,7 +36,6 @@ import com.cloud.configuration.ResourceCountVO;
import com.cloud.configuration.ResourceLimit;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.UnsupportedServiceException;
import com.cloud.user.AccountVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.db.DB;
@ -171,9 +170,6 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
ResourceType[] resourceTypes = Resource.ResourceType.values();
for (ResourceType resourceType : resourceTypes) {
if (!resourceType.supportsOwner(ownerType)) {
continue;
}
ResourceCountVO resourceCountVO = new ResourceCountVO(resourceType, 0, ownerId, ownerType);
persist(resourceCountVO);
}
@ -217,17 +213,6 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
}
}
@Override
public ResourceCountVO persist(ResourceCountVO resourceCountVO) {
ResourceOwnerType ownerType = resourceCountVO.getResourceOwnerType();
ResourceType resourceType = resourceCountVO.getType();
if (!resourceType.supportsOwner(ownerType)) {
throw new UnsupportedServiceException("Resource type " + resourceType + " is not supported for owner of type " + ownerType.getName());
}
return super.persist(resourceCountVO);
}
@Override
public long removeEntriesByOwner(long ownerId, ResourceOwnerType ownerType) {
SearchCriteria<ResourceCountVO> sc = TypeSearch.create();

View File

@ -509,13 +509,12 @@ public class SystemVmTemplateRegistration {
}
}
public void updateTemplateDetails(SystemVMTemplateDetails details, boolean updateTemplateDetails) {
public void updateTemplateDetails(SystemVMTemplateDetails details) {
VMTemplateVO template = vmTemplateDao.findById(details.getId());
if (updateTemplateDetails) {
template.setSize(details.getSize());
template.setState(VirtualMachineTemplate.State.Active);
vmTemplateDao.update(template.getId(), template);
}
template.setSize(details.getSize());
template.setState(VirtualMachineTemplate.State.Active);
vmTemplateDao.update(template.getId(), template);
TemplateDataStoreVO templateDataStoreVO = templateDataStoreDao.findByStoreTemplate(details.getStoreId(), template.getId());
templateDataStoreVO.setSize(details.getSize());
templateDataStoreVO.setPhysicalSize(details.getPhysicalSize());
@ -613,7 +612,7 @@ public class SystemVmTemplateRegistration {
private Long performTemplateRegistrationOperations(Pair<Hypervisor.HypervisorType, String> hypervisorAndTemplateName,
String url, String checksum, ImageFormat format, long guestOsId,
Long storeId, Long templateId, String filePath, boolean updateTmpltDetails) {
Long storeId, Long templateId, String filePath, TemplateDataStoreVO templateDataStoreVO) {
Hypervisor.HypervisorType hypervisor = hypervisorAndTemplateName.first();
String templateName = UUID.randomUUID().toString();
Date created = new Date(DateUtil.currentGMTTime().getTime());
@ -631,21 +630,24 @@ public class SystemVmTemplateRegistration {
String destTempFolderName = String.valueOf(templateId);
String destTempFolder = filePath + PARTIAL_TEMPLATE_FOLDER + destTempFolderName;
details.setInstallPath(PARTIAL_TEMPLATE_FOLDER + destTempFolderName + File.separator + templateName + "." + hypervisorImageFormat.get(hypervisor).getFileExtension());
createTemplateStoreRefEntry(details);
if (templateDataStoreVO == null) {
createTemplateStoreRefEntry(details);
}
setupTemplate(templateName, hypervisorAndTemplateName, destTempFolder);
readTemplateProperties(destTempFolder + "/template.properties", details);
details.setUpdated(new Date(DateUtil.currentGMTTime().getTime()));
updateTemplateDetails(details, updateTmpltDetails);
updateTemplateDetails(details);
return templateId;
}
public void registerTemplate(Pair<Hypervisor.HypervisorType, String> hypervisorAndTemplateName,
Pair<String, Long> storeUrlAndId, VMTemplateVO templateVO, String filePath) {
Pair<String, Long> storeUrlAndId, VMTemplateVO templateVO,
TemplateDataStoreVO templateDataStoreVO, String filePath) {
Long templateId = null;
try {
templateId = templateVO.getId();
performTemplateRegistrationOperations(hypervisorAndTemplateName, templateVO.getUrl(), templateVO.getChecksum(),
templateVO.getFormat(), templateVO.getGuestOSId(), storeUrlAndId.second(), templateId, filePath, false);
templateVO.getFormat(), templateVO.getGuestOSId(), storeUrlAndId.second(), templateId, filePath, templateDataStoreVO);
} catch (Exception e) {
String errMsg = String.format("Failed to register template for hypervisor: %s", hypervisorAndTemplateName.first());
LOGGER.error(errMsg, e);
@ -662,7 +664,7 @@ public class SystemVmTemplateRegistration {
try {
Hypervisor.HypervisorType hypervisor = hypervisorAndTemplateName.first();
templateId = performTemplateRegistrationOperations(hypervisorAndTemplateName, NewTemplateUrl.get(hypervisor), NewTemplateChecksum.get(hypervisor),
hypervisorImageFormat.get(hypervisor), hypervisorGuestOsMap.get(hypervisor), storeUrlAndId.second(), null, filePath, true);
hypervisorImageFormat.get(hypervisor), hypervisorGuestOsMap.get(hypervisor), storeUrlAndId.second(), null, filePath, null);
Map<String, String> configParams = new HashMap<>();
configParams.put(RouterTemplateConfigurationNames.get(hypervisorAndTemplateName.first()), hypervisorAndTemplateName.second());
configParams.put("minreq.sysvmtemplate.version", getSystemVmTemplateVersion());
@ -783,7 +785,7 @@ public class SystemVmTemplateRegistration {
if (validateIfSeeded(storeUrlAndId.first(), installPath)) {
continue;
} else if (templateVO != null) {
registerTemplate(hypervisorAndTemplateName, storeUrlAndId, templateVO, filePath);
registerTemplate(hypervisorAndTemplateName, storeUrlAndId, templateVO, templateDataStoreVO, filePath);
continue;
}
}

View File

@ -36,6 +36,7 @@ import org.apache.cloudstack.quota.vo.QuotaAccountVO;
import org.apache.cloudstack.quota.vo.QuotaEmailTemplatesVO;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.text.StrSubstitutor;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
@ -223,7 +224,7 @@ public class QuotaAlertManagerImpl extends ManagerBase implements QuotaAlertMana
final String body = bodySubstitutor.replace(emailTemplate.getTemplateBody());
try {
sendQuotaAlert(account.getUuid(), emailRecipients, subject, body);
sendQuotaAlert(account, emailRecipients, subject, body);
emailToBeSent.sentSuccessfully(_quotaAcc);
} catch (Exception e) {
s_logger.error(String.format("Unable to send quota alert email (subject=%s; body=%s) to account %s (%s) recipients (%s) due to error (%s)", subject, body, account.getAccountName(),
@ -354,17 +355,20 @@ public class QuotaAlertManagerImpl extends ManagerBase implements QuotaAlertMana
}
};
protected void sendQuotaAlert(String accountUuid, List<String> emails, String subject, String body) {
protected void sendQuotaAlert(Account account, List<String> emails, String subject, String body) {
SMTPMailProperties mailProperties = new SMTPMailProperties();
mailProperties.setSender(new MailAddress(senderAddress));
body = addHeaderAndFooter(body, QuotaConfig.QuotaEmailHeader.valueIn(account.getDomainId()), QuotaConfig.QuotaEmailFooter.valueIn(account.getDomainId()));
mailProperties.setSubject(subject);
mailProperties.setContent(body);
mailProperties.setContentType("text/html; charset=utf-8");
if (CollectionUtils.isEmpty(emails)) {
s_logger.warn(String.format("Account [%s] does not have users with email registered, "
+ "therefore we are unable to send quota alert email with subject [%s] and content [%s].", accountUuid, subject, body));
+ "therefore we are unable to send quota alert email with subject [%s] and content [%s].", account.getUuid(), subject, body));
return;
}
@ -378,4 +382,16 @@ public class QuotaAlertManagerImpl extends ManagerBase implements QuotaAlertMana
mailSender.sendMail(mailProperties);
}
protected String addHeaderAndFooter(String body, String header, String footer) {
if (StringUtils.isNotEmpty(header)) {
body = String.format("%s%s", header, body);
}
if (StringUtils.isNotEmpty(footer)) {
body = String.format("%s%s", body, footer);
}
return body;
}
}

View File

@ -63,6 +63,12 @@ public interface QuotaConfig {
ConfigKey<Boolean> QuotaAccountEnabled = new ConfigKey<>("Advanced", Boolean.class, "quota.account.enabled", "true", "Indicates whether Quota plugin is enabled or not for " +
"the account.", true, ConfigKey.Scope.Account);
ConfigKey<String> QuotaEmailHeader = new ConfigKey<>("Advanced", String.class, "quota.email.header", "",
"Text to be added as a header for quota emails. Line breaks are not automatically inserted between this section and the body.", true, ConfigKey.Scope.Domain);
ConfigKey<String> QuotaEmailFooter = new ConfigKey<>("Advanced", String.class, "quota.email.footer", "",
"Text to be added as a footer for quota emails. Line breaks are not automatically inserted between this section and the body.", true, ConfigKey.Scope.Domain);
enum QuotaEmailTemplateTypes {
QUOTA_LOW, QUOTA_EMPTY, QUOTA_UNLOCK_ACCOUNT, QUOTA_STATEMENT
}

View File

@ -71,6 +71,21 @@ public class QuotaAlertManagerImplTest extends TestCase {
@Mock
private ConfigurationDao configDao;
@Mock
private QuotaAccountVO quotaAccountVOMock;
@Mock
private List<QuotaAlertManagerImpl.DeferredQuotaEmail> deferredQuotaEmailListMock;
@Mock
private QuotaManagerImpl quotaManagerMock;
@Mock
private Date balanceDateMock;
@Mock
private AccountVO accountMock;
@Spy
@InjectMocks
private QuotaAlertManagerImpl quotaAlertManager = new QuotaAlertManagerImpl();
@ -162,10 +177,22 @@ public class QuotaAlertManagerImplTest extends TestCase {
quotaAlertManager.sendQuotaAlert(email);
assertTrue(email.getSendDate() != null);
Mockito.verify(quotaAlertManager, Mockito.times(1)).sendQuotaAlert(Mockito.anyString(), Mockito.anyListOf(String.class), Mockito.anyString(), Mockito.anyString());
Mockito.verify(quotaAlertManager, Mockito.times(1)).sendQuotaAlert(Mockito.any(), Mockito.anyListOf(String.class), Mockito.anyString(), Mockito.anyString());
Mockito.verify(quotaAlertManager.mailSender, Mockito.times(1)).sendMail(Mockito.any(SMTPMailProperties.class));
}
@Test
public void addHeaderAndFooterTestIfHeaderAndFootersAreAdded() {
String body = quotaAlertManager.addHeaderAndFooter("body", "Header", "Footer");
assertEquals("HeaderbodyFooter", body);
}
@Test
public void addHeaderAndFooterTestIfHeaderAndFootersAreNotAddedIfEmpty() {
String body = quotaAlertManager.addHeaderAndFooter("body", "", "");
assertEquals("body", body);
}
@Test
public void testGetDifferenceDays() {
Date now = new Date();

View File

@ -302,7 +302,7 @@ ln -sf log4j-cloud.xml ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/management/log4j
install python/bindir/cloud-external-ipallocator.py ${RPM_BUILD_ROOT}%{_bindir}/%{name}-external-ipallocator.py
install -D client/target/pythonlibs/jasypt-1.9.3.jar ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/lib/jasypt-1.9.3.jar
install -D utils/target/cloud-utils-%{_maventag}.jar ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/lib/%{name}-utils.jar
install -D utils/target/cloud-utils-%{_maventag}-SHADED.jar ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/lib/%{name}-utils.jar
install -D packaging/centos7/cloud-ipallocator.rc ${RPM_BUILD_ROOT}%{_initrddir}/%{name}-ipallocator
install -D packaging/centos7/cloud.limits ${RPM_BUILD_ROOT}%{_sysconfdir}/security/limits.d/cloud

View File

@ -284,7 +284,7 @@ ln -sf log4j-cloud.xml ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/management/log4j
install python/bindir/cloud-external-ipallocator.py ${RPM_BUILD_ROOT}%{_bindir}/%{name}-external-ipallocator.py
install -D client/target/pythonlibs/jasypt-1.9.3.jar ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/lib/jasypt-1.9.3.jar
install -D utils/target/cloud-utils-%{_maventag}.jar ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/lib/%{name}-utils.jar
install -D utils/target/cloud-utils-%{_maventag}-SHADED.jar ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/lib/%{name}-utils.jar
install -D packaging/centos8/cloud-ipallocator.rc ${RPM_BUILD_ROOT}%{_initrddir}/%{name}-ipallocator
install -D packaging/centos8/cloud.limits ${RPM_BUILD_ROOT}%{_sysconfdir}/security/limits.d/cloud

View File

@ -141,7 +141,8 @@ public class QuotaServiceImpl extends ManagerBase implements QuotaService, Confi
@Override
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {QuotaPluginEnabled, QuotaEnableEnforcement, QuotaCurrencySymbol, QuotaStatementPeriod, QuotaSmtpHost, QuotaSmtpPort, QuotaSmtpTimeout,
QuotaSmtpUser, QuotaSmtpPassword, QuotaSmtpAuthType, QuotaSmtpSender, QuotaSmtpEnabledSecurityProtocols, QuotaSmtpUseStartTLS, QuotaActivationRuleTimeout, QuotaAccountEnabled};
QuotaSmtpUser, QuotaSmtpPassword, QuotaSmtpAuthType, QuotaSmtpSender, QuotaSmtpEnabledSecurityProtocols, QuotaSmtpUseStartTLS, QuotaActivationRuleTimeout, QuotaAccountEnabled,
QuotaEmailHeader, QuotaEmailFooter};
}
@Override

View File

@ -17,7 +17,6 @@
package com.cloud.hypervisor;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
@ -96,14 +95,7 @@ public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru,
if (userVmVO != null) {
HostVO host = hostDao.findById(userVmVO.getHostId());
if (host != null) {
List<HostVO> clusterHosts = hostDao.listByClusterAndHypervisorType(host.getClusterId(), host.getHypervisorType());
HostVO hostWithMinSocket = clusterHosts.stream().min(Comparator.comparing(HostVO::getCpuSockets)).orElse(null);
Integer vCpus = MaxNumberOfVCPUSPerVM.valueIn(host.getClusterId());
if (hostWithMinSocket != null && hostWithMinSocket.getCpuSockets() != null &&
hostWithMinSocket.getCpuSockets() < vCpus) {
vCpus = hostWithMinSocket.getCpuSockets();
}
to.setVcpuMaxLimit(vCpus);
to.setVcpuMaxLimit(MaxNumberOfVCPUSPerVM.valueIn(host.getClusterId()));
}
}

View File

@ -1338,7 +1338,7 @@ public abstract class CitrixResourceBase extends ServerResourceBase implements S
vmr.VCPUsMax = (long)vmSpec.getCpus();
} else {
if (vmSpec.getVcpuMaxLimit() != null) {
vmr.VCPUsMax = (long)vmSpec.getVcpuMaxLimit();
vmr.VCPUsMax = Math.min(vmSpec.getVcpuMaxLimit(), (long) _host.getCpus());
}
}
} else {

View File

@ -701,7 +701,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
if (isAccount) {
if (accountLimitStr.size() < resourceTypes.length) {
for (ResourceType rt : resourceTypes) {
if (!accountLimitStr.contains(rt.toString()) && rt.supportsOwner(ResourceOwnerType.Account)) {
if (!accountLimitStr.contains(rt.toString())) {
limits.add(new ResourceLimitVO(rt, findCorrectResourceLimitForAccount(_accountMgr.getAccount(accountId), rt), accountId, ResourceOwnerType.Account));
}
}
@ -710,7 +710,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
} else {
if (domainLimitStr.size() < resourceTypes.length) {
for (ResourceType rt : resourceTypes) {
if (!domainLimitStr.contains(rt.toString()) && rt.supportsOwner(ResourceOwnerType.Domain)) {
if (!domainLimitStr.contains(rt.toString())) {
limits.add(new ResourceLimitVO(rt, findCorrectResourceLimitForDomain(_domainDao.findById(domainId), rt), domainId, ResourceOwnerType.Domain));
}
}
@ -855,16 +855,12 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
for (ResourceType type : resourceTypes) {
if (accountId != null) {
if (type.supportsOwner(ResourceOwnerType.Account)) {
count = recalculateAccountResourceCount(accountId, type);
counts.add(new ResourceCountVO(type, count, accountId, ResourceOwnerType.Account));
}
count = recalculateAccountResourceCount(accountId, type);
counts.add(new ResourceCountVO(type, count, accountId, ResourceOwnerType.Account));
} else {
if (type.supportsOwner(ResourceOwnerType.Domain)) {
count = recalculateDomainResourceCount(domainId, type);
counts.add(new ResourceCountVO(type, count, domainId, ResourceOwnerType.Domain));
}
count = recalculateDomainResourceCount(domainId, type);
counts.add(new ResourceCountVO(type, count, domainId, ResourceOwnerType.Domain));
}
}
@ -921,25 +917,20 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
List<DomainVO> domainChildren = _domainDao.findImmediateChildrenForParent(domainId);
// for each child domain update the resource count
if (type.supportsOwner(ResourceOwnerType.Domain)) {
// calculate project count here
if (type == ResourceType.project) {
newResourceCount += _projectDao.countProjectsForDomain(domainId);
}
for (DomainVO childDomain : domainChildren) {
long childDomainResourceCount = recalculateDomainResourceCount(childDomain.getId(), type);
newResourceCount += childDomainResourceCount; // add the child domain count to parent domain count
}
// calculate project count here
if (type == ResourceType.project) {
newResourceCount += _projectDao.countProjectsForDomain(domainId);
}
if (type.supportsOwner(ResourceOwnerType.Account)) {
List<AccountVO> accounts = _accountDao.findActiveAccountsForDomain(domainId);
for (AccountVO account : accounts) {
long accountResourceCount = recalculateAccountResourceCount(account.getId(), type);
newResourceCount += accountResourceCount; // add account's resource count to parent domain count
}
for (DomainVO childDomain : domainChildren) {
long childDomainResourceCount = recalculateDomainResourceCount(childDomain.getId(), type);
newResourceCount += childDomainResourceCount; // add the child domain count to parent domain count
}
List<AccountVO> accounts = _accountDao.findActiveAccountsForDomain(domainId);
for (AccountVO account : accounts) {
long accountResourceCount = recalculateAccountResourceCount(account.getId(), type);
newResourceCount += accountResourceCount; // add account's resource count to parent domain count
}
_resourceCountDao.setResourceCount(domainId, ResourceOwnerType.Domain, type, newResourceCount);
@ -1201,18 +1192,14 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
}
for (ResourceType type : ResourceType.values()) {
if (type.supportsOwner(ResourceOwnerType.Domain)) {
recalculateDomainResourceCountInContext(Domain.ROOT_DOMAIN, type);
for (Domain domain : domains) {
recalculateDomainResourceCount(domain.getId(), type);
}
recalculateDomainResourceCountInContext(Domain.ROOT_DOMAIN, type);
for (Domain domain : domains) {
recalculateDomainResourceCount(domain.getId(), type);
}
if (type.supportsOwner(ResourceOwnerType.Account)) {
// run through the accounts in the root domain
for (AccountVO account : accounts) {
recalculateAccountResourceCountInContext(account.getId(), type);
}
// run through the accounts in the root domain
for (AccountVO account : accounts) {
recalculateAccountResourceCountInContext(account.getId(), type);
}
}
}

View File

@ -1334,22 +1334,9 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio
List<ResourceCountVO> domainResourceCount = _resourceCountDao.listResourceCountByOwnerType(ResourceOwnerType.Domain);
List<ResourceCountVO> accountResourceCount = _resourceCountDao.listResourceCountByOwnerType(ResourceOwnerType.Account);
final List<ResourceType> accountSupportedResourceTypes = new ArrayList<ResourceType>();
final List<ResourceType> domainSupportedResourceTypes = new ArrayList<ResourceType>();
final int expectedCount = resourceTypes.length;
for (ResourceType resourceType : resourceTypes) {
if (resourceType.supportsOwner(ResourceOwnerType.Account)) {
accountSupportedResourceTypes.add(resourceType);
}
if (resourceType.supportsOwner(ResourceOwnerType.Domain)) {
domainSupportedResourceTypes.add(resourceType);
}
}
final int accountExpectedCount = accountSupportedResourceTypes.size();
final int domainExpectedCount = domainSupportedResourceTypes.size();
if ((domainResourceCount.size() < domainExpectedCount * domains.size())) {
if ((domainResourceCount.size() < expectedCount * domains.size())) {
s_logger.debug("resource_count table has records missing for some domains...going to insert them");
for (final DomainVO domain : domains) {
// Lock domain
@ -1363,8 +1350,8 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio
domainCountStr.add(domainCount.getType().toString());
}
if (domainCountStr.size() < domainExpectedCount) {
for (ResourceType resourceType : domainSupportedResourceTypes) {
if (domainCountStr.size() < expectedCount) {
for (ResourceType resourceType : resourceTypes) {
if (!domainCountStr.contains(resourceType.toString())) {
ResourceCountVO resourceCountVO = new ResourceCountVO(resourceType, 0, domain.getId(), ResourceOwnerType.Domain);
s_logger.debug("Inserting resource count of type " + resourceType + " for domain id=" + domain.getId());
@ -1378,7 +1365,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio
}
}
if ((accountResourceCount.size() < accountExpectedCount * accounts.size())) {
if ((accountResourceCount.size() < expectedCount * accounts.size())) {
s_logger.debug("resource_count table has records missing for some accounts...going to insert them");
for (final AccountVO account : accounts) {
// lock account
@ -1392,8 +1379,8 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio
accountCountStr.add(accountCount.getType().toString());
}
if (accountCountStr.size() < accountExpectedCount) {
for (ResourceType resourceType : accountSupportedResourceTypes) {
if (accountCountStr.size() < expectedCount) {
for (ResourceType resourceType : resourceTypes) {
if (!accountCountStr.contains(resourceType.toString())) {
ResourceCountVO resourceCountVO = new ResourceCountVO(resourceType, 0, account.getId(), ResourceOwnerType.Account);
s_logger.debug("Inserting resource count of type " + resourceType + " for account id=" + account.getId());

View File

@ -2917,7 +2917,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
}
SystemVmTemplateRegistration.mountStore(storeUrlAndId.first(), filePath);
if (templateVO != null && vmTemplateVO != null) {
systemVmTemplateRegistration.registerTemplate(hypervisorAndTemplateName, storeUrlAndId, vmTemplateVO, filePath);
systemVmTemplateRegistration.registerTemplate(hypervisorAndTemplateName, storeUrlAndId, vmTemplateVO, templateVO, filePath);
} else {
systemVmTemplateRegistration.registerTemplate(hypervisorAndTemplateName, storeUrlAndId, filePath);
}

View File

@ -3949,7 +3949,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
rootDiskOfferingId = diskOfferingId;
diskOfferingId = null;
}
if (!customParameters.containsKey(VmDetailConstants.ROOT_DISK_SIZE)) {
if (!customParameters.containsKey(VmDetailConstants.ROOT_DISK_SIZE) && diskSize != null) {
customParameters.put(VmDetailConstants.ROOT_DISK_SIZE, String.valueOf(diskSize));
}
}
@ -4336,7 +4336,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
*/
protected long configureCustomRootDiskSize(Map<String, String> customParameters, VMTemplateVO template, HypervisorType hypervisorType, DiskOfferingVO rootDiskOffering) {
verifyIfHypervisorSupportsRootdiskSizeOverride(hypervisorType);
long rootDiskSizeInBytes = verifyAndGetDiskSize(rootDiskOffering, NumbersUtil.parseLong(customParameters.get(VmDetailConstants.ROOT_DISK_SIZE), -1));
Long rootDiskSizeCustomParam = null;
if (customParameters.containsKey(VmDetailConstants.ROOT_DISK_SIZE)) {
rootDiskSizeCustomParam = NumbersUtil.parseLong(customParameters.get(VmDetailConstants.ROOT_DISK_SIZE), -1);
if (rootDiskSizeCustomParam <= 0) {
throw new InvalidParameterValueException("Root disk size should be a positive number.");
}
}
long rootDiskSizeInBytes = verifyAndGetDiskSize(rootDiskOffering, rootDiskSizeCustomParam);
if (rootDiskSizeInBytes > 0) { //if the size at DiskOffering is not zero then the Service Offering had it configured, it holds priority over the User custom size
_volumeService.validateVolumeSizeInBytes(rootDiskSizeInBytes);
long rootDiskSizeInGiB = rootDiskSizeInBytes / GiB_TO_BYTES;
@ -4345,11 +4352,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
if (customParameters.containsKey(VmDetailConstants.ROOT_DISK_SIZE)) {
Long rootDiskSize = NumbersUtil.parseLong(customParameters.get(VmDetailConstants.ROOT_DISK_SIZE), -1);
if (rootDiskSize <= 0) {
throw new InvalidParameterValueException("Root disk size should be a positive number.");
}
rootDiskSize *= GiB_TO_BYTES;
Long rootDiskSize = rootDiskSizeCustomParam * GiB_TO_BYTES;
_volumeService.validateVolumeSizeInBytes(rootDiskSize);
return rootDiskSize;
} else {

View File

@ -204,7 +204,10 @@ class TestVmAutoScaling(cloudstackTestCase):
cls.apiUserdata = UserData.register(
cls.apiclient,
name="ApiUserdata",
userdata="QVBJdXNlcmRhdGE=", #APIuserdata
userdata="IyEvYmluL2Jhc2gKCmVjaG8gIkFQSVVzZXJkYXRhIgoK",
# #!/bin/bash
#
# echo "APIUserData"
account=cls.regular_user.name,
domainid=cls.regular_user.domainid
)
@ -327,7 +330,10 @@ class TestVmAutoScaling(cloudstackTestCase):
serviceofferingid=cls.service_offering.id,
zoneid=cls.zone.id,
templateid=cls.template.id,
userdata="VGVzdFVzZXJEYXRh", #TestUserData
userdata="IyEvYmluL2Jhc2gKCmVjaG8gIlRlc3RVc2VyRGF0YSIKCg==",
# #!/bin/bash
#
# echo "TestUserData"
expungevmgraceperiod=DEFAULT_EXPUNGE_VM_GRACE_PERIOD,
otherdeployparams=cls.otherdeployparams
)

View File

@ -261,6 +261,7 @@
<goal>shade</goal>
</goals>
<configuration>
<finalName>${project.artifactId}-${project.version}-SHADED</finalName>
<createDependencyReducedPom>false</createDependencyReducedPom>
<artifactSet>
<includes>