mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-02 11:52:28 +01:00
Merge remote-tracking branch 'origin/4.15'
This commit is contained in:
commit
22f6c19248
@ -22,8 +22,10 @@ import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
||||
/**
|
||||
@ -141,4 +143,6 @@ public interface CapacityManager {
|
||||
long getUsedBytes(StoragePoolVO pool);
|
||||
|
||||
long getUsedIops(StoragePoolVO pool);
|
||||
|
||||
Pair<Boolean, Boolean> checkIfHostHasCpuCapabilityAndCapacity(Host host, ServiceOffering offering, boolean considerReservedCapacity);
|
||||
}
|
||||
|
||||
@ -23,3 +23,36 @@
|
||||
UPDATE `cloud`.`guest_os` SET display_name='Fedora Linux (32 bit)' WHERE id=320;
|
||||
UPDATE `cloud`.`guest_os` SET display_name='Mandriva Linux (32 bit)' WHERE id=323;
|
||||
UPDATE `cloud`.`guest_os` SET display_name='OpenSUSE Linux (32 bit)' WHERE id=327;
|
||||
|
||||
-- Add support for SUSE Linux Enterprise Desktop 12 SP3 (64-bit) for Xenserver 8.1.0
|
||||
INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (330, UUID(), 5, 'SUSE Linux Enterprise Desktop 12 SP3 (64-bit)', now());
|
||||
INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '8.1.0', 'SUSE Linux Enterprise Desktop 12 SP3 (64-bit)', 330, now(), 0);
|
||||
-- Add support for SUSE Linux Enterprise Desktop 12 SP4 (64-bit) for Xenserver 8.1.0
|
||||
INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (331, UUID(), 5, 'SUSE Linux Enterprise Desktop 12 SP4 (64-bit)', now());
|
||||
INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '8.1.0', 'SUSE Linux Enterprise Desktop 12 SP4 (64-bit)', 331, now(), 0);
|
||||
-- Add support for SUSE Linux Enterprise Server 12 SP4 (64-bit) for Xenserver 8.1.0
|
||||
INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (332, UUID(), 5, 'SUSE Linux Enterprise Server 12 SP4 (64-bit)', now());
|
||||
INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '8.1.0', 'SUSE Linux Enterprise Server 12 SP4 (64-bit)', 332, now(), 0);
|
||||
-- Add support for Scientific Linux 7 for Xenserver 8.1.0
|
||||
INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (333, UUID(), 9, 'Scientific Linux 7', now());
|
||||
INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '8.1.0', 'Scientific Linux 7', 333, now(), 0);
|
||||
-- Add support for NeoKylin Linux Server 7 for Xenserver 8.1.0
|
||||
INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (334, UUID(), 9, 'NeoKylin Linux Server 7', now());
|
||||
INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '8.1.0', 'NeoKylin Linux Server 7', 332, now(), 0);
|
||||
-- Add support CentOS 8 for Xenserver 8.1.0
|
||||
INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '8.1.0', 'CentOS 8', 297, now(), 0);
|
||||
-- Add support for Debian Buster 10 for Xenserver 8.1.0
|
||||
INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '8.1.0', 'Debian Buster 10', 292, now(), 0);
|
||||
INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '8.1.0', 'Debian Buster 10', 293, now(), 0);
|
||||
-- Add support for SUSE Linux Enterprise 15 (64-bit) for Xenserver 8.1.0
|
||||
INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '8.1.0', 'SUSE Linux Enterprise 15 (64-bit)', 291, now(), 0);
|
||||
|
||||
-- Add XenServer 8.2.0 hypervisor capabilities
|
||||
INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(uuid, hypervisor_type, hypervisor_version, max_guests_limit, max_data_volumes_limit, max_hosts_per_cluster, storage_motion_supported) values (UUID(), 'XenServer', '8.2.0', 1000, 253, 64, 1);
|
||||
|
||||
-- Copy XenServer 8.1.0 hypervisor guest OS mappings to XenServer 8.2.0
|
||||
INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) SELECT UUID(),'Xenserver', '8.2.0', guest_os_name, guest_os_id, utc_timestamp(), 0 FROM `cloud`.`guest_os_hypervisor` WHERE hypervisor_type='Xenserver' AND hypervisor_version='8.1.0';
|
||||
|
||||
-- Add support for Ubuntu Focal Fossa 20.04 for Xenserver 8.2.0
|
||||
INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (335, UUID(), 10, 'Ubuntu 20.04 LTS', now());
|
||||
INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '8.2.0', 'Ubuntu Focal Fossa 20.04', 330, now(), 0);
|
||||
|
||||
@ -22,10 +22,14 @@ import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.agent.manager.allocator.HostAllocator;
|
||||
import com.cloud.capacity.CapacityManager;
|
||||
import com.cloud.dc.ClusterDetailsDao;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
import com.cloud.host.Host;
|
||||
@ -34,6 +38,7 @@ import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.resource.ResourceManager;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
@ -45,6 +50,81 @@ public class RandomAllocator extends AdapterBase implements HostAllocator {
|
||||
private HostDao _hostDao;
|
||||
@Inject
|
||||
private ResourceManager _resourceMgr;
|
||||
@Inject
|
||||
private ClusterDao clusterDao;
|
||||
@Inject
|
||||
private ClusterDetailsDao clusterDetailsDao;
|
||||
@Inject
|
||||
private CapacityManager capacityManager;
|
||||
|
||||
private List<Host> findSuitableHosts(VirtualMachineProfile vmProfile, DeploymentPlan plan, Type type,
|
||||
ExcludeList avoid, List<? extends Host> hosts, int returnUpTo,
|
||||
boolean considerReservedCapacity) {
|
||||
long dcId = plan.getDataCenterId();
|
||||
Long podId = plan.getPodId();
|
||||
Long clusterId = plan.getClusterId();
|
||||
ServiceOffering offering = vmProfile.getServiceOffering();
|
||||
List<? extends Host> hostsCopy = null;
|
||||
List<Host> suitableHosts = new ArrayList<Host>();
|
||||
|
||||
if (type == Host.Type.Storage) {
|
||||
return suitableHosts;
|
||||
}
|
||||
String hostTag = offering.getHostTag();
|
||||
if (hostTag != null) {
|
||||
s_logger.debug("Looking for hosts in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId + " having host tag:" + hostTag);
|
||||
} else {
|
||||
s_logger.debug("Looking for hosts in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId);
|
||||
}
|
||||
if (hosts != null) {
|
||||
// retain all computing hosts, regardless of whether they support routing...it's random after all
|
||||
hostsCopy = new ArrayList<Host>(hosts);
|
||||
if (hostTag != null) {
|
||||
hostsCopy.retainAll(_hostDao.listByHostTag(type, clusterId, podId, dcId, hostTag));
|
||||
} else {
|
||||
hostsCopy.retainAll(_resourceMgr.listAllUpAndEnabledHosts(type, clusterId, podId, dcId));
|
||||
}
|
||||
} else {
|
||||
// list all computing hosts, regardless of whether they support routing...it's random after all
|
||||
hostsCopy = new ArrayList<HostVO>();
|
||||
if (hostTag != null) {
|
||||
hostsCopy = _hostDao.listByHostTag(type, clusterId, podId, dcId, hostTag);
|
||||
} else {
|
||||
hostsCopy = _resourceMgr.listAllUpAndEnabledHosts(type, clusterId, podId, dcId);
|
||||
}
|
||||
}
|
||||
s_logger.debug("Random Allocator found " + hostsCopy.size() + " hosts");
|
||||
if (hostsCopy.size() == 0) {
|
||||
return suitableHosts;
|
||||
}
|
||||
Collections.shuffle(hostsCopy);
|
||||
for (Host host : hostsCopy) {
|
||||
if (suitableHosts.size() == returnUpTo) {
|
||||
break;
|
||||
}
|
||||
if (avoid.shouldAvoid(host)) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Host name: " + host.getName() + ", hostId: " + host.getId() + " is in avoid set, skipping this and trying other available hosts");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
Pair<Boolean, Boolean> cpuCapabilityAndCapacity = capacityManager.checkIfHostHasCpuCapabilityAndCapacity(host, offering, considerReservedCapacity);
|
||||
if (!cpuCapabilityAndCapacity.first() || !cpuCapabilityAndCapacity.second()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Not using host " + host.getId() + "; host has cpu capability? " + cpuCapabilityAndCapacity.first() + ", host has capacity?" + cpuCapabilityAndCapacity.second());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Found a suitable host, adding to list: " + host.getId());
|
||||
}
|
||||
suitableHosts.add(host);
|
||||
}
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Random Host Allocator returning " + suitableHosts.size() + " suitable hosts");
|
||||
}
|
||||
return suitableHosts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Host> allocateTo(VirtualMachineProfile vmProfile, DeploymentPlan plan, Type type, ExcludeList avoid, int returnUpTo) {
|
||||
@ -52,113 +132,22 @@ public class RandomAllocator extends AdapterBase implements HostAllocator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Host> allocateTo(VirtualMachineProfile vmProfile, DeploymentPlan plan, Type type, ExcludeList avoid, List<? extends Host> hosts, int returnUpTo,
|
||||
boolean considerReservedCapacity) {
|
||||
long dcId = plan.getDataCenterId();
|
||||
Long podId = plan.getPodId();
|
||||
Long clusterId = plan.getClusterId();
|
||||
ServiceOffering offering = vmProfile.getServiceOffering();
|
||||
List<Host> suitableHosts = new ArrayList<Host>();
|
||||
List<Host> hostsCopy = new ArrayList<Host>(hosts);
|
||||
|
||||
if (type == Host.Type.Storage) {
|
||||
return suitableHosts;
|
||||
}
|
||||
|
||||
String hostTag = offering.getHostTag();
|
||||
if (hostTag != null) {
|
||||
s_logger.debug("Looking for hosts in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId + " having host tag:" + hostTag);
|
||||
} else {
|
||||
s_logger.debug("Looking for hosts in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId);
|
||||
}
|
||||
|
||||
// list all computing hosts, regardless of whether they support routing...it's random after all
|
||||
if (hostTag != null) {
|
||||
hostsCopy.retainAll(_hostDao.listByHostTag(type, clusterId, podId, dcId, hostTag));
|
||||
} else {
|
||||
hostsCopy.retainAll(_resourceMgr.listAllUpAndEnabledHosts(type, clusterId, podId, dcId));
|
||||
}
|
||||
|
||||
s_logger.debug("Random Allocator found " + hostsCopy.size() + " hosts");
|
||||
if (hostsCopy.size() == 0) {
|
||||
return suitableHosts;
|
||||
}
|
||||
|
||||
Collections.shuffle(hostsCopy);
|
||||
for (Host host : hostsCopy) {
|
||||
if (suitableHosts.size() == returnUpTo) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!avoid.shouldAvoid(host)) {
|
||||
suitableHosts.add(host);
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Host name: " + host.getName() + ", hostId: " + host.getId() + " is in avoid set, " + "skipping this and trying other available hosts");
|
||||
}
|
||||
public List<Host> allocateTo(VirtualMachineProfile vmProfile, DeploymentPlan plan, Type type,
|
||||
ExcludeList avoid, List<? extends Host> hosts, int returnUpTo,
|
||||
boolean considerReservedCapacity) {
|
||||
if (CollectionUtils.isEmpty(hosts)) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Random Allocator found 0 hosts as given host list is empty");
|
||||
}
|
||||
return new ArrayList<Host>();
|
||||
}
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Random Host Allocator returning " + suitableHosts.size() + " suitable hosts");
|
||||
}
|
||||
|
||||
return suitableHosts;
|
||||
return findSuitableHosts(vmProfile, plan, type, avoid, hosts, returnUpTo, considerReservedCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Host> allocateTo(VirtualMachineProfile vmProfile, DeploymentPlan plan, Type type, ExcludeList avoid, int returnUpTo, boolean considerReservedCapacity) {
|
||||
|
||||
long dcId = plan.getDataCenterId();
|
||||
Long podId = plan.getPodId();
|
||||
Long clusterId = plan.getClusterId();
|
||||
ServiceOffering offering = vmProfile.getServiceOffering();
|
||||
|
||||
List<Host> suitableHosts = new ArrayList<Host>();
|
||||
|
||||
if (type == Host.Type.Storage) {
|
||||
return suitableHosts;
|
||||
}
|
||||
|
||||
String hostTag = offering.getHostTag();
|
||||
if (hostTag != null) {
|
||||
s_logger.debug("Looking for hosts in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId + " having host tag:" + hostTag);
|
||||
} else {
|
||||
s_logger.debug("Looking for hosts in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId);
|
||||
}
|
||||
|
||||
// list all computing hosts, regardless of whether they support routing...it's random after all
|
||||
List<? extends Host> hosts = new ArrayList<HostVO>();
|
||||
if (hostTag != null) {
|
||||
hosts = _hostDao.listByHostTag(type, clusterId, podId, dcId, hostTag);
|
||||
} else {
|
||||
hosts = _resourceMgr.listAllUpAndEnabledHosts(type, clusterId, podId, dcId);
|
||||
}
|
||||
|
||||
s_logger.debug("Random Allocator found " + hosts.size() + " hosts");
|
||||
|
||||
if (hosts.size() == 0) {
|
||||
return suitableHosts;
|
||||
}
|
||||
|
||||
Collections.shuffle(hosts);
|
||||
for (Host host : hosts) {
|
||||
if (suitableHosts.size() == returnUpTo) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!avoid.shouldAvoid(host)) {
|
||||
suitableHosts.add(host);
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Host name: " + host.getName() + ", hostId: " + host.getId() + " is in avoid set, skipping this and trying other available hosts");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Random Host Allocator returning " + suitableHosts.size() + " suitable hosts");
|
||||
}
|
||||
return suitableHosts;
|
||||
public List<Host> allocateTo(VirtualMachineProfile vmProfile, DeploymentPlan plan,
|
||||
Type type, ExcludeList avoid, int returnUpTo, boolean considerReservedCapacity) {
|
||||
return findSuitableHosts(vmProfile, plan, type, avoid, null, returnUpTo, considerReservedCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
package com.cloud.hypervisor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -98,7 +99,14 @@ public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru,
|
||||
if (userVmVO != null) {
|
||||
HostVO host = hostDao.findById(userVmVO.getHostId());
|
||||
if (host != null) {
|
||||
to.setVcpuMaxLimit(MaxNumberOfVCPUSPerVM.valueIn(host.getClusterId()));
|
||||
List<HostVO> clusterHosts = hostDao.listByClusterAndHypervisorType(host.getClusterId(), host.getHypervisorType());
|
||||
HostVO hostWithMinSocket = clusterHosts.stream().min(Comparator.comparing(HostVO::getCpuSockets)).orElse(null);
|
||||
Integer vCpus = MaxNumberOfVCPUSPerVM.valueIn(host.getClusterId());
|
||||
if (hostWithMinSocket != null && hostWithMinSocket.getCpuSockets() != null &&
|
||||
hostWithMinSocket.getCpuSockets() < vCpus) {
|
||||
vCpus = hostWithMinSocket.getCpuSockets();
|
||||
}
|
||||
to.setVcpuMaxLimit(vCpus);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -307,7 +307,6 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
|
||||
Field f = startVm.getClass().getDeclaredField("id");
|
||||
f.setAccessible(true);
|
||||
f.set(startVm, vm.getId());
|
||||
resizeNodeVolume(vm);
|
||||
userVmService.startVirtualMachine(startVm);
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info(String.format("Started VM : %s in the Kubernetes cluster : %s", vm.getDisplayName(), kubernetesCluster.getName()));
|
||||
|
||||
@ -35,7 +35,6 @@ import com.cloud.capacity.CapacityVO;
|
||||
import com.cloud.capacity.dao.CapacityDao;
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.dc.ClusterDetailsDao;
|
||||
import com.cloud.dc.ClusterDetailsVO;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
@ -47,7 +46,6 @@ import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.host.dao.HostDetailsDao;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.org.Cluster;
|
||||
import com.cloud.resource.ResourceManager;
|
||||
import com.cloud.service.ServiceOfferingDetailsVO;
|
||||
import com.cloud.service.dao.ServiceOfferingDetailsDao;
|
||||
@ -57,12 +55,13 @@ import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.dao.GuestOSCategoryDao;
|
||||
import com.cloud.storage.dao.GuestOSDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.vm.UserVmDetailVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.cloud.vm.UserVmDetailVO;
|
||||
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
|
||||
/**
|
||||
@ -336,27 +335,15 @@ public class FirstFitAllocator extends AdapterBase implements HostAllocator {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
int cpu_requested = offering.getCpu() * offering.getSpeed();
|
||||
long ram_requested = offering.getRamSize() * 1024L * 1024L;
|
||||
Cluster cluster = _clusterDao.findById(host.getClusterId());
|
||||
ClusterDetailsVO clusterDetailsCpuOvercommit = _clusterDetailsDao.findDetail(cluster.getId(), "cpuOvercommitRatio");
|
||||
ClusterDetailsVO clusterDetailsRamOvercommmt = _clusterDetailsDao.findDetail(cluster.getId(), "memoryOvercommitRatio");
|
||||
Float cpuOvercommitRatio = Float.parseFloat(clusterDetailsCpuOvercommit.getValue());
|
||||
Float memoryOvercommitRatio = Float.parseFloat(clusterDetailsRamOvercommmt.getValue());
|
||||
|
||||
boolean hostHasCpuCapability = _capacityMgr.checkIfHostHasCpuCapability(host.getId(), offering.getCpu(), offering.getSpeed());
|
||||
boolean hostHasCapacity = _capacityMgr.checkIfHostHasCapacity(host.getId(), cpu_requested, ram_requested, false, cpuOvercommitRatio, memoryOvercommitRatio,
|
||||
considerReservedCapacity);
|
||||
|
||||
if (hostHasCpuCapability && hostHasCapacity) {
|
||||
Pair<Boolean, Boolean> cpuCapabilityAndCapacity = _capacityMgr.checkIfHostHasCpuCapabilityAndCapacity(host, offering, considerReservedCapacity);
|
||||
if (cpuCapabilityAndCapacity.first() && cpuCapabilityAndCapacity.second()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Found a suitable host, adding to list: " + host.getId());
|
||||
}
|
||||
suitableHosts.add(host);
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Not using host " + host.getId() + "; host has cpu capability? " + hostHasCpuCapability + ", host has capacity?" + hostHasCapacity);
|
||||
s_logger.debug("Not using host " + host.getId() + "; host has cpu capability? " + cpuCapabilityAndCapacity.first() + ", host has capacity?" + cpuCapabilityAndCapacity.second());
|
||||
}
|
||||
avoid.addHost(host.getId());
|
||||
}
|
||||
|
||||
@ -60,6 +60,7 @@ import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.org.Cluster;
|
||||
import com.cloud.resource.ResourceListener;
|
||||
import com.cloud.resource.ResourceManager;
|
||||
import com.cloud.resource.ResourceState;
|
||||
@ -1101,6 +1102,23 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<Boolean, Boolean> checkIfHostHasCpuCapabilityAndCapacity(Host host, ServiceOffering offering, boolean considerReservedCapacity) {
|
||||
int cpu_requested = offering.getCpu() * offering.getSpeed();
|
||||
long ram_requested = offering.getRamSize() * 1024L * 1024L;
|
||||
Cluster cluster = _clusterDao.findById(host.getClusterId());
|
||||
ClusterDetailsVO clusterDetailsCpuOvercommit = _clusterDetailsDao.findDetail(cluster.getId(), "cpuOvercommitRatio");
|
||||
ClusterDetailsVO clusterDetailsRamOvercommmt = _clusterDetailsDao.findDetail(cluster.getId(), "memoryOvercommitRatio");
|
||||
Float cpuOvercommitRatio = Float.parseFloat(clusterDetailsCpuOvercommit.getValue());
|
||||
Float memoryOvercommitRatio = Float.parseFloat(clusterDetailsRamOvercommmt.getValue());
|
||||
|
||||
boolean hostHasCpuCapability = checkIfHostHasCpuCapability(host.getId(), offering.getCpu(), offering.getSpeed());
|
||||
boolean hostHasCapacity = checkIfHostHasCapacity(host.getId(), cpu_requested, ram_requested, false, cpuOvercommitRatio, memoryOvercommitRatio,
|
||||
considerReservedCapacity);
|
||||
|
||||
return new Pair<>(hostHasCpuCapability, hostHasCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processAnswers(long agentId, long seq, Answer[] answers) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
@ -37,6 +37,7 @@ from marvin.codes import PASS, FAILED
|
||||
from marvin.lib.base import (Template,
|
||||
ServiceOffering,
|
||||
Account,
|
||||
StoragePool,
|
||||
Configurations)
|
||||
from marvin.lib.utils import (cleanup_resources,
|
||||
validateList,
|
||||
@ -81,7 +82,7 @@ class TestKubernetesCluster(cloudstackTestCase):
|
||||
"cloud.kubernetes.service.enabled",
|
||||
"true")
|
||||
cls.restartServer()
|
||||
|
||||
cls.updateVmwareSettings(False)
|
||||
cls.cks_template = None
|
||||
cls.initial_configuration_cks_template_name = None
|
||||
cls.cks_service_offering = None
|
||||
@ -120,12 +121,13 @@ class TestKubernetesCluster(cloudstackTestCase):
|
||||
(cls.services["cks_kubernetes_versions"]["1.16.3"]["semanticversion"], cls.services["cks_kubernetes_versions"]["1.16.3"]["url"], e))
|
||||
|
||||
if cls.setup_failed == False:
|
||||
cls.cks_template = cls.getKubernetesTemplate()
|
||||
cls.cks_template, existAlready = cls.getKubernetesTemplate()
|
||||
if cls.cks_template == FAILED:
|
||||
assert False, "getKubernetesTemplate() failed to return template for hypervisor %s" % cls.hypervisor
|
||||
cls.setup_failed = True
|
||||
else:
|
||||
cls._cleanup.append(cls.cks_template)
|
||||
if not existAlready:
|
||||
cls._cleanup.append(cls.cks_template)
|
||||
|
||||
if cls.setup_failed == False:
|
||||
cls.initial_configuration_cks_template_name = Configurations.list(cls.apiclient,
|
||||
@ -162,8 +164,6 @@ class TestKubernetesCluster(cloudstackTestCase):
|
||||
cls.debug("Error: Exception during cleanup for added Kubernetes supported versions: %s" % e)
|
||||
try:
|
||||
# Restore original CKS template
|
||||
if cls.cks_template != None:
|
||||
cls.cks_template.delete(cls.apiclient)
|
||||
if cls.hypervisorNotSupported == False and cls.initial_configuration_cks_template_name != None:
|
||||
Configurations.update(cls.apiclient,
|
||||
cls.cks_template_name_key,
|
||||
@ -176,6 +176,8 @@ class TestKubernetesCluster(cloudstackTestCase):
|
||||
"false")
|
||||
cls.restartServer()
|
||||
|
||||
cls.updateVmwareSettings(True)
|
||||
|
||||
cleanup_resources(cls.apiclient, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
@ -183,6 +185,24 @@ class TestKubernetesCluster(cloudstackTestCase):
|
||||
raise Exception("Warning: Exception during cleanup, unable to delete Kubernetes supported versions")
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def updateVmwareSettings(cls, tearDown):
|
||||
value = "false"
|
||||
if not tearDown:
|
||||
value = "true"
|
||||
if cls.hypervisor.lower() == 'vmware':
|
||||
Configurations.update(cls.apiclient,
|
||||
"vmware.create.full.clone",
|
||||
value)
|
||||
allStoragePools = StoragePool.list(
|
||||
cls.apiclient
|
||||
)
|
||||
for pool in allStoragePools:
|
||||
Configurations.update(cls.apiclient,
|
||||
storageid=pool.id,
|
||||
name="vmware.create.full.clone",
|
||||
value=value)
|
||||
|
||||
@classmethod
|
||||
def restartServer(cls):
|
||||
"""Restart management server"""
|
||||
@ -227,7 +247,7 @@ class TestKubernetesCluster(cloudstackTestCase):
|
||||
|
||||
if hypervisor not in cks_templates.keys():
|
||||
cls.debug("Provided hypervisor has no CKS template")
|
||||
return FAILED
|
||||
return FAILED, False
|
||||
|
||||
cks_template = cks_templates[hypervisor]
|
||||
|
||||
@ -244,13 +264,13 @@ class TestKubernetesCluster(cloudstackTestCase):
|
||||
details = [{"keyboard": "us"}]
|
||||
template = Template.register(cls.apiclient, cks_template, zoneid=cls.zone.id, hypervisor=hypervisor.lower(), randomize_name=False, details=details)
|
||||
template.download(cls.apiclient)
|
||||
return template
|
||||
return template, False
|
||||
|
||||
for template in templates:
|
||||
if template.isready and template.ispublic:
|
||||
return Template(template.__dict__)
|
||||
return Template(template.__dict__), True
|
||||
|
||||
return FAILED
|
||||
return FAILED, False
|
||||
|
||||
@classmethod
|
||||
def waitForKubernetesSupportedVersionIsoReadyState(cls, version_id, retries=30, interval=60):
|
||||
@ -313,38 +333,7 @@ class TestKubernetesCluster(cloudstackTestCase):
|
||||
|
||||
@attr(tags=["advanced", "smoke"], required_hardware="true")
|
||||
@skipTestIf("hypervisorNotSupported")
|
||||
def test_01_deploy_kubernetes_cluster(self):
|
||||
"""Test to deploy a new Kubernetes cluster
|
||||
|
||||
# Validate the following:
|
||||
# 1. createKubernetesCluster should return valid info for new cluster
|
||||
# 2. The Cloud Database contains the valid information
|
||||
# 3. stopKubernetesCluster should stop the cluster
|
||||
"""
|
||||
if self.setup_failed == True:
|
||||
self.fail("Setup incomplete")
|
||||
global k8s_cluster
|
||||
k8s_cluster = self.getValidKubernetesCluster()
|
||||
|
||||
self.debug("Kubernetes cluster with ID: %s successfully deployed, now stopping it" % k8s_cluster.id)
|
||||
|
||||
self.stopAndVerifyKubernetesCluster(k8s_cluster.id)
|
||||
|
||||
self.debug("Kubernetes cluster with ID: %s successfully stopped, now starting it again" % k8s_cluster.id)
|
||||
|
||||
try:
|
||||
k8s_cluster = self.startKubernetesCluster(k8s_cluster.id)
|
||||
except Exception as e:
|
||||
self.deleteKubernetesClusterAndVerify(k8s_cluster.id, False, True)
|
||||
self.fail("Failed to start Kubernetes cluster due to: %s" % e)
|
||||
|
||||
self.verifyKubernetesClusterState(k8s_cluster, 'Running')
|
||||
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "smoke"], required_hardware="true")
|
||||
@skipTestIf("hypervisorNotSupported")
|
||||
def test_02_invalid_upgrade_kubernetes_cluster(self):
|
||||
def test_01_invalid_upgrade_kubernetes_cluster(self):
|
||||
"""Test to check for failure while tying to upgrade a Kubernetes cluster to a lower version
|
||||
|
||||
# Validate the following:
|
||||
@ -364,12 +353,13 @@ class TestKubernetesCluster(cloudstackTestCase):
|
||||
self.fail("Kubernetes cluster upgraded to a lower Kubernetes supported version. Must be an error.")
|
||||
except Exception as e:
|
||||
self.debug("Upgrading Kubernetes cluster with invalid Kubernetes supported version check successful, API failure: %s" % e)
|
||||
self.deleteKubernetesClusterAndVerify(k8s_cluster.id, False, True)
|
||||
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "smoke"], required_hardware="true")
|
||||
@skipTestIf("hypervisorNotSupported")
|
||||
def test_03_deploy_and_upgrade_kubernetes_cluster(self):
|
||||
def test_02_deploy_and_upgrade_kubernetes_cluster(self):
|
||||
"""Test to deploy a new Kubernetes cluster and upgrade it to newer version
|
||||
|
||||
# Validate the following:
|
||||
@ -395,7 +385,7 @@ class TestKubernetesCluster(cloudstackTestCase):
|
||||
|
||||
@attr(tags=["advanced", "smoke"], required_hardware="true")
|
||||
@skipTestIf("hypervisorNotSupported")
|
||||
def test_04_deploy_and_scale_kubernetes_cluster(self):
|
||||
def test_03_deploy_and_scale_kubernetes_cluster(self):
|
||||
"""Test to deploy a new Kubernetes cluster and check for failure while tying to scale it
|
||||
|
||||
# Validate the following:
|
||||
@ -431,6 +421,36 @@ class TestKubernetesCluster(cloudstackTestCase):
|
||||
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "smoke"], required_hardware="true")
|
||||
@skipTestIf("hypervisorNotSupported")
|
||||
def test_04_basic_lifecycle_kubernetes_cluster(self):
|
||||
"""Test to deploy a new Kubernetes cluster
|
||||
|
||||
# Validate the following:
|
||||
# 1. createKubernetesCluster should return valid info for new cluster
|
||||
# 2. The Cloud Database contains the valid information
|
||||
# 3. stopKubernetesCluster should stop the cluster
|
||||
"""
|
||||
if self.setup_failed == True:
|
||||
self.fail("Setup incomplete")
|
||||
global k8s_cluster
|
||||
k8s_cluster = self.getValidKubernetesCluster()
|
||||
|
||||
self.debug("Kubernetes cluster with ID: %s successfully deployed, now stopping it" % k8s_cluster.id)
|
||||
|
||||
self.stopAndVerifyKubernetesCluster(k8s_cluster.id)
|
||||
|
||||
self.debug("Kubernetes cluster with ID: %s successfully stopped, now starting it again" % k8s_cluster.id)
|
||||
|
||||
try:
|
||||
k8s_cluster = self.startKubernetesCluster(k8s_cluster.id)
|
||||
except Exception as e:
|
||||
self.deleteKubernetesClusterAndVerify(k8s_cluster.id, False, True)
|
||||
self.fail("Failed to start Kubernetes cluster due to: %s" % e)
|
||||
|
||||
self.verifyKubernetesClusterState(k8s_cluster, 'Running')
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "smoke"], required_hardware="true")
|
||||
@skipTestIf("hypervisorNotSupported")
|
||||
def test_05_delete_kubernetes_cluster(self):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user