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. | ||||
| package com.cloud.host.dao; | ||||
| 
 | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import com.cloud.host.DetailVO; | ||||
| @ -29,4 +30,6 @@ public interface HostDetailsDao extends GenericDao<DetailVO, Long> { | ||||
|     DetailVO findDetail(long hostId, String name); | ||||
| 
 | ||||
|     void deleteDetails(long hostId); | ||||
| 
 | ||||
|     List<DetailVO> findByName(String name); | ||||
| } | ||||
|  | ||||
| @ -22,7 +22,6 @@ import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| 
 | ||||
| import org.springframework.stereotype.Component; | ||||
| 
 | ||||
| import com.cloud.host.DetailVO; | ||||
| @ -37,6 +36,7 @@ import com.cloud.utils.exception.CloudRuntimeException; | ||||
| public class HostDetailsDaoImpl extends GenericDaoBase<DetailVO, Long> implements HostDetailsDao { | ||||
|     protected final SearchBuilder<DetailVO> HostSearch; | ||||
|     protected final SearchBuilder<DetailVO> DetailSearch; | ||||
|     protected final SearchBuilder<DetailVO> DetailNameSearch; | ||||
| 
 | ||||
|     public HostDetailsDaoImpl() { | ||||
|         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("name", DetailSearch.entity().getName(), SearchCriteria.Op.EQ); | ||||
|         DetailSearch.done(); | ||||
| 
 | ||||
|         DetailNameSearch = createSearchBuilder(); | ||||
|         DetailNameSearch.and("name", DetailNameSearch.entity().getName(), SearchCriteria.Op.EQ); | ||||
|         DetailNameSearch.done(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
| @ -119,4 +123,11 @@ public class HostDetailsDaoImpl extends GenericDaoBase<DetailVO, Long> implement | ||||
|         } | ||||
|         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.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.SecurityChecker; | ||||
| import org.apache.cloudstack.affinity.AffinityGroupProcessor; | ||||
| @ -611,8 +595,14 @@ import org.apache.commons.lang3.StringUtils; | ||||
| import org.apache.log4j.Logger; | ||||
| 
 | ||||
| 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.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.alert.Alert; | ||||
| import com.cloud.alert.AlertManager; | ||||
| @ -633,6 +623,7 @@ import com.cloud.consoleproxy.ConsoleProxyManager; | ||||
| import com.cloud.dc.AccountVlanMapVO; | ||||
| import com.cloud.dc.ClusterVO; | ||||
| import com.cloud.dc.DataCenterVO; | ||||
| import com.cloud.dc.DomainVlanMapVO; | ||||
| import com.cloud.dc.HostPodVO; | ||||
| import com.cloud.dc.Pod; | ||||
| 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.ClusterDao; | ||||
| import com.cloud.dc.dao.DataCenterDao; | ||||
| import com.cloud.dc.dao.DomainVlanMapDao; | ||||
| import com.cloud.dc.dao.HostPodDao; | ||||
| import com.cloud.dc.dao.PodVlanMapDao; | ||||
| import com.cloud.dc.dao.VlanDao; | ||||
| @ -656,6 +648,7 @@ import com.cloud.event.ActionEventUtils; | ||||
| import com.cloud.event.EventTypes; | ||||
| import com.cloud.event.EventVO; | ||||
| import com.cloud.event.dao.EventDao; | ||||
| import com.cloud.exception.AgentUnavailableException; | ||||
| import com.cloud.exception.ConcurrentOperationException; | ||||
| import com.cloud.exception.InsufficientAddressCapacityException; | ||||
| import com.cloud.exception.InvalidParameterValueException; | ||||
| @ -686,6 +679,7 @@ import com.cloud.network.IpAddressManager; | ||||
| import com.cloud.network.IpAddressManagerImpl; | ||||
| import com.cloud.network.Network; | ||||
| import com.cloud.network.NetworkModel; | ||||
| import com.cloud.network.Networks; | ||||
| import com.cloud.network.dao.IPAddressDao; | ||||
| import com.cloud.network.dao.IPAddressVO; | ||||
| 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.TransactionCallbackNoReturn; | ||||
| import com.cloud.utils.db.TransactionStatus; | ||||
| import com.cloud.utils.db.UUIDManager; | ||||
| import com.cloud.utils.exception.CloudRuntimeException; | ||||
| import com.cloud.utils.fsm.StateMachine2; | ||||
| import com.cloud.utils.net.MacAddress; | ||||
| import com.cloud.utils.net.NetUtils; | ||||
| import com.cloud.utils.ssh.SSHKeysHelper; | ||||
| import com.cloud.vm.ConsoleProxyVO; | ||||
| import com.cloud.vm.DiskProfile; | ||||
| import com.cloud.vm.DomainRouterVO; | ||||
| import com.cloud.vm.InstanceGroupVO; | ||||
| import com.cloud.vm.NicVO; | ||||
| import com.cloud.vm.SecondaryStorageVmVO; | ||||
| import com.cloud.vm.UserVmDetailVO; | ||||
| import com.cloud.vm.UserVmManager; | ||||
| @ -778,7 +776,9 @@ import com.cloud.vm.VirtualMachineManager; | ||||
| import com.cloud.vm.VirtualMachineProfile; | ||||
| import com.cloud.vm.VirtualMachineProfileImpl; | ||||
| import com.cloud.vm.dao.ConsoleProxyDao; | ||||
| import com.cloud.vm.dao.DomainRouterDao; | ||||
| import com.cloud.vm.dao.InstanceGroupDao; | ||||
| import com.cloud.vm.dao.NicDao; | ||||
| import com.cloud.vm.dao.SecondaryStorageVmDao; | ||||
| import com.cloud.vm.dao.UserVmDao; | ||||
| 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); | ||||
|     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 | ||||
|     public AccountManager _accountMgr; | ||||
|     @Inject | ||||
| @ -807,7 +810,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe | ||||
|     @Inject | ||||
|     private ClusterDao _clusterDao; | ||||
|     @Inject | ||||
|     private UserVmDetailsDao _UserVmDetailsDao; | ||||
|     protected UserVmDetailsDao _UserVmDetailsDao; | ||||
|     @Inject | ||||
|     private SecondaryStorageVmDao _secStorageVmDao; | ||||
|     @Inject | ||||
| @ -823,7 +826,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe | ||||
|     @Inject | ||||
|     private HostDao _hostDao; | ||||
|     @Inject | ||||
|     private HostDetailsDao _detailsDao; | ||||
|     protected HostDetailsDao _detailsDao; | ||||
|     @Inject | ||||
|     private UserDao _userDao; | ||||
|     @Inject | ||||
| @ -1277,6 +1280,26 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe | ||||
|         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 | ||||
|     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) { | ||||
| @ -1303,33 +1326,21 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe | ||||
|             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) { | ||||
|             s_logger.info(" Live Migration of GPU enabled VM : " + vm.getInstanceName() + " is not supported"); | ||||
|             // 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>()); | ||||
|             return new Ternary<>(new Pair<>(new ArrayList<HostVO>(), new Integer(0)), | ||||
|                     new ArrayList<>(), new HashMap<>()); | ||||
|         } | ||||
| 
 | ||||
|         if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) && !vm.getHypervisorType().equals(HypervisorType.KVM) | ||||
|                 && !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 (!LIVE_MIGRATION_SUPPORTING_HYPERVISORS.contains(vm.getHypervisorType())) { | ||||
|             if (s_logger.isDebugEnabled()) { | ||||
|                 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"); | ||||
|         } | ||||
| 
 | ||||
|         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"); | ||||
|         } | ||||
| 
 | ||||
| @ -1376,21 +1387,21 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe | ||||
|         final Type hostType = srcHost.getType(); | ||||
|         Pair<List<HostVO>, Integer> allHostsPair = null; | ||||
|         List<HostVO> allHosts = null; | ||||
|         List<HostVO> hostsForMigrationWithStorage = null; | ||||
|         final Map<Host, Boolean> requiresStorageMotion = new HashMap<Host, Boolean>(); | ||||
|         List<HostVO> filteredHosts = null; | ||||
|         final Map<Host, Boolean> requiresStorageMotion = new HashMap<>(); | ||||
|         DataCenterDeployment plan = null; | ||||
|         if (canMigrateWithStorage) { | ||||
|             Long podId = !VirtualMachine.Type.User.equals(vm.getType()) ? srcHost.getPodId() : null; | ||||
|             allHostsPair = searchForServers(startIndex, pageSize, null, hostType, null, srcHost.getDataCenterId(), podId, null, null, keyword, | ||||
|                 null, null, srcHost.getHypervisorType(), null, srcHost.getId()); | ||||
|             allHosts = allHostsPair.first(); | ||||
|             hostsForMigrationWithStorage = new ArrayList<>(allHosts); | ||||
|             filteredHosts = new ArrayList<>(allHosts); | ||||
| 
 | ||||
|             for (final VolumeVO volume : volumes) { | ||||
|                 StoragePool storagePool = _poolDao.findById(volume.getPoolId()); | ||||
|                 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(); | ||||
|                     String hostVersion = host.getHypervisorVersion(); | ||||
|                     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); | ||||
|         } else { | ||||
|             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); | ||||
|         } | ||||
| 
 | ||||
|         final Pair<List<? extends Host>, Integer> otherHosts = new Pair<List<? extends Host>, Integer>(allHosts, allHostsPair.second()); | ||||
|         List<Host> suitableHosts = new ArrayList<Host>(); | ||||
|         final Pair<List<? extends Host>, Integer> otherHosts = new Pair<>(allHosts, allHostsPair.second()); | ||||
|         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(); | ||||
|         excludes.addHost(srcHostId); | ||||
| 
 | ||||
| @ -1470,8 +1490,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe | ||||
|         } | ||||
| 
 | ||||
|         for (final HostAllocator allocator : hostAllocators) { | ||||
|             if (canMigrateWithStorage) { | ||||
|                 suitableHosts = allocator.allocateTo(vmProfile, plan, Host.Type.Routing, excludes, hostsForMigrationWithStorage, HostAllocator.RETURN_UPTO_ALL, false); | ||||
|             if (CollectionUtils.isNotEmpty(filteredHosts)) { | ||||
|                 suitableHosts = allocator.allocateTo(vmProfile, plan, Host.Type.Routing, excludes, filteredHosts, HostAllocator.RETURN_UPTO_ALL, false); | ||||
|             } else { | ||||
|                 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.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.ssh.RegisterSSHKeyPairCmd; | ||||
| import org.apache.cloudstack.framework.config.ConfigKey; | ||||
| import org.junit.Assert; | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| @ -32,9 +37,14 @@ import org.mockito.Mockito; | ||||
| import org.mockito.Spy; | ||||
| import org.mockito.runners.MockitoJUnitRunner; | ||||
| import org.powermock.reflect.Whitebox; | ||||
| import org.springframework.test.util.ReflectionTestUtils; | ||||
| 
 | ||||
| import com.cloud.dc.Vlan.VlanType; | ||||
| 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.IpAddressManagerImpl; | ||||
| import com.cloud.network.dao.IPAddressVO; | ||||
| @ -42,7 +52,11 @@ import com.cloud.user.Account; | ||||
| import com.cloud.user.SSHKeyPair; | ||||
| import com.cloud.user.SSHKeyPairVO; | ||||
| import com.cloud.user.dao.SSHKeyPairDao; | ||||
| import com.cloud.utils.Pair; | ||||
| 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) | ||||
| public class ManagementServerImplTest { | ||||
| @ -61,7 +75,6 @@ public class ManagementServerImplTest { | ||||
| 
 | ||||
|     @Mock | ||||
|     SSHKeyPairDao sshKeyPairDao; | ||||
|     ManagementServerImpl ms = new ManagementServerImpl(); | ||||
| 
 | ||||
|     @Mock | ||||
|     SSHKeyPair sshKeyPair; | ||||
| @ -74,10 +87,18 @@ public class ManagementServerImplTest { | ||||
| 
 | ||||
|     ConfigKey mockConfig; | ||||
| 
 | ||||
|     @Mock | ||||
|     UserVmDetailsDao userVmDetailsDao; | ||||
| 
 | ||||
|     @Mock | ||||
|     HostDetailsDao hostDetailsDao; | ||||
| 
 | ||||
|     @Before | ||||
|     public void setup() { | ||||
|         mockConfig = Mockito.mock(ConfigKey.class); | ||||
|         Whitebox.setInternalState(ipAddressManagerImpl.getClass(), "SystemVmPublicIpReservationModeStrictness", mockConfig); | ||||
|         spy._UserVmDetailsDao = userVmDetailsDao; | ||||
|         spy._detailsDao = hostDetailsDao; | ||||
|     } | ||||
| 
 | ||||
|     @Test(expected = InvalidParameterValueException.class) | ||||
| @ -221,4 +242,101 @@ public class ManagementServerImplTest { | ||||
|         Mockito.verify(sc, Mockito.times(1)).setParameters("sourceNetworkId", 10L); | ||||
|         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