From f82e4e4f52f0d102cf9646d197185ca07da52f8f Mon Sep 17 00:00:00 2001 From: nvazquez Date: Tue, 3 Mar 2026 16:44:44 -0300 Subject: [PATCH 1/2] [VMware to KVM] Add guest OS for importing VM based on the source VM OS --- .../main/java/com/cloud/vm/UserVmService.java | 3 +- .../api/command/admin/vm/ImportVmCmd.java | 10 +++++ .../command/user/guest/ListGuestOsCmd.java | 9 +++++ .../response/UnmanagedInstanceResponse.java | 12 ++++++ .../cloudstack/vm/UnmanagedInstanceTO.java | 10 +++++ .../com/cloud/storage/dao/GuestOSDao.java | 2 +- .../com/cloud/storage/dao/GuestOSDaoImpl.java | 6 +-- .../java/com/cloud/api/ApiResponseHelper.java | 11 +++++- .../cloud/server/ManagementServerImpl.java | 8 ++-- .../java/com/cloud/vm/UserVmManagerImpl.java | 14 +++---- .../vm/UnmanagedVMsManagerImpl.java | 22 ++++++++--- .../vm/UnmanagedVMsManagerImplTest.java | 2 +- ui/public/locales/en.json | 1 + .../views/tools/ImportUnmanagedInstance.vue | 37 ++++++++++++++++++- ui/src/views/tools/ManageInstances.vue | 21 ++++++++++- .../cloud/hypervisor/vmware/mo/BaseMO.java | 6 +-- .../hypervisor/vmware/util/VmwareHelper.java | 12 ++++++ .../vmware/util/VmwareHelperTest.java | 23 ++++++++++++ 18 files changed, 177 insertions(+), 32 deletions(-) diff --git a/api/src/main/java/com/cloud/vm/UserVmService.java b/api/src/main/java/com/cloud/vm/UserVmService.java index 01f11b73cd41..4ad1ffb755bc 100644 --- a/api/src/main/java/com/cloud/vm/UserVmService.java +++ b/api/src/main/java/com/cloud/vm/UserVmService.java @@ -524,6 +524,7 @@ UserVm upgradeVirtualMachine(ScaleVMCmd cmd) throws ResourceUnavailableException * @param userId user ID * @param serviceOffering service offering for the imported VM * @param sshPublicKey ssh key for the imported VM + * @param guestOsId guest OS ID for the imported VM (if not passed, then the guest OS of the template will be used) * @param hostName the name for the imported VM * @param hypervisorType hypervisor type for the imported VM * @param customParameters details for the imported VM @@ -533,7 +534,7 @@ UserVm upgradeVirtualMachine(ScaleVMCmd cmd) throws ResourceUnavailableException * @throws InsufficientCapacityException in case of errors */ UserVm importVM(final DataCenter zone, final Host host, final VirtualMachineTemplate template, final String instanceNameInternal, final String displayName, final Account owner, final String userData, final Account caller, final Boolean isDisplayVm, final String keyboard, - final long accountId, final long userId, final ServiceOffering serviceOffering, final String sshPublicKey, + final long accountId, final long userId, final ServiceOffering serviceOffering, final String sshPublicKey, final Long guestOsId, final String hostName, final HypervisorType hypervisorType, final Map customParameters, final VirtualMachine.PowerState powerState, final LinkedHashMap> networkNicMap) throws InsufficientCapacityException; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ImportVmCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ImportVmCmd.java index f7940460d6cd..ef7e75cc5a3d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ImportVmCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ImportVmCmd.java @@ -171,6 +171,12 @@ public class ImportVmCmd extends ImportUnmanagedInstanceCmd { description = "(only for importing VMs from VMware to KVM) optional - if true, forces virt-v2v conversions to write directly on the provided storage pool (avoid using temporary conversion pool).") private Boolean forceConvertToPool; + @Parameter(name = ApiConstants.OS_ID, + type = CommandType.UUID, + since = "4.22.1", + description = "(only for importing VMs from VMware to KVM) optional - the ID of the guest OS for the imported VM.") + private Long guestOsId; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -268,6 +274,10 @@ public boolean getForceConvertToPool() { return BooleanUtils.toBooleanDefaultIfNull(forceConvertToPool, false); } + public Long getGuestOsId() { + return guestOsId; + } + @Override public String getEventDescription() { String vmName = getName(); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/guest/ListGuestOsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/guest/ListGuestOsCmd.java index 4ff2ebf0a667..d558e4c4f245 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/guest/ListGuestOsCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/guest/ListGuestOsCmd.java @@ -45,6 +45,11 @@ public class ListGuestOsCmd extends BaseListCmd { @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = GuestOSResponse.class, description = "List by OS type ID") private Long id; + @Parameter(name = ApiConstants.IDS, type = CommandType.LIST, collectionType = CommandType.UUID, + entityType = GuestOSResponse.class, since = "4.22.1", + description = "Comma separated list of OS types") + private List ids; + @Parameter(name = ApiConstants.OS_CATEGORY_ID, type = CommandType.UUID, entityType = GuestOSCategoryResponse.class, description = "List by OS Category ID") private Long osCategoryId; @@ -63,6 +68,10 @@ public Long getId() { return id; } + public List getIds() { + return ids; + } + public Long getOsCategoryId() { return osCategoryId; } diff --git a/api/src/main/java/org/apache/cloudstack/api/response/UnmanagedInstanceResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/UnmanagedInstanceResponse.java index 195323b741d2..aef4f4c93c12 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/UnmanagedInstanceResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/UnmanagedInstanceResponse.java @@ -51,6 +51,10 @@ public class UnmanagedInstanceResponse extends BaseResponse { @Param(description = "The name of the host to which Instance belongs") private String hostName; + @SerializedName(ApiConstants.HYPERVISOR_VERSION) + @Param(description = "The version of the host to which Instance belongs") + private String hypervisorVersion; + @SerializedName(ApiConstants.POWER_STATE) @Param(description = "The power state of the Instance") private String powerState; @@ -140,6 +144,14 @@ public void setHostName(String hostName) { this.hostName = hostName; } + public String getHypervisorVersion() { + return hypervisorVersion; + } + + public void setHypervisorVersion(String hypervisorVersion) { + this.hypervisorVersion = hypervisorVersion; + } + public String getPowerState() { return powerState; } diff --git a/api/src/main/java/org/apache/cloudstack/vm/UnmanagedInstanceTO.java b/api/src/main/java/org/apache/cloudstack/vm/UnmanagedInstanceTO.java index bba97dff71cb..fe273bbdbd28 100644 --- a/api/src/main/java/org/apache/cloudstack/vm/UnmanagedInstanceTO.java +++ b/api/src/main/java/org/apache/cloudstack/vm/UnmanagedInstanceTO.java @@ -55,6 +55,8 @@ public enum PowerState { private String hostName; + private String hostHypervisorVersion; + private List disks; private List nics; @@ -168,6 +170,14 @@ public void setHostName(String hostName) { this.hostName = hostName; } + public String getHostHypervisorVersion() { + return hostHypervisorVersion; + } + + public void setHostHypervisorVersion(String hostHypervisorVersion) { + this.hostHypervisorVersion = hostHypervisorVersion; + } + public List getDisks() { return disks; } diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSDao.java index 1a2b098c40a7..f24f3f3b67c4 100644 --- a/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSDao.java +++ b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSDao.java @@ -35,7 +35,7 @@ public interface GuestOSDao extends GenericDao { List listByDisplayName(String displayName); - Pair, Integer> listGuestOSByCriteria(Long startIndex, Long pageSize, Long id, Long osCategoryId, String description, String keyword, Boolean forDisplay); + Pair, Integer> listGuestOSByCriteria(Long startIndex, Long pageSize, List ids, Long osCategoryId, String description, String keyword, Boolean forDisplay); List listIdsByCategoryId(final long categoryId); } diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSDaoImpl.java index 881be207c1aa..09f8772fb59c 100644 --- a/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSDaoImpl.java @@ -125,12 +125,12 @@ public List listByDisplayName(String displayName) { return listBy(sc); } - public Pair, Integer> listGuestOSByCriteria(Long startIndex, Long pageSize, Long id, Long osCategoryId, String description, String keyword, Boolean forDisplay) { + public Pair, Integer> listGuestOSByCriteria(Long startIndex, Long pageSize, List ids, Long osCategoryId, String description, String keyword, Boolean forDisplay) { final Filter searchFilter = new Filter(GuestOSVO.class, "displayName", true, startIndex, pageSize); final SearchCriteria sc = createSearchCriteria(); - if (id != null) { - sc.addAnd("id", SearchCriteria.Op.EQ, id); + if (CollectionUtils.isNotEmpty(ids)) { + sc.addAnd("id", SearchCriteria.Op.IN, ids.toArray()); } if (osCategoryId != null) { diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java b/server/src/main/java/com/cloud/api/ApiResponseHelper.java index e0dcc574ed56..868326ba6419 100644 --- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java +++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java @@ -5339,8 +5339,15 @@ public UnmanagedInstanceResponse createUnmanagedInstanceResponse(UnmanagedInstan if (host != null) { response.setHostId(host.getUuid()); response.setHostName(host.getName()); - } else if (instance.getHostName() != null) { - response.setHostName(instance.getHostName()); + response.setHypervisorVersion(host.getHypervisorVersion()); + } else { + // In case the unmanaged instance is on an external host + if (instance.getHostName() != null) { + response.setHostName(instance.getHostName()); + } + if (instance.getHostHypervisorVersion() != null) { + response.setHypervisorVersion(instance.getHostHypervisorVersion()); + } } response.setPowerState((instance.getPowerState() != null)? instance.getPowerState().toString() : UnmanagedInstanceTO.PowerState.PowerUnknown.toString()); response.setCpuCores(instance.getCpuCores()); diff --git a/server/src/main/java/com/cloud/server/ManagementServerImpl.java b/server/src/main/java/com/cloud/server/ManagementServerImpl.java index 4cb395d476e4..61d669dd3272 100644 --- a/server/src/main/java/com/cloud/server/ManagementServerImpl.java +++ b/server/src/main/java/com/cloud/server/ManagementServerImpl.java @@ -43,6 +43,7 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.api.query.MutualExclusiveIdsManagerBase; import com.cloud.network.vpc.VpcVO; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.SecurityChecker; @@ -832,7 +833,6 @@ import com.cloud.utils.PasswordGenerator; import com.cloud.utils.Ternary; import com.cloud.utils.component.ComponentLifecycle; -import com.cloud.utils.component.ManagerBase; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.db.DB; @@ -875,7 +875,7 @@ import com.cloud.vm.dao.VMInstanceDao; import com.cloud.vm.dao.VMInstanceDetailsDao; -public class ManagementServerImpl extends ManagerBase implements ManagementServer, Configurable { +public class ManagementServerImpl extends MutualExclusiveIdsManagerBase implements ManagementServer, Configurable { protected StateMachine2 _stateMachine; static final String FOR_SYSTEMVMS = "forsystemvms"; @@ -2898,7 +2898,7 @@ protected void setParameters(SearchCriteria sc, final ListPublicIpA @Override public Pair, Integer> listGuestOSByCriteria(final ListGuestOsCmd cmd) { - final Long id = cmd.getId(); + List ids = getIdsListFromCmd(cmd.getId(), cmd.getIds()); final Long osCategoryId = cmd.getOsCategoryId(); final String description = cmd.getDescription(); final String keyword = cmd.getKeyword(); @@ -2906,7 +2906,7 @@ public Pair, Integer> listGuestOSByCriteria(final ListGu final Long pageSize = cmd.getPageSizeVal(); Boolean forDisplay = cmd.getDisplay(); - return _guestOSDao.listGuestOSByCriteria(startIndex, pageSize, id, osCategoryId, description, keyword, forDisplay); + return _guestOSDao.listGuestOSByCriteria(startIndex, pageSize, ids, osCategoryId, description, keyword, forDisplay); } @Override diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index f36c851e5bb3..a492aae19a74 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -4803,12 +4803,13 @@ private String generateHostName(String uuidName) { private UserVmVO commitUserVm(final boolean isImport, final DataCenter zone, final Host host, final Host lastHost, final VirtualMachineTemplate template, final String hostName, final String displayName, final Account owner, final Long diskOfferingId, final Long diskSize, final String userData, Long userDataId, String userDataDetails, final Boolean isDisplayVm, final String keyboard, - final long accountId, final long userId, final ServiceOffering offering, final boolean isIso, final String sshPublicKeys, final LinkedHashMap> networkNicMap, + final long accountId, final long userId, final ServiceOffering offering, final boolean isIso, final Long guestOsId, final String sshPublicKeys, final LinkedHashMap> networkNicMap, final long id, final String instanceName, final String uuidName, final HypervisorType hypervisorType, final Map customParameters, final Map> extraDhcpOptionMap, final Map dataDiskTemplateToDiskOfferingMap, final Map userVmOVFPropertiesMap, final VirtualMachine.PowerState powerState, final boolean dynamicScalingEnabled, String vmType, final Long rootDiskOfferingId, String sshkeypairs, List dataDiskInfoList, Volume volume, Snapshot snapshot) throws InsufficientCapacityException { - UserVmVO vm = new UserVmVO(id, instanceName, displayName, template.getId(), hypervisorType, template.getGuestOSId(), offering.isOfferHA(), + Long selectedGuestOsId = guestOsId != null ? guestOsId : template.getGuestOSId(); + UserVmVO vm = new UserVmVO(id, instanceName, displayName, template.getId(), hypervisorType, selectedGuestOsId, offering.isOfferHA(), offering.getLimitCpuUse(), owner.getDomainId(), owner.getId(), userId, offering.getId(), userData, userDataId, userDataDetails, hostName); vm.setUuid(uuidName); vm.setDynamicallyScalable(dynamicScalingEnabled); @@ -4834,8 +4835,7 @@ private UserVmVO commitUserVm(final boolean isImport, final DataCenter zone, fin vm.setIsoId(template.getId()); } - long guestOSId = template.getGuestOSId(); - GuestOSVO guestOS = _guestOSDao.findById(guestOSId); + GuestOSVO guestOS = _guestOSDao.findById(selectedGuestOsId); long guestOSCategoryId = guestOS.getCategoryId(); GuestOSCategoryVO guestOSCategory = _guestOSCategoryDao.findById(guestOSCategoryId); if (hypervisorType.equals(HypervisorType.VMware)) { @@ -5093,7 +5093,7 @@ private UserVmVO commitUserVm(final DataCenter zone, final VirtualMachineTemplat List dataDiskInfoList, Volume volume, Snapshot snapshot) throws InsufficientCapacityException { return commitUserVm(false, zone, null, null, template, hostName, displayName, owner, diskOfferingId, diskSize, userData, userDataId, userDataDetails, isDisplayVm, keyboard, - accountId, userId, offering, isIso, sshPublicKeys, networkNicMap, + accountId, userId, offering, isIso, null, sshPublicKeys, networkNicMap, id, instanceName, uuidName, hypervisorType, customParameters, extraDhcpOptionMap, dataDiskTemplateToDiskOfferingMap, userVmOVFPropertiesMap, null, dynamicScalingEnabled, vmType, rootDiskOfferingId, sshkeypairs, dataDiskInfoList, volume, snapshot); @@ -9498,7 +9498,7 @@ private String getInternalName(long accountId, long vmId) { @Override public UserVm importVM(final DataCenter zone, final Host host, final VirtualMachineTemplate template, final String instanceNameInternal, final String displayName, final Account owner, final String userData, final Account caller, final Boolean isDisplayVm, final String keyboard, - final long accountId, final long userId, final ServiceOffering serviceOffering, final String sshPublicKeys, + final long accountId, final long userId, final ServiceOffering serviceOffering, final String sshPublicKeys, final Long guestOsId, final String hostName, final HypervisorType hypervisorType, final Map customParameters, final VirtualMachine.PowerState powerState, final LinkedHashMap> networkNicMap) throws InsufficientCapacityException { return Transaction.execute((TransactionCallbackWithException) status -> { @@ -9524,7 +9524,7 @@ public UserVm importVM(final DataCenter zone, final Host host, final VirtualMach final Boolean dynamicScalingEnabled = checkIfDynamicScalingCanBeEnabled(null, serviceOffering, template, zone.getId()); return commitUserVm(true, zone, host, lastHost, template, hostName, displayName, owner, null, null, userData, null, null, isDisplayVm, keyboard, - accountId, userId, serviceOffering, template.getFormat().equals(ImageFormat.ISO), sshPublicKeys, networkNicMap, + accountId, userId, serviceOffering, template.getFormat().equals(ImageFormat.ISO), guestOsId, sshPublicKeys, networkNicMap, id, instanceName, uuidName, hypervisorType, customParameters, null, null, null, powerState, dynamicScalingEnabled, null, serviceOffering.getDiskOfferingId(), null, null, null, null); }); diff --git a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java index 13fa2608016c..bd70c7ad8c25 100644 --- a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java @@ -350,6 +350,15 @@ private UnmanagedInstanceResponse createUnmanagedInstanceResponse(UnmanagedInsta if (host != null) { response.setHostId(host.getUuid()); response.setHostName(host.getName()); + response.setHypervisorVersion(host.getHypervisorVersion()); + } else { + // In case the unmanaged instance is on an external host + if (instance.getHostName() != null) { + response.setHostName(instance.getHostName()); + } + if (instance.getHostHypervisorVersion() != null) { + response.setHypervisorVersion(instance.getHostHypervisorVersion()); + } } response.setPowerState(instance.getPowerState().toString()); response.setCpuCores(instance.getCpuCores()); @@ -1145,7 +1154,7 @@ protected void checkUnmanagedDiskLimits(Account account, UnmanagedInstanceTO.Dis private UserVm importVirtualMachineInternal(final UnmanagedInstanceTO unmanagedInstance, final String instanceNameInternal, final DataCenter zone, final Cluster cluster, final HostVO host, final VirtualMachineTemplate template, final String displayName, final String hostName, final Account caller, final Account owner, final Long userId, final ServiceOfferingVO serviceOffering, final Map dataDiskOfferingMap, - final Map nicNetworkMap, final Map callerNicIpAddressMap, + final Map nicNetworkMap, final Map callerNicIpAddressMap, final Long guestOsId, final Map details, final boolean migrateAllowed, final boolean forced, final boolean isImportUnmanagedFromSameHypervisor) { logger.debug(LogUtils.logGsonWithoutException("Trying to import VM [%s] with name [%s], in zone [%s], cluster [%s], and host [%s], using template [%s], service offering [%s], disks map [%s], NICs map [%s] and details [%s].", unmanagedInstance, displayName, zone, cluster, host, template, serviceOffering, dataDiskOfferingMap, nicNetworkMap, details)); @@ -1231,7 +1240,7 @@ private UserVm importVirtualMachineInternal(final UnmanagedInstanceTO unmanagedI try { userVm = userVmManager.importVM(zone, host, template, internalCSName, displayName, owner, null, caller, true, null, owner.getAccountId(), userId, - validatedServiceOffering, null, hostName, + validatedServiceOffering, null, guestOsId, hostName, cluster.getHypervisorType(), allDetails, powerState, null); } catch (InsufficientCapacityException ice) { String errorMsg = String.format("Failed to import VM [%s] due to [%s].", displayName, ice.getMessage()); @@ -1632,7 +1641,7 @@ private UserVm importUnmanagedInstanceFromHypervisor(DataCenter zone, Cluster cl userVm = importVirtualMachineInternal(unmanagedInstance, instanceName, zone, cluster, host, template, displayName, hostName, CallContext.current().getCallingAccount(), owner, userId, serviceOffering, dataDiskOfferingMap, - nicNetworkMap, nicIpAddressMap, + nicNetworkMap, nicIpAddressMap, null, details, migrateAllowed, forced, true); break; } @@ -1712,6 +1721,7 @@ protected UserVm importUnmanagedInstanceFromVmwareToKvm(DataCenter zone, Cluster Long convertStoragePoolId = cmd.getConvertStoragePoolId(); String extraParams = cmd.getExtraParams(); boolean forceConvertToPool = cmd.getForceConvertToPool(); + Long guestOsId = cmd.getGuestOsId(); if ((existingVcenterId == null && vcenter == null) || (existingVcenterId != null && vcenter != null)) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, @@ -1799,7 +1809,7 @@ protected UserVm importUnmanagedInstanceFromVmwareToKvm(DataCenter zone, Cluster UserVm userVm = importVirtualMachineInternal(convertedInstance, null, zone, destinationCluster, null, template, displayName, hostName, caller, owner, userId, serviceOffering, dataDiskOfferingMap, - nicNetworkMap, nicIpAddressMap, + nicNetworkMap, nicIpAddressMap, guestOsId, details, false, forced, false); long timeElapsedInSecs = (System.currentTimeMillis() - importStartTime) / 1000; logger.debug(String.format("VMware VM %s imported successfully to CloudStack instance %s (%s), Time taken: %d secs, OVF files imported from %s, Source VMware VM details - OS: %s, PowerState: %s, Disks: %s, NICs: %s", @@ -2676,7 +2686,7 @@ private UserVm importExternalKvmVirtualMachine(final UnmanagedInstanceTO unmanag try { userVm = userVmManager.importVM(zone, null, template, null, displayName, owner, null, caller, true, null, owner.getAccountId(), userId, - serviceOffering, null, hostName, + serviceOffering, null, null, hostName, Hypervisor.HypervisorType.KVM, allDetails, powerState, null); } catch (InsufficientCapacityException ice) { logger.error(String.format("Failed to import vm name: %s", instanceName), ice); @@ -2814,7 +2824,7 @@ private UserVm importKvmVirtualMachineFromDisk(final ImportSource importSource, try { userVm = userVmManager.importVM(zone, null, template, null, displayName, owner, null, caller, true, null, owner.getAccountId(), userId, - serviceOffering, null, hostName, + serviceOffering, null, null, hostName, Hypervisor.HypervisorType.KVM, allDetails, powerState, networkNicMap); } catch (InsufficientCapacityException ice) { logger.error(String.format("Failed to import vm name: %s", instanceName), ice); diff --git a/server/src/test/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImplTest.java b/server/src/test/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImplTest.java index a24ba7f068b2..541148b5ddf8 100644 --- a/server/src/test/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImplTest.java +++ b/server/src/test/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImplTest.java @@ -360,7 +360,7 @@ public void setUp() throws Exception { when(primaryDataStoreDao.listPoolByHostPath(Mockito.anyString(), Mockito.anyString())).thenReturn(pools); when(userVmManager.importVM(nullable(DataCenter.class), nullable(Host.class), nullable(VirtualMachineTemplate.class), nullable(String.class), nullable(String.class), nullable(Account.class), nullable(String.class), nullable(Account.class), nullable(Boolean.class), nullable(String.class), - nullable(Long.class), nullable(Long.class), nullable(ServiceOffering.class), nullable(String.class), + nullable(Long.class), nullable(Long.class), nullable(ServiceOffering.class), nullable(String.class), nullable(Long.class), nullable(String.class), nullable(Hypervisor.HypervisorType.class), nullable(Map.class), nullable(VirtualMachine.PowerState.class), nullable(LinkedHashMap.class))).thenReturn(userVm); NetworkVO networkVO = Mockito.mock(NetworkVO.class); when(networkVO.getGuestType()).thenReturn(Network.GuestType.L2); diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 82fa22b5333e..6494995bf223 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -1727,6 +1727,7 @@ "label.no.data": "No data to show", "label.no.errors": "No recent errors", "label.no.items": "No available Items", +"label.no.matching.guest.os.vmware.import": "No matching guest OS mapping found, using the default import template guest OS", "label.no.matching.offering": "No matching offering found", "label.no.matching.network": "No matching Networks found", "label.node.version": "Node version", diff --git a/ui/src/views/tools/ImportUnmanagedInstance.vue b/ui/src/views/tools/ImportUnmanagedInstance.vue index 1d5bec8be744..cbe0dc7d5a02 100644 --- a/ui/src/views/tools/ImportUnmanagedInstance.vue +++ b/ui/src/views/tools/ImportUnmanagedInstance.vue @@ -232,6 +232,29 @@ + + + + +