mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge branch '4.16' into main
This commit is contained in:
commit
208ae84dd7
@ -154,5 +154,7 @@ public interface VolumeApiService {
|
||||
|
||||
Volume recoverVolume(long volumeId);
|
||||
|
||||
boolean validateVolumeSizeInBytes(long size);
|
||||
|
||||
Volume changeDiskOfferingForVolume(ChangeOfferingForVolumeCmd cmd) throws ResourceAllocationException;
|
||||
}
|
||||
|
||||
@ -355,7 +355,7 @@ public abstract class BaseCmd {
|
||||
if (roleIsAllowed) {
|
||||
validFields.add(field);
|
||||
} 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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -75,6 +75,13 @@ public interface VolumeOrchestrationService {
|
||||
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)
|
||||
throws ConcurrentOperationException, StorageUnavailableException;
|
||||
|
||||
|
||||
@ -221,7 +221,7 @@ public class VMEntityManagerImpl implements VMEntityManager {
|
||||
// call retry it.
|
||||
return UUID.randomUUID().toString();
|
||||
} 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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,10 +18,12 @@
|
||||
*/
|
||||
package org.apache.cloudstack.engine.orchestration;
|
||||
|
||||
import static com.cloud.storage.resource.StorageProcessor.REQUEST_TEMPLATE_RELOAD;
|
||||
import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -35,13 +37,6 @@ import java.util.stream.Collectors;
|
||||
import javax.inject.Inject;
|
||||
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.volume.MigrateVolumeCmdByAdmin;
|
||||
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.TemplateDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
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.VirtualMachineTO;
|
||||
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.StateMachine2;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
import com.cloud.vm.SecondaryStorageVmVO;
|
||||
import com.cloud.vm.UserVmCloneSettingVO;
|
||||
import com.cloud.vm.UserVmDetailVO;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.VirtualMachineProfileImpl;
|
||||
import com.cloud.vm.VmDetailConstants;
|
||||
import com.cloud.vm.VmWorkAttachVolume;
|
||||
import com.cloud.vm.VmWorkMigrateVolume;
|
||||
import com.cloud.vm.VmWorkSerializer;
|
||||
import com.cloud.vm.VmWorkTakeVolumeSnapshot;
|
||||
import com.cloud.vm.dao.SecondaryStorageVmDao;
|
||||
import com.cloud.vm.dao.UserVmCloneSettingDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
|
||||
import static com.cloud.storage.resource.StorageProcessor.REQUEST_TEMPLATE_RELOAD;
|
||||
import java.util.Date;
|
||||
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||
|
||||
public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrationService, Configurable {
|
||||
|
||||
@ -1779,8 +1778,6 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
||||
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",
|
||||
"If true, will recreate system vm root disk whenever starting system vm", true);
|
||||
|
||||
|
||||
@ -29,9 +29,9 @@
|
||||
</parent>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${cs.log4j.version}</version>
|
||||
<groupId>ch.qos.reload4j</groupId>
|
||||
<artifactId>reload4j</artifactId>
|
||||
<version>${cs.reload4j.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@ -139,16 +139,15 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
|
||||
}
|
||||
s_logger.info("Getting pending quota records for account=" + account.getAccountName());
|
||||
for (UsageVO usageRecord : usageRecords.first()) {
|
||||
BigDecimal aggregationRatio = new BigDecimal(_aggregationDuration).divide(s_minutesInMonth, 8, RoundingMode.HALF_EVEN);
|
||||
switch (usageRecord.getUsageType()) {
|
||||
case QuotaTypes.RUNNING_VM:
|
||||
List<QuotaUsageVO> lq = updateQuotaRunningVMUsage(usageRecord, aggregationRatio);
|
||||
List<QuotaUsageVO> lq = updateQuotaRunningVMUsage(usageRecord);
|
||||
if (!lq.isEmpty()) {
|
||||
quotaListForAccount.addAll(lq);
|
||||
}
|
||||
break;
|
||||
case QuotaTypes.ALLOCATED_VM:
|
||||
QuotaUsageVO qu = updateQuotaAllocatedVMUsage(usageRecord, aggregationRatio);
|
||||
QuotaUsageVO qu = updateQuotaAllocatedVMUsage(usageRecord);
|
||||
if (qu != null) {
|
||||
quotaListForAccount.add(qu);
|
||||
}
|
||||
@ -159,7 +158,7 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
|
||||
case QuotaTypes.VOLUME:
|
||||
case QuotaTypes.VM_SNAPSHOT:
|
||||
case QuotaTypes.BACKUP:
|
||||
qu = updateQuotaDiskUsage(usageRecord, aggregationRatio, usageRecord.getUsageType());
|
||||
qu = updateQuotaDiskUsage(usageRecord, usageRecord.getUsageType());
|
||||
if (qu != null) {
|
||||
quotaListForAccount.add(qu);
|
||||
}
|
||||
@ -170,7 +169,7 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
|
||||
case QuotaTypes.NETWORK_OFFERING:
|
||||
case QuotaTypes.SECURITY_GROUP:
|
||||
case QuotaTypes.VPN_USERS:
|
||||
qu = updateQuotaRaw(usageRecord, aggregationRatio, usageRecord.getUsageType());
|
||||
qu = updateQuotaRaw(usageRecord, usageRecord.getUsageType());
|
||||
if (qu != null) {
|
||||
quotaListForAccount.add(qu);
|
||||
}
|
||||
@ -333,14 +332,14 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
|
||||
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;
|
||||
QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(quotaType, usageRecord.getEndDate());
|
||||
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0) {
|
||||
BigDecimal quotaUsgage;
|
||||
BigDecimal onehourcostpergb;
|
||||
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);
|
||||
quotaUsgage = new BigDecimal(usageRecord.getRawUsage()).multiply(onehourcostpergb).multiply(noofgbinuse);
|
||||
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;
|
||||
}
|
||||
|
||||
public List<QuotaUsageVO> updateQuotaRunningVMUsage(UsageVO usageRecord, final BigDecimal aggregationRatio) {
|
||||
public List<QuotaUsageVO> updateQuotaRunningVMUsage(UsageVO usageRecord) {
|
||||
List<QuotaUsageVO> quotalist = new ArrayList<QuotaUsageVO>();
|
||||
QuotaUsageVO quota_usage;
|
||||
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());
|
||||
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0 && serviceoffering.getCpu() != null) {
|
||||
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);
|
||||
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.CPU_NUMBER,
|
||||
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());
|
||||
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0 && serviceoffering.getSpeed() != null) {
|
||||
BigDecimal speed = new BigDecimal(serviceoffering.getSpeed() / 100.00);
|
||||
onehourcostper100mhz = tariff.getCurrencyValue().multiply(aggregationRatio);
|
||||
BigDecimal speed = new BigDecimal(serviceoffering.getSpeed()*serviceoffering.getCpu() / 100.00);
|
||||
onehourcostper100mhz = tariff.getCurrencyValue().divide(s_hoursInMonth, 8, RoundingMode.HALF_DOWN);
|
||||
speedquotausage = rawusage.multiply(onehourcostper100mhz).multiply(speed);
|
||||
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.CPU_CLOCK_RATE,
|
||||
speedquotausage, usageRecord.getStartDate(), usageRecord.getEndDate());
|
||||
@ -388,7 +387,7 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
|
||||
tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.MEMORY, usageRecord.getEndDate());
|
||||
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0 && serviceoffering.getRamSize() != null) {
|
||||
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);
|
||||
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.MEMORY, memoryquotausage,
|
||||
usageRecord.getStartDate(), usageRecord.getEndDate());
|
||||
@ -397,7 +396,7 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
|
||||
}
|
||||
tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.RUNNING_VM, usageRecord.getEndDate());
|
||||
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);
|
||||
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.RUNNING_VM, vmusage,
|
||||
usageRecord.getStartDate(), usageRecord.getEndDate());
|
||||
@ -410,13 +409,13 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
|
||||
return quotalist;
|
||||
}
|
||||
|
||||
public QuotaUsageVO updateQuotaAllocatedVMUsage(UsageVO usageRecord, final BigDecimal aggregationRatio) {
|
||||
public QuotaUsageVO updateQuotaAllocatedVMUsage(UsageVO usageRecord) {
|
||||
QuotaUsageVO quota_usage = null;
|
||||
QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.ALLOCATED_VM, usageRecord.getEndDate());
|
||||
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0) {
|
||||
BigDecimal vmusage;
|
||||
BigDecimal onehourcostforvmusage;
|
||||
onehourcostforvmusage = tariff.getCurrencyValue().multiply(aggregationRatio);
|
||||
onehourcostforvmusage = tariff.getCurrencyValue().divide(s_hoursInMonth, 8, RoundingMode.HALF_DOWN);
|
||||
vmusage = new BigDecimal(usageRecord.getRawUsage()).multiply(onehourcostforvmusage);
|
||||
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.ALLOCATED_VM, vmusage,
|
||||
usageRecord.getStartDate(), usageRecord.getEndDate());
|
||||
@ -428,13 +427,13 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
|
||||
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;
|
||||
QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(ruleType, usageRecord.getEndDate());
|
||||
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0) {
|
||||
BigDecimal ruleusage;
|
||||
BigDecimal onehourcost;
|
||||
onehourcost = tariff.getCurrencyValue().multiply(aggregationRatio);
|
||||
onehourcost = tariff.getCurrencyValue().divide(s_hoursInMonth, 8, RoundingMode.HALF_DOWN);
|
||||
ruleusage = new BigDecimal(usageRecord.getRawUsage()).multiply(onehourcost);
|
||||
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), ruleType, ruleusage,
|
||||
usageRecord.getStartDate(), usageRecord.getEndDate());
|
||||
|
||||
@ -151,7 +151,7 @@ public class QuotaManagerImplTest extends TestCase {
|
||||
|
||||
QuotaUsageVO quotaUsageVO = new QuotaUsageVO();
|
||||
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, usageRecords).size() == 1);
|
||||
@ -172,11 +172,11 @@ public class QuotaManagerImplTest extends TestCase {
|
||||
|
||||
QuotaUsageVO qu = quotaManager.updateQuotaNetwork(usageVO, UsageTypes.NETWORK_BYTES_SENT);
|
||||
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);
|
||||
qu = quotaManager.updateQuotaDiskUsage(usageVO, new BigDecimal(0.5), UsageTypes.VOLUME);
|
||||
qu = quotaManager.updateQuotaDiskUsage(usageVO, UsageTypes.VOLUME);
|
||||
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);
|
||||
|
||||
Mockito.verify(quotaUsageDao, Mockito.times(4)).persistQuotaUsage(Mockito.any(QuotaUsageVO.class));
|
||||
|
||||
@ -305,6 +305,9 @@ public class ExplicitDedicationProcessor extends AffinityProcessorBase implement
|
||||
for (HostPodVO pod : podList) {
|
||||
DedicatedResourceVO dPod = _dedicatedDao.findByPodId(pod.getId());
|
||||
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());
|
||||
} else {
|
||||
includeList.addPod(pod.getId());
|
||||
@ -343,6 +346,9 @@ public class ExplicitDedicationProcessor extends AffinityProcessorBase implement
|
||||
|
||||
for (HostPodVO pod : pods) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,8 +33,8 @@
|
||||
<artifactId>org.apache.servicemix.bundles.snmp4j</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<groupId>ch.qos.reload4j</groupId>
|
||||
<artifactId>reload4j</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@ -29,8 +29,8 @@
|
||||
</parent>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<groupId>ch.qos.reload4j</groupId>
|
||||
<artifactId>reload4j</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@ -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);
|
||||
|
||||
if (!hostRunningVmsOfAccount.isEmpty() && (hostsToAvoid == null || !hostsToAvoid.containsAll(hostRunningVmsOfAccount))) {
|
||||
|
||||
@ -44,8 +44,8 @@
|
||||
<version>${cs.commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<groupId>ch.qos.reload4j</groupId>
|
||||
<artifactId>reload4j</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
|
||||
@ -86,9 +86,9 @@
|
||||
<version>${cs.guava.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${cs.log4j.version}</version>
|
||||
<groupId>ch.qos.reload4j</groupId>
|
||||
<artifactId>reload4j</artifactId>
|
||||
<version>${cs.reload4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
|
||||
@ -112,6 +112,12 @@
|
||||
<groupId>net.juniper.contrail</groupId>
|
||||
<artifactId>juniper-contrail-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>log4j</artifactId>
|
||||
<groupId>log4j</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
|
||||
@ -175,6 +175,10 @@
|
||||
<version>${ads.version}</version>
|
||||
<scope>test</scope>
|
||||
<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
|
||||
-->
|
||||
|
||||
20
pom.xml
20
pom.xml
@ -76,14 +76,14 @@
|
||||
<cs.clover-maven-plugin.version>4.4.1</cs.clover-maven-plugin.version>
|
||||
|
||||
<!-- 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.logging.version>1.1.1</cs.logging.version>
|
||||
|
||||
<!-- Apache Commons versions -->
|
||||
<cs.codec.version>1.15</cs.codec.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-fileupload.version>1.4</cs.commons-fileupload.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.testng.version>7.1.0</cs.testng.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 -->
|
||||
<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.xapi.version>6.2.0-3.1</cs.xapi.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>
|
||||
<cs.ini.version>0.5.4</cs.ini.version>
|
||||
<cs.gmaven.version>1.12.0</cs.gmaven.version>
|
||||
@ -439,9 +439,9 @@
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${cs.log4j.version}</version>
|
||||
<groupId>ch.qos.reload4j</groupId>
|
||||
<artifactId>reload4j</artifactId>
|
||||
<version>${cs.reload4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
@ -618,6 +618,12 @@
|
||||
<groupId>org.owasp.esapi</groupId>
|
||||
<artifactId>esapi</artifactId>
|
||||
<version>2.1.0.1</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- Test dependency in mysql for db tests -->
|
||||
<dependency>
|
||||
|
||||
@ -16,6 +16,15 @@
|
||||
// under the License.
|
||||
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.consoleproxy.ConsoleProxyManager;
|
||||
import com.cloud.ha.HighAvailabilityManager;
|
||||
@ -29,14 +38,6 @@ import com.cloud.storage.snapshot.SnapshotManager;
|
||||
import com.cloud.template.TemplateManager;
|
||||
import com.cloud.vm.UserVmManager;
|
||||
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
|
||||
@ -144,7 +145,6 @@ public enum Config {
|
||||
"60000",
|
||||
"The interval (in milliseconds) when storage stats (per host) are retrieved from agents.",
|
||||
null),
|
||||
MaxVolumeSize("Storage", ManagementServer.class, Integer.class, "storage.max.volume.size", "2000", "The maximum size for a volume (in GB).", null),
|
||||
StorageCacheReplacementLRUTimeInterval(
|
||||
"Storage",
|
||||
ManagementServer.class,
|
||||
|
||||
@ -43,7 +43,6 @@ import java.util.Vector;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.googlecode.ipv6.IPv6Address;
|
||||
import org.apache.cloudstack.acl.SecurityChecker;
|
||||
import org.apache.cloudstack.affinity.AffinityGroup;
|
||||
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.context.CallContext;
|
||||
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.ZoneScope;
|
||||
import org.apache.cloudstack.framework.config.ConfigDepot;
|
||||
@ -270,6 +270,7 @@ import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Preconditions;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.googlecode.ipv6.IPv6Address;
|
||||
|
||||
public class ConfigurationManagerImpl extends ManagerBase implements ConfigurationManager, ConfigurationService, Configurable {
|
||||
public static final Logger s_logger = Logger.getLogger(ConfigurationManagerImpl.class);
|
||||
@ -421,7 +422,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
@Inject
|
||||
protected DataCenterLinkLocalIpAddressDao _linkLocalIpAllocDao;
|
||||
|
||||
private int _maxVolumeSizeInGb = Integer.parseInt(Config.MaxVolumeSize.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}$";
|
||||
protected Set<String> configValuesForValidation;
|
||||
@ -477,9 +477,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
|
||||
@Override
|
||||
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());
|
||||
_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) {
|
||||
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) {
|
||||
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;
|
||||
diskOffering.setDiskSize(rootDiskSizeInBytes);
|
||||
}
|
||||
@ -3313,10 +3314,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength,
|
||||
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 maxVolumeSizeInGb = VolumeOrchestrationService.MaxVolumeSize.value();
|
||||
if (numGibibytes != null && numGibibytes <= 0) {
|
||||
throw new InvalidParameterValueException("Please specify a disk size of at least 1 Gb.");
|
||||
} else if (numGibibytes != null && numGibibytes > _maxVolumeSizeInGb) {
|
||||
throw new InvalidParameterValueException("The maximum size for a disk is " + _maxVolumeSizeInGb + " Gb.");
|
||||
throw new InvalidParameterValueException("Please specify a disk size of at least 1 GB.");
|
||||
} else if (numGibibytes != null && numGibibytes > maxVolumeSizeInGb) {
|
||||
throw new InvalidParameterValueException(String.format("The maximum size for a disk is %d GB.", maxVolumeSizeInGb));
|
||||
}
|
||||
final ProvisioningType typedProvisioningType = ProvisioningType.getProvisioningType(provisioningType);
|
||||
|
||||
|
||||
@ -752,9 +752,17 @@ StateListener<State, VirtualMachine.Event, VirtualMachine>, Configurable {
|
||||
//Only when the type is instance VM and not explicitly dedicated.
|
||||
if (vm.getType() == VirtualMachine.Type.User && !isExplicit) {
|
||||
//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);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Adding clusters to avoid lists for non-explicit VM deployment: " + 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);
|
||||
}
|
||||
|
||||
@ -833,8 +841,17 @@ StateListener<State, VirtualMachine.Event, VirtualMachine>, Configurable {
|
||||
}
|
||||
|
||||
//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);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Adding clusters to avoid lists: " + allClustersInDc);
|
||||
}
|
||||
avoids.addClusterList(allClustersInDc);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Adding hosts to avoid lists: " + allHostsInDc);
|
||||
}
|
||||
avoids.addHostList(allHostsInDc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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",
|
||||
"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 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();
|
||||
}
|
||||
|
||||
if (!validateVolumeSizeRange(size)) {// convert size from mb to gb
|
||||
// for validation
|
||||
throw new InvalidParameterValueException("Invalid size for custom volume creation: " + size + " ,max volume size is:" + _maxVolumeSizeInGb);
|
||||
if (!validateVolumeSizeInBytes(size)) {
|
||||
throw new InvalidParameterValueException(String.format("Invalid size for custom volume creation: %s, max volume size is: %s GB", NumbersUtil.toReadableSize(size), VolumeOrchestrationService.MaxVolumeSize.value()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -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))) {
|
||||
throw new InvalidParameterValueException("Please specify a size of at least 1 GB.");
|
||||
} else if (size > (_maxVolumeSizeInGb * 1024 * 1024 * 1024)) {
|
||||
throw new InvalidParameterValueException("Requested volume size is " + size + ", but the maximum size allowed is " + _maxVolumeSizeInGb + " GB.");
|
||||
} else if (size > (maxVolumeSize * 1024 * 1024 * 1024)) {
|
||||
throw new InvalidParameterValueException(String.format("Requested volume size is %s, but the maximum size allowed is %d GB.", NumbersUtil.toReadableSize(size), maxVolumeSize));
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
@ -3943,8 +3943,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) {
|
||||
String maxVolumeSizeInGbString = _configDao.getValue(Config.MaxVolumeSize.toString());
|
||||
_maxVolumeSizeInGb = NumbersUtil.parseLong(maxVolumeSizeInGbString, 2000);
|
||||
supportingDefaultHV = _hypervisorCapabilitiesDao.getHypervisorsWithDefaultEntries();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
// under the License.
|
||||
package com.cloud.vm;
|
||||
|
||||
import static com.cloud.configuration.ConfigurationManagerImpl.VM_USERDATA_MAX_LENGTH;
|
||||
import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -26,6 +27,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
@ -50,8 +52,6 @@ import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
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.ACLType;
|
||||
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.TemplateDataStoreDao;
|
||||
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.collections.CollectionUtils;
|
||||
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.guru.NetworkGuru;
|
||||
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.rules.FirewallManager;
|
||||
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.VMSnapshotVO;
|
||||
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 {
|
||||
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);
|
||||
long size = configureCustomRootDiskSize(customParameters, template, hypervisorType, rootdiskOffering);
|
||||
long volumesSize = configureCustomRootDiskSize(customParameters, template, hypervisorType, rootdiskOffering);
|
||||
|
||||
if (!isIso && diskOfferingId != null) {
|
||||
DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
|
||||
size += verifyAndGetDiskSize(diskOffering, diskSize);
|
||||
volumesSize += verifyAndGetDiskSize(diskOffering, diskSize);
|
||||
}
|
||||
if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
||||
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.primary_storage, size);
|
||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumesSize);
|
||||
|
||||
// verify security group ids
|
||||
if (securityGroupIdList != null) {
|
||||
@ -4136,7 +4135,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
|
||||
private long verifyAndGetDiskSize(DiskOfferingVO diskOffering, Long diskSize) {
|
||||
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) {
|
||||
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
|
||||
+ " Min:" + customDiskOfferingMinSize);
|
||||
}
|
||||
size += diskSize * GiB_TO_BYTES;
|
||||
size = diskSize * GiB_TO_BYTES;
|
||||
} else {
|
||||
size = diskOffering.getDiskSize();
|
||||
}
|
||||
size += diskOffering.getDiskSize();
|
||||
_volumeService.validateVolumeSizeInBytes(size);
|
||||
return size;
|
||||
}
|
||||
|
||||
@ -4170,6 +4174,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
verifyIfHypervisorSupportsRootdiskSizeOverride(hypervisorType);
|
||||
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
|
||||
_volumeService.validateVolumeSizeInBytes(rootDiskSizeInBytes);
|
||||
long rootDiskSizeInGiB = rootDiskSizeInBytes / GiB_TO_BYTES;
|
||||
customParameters.put(VmDetailConstants.ROOT_DISK_SIZE, String.valueOf(rootDiskSizeInGiB));
|
||||
return rootDiskSizeInBytes;
|
||||
@ -4180,7 +4185,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
if (rootDiskSize <= 0) {
|
||||
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 {
|
||||
// For baremetal, size can be 0 (zero)
|
||||
Long templateSize = _templateDao.findById(template.getId()).getSize();
|
||||
|
||||
@ -33,15 +33,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
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.command.user.vm.UpdateVMCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
|
||||
@ -59,24 +50,34 @@ import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
|
||||
import com.cloud.configuration.Resource;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.exception.InsufficientAddressCapacityException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
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.VMTemplateDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.ResourceLimitService;
|
||||
import com.cloud.user.UserVO;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
@ -151,6 +152,9 @@ public class UserVmManagerImplTest {
|
||||
@Mock
|
||||
ResourceLimitService resourceLimitMgr;
|
||||
|
||||
@Mock
|
||||
VolumeApiService volumeApiService;
|
||||
|
||||
private long vmId = 1l;
|
||||
|
||||
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(volumeApiService.validateVolumeSizeInBytes(Mockito.anyLong())).thenReturn(true);
|
||||
long rootDiskSize = userVmManagerImpl.configureCustomRootDiskSize(customParameters, template, Hypervisor.HypervisorType.KVM, diskfferingVo);
|
||||
|
||||
Assert.assertEquals(expectedRootDiskSize, rootDiskSize);
|
||||
|
||||
@ -29,8 +29,8 @@
|
||||
</parent>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<groupId>ch.qos.reload4j</groupId>
|
||||
<artifactId>reload4j</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
|
||||
@ -29,8 +29,8 @@
|
||||
</parent>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<groupId>ch.qos.reload4j</groupId>
|
||||
<artifactId>reload4j</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
|
||||
@ -33,8 +33,8 @@
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<groupId>ch.qos.reload4j</groupId>
|
||||
<artifactId>reload4j</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jenkins-ci</groupId>
|
||||
|
||||
@ -1688,7 +1688,7 @@
|
||||
"label.powerflex.gateway.username": "Gateway Username",
|
||||
"label.powerflex.storage.pool": "Storage Pool",
|
||||
"label.powerstate": "Power State",
|
||||
"label.preferred": "Prefered",
|
||||
"label.preferred": "Preferred",
|
||||
"label.presetup": "PreSetup",
|
||||
"label.prev": "Prev",
|
||||
"label.previous": "Previous",
|
||||
@ -1992,6 +1992,7 @@
|
||||
"label.select.instance": "Select instance",
|
||||
"label.select.instance.to.attach.volume.to": "Select instance to attach volume to",
|
||||
"label.select.iso.or.template": "Select ISO or template",
|
||||
"label.select.network": "Select Network",
|
||||
"label.select.offering": "Select offering",
|
||||
"label.select.project": "Select Project",
|
||||
"label.select.projects": "Select Projects",
|
||||
|
||||
149
ui/src/components/view/InstanceNicsNetworkSelectListView.vue
Normal file
149
ui/src/components/view/InstanceNicsNetworkSelectListView.vue
Normal 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>
|
||||
228
ui/src/components/view/NicNetworkSelectForm.vue
Normal file
228
ui/src/components/view/NicNetworkSelectForm.vue
Normal 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>
|
||||
@ -390,31 +390,10 @@
|
||||
<template slot="description">
|
||||
<div v-if="zoneSelected">
|
||||
<div v-if="vm.templateid && templateNics && templateNics.length > 0">
|
||||
<a-form-item
|
||||
v-for="(nic, nicIndex) in templateNics"
|
||||
:key="nicIndex"
|
||||
:v-bind="nic.name" >
|
||||
<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>
|
||||
<instance-nics-network-select-list-view
|
||||
:nics="templateNics"
|
||||
:zoneid="selectedZone"
|
||||
@select="handleNicsNetworkSelection" />
|
||||
</div>
|
||||
<div v-show="!(vm.templateid && templateNics && templateNics.length > 0)" >
|
||||
<network-selection
|
||||
@ -771,6 +750,7 @@ import NetworkConfiguration from '@views/compute/wizard/NetworkConfiguration'
|
||||
import SshKeyPairSelection from '@views/compute/wizard/SshKeyPairSelection'
|
||||
import SecurityGroupSelection from '@views/compute/wizard/SecurityGroupSelection'
|
||||
import TooltipLabel from '@/components/widgets/TooltipLabel'
|
||||
import InstanceNicsNetworkSelectListView from '@/components/view/InstanceNicsNetworkSelectListView.vue'
|
||||
|
||||
export default {
|
||||
name: 'Wizard',
|
||||
@ -788,7 +768,8 @@ export default {
|
||||
ComputeSelection,
|
||||
SecurityGroupSelection,
|
||||
ResourceIcon,
|
||||
TooltipLabel
|
||||
TooltipLabel,
|
||||
InstanceNicsNetworkSelectListView
|
||||
},
|
||||
props: {
|
||||
visible: {
|
||||
@ -911,7 +892,8 @@ export default {
|
||||
minIops: 0,
|
||||
maxIops: 0,
|
||||
zones: [],
|
||||
selectedZone: ''
|
||||
selectedZone: '',
|
||||
nicToNetworkSelection: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -1796,13 +1778,11 @@ export default {
|
||||
deployVmData.affinitygroupids = (values.affinitygroupids || []).join(',')
|
||||
// step 6: select network
|
||||
if (this.zone.networktype !== 'Basic') {
|
||||
if ('networkMap' in values) {
|
||||
const keys = Object.keys(values.networkMap)
|
||||
for (var j = 0; j < keys.length; ++j) {
|
||||
if (values.networkMap[keys[j]] && values.networkMap[keys[j]].length > 0) {
|
||||
deployVmData['nicnetworklist[' + j + '].nic'] = keys[j].replace('nic-', '')
|
||||
deployVmData['nicnetworklist[' + j + '].network'] = values.networkMap[keys[j]]
|
||||
}
|
||||
if (this.nicToNetworkSelection && this.nicToNetworkSelection.length > 0) {
|
||||
for (var j in this.nicToNetworkSelection) {
|
||||
var nicNetwork = this.nicToNetworkSelection[j]
|
||||
deployVmData['nicnetworklist[' + j + '].nic'] = nicNetwork.nic
|
||||
deployVmData['nicnetworklist[' + j + '].network'] = nicNetwork.network
|
||||
}
|
||||
} else {
|
||||
const arrNetwork = []
|
||||
@ -2172,6 +2152,17 @@ export default {
|
||||
nics.sort(function (a, b) {
|
||||
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
|
||||
},
|
||||
@ -2336,6 +2327,9 @@ export default {
|
||||
onBootTypeChange (value) {
|
||||
this.fetchBootModes(value)
|
||||
this.updateFieldValue('bootmode', this.options.bootModes?.[0]?.id || undefined)
|
||||
},
|
||||
handleNicsNetworkSelection (nicToNetworkSelection) {
|
||||
this.nicToNetworkSelection = nicToNetworkSelection
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -228,7 +228,7 @@
|
||||
<a-radio-button value="strict">
|
||||
{{ $t('label.strict') }}
|
||||
</a-radio-button>
|
||||
<a-radio-button value="preferred">
|
||||
<a-radio-button value="Preferred">
|
||||
{{ $t('label.preferred') }}
|
||||
</a-radio-button>
|
||||
</a-radio-group>
|
||||
|
||||
@ -47,8 +47,8 @@
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<groupId>ch.qos.reload4j</groupId>
|
||||
<artifactId>reload4j</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
@ -143,6 +143,10 @@
|
||||
<groupId>org.owasp.esapi</groupId>
|
||||
<artifactId>esapi</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>xml-apis</groupId>
|
||||
<artifactId>xml-apis</artifactId>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user