mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
server: correctly list suitable hosts for migration with uefi capability (#7024)
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
parent
89d4c7537f
commit
eb5c8a5a8c
@ -16,6 +16,7 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.host.dao;
|
package com.cloud.host.dao;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.cloud.host.DetailVO;
|
import com.cloud.host.DetailVO;
|
||||||
@ -29,4 +30,6 @@ public interface HostDetailsDao extends GenericDao<DetailVO, Long> {
|
|||||||
DetailVO findDetail(long hostId, String name);
|
DetailVO findDetail(long hostId, String name);
|
||||||
|
|
||||||
void deleteDetails(long hostId);
|
void deleteDetails(long hostId);
|
||||||
|
|
||||||
|
List<DetailVO> findByName(String name);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,6 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.cloud.host.DetailVO;
|
import com.cloud.host.DetailVO;
|
||||||
@ -37,6 +36,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
|||||||
public class HostDetailsDaoImpl extends GenericDaoBase<DetailVO, Long> implements HostDetailsDao {
|
public class HostDetailsDaoImpl extends GenericDaoBase<DetailVO, Long> implements HostDetailsDao {
|
||||||
protected final SearchBuilder<DetailVO> HostSearch;
|
protected final SearchBuilder<DetailVO> HostSearch;
|
||||||
protected final SearchBuilder<DetailVO> DetailSearch;
|
protected final SearchBuilder<DetailVO> DetailSearch;
|
||||||
|
protected final SearchBuilder<DetailVO> DetailNameSearch;
|
||||||
|
|
||||||
public HostDetailsDaoImpl() {
|
public HostDetailsDaoImpl() {
|
||||||
HostSearch = createSearchBuilder();
|
HostSearch = createSearchBuilder();
|
||||||
@ -47,6 +47,10 @@ public class HostDetailsDaoImpl extends GenericDaoBase<DetailVO, Long> implement
|
|||||||
DetailSearch.and("hostId", DetailSearch.entity().getHostId(), SearchCriteria.Op.EQ);
|
DetailSearch.and("hostId", DetailSearch.entity().getHostId(), SearchCriteria.Op.EQ);
|
||||||
DetailSearch.and("name", DetailSearch.entity().getName(), SearchCriteria.Op.EQ);
|
DetailSearch.and("name", DetailSearch.entity().getName(), SearchCriteria.Op.EQ);
|
||||||
DetailSearch.done();
|
DetailSearch.done();
|
||||||
|
|
||||||
|
DetailNameSearch = createSearchBuilder();
|
||||||
|
DetailNameSearch.and("name", DetailNameSearch.entity().getName(), SearchCriteria.Op.EQ);
|
||||||
|
DetailNameSearch.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -119,4 +123,11 @@ public class HostDetailsDaoImpl extends GenericDaoBase<DetailVO, Long> implement
|
|||||||
}
|
}
|
||||||
txn.commit();
|
txn.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DetailVO> findByName(String name) {
|
||||||
|
SearchCriteria<DetailVO> sc = DetailNameSearch.create();
|
||||||
|
sc.setParameters("name", name);
|
||||||
|
return listBy(sc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,22 +43,6 @@ import javax.crypto.spec.SecretKeySpec;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
import com.cloud.agent.api.Answer;
|
|
||||||
import com.cloud.agent.api.Command;
|
|
||||||
import com.cloud.agent.api.PatchSystemVmAnswer;
|
|
||||||
import com.cloud.agent.api.PatchSystemVmCommand;
|
|
||||||
import com.cloud.agent.api.routing.NetworkElementCommand;
|
|
||||||
import com.cloud.agent.manager.Commands;
|
|
||||||
import com.cloud.dc.DomainVlanMapVO;
|
|
||||||
import com.cloud.dc.dao.DomainVlanMapDao;
|
|
||||||
import com.cloud.exception.AgentUnavailableException;
|
|
||||||
import com.cloud.network.Networks;
|
|
||||||
import com.cloud.utils.db.UUIDManager;
|
|
||||||
import com.cloud.utils.fsm.StateMachine2;
|
|
||||||
import com.cloud.vm.DomainRouterVO;
|
|
||||||
import com.cloud.vm.NicVO;
|
|
||||||
import com.cloud.vm.dao.DomainRouterDao;
|
|
||||||
import com.cloud.vm.dao.NicDao;
|
|
||||||
import org.apache.cloudstack.acl.ControlledEntity;
|
import org.apache.cloudstack.acl.ControlledEntity;
|
||||||
import org.apache.cloudstack.acl.SecurityChecker;
|
import org.apache.cloudstack.acl.SecurityChecker;
|
||||||
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
|
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
|
||||||
@ -611,8 +595,14 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import com.cloud.agent.AgentManager;
|
import com.cloud.agent.AgentManager;
|
||||||
|
import com.cloud.agent.api.Answer;
|
||||||
|
import com.cloud.agent.api.Command;
|
||||||
import com.cloud.agent.api.GetVncPortAnswer;
|
import com.cloud.agent.api.GetVncPortAnswer;
|
||||||
import com.cloud.agent.api.GetVncPortCommand;
|
import com.cloud.agent.api.GetVncPortCommand;
|
||||||
|
import com.cloud.agent.api.PatchSystemVmAnswer;
|
||||||
|
import com.cloud.agent.api.PatchSystemVmCommand;
|
||||||
|
import com.cloud.agent.api.routing.NetworkElementCommand;
|
||||||
|
import com.cloud.agent.manager.Commands;
|
||||||
import com.cloud.agent.manager.allocator.HostAllocator;
|
import com.cloud.agent.manager.allocator.HostAllocator;
|
||||||
import com.cloud.alert.Alert;
|
import com.cloud.alert.Alert;
|
||||||
import com.cloud.alert.AlertManager;
|
import com.cloud.alert.AlertManager;
|
||||||
@ -633,6 +623,7 @@ import com.cloud.consoleproxy.ConsoleProxyManager;
|
|||||||
import com.cloud.dc.AccountVlanMapVO;
|
import com.cloud.dc.AccountVlanMapVO;
|
||||||
import com.cloud.dc.ClusterVO;
|
import com.cloud.dc.ClusterVO;
|
||||||
import com.cloud.dc.DataCenterVO;
|
import com.cloud.dc.DataCenterVO;
|
||||||
|
import com.cloud.dc.DomainVlanMapVO;
|
||||||
import com.cloud.dc.HostPodVO;
|
import com.cloud.dc.HostPodVO;
|
||||||
import com.cloud.dc.Pod;
|
import com.cloud.dc.Pod;
|
||||||
import com.cloud.dc.PodVlanMapVO;
|
import com.cloud.dc.PodVlanMapVO;
|
||||||
@ -642,6 +633,7 @@ import com.cloud.dc.VlanVO;
|
|||||||
import com.cloud.dc.dao.AccountVlanMapDao;
|
import com.cloud.dc.dao.AccountVlanMapDao;
|
||||||
import com.cloud.dc.dao.ClusterDao;
|
import com.cloud.dc.dao.ClusterDao;
|
||||||
import com.cloud.dc.dao.DataCenterDao;
|
import com.cloud.dc.dao.DataCenterDao;
|
||||||
|
import com.cloud.dc.dao.DomainVlanMapDao;
|
||||||
import com.cloud.dc.dao.HostPodDao;
|
import com.cloud.dc.dao.HostPodDao;
|
||||||
import com.cloud.dc.dao.PodVlanMapDao;
|
import com.cloud.dc.dao.PodVlanMapDao;
|
||||||
import com.cloud.dc.dao.VlanDao;
|
import com.cloud.dc.dao.VlanDao;
|
||||||
@ -656,6 +648,7 @@ import com.cloud.event.ActionEventUtils;
|
|||||||
import com.cloud.event.EventTypes;
|
import com.cloud.event.EventTypes;
|
||||||
import com.cloud.event.EventVO;
|
import com.cloud.event.EventVO;
|
||||||
import com.cloud.event.dao.EventDao;
|
import com.cloud.event.dao.EventDao;
|
||||||
|
import com.cloud.exception.AgentUnavailableException;
|
||||||
import com.cloud.exception.ConcurrentOperationException;
|
import com.cloud.exception.ConcurrentOperationException;
|
||||||
import com.cloud.exception.InsufficientAddressCapacityException;
|
import com.cloud.exception.InsufficientAddressCapacityException;
|
||||||
import com.cloud.exception.InvalidParameterValueException;
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
@ -686,6 +679,7 @@ import com.cloud.network.IpAddressManager;
|
|||||||
import com.cloud.network.IpAddressManagerImpl;
|
import com.cloud.network.IpAddressManagerImpl;
|
||||||
import com.cloud.network.Network;
|
import com.cloud.network.Network;
|
||||||
import com.cloud.network.NetworkModel;
|
import com.cloud.network.NetworkModel;
|
||||||
|
import com.cloud.network.Networks;
|
||||||
import com.cloud.network.dao.IPAddressDao;
|
import com.cloud.network.dao.IPAddressDao;
|
||||||
import com.cloud.network.dao.IPAddressVO;
|
import com.cloud.network.dao.IPAddressVO;
|
||||||
import com.cloud.network.dao.LoadBalancerDao;
|
import com.cloud.network.dao.LoadBalancerDao;
|
||||||
@ -760,13 +754,17 @@ import com.cloud.utils.db.SearchCriteria;
|
|||||||
import com.cloud.utils.db.Transaction;
|
import com.cloud.utils.db.Transaction;
|
||||||
import com.cloud.utils.db.TransactionCallbackNoReturn;
|
import com.cloud.utils.db.TransactionCallbackNoReturn;
|
||||||
import com.cloud.utils.db.TransactionStatus;
|
import com.cloud.utils.db.TransactionStatus;
|
||||||
|
import com.cloud.utils.db.UUIDManager;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
import com.cloud.utils.fsm.StateMachine2;
|
||||||
import com.cloud.utils.net.MacAddress;
|
import com.cloud.utils.net.MacAddress;
|
||||||
import com.cloud.utils.net.NetUtils;
|
import com.cloud.utils.net.NetUtils;
|
||||||
import com.cloud.utils.ssh.SSHKeysHelper;
|
import com.cloud.utils.ssh.SSHKeysHelper;
|
||||||
import com.cloud.vm.ConsoleProxyVO;
|
import com.cloud.vm.ConsoleProxyVO;
|
||||||
import com.cloud.vm.DiskProfile;
|
import com.cloud.vm.DiskProfile;
|
||||||
|
import com.cloud.vm.DomainRouterVO;
|
||||||
import com.cloud.vm.InstanceGroupVO;
|
import com.cloud.vm.InstanceGroupVO;
|
||||||
|
import com.cloud.vm.NicVO;
|
||||||
import com.cloud.vm.SecondaryStorageVmVO;
|
import com.cloud.vm.SecondaryStorageVmVO;
|
||||||
import com.cloud.vm.UserVmDetailVO;
|
import com.cloud.vm.UserVmDetailVO;
|
||||||
import com.cloud.vm.UserVmManager;
|
import com.cloud.vm.UserVmManager;
|
||||||
@ -778,7 +776,9 @@ import com.cloud.vm.VirtualMachineManager;
|
|||||||
import com.cloud.vm.VirtualMachineProfile;
|
import com.cloud.vm.VirtualMachineProfile;
|
||||||
import com.cloud.vm.VirtualMachineProfileImpl;
|
import com.cloud.vm.VirtualMachineProfileImpl;
|
||||||
import com.cloud.vm.dao.ConsoleProxyDao;
|
import com.cloud.vm.dao.ConsoleProxyDao;
|
||||||
|
import com.cloud.vm.dao.DomainRouterDao;
|
||||||
import com.cloud.vm.dao.InstanceGroupDao;
|
import com.cloud.vm.dao.InstanceGroupDao;
|
||||||
|
import com.cloud.vm.dao.NicDao;
|
||||||
import com.cloud.vm.dao.SecondaryStorageVmDao;
|
import com.cloud.vm.dao.SecondaryStorageVmDao;
|
||||||
import com.cloud.vm.dao.UserVmDao;
|
import com.cloud.vm.dao.UserVmDao;
|
||||||
import com.cloud.vm.dao.UserVmDetailsDao;
|
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||||
@ -794,6 +794,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
public static final ConfigKey<String> customCsIdentifier = new ConfigKey<String>("Advanced", String.class, "custom.cs.identifier", UUID.randomUUID().toString().split("-")[0].substring(4), "Custom identifier for the cloudstack installation", true, ConfigKey.Scope.Global);
|
public static final ConfigKey<String> customCsIdentifier = new ConfigKey<String>("Advanced", String.class, "custom.cs.identifier", UUID.randomUUID().toString().split("-")[0].substring(4), "Custom identifier for the cloudstack installation", true, ConfigKey.Scope.Global);
|
||||||
private static final VirtualMachine.Type []systemVmTypes = { VirtualMachine.Type.SecondaryStorageVm, VirtualMachine.Type.ConsoleProxy};
|
private static final VirtualMachine.Type []systemVmTypes = { VirtualMachine.Type.SecondaryStorageVm, VirtualMachine.Type.ConsoleProxy};
|
||||||
|
|
||||||
|
private static final List<HypervisorType> LIVE_MIGRATION_SUPPORTING_HYPERVISORS = List.of(HypervisorType.Hyperv, HypervisorType.KVM,
|
||||||
|
HypervisorType.LXC, HypervisorType.Ovm, HypervisorType.Ovm3, HypervisorType.Simulator, HypervisorType.VMware, HypervisorType.XenServer);
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public AccountManager _accountMgr;
|
public AccountManager _accountMgr;
|
||||||
@Inject
|
@Inject
|
||||||
@ -807,7 +810,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
@Inject
|
@Inject
|
||||||
private ClusterDao _clusterDao;
|
private ClusterDao _clusterDao;
|
||||||
@Inject
|
@Inject
|
||||||
private UserVmDetailsDao _UserVmDetailsDao;
|
protected UserVmDetailsDao _UserVmDetailsDao;
|
||||||
@Inject
|
@Inject
|
||||||
private SecondaryStorageVmDao _secStorageVmDao;
|
private SecondaryStorageVmDao _secStorageVmDao;
|
||||||
@Inject
|
@Inject
|
||||||
@ -823,7 +826,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
@Inject
|
@Inject
|
||||||
private HostDao _hostDao;
|
private HostDao _hostDao;
|
||||||
@Inject
|
@Inject
|
||||||
private HostDetailsDao _detailsDao;
|
protected HostDetailsDao _detailsDao;
|
||||||
@Inject
|
@Inject
|
||||||
private UserDao _userDao;
|
private UserDao _userDao;
|
||||||
@Inject
|
@Inject
|
||||||
@ -1277,6 +1280,26 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
return new Pair<List<? extends Host>, Integer>(result.first(), result.second());
|
return new Pair<List<? extends Host>, Integer>(result.first(), result.second());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Pair<Boolean, List<HostVO>> filterUefiHostsForMigration(List<HostVO> allHosts, List<HostVO> filteredHosts, VMInstanceVO vm) {
|
||||||
|
UserVmDetailVO userVmDetailVO = _UserVmDetailsDao.findDetail(vm.getId(), ApiConstants.BootType.UEFI.toString());
|
||||||
|
if (userVmDetailVO != null &&
|
||||||
|
(ApiConstants.BootMode.LEGACY.toString().equalsIgnoreCase(userVmDetailVO.getValue()) ||
|
||||||
|
ApiConstants.BootMode.SECURE.toString().equalsIgnoreCase(userVmDetailVO.getValue()))) {
|
||||||
|
s_logger.info(" Live Migration of UEFI enabled VM : " + vm.getInstanceName() + " is not supported");
|
||||||
|
if (CollectionUtils.isEmpty(filteredHosts)) {
|
||||||
|
filteredHosts = new ArrayList<>(allHosts);
|
||||||
|
}
|
||||||
|
List<DetailVO> details = _detailsDao.findByName(Host.HOST_UEFI_ENABLE);
|
||||||
|
List<Long> uefiEnabledHosts = details.stream().filter(x -> Boolean.TRUE.toString().equalsIgnoreCase(x.getValue())).map(DetailVO::getHostId).collect(Collectors.toList());
|
||||||
|
if (CollectionUtils.isEmpty(uefiEnabledHosts)) {
|
||||||
|
return new Pair<>(false, null);
|
||||||
|
}
|
||||||
|
filteredHosts.removeIf(host -> !uefiEnabledHosts.contains(host.getId()));
|
||||||
|
return new Pair<>(!filteredHosts.isEmpty(), filteredHosts);
|
||||||
|
}
|
||||||
|
return new Pair<>(true, filteredHosts);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Host, Boolean>> listHostsForMigrationOfVM(final Long vmId, final Long startIndex, final Long pageSize,
|
public Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Host, Boolean>> listHostsForMigrationOfVM(final Long vmId, final Long startIndex, final Long pageSize,
|
||||||
final String keyword) {
|
final String keyword) {
|
||||||
@ -1303,33 +1326,21 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
UserVmDetailVO userVmDetailVO = _UserVmDetailsDao.findDetail(vm.getId(), ApiConstants.BootType.UEFI.toString());
|
|
||||||
if (userVmDetailVO != null) {
|
|
||||||
s_logger.info(" Live Migration of UEFI enabled VM : " + vm.getInstanceName() + " is not supported");
|
|
||||||
if ("legacy".equalsIgnoreCase(userVmDetailVO.getValue()) || "secure".equalsIgnoreCase(userVmDetailVO.getValue())) {
|
|
||||||
// Return empty list.
|
|
||||||
return new Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Host, Boolean>>(new Pair<List<? extends Host>,
|
|
||||||
Integer>(new ArrayList<HostVO>(), new Integer(0)), new ArrayList<Host>(), new HashMap<Host, Boolean>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.pciDevice.toString()) != null) {
|
if (_serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.pciDevice.toString()) != null) {
|
||||||
s_logger.info(" Live Migration of GPU enabled VM : " + vm.getInstanceName() + " is not supported");
|
s_logger.info(" Live Migration of GPU enabled VM : " + vm.getInstanceName() + " is not supported");
|
||||||
// Return empty list.
|
// Return empty list.
|
||||||
return new Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Host, Boolean>>(new Pair<List<? extends Host>, Integer>(new ArrayList<HostVO>(), new Integer(0)),
|
return new Ternary<>(new Pair<>(new ArrayList<HostVO>(), new Integer(0)),
|
||||||
new ArrayList<Host>(), new HashMap<Host, Boolean>());
|
new ArrayList<>(), new HashMap<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) && !vm.getHypervisorType().equals(HypervisorType.KVM)
|
if (!LIVE_MIGRATION_SUPPORTING_HYPERVISORS.contains(vm.getHypervisorType())) {
|
||||||
&& !vm.getHypervisorType().equals(HypervisorType.Ovm) && !vm.getHypervisorType().equals(HypervisorType.Hyperv) && !vm.getHypervisorType().equals(HypervisorType.LXC)
|
|
||||||
&& !vm.getHypervisorType().equals(HypervisorType.Simulator) && !vm.getHypervisorType().equals(HypervisorType.Ovm3)) {
|
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug(vm + " is not XenServer/VMware/KVM/Ovm/Hyperv/Ovm3, cannot migrate this VM.");
|
s_logger.debug(vm + " is not XenServer/VMware/KVM/Ovm/Hyperv/Ovm3, cannot migrate this VM.");
|
||||||
}
|
}
|
||||||
throw new InvalidParameterValueException("Unsupported Hypervisor Type for VM migration, we support " + "XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only");
|
throw new InvalidParameterValueException("Unsupported Hypervisor Type for VM migration, we support " + "XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vm.getType().equals(VirtualMachine.Type.User) && vm.getHypervisorType().equals(HypervisorType.LXC)) {
|
if (VirtualMachine.Type.User.equals(vm.getType()) && HypervisorType.LXC.equals(vm.getHypervisorType())) {
|
||||||
throw new InvalidParameterValueException("Unsupported Hypervisor Type for User VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only");
|
throw new InvalidParameterValueException("Unsupported Hypervisor Type for User VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1376,21 +1387,21 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
final Type hostType = srcHost.getType();
|
final Type hostType = srcHost.getType();
|
||||||
Pair<List<HostVO>, Integer> allHostsPair = null;
|
Pair<List<HostVO>, Integer> allHostsPair = null;
|
||||||
List<HostVO> allHosts = null;
|
List<HostVO> allHosts = null;
|
||||||
List<HostVO> hostsForMigrationWithStorage = null;
|
List<HostVO> filteredHosts = null;
|
||||||
final Map<Host, Boolean> requiresStorageMotion = new HashMap<Host, Boolean>();
|
final Map<Host, Boolean> requiresStorageMotion = new HashMap<>();
|
||||||
DataCenterDeployment plan = null;
|
DataCenterDeployment plan = null;
|
||||||
if (canMigrateWithStorage) {
|
if (canMigrateWithStorage) {
|
||||||
Long podId = !VirtualMachine.Type.User.equals(vm.getType()) ? srcHost.getPodId() : null;
|
Long podId = !VirtualMachine.Type.User.equals(vm.getType()) ? srcHost.getPodId() : null;
|
||||||
allHostsPair = searchForServers(startIndex, pageSize, null, hostType, null, srcHost.getDataCenterId(), podId, null, null, keyword,
|
allHostsPair = searchForServers(startIndex, pageSize, null, hostType, null, srcHost.getDataCenterId(), podId, null, null, keyword,
|
||||||
null, null, srcHost.getHypervisorType(), null, srcHost.getId());
|
null, null, srcHost.getHypervisorType(), null, srcHost.getId());
|
||||||
allHosts = allHostsPair.first();
|
allHosts = allHostsPair.first();
|
||||||
hostsForMigrationWithStorage = new ArrayList<>(allHosts);
|
filteredHosts = new ArrayList<>(allHosts);
|
||||||
|
|
||||||
for (final VolumeVO volume : volumes) {
|
for (final VolumeVO volume : volumes) {
|
||||||
StoragePool storagePool = _poolDao.findById(volume.getPoolId());
|
StoragePool storagePool = _poolDao.findById(volume.getPoolId());
|
||||||
Long volClusterId = storagePool.getClusterId();
|
Long volClusterId = storagePool.getClusterId();
|
||||||
|
|
||||||
for (Iterator<HostVO> iterator = hostsForMigrationWithStorage.iterator(); iterator.hasNext();) {
|
for (Iterator<HostVO> iterator = filteredHosts.iterator(); iterator.hasNext();) {
|
||||||
final Host host = iterator.next();
|
final Host host = iterator.next();
|
||||||
String hostVersion = host.getHypervisorVersion();
|
String hostVersion = host.getHypervisorVersion();
|
||||||
if (HypervisorType.KVM.equals(host.getHypervisorType()) && hostVersion == null) {
|
if (HypervisorType.KVM.equals(host.getHypervisorType()) && hostVersion == null) {
|
||||||
@ -1434,6 +1445,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(filteredHosts)) {
|
||||||
|
return new Ternary<>(new Pair<>(allHosts, allHostsPair.second()), new ArrayList<>(), new HashMap<>());
|
||||||
|
}
|
||||||
plan = new DataCenterDeployment(srcHost.getDataCenterId(), podId, null, null, null, null);
|
plan = new DataCenterDeployment(srcHost.getDataCenterId(), podId, null, null, null, null);
|
||||||
} else {
|
} else {
|
||||||
final Long cluster = srcHost.getClusterId();
|
final Long cluster = srcHost.getClusterId();
|
||||||
@ -1446,8 +1460,14 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
plan = new DataCenterDeployment(srcHost.getDataCenterId(), srcHost.getPodId(), srcHost.getClusterId(), null, null, null);
|
plan = new DataCenterDeployment(srcHost.getDataCenterId(), srcHost.getPodId(), srcHost.getClusterId(), null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Pair<List<? extends Host>, Integer> otherHosts = new Pair<List<? extends Host>, Integer>(allHosts, allHostsPair.second());
|
final Pair<List<? extends Host>, Integer> otherHosts = new Pair<>(allHosts, allHostsPair.second());
|
||||||
List<Host> suitableHosts = new ArrayList<Host>();
|
Pair<Boolean, List<HostVO>> uefiFilteredResult = filterUefiHostsForMigration(allHosts, filteredHosts, vm);
|
||||||
|
if (!uefiFilteredResult.first()) {
|
||||||
|
return new Ternary<>(otherHosts, new ArrayList<>(), new HashMap<>());
|
||||||
|
}
|
||||||
|
filteredHosts = uefiFilteredResult.second();
|
||||||
|
|
||||||
|
List<Host> suitableHosts = new ArrayList<>();
|
||||||
final ExcludeList excludes = new ExcludeList();
|
final ExcludeList excludes = new ExcludeList();
|
||||||
excludes.addHost(srcHostId);
|
excludes.addHost(srcHostId);
|
||||||
|
|
||||||
@ -1470,8 +1490,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (final HostAllocator allocator : hostAllocators) {
|
for (final HostAllocator allocator : hostAllocators) {
|
||||||
if (canMigrateWithStorage) {
|
if (CollectionUtils.isNotEmpty(filteredHosts)) {
|
||||||
suitableHosts = allocator.allocateTo(vmProfile, plan, Host.Type.Routing, excludes, hostsForMigrationWithStorage, HostAllocator.RETURN_UPTO_ALL, false);
|
suitableHosts = allocator.allocateTo(vmProfile, plan, Host.Type.Routing, excludes, filteredHosts, HostAllocator.RETURN_UPTO_ALL, false);
|
||||||
} else {
|
} else {
|
||||||
suitableHosts = allocator.allocateTo(vmProfile, plan, Host.Type.Routing, excludes, HostAllocator.RETURN_UPTO_ALL, false);
|
suitableHosts = allocator.allocateTo(vmProfile, plan, Host.Type.Routing, excludes, HostAllocator.RETURN_UPTO_ALL, false);
|
||||||
}
|
}
|
||||||
@ -1489,7 +1509,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Host, Boolean>>(otherHosts, suitableHosts, requiresStorageMotion);
|
return new Ternary<>(otherHosts, suitableHosts, requiresStorageMotion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -21,9 +21,14 @@ import static org.mockito.Mockito.any;
|
|||||||
import static org.mockito.Mockito.lenient;
|
import static org.mockito.Mockito.lenient;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.cloudstack.api.command.user.address.ListPublicIpAddressesCmd;
|
import org.apache.cloudstack.api.command.user.address.ListPublicIpAddressesCmd;
|
||||||
import org.apache.cloudstack.api.command.user.ssh.RegisterSSHKeyPairCmd;
|
import org.apache.cloudstack.api.command.user.ssh.RegisterSSHKeyPairCmd;
|
||||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@ -32,9 +37,14 @@ import org.mockito.Mockito;
|
|||||||
import org.mockito.Spy;
|
import org.mockito.Spy;
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
import org.powermock.reflect.Whitebox;
|
import org.powermock.reflect.Whitebox;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
import com.cloud.dc.Vlan.VlanType;
|
import com.cloud.dc.Vlan.VlanType;
|
||||||
import com.cloud.exception.InvalidParameterValueException;
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
|
import com.cloud.host.DetailVO;
|
||||||
|
import com.cloud.host.Host;
|
||||||
|
import com.cloud.host.HostVO;
|
||||||
|
import com.cloud.host.dao.HostDetailsDao;
|
||||||
import com.cloud.network.IpAddress;
|
import com.cloud.network.IpAddress;
|
||||||
import com.cloud.network.IpAddressManagerImpl;
|
import com.cloud.network.IpAddressManagerImpl;
|
||||||
import com.cloud.network.dao.IPAddressVO;
|
import com.cloud.network.dao.IPAddressVO;
|
||||||
@ -42,7 +52,11 @@ import com.cloud.user.Account;
|
|||||||
import com.cloud.user.SSHKeyPair;
|
import com.cloud.user.SSHKeyPair;
|
||||||
import com.cloud.user.SSHKeyPairVO;
|
import com.cloud.user.SSHKeyPairVO;
|
||||||
import com.cloud.user.dao.SSHKeyPairDao;
|
import com.cloud.user.dao.SSHKeyPairDao;
|
||||||
|
import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.db.SearchCriteria;
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
|
import com.cloud.vm.UserVmDetailVO;
|
||||||
|
import com.cloud.vm.UserVmVO;
|
||||||
|
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class ManagementServerImplTest {
|
public class ManagementServerImplTest {
|
||||||
@ -61,7 +75,6 @@ public class ManagementServerImplTest {
|
|||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
SSHKeyPairDao sshKeyPairDao;
|
SSHKeyPairDao sshKeyPairDao;
|
||||||
ManagementServerImpl ms = new ManagementServerImpl();
|
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
SSHKeyPair sshKeyPair;
|
SSHKeyPair sshKeyPair;
|
||||||
@ -74,10 +87,18 @@ public class ManagementServerImplTest {
|
|||||||
|
|
||||||
ConfigKey mockConfig;
|
ConfigKey mockConfig;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
UserVmDetailsDao userVmDetailsDao;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
HostDetailsDao hostDetailsDao;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
mockConfig = Mockito.mock(ConfigKey.class);
|
mockConfig = Mockito.mock(ConfigKey.class);
|
||||||
Whitebox.setInternalState(ipAddressManagerImpl.getClass(), "SystemVmPublicIpReservationModeStrictness", mockConfig);
|
Whitebox.setInternalState(ipAddressManagerImpl.getClass(), "SystemVmPublicIpReservationModeStrictness", mockConfig);
|
||||||
|
spy._UserVmDetailsDao = userVmDetailsDao;
|
||||||
|
spy._detailsDao = hostDetailsDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = InvalidParameterValueException.class)
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
@ -221,4 +242,101 @@ public class ManagementServerImplTest {
|
|||||||
Mockito.verify(sc, Mockito.times(1)).setParameters("sourceNetworkId", 10L);
|
Mockito.verify(sc, Mockito.times(1)).setParameters("sourceNetworkId", 10L);
|
||||||
Mockito.verify(sc, Mockito.never()).setParameters("forsystemvms", false);
|
Mockito.verify(sc, Mockito.never()).setParameters("forsystemvms", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private UserVmVO mockFilterUefiHostsTestVm(String uefiValue) {
|
||||||
|
UserVmVO vm = Mockito.mock(UserVmVO.class);
|
||||||
|
Mockito.when(vm.getId()).thenReturn(1L);
|
||||||
|
if (uefiValue == null) {
|
||||||
|
Mockito.when(userVmDetailsDao.findDetail(vm.getId(), ApiConstants.BootType.UEFI.toString())).thenReturn(null);
|
||||||
|
} else {
|
||||||
|
UserVmDetailVO detail = new UserVmDetailVO(vm.getId(), ApiConstants.BootType.UEFI.toString(), uefiValue, true);
|
||||||
|
Mockito.when(userVmDetailsDao.findDetail(vm.getId(), ApiConstants.BootType.UEFI.toString())).thenReturn(detail);
|
||||||
|
Mockito.when(hostDetailsDao.findByName(Host.HOST_UEFI_ENABLE)).thenReturn(new ArrayList<>(List.of(new DetailVO(1l, Host.HOST_UEFI_ENABLE, "true"), new DetailVO(2l, Host.HOST_UEFI_ENABLE, "false"))));
|
||||||
|
}
|
||||||
|
return vm;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<HostVO> mockHostsList(Long filtered) {
|
||||||
|
List<HostVO> hosts = new ArrayList<>();
|
||||||
|
HostVO h1 = new HostVO("guid-1");
|
||||||
|
ReflectionTestUtils.setField(h1, "id", 1L);
|
||||||
|
hosts.add(h1);
|
||||||
|
HostVO h2 = new HostVO("guid-2");
|
||||||
|
ReflectionTestUtils.setField(h2, "id", 2L);
|
||||||
|
hosts.add(h2);
|
||||||
|
HostVO h3 = new HostVO("guid-3");
|
||||||
|
ReflectionTestUtils.setField(h3, "id", 3L);
|
||||||
|
hosts.add(h3);
|
||||||
|
if (filtered != null) {
|
||||||
|
hosts.removeIf(h -> h.getId() == filtered);
|
||||||
|
}
|
||||||
|
return hosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFilterUefiHostsForMigrationBiosVm() {
|
||||||
|
UserVmVO vm = mockFilterUefiHostsTestVm(null);
|
||||||
|
Pair<Boolean, List<HostVO>> result = spy.filterUefiHostsForMigration(new ArrayList<>(), new ArrayList<>(), vm);
|
||||||
|
Assert.assertTrue(result.first());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFilterUefiHostsForMigrationBiosVmFiltered() {
|
||||||
|
List<HostVO> filteredHosts = mockHostsList(2L);
|
||||||
|
UserVmVO vm = mockFilterUefiHostsTestVm(null);
|
||||||
|
Pair<Boolean, List<HostVO>> result = spy.filterUefiHostsForMigration(new ArrayList<>(), filteredHosts, vm);
|
||||||
|
Assert.assertTrue(result.first());
|
||||||
|
Assert.assertNotNull(result.second());
|
||||||
|
Assert.assertEquals(2, result.second().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFilterUefiHostsForMigrationUefiInvalidValueVm() {
|
||||||
|
UserVmVO vm = mockFilterUefiHostsTestVm("");
|
||||||
|
Pair<Boolean, List<HostVO>> result = spy.filterUefiHostsForMigration(new ArrayList<>(), new ArrayList<>(), vm);
|
||||||
|
Assert.assertTrue(result.first());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFilterUefiHostsForMigrationUefiVMHostsUnavailable() {
|
||||||
|
UserVmVO vm = mockFilterUefiHostsTestVm(ApiConstants.BootMode.SECURE.toString());
|
||||||
|
List<HostVO> filteredHosts = new ArrayList<>();
|
||||||
|
Mockito.when(hostDetailsDao.findByName(Host.HOST_UEFI_ENABLE)).thenReturn(new ArrayList<>());
|
||||||
|
Pair<Boolean, List<HostVO>> result = spy.filterUefiHostsForMigration(mockHostsList(null), filteredHosts, vm);
|
||||||
|
Assert.assertFalse(result.first());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFilterUefiHostsForMigrationUefiVMHostsAvailable() {
|
||||||
|
UserVmVO vm = mockFilterUefiHostsTestVm(ApiConstants.BootMode.LEGACY.toString());
|
||||||
|
Pair<Boolean, List<HostVO>> result = spy.filterUefiHostsForMigration(mockHostsList(null), null, vm);
|
||||||
|
Assert.assertTrue(result.first());
|
||||||
|
Assert.assertNotNull(result.second());
|
||||||
|
Assert.assertEquals(1, result.second().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFilterUefiHostsForMigrationNoHostsAvailable() {
|
||||||
|
UserVmVO vm = mockFilterUefiHostsTestVm(ApiConstants.BootMode.SECURE.toString());
|
||||||
|
Pair<Boolean, List<HostVO>> result = spy.filterUefiHostsForMigration(new ArrayList<>(), null, vm);
|
||||||
|
Assert.assertFalse(result.first());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFilterUefiHostsForMigrationUefiVMHostsAvailableFiltered() {
|
||||||
|
UserVmVO vm = mockFilterUefiHostsTestVm(ApiConstants.BootMode.LEGACY.toString());
|
||||||
|
Pair<Boolean, List<HostVO>> result = spy.filterUefiHostsForMigration(mockHostsList(null), mockHostsList(3L), vm);
|
||||||
|
Assert.assertTrue(result.first());
|
||||||
|
Assert.assertNotNull(result.second());
|
||||||
|
Assert.assertEquals(1, result.second().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFilterUefiHostsForMigrationUefiVMNoHostsAvailableFiltered() {
|
||||||
|
UserVmVO vm = mockFilterUefiHostsTestVm(ApiConstants.BootMode.SECURE.toString());
|
||||||
|
Pair<Boolean, List<HostVO>> result = spy.filterUefiHostsForMigration(mockHostsList(null), mockHostsList(1L), vm);
|
||||||
|
Assert.assertFalse(result.first());
|
||||||
|
Assert.assertNotNull(result.second());
|
||||||
|
Assert.assertEquals(0, result.second().size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user