Merge branch '4.16' into main

This commit is contained in:
Suresh Kumar Anaparti 2022-02-08 19:01:34 +05:30
commit 208ae84dd7
No known key found for this signature in database
GPG Key ID: D7CEAE3A9E71D0AA
32 changed files with 583 additions and 151 deletions

View File

@ -154,5 +154,7 @@ public interface VolumeApiService {
Volume recoverVolume(long volumeId); Volume recoverVolume(long volumeId);
boolean validateVolumeSizeInBytes(long size);
Volume changeDiskOfferingForVolume(ChangeOfferingForVolumeCmd cmd) throws ResourceAllocationException; Volume changeDiskOfferingForVolume(ChangeOfferingForVolumeCmd cmd) throws ResourceAllocationException;
} }

View File

@ -355,7 +355,7 @@ public abstract class BaseCmd {
if (roleIsAllowed) { if (roleIsAllowed) {
validFields.add(field); validFields.add(field);
} else { } else {
s_logger.debug("Ignoring paremeter " + parameterAnnotation.name() + " as the caller is not authorized to pass it in"); s_logger.debug("Ignoring parameter " + parameterAnnotation.name() + " as the caller is not authorized to pass it in");
} }
} }

View File

@ -75,6 +75,13 @@ public interface VolumeOrchestrationService {
true true
); );
ConfigKey<Long> MaxVolumeSize = new ConfigKey<Long>("Storage",
Long.class,
"storage.max.volume.size",
"2000",
"The maximum size for a volume (in GB).",
true);
VolumeInfo moveVolume(VolumeInfo volume, long destPoolDcId, Long destPoolPodId, Long destPoolClusterId, HypervisorType dataDiskHyperType) VolumeInfo moveVolume(VolumeInfo volume, long destPoolDcId, Long destPoolPodId, Long destPoolClusterId, HypervisorType dataDiskHyperType)
throws ConcurrentOperationException, StorageUnavailableException; throws ConcurrentOperationException, StorageUnavailableException;

View File

@ -221,7 +221,7 @@ public class VMEntityManagerImpl implements VMEntityManager {
// call retry it. // call retry it.
return UUID.randomUUID().toString(); return UUID.randomUUID().toString();
} else { } else {
throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId(), throw new InsufficientServerCapacityException("No destination found for a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId(),
areAffinityGroupsAssociated(vmProfile)); areAffinityGroupsAssociated(vmProfile));
} }
} }

View File

@ -18,10 +18,12 @@
*/ */
package org.apache.cloudstack.engine.orchestration; package org.apache.cloudstack.engine.orchestration;
import static com.cloud.storage.resource.StorageProcessor.REQUEST_TEMPLATE_RELOAD;
import static com.cloud.utils.NumbersUtil.toHumanReadableSize; import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -35,13 +37,6 @@ import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
import com.cloud.agent.api.to.DatadiskTO;
import com.cloud.vm.SecondaryStorageVmVO;
import com.cloud.vm.UserVmDetailVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VmDetailConstants;
import com.cloud.vm.dao.SecondaryStorageVmDao;
import com.cloud.vm.dao.UserVmDetailsDao;
import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd; import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd;
import org.apache.cloudstack.api.command.admin.volume.MigrateVolumeCmdByAdmin; import org.apache.cloudstack.api.command.admin.volume.MigrateVolumeCmdByAdmin;
import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd; import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
@ -83,12 +78,13 @@ import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils; import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.DataTO;
import com.cloud.agent.api.to.DatadiskTO;
import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.DiskTO;
import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.manager.allocator.PodAllocator; import com.cloud.agent.manager.allocator.PodAllocator;
@ -150,21 +146,24 @@ import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.fsm.NoTransitionException; import com.cloud.utils.fsm.NoTransitionException;
import com.cloud.utils.fsm.StateMachine2; import com.cloud.utils.fsm.StateMachine2;
import com.cloud.vm.DiskProfile; import com.cloud.vm.DiskProfile;
import com.cloud.vm.SecondaryStorageVmVO;
import com.cloud.vm.UserVmCloneSettingVO; import com.cloud.vm.UserVmCloneSettingVO;
import com.cloud.vm.UserVmDetailVO;
import com.cloud.vm.UserVmVO; import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.VirtualMachineProfileImpl; import com.cloud.vm.VirtualMachineProfileImpl;
import com.cloud.vm.VmDetailConstants;
import com.cloud.vm.VmWorkAttachVolume; import com.cloud.vm.VmWorkAttachVolume;
import com.cloud.vm.VmWorkMigrateVolume; import com.cloud.vm.VmWorkMigrateVolume;
import com.cloud.vm.VmWorkSerializer; import com.cloud.vm.VmWorkSerializer;
import com.cloud.vm.VmWorkTakeVolumeSnapshot; import com.cloud.vm.VmWorkTakeVolumeSnapshot;
import com.cloud.vm.dao.SecondaryStorageVmDao;
import com.cloud.vm.dao.UserVmCloneSettingDao; import com.cloud.vm.dao.UserVmCloneSettingDao;
import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.UserVmDetailsDao;
import static com.cloud.storage.resource.StorageProcessor.REQUEST_TEMPLATE_RELOAD;
import java.util.Date;
public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrationService, Configurable { public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrationService, Configurable {
@ -1779,8 +1778,6 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
return true; return true;
} }
public static final ConfigKey<Long> MaxVolumeSize = new ConfigKey<Long>(Long.class, "storage.max.volume.size", "Storage", "2000", "The maximum size for a volume (in GB).", true);
public static final ConfigKey<Boolean> RecreatableSystemVmEnabled = new ConfigKey<Boolean>(Boolean.class, "recreate.systemvm.enabled", "Advanced", "false", public static final ConfigKey<Boolean> RecreatableSystemVmEnabled = new ConfigKey<Boolean>(Boolean.class, "recreate.systemvm.enabled", "Advanced", "false",
"If true, will recreate system vm root disk whenever starting system vm", true); "If true, will recreate system vm root disk whenever starting system vm", true);

View File

@ -29,9 +29,9 @@
</parent> </parent>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>log4j</groupId> <groupId>ch.qos.reload4j</groupId>
<artifactId>log4j</artifactId> <artifactId>reload4j</artifactId>
<version>${cs.log4j.version}</version> <version>${cs.reload4j.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -139,16 +139,15 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
} }
s_logger.info("Getting pending quota records for account=" + account.getAccountName()); s_logger.info("Getting pending quota records for account=" + account.getAccountName());
for (UsageVO usageRecord : usageRecords.first()) { for (UsageVO usageRecord : usageRecords.first()) {
BigDecimal aggregationRatio = new BigDecimal(_aggregationDuration).divide(s_minutesInMonth, 8, RoundingMode.HALF_EVEN);
switch (usageRecord.getUsageType()) { switch (usageRecord.getUsageType()) {
case QuotaTypes.RUNNING_VM: case QuotaTypes.RUNNING_VM:
List<QuotaUsageVO> lq = updateQuotaRunningVMUsage(usageRecord, aggregationRatio); List<QuotaUsageVO> lq = updateQuotaRunningVMUsage(usageRecord);
if (!lq.isEmpty()) { if (!lq.isEmpty()) {
quotaListForAccount.addAll(lq); quotaListForAccount.addAll(lq);
} }
break; break;
case QuotaTypes.ALLOCATED_VM: case QuotaTypes.ALLOCATED_VM:
QuotaUsageVO qu = updateQuotaAllocatedVMUsage(usageRecord, aggregationRatio); QuotaUsageVO qu = updateQuotaAllocatedVMUsage(usageRecord);
if (qu != null) { if (qu != null) {
quotaListForAccount.add(qu); quotaListForAccount.add(qu);
} }
@ -159,7 +158,7 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
case QuotaTypes.VOLUME: case QuotaTypes.VOLUME:
case QuotaTypes.VM_SNAPSHOT: case QuotaTypes.VM_SNAPSHOT:
case QuotaTypes.BACKUP: case QuotaTypes.BACKUP:
qu = updateQuotaDiskUsage(usageRecord, aggregationRatio, usageRecord.getUsageType()); qu = updateQuotaDiskUsage(usageRecord, usageRecord.getUsageType());
if (qu != null) { if (qu != null) {
quotaListForAccount.add(qu); quotaListForAccount.add(qu);
} }
@ -170,7 +169,7 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
case QuotaTypes.NETWORK_OFFERING: case QuotaTypes.NETWORK_OFFERING:
case QuotaTypes.SECURITY_GROUP: case QuotaTypes.SECURITY_GROUP:
case QuotaTypes.VPN_USERS: case QuotaTypes.VPN_USERS:
qu = updateQuotaRaw(usageRecord, aggregationRatio, usageRecord.getUsageType()); qu = updateQuotaRaw(usageRecord, usageRecord.getUsageType());
if (qu != null) { if (qu != null) {
quotaListForAccount.add(qu); quotaListForAccount.add(qu);
} }
@ -333,14 +332,14 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
return true; return true;
} }
public QuotaUsageVO updateQuotaDiskUsage(UsageVO usageRecord, final BigDecimal aggregationRatio, final int quotaType) { public QuotaUsageVO updateQuotaDiskUsage(UsageVO usageRecord, final int quotaType) {
QuotaUsageVO quota_usage = null; QuotaUsageVO quota_usage = null;
QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(quotaType, usageRecord.getEndDate()); QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(quotaType, usageRecord.getEndDate());
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0) { if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0) {
BigDecimal quotaUsgage; BigDecimal quotaUsgage;
BigDecimal onehourcostpergb; BigDecimal onehourcostpergb;
BigDecimal noofgbinuse; BigDecimal noofgbinuse;
onehourcostpergb = tariff.getCurrencyValue().multiply(aggregationRatio); onehourcostpergb = tariff.getCurrencyValue().divide(s_hoursInMonth, 8, RoundingMode.HALF_DOWN);
noofgbinuse = new BigDecimal(usageRecord.getSize()).divide(s_gb, 8, RoundingMode.HALF_EVEN); noofgbinuse = new BigDecimal(usageRecord.getSize()).divide(s_gb, 8, RoundingMode.HALF_EVEN);
quotaUsgage = new BigDecimal(usageRecord.getRawUsage()).multiply(onehourcostpergb).multiply(noofgbinuse); quotaUsgage = new BigDecimal(usageRecord.getRawUsage()).multiply(onehourcostpergb).multiply(noofgbinuse);
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), usageRecord.getUsageType(), quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), usageRecord.getUsageType(),
@ -352,7 +351,7 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
return quota_usage; return quota_usage;
} }
public List<QuotaUsageVO> updateQuotaRunningVMUsage(UsageVO usageRecord, final BigDecimal aggregationRatio) { public List<QuotaUsageVO> updateQuotaRunningVMUsage(UsageVO usageRecord) {
List<QuotaUsageVO> quotalist = new ArrayList<QuotaUsageVO>(); List<QuotaUsageVO> quotalist = new ArrayList<QuotaUsageVO>();
QuotaUsageVO quota_usage; QuotaUsageVO quota_usage;
BigDecimal cpuquotausgage, speedquotausage, memoryquotausage, vmusage; BigDecimal cpuquotausgage, speedquotausage, memoryquotausage, vmusage;
@ -368,7 +367,7 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.CPU_NUMBER, usageRecord.getEndDate()); QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.CPU_NUMBER, usageRecord.getEndDate());
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0 && serviceoffering.getCpu() != null) { if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0 && serviceoffering.getCpu() != null) {
BigDecimal cpu = new BigDecimal(serviceoffering.getCpu()); BigDecimal cpu = new BigDecimal(serviceoffering.getCpu());
onehourcostpercpu = tariff.getCurrencyValue().multiply(aggregationRatio); onehourcostpercpu = tariff.getCurrencyValue().divide(s_hoursInMonth, 8, RoundingMode.HALF_DOWN);
cpuquotausgage = rawusage.multiply(onehourcostpercpu).multiply(cpu); cpuquotausgage = rawusage.multiply(onehourcostpercpu).multiply(cpu);
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.CPU_NUMBER, quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.CPU_NUMBER,
cpuquotausgage, usageRecord.getStartDate(), usageRecord.getEndDate()); cpuquotausgage, usageRecord.getStartDate(), usageRecord.getEndDate());
@ -377,8 +376,8 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
} }
tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.CPU_CLOCK_RATE, usageRecord.getEndDate()); tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.CPU_CLOCK_RATE, usageRecord.getEndDate());
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0 && serviceoffering.getSpeed() != null) { if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0 && serviceoffering.getSpeed() != null) {
BigDecimal speed = new BigDecimal(serviceoffering.getSpeed() / 100.00); BigDecimal speed = new BigDecimal(serviceoffering.getSpeed()*serviceoffering.getCpu() / 100.00);
onehourcostper100mhz = tariff.getCurrencyValue().multiply(aggregationRatio); onehourcostper100mhz = tariff.getCurrencyValue().divide(s_hoursInMonth, 8, RoundingMode.HALF_DOWN);
speedquotausage = rawusage.multiply(onehourcostper100mhz).multiply(speed); speedquotausage = rawusage.multiply(onehourcostper100mhz).multiply(speed);
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.CPU_CLOCK_RATE, quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.CPU_CLOCK_RATE,
speedquotausage, usageRecord.getStartDate(), usageRecord.getEndDate()); speedquotausage, usageRecord.getStartDate(), usageRecord.getEndDate());
@ -388,7 +387,7 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.MEMORY, usageRecord.getEndDate()); tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.MEMORY, usageRecord.getEndDate());
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0 && serviceoffering.getRamSize() != null) { if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0 && serviceoffering.getRamSize() != null) {
BigDecimal memory = new BigDecimal(serviceoffering.getRamSize()); BigDecimal memory = new BigDecimal(serviceoffering.getRamSize());
onehourcostper1mb = tariff.getCurrencyValue().multiply(aggregationRatio); onehourcostper1mb = tariff.getCurrencyValue().divide(s_hoursInMonth, 8, RoundingMode.HALF_DOWN);
memoryquotausage = rawusage.multiply(onehourcostper1mb).multiply(memory); memoryquotausage = rawusage.multiply(onehourcostper1mb).multiply(memory);
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.MEMORY, memoryquotausage, quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.MEMORY, memoryquotausage,
usageRecord.getStartDate(), usageRecord.getEndDate()); usageRecord.getStartDate(), usageRecord.getEndDate());
@ -397,7 +396,7 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
} }
tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.RUNNING_VM, usageRecord.getEndDate()); tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.RUNNING_VM, usageRecord.getEndDate());
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0) { if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0) {
onehourcostforvmusage = tariff.getCurrencyValue().multiply(aggregationRatio); onehourcostforvmusage = tariff.getCurrencyValue().divide(s_hoursInMonth, 8, RoundingMode.HALF_DOWN);
vmusage = rawusage.multiply(onehourcostforvmusage); vmusage = rawusage.multiply(onehourcostforvmusage);
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.RUNNING_VM, vmusage, quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.RUNNING_VM, vmusage,
usageRecord.getStartDate(), usageRecord.getEndDate()); usageRecord.getStartDate(), usageRecord.getEndDate());
@ -410,13 +409,13 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
return quotalist; return quotalist;
} }
public QuotaUsageVO updateQuotaAllocatedVMUsage(UsageVO usageRecord, final BigDecimal aggregationRatio) { public QuotaUsageVO updateQuotaAllocatedVMUsage(UsageVO usageRecord) {
QuotaUsageVO quota_usage = null; QuotaUsageVO quota_usage = null;
QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.ALLOCATED_VM, usageRecord.getEndDate()); QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.ALLOCATED_VM, usageRecord.getEndDate());
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0) { if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0) {
BigDecimal vmusage; BigDecimal vmusage;
BigDecimal onehourcostforvmusage; BigDecimal onehourcostforvmusage;
onehourcostforvmusage = tariff.getCurrencyValue().multiply(aggregationRatio); onehourcostforvmusage = tariff.getCurrencyValue().divide(s_hoursInMonth, 8, RoundingMode.HALF_DOWN);
vmusage = new BigDecimal(usageRecord.getRawUsage()).multiply(onehourcostforvmusage); vmusage = new BigDecimal(usageRecord.getRawUsage()).multiply(onehourcostforvmusage);
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.ALLOCATED_VM, vmusage, quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.ALLOCATED_VM, vmusage,
usageRecord.getStartDate(), usageRecord.getEndDate()); usageRecord.getStartDate(), usageRecord.getEndDate());
@ -428,13 +427,13 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
return quota_usage; return quota_usage;
} }
public QuotaUsageVO updateQuotaRaw(UsageVO usageRecord, final BigDecimal aggregationRatio, final int ruleType) { public QuotaUsageVO updateQuotaRaw(UsageVO usageRecord, final int ruleType) {
QuotaUsageVO quota_usage = null; QuotaUsageVO quota_usage = null;
QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(ruleType, usageRecord.getEndDate()); QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(ruleType, usageRecord.getEndDate());
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0) { if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0) {
BigDecimal ruleusage; BigDecimal ruleusage;
BigDecimal onehourcost; BigDecimal onehourcost;
onehourcost = tariff.getCurrencyValue().multiply(aggregationRatio); onehourcost = tariff.getCurrencyValue().divide(s_hoursInMonth, 8, RoundingMode.HALF_DOWN);
ruleusage = new BigDecimal(usageRecord.getRawUsage()).multiply(onehourcost); ruleusage = new BigDecimal(usageRecord.getRawUsage()).multiply(onehourcost);
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), ruleType, ruleusage, quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), ruleType, ruleusage,
usageRecord.getStartDate(), usageRecord.getEndDate()); usageRecord.getStartDate(), usageRecord.getEndDate());

View File

@ -151,7 +151,7 @@ public class QuotaManagerImplTest extends TestCase {
QuotaUsageVO quotaUsageVO = new QuotaUsageVO(); QuotaUsageVO quotaUsageVO = new QuotaUsageVO();
quotaUsageVO.setAccountId(2L); quotaUsageVO.setAccountId(2L);
Mockito.doReturn(quotaUsageVO).when(quotaManager).updateQuotaAllocatedVMUsage(Mockito.eq(usageVO), Mockito.any(BigDecimal.class)); Mockito.doReturn(quotaUsageVO).when(quotaManager).updateQuotaAllocatedVMUsage(Mockito.eq(usageVO));
assertTrue(quotaManager.aggregatePendingQuotaRecordsForAccount(accountVO, new Pair<List<? extends UsageVO>, Integer>(null, 0)).size() == 0); assertTrue(quotaManager.aggregatePendingQuotaRecordsForAccount(accountVO, new Pair<List<? extends UsageVO>, Integer>(null, 0)).size() == 0);
assertTrue(quotaManager.aggregatePendingQuotaRecordsForAccount(accountVO, usageRecords).size() == 1); assertTrue(quotaManager.aggregatePendingQuotaRecordsForAccount(accountVO, usageRecords).size() == 1);
@ -172,11 +172,11 @@ public class QuotaManagerImplTest extends TestCase {
QuotaUsageVO qu = quotaManager.updateQuotaNetwork(usageVO, UsageTypes.NETWORK_BYTES_SENT); QuotaUsageVO qu = quotaManager.updateQuotaNetwork(usageVO, UsageTypes.NETWORK_BYTES_SENT);
assertTrue(qu.getQuotaUsed().compareTo(BigDecimal.ZERO) > 0); assertTrue(qu.getQuotaUsed().compareTo(BigDecimal.ZERO) > 0);
qu = quotaManager.updateQuotaAllocatedVMUsage(usageVO, new BigDecimal(0.5)); qu = quotaManager.updateQuotaAllocatedVMUsage(usageVO);
assertTrue(qu.getQuotaUsed().compareTo(BigDecimal.ZERO) > 0); assertTrue(qu.getQuotaUsed().compareTo(BigDecimal.ZERO) > 0);
qu = quotaManager.updateQuotaDiskUsage(usageVO, new BigDecimal(0.5), UsageTypes.VOLUME); qu = quotaManager.updateQuotaDiskUsage(usageVO, UsageTypes.VOLUME);
assertTrue(qu.getQuotaUsed().compareTo(BigDecimal.ZERO) > 0); assertTrue(qu.getQuotaUsed().compareTo(BigDecimal.ZERO) > 0);
qu = quotaManager.updateQuotaRaw(usageVO, new BigDecimal(0.5), UsageTypes.VPN_USERS); qu = quotaManager.updateQuotaRaw(usageVO, UsageTypes.VPN_USERS);
assertTrue(qu.getQuotaUsed().compareTo(BigDecimal.ZERO) > 0); assertTrue(qu.getQuotaUsed().compareTo(BigDecimal.ZERO) > 0);
Mockito.verify(quotaUsageDao, Mockito.times(4)).persistQuotaUsage(Mockito.any(QuotaUsageVO.class)); Mockito.verify(quotaUsageDao, Mockito.times(4)).persistQuotaUsage(Mockito.any(QuotaUsageVO.class));

View File

@ -305,6 +305,9 @@ public class ExplicitDedicationProcessor extends AffinityProcessorBase implement
for (HostPodVO pod : podList) { for (HostPodVO pod : podList) {
DedicatedResourceVO dPod = _dedicatedDao.findByPodId(pod.getId()); DedicatedResourceVO dPod = _dedicatedDao.findByPodId(pod.getId());
if (dPod != null && !dedicatedResources.contains(dPod)) { if (dPod != null && !dedicatedResources.contains(dPod)) {
if (s_logger.isDebugEnabled()) {
s_logger.debug(String.format("Avoiding POD %s [%s] because it is not dedicated.", pod.getName(), pod.getUuid()));
}
avoidList.addPod(pod.getId()); avoidList.addPod(pod.getId());
} else { } else {
includeList.addPod(pod.getId()); includeList.addPod(pod.getId());
@ -343,6 +346,9 @@ public class ExplicitDedicationProcessor extends AffinityProcessorBase implement
for (HostPodVO pod : pods) { for (HostPodVO pod : pods) {
if (podsInIncludeList != null && !podsInIncludeList.contains(pod.getId())) { if (podsInIncludeList != null && !podsInIncludeList.contains(pod.getId())) {
if (s_logger.isDebugEnabled()) {
s_logger.debug(String.format("Avoiding POD %s [%s], as it is not in include list.", pod.getName(), pod.getUuid()));
}
avoidList.addPod(pod.getId()); avoidList.addPod(pod.getId());
} }
} }

View File

@ -33,8 +33,8 @@
<artifactId>org.apache.servicemix.bundles.snmp4j</artifactId> <artifactId>org.apache.servicemix.bundles.snmp4j</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>log4j</groupId> <groupId>ch.qos.reload4j</groupId>
<artifactId>log4j</artifactId> <artifactId>reload4j</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -29,8 +29,8 @@
</parent> </parent>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>log4j</groupId> <groupId>ch.qos.reload4j</groupId>
<artifactId>log4j</artifactId> <artifactId>reload4j</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -107,7 +107,7 @@ public class ImplicitDedicationPlanner extends FirstFitPlanner implements Deploy
} }
} }
// Hosts running vms of other accounts created by ab implicit planner in strict mode should always be avoided. // Hosts running vms of other accounts created by an implicit planner in strict mode should always be avoided.
avoid.addHostList(hostRunningStrictImplicitVmsOfOtherAccounts); avoid.addHostList(hostRunningStrictImplicitVmsOfOtherAccounts);
if (!hostRunningVmsOfAccount.isEmpty() && (hostsToAvoid == null || !hostsToAvoid.containsAll(hostRunningVmsOfAccount))) { if (!hostRunningVmsOfAccount.isEmpty() && (hostsToAvoid == null || !hostsToAvoid.containsAll(hostRunningVmsOfAccount))) {

View File

@ -44,8 +44,8 @@
<version>${cs.commons-lang3.version}</version> <version>${cs.commons-lang3.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>log4j</groupId> <groupId>ch.qos.reload4j</groupId>
<artifactId>log4j</artifactId> <artifactId>reload4j</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -86,9 +86,9 @@
<version>${cs.guava.version}</version> <version>${cs.guava.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>log4j</groupId> <groupId>ch.qos.reload4j</groupId>
<artifactId>log4j</artifactId> <artifactId>reload4j</artifactId>
<version>${cs.log4j.version}</version> <version>${cs.reload4j.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>

View File

@ -112,6 +112,12 @@
<groupId>net.juniper.contrail</groupId> <groupId>net.juniper.contrail</groupId>
<artifactId>juniper-contrail-api</artifactId> <artifactId>juniper-contrail-api</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>mysql</groupId> <groupId>mysql</groupId>

View File

@ -175,6 +175,10 @@
<version>${ads.version}</version> <version>${ads.version}</version>
<scope>test</scope> <scope>test</scope>
<exclusions> <exclusions>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
<!-- <!--
shared-ldap-schema module needs to be excluded to avoid multiple schema resources on the classpath shared-ldap-schema module needs to be excluded to avoid multiple schema resources on the classpath
--> -->

20
pom.xml
View File

@ -76,14 +76,14 @@
<cs.clover-maven-plugin.version>4.4.1</cs.clover-maven-plugin.version> <cs.clover-maven-plugin.version>4.4.1</cs.clover-maven-plugin.version>
<!-- Logging versions --> <!-- Logging versions -->
<cs.log4j.version>1.2.17</cs.log4j.version> <cs.reload4j.version>1.2.18.4</cs.reload4j.version>
<cs.log4j.extras.version>1.2.17</cs.log4j.extras.version> <cs.log4j.extras.version>1.2.17</cs.log4j.extras.version>
<cs.logging.version>1.1.1</cs.logging.version> <cs.logging.version>1.1.1</cs.logging.version>
<!-- Apache Commons versions --> <!-- Apache Commons versions -->
<cs.codec.version>1.15</cs.codec.version> <cs.codec.version>1.15</cs.codec.version>
<cs.commons-collections.version>4.4</cs.commons-collections.version> <cs.commons-collections.version>4.4</cs.commons-collections.version>
<cs.commons-compress.version>1.20</cs.commons-compress.version> <cs.commons-compress.version>1.21</cs.commons-compress.version>
<cs.commons-exec.version>1.3</cs.commons-exec.version> <cs.commons-exec.version>1.3</cs.commons-exec.version>
<cs.commons-fileupload.version>1.4</cs.commons-fileupload.version> <cs.commons-fileupload.version>1.4</cs.commons-fileupload.version>
<cs.commons-httpclient.version>3.1</cs.commons-httpclient.version> <cs.commons-httpclient.version>3.1</cs.commons-httpclient.version>
@ -113,7 +113,7 @@
<cs.selenium-java-client-driver.version>1.0.1</cs.selenium-java-client-driver.version> <cs.selenium-java-client-driver.version>1.0.1</cs.selenium-java-client-driver.version>
<cs.testng.version>7.1.0</cs.testng.version> <cs.testng.version>7.1.0</cs.testng.version>
<cs.wiremock.version>2.27.2</cs.wiremock.version> <cs.wiremock.version>2.27.2</cs.wiremock.version>
<cs.xercesImpl.version>2.12.0</cs.xercesImpl.version> <cs.xercesImpl.version>2.12.2</cs.xercesImpl.version>
<!-- Dependencies versions --> <!-- Dependencies versions -->
<cs.amqp-client.version>5.10.0</cs.amqp-client.version> <cs.amqp-client.version>5.10.0</cs.amqp-client.version>
@ -171,7 +171,7 @@
<cs.winrm4j.version>0.5.0</cs.winrm4j.version> <cs.winrm4j.version>0.5.0</cs.winrm4j.version>
<cs.xapi.version>6.2.0-3.1</cs.xapi.version> <cs.xapi.version>6.2.0-3.1</cs.xapi.version>
<cs.xmlrpc.version>3.1.3</cs.xmlrpc.version> <cs.xmlrpc.version>3.1.3</cs.xmlrpc.version>
<cs.xstream.version>1.4.15</cs.xstream.version> <cs.xstream.version>1.4.19</cs.xstream.version>
<org.springframework.version>5.3.3</org.springframework.version> <org.springframework.version>5.3.3</org.springframework.version>
<cs.ini.version>0.5.4</cs.ini.version> <cs.ini.version>0.5.4</cs.ini.version>
<cs.gmaven.version>1.12.0</cs.gmaven.version> <cs.gmaven.version>1.12.0</cs.gmaven.version>
@ -439,9 +439,9 @@
</exclusions> </exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>log4j</groupId> <groupId>ch.qos.reload4j</groupId>
<artifactId>log4j</artifactId> <artifactId>reload4j</artifactId>
<version>${cs.log4j.version}</version> <version>${cs.reload4j.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>mysql</groupId> <groupId>mysql</groupId>
@ -618,6 +618,12 @@
<groupId>org.owasp.esapi</groupId> <groupId>org.owasp.esapi</groupId>
<artifactId>esapi</artifactId> <artifactId>esapi</artifactId>
<version>2.1.0.1</version> <version>2.1.0.1</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<!-- Test dependency in mysql for db tests --> <!-- Test dependency in mysql for db tests -->
<dependency> <dependency>

View File

@ -16,6 +16,15 @@
// under the License. // under the License.
package com.cloud.configuration; package com.cloud.configuration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
import org.apache.cloudstack.framework.config.ConfigKey;
import com.cloud.agent.AgentManager; import com.cloud.agent.AgentManager;
import com.cloud.consoleproxy.ConsoleProxyManager; import com.cloud.consoleproxy.ConsoleProxyManager;
import com.cloud.ha.HighAvailabilityManager; import com.cloud.ha.HighAvailabilityManager;
@ -29,14 +38,6 @@ import com.cloud.storage.snapshot.SnapshotManager;
import com.cloud.template.TemplateManager; import com.cloud.template.TemplateManager;
import com.cloud.vm.UserVmManager; import com.cloud.vm.UserVmManager;
import com.cloud.vm.snapshot.VMSnapshotManager; import com.cloud.vm.snapshot.VMSnapshotManager;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
import org.apache.cloudstack.framework.config.ConfigKey;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;
/** /**
* @deprecated use the more dynamic ConfigKey * @deprecated use the more dynamic ConfigKey
@ -144,7 +145,6 @@ public enum Config {
"60000", "60000",
"The interval (in milliseconds) when storage stats (per host) are retrieved from agents.", "The interval (in milliseconds) when storage stats (per host) are retrieved from agents.",
null), null),
MaxVolumeSize("Storage", ManagementServer.class, Integer.class, "storage.max.volume.size", "2000", "The maximum size for a volume (in GB).", null),
StorageCacheReplacementLRUTimeInterval( StorageCacheReplacementLRUTimeInterval(
"Storage", "Storage",
ManagementServer.class, ManagementServer.class,

View File

@ -43,7 +43,6 @@ import java.util.Vector;
import javax.inject.Inject; import javax.inject.Inject;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
import com.googlecode.ipv6.IPv6Address;
import org.apache.cloudstack.acl.SecurityChecker; import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroup;
import org.apache.cloudstack.affinity.AffinityGroupService; import org.apache.cloudstack.affinity.AffinityGroupService;
@ -85,6 +84,7 @@ import org.apache.cloudstack.config.ApiServiceConfiguration;
import org.apache.cloudstack.config.Configuration; import org.apache.cloudstack.config.Configuration;
import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigDepot;
@ -270,6 +270,7 @@ import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.googlecode.ipv6.IPv6Address;
public class ConfigurationManagerImpl extends ManagerBase implements ConfigurationManager, ConfigurationService, Configurable { public class ConfigurationManagerImpl extends ManagerBase implements ConfigurationManager, ConfigurationService, Configurable {
public static final Logger s_logger = Logger.getLogger(ConfigurationManagerImpl.class); public static final Logger s_logger = Logger.getLogger(ConfigurationManagerImpl.class);
@ -421,7 +422,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
@Inject @Inject
protected DataCenterLinkLocalIpAddressDao _linkLocalIpAllocDao; protected DataCenterLinkLocalIpAddressDao _linkLocalIpAllocDao;
private int _maxVolumeSizeInGb = Integer.parseInt(Config.MaxVolumeSize.getDefaultValue());
private long _defaultPageSize = Long.parseLong(Config.DefaultPageSize.getDefaultValue()); private long _defaultPageSize = Long.parseLong(Config.DefaultPageSize.getDefaultValue());
private static final String DOMAIN_NAME_PATTERN = "^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{1,63}$"; private static final String DOMAIN_NAME_PATTERN = "^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{1,63}$";
protected Set<String> configValuesForValidation; protected Set<String> configValuesForValidation;
@ -477,9 +477,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
@Override @Override
public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException { public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
final String maxVolumeSizeInGbString = _configDao.getValue(Config.MaxVolumeSize.key());
_maxVolumeSizeInGb = NumbersUtil.parseInt(maxVolumeSizeInGbString, Integer.parseInt(Config.MaxVolumeSize.getDefaultValue()));
final String defaultPageSizeString = _configDao.getValue(Config.DefaultPageSize.key()); final String defaultPageSizeString = _configDao.getValue(Config.DefaultPageSize.key());
_defaultPageSize = NumbersUtil.parseLong(defaultPageSizeString, Long.parseLong(Config.DefaultPageSize.getDefaultValue())); _defaultPageSize = NumbersUtil.parseLong(defaultPageSizeString, Long.parseLong(Config.DefaultPageSize.getDefaultValue()));
@ -3048,6 +3045,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
if (rootDiskSizeInGiB != null && rootDiskSizeInGiB <= 0L) { if (rootDiskSizeInGiB != null && rootDiskSizeInGiB <= 0L) {
throw new InvalidParameterValueException(String.format("The Root disk size is of %s GB but it must be greater than 0.", rootDiskSizeInGiB)); throw new InvalidParameterValueException(String.format("The Root disk size is of %s GB but it must be greater than 0.", rootDiskSizeInGiB));
} else if (rootDiskSizeInGiB != null) { } else if (rootDiskSizeInGiB != null) {
long maxVolumeSizeInGb = VolumeOrchestrationService.MaxVolumeSize.value();
if (rootDiskSizeInGiB > maxVolumeSizeInGb) {
throw new InvalidParameterValueException(String.format("The maximum size for a disk is %d GB.", maxVolumeSizeInGb));
}
long rootDiskSizeInBytes = rootDiskSizeInGiB * GiB_TO_BYTES; long rootDiskSizeInBytes = rootDiskSizeInGiB * GiB_TO_BYTES;
diskOffering.setDiskSize(rootDiskSizeInBytes); diskOffering.setDiskSize(rootDiskSizeInBytes);
} }
@ -3313,10 +3314,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength, Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength,
final Integer hypervisorSnapshotReserve, String cacheMode, final Map<String, String> details, final Long storagePolicyID, final boolean diskSizeStrictness) { final Integer hypervisorSnapshotReserve, String cacheMode, final Map<String, String> details, final Long storagePolicyID, final boolean diskSizeStrictness) {
long diskSize = 0;// special case for custom disk offerings long diskSize = 0;// special case for custom disk offerings
long maxVolumeSizeInGb = VolumeOrchestrationService.MaxVolumeSize.value();
if (numGibibytes != null && numGibibytes <= 0) { if (numGibibytes != null && numGibibytes <= 0) {
throw new InvalidParameterValueException("Please specify a disk size of at least 1 Gb."); throw new InvalidParameterValueException("Please specify a disk size of at least 1 GB.");
} else if (numGibibytes != null && numGibibytes > _maxVolumeSizeInGb) { } else if (numGibibytes != null && numGibibytes > maxVolumeSizeInGb) {
throw new InvalidParameterValueException("The maximum size for a disk is " + _maxVolumeSizeInGb + " Gb."); throw new InvalidParameterValueException(String.format("The maximum size for a disk is %d GB.", maxVolumeSizeInGb));
} }
final ProvisioningType typedProvisioningType = ProvisioningType.getProvisioningType(provisioningType); final ProvisioningType typedProvisioningType = ProvisioningType.getProvisioningType(provisioningType);

View File

@ -752,9 +752,17 @@ StateListener<State, VirtualMachine.Event, VirtualMachine>, Configurable {
//Only when the type is instance VM and not explicitly dedicated. //Only when the type is instance VM and not explicitly dedicated.
if (vm.getType() == VirtualMachine.Type.User && !isExplicit) { if (vm.getType() == VirtualMachine.Type.User && !isExplicit) {
//add explicitly dedicated resources in avoidList //add explicitly dedicated resources in avoidList
if (s_logger.isDebugEnabled()) {
s_logger.debug("Adding pods to avoid lists for non-explicit VM deployment: " + allPodsInDc);
}
avoids.addPodList(allPodsInDc); avoids.addPodList(allPodsInDc);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Adding clusters to avoid lists for non-explicit VM deployment: " + allClustersInDc);
}
avoids.addClusterList(allClustersInDc); avoids.addClusterList(allClustersInDc);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Adding hosts to avoid lists for non-explicit VM deployment: " + allHostsInDc);
}
avoids.addHostList(allHostsInDc); avoids.addHostList(allHostsInDc);
} }
@ -833,8 +841,17 @@ StateListener<State, VirtualMachine.Event, VirtualMachine>, Configurable {
} }
//Add in avoid list or no addition if no dedication //Add in avoid list or no addition if no dedication
if (s_logger.isDebugEnabled()) {
s_logger.debug("Adding pods to avoid lists: " + allPodsInDc);
}
avoids.addPodList(allPodsInDc); avoids.addPodList(allPodsInDc);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Adding clusters to avoid lists: " + allClustersInDc);
}
avoids.addClusterList(allClustersInDc); avoids.addClusterList(allClustersInDc);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Adding hosts to avoid lists: " + allHostsInDc);
}
avoids.addHostList(allHostsInDc); avoids.addHostList(allHostsInDc);
} }
} }

View File

@ -325,7 +325,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
public static final ConfigKey<Boolean> MatchStoragePoolTagsWithDiskOffering = new ConfigKey<Boolean>("Advanced", Boolean.class, "match.storage.pool.tags.with.disk.offering", "true", public static final ConfigKey<Boolean> MatchStoragePoolTagsWithDiskOffering = new ConfigKey<Boolean>("Advanced", Boolean.class, "match.storage.pool.tags.with.disk.offering", "true",
"If true, volume's disk offering can be changed only with the matched storage tags", true, ConfigKey.Scope.Zone); "If true, volume's disk offering can be changed only with the matched storage tags", true, ConfigKey.Scope.Zone);
private long _maxVolumeSizeInGb;
private final StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine; private final StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine;
private static final Set<Volume.State> STATES_VOLUME_CANNOT_BE_DESTROYED = new HashSet<>(Arrays.asList(Volume.State.Destroy, Volume.State.Expunging, Volume.State.Expunged, Volume.State.Allocated)); private static final Set<Volume.State> STATES_VOLUME_CANNOT_BE_DESTROYED = new HashSet<>(Arrays.asList(Volume.State.Destroy, Volume.State.Expunging, Volume.State.Expunged, Volume.State.Allocated));
@ -745,9 +744,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
maxIops = diskOffering.getMaxIops(); maxIops = diskOffering.getMaxIops();
} }
if (!validateVolumeSizeRange(size)) {// convert size from mb to gb if (!validateVolumeSizeInBytes(size)) {
// for validation throw new InvalidParameterValueException(String.format("Invalid size for custom volume creation: %s, max volume size is: %s GB", NumbersUtil.toReadableSize(size), VolumeOrchestrationService.MaxVolumeSize.value()));
throw new InvalidParameterValueException("Invalid size for custom volume creation: " + size + " ,max volume size is:" + _maxVolumeSizeInGb);
} }
} }
@ -901,11 +899,13 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
}); });
} }
public boolean validateVolumeSizeRange(long size) { @Override
public boolean validateVolumeSizeInBytes(long size) {
long maxVolumeSize = VolumeOrchestrationService.MaxVolumeSize.value();
if (size < 0 || (size > 0 && size < (1024 * 1024 * 1024))) { if (size < 0 || (size > 0 && size < (1024 * 1024 * 1024))) {
throw new InvalidParameterValueException("Please specify a size of at least 1 GB."); throw new InvalidParameterValueException("Please specify a size of at least 1 GB.");
} else if (size > (_maxVolumeSizeInGb * 1024 * 1024 * 1024)) { } else if (size > (maxVolumeSize * 1024 * 1024 * 1024)) {
throw new InvalidParameterValueException("Requested volume size is " + size + ", but the maximum size allowed is " + _maxVolumeSizeInGb + " GB."); throw new InvalidParameterValueException(String.format("Requested volume size is %s, but the maximum size allowed is %d GB.", NumbersUtil.toReadableSize(size), maxVolumeSize));
} }
return true; return true;
@ -1144,7 +1144,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
} }
} }
if (!validateVolumeSizeRange(newSize)) { if (!validateVolumeSizeInBytes(newSize)) {
throw new InvalidParameterValueException("Requested size out of range"); throw new InvalidParameterValueException("Requested size out of range");
} }
@ -1962,7 +1962,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
} }
} }
if (!validateVolumeSizeRange(newSize)) { if (!validateVolumeSizeInBytes(newSize)) {
throw new InvalidParameterValueException("Requested size out of range"); throw new InvalidParameterValueException("Requested size out of range");
} }
@ -3943,8 +3943,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
@Override @Override
public boolean configure(String name, Map<String, Object> params) { public boolean configure(String name, Map<String, Object> params) {
String maxVolumeSizeInGbString = _configDao.getValue(Config.MaxVolumeSize.toString());
_maxVolumeSizeInGb = NumbersUtil.parseLong(maxVolumeSizeInGbString, 2000);
supportingDefaultHV = _hypervisorCapabilitiesDao.getHypervisorsWithDefaultEntries(); supportingDefaultHV = _hypervisorCapabilitiesDao.getHypervisorsWithDefaultEntries();
return true; return true;
} }

View File

@ -16,6 +16,7 @@
// under the License. // under the License.
package com.cloud.vm; package com.cloud.vm;
import static com.cloud.configuration.ConfigurationManagerImpl.VM_USERDATA_MAX_LENGTH;
import static com.cloud.utils.NumbersUtil.toHumanReadableSize; import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
import java.io.IOException; import java.io.IOException;
@ -26,6 +27,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
@ -50,8 +52,6 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import com.cloud.network.router.CommandSetupHelper;
import com.cloud.network.router.NetworkHelper;
import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.acl.SecurityChecker.AccessType;
@ -118,6 +118,7 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
import org.apache.cloudstack.utils.bytescale.ByteScaleUtils;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils; import org.apache.commons.collections.MapUtils;
@ -248,6 +249,8 @@ import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.element.UserDataServiceProvider; import com.cloud.network.element.UserDataServiceProvider;
import com.cloud.network.guru.NetworkGuru; import com.cloud.network.guru.NetworkGuru;
import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.lb.LoadBalancingRulesManager;
import com.cloud.network.router.CommandSetupHelper;
import com.cloud.network.router.NetworkHelper;
import com.cloud.network.router.VpcVirtualNetworkApplianceManager; import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
import com.cloud.network.rules.FirewallManager; import com.cloud.network.rules.FirewallManager;
import com.cloud.network.rules.FirewallRuleVO; import com.cloud.network.rules.FirewallRuleVO;
@ -357,10 +360,6 @@ import com.cloud.vm.dao.VMInstanceDao;
import com.cloud.vm.snapshot.VMSnapshotManager; import com.cloud.vm.snapshot.VMSnapshotManager;
import com.cloud.vm.snapshot.VMSnapshotVO; import com.cloud.vm.snapshot.VMSnapshotVO;
import com.cloud.vm.snapshot.dao.VMSnapshotDao; import com.cloud.vm.snapshot.dao.VMSnapshotDao;
import java.util.HashSet;
import org.apache.cloudstack.utils.bytescale.ByteScaleUtils;
import static com.cloud.configuration.ConfigurationManagerImpl.VM_USERDATA_MAX_LENGTH;
public class UserVmManagerImpl extends ManagerBase implements UserVmManager, VirtualMachineGuru, UserVmService, Configurable { public class UserVmManagerImpl extends ManagerBase implements UserVmManager, VirtualMachineGuru, UserVmService, Configurable {
private static final Logger s_logger = Logger.getLogger(UserVmManagerImpl.class); private static final Logger s_logger = Logger.getLogger(UserVmManagerImpl.class);
@ -3819,18 +3818,18 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
} }
DiskOfferingVO rootdiskOffering = _diskOfferingDao.findById(rootDiskOfferingId); DiskOfferingVO rootdiskOffering = _diskOfferingDao.findById(rootDiskOfferingId);
long size = configureCustomRootDiskSize(customParameters, template, hypervisorType, rootdiskOffering); long volumesSize = configureCustomRootDiskSize(customParameters, template, hypervisorType, rootdiskOffering);
if (!isIso && diskOfferingId != null) { if (!isIso && diskOfferingId != null) {
DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId); DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
size += verifyAndGetDiskSize(diskOffering, diskSize); volumesSize += verifyAndGetDiskSize(diskOffering, diskSize);
} }
if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) { if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
resourceLimitCheck(owner, isDisplayVm, new Long(offering.getCpu()), new Long(offering.getRamSize())); resourceLimitCheck(owner, isDisplayVm, new Long(offering.getCpu()), new Long(offering.getRamSize()));
} }
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, (isIso || diskOfferingId == null ? 1 : 2)); _resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, (isIso || diskOfferingId == null ? 1 : 2));
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, size); _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumesSize);
// verify security group ids // verify security group ids
if (securityGroupIdList != null) { if (securityGroupIdList != null) {
@ -4136,7 +4135,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
private long verifyAndGetDiskSize(DiskOfferingVO diskOffering, Long diskSize) { private long verifyAndGetDiskSize(DiskOfferingVO diskOffering, Long diskSize) {
long size = 0l; long size = 0l;
if (diskOffering != null && diskOffering.isCustomized() && !diskOffering.isComputeOnly()) { if (diskOffering == null) {
throw new InvalidParameterValueException("Specified disk offering cannot be found");
}
if (diskOffering.isCustomized() && !diskOffering.isComputeOnly()) {
if (diskSize == null) { if (diskSize == null) {
throw new InvalidParameterValueException("This disk offering requires a custom size specified"); throw new InvalidParameterValueException("This disk offering requires a custom size specified");
} }
@ -4146,9 +4148,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
throw new InvalidParameterValueException("VM Creation failed. Volume size: " + diskSize + "GB is out of allowed range. Max: " + customDiskOfferingMaxSize throw new InvalidParameterValueException("VM Creation failed. Volume size: " + diskSize + "GB is out of allowed range. Max: " + customDiskOfferingMaxSize
+ " Min:" + customDiskOfferingMinSize); + " Min:" + customDiskOfferingMinSize);
} }
size += diskSize * GiB_TO_BYTES; size = diskSize * GiB_TO_BYTES;
} else {
size = diskOffering.getDiskSize();
} }
size += diskOffering.getDiskSize(); _volumeService.validateVolumeSizeInBytes(size);
return size; return size;
} }
@ -4170,6 +4174,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
verifyIfHypervisorSupportsRootdiskSizeOverride(hypervisorType); verifyIfHypervisorSupportsRootdiskSizeOverride(hypervisorType);
long rootDiskSizeInBytes = verifyAndGetDiskSize(rootDiskOffering, NumbersUtil.parseLong(customParameters.get(VmDetailConstants.ROOT_DISK_SIZE), -1)); long rootDiskSizeInBytes = verifyAndGetDiskSize(rootDiskOffering, NumbersUtil.parseLong(customParameters.get(VmDetailConstants.ROOT_DISK_SIZE), -1));
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 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; long rootDiskSizeInGiB = rootDiskSizeInBytes / GiB_TO_BYTES;
customParameters.put(VmDetailConstants.ROOT_DISK_SIZE, String.valueOf(rootDiskSizeInGiB)); customParameters.put(VmDetailConstants.ROOT_DISK_SIZE, String.valueOf(rootDiskSizeInGiB));
return rootDiskSizeInBytes; return rootDiskSizeInBytes;
@ -4180,7 +4185,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
if (rootDiskSize <= 0) { if (rootDiskSize <= 0) {
throw new InvalidParameterValueException("Root disk size should be a positive number."); throw new InvalidParameterValueException("Root disk size should be a positive number.");
} }
return rootDiskSize * GiB_TO_BYTES; rootDiskSize *= GiB_TO_BYTES;
_volumeService.validateVolumeSizeInBytes(rootDiskSize);
return rootDiskSize;
} else { } else {
// For baremetal, size can be 0 (zero) // For baremetal, size can be 0 (zero)
Long templateSize = _templateDao.findById(template.getId()).getSize(); Long templateSize = _templateDao.findById(template.getId()).getSize();

View File

@ -33,15 +33,6 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.cloud.configuration.Resource;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.storage.DiskOfferingVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.user.ResourceLimitService;
import com.cloud.user.dao.AccountDao;
import org.apache.cloudstack.api.BaseCmd.HTTPMethod; import org.apache.cloudstack.api.BaseCmd.HTTPMethod;
import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd; import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd;
import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd; import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
@ -59,24 +50,34 @@ import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.core.classloader.annotations.PrepareForTest;
import com.cloud.configuration.Resource;
import com.cloud.dc.DataCenterVO; import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.DataCenterDao;
import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.ResourceUnavailableException;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.network.NetworkModel; import com.cloud.network.NetworkModel;
import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.NetworkVO;
import com.cloud.offering.ServiceOffering; import com.cloud.offering.ServiceOffering;
import com.cloud.service.ServiceOfferingVO; import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.DiskOfferingVO;
import com.cloud.storage.GuestOSVO; import com.cloud.storage.GuestOSVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeApiService;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.GuestOSDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.user.Account; import com.cloud.user.Account;
import com.cloud.user.AccountManager; import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO; import com.cloud.user.AccountVO;
import com.cloud.user.ResourceLimitService;
import com.cloud.user.UserVO; import com.cloud.user.UserVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.uservm.UserVm; import com.cloud.uservm.UserVm;
import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.UserVmDao;
@ -151,6 +152,9 @@ public class UserVmManagerImplTest {
@Mock @Mock
ResourceLimitService resourceLimitMgr; ResourceLimitService resourceLimitMgr;
@Mock
VolumeApiService volumeApiService;
private long vmId = 1l; private long vmId = 1l;
private static final long GiB_TO_BYTES = 1024 * 1024 * 1024; private static final long GiB_TO_BYTES = 1024 * 1024 * 1024;
@ -474,6 +478,7 @@ public class UserVmManagerImplTest {
Mockito.when(diskfferingVo.getDiskSize()).thenReturn(offeringRootDiskSize); Mockito.when(diskfferingVo.getDiskSize()).thenReturn(offeringRootDiskSize);
Mockito.when(volumeApiService.validateVolumeSizeInBytes(Mockito.anyLong())).thenReturn(true);
long rootDiskSize = userVmManagerImpl.configureCustomRootDiskSize(customParameters, template, Hypervisor.HypervisorType.KVM, diskfferingVo); long rootDiskSize = userVmManagerImpl.configureCustomRootDiskSize(customParameters, template, Hypervisor.HypervisorType.KVM, diskfferingVo);
Assert.assertEquals(expectedRootDiskSize, rootDiskSize); Assert.assertEquals(expectedRootDiskSize, rootDiskSize);

View File

@ -29,8 +29,8 @@
</parent> </parent>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>log4j</groupId> <groupId>ch.qos.reload4j</groupId>
<artifactId>log4j</artifactId> <artifactId>reload4j</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.google.code.gson</groupId> <groupId>com.google.code.gson</groupId>

View File

@ -29,8 +29,8 @@
</parent> </parent>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>log4j</groupId> <groupId>ch.qos.reload4j</groupId>
<artifactId>log4j</artifactId> <artifactId>reload4j</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.google.code.gson</groupId> <groupId>com.google.code.gson</groupId>

View File

@ -33,8 +33,8 @@
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>log4j</groupId> <groupId>ch.qos.reload4j</groupId>
<artifactId>log4j</artifactId> <artifactId>reload4j</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.jenkins-ci</groupId> <groupId>org.jenkins-ci</groupId>

View File

@ -1688,7 +1688,7 @@
"label.powerflex.gateway.username": "Gateway Username", "label.powerflex.gateway.username": "Gateway Username",
"label.powerflex.storage.pool": "Storage Pool", "label.powerflex.storage.pool": "Storage Pool",
"label.powerstate": "Power State", "label.powerstate": "Power State",
"label.preferred": "Prefered", "label.preferred": "Preferred",
"label.presetup": "PreSetup", "label.presetup": "PreSetup",
"label.prev": "Prev", "label.prev": "Prev",
"label.previous": "Previous", "label.previous": "Previous",
@ -1992,6 +1992,7 @@
"label.select.instance": "Select instance", "label.select.instance": "Select instance",
"label.select.instance.to.attach.volume.to": "Select instance to attach volume to", "label.select.instance.to.attach.volume.to": "Select instance to attach volume to",
"label.select.iso.or.template": "Select ISO or template", "label.select.iso.or.template": "Select ISO or template",
"label.select.network": "Select Network",
"label.select.offering": "Select offering", "label.select.offering": "Select offering",
"label.select.project": "Select Project", "label.select.project": "Select Project",
"label.select.projects": "Select Projects", "label.select.projects": "Select Projects",

View File

@ -0,0 +1,149 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
<template>
<div>
<a-table
class="top-spaced"
size="small"
style="max-height: 250px; overflow-y: auto"
:columns="nicColumns"
:dataSource="nics"
:pagination="false"
:rowKey="record => record.InstanceID">
<template slot="displaytext" slot-scope="record">
<span>{{ record.elementName + ' - ' + record.name }}
<a-tooltip :title="record.nicDescription" placement="top">
<a-icon type="info-circle" class="table-tooltip-icon" />
</a-tooltip>
</span>
</template>
<div slot="size" slot-scope="record">
<span v-if="record.size">
{{ $bytesToHumanReadableSize(record.size) }}
</span>
</div>
<template slot="selectednetwork" slot-scope="record">
<span>{{ record.selectednetworkname || '' }}</span>
</template>
<template slot="select" slot-scope="record">
<div style="display: flex; justify-content: flex-end;"><a-button @click="openNicNetworkSelector(record)">{{ record.selectednetworkid ? $t('label.change') : $t('label.select') }}</a-button></div>
</template>
</a-table>
<a-modal
:visible="!(!selectedNicForNetworkSelection.id)"
:title="$t('label.select.network')"
:closable="true"
:maskClosable="false"
:footer="null"
:cancelText="$t('label.cancel')"
@cancel="closeNicNetworkSelector()"
centered
width="auto">
<nic-network-select-form
:resource="selectedNicForNetworkSelection"
:zoneid="zoneid"
:isOpen="!(!selectedNicForNetworkSelection.id)"
@close-action="closeNicNetworkSelector()"
@select="handleNicNetworkSelection" />
</a-modal>
</div>
</template>
<script>
import NicNetworkSelectForm from '@/components/view/NicNetworkSelectForm'
export default {
name: 'InstanceNicsNetworkSelectListView',
components: {
NicNetworkSelectForm
},
props: {
nics: {
type: Array,
required: true
},
zoneid: {
type: String,
required: true
}
},
data () {
return {
nicColumns: [
{
title: this.$t('label.nic'),
scopedSlots: { customRender: 'displaytext' }
},
{
title: this.$t('label.network'),
scopedSlots: { customRender: 'selectednetwork' }
},
{
title: '',
scopedSlots: { customRender: 'select' }
}
],
selectedNicForNetworkSelection: {}
}
},
methods: {
resetSelection () {
var nics = this.nics
this.nics = []
for (var nic of nics) {
nic.selectednetworkid = null
nic.selectednetworkname = ''
}
this.nics = nics
this.updateNicToNetworkSelection()
},
openNicNetworkSelector (nic) {
this.selectedNicForNetworkSelection = nic
},
closeNicNetworkSelector () {
this.selectedNicForNetworkSelection = {}
},
handleNicNetworkSelection (nicId, network) {
for (const nic of this.nics) {
if (nic.id === nicId) {
nic.selectednetworkid = network.id
nic.selectednetworkname = network.name
break
}
}
this.updateNicToNetworkSelection()
},
updateNicToNetworkSelection () {
var nicToNetworkSelection = []
for (const nic of this.nics) {
if (nic.selectednetworkid && nic.selectednetworkid !== -1) {
nicToNetworkSelection.push({ nic: nic.id, network: nic.selectednetworkid })
}
}
this.$emit('select', nicToNetworkSelection)
}
}
}
</script>
<style scoped lang="less">
.top-spaced {
margin-top: 20px;
}
</style>

View File

@ -0,0 +1,228 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
<template>
<div class="form" v-ctrl-enter="handleKeyboardSubmit">
<div>
<a-input-search
class="top-spaced"
:placeholder="$t('label.search')"
v-model="searchQuery"
style="margin-bottom: 10px;"
@search="fetchNetworks"
autoFocus />
<a-table
size="small"
style="overflow-y: auto"
:loading="loading"
:columns="columns"
:dataSource="networks"
:pagination="false"
:rowKey="record => record.id">
<template slot="select" slot-scope="record">
<a-radio
@click="updateSelection(record)"
:checked="selectedNetwork != null && record.id === selectedNetwork.id">
</a-radio>
</template>
</a-table>
<a-pagination
class="top-spaced"
size="small"
:current="page"
:pageSize="pageSize"
:total="totalCount"
:showTotal="total => `${$t('label.total')} ${total} ${$t('label.items')}`"
:pageSizeOptions="['10', '20', '40', '80', '100']"
@change="handleChangePage"
@showSizeChange="handleChangePageSize"
showSizeChanger>
<template slot="buildOptionText" slot-scope="props">
<span>{{ props.value }} / {{ $t('label.page') }}</span>
</template>
</a-pagination>
</div>
<a-divider />
<div class="actions">
<a-button @click="closeModal">{{ $t('label.cancel') }}</a-button>
<a-button type="primary" ref="submit" :disabled="!selectedNetwork" @click="submitForm">{{ $t('label.ok') }}</a-button>
</div>
</div>
</template>
<script>
import { api } from '@/api'
export default {
name: 'NicNetworkSelectForm',
props: {
resource: {
type: Object,
required: true
},
zoneid: {
type: String,
required: true
},
isOpen: {
type: Boolean,
required: false
}
},
data () {
return {
loading: false,
networks: [],
searchQuery: '',
totalCount: 0,
page: 1,
pageSize: 10,
selectedNetwork: null,
columns: [
{
title: this.$t('label.networkid'),
dataIndex: 'name'
},
{
title: this.$t('label.guestiptype'),
dataIndex: 'type'
},
{
title: this.$t('label.vpc'),
dataIndex: 'vpcName'
},
{
title: this.$t('label.cidr'),
dataIndex: 'cidr'
},
{
title: this.$t('label.select'),
scopedSlots: { customRender: 'select' }
}
]
}
},
created () {
this.fetchNetworks()
this.preselectNetwork()
},
watch: {
isOpen (newValue) {
if (newValue) {
setTimeout(() => {
this.reset()
}, 50)
}
}
},
methods: {
fetchNetworks () {
this.loading = true
var params = {
zoneid: this.zoneid,
keyword: this.searchQuery,
page: this.page,
pagesize: this.pageSize,
canusefordeploy: true,
projectid: this.$store.getters.project ? this.$store.getters.project.id : null,
domainid: this.$store.getters.project && this.$store.getters.project.id ? null : this.$store.getters.userInfo.domainid,
account: this.$store.getters.project && this.$store.getters.project.id ? null : this.$store.getters.userInfo.account
}
api('listNetworks', params).then(response => {
this.networks = response.listnetworksresponse.network || []
this.totalCount = response.listnetworksresponse.count
}).catch(error => {
this.$notifyError(error)
}).finally(() => {
this.loading = false
})
},
handleChangePage (page, pageSize) {
this.page = page
this.pageSize = pageSize
this.fetchNetworks()
},
handleChangePageSize (currentPage, pageSize) {
this.page = currentPage
this.pageSize = pageSize
this.fetchNetworks()
},
preselectNetwork () {
if (this.resource && 'selectednetworkid' in this.resource) {
this.selectedNetwork = { id: this.resource.selectednetworkid }
}
},
clearView () {
this.networks = []
this.searchQuery = ''
this.totalCount = 0
this.page = 1
this.pageSize = 10
this.selectedNetwork = null
},
reset () {
this.clearView()
this.preselectNetwork()
this.fetchNetworks()
},
updateSelection (network) {
this.selectedNetwork = network
},
closeModal () {
this.$emit('close-action')
},
handleKeyboardSubmit () {
if (this.selectedNetwork != null) {
this.submitForm()
}
},
submitForm () {
this.$emit('select', this.resource.id, this.selectedNetwork)
this.closeModal()
}
}
}
</script>
<style scoped lang="scss">
.form {
width: 80vw;
@media (min-width: 900px) {
width: 850px;
}
}
.top-spaced {
margin-top: 20px;
}
.actions {
display: flex;
justify-content: flex-end;
margin-top: 20px;
button {
&:not(:last-child) {
margin-right: 10px;
}
}
}
</style>

View File

@ -390,31 +390,10 @@
<template slot="description"> <template slot="description">
<div v-if="zoneSelected"> <div v-if="zoneSelected">
<div v-if="vm.templateid && templateNics && templateNics.length > 0"> <div v-if="vm.templateid && templateNics && templateNics.length > 0">
<a-form-item <instance-nics-network-select-list-view
v-for="(nic, nicIndex) in templateNics" :nics="templateNics"
:key="nicIndex" :zoneid="selectedZone"
:v-bind="nic.name" > @select="handleNicsNetworkSelection" />
<tooltip-label slot="label" :title="nic.elementName + ' - ' + nic.name" :tooltip="nic.networkDescription"/>
<a-select
showSearch
optionFilterProp="children"
v-decorator="[
'networkMap.nic-' + nic.InstanceID.toString(),
{ initialValue: options.networks && options.networks.length > 0 ? options.networks[Math.min(nicIndex, options.networks.length - 1)].id : null }
]"
:placeholder="nic.networkDescription"
:filterOption="(input, option) => {
return option.componentOptions.children[0].children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
}"
>
<a-select-option v-for="opt in options.networks" :key="opt.id">
<span v-if="opt.type!=='L2'">
{{ opt.name || opt.description }} ({{ `${$t('label.cidr')}: ${opt.cidr}` }})
</span>
<span v-else>{{ opt.name || opt.description }}</span>
</a-select-option>
</a-select>
</a-form-item>
</div> </div>
<div v-show="!(vm.templateid && templateNics && templateNics.length > 0)" > <div v-show="!(vm.templateid && templateNics && templateNics.length > 0)" >
<network-selection <network-selection
@ -771,6 +750,7 @@ import NetworkConfiguration from '@views/compute/wizard/NetworkConfiguration'
import SshKeyPairSelection from '@views/compute/wizard/SshKeyPairSelection' import SshKeyPairSelection from '@views/compute/wizard/SshKeyPairSelection'
import SecurityGroupSelection from '@views/compute/wizard/SecurityGroupSelection' import SecurityGroupSelection from '@views/compute/wizard/SecurityGroupSelection'
import TooltipLabel from '@/components/widgets/TooltipLabel' import TooltipLabel from '@/components/widgets/TooltipLabel'
import InstanceNicsNetworkSelectListView from '@/components/view/InstanceNicsNetworkSelectListView.vue'
export default { export default {
name: 'Wizard', name: 'Wizard',
@ -788,7 +768,8 @@ export default {
ComputeSelection, ComputeSelection,
SecurityGroupSelection, SecurityGroupSelection,
ResourceIcon, ResourceIcon,
TooltipLabel TooltipLabel,
InstanceNicsNetworkSelectListView
}, },
props: { props: {
visible: { visible: {
@ -911,7 +892,8 @@ export default {
minIops: 0, minIops: 0,
maxIops: 0, maxIops: 0,
zones: [], zones: [],
selectedZone: '' selectedZone: '',
nicToNetworkSelection: []
} }
}, },
computed: { computed: {
@ -1796,13 +1778,11 @@ export default {
deployVmData.affinitygroupids = (values.affinitygroupids || []).join(',') deployVmData.affinitygroupids = (values.affinitygroupids || []).join(',')
// step 6: select network // step 6: select network
if (this.zone.networktype !== 'Basic') { if (this.zone.networktype !== 'Basic') {
if ('networkMap' in values) { if (this.nicToNetworkSelection && this.nicToNetworkSelection.length > 0) {
const keys = Object.keys(values.networkMap) for (var j in this.nicToNetworkSelection) {
for (var j = 0; j < keys.length; ++j) { var nicNetwork = this.nicToNetworkSelection[j]
if (values.networkMap[keys[j]] && values.networkMap[keys[j]].length > 0) { deployVmData['nicnetworklist[' + j + '].nic'] = nicNetwork.nic
deployVmData['nicnetworklist[' + j + '].nic'] = keys[j].replace('nic-', '') deployVmData['nicnetworklist[' + j + '].network'] = nicNetwork.network
deployVmData['nicnetworklist[' + j + '].network'] = values.networkMap[keys[j]]
}
} }
} else { } else {
const arrNetwork = [] const arrNetwork = []
@ -2172,6 +2152,17 @@ export default {
nics.sort(function (a, b) { nics.sort(function (a, b) {
return a.InstanceID - b.InstanceID return a.InstanceID - b.InstanceID
}) })
if (this.options.networks && this.options.networks.length > 0) {
this.nicToNetworkSelection = []
for (var i = 0; i < nics.length; ++i) {
var nic = nics[i]
nic.id = nic.InstanceID
var network = this.options.networks[Math.min(i, this.options.networks.length - 1)]
nic.selectednetworkid = network.id
nic.selectednetworkname = network.name
this.nicToNetworkSelection.push({ nic: nic.id, network: network.id })
}
}
} }
return nics return nics
}, },
@ -2336,6 +2327,9 @@ export default {
onBootTypeChange (value) { onBootTypeChange (value) {
this.fetchBootModes(value) this.fetchBootModes(value)
this.updateFieldValue('bootmode', this.options.bootModes?.[0]?.id || undefined) this.updateFieldValue('bootmode', this.options.bootModes?.[0]?.id || undefined)
},
handleNicsNetworkSelection (nicToNetworkSelection) {
this.nicToNetworkSelection = nicToNetworkSelection
} }
} }
} }

View File

@ -228,7 +228,7 @@
<a-radio-button value="strict"> <a-radio-button value="strict">
{{ $t('label.strict') }} {{ $t('label.strict') }}
</a-radio-button> </a-radio-button>
<a-radio-button value="preferred"> <a-radio-button value="Preferred">
{{ $t('label.preferred') }} {{ $t('label.preferred') }}
</a-radio-button> </a-radio-button>
</a-radio-group> </a-radio-group>

View File

@ -47,8 +47,8 @@
<artifactId>aspectjweaver</artifactId> <artifactId>aspectjweaver</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>log4j</groupId> <groupId>ch.qos.reload4j</groupId>
<artifactId>log4j</artifactId> <artifactId>reload4j</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>cglib</groupId> <groupId>cglib</groupId>
@ -143,6 +143,10 @@
<groupId>org.owasp.esapi</groupId> <groupId>org.owasp.esapi</groupId>
<artifactId>esapi</artifactId> <artifactId>esapi</artifactId>
<exclusions> <exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion> <exclusion>
<groupId>xml-apis</groupId> <groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId> <artifactId>xml-apis</artifactId>