You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ha...@apache.org on 2022/12/30 07:46:32 UTC

[cloudstack] 02/07: Added API getHypervisorGuestOsNames to list the guest OS names in the hypervisor, and code improvements

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

harikrishna pushed a commit to branch guest-os-mappings-improvements
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit 3d3e65d5a12402482c34b5e71c9830c0c69f98e4
Author: Suresh Kumar Anaparti <su...@gmail.com>
AuthorDate: Tue Jul 19 19:03:36 2022 +0530

    Added API getHypervisorGuestOsNames to list the guest OS names in the hypervisor, and code improvements
---
 api/src/main/java/com/cloud/event/EventTypes.java  |   2 +
 .../java/com/cloud/server/ManagementService.java   |   7 ++
 .../org/apache/cloudstack/api/ApiConstants.java    |   2 +
 .../apache/cloudstack/api/ResponseGenerator.java   |   3 +
 .../command/admin/guest/AddGuestOsMappingCmd.java  |   4 +-
 .../admin/guest/GetHypervisorGuestOsNamesCmd.java  | 106 +++++++++++++++++++++
 .../response/HypervisorGuestOsNamesResponse.java   |  76 +++++++++++++++
 .../api/response/HypervisorGuestOsResponse.java    |  51 ++++++++++
 .../agent/api/GetHypervisorGuestOsNamesAnswer.java |  48 ++++++++++
 .../api/GetHypervisorGuestOsNamesCommand.java      |  42 ++++++++
 .../cloud/storage/dao/GuestOSHypervisorDao.java    |   2 +
 .../storage/dao/GuestOSHypervisorDaoImpl.java      |  13 +++
 .../main/java/com/cloud/upgrade/GuestOsMapper.java |  35 ++++++-
 .../hypervisor/vmware/resource/VmwareResource.java |  40 +++++++-
 .../CitrixCheckGuestOsMappingCommandWrapper.java   |  14 ++-
 ...rixGetHypervisorGuestOsNamesCommandWrapper.java |  75 +++++++++++++++
 .../main/java/com/cloud/api/ApiResponseHelper.java |  24 +++++
 .../com/cloud/server/ManagementServerImpl.java     |  31 +++++-
 .../com/cloud/hypervisor/vmware/mo/ClusterMO.java  |   6 ++
 .../com/cloud/hypervisor/vmware/mo/HostMO.java     |  10 ++
 .../hypervisor/vmware/mo/VmwareHypervisorHost.java |   2 +
 21 files changed, 577 insertions(+), 16 deletions(-)

diff --git a/api/src/main/java/com/cloud/event/EventTypes.java b/api/src/main/java/com/cloud/event/EventTypes.java
index 93dee22e4df..51fe9430194 100644
--- a/api/src/main/java/com/cloud/event/EventTypes.java
+++ b/api/src/main/java/com/cloud/event/EventTypes.java
@@ -626,6 +626,7 @@ public class EventTypes {
     public static final String EVENT_GUEST_OS_MAPPING_ADD = "GUEST.OS.MAPPING.ADD";
     public static final String EVENT_GUEST_OS_MAPPING_REMOVE = "GUEST.OS.MAPPING.REMOVE";
     public static final String EVENT_GUEST_OS_MAPPING_UPDATE = "GUEST.OS.MAPPING.UPDATE";
+    public static final String EVENT_GUEST_OS_HYPERVISOR_NAME_FETCH = "GUEST.OS.HYPERVISOR.NAME.FETCH";
 
     public static final String EVENT_NIC_SECONDARY_IP_ASSIGN = "NIC.SECONDARY.IP.ASSIGN";
     public static final String EVENT_NIC_SECONDARY_IP_UNASSIGN = "NIC.SECONDARY.IP.UNASSIGN";
@@ -1063,6 +1064,7 @@ public class EventTypes {
         entityEventDetails.put(EVENT_GUEST_OS_MAPPING_ADD, GuestOSHypervisor.class);
         entityEventDetails.put(EVENT_GUEST_OS_MAPPING_REMOVE, GuestOSHypervisor.class);
         entityEventDetails.put(EVENT_GUEST_OS_MAPPING_UPDATE, GuestOSHypervisor.class);
+        entityEventDetails.put(EVENT_GUEST_OS_HYPERVISOR_NAME_FETCH, GuestOSHypervisor.class);
         entityEventDetails.put(EVENT_NIC_SECONDARY_IP_ASSIGN, NicSecondaryIp.class);
         entityEventDetails.put(EVENT_NIC_SECONDARY_IP_UNASSIGN, NicSecondaryIp.class);
         entityEventDetails.put(EVENT_NIC_SECONDARY_IP_CONFIGURE, NicSecondaryIp.class);
diff --git a/api/src/main/java/com/cloud/server/ManagementService.java b/api/src/main/java/com/cloud/server/ManagementService.java
index e1b9705ecf5..0b019fb591a 100644
--- a/api/src/main/java/com/cloud/server/ManagementService.java
+++ b/api/src/main/java/com/cloud/server/ManagementService.java
@@ -26,6 +26,7 @@ import org.apache.cloudstack.api.command.admin.config.ListCfgsByCmd;
 import org.apache.cloudstack.api.command.admin.config.UpdateHypervisorCapabilitiesCmd;
 import org.apache.cloudstack.api.command.admin.guest.AddGuestOsCmd;
 import org.apache.cloudstack.api.command.admin.guest.AddGuestOsMappingCmd;
+import org.apache.cloudstack.api.command.admin.guest.GetHypervisorGuestOsNamesCmd;
 import org.apache.cloudstack.api.command.admin.guest.ListGuestOsMappingCmd;
 import org.apache.cloudstack.api.command.admin.guest.RemoveGuestOsCmd;
 import org.apache.cloudstack.api.command.admin.guest.RemoveGuestOsMappingCmd;
@@ -179,6 +180,12 @@ public interface ManagementService {
      */
     GuestOSHypervisor getAddedGuestOsMapping(Long guestOsHypervisorId);
 
+    /**
+     * Get hypervisor guest OS names
+     *
+     * @return the hypervisor guest OS name that can be used for mapping, with guest OS name, and the name of guest OS specific to hypervisor
+     */
+    List<Pair<String, String>> getHypervisorGuestOsNames(GetHypervisorGuestOsNamesCmd getHypervisorGuestOsNamesCmd);
     /**
      * Adds a new guest OS
      *
diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
index a52eba6e555..ae97c2ef903 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
@@ -301,6 +301,8 @@ public class ApiConstants {
     public static final String OS_TYPE_ID = "ostypeid";
     public static final String OS_DISPLAY_NAME = "osdisplayname";
     public static final String OS_NAME_FOR_HYPERVISOR = "osnameforhypervisor";
+    public static final String GUEST_OSES = "guestoses";
+    public static final String GUEST_OSES_COUNT = "guestosescount";
     public static final String OS_MAPPING_CHECK_ENABLED = "osmappingcheckenabled";
     public static final String OUTOFBANDMANAGEMENT_POWERSTATE = "outofbandmanagementpowerstate";
     public static final String OUTOFBANDMANAGEMENT_ENABLED = "outofbandmanagementenabled";
diff --git a/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java
index a90c222e351..94c2c6b59d7 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java
@@ -61,6 +61,7 @@ import org.apache.cloudstack.api.response.GuestVlanResponse;
 import org.apache.cloudstack.api.response.HostForMigrationResponse;
 import org.apache.cloudstack.api.response.HostResponse;
 import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse;
+import org.apache.cloudstack.api.response.HypervisorGuestOsNamesResponse;
 import org.apache.cloudstack.api.response.IPAddressResponse;
 import org.apache.cloudstack.api.response.ImageStoreResponse;
 import org.apache.cloudstack.api.response.InstanceGroupResponse;
@@ -459,6 +460,8 @@ public interface ResponseGenerator {
 
     GuestOsMappingResponse createGuestOSMappingResponse(GuestOSHypervisor osHypervisor);
 
+    HypervisorGuestOsNamesResponse createHypervisorGuestOSNamesResponse(List<Pair<String, String>> hypervisorGuestOsNames);
+
     SnapshotScheduleResponse createSnapshotScheduleResponse(SnapshotSchedule sched);
 
     UsageRecordResponse createUsageResponse(Usage usageRecord);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsMappingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsMappingCmd.java
index 829668b134f..17b0504db81 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsMappingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsMappingCmd.java
@@ -58,10 +58,10 @@ public class AddGuestOsMappingCmd extends BaseAsyncCreateCmd {
     @Parameter(name = ApiConstants.OS_NAME_FOR_HYPERVISOR, type = CommandType.STRING, required = true, description = "OS name specific to the hypervisor")
     private String osNameForHypervisor;
 
-    @Parameter(name = ApiConstants.OS_MAPPING_CHECK_ENABLED, type = CommandType.BOOLEAN, required = false, description = "When set to true, checks the guest os mapping name in the hypervisor (supports VMware and XenServer only)", since = "4.18.0")
+    @Parameter(name = ApiConstants.OS_MAPPING_CHECK_ENABLED, type = CommandType.BOOLEAN, required = false, description = "When set to true, checks the guest os mapping name in the hypervisor (supports VMware and XenServer only, atleast one hypervisor host with the version specified must be available)", since = "4.18.0")
     private Boolean osMappingCheckEnabled;
 
-    @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, required = false, description = "Forces add guest os mapping, overrides any existing user defined mapping", since = "4.18.0")
+    @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, required = false, description = "Forces add user defined guest os mapping, overrides any existing user defined mapping", since = "4.18.0")
     private Boolean forced;
 
     /////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/GetHypervisorGuestOsNamesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/GetHypervisorGuestOsNamesCmd.java
new file mode 100644
index 00000000000..ef5130e1497
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/GetHypervisorGuestOsNamesCmd.java
@@ -0,0 +1,106 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.guest;
+
+import java.util.List;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiArgValidator;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.HypervisorGuestOsNamesResponse;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+import com.cloud.utils.Pair;
+
+@APICommand(name = GetHypervisorGuestOsNamesCmd.APINAME, description = "Gets the guest OS names in the hypervisor", responseObject = HypervisorGuestOsNamesResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.18.0", authorized = {RoleType.Admin})
+public class GetHypervisorGuestOsNamesCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(GetHypervisorGuestOsNamesCmd.class.getName());
+
+    public static final String APINAME = "getHypervisorGuestOsNames";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, required = true, description = "Hypervisor type. One of : VMware, XenServer",
+            validations = {ApiArgValidator.NotNullOrEmpty})
+    private String hypervisor;
+
+    @Parameter(name = ApiConstants.HYPERVISOR_VERSION, type = CommandType.STRING, required = true, description = "Hypervisor version to get the guest os names (atleast one hypervisor host with the version specified must be available)",
+            validations = {ApiArgValidator.NotNullOrEmpty})
+    private String hypervisorVersion;
+
+    @Parameter(name = ApiConstants.KEYWORD, type = CommandType.STRING, required = false, description = "Keyword for guest os name")
+    private String keyword;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getHypervisor() {
+        return hypervisor;
+    }
+
+    public String getHypervisorVersion() {
+        return hypervisorVersion;
+    }
+
+    public String getKeyword() {
+        return keyword;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public void execute() {
+        List<Pair<String, String>> hypervisorGuestOsNames = _mgr.getHypervisorGuestOsNames(this);
+        HypervisorGuestOsNamesResponse response = _responseGenerator.createHypervisorGuestOSNamesResponse(hypervisorGuestOsNames);
+        response.setHypervisor(getHypervisor());
+        response.setHypervisorVersion(getHypervisorVersion());
+        response.setResponseName(getCommandName());
+        setResponseObject(response);
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_GUEST_OS_HYPERVISOR_NAME_FETCH;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Getting guest OS names from hypervisor: " + getHypervisor() + ", version: " + getHypervisorVersion();
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/HypervisorGuestOsNamesResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/HypervisorGuestOsNamesResponse.java
new file mode 100644
index 00000000000..04d98866875
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/response/HypervisorGuestOsNamesResponse.java
@@ -0,0 +1,76 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.cloudstack.api.response;
+
+import java.util.List;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+
+public class HypervisorGuestOsNamesResponse extends BaseResponse {
+    @SerializedName(ApiConstants.HYPERVISOR)
+    @Param(description = "the hypervisor")
+    private String hypervisor;
+
+    @SerializedName(ApiConstants.HYPERVISOR_VERSION)
+    @Param(description = "version of the hypervisor for guest os names")
+    private String hypervisorVersion;
+
+    @SerializedName(ApiConstants.GUEST_OSES)
+    @Param(description = "the guest OSes of the hypervisor", responseObject = HypervisorGuestOsResponse.class)
+    private List<HypervisorGuestOsResponse> guestOSes;
+
+    @SerializedName(ApiConstants.GUEST_OSES_COUNT)
+    @Param(description = "the count of guest OSes of the hypervisor")
+    private Integer guestOSesCount;
+
+    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 List<HypervisorGuestOsResponse> getGuestOSes() {
+        return guestOSes;
+    }
+
+    public void setGuestOSes(List<HypervisorGuestOsResponse> guestOSes) {
+        this.guestOSes = guestOSes;
+    }
+
+    public Integer getGuestOSesCount() {
+        return guestOSesCount;
+    }
+
+    public void setGuestOSesCount(Integer guestOSesCount) {
+        this.guestOSesCount = guestOSesCount;
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/HypervisorGuestOsResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/HypervisorGuestOsResponse.java
new file mode 100644
index 00000000000..e9ef630e17f
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/response/HypervisorGuestOsResponse.java
@@ -0,0 +1,51 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.cloudstack.api.response;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+
+import com.cloud.serializer.Param;
+
+public class HypervisorGuestOsResponse extends BaseResponse {
+    @SerializedName(ApiConstants.OS_DISPLAY_NAME)
+    @Param(description = "standard display name for the Guest OS")
+    private String osStdName;
+
+    @SerializedName(ApiConstants.OS_NAME_FOR_HYPERVISOR)
+    @Param(description = "hypervisor specific name for the Guest OS")
+    private String osNameForHypervisor;
+
+    public String getOsStdName() {
+        return osStdName;
+    }
+
+    public void setOsStdName(String osStdName) {
+        this.osStdName = osStdName;
+    }
+
+    public String getOsNameForHypervisor() {
+        return osNameForHypervisor;
+    }
+
+    public void setOsNameForHypervisor(String osNameForHypervisor) {
+        this.osNameForHypervisor = osNameForHypervisor;
+    }
+}
diff --git a/core/src/main/java/com/cloud/agent/api/GetHypervisorGuestOsNamesAnswer.java b/core/src/main/java/com/cloud/agent/api/GetHypervisorGuestOsNamesAnswer.java
new file mode 100644
index 00000000000..707b1d486a8
--- /dev/null
+++ b/core/src/main/java/com/cloud/agent/api/GetHypervisorGuestOsNamesAnswer.java
@@ -0,0 +1,48 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.agent.api;
+
+import java.util.List;
+
+import com.cloud.utils.Pair;
+
+public class GetHypervisorGuestOsNamesAnswer extends Answer {
+    private List<Pair<String, String>> hypervisorGuestOsNames;
+
+    protected GetHypervisorGuestOsNamesAnswer() {
+    }
+
+    public GetHypervisorGuestOsNamesAnswer(GetHypervisorGuestOsNamesCommand cmd, List<Pair<String, String>> hypervisorGuestOsNames) {
+        super(cmd, true, null);
+        this.hypervisorGuestOsNames = hypervisorGuestOsNames;
+    }
+
+    public GetHypervisorGuestOsNamesAnswer(GetHypervisorGuestOsNamesCommand cmd, String details) {
+        super(cmd, false, details);
+    }
+
+    public GetHypervisorGuestOsNamesAnswer(GetHypervisorGuestOsNamesCommand cmd, Throwable th) {
+        super(cmd, false, th.getMessage());
+    }
+
+    public List<Pair<String, String>> getHypervisorGuestOsNames() {
+        return hypervisorGuestOsNames;
+    }
+}
diff --git a/core/src/main/java/com/cloud/agent/api/GetHypervisorGuestOsNamesCommand.java b/core/src/main/java/com/cloud/agent/api/GetHypervisorGuestOsNamesCommand.java
new file mode 100644
index 00000000000..3f668091e0d
--- /dev/null
+++ b/core/src/main/java/com/cloud/agent/api/GetHypervisorGuestOsNamesCommand.java
@@ -0,0 +1,42 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.agent.api;
+
+public class GetHypervisorGuestOsNamesCommand extends Command {
+    String keyword;
+
+    public GetHypervisorGuestOsNamesCommand() {
+        super();
+    }
+
+    public GetHypervisorGuestOsNamesCommand(String keyword) {
+        super();
+        this.keyword = keyword;
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        return false;
+    }
+
+    public String getKeyword() {
+        return keyword;
+    }
+}
diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDao.java
index 17c6b3c959d..47a71433a32 100644
--- a/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDao.java
+++ b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDao.java
@@ -40,4 +40,6 @@ public interface GuestOSHypervisorDao extends GenericDao<GuestOSHypervisorVO, Lo
                                                                       String minHypervisorVersion);
 
     List<String> listHypervisorSupportedVersionsFromMinimumVersion(String hypervisorType, String hypervisorVersion);
+
+    List<GuestOSHypervisorVO> listByHypervisorTypeAndVersion(String hypervisorType, String hypervisorVersion);
 }
diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java
index ae3ae9aceb8..65f17c29fbc 100644
--- a/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java
@@ -39,6 +39,7 @@ public class GuestOSHypervisorDaoImpl extends GenericDaoBase<GuestOSHypervisorVO
     protected final SearchBuilder<GuestOSHypervisorVO> userDefinedMappingSearch;
     protected final SearchBuilder<GuestOSHypervisorVO> guestOsNameSearch;
     protected final SearchBuilder<GuestOSHypervisorVO> availableHypervisorVersionSearch;
+    protected final SearchBuilder<GuestOSHypervisorVO> hypervisorTypeAndVersionSearch;
 
     public GuestOSHypervisorDaoImpl() {
         guestOsSearch = createSearchBuilder();
@@ -73,6 +74,11 @@ public class GuestOSHypervisorDaoImpl extends GenericDaoBase<GuestOSHypervisorVO
         availableHypervisorVersionSearch.select(null, SearchCriteria.Func.DISTINCT,
                 availableHypervisorVersionSearch.entity().getHypervisorVersion());
         availableHypervisorVersionSearch.done();
+
+        hypervisorTypeAndVersionSearch = createSearchBuilder();
+        hypervisorTypeAndVersionSearch.and("hypervisor_type", hypervisorTypeAndVersionSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ);
+        hypervisorTypeAndVersionSearch.and("hypervisor_version", hypervisorTypeAndVersionSearch.entity().getHypervisorVersion(), SearchCriteria.Op.EQ);
+        hypervisorTypeAndVersionSearch.done();
     }
 
     @Override
@@ -176,4 +182,11 @@ public class GuestOSHypervisorDaoImpl extends GenericDaoBase<GuestOSHypervisorVO
         return versions;
     }
 
+    @Override
+    public List<GuestOSHypervisorVO> listByHypervisorTypeAndVersion(String hypervisorType, String hypervisorVersion) {
+        SearchCriteria<GuestOSHypervisorVO> sc = hypervisorTypeAndVersionSearch.create();
+        sc.setParameters("hypervisor_type", hypervisorType);
+        sc.setParameters("hypervisor_version", hypervisorVersion);
+        return listIncludingRemovedBy(sc);
+    }
 }
diff --git a/engine/schema/src/main/java/com/cloud/upgrade/GuestOsMapper.java b/engine/schema/src/main/java/com/cloud/upgrade/GuestOsMapper.java
index f8b3d7a69cd..8bd135adfa1 100644
--- a/engine/schema/src/main/java/com/cloud/upgrade/GuestOsMapper.java
+++ b/engine/schema/src/main/java/com/cloud/upgrade/GuestOsMapper.java
@@ -17,6 +17,7 @@
 package com.cloud.upgrade;
 
 import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.log4j.Logger;
 
 import java.sql.Connection;
@@ -26,6 +27,7 @@ import java.util.List;
 
 import javax.inject.Inject;
 
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.storage.GuestOSHypervisorMapping;
 import com.cloud.storage.GuestOSHypervisorVO;
 import com.cloud.storage.GuestOSVO;
@@ -92,7 +94,7 @@ public class GuestOsMapper {
         }
     }
 
-    private boolean addGuestOs(long categoryId, String displayName) {
+    public boolean addGuestOs(long categoryId, String displayName) {
         LOG.debug("Adding guest OS with category id: " + categoryId + " and display name: " + displayName);
         GuestOSVO guestOS = new GuestOSVO();
         guestOS.setCategoryId(categoryId);
@@ -106,7 +108,7 @@ public class GuestOsMapper {
             return;
         }
 
-        LOG.debug("Adding guest OS hypervisor mapping - " + mapping.toString());
+        LOG.debug("Adding guest OS hypervisor mapping - " + mapping.toString() + ", for guest OS with id - " + guestOsId);
         GuestOSHypervisorVO guestOsMapping = new GuestOSHypervisorVO();
         guestOsMapping.setHypervisorType(mapping.getHypervisorType());
         guestOsMapping.setHypervisorVersion(mapping.getHypervisorVersion());
@@ -188,4 +190,33 @@ public class GuestOsMapper {
         LOG.warn("Invalid Guest OS hypervisor mapping");
         return false;
     }
+
+    /**
+     * Copies guest OS mappings from src version to dest version for the hypervisor (use this to copy all mappings from older version to newer version during upgrade)
+     * @return true if copied successfully, else false.
+     */
+    public boolean copyGuestOSHypervisorMappings(HypervisorType hypervisorType, String srcVersion, String destVersion) {
+        if (hypervisorType == HypervisorType.None || hypervisorType == HypervisorType.Any) {
+            LOG.warn("Unable to copy, invalid hypervisor");
+            return false;
+        }
+
+        if (StringUtils.isBlank(srcVersion) || StringUtils.isBlank(destVersion)) {
+            LOG.warn("Unable to copy, invalid hypervisor version details");
+            return false;
+        }
+
+        List<GuestOSHypervisorVO> guestOSHypervisorMappingsForSrcVersion = guestOSHypervisorDao.listByHypervisorTypeAndVersion(hypervisorType.toString(), srcVersion);
+        if (CollectionUtils.isEmpty(guestOSHypervisorMappingsForSrcVersion)) {
+            LOG.warn(String.format("Unable to copy, couldn't find guest OS mappings for hypervisor: %s and src version: %s", hypervisorType.toString(), srcVersion));
+            return false;
+        }
+
+        LOG.debug(String.format("Adding guest OS mappings for hypervisor: %s and version: %s, from version: %s ", hypervisorType.toString(), destVersion, srcVersion));
+        for (GuestOSHypervisorVO guestOSHypervisorMapping : guestOSHypervisorMappingsForSrcVersion) {
+            GuestOSHypervisorMapping mapping = new GuestOSHypervisorMapping(hypervisorType.toString(), destVersion, guestOSHypervisorMapping.getGuestOsName());
+            addGuestOsHypervisorMapping(mapping, guestOSHypervisorMapping.getGuestOsId());
+        }
+        return true;
+    }
 }
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index d1ccba3baff..1c162583986 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -49,6 +49,8 @@ import javax.xml.datatype.XMLGregorianCalendar;
 
 import com.cloud.agent.api.CheckGuestOsMappingAnswer;
 import com.cloud.agent.api.CheckGuestOsMappingCommand;
+import com.cloud.agent.api.GetHypervisorGuestOsNamesAnswer;
+import com.cloud.agent.api.GetHypervisorGuestOsNamesCommand;
 import com.cloud.agent.api.PatchSystemVmAnswer;
 import com.cloud.agent.api.PatchSystemVmCommand;
 import com.cloud.resource.ServerResourceBase;
@@ -609,6 +611,8 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
                 answer = execute((GetAutoScaleMetricsCommand) cmd);
             } else if (clz == CheckGuestOsMappingCommand.class) {
                 answer = execute((CheckGuestOsMappingCommand) cmd);
+            } else if (clz == GetHypervisorGuestOsNamesCommand.class) {
+                answer = execute((GetHypervisorGuestOsNamesCommand) cmd);
             } else {
                 answer = Answer.createUnsupportedCommandAnswer(cmd);
             }
@@ -7729,13 +7733,14 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
             VmwareHypervisorHost hyperHost = getHyperHost(context);
             GuestOsDescriptor guestOsDescriptor = hyperHost.getGuestOsDescriptor(guestOsMappingName);
             if (guestOsDescriptor == null) {
-                return new CheckGuestOsMappingAnswer(cmd, "Guest os mapping name not found in the hypervisor");
+                return new CheckGuestOsMappingAnswer(cmd, "Guest os mapping name: " + guestOsMappingName + " not found in the hypervisor");
             }
             s_logger.debug("Matching hypervisor guest os - id: " + guestOsDescriptor.getId() + ", full name: " + guestOsDescriptor.getFullName() + ", family: " + guestOsDescriptor.getFamily());
             if (guestOsDescriptor.getFullName().equalsIgnoreCase(guestOsName)) {
-                // Extact matching may fail, try with regex?
-                s_logger.debug("Hypervisor guest os name matches with os name: " + guestOsName + " from user");
+                // Exact matching may fail, try with regex?
+                s_logger.debug("Hypervisor guest os name in the descriptor matches with os name: " + guestOsName);
             }
+            s_logger.info("Hypervisor guest os name in the descriptor matches with os mapping: " + guestOsMappingName + " from user");
             return new CheckGuestOsMappingAnswer(cmd);
         } catch (Exception e) {
             s_logger.error("Failed to check the hypervisor guest os mapping name: " + guestOsMappingName, e);
@@ -7743,6 +7748,35 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
         }
     }
 
+    private GetHypervisorGuestOsNamesAnswer execute(GetHypervisorGuestOsNamesCommand cmd) {
+        String keyword = cmd.getKeyword();
+        s_logger.info("Getting guest os names in the hypervisor");
+        try {
+            VmwareContext context = getServiceContext();
+            VmwareHypervisorHost hyperHost = getHyperHost(context);
+            List<GuestOsDescriptor> guestOsDescriptors = hyperHost.getGuestOsDescriptors();
+            if (guestOsDescriptors == null) {
+                return new GetHypervisorGuestOsNamesAnswer(cmd, "Guest os names not found in the hypervisor");
+            }
+            List<Pair<String, String>> hypervisorGuestOsNames = new ArrayList<>();
+            for (GuestOsDescriptor guestOsDescriptor : guestOsDescriptors) {
+                if (StringUtils.isNotBlank(keyword)) {
+                    if (guestOsDescriptor.getFullName().toLowerCase().contains(keyword.toLowerCase()) || guestOsDescriptor.getId().toLowerCase().contains(keyword.toLowerCase())) {
+                        Pair<String, String> hypervisorGuestOs = new Pair<>(guestOsDescriptor.getFullName(), guestOsDescriptor.getId());
+                        hypervisorGuestOsNames.add(hypervisorGuestOs);
+                    }
+                } else {
+                    Pair<String, String> hypervisorGuestOs = new Pair<>(guestOsDescriptor.getFullName(), guestOsDescriptor.getId());
+                    hypervisorGuestOsNames.add(hypervisorGuestOs);
+                }
+            }
+            return new GetHypervisorGuestOsNamesAnswer(cmd, hypervisorGuestOsNames);
+        } catch (Exception e) {
+            s_logger.error("Failed to get the hypervisor guest names due to: " + e.getLocalizedMessage(), e);
+            return new GetHypervisorGuestOsNamesAnswer(cmd, e.getLocalizedMessage());
+        }
+    }
+
     private Integer getVmwareWindowTimeInterval() {
         Integer windowInterval = VmwareManager.VMWARE_STATS_TIME_WINDOW.value();
         if (windowInterval == null || windowInterval < 20) {
diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckGuestOsMappingCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckGuestOsMappingCommandWrapper.java
index ed16d5bfed3..da3087cab91 100644
--- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckGuestOsMappingCommandWrapper.java
+++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckGuestOsMappingCommandWrapper.java
@@ -46,15 +46,19 @@ public final class CitrixCheckGuestOsMappingCommandWrapper extends CommandWrappe
             s_logger.info("Checking guest os mapping name: " + guestOsMappingName + " for the guest os: " + guestOsName + " in the hypervisor");
             final Set<VM> vms = VM.getAll(conn);
             if (vms.size() == 0) {
-                return new CheckGuestOsMappingAnswer(command, "Guest os mapping name not found in the hypervisor");
+                return new CheckGuestOsMappingAnswer(command, "Unable to match guest os mapping name: " + guestOsMappingName + " in the hypervisor");
             }
             for (VM vm : vms) {
-                if (guestOsMappingName.equalsIgnoreCase(vm.getNameLabel(conn))) {
-                    // Extact matching may fail, try with regex?
-                    s_logger.debug("Hypervisor guest os name matches with os name: " + guestOsName + " from user");
+                if (vm != null && vm.getIsATemplate(conn) && guestOsMappingName.equalsIgnoreCase(vm.getNameLabel(conn))) {
+                    if (guestOsName.equalsIgnoreCase(vm.getNameLabel(conn))) {
+                        // Exact matching may fail, try with regex?
+                        s_logger.debug("Hypervisor guest os name label matches with os name: " + guestOsName);
+                    }
+                    s_logger.info("Hypervisor guest os name label matches with os mapping: " + guestOsMappingName + " from user");
+                    return new CheckGuestOsMappingAnswer(command);
                 }
             }
-            return new CheckGuestOsMappingAnswer(command);
+            return new CheckGuestOsMappingAnswer(command, "Guest os mapping name: " + guestOsMappingName + " not found in the hypervisor");
         } catch (final Exception e) {
             s_logger.error("Failed to find the hypervisor guest os mapping name: " + guestOsMappingName, e);
             return new CheckGuestOsMappingAnswer(command, e.getLocalizedMessage());
diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetHypervisorGuestOsNamesCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetHypervisorGuestOsNamesCommandWrapper.java
new file mode 100644
index 00000000000..73cecebe00d
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetHypervisorGuestOsNamesCommandWrapper.java
@@ -0,0 +1,75 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.hypervisor.xenserver.resource.wrapper.xenbase;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.GetHypervisorGuestOsNamesAnswer;
+import com.cloud.agent.api.GetHypervisorGuestOsNamesCommand;
+import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
+import com.cloud.resource.CommandWrapper;
+import com.cloud.resource.ResourceWrapper;
+import com.cloud.utils.Pair;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.VM;
+
+@ResourceWrapper(handles =  GetHypervisorGuestOsNamesCommand.class)
+public final class CitrixGetHypervisorGuestOsNamesCommandWrapper extends CommandWrapper<GetHypervisorGuestOsNamesCommand, Answer, CitrixResourceBase> {
+
+    private static final Logger s_logger = Logger.getLogger(CitrixGetHypervisorGuestOsNamesCommandWrapper.class);
+
+    @Override
+    public Answer execute(final GetHypervisorGuestOsNamesCommand command, final CitrixResourceBase citrixResourceBase) {
+        final Connection conn = citrixResourceBase.getConnection();
+        String keyword = command.getKeyword();
+        try {
+            s_logger.info("Getting guest os names in the hypervisor");
+            final Set<VM> vms = VM.getAll(conn);
+            if (vms.size() == 0) {
+                return new GetHypervisorGuestOsNamesAnswer(command, "Guest os names not found in the hypervisor");
+            }
+            List<Pair<String, String>> hypervisorGuestOsNames = new ArrayList<>();
+            for (VM vm : vms) {
+                if (vm != null && vm.getIsATemplate(conn)) {
+                    String guestOSNameLabel = vm.getNameLabel(conn);
+                    if (StringUtils.isNotBlank(keyword)) {
+                        if (guestOSNameLabel.toLowerCase().contains(keyword.toLowerCase())) {
+                            Pair<String, String> hypervisorGuestOs = new Pair<>(guestOSNameLabel, guestOSNameLabel);
+                            hypervisorGuestOsNames.add(hypervisorGuestOs);
+                        }
+                    } else {
+                        Pair<String, String> hypervisorGuestOs = new Pair<>(guestOSNameLabel, guestOSNameLabel);
+                        hypervisorGuestOsNames.add(hypervisorGuestOs);
+                    }
+                }
+            }
+            return new GetHypervisorGuestOsNamesAnswer(command, hypervisorGuestOsNames);
+        } catch (final Exception e) {
+            s_logger.error("Failed to fetch hypervisor guest os names due to: " + e.getLocalizedMessage(), e);
+            return new GetHypervisorGuestOsNamesAnswer(command, e.getLocalizedMessage());
+        }
+    }
+}
\ No newline at end of file
diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java b/server/src/main/java/com/cloud/api/ApiResponseHelper.java
index e08ba5250e9..3e71a416c61 100644
--- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java
@@ -93,6 +93,8 @@ import org.apache.cloudstack.api.response.GuestVlanResponse;
 import org.apache.cloudstack.api.response.HostForMigrationResponse;
 import org.apache.cloudstack.api.response.HostResponse;
 import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse;
+import org.apache.cloudstack.api.response.HypervisorGuestOsNamesResponse;
+import org.apache.cloudstack.api.response.HypervisorGuestOsResponse;
 import org.apache.cloudstack.api.response.IPAddressResponse;
 import org.apache.cloudstack.api.response.ImageStoreResponse;
 import org.apache.cloudstack.api.response.InstanceGroupResponse;
@@ -3611,6 +3613,28 @@ public class ApiResponseHelper implements ResponseGenerator {
         return response;
     }
 
+    @Override
+    public HypervisorGuestOsNamesResponse createHypervisorGuestOSNamesResponse(List<Pair<String, String>> hypervisorGuestOsNames) {
+        HypervisorGuestOsNamesResponse response = new HypervisorGuestOsNamesResponse();
+        List<HypervisorGuestOsResponse> hypervisorGuestOsResponses = new ArrayList<>();
+        for (Pair<String, String> hypervisorGuestOsName : hypervisorGuestOsNames) {
+            HypervisorGuestOsResponse hypervisorGuestOsResponse = createHypervisorGuestOsResponse(hypervisorGuestOsName);
+            hypervisorGuestOsResponses.add(hypervisorGuestOsResponse);
+        }
+        response.setGuestOSes(hypervisorGuestOsResponses);
+        response.setGuestOSesCount(hypervisorGuestOsResponses.size());
+        response.setObjectName("hypervisorguestosnames");
+        return response;
+    }
+
+    private HypervisorGuestOsResponse createHypervisorGuestOsResponse(Pair<String, String> hypervisorGuestOsName) {
+        HypervisorGuestOsResponse hypervisorGuestOsResponse = new HypervisorGuestOsResponse();
+        hypervisorGuestOsResponse.setOsStdName(hypervisorGuestOsName.first());
+        hypervisorGuestOsResponse.setOsNameForHypervisor(hypervisorGuestOsName.second());
+        hypervisorGuestOsResponse.setObjectName("guestoses");
+        return hypervisorGuestOsResponse;
+    }
+
     @Override
     public SnapshotScheduleResponse createSnapshotScheduleResponse(SnapshotSchedule snapshotSchedule) {
         SnapshotScheduleResponse response = new SnapshotScheduleResponse();
diff --git a/server/src/main/java/com/cloud/server/ManagementServerImpl.java b/server/src/main/java/com/cloud/server/ManagementServerImpl.java
index 29c66bfed6f..5eb0ea18325 100644
--- a/server/src/main/java/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/main/java/com/cloud/server/ManagementServerImpl.java
@@ -54,6 +54,8 @@ import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.CheckGuestOsMappingAnswer;
 import com.cloud.agent.api.CheckGuestOsMappingCommand;
 import com.cloud.agent.api.Command;
+import com.cloud.agent.api.GetHypervisorGuestOsNamesAnswer;
+import com.cloud.agent.api.GetHypervisorGuestOsNamesCommand;
 import com.cloud.agent.api.PatchSystemVmAnswer;
 import com.cloud.agent.api.PatchSystemVmCommand;
 import com.cloud.agent.api.proxy.AllowConsoleAccessCommand;
@@ -115,6 +117,7 @@ import org.apache.cloudstack.api.command.admin.domain.ListDomainsCmdByAdmin;
 import org.apache.cloudstack.api.command.admin.domain.UpdateDomainCmd;
 import org.apache.cloudstack.api.command.admin.guest.AddGuestOsCmd;
 import org.apache.cloudstack.api.command.admin.guest.AddGuestOsMappingCmd;
+import org.apache.cloudstack.api.command.admin.guest.GetHypervisorGuestOsNamesCmd;
 import org.apache.cloudstack.api.command.admin.guest.ListGuestOsMappingCmd;
 import org.apache.cloudstack.api.command.admin.guest.RemoveGuestOsCmd;
 import org.apache.cloudstack.api.command.admin.guest.RemoveGuestOsMappingCmd;
@@ -2708,12 +2711,12 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
     }
 
     private void checkGuestOSHypervisorMapping(HypervisorType hypervisorType, String hypervisorVersion, String guestOsName, String guestOsNameForHypervisor) {
-        if (!isGuestOSMappingCheckSupported(hypervisorType)) {
-            throw new InvalidParameterValueException(String.format("Guest OS mapping check is not supported for hypervisor: %s", hypervisorType.toString()));
+        if (!canCheckGuestOsNameInHypervisor(hypervisorType)) {
+            throw new InvalidParameterValueException(String.format("Guest OS mapping check is not supported for hypervisor: %s, please specify a valid hypervisor : VMware, XenServer", hypervisorType.toString()));
         }
         final HostVO host = _hostDao.findHostByHypervisorTypeAndVersion(hypervisorType, hypervisorVersion);
         if (host == null) {
-            throw new CloudRuntimeException(String.format("No host available with hypervisor: %s and version: %s, unable to check the guest os mapping", hypervisorType.toString(), hypervisorVersion));
+            throw new CloudRuntimeException(String.format("No host exists with hypervisor: %s and version: %s, please specify available hypervisor and version", hypervisorType.toString(), hypervisorVersion));
         }
         CheckGuestOsMappingAnswer answer = (CheckGuestOsMappingAnswer) _agentMgr.easySend(host.getId(), new CheckGuestOsMappingCommand(guestOsName, guestOsNameForHypervisor, hypervisorVersion));
         if (answer == null || !answer.getResult()) {
@@ -2721,7 +2724,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
         }
     }
 
-    private boolean isGuestOSMappingCheckSupported(HypervisorType hypervisorType) {
+    private boolean canCheckGuestOsNameInHypervisor(HypervisorType hypervisorType) {
         return (hypervisorType == HypervisorType.VMware || hypervisorType == HypervisorType.XenServer);
     }
 
@@ -2731,6 +2734,25 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
         return getGuestOsHypervisor(guestOsMappingId);
     }
 
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_HYPERVISOR_NAME_FETCH, eventDescription = "Getting guest OS names from hypervisor", async = true)
+    public List<Pair<String, String>> getHypervisorGuestOsNames(GetHypervisorGuestOsNamesCmd getHypervisorGuestOsNamesCmd) {
+        final HypervisorType hypervisorType = HypervisorType.getType(getHypervisorGuestOsNamesCmd.getHypervisor());
+        if (!canCheckGuestOsNameInHypervisor(hypervisorType)) {
+            throw new InvalidParameterValueException(String.format("Guest OS names cannot be fetched for hypervisor: %s, please specify a valid hypervisor : VMware, XenServer", hypervisorType.toString()));
+        }
+
+        final HostVO host = _hostDao.findHostByHypervisorTypeAndVersion(hypervisorType, getHypervisorGuestOsNamesCmd.getHypervisorVersion());
+        if (host == null) {
+            throw new CloudRuntimeException(String.format("No host exists with hypervisor: %s and version: %s, please specify available hypervisor and version", hypervisorType.toString(), getHypervisorGuestOsNamesCmd.getHypervisorVersion()));
+        }
+        GetHypervisorGuestOsNamesAnswer answer = (GetHypervisorGuestOsNamesAnswer) _agentMgr.easySend(host.getId(), new GetHypervisorGuestOsNamesCommand(getHypervisorGuestOsNamesCmd.getKeyword()));
+        if (answer == null || !answer.getResult()) {
+            throw new CloudRuntimeException(String.format("Unable to get guest os names for %s, hypervisor: %s, version: %s", hypervisorType.toString(), getHypervisorGuestOsNamesCmd.getHypervisorVersion()));
+        }
+        return answer.getHypervisorGuestOsNames();
+    }
+
     @Override
     @DB
     @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_ADD, eventDescription = "Adding new guest OS type", create = true)
@@ -3434,6 +3456,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
         cmdList.add(UpdateGuestOsMappingCmd.class);
         cmdList.add(RemoveGuestOsCmd.class);
         cmdList.add(RemoveGuestOsMappingCmd.class);
+        cmdList.add(GetHypervisorGuestOsNamesCmd.class);
         cmdList.add(AttachIsoCmd.class);
         cmdList.add(CopyIsoCmd.class);
         cmdList.add(DeleteIsoCmd.class);
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/ClusterMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/ClusterMO.java
index 318cdb87e61..8994796def2 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/ClusterMO.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/ClusterMO.java
@@ -752,4 +752,10 @@ public class ClusterMO extends BaseMO implements VmwareHypervisorHost {
         }
         return null;
     }
+
+    @Override
+    public List<GuestOsDescriptor> getGuestOsDescriptors() throws Exception {
+        VirtualMachineConfigOption vmConfigOption = _context.getService().queryConfigOption(getEnvironmentBrowser(), null, null);
+        return vmConfigOption.getGuestOSDescriptor();
+    }
 }
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java
index 7240f0972ba..f5406d16ba3 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java
@@ -1174,6 +1174,16 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
         return null;
     }
 
+    @Override
+    public List<GuestOsDescriptor> getGuestOsDescriptors() throws Exception {
+        ManagedObjectReference morParent = getParentMor();
+        if (morParent.getType().equals("ClusterComputeResource")) {
+            ClusterMO clusterMo = new ClusterMO(_context, morParent);
+            return clusterMo.getGuestOsDescriptors();
+        }
+        return null;
+    }
+
     public String getHostManagementIp(String managementPortGroup) throws Exception {
         HostNetworkInfo netInfo = getHostNetworkInfo();
 
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
index 3e6182b5666..2177b062b00 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
@@ -96,4 +96,6 @@ public interface VmwareHypervisorHost {
     String getRecommendedDiskController(String guestOsId) throws Exception;
 
     GuestOsDescriptor getGuestOsDescriptor(String guestOsId) throws Exception;
+
+    List<GuestOsDescriptor> getGuestOsDescriptors() throws Exception;
 }