This is an automated email from the ASF dual-hosted git repository.

sureshanaparti pushed a commit to branch 4.22
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.22 by this push:
     new 7107d28db82 [VMware to KVM] Add guest OS for importing VM based on the 
source VM OS (#12802)
7107d28db82 is described below

commit 7107d28db82fe656a2fba11bf76b487ae05376f3
Author: Nicolas Vazquez <[email protected]>
AuthorDate: Tue Mar 24 06:36:38 2026 -0300

    [VMware to KVM] Add guest OS for importing VM based on the source VM OS 
(#12802)
---
 api/src/main/java/com/cloud/vm/UserVmService.java  |  3 +-
 .../api/command/admin/vm/ImportVmCmd.java          | 12 ++++
 .../api/command/user/guest/ListGuestOsCmd.java     |  9 +++
 .../api/response/UnmanagedInstanceResponse.java    | 24 +++++++
 .../apache/cloudstack/vm/UnmanagedInstanceTO.java  | 19 +++++
 .../java/com/cloud/storage/dao/GuestOSDao.java     |  2 +-
 .../java/com/cloud/storage/dao/GuestOSDaoImpl.java |  6 +-
 .../wrapper/LibvirtGetRemoteVmsCommandWrapper.java |  2 +
 ...LibvirtGetUnmanagedInstancesCommandWrapper.java |  2 +
 .../main/java/com/cloud/api/ApiResponseHelper.java | 17 ++++-
 .../com/cloud/server/ManagementServerImpl.java     | 33 ++++++---
 .../main/java/com/cloud/vm/UserVmManagerImpl.java  | 14 ++--
 .../cloudstack/vm/UnmanagedVMsManagerImpl.java     | 80 +++-------------------
 .../cloudstack/vm/UnmanagedVMsManagerImplTest.java |  2 +-
 ui/public/locales/en.json                          |  1 +
 ui/src/views/tools/ImportUnmanagedInstance.vue     | 37 +++++++++-
 ui/src/views/tools/ManageInstances.vue             | 21 +++++-
 .../com/cloud/hypervisor/vmware/mo/BaseMO.java     | 25 +++++--
 .../cloud/hypervisor/vmware/util/VmwareHelper.java | 14 ++++
 .../hypervisor/vmware/util/VmwareHelperTest.java   | 23 +++++++
 20 files changed, 240 insertions(+), 106 deletions(-)

diff --git a/api/src/main/java/com/cloud/vm/UserVmService.java 
b/api/src/main/java/com/cloud/vm/UserVmService.java
index 01f11b73cd4..4ad1ffb755b 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 @@ public interface UserVmService {
      * @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 @@ public interface UserVmService {
      * @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<String, String> customParameters,
                     final VirtualMachine.PowerState powerState, final 
LinkedHashMap<String, List<NicProfile>> 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 f7940460d6c..50ccfbd69c5 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
@@ -30,6 +30,7 @@ import org.apache.cloudstack.api.BaseCmd;
 import org.apache.cloudstack.api.Parameter;
 import org.apache.cloudstack.api.ResponseObject;
 import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.GuestOSResponse;
 import org.apache.cloudstack.api.response.HostResponse;
 import org.apache.cloudstack.api.response.NetworkResponse;
 import org.apache.cloudstack.api.response.StoragePoolResponse;
@@ -171,6 +172,13 @@ 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,
+            entityType = GuestOSResponse.class,
+            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 +276,10 @@ public class ImportVmCmd extends 
ImportUnmanagedInstanceCmd {
         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 4ff2ebf0a66..d558e4c4f24 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<Long> 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 class ListGuestOsCmd extends BaseListCmd {
         return id;
     }
 
+    public List<Long> 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 195323b741d..3f2dc045e87 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,14 @@ public class UnmanagedInstanceResponse extends BaseResponse {
     @Param(description = "The name of the host to which Instance belongs")
     private String hostName;
 
+    @SerializedName(ApiConstants.HYPERVISOR)
+    @Param(description = "The hypervisor to which Instance belongs")
+    private String hypervisor;
+
+    @SerializedName(ApiConstants.HYPERVISOR_VERSION)
+    @Param(description = "The hypervisor 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 +148,22 @@ public class UnmanagedInstanceResponse extends 
BaseResponse {
         this.hostName = hostName;
     }
 
+    public String getHypervisor() {
+        return hypervisor;
+    }
+
+    public void setHypervisor(String hypervisor) {
+        this.hypervisor = hypervisor;
+    }
+
+    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 bba97dff71c..cbb7c4de698 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,9 @@ public class UnmanagedInstanceTO {
 
     private String hostName;
 
+    private String hypervisorType;
+    private String hostHypervisorVersion;
+
     private List<Disk> disks;
 
     private List<Nic> nics;
@@ -168,6 +171,22 @@ public class UnmanagedInstanceTO {
         this.hostName = hostName;
     }
 
+    public String getHypervisorType() {
+        return hypervisorType;
+    }
+
+    public void setHypervisorType(String hypervisorType) {
+        this.hypervisorType = hypervisorType;
+    }
+
+    public String getHostHypervisorVersion() {
+        return hostHypervisorVersion;
+    }
+
+    public void setHostHypervisorVersion(String hostHypervisorVersion) {
+        this.hostHypervisorVersion = hostHypervisorVersion;
+    }
+
     public List<Disk> 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 1a2b098c40a..f24f3f3b67c 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<GuestOSVO, 
Long> {
 
     List<GuestOSVO> listByDisplayName(String displayName);
 
-    Pair<List<? extends GuestOS>, Integer> listGuestOSByCriteria(Long 
startIndex, Long pageSize, Long id, Long osCategoryId, String description, 
String keyword, Boolean forDisplay);
+    Pair<List<? extends GuestOS>, Integer> listGuestOSByCriteria(Long 
startIndex, Long pageSize, List<Long> ids, Long osCategoryId, String 
description, String keyword, Boolean forDisplay);
 
     List<Long> 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 881be207c1a..09f8772fb59 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 class GuestOSDaoImpl extends 
GenericDaoBase<GuestOSVO, Long> implements G
         return listBy(sc);
     }
 
-    public Pair<List<? extends GuestOS>, Integer> listGuestOSByCriteria(Long 
startIndex, Long pageSize, Long id, Long osCategoryId, String description, 
String keyword, Boolean forDisplay) {
+    public Pair<List<? extends GuestOS>, Integer> listGuestOSByCriteria(Long 
startIndex, Long pageSize, List<Long> ids, Long osCategoryId, String 
description, String keyword, Boolean forDisplay) {
         final Filter searchFilter = new Filter(GuestOSVO.class, "displayName", 
true, startIndex, pageSize);
         final SearchCriteria<GuestOSVO> 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/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetRemoteVmsCommandWrapper.java
 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetRemoteVmsCommandWrapper.java
index 114b27d3a5b..c0887415c65 100644
--- 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetRemoteVmsCommandWrapper.java
+++ 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetRemoteVmsCommandWrapper.java
@@ -22,6 +22,7 @@ package com.cloud.hypervisor.kvm.resource.wrapper;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.GetRemoteVmsAnswer;
 import com.cloud.agent.api.GetRemoteVmsCommand;
+import com.cloud.hypervisor.Hypervisor;
 import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
 import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
 import com.cloud.hypervisor.kvm.resource.LibvirtDomainXMLParser;
@@ -97,6 +98,7 @@ public final class LibvirtGetRemoteVmsCommandWrapper extends 
CommandWrapper<GetR
             if (parser.getCpuTuneDef() !=null) {
                 instance.setCpuSpeed(parser.getCpuTuneDef().getShares());
             }
+            instance.setHypervisorType(Hypervisor.HypervisorType.KVM.name());
             
instance.setPowerState(getPowerState(libvirtComputingResource.getVmState(conn,domain.getName())));
             instance.setNics(getUnmanagedInstanceNics(parser.getInterfaces()));
             
instance.setDisks(getUnmanagedInstanceDisks(parser.getDisks(),libvirtComputingResource,
 domain));
diff --git 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetUnmanagedInstancesCommandWrapper.java
 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetUnmanagedInstancesCommandWrapper.java
index b382613f8ab..60bc222594b 100644
--- 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetUnmanagedInstancesCommandWrapper.java
+++ 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetUnmanagedInstancesCommandWrapper.java
@@ -19,6 +19,7 @@ package com.cloud.hypervisor.kvm.resource.wrapper;
 
 import com.cloud.agent.api.GetUnmanagedInstancesAnswer;
 import com.cloud.agent.api.GetUnmanagedInstancesCommand;
+import com.cloud.hypervisor.Hypervisor;
 import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
 import com.cloud.hypervisor.kvm.resource.LibvirtDomainXMLParser;
 import com.cloud.hypervisor.kvm.resource.LibvirtVMDef;
@@ -130,6 +131,7 @@ public final class 
LibvirtGetUnmanagedInstancesCommandWrapper extends CommandWra
             if (parser.getCpuModeDef() != null) {
                 
instance.setCpuCoresPerSocket(parser.getCpuModeDef().getCoresPerSocket());
             }
+            instance.setHypervisorType(Hypervisor.HypervisorType.KVM.name());
             
instance.setPowerState(getPowerState(libvirtComputingResource.getVmState(conn,domain.getName())));
             instance.setMemory((int) 
LibvirtComputingResource.getDomainMemory(domain) / 1024);
             
instance.setNics(getUnmanagedInstanceNics(libvirtComputingResource, 
parser.getInterfaces()));
diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java 
b/server/src/main/java/com/cloud/api/ApiResponseHelper.java
index e0dcc574ed5..bd8c32b390b 100644
--- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java
@@ -5339,8 +5339,21 @@ public class ApiResponseHelper implements 
ResponseGenerator {
         if (host != null) {
             response.setHostId(host.getUuid());
             response.setHostName(host.getName());
-        } else if (instance.getHostName() != null) {
-            response.setHostName(instance.getHostName());
+            if (host.getHypervisorType() != null) {
+                response.setHypervisor(host.getHypervisorType().name());
+            }
+            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.getHypervisorType() != null) {
+                response.setHypervisor(instance.getHypervisorType());
+            }
+            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 4cb395d476e..4875002074c 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.crypto.spec.SecretKeySpec;
 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.Pair;
 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.UserVmDao;
 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<State, VirtualMachine.Event, VirtualMachine> 
_stateMachine;
 
     static final String FOR_SYSTEMVMS = "forsystemvms";
@@ -2898,7 +2898,7 @@ public class ManagementServerImpl extends ManagerBase 
implements ManagementServe
 
     @Override
     public Pair<List<? extends GuestOS>, Integer> listGuestOSByCriteria(final 
ListGuestOsCmd cmd) {
-        final Long id = cmd.getId();
+        List<Long> 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 class ManagementServerImpl extends ManagerBase 
implements ManagementServe
         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
@@ -3038,28 +3038,41 @@ public class ManagementServerImpl extends ManagerBase 
implements ManagementServe
             throw new InvalidParameterValueException("Hypervisor version 
parameter cannot be used without specifying a hypervisor : XenServer, KVM or 
VMware");
         }
 
-        final SearchCriteria<GuestOSHypervisorVO> sc = 
_guestOSHypervisorDao.createSearchCriteria();
+        SearchBuilder<GuestOSHypervisorVO> sb = 
_guestOSHypervisorDao.createSearchBuilder();
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("guestOsName", sb.entity().getGuestOsName(), 
SearchCriteria.Op.LIKE);
+        sb.and("hypervisorType", sb.entity().getHypervisorType(), 
SearchCriteria.Op.LIKE);
+        sb.and("hypervisorVersion", sb.entity().getHypervisorVersion(), 
SearchCriteria.Op.LIKE);
+        sb.and(guestOsId, sb.entity().getGuestOsId(), SearchCriteria.Op.EQ);
+        SearchBuilder<GuestOSVO> guestOSSearch = 
_guestOSDao.createSearchBuilder();
+        guestOSSearch.and("display", guestOSSearch.entity().isDisplay(), 
SearchCriteria.Op.LIKE);
+        sb.join("guestOSSearch", guestOSSearch, sb.entity().getGuestOsId(), 
guestOSSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+
+        final SearchCriteria<GuestOSHypervisorVO> sc = sb.create();
 
         if (id != null) {
-            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+            sc.setParameters("id", SearchCriteria.Op.EQ, id);
         }
 
         if (osTypeId != null) {
-            sc.addAnd(guestOsId, SearchCriteria.Op.EQ, osTypeId);
+            sc.setParameters(guestOsId, osTypeId);
         }
 
         if (osNameForHypervisor != null) {
-            sc.addAnd("guestOsName", SearchCriteria.Op.LIKE, "%" + 
osNameForHypervisor + "%");
+            sc.setParameters("guestOsName", "%" + osNameForHypervisor + "%");
         }
 
         if (hypervisor != null) {
-            sc.addAnd("hypervisorType", SearchCriteria.Op.LIKE, "%" + 
hypervisor + "%");
+            sc.setParameters("hypervisorType", "%" + hypervisor + "%");
         }
 
         if (hypervisorVersion != null) {
-            sc.addAnd("hypervisorVersion", SearchCriteria.Op.LIKE, "%" + 
hypervisorVersion + "%");
+            sc.setParameters("hypervisorVersion", "%" + hypervisorVersion + 
"%");
         }
 
+        // Exclude the mappings for guest OS marked as display = false
+        sc.setJoinParameters("guestOSSearch", "display", true);
+
         if (osDisplayName != null) {
             List<GuestOSVO> guestOSVOS = 
_guestOSDao.listLikeDisplayName(osDisplayName);
             if (CollectionUtils.isNotEmpty(guestOSVOS)) {
diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java 
b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
index 0c924dcced6..fb04d455dec 100644
--- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
@@ -4830,12 +4830,13 @@ public class UserVmManagerImpl extends ManagerBase 
implements UserVmManager, Vir
 
     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<String, List<NicProfile>> networkNicMap,
+                                  final long accountId, final long userId, 
final ServiceOffering offering, final boolean isIso, final Long guestOsId, 
final String sshPublicKeys, final LinkedHashMap<String, List<NicProfile>> 
networkNicMap,
                                   final long id, final String instanceName, 
final String uuidName, final HypervisorType hypervisorType, final Map<String, 
String> customParameters,
                                   final Map<String, Map<Integer, String>> 
extraDhcpOptionMap, final Map<Long, DiskOffering> 
dataDiskTemplateToDiskOfferingMap,
                                   final Map<String, String> 
userVmOVFPropertiesMap, final VirtualMachine.PowerState powerState, final 
boolean dynamicScalingEnabled, String vmType, final Long rootDiskOfferingId, 
String sshkeypairs,
                                   List<VmDiskInfo> 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);
@@ -4861,8 +4862,7 @@ public class UserVmManagerImpl extends ManagerBase 
implements UserVmManager, Vir
             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)) {
@@ -5120,7 +5120,7 @@ public class UserVmManagerImpl extends ManagerBase 
implements UserVmManager, Vir
                                   List<VmDiskInfo> 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);
@@ -9525,7 +9525,7 @@ public class UserVmManagerImpl extends ManagerBase 
implements UserVmManager, Vir
     @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<String, String> customParameters,
                            final VirtualMachine.PowerState powerState, final 
LinkedHashMap<String, List<NicProfile>> networkNicMap) throws 
InsufficientCapacityException {
         return Transaction.execute((TransactionCallbackWithException<UserVm, 
InsufficientCapacityException>) status -> {
@@ -9551,7 +9551,7 @@ public class UserVmManagerImpl extends ManagerBase 
implements UserVmManager, Vir
             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 8bc710d113f..acd40447ee4 100644
--- a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java
+++ b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java
@@ -155,8 +155,6 @@ import 
org.apache.cloudstack.api.command.admin.vm.ListUnmanagedInstancesCmd;
 import org.apache.cloudstack.api.command.admin.vm.ListVmsForImportCmd;
 import org.apache.cloudstack.api.command.admin.vm.UnmanageVMInstanceCmd;
 import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.NicResponse;
-import org.apache.cloudstack.api.response.UnmanagedInstanceDiskResponse;
 import org.apache.cloudstack.api.response.UnmanagedInstanceResponse;
 import org.apache.cloudstack.api.response.UserVmResponse;
 import org.apache.cloudstack.context.CallContext;
@@ -341,68 +339,6 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
         return template;
     }
 
-    private UnmanagedInstanceResponse 
createUnmanagedInstanceResponse(UnmanagedInstanceTO instance, Cluster cluster, 
Host host) {
-        UnmanagedInstanceResponse response = new UnmanagedInstanceResponse();
-        response.setName(instance.getName());
-
-        if (cluster != null) {
-            response.setClusterId(cluster.getUuid());
-        }
-        if (host != null) {
-            response.setHostId(host.getUuid());
-            response.setHostName(host.getName());
-        }
-        response.setPowerState(instance.getPowerState().toString());
-        response.setCpuCores(instance.getCpuCores());
-        response.setCpuSpeed(instance.getCpuSpeed());
-        response.setCpuCoresPerSocket(instance.getCpuCoresPerSocket());
-        response.setMemory(instance.getMemory());
-        response.setOperatingSystemId(instance.getOperatingSystemId());
-        response.setOperatingSystem(instance.getOperatingSystem());
-        response.setObjectName("unmanagedinstance");
-
-        if (instance.getDisks() != null) {
-            for (UnmanagedInstanceTO.Disk disk : instance.getDisks()) {
-                UnmanagedInstanceDiskResponse diskResponse = new 
UnmanagedInstanceDiskResponse();
-                diskResponse.setDiskId(disk.getDiskId());
-                if (StringUtils.isNotEmpty(disk.getLabel())) {
-                    diskResponse.setLabel(disk.getLabel());
-                }
-                diskResponse.setCapacity(disk.getCapacity());
-                diskResponse.setController(disk.getController());
-                diskResponse.setControllerUnit(disk.getControllerUnit());
-                diskResponse.setPosition(disk.getPosition());
-                diskResponse.setImagePath(disk.getImagePath());
-                diskResponse.setDatastoreName(disk.getDatastoreName());
-                diskResponse.setDatastoreHost(disk.getDatastoreHost());
-                diskResponse.setDatastorePath(disk.getDatastorePath());
-                diskResponse.setDatastoreType(disk.getDatastoreType());
-                response.addDisk(diskResponse);
-            }
-        }
-
-        if (instance.getNics() != null) {
-            for (UnmanagedInstanceTO.Nic nic : instance.getNics()) {
-                NicResponse nicResponse = new NicResponse();
-                nicResponse.setId(nic.getNicId());
-                nicResponse.setNetworkName(nic.getNetwork());
-                nicResponse.setMacAddress(nic.getMacAddress());
-                if (StringUtils.isNotEmpty(nic.getAdapterType())) {
-                    nicResponse.setAdapterType(nic.getAdapterType());
-                }
-                if (!CollectionUtils.isEmpty(nic.getIpAddress())) {
-                    nicResponse.setIpAddresses(nic.getIpAddress());
-                }
-                nicResponse.setVlanId(nic.getVlan());
-                nicResponse.setIsolatedPvlanId(nic.getPvlan());
-                nicResponse.setIsolatedPvlanType(nic.getPvlanType());
-                response.addNic(nicResponse);
-            }
-        }
-
-        return response;
-    }
-
     private List<String> getAdditionalNameFilters(Cluster cluster) {
         List<String> additionalNameFilter = new ArrayList<>();
         if (cluster == null) {
@@ -1146,7 +1082,7 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
     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<String, Long> dataDiskOfferingMap,
-                                                final Map<String, Long> 
nicNetworkMap, final Map<String, Network.IpAddresses> callerNicIpAddressMap,
+                                                final Map<String, Long> 
nicNetworkMap, final Map<String, Network.IpAddresses> callerNicIpAddressMap, 
final Long guestOsId,
                                                 final Map<String, String> 
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));
@@ -1232,7 +1168,7 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
         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());
@@ -1633,7 +1569,7 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
                 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;
             }
@@ -1713,6 +1649,7 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
         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,
@@ -1800,7 +1737,7 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
             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",
@@ -2677,7 +2614,7 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
         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);
@@ -2815,7 +2752,7 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
         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);
@@ -3000,9 +2937,8 @@ public class UnmanagedVMsManagerImpl implements 
UnmanagedVMsManager {
                     !instance.getName().toLowerCase().contains(keyword)) {
                 continue;
             }
-            responses.add(createUnmanagedInstanceResponse(instance, null, 
null));
+            
responses.add(responseGenerator.createUnmanagedInstanceResponse(instance, null, 
null));
         }
-
         ListResponse<UnmanagedInstanceResponse> listResponses = new 
ListResponse<>();
         listResponses.setResponses(responses, responses.size());
         return listResponses;
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 a24ba7f068b..541148b5ddf 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 class UnmanagedVMsManagerImplTest {
         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 82fa22b5333..6494995bf22 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 1d5bec8be74..cbe0dc7d5a0 100644
--- a/ui/src/views/tools/ImportUnmanagedInstance.vue
+++ b/ui/src/views/tools/ImportUnmanagedInstance.vue
@@ -232,6 +232,29 @@
                 </template>
                 <a-switch v-model:checked="form.forcemstoimportvmfiles" 
@change="val => { switches.forceMsToImportVmFiles = val }" />
               </a-form-item>
+              <a-form-item name="osid" ref="osid" v-if="selectedVmwareVcenter">
+                <template #label>
+                  <tooltip-label :title="$t('label.guest.os')" 
:tooltip="$t('label.select.guest.os.type')"/>
+                </template>
+                <a-spin v-if="loadingGuestOsMappings" />
+                <template v-else>
+                  <a-select
+                    v-if="resource.guestOsMappings && 
resource.guestOsMappings.length > 0"
+                    v-model:value="form.osid"
+                    showSearch
+                    optionFilterProp="label"
+                    :filterOption="(input, option) => {
+                      return 
option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
+                    }">
+                    <a-select-option v-for="mapping in 
resource.guestOsMappings" :key="mapping.ostypeid" 
:label="mapping.osdisplayname">
+                      <span>
+                        {{ mapping.osdisplayname }}
+                      </span>
+                    </a-select-option>
+                  </a-select>
+                  <a-span v-else>{{ 
$t('label.no.matching.guest.os.vmware.import') }}</a-span>
+                </template>
+              </a-form-item>
               <a-form-item name="serviceofferingid" ref="serviceofferingid">
                 <template #label>
                   <tooltip-label :title="$t('label.serviceofferingid')" 
:tooltip="apiParams.serviceofferingid.description"/>
@@ -490,6 +513,10 @@ export default {
     selectedVmwareVcenter: {
       type: Array,
       required: false
+    },
+    loadingGuestOsMappings: {
+      type: Boolean,
+      required: false
     }
   },
   data () {
@@ -739,6 +766,11 @@ export default {
         this.$refs.displayname.focus()
         this.selectMatchingComputeOffering()
       }
+    },
+    'resource.guestOsMappings' (mappings) {
+      if (mappings && mappings.length > 0) {
+        this.form.osid = mappings[0].ostypeid
+      }
     }
   },
   methods: {
@@ -751,7 +783,8 @@ export default {
         forcemstoimportvmfiles: this.switches.forceMsToImportVmFiles,
         forceconverttopool: this.switches.forceConvertToPool,
         domainid: null,
-        account: null
+        account: null,
+        osid: null
       })
       this.rules = reactive({
         displayname: [{ required: true, message: 
this.$t('message.error.input.value') }],
@@ -1207,7 +1240,7 @@ export default {
             params.forceconverttopool = values.forceconverttopool
           }
         }
-        var keys = ['hostname', 'domainid', 'projectid', 'account', 
'migrateallowed', 'forced', 'forcemstoimportvmfiles']
+        var keys = ['hostname', 'domainid', 'projectid', 'account', 
'migrateallowed', 'forced', 'forcemstoimportvmfiles', 'osid']
         if (this.templateType !== 'auto') {
           keys.push('templateid')
         }
diff --git a/ui/src/views/tools/ManageInstances.vue 
b/ui/src/views/tools/ManageInstances.vue
index a6260bfb316..6f625961ea8 100644
--- a/ui/src/views/tools/ManageInstances.vue
+++ b/ui/src/views/tools/ManageInstances.vue
@@ -541,6 +541,7 @@
             :tmppath="this.values?.tmppath || ''"
             :diskpath="this.values?.diskpath || ''"
             :isOpen="showUnmanageForm"
+            :loadingGuestOsMappings="loadingGuestOsMappings"
             :selectedVmwareVcenter="selectedVmwareVcenter"
             @refresh-data="fetchInstances"
             @close-action="closeImportUnmanagedInstanceForm"
@@ -774,7 +775,8 @@ export default {
       activeTabKey: 1,
       loadingImportVmTasks: false,
       importVmTasks: [],
-      importVmTasksFilter: 'running'
+      importVmTasksFilter: 'running',
+      loadingGuestOsMappings: false
     }
   },
   created () {
@@ -1377,8 +1379,21 @@ export default {
         this.fetchInstances()
       }
     },
+    async fetchGuestOsMappings (osIdentifier, hypervisorVersion) {
+      const params = {}
+      params.hypervisor = 'VMware'
+      params.hypervisorversion = hypervisorVersion
+      params.osnameforhypervisor = osIdentifier
+      return await getAPI('listGuestOsMapping', params).then(json => {
+        return json.listguestosmappingresponse?.guestosmapping || []
+      }).catch(error => {
+        this.$notifyError(error)
+        return []
+      })
+    },
     fetchVmwareInstanceForKVMMigration (vmname, hostname) {
       const params = {}
+      this.loadingGuestOsMappings = true
       if (this.isMigrateFromVmware && this.selectedVmwareVcenter) {
         if (this.selectedVmwareVcenter.vcenter) {
           params.datacentername = this.selectedVmwareVcenter.datacentername
@@ -1391,15 +1406,17 @@ export default {
         params.instancename = vmname
         params.hostname = hostname
       }
-      getAPI('listVmwareDcVms', params).then(json => {
+      getAPI('listVmwareDcVms', params).then(async json => {
         const response = json.listvmwaredcvmsresponse
         this.selectedUnmanagedInstance = response.unmanagedinstance[0]
         this.selectedUnmanagedInstance.ostypename = 
this.selectedUnmanagedInstance.osdisplayname
         this.selectedUnmanagedInstance.state = 
this.selectedUnmanagedInstance.powerstate
+        this.selectedUnmanagedInstance.guestOsMappings = await 
this.fetchGuestOsMappings(this.selectedUnmanagedInstance.osid, 
this.selectedUnmanagedInstance.hypervisorversion)
       }).catch(error => {
         this.$notifyError(error)
       }).finally(() => {
         this.loading = false
+        this.loadingGuestOsMappings = false
       })
     },
     onManageInstanceAction () {
diff --git 
a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/BaseMO.java 
b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/BaseMO.java
index cb123608ea1..1266c04f3b4 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/BaseMO.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/BaseMO.java
@@ -16,6 +16,7 @@
 // under the License.
 package com.cloud.hypervisor.vmware.mo;
 
+import com.cloud.hypervisor.Hypervisor;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.LogManager;
 
@@ -45,9 +46,9 @@ public class BaseMO {
     protected VmwareContext _context;
     protected ManagedObjectReference _mor;
 
-    protected static String[] propertyPathsForUnmanagedVmsThinListing = new 
String[] {"name", "config.template",
-            "runtime.powerState", "config.guestId", "config.guestFullName", 
"runtime.host",
-            "config.bootOptions", "config.firmware"};
+    protected static String[] propertyPathsForUnmanagedVmsThinListing = new 
String[] {"name", "config.template", "runtime.powerState",
+            "config.guestId", "config.guestFullName", "summary.guest.guestId", 
"summary.guest.guestFullName",
+            "runtime.host", "config.bootOptions", "config.firmware"};
 
     private String _name;
 
@@ -207,6 +208,11 @@ public class BaseMO {
         boolean isTemplate = false;
         boolean excludeByKeyword = false;
 
+        String configGuestId = null;
+        String configGuestFullName = null;
+        String summaryGuestId = null;
+        String summaryGuestFullName = null;
+
         for (DynamicProperty objProp : objProps) {
             if (objProp.getName().equals("name")) {
                 vmName = (String) objProp.getVal();
@@ -220,9 +226,13 @@ public class BaseMO {
                 VirtualMachinePowerState powerState = 
(VirtualMachinePowerState) objProp.getVal();
                 vm.setPowerState(convertPowerState(powerState));
             } else if (objProp.getName().equals("config.guestFullName")) {
-                vm.setOperatingSystem((String) objProp.getVal());
+                configGuestFullName = (String) objProp.getVal();
             } else if (objProp.getName().equals("config.guestId")) {
-                vm.setOperatingSystemId((String) objProp.getVal());
+                configGuestId = (String) objProp.getVal();
+            } else if 
(objProp.getName().equals("summary.guest.guestFullName")) {
+                summaryGuestFullName = (String) objProp.getVal();
+            } else if (objProp.getName().equals("summary.guest.guestId")) {
+                summaryGuestId = (String) objProp.getVal();
             } else if (objProp.getName().equals("config.bootOptions")) {
                 VirtualMachineBootOptions bootOptions = 
(VirtualMachineBootOptions) objProp.getVal();
                 String bootMode = "LEGACY";
@@ -238,6 +248,11 @@ public class BaseMO {
                 setUnmanagedInstanceTOHostAndCluster(vm, hostMor, 
hostClusterNamesMap);
             }
         }
+
+        vm.setHypervisorType(Hypervisor.HypervisorType.VMware.name());
+        vm.setOperatingSystem(StringUtils.isNotBlank(summaryGuestFullName) ? 
summaryGuestFullName : configGuestFullName);
+        vm.setOperatingSystemId(StringUtils.isNotBlank(summaryGuestId) ? 
summaryGuestId : configGuestId);
+
         if (isTemplate || excludeByKeyword) {
             return null;
         }
diff --git 
a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java 
b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java
index 70fcdd23040..036d1f29cfb 100644
--- 
a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java
+++ 
b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java
@@ -41,6 +41,7 @@ import javax.xml.datatype.DatatypeFactory;
 import javax.xml.datatype.XMLGregorianCalendar;
 
 import com.cloud.agent.api.to.DiskTO;
+import com.cloud.hypervisor.Hypervisor;
 import com.cloud.hypervisor.vmware.mo.ClusterMO;
 import com.cloud.hypervisor.vmware.mo.DatastoreFile;
 import com.cloud.hypervisor.vmware.mo.DistributedVirtualSwitchMO;
@@ -833,6 +834,8 @@ public class VmwareHelper {
             }
 
             instance.setHostName(hyperHost.getHyperHostName());
+            
instance.setHypervisorType(Hypervisor.HypervisorType.VMware.name());
+            instance.setHostHypervisorVersion(getVmwareHostVersion(hyperHost));
 
             if (StringUtils.isEmpty(instance.getOperatingSystemId()) && 
configSummary != null) {
                 instance.setOperatingSystemId(configSummary.getGuestId());
@@ -866,6 +869,17 @@ public class VmwareHelper {
         return instance;
     }
 
+    protected static String getVmwareHostVersion(VmwareHypervisorHost 
hyperHost) {
+        if (hyperHost instanceof HostMO) {
+            try {
+                return ((HostMO) hyperHost).getProductVersion();
+            } catch (Exception e) {
+                LOGGER.warn("Unable to get unmanaged instance host version, 
due to: " + e.getMessage(), e);
+            }
+        }
+        return null;
+    }
+
     protected static List<UnmanagedInstanceTO.Disk> 
getUnmanageInstanceDisks(VirtualMachineMO vmMo) {
         List<UnmanagedInstanceTO.Disk> instanceDisks = new ArrayList<>();
         VirtualDisk[] disks = null;
diff --git 
a/vmware-base/src/test/java/com/cloud/hypervisor/vmware/util/VmwareHelperTest.java
 
b/vmware-base/src/test/java/com/cloud/hypervisor/vmware/util/VmwareHelperTest.java
index 3908f8b0be3..54a312909b3 100644
--- 
a/vmware-base/src/test/java/com/cloud/hypervisor/vmware/util/VmwareHelperTest.java
+++ 
b/vmware-base/src/test/java/com/cloud/hypervisor/vmware/util/VmwareHelperTest.java
@@ -20,6 +20,8 @@ package com.cloud.hypervisor.vmware.util;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 
+import com.cloud.hypervisor.vmware.mo.ClusterMO;
+import com.cloud.hypervisor.vmware.mo.HostMO;
 import com.vmware.vim25.DatastoreInfo;
 import com.vmware.vim25.Description;
 import com.vmware.vim25.ManagedObjectReference;
@@ -105,4 +107,25 @@ public class VmwareHelperTest {
         Assert.assertEquals(diskFileBaseName, disk.getFileBaseName());
         Assert.assertEquals(dataStoreName, disk.getDatastoreName());
     }
+
+    @Test
+    public void testGetVmwareHostVersionException() throws Exception {
+        HostMO hostMO = Mockito.mock(HostMO.class);
+        Mockito.when(hostMO.getProductVersion()).thenThrow(new 
Exception("Error obtaining host version"));
+        Assert.assertNull(VmwareHelper.getVmwareHostVersion(hostMO));
+    }
+
+    @Test
+    public void testGetVmwareHostVersion() throws Exception {
+        HostMO hostMO = Mockito.mock(HostMO.class);
+        String version = "8.0.3";
+        Mockito.when(hostMO.getProductVersion()).thenReturn(version);
+        Assert.assertEquals(version, 
VmwareHelper.getVmwareHostVersion(hostMO));
+    }
+
+    @Test
+    public void testGetVmwareHostVersionInvalidParameter() {
+        ClusterMO clusterMO = Mockito.mock(ClusterMO.class);
+        Assert.assertNull(VmwareHelper.getVmwareHostVersion(clusterMO));
+    }
 }

Reply via email to