Guest os mappings improvements (#6979)

* Guest OS mapping improvements
- Checks the OS mapping name in hypervisor (VMware, XenServer)
- Displays guest OS mappings in UI

* Added API getHypervisorGuestOsNames to list the guest OS names in the hypervisor, and code improvements

* Some static analysis fixes

* Removed commented code in listview

* Guest OS list

* UI changes for adding guest os and mappings

* Added guest os mappings in guest os form

* Added new filter to guest os mapping

* Name and description changes

* VMWare Host and cluster MO unit tests

* CheckGuestOsMapping command and answer unit tests

* GetHypervisorGuestOsNames command and answer unit tests

* VmwareResource unitests

* GuestOsMapper unittests

* icon changes

* Addressed review comments

* Renaming fixes

* Removed comments

* marvin tests for guest os operations

* Added marvin tests for OS mappings

* Document links and UI improvements

* Added deduplication for the list guest OS API

* Fixed linter failure

* Few bug fixes and UI changes

* Few improvements

* Addressed code smells

* Fixed UI issues after rebase

---------

Co-authored-by: Suresh Kumar Anaparti <sureshkumar.anaparti@gmail.com>
Co-authored-by: Harikrishna Patnala <harikrishna.patnala@gmail.com>
This commit is contained in:
dahn 2023-06-27 10:19:20 +02:00 committed by GitHub
parent fa3f2a75eb
commit 06caf32bc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 2157 additions and 87 deletions

View File

@ -667,6 +667,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";
@ -1114,6 +1115,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);

View File

@ -27,6 +27,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;
@ -188,6 +189,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
*

View File

@ -313,10 +313,14 @@ public class ApiConstants {
public static final String OPTIONS = "options";
public static final String OS_CATEGORY_ID = "oscategoryid";
public static final String OS_CATEGORY_NAME = "oscategoryname";
public static final String OS_NAME = "osname";
public static final String OS_ID = "osid";
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_OS_LIST = "guestoslist";
public static final String GUEST_OS_COUNT = "guestoscount";
public static final String OS_MAPPING_CHECK_ENABLED = "osmappingcheckenabled";
public static final String OUTOFBANDMANAGEMENT_POWERSTATE = "outofbandmanagementpowerstate";
public static final String OUTOFBANDMANAGEMENT_ENABLED = "outofbandmanagementenabled";
public static final String OUTPUT = "output";

View File

@ -62,6 +62,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;
@ -463,6 +464,8 @@ public interface ResponseGenerator {
GuestOsMappingResponse createGuestOSMappingResponse(GuestOSHypervisor osHypervisor);
HypervisorGuestOsNamesResponse createHypervisorGuestOSNamesResponse(List<Pair<String, String>> hypervisorGuestOsNames);
SnapshotScheduleResponse createSnapshotScheduleResponse(SnapshotSchedule sched);
UsageRecordResponse createUsageResponse(Usage usageRecord);

View File

@ -16,6 +16,7 @@
// under the License.
package org.apache.cloudstack.api.command.admin.guest;
import org.apache.commons.collections.MapUtils;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
@ -57,7 +58,7 @@ public class AddGuestOsCmd extends BaseAsyncCreateCmd {
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = false, description = "Optional name for Guest OS")
private String osName;
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, required = true, description = "Map of (key/value pairs)")
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, required = false, description = "Map of (key/value pairs)")
private Map details;
@ -79,7 +80,7 @@ public class AddGuestOsCmd extends BaseAsyncCreateCmd {
public Map getDetails() {
Map<String, String> detailsMap = new HashMap<String, String>();
if (!details.isEmpty()) {
if (!MapUtils.isEmpty(details)) {
Collection<?> servicesCollection = details.values();
Iterator<?> iter = servicesCollection.iterator();
while (iter.hasNext()) {

View File

@ -16,6 +16,7 @@
// under the License.
package org.apache.cloudstack.api.command.admin.guest;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
@ -51,12 +52,18 @@ public class AddGuestOsMappingCmd extends BaseAsyncCreateCmd {
@Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, required = true, description = "Hypervisor type. One of : XenServer, KVM, VMWare")
private String hypervisor;
@Parameter(name = ApiConstants.HYPERVISOR_VERSION, type = CommandType.STRING, required = true, description = "Hypervisor version to create the mapping for. Use 'default' for default versions")
@Parameter(name = ApiConstants.HYPERVISOR_VERSION, type = CommandType.STRING, required = true, description = "Hypervisor version to create the mapping. Use 'default' for default versions. Please check hypervisor capabilities for correct version")
private String hypervisorVersion;
@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 for the correct guest os mapping name in the provided hypervisor (supports VMware and XenServer only. At least one hypervisor host with the version specified must be available. Default version will not work.)", since = "4.19.0")
private Boolean osMappingCheckEnabled;
@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.19.0")
private Boolean forced;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -81,6 +88,14 @@ public class AddGuestOsMappingCmd extends BaseAsyncCreateCmd {
return osNameForHypervisor;
}
public Boolean getOsMappingCheckEnabled() {
return BooleanUtils.toBooleanDefaultIfNull(osMappingCheckEnabled, false);
}
public boolean isForced() {
return BooleanUtils.toBooleanDefaultIfNull(forced, false);
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -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.19.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();
}
}

View File

@ -48,6 +48,12 @@ public class ListGuestOsMappingCmd extends BaseListCmd {
@Parameter(name = ApiConstants.OS_TYPE_ID, type = CommandType.UUID, entityType = GuestOSResponse.class, required = false, description = "list mapping by Guest OS Type UUID")
private Long osTypeId;
@Parameter(name = ApiConstants.OS_DISPLAY_NAME, type = CommandType.STRING, required = false, description = "list Guest OS mapping by OS display name")
private String osDisplayName;
@Parameter(name = ApiConstants.OS_NAME_FOR_HYPERVISOR, type = CommandType.STRING, required = false, description = "list Guest OS mapping by OS mapping name with hypervisor")
private String osNameForHypervisor;
@Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, required = false, description = "list Guest OS mapping by hypervisor")
private String hypervisor;
@ -66,6 +72,14 @@ public class ListGuestOsMappingCmd extends BaseListCmd {
return osTypeId;
}
public String getOsDisplayName() {
return osDisplayName;
}
public String getOsNameForHypervisor() {
return osNameForHypervisor;
}
public String getHypervisor() {
return hypervisor;
}

View File

@ -16,6 +16,7 @@
// under the License.
package org.apache.cloudstack.api.command.admin.guest;
import org.apache.commons.collections.MapUtils;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
@ -53,7 +54,7 @@ public class UpdateGuestOsCmd extends BaseAsyncCmd {
@Parameter(name = ApiConstants.OS_DISPLAY_NAME, type = CommandType.STRING, required = true, description = "Unique display name for Guest OS")
private String osDisplayName;
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, required = true, description = "Map of (key/value pairs)")
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, required = false, description = "Map of (key/value pairs)")
private Map details;
@ -71,7 +72,7 @@ public class UpdateGuestOsCmd extends BaseAsyncCmd {
public Map getDetails() {
Map<String, String> detailsMap = new HashMap<String, String>();;
if (!details.isEmpty()) {
if (MapUtils.isNotEmpty(detailsMap)) {
Collection<?> servicesCollection = details.values();
Iterator<?> iter = servicesCollection.iterator();
while (iter.hasNext()) {

View File

@ -16,6 +16,7 @@
// under the License.
package org.apache.cloudstack.api.command.admin.guest;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
@ -47,6 +48,9 @@ public class UpdateGuestOsMappingCmd extends BaseAsyncCmd {
@Parameter(name = ApiConstants.OS_NAME_FOR_HYPERVISOR, type = CommandType.STRING, required = true, description = "Hypervisor specific name for this Guest OS")
private String osNameForHypervisor;
@Parameter(name = ApiConstants.OS_MAPPING_CHECK_ENABLED, type = CommandType.BOOLEAN, required = false, description = "When set to true, checks for the correct guest os mapping name in the provided hypervisor (supports VMware and XenServer only. At least one hypervisor host with the version specified must be available. Default version will not work.)", since = "4.19.0")
private Boolean osMappingCheckEnabled;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -59,6 +63,10 @@ public class UpdateGuestOsMappingCmd extends BaseAsyncCmd {
return osNameForHypervisor;
}
public Boolean getOsMappingCheckEnabled() {
return BooleanUtils.toBooleanDefaultIfNull(osMappingCheckEnabled, false);
}
@Override
public void execute() {
GuestOSHypervisor guestOsMapping = _mgr.updateGuestOsMapping(this);

View File

@ -35,13 +35,25 @@ public class GuestOSResponse extends BaseResponse {
@Param(description = "the ID of the OS category")
private String osCategoryId;
@SerializedName(ApiConstants.OS_CATEGORY_NAME)
@Param(description = "the name of the OS category")
private String osCategoryName;
@SerializedName(ApiConstants.NAME)
@Param(description = "the name of the OS type")
private String name;
/**
* @deprecated description, as name is the correct interpretation and is needed for UI forms
*/
@Deprecated(since = "4.19")
@SerializedName(ApiConstants.DESCRIPTION)
@Param(description = "the name/description of the OS type")
private String description;
@SerializedName(ApiConstants.IS_USER_DEFINED)
@Param(description = "is the guest OS user defined")
private Boolean isUserDefined;
private String isUserDefined;
public String getId() {
return id;
@ -59,6 +71,22 @@ public class GuestOSResponse extends BaseResponse {
this.osCategoryId = osCategoryId;
}
public String getOsCategoryName() {
return osCategoryName;
}
public void setOsCategoryName(String osCategoryName) {
this.osCategoryName = osCategoryName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
@ -67,11 +95,11 @@ public class GuestOSResponse extends BaseResponse {
this.description = description;
}
public Boolean getIsUserDefined() {
public String getIsUserDefined() {
return isUserDefined;
}
public void setIsUserDefined(Boolean isUserDefined) {
public void setIsUserDefined(String isUserDefined) {
this.isUserDefined = isUserDefined;
}

View File

@ -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_OS_LIST)
@Param(description = "the guest OS list of the hypervisor", responseObject = HypervisorGuestOsResponse.class)
private List<HypervisorGuestOsResponse> guestOSList;
@SerializedName(ApiConstants.GUEST_OS_COUNT)
@Param(description = "the guest OS count of the hypervisor")
private Integer guestOSCount;
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> getGuestOSList() {
return guestOSList;
}
public void setGuestOSList(List<HypervisorGuestOsResponse> guestOSList) {
this.guestOSList = guestOSList;
}
public Integer getGuestOSCount() {
return guestOSCount;
}
public void setGuestOSCount(Integer guestOSCount) {
this.guestOSCount = guestOSCount;
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,38 @@
//
// 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 CheckGuestOsMappingAnswer extends Answer {
protected CheckGuestOsMappingAnswer() {
}
public CheckGuestOsMappingAnswer(CheckGuestOsMappingCommand cmd) {
super(cmd, true, null);
}
public CheckGuestOsMappingAnswer(CheckGuestOsMappingCommand cmd, String details) {
super(cmd, false, details);
}
public CheckGuestOsMappingAnswer(CheckGuestOsMappingCommand cmd, Throwable th) {
super(cmd, false, th.getMessage());
}
}

View File

@ -0,0 +1,65 @@
//
// 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.Objects;
public class CheckGuestOsMappingCommand extends Command {
String guestOsName;
String guestOsHypervisorMappingName;
String hypervisorVersion;
public CheckGuestOsMappingCommand() {
super();
}
public CheckGuestOsMappingCommand(String guestOsName, String guestOsHypervisorMappingName, String hypervisorVersion) {
super();
this.guestOsName = guestOsName;
this.guestOsHypervisorMappingName = guestOsHypervisorMappingName;
this.hypervisorVersion = hypervisorVersion;
}
@Override
public boolean executeInSequence() {
return false;
}
public String getGuestOsName() {
return guestOsName;
}
public String getGuestOsHypervisorMappingName() {
return guestOsHypervisorMappingName;
}
public String getHypervisorVersion() {
return hypervisorVersion;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
CheckGuestOsMappingCommand that = (CheckGuestOsMappingCommand) o;
return Objects.equals(guestOsName, that.guestOsName) && Objects.equals(guestOsHypervisorMappingName, that.guestOsHypervisorMappingName) && Objects.equals(hypervisorVersion, that.hypervisorVersion);
}
}

View File

@ -0,0 +1,58 @@
//
// 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 java.util.Objects;
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;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
GetHypervisorGuestOsNamesAnswer that = (GetHypervisorGuestOsNamesAnswer) o;
return Objects.equals(hypervisorGuestOsNames, that.hypervisorGuestOsNames);
}
}

View File

@ -0,0 +1,53 @@
//
// 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.Objects;
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;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
GetHypervisorGuestOsNamesCommand that = (GetHypervisorGuestOsNamesCommand) o;
return Objects.equals(keyword, that.keyword);
}
}

View File

@ -0,0 +1,66 @@
//
// 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 com.cloud.utils.Pair;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class GetHypervisorGuestOsNamesAnswerTest {
@Test
public void testGuestOsMappingAnswerSuccess() {
List<Pair<String, String>> hypervisorGuestOsNames = new ArrayList<>();
hypervisorGuestOsNames.add(new Pair<>("centos", "centos"));
GetHypervisorGuestOsNamesCommand cmd = new GetHypervisorGuestOsNamesCommand();
GetHypervisorGuestOsNamesAnswer answer = new GetHypervisorGuestOsNamesAnswer(cmd, hypervisorGuestOsNames);
List<Pair<String, String>> resultOsNames = answer.getHypervisorGuestOsNames();
Assert.assertEquals("centos", resultOsNames.get(0).first());
assertTrue(answer.getResult());
}
@Test
public void testGuestOsMappingAnswerFailure1() {
Throwable th = Mockito.mock(Throwable.class);
Mockito.when(th.getMessage()).thenReturn("failure");
GetHypervisorGuestOsNamesCommand cmd = new GetHypervisorGuestOsNamesCommand();
GetHypervisorGuestOsNamesAnswer answer = new GetHypervisorGuestOsNamesAnswer(cmd, th);
Assert.assertEquals("failure", answer.getDetails());
assertFalse(answer.getResult());
}
@Test
public void testGuestOsMappingAnswerFailure2() {
GetHypervisorGuestOsNamesCommand cmd = new GetHypervisorGuestOsNamesCommand();
GetHypervisorGuestOsNamesAnswer answer = new GetHypervisorGuestOsNamesAnswer(cmd, "failure");
Assert.assertEquals("failure", answer.getDetails());
assertFalse(answer.getResult());
}
}

View File

@ -0,0 +1,40 @@
//
// 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 static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import org.junit.Test;
public class GetHypervisorGuestOsNamesCommandTest {
@Test
public void testExecuteInSequence() {
GetHypervisorGuestOsNamesCommand cmd = new GetHypervisorGuestOsNamesCommand();
assertFalse(cmd.executeInSequence());
}
@Test
public void testKeyword() {
GetHypervisorGuestOsNamesCommand cmd = new GetHypervisorGuestOsNamesCommand("centos");
assertEquals("centos", cmd.getKeyword());
}
}

View File

@ -0,0 +1,66 @@
//
// 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.agent.test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import com.cloud.agent.api.CheckGuestOsMappingAnswer;
import com.cloud.agent.api.CheckGuestOsMappingCommand;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
public class CheckGuestOsMappingAnswerTest {
CheckGuestOsMappingCommand cmd = new CheckGuestOsMappingCommand("CentOS 7.2", "centos64Guest", "6.0");
CheckGuestOsMappingAnswer answer = new CheckGuestOsMappingAnswer(cmd);
@Test
public void testGetResult() {
boolean b = answer.getResult();
assertTrue(b);
}
@Test
public void testExecuteInSequence() {
boolean b = answer.executeInSequence();
assertFalse(b);
}
@Test
public void testGuestOsMappingAnswerDetails() {
CheckGuestOsMappingCommand cmd = new CheckGuestOsMappingCommand("CentOS 7.2", "centos64Guest", "6.0");
CheckGuestOsMappingAnswer answer = new CheckGuestOsMappingAnswer(cmd, "details");
String details = answer.getDetails();
Assert.assertEquals("details", details);
}
@Test
public void testGuestOsMappingAnswerFailure() {
Throwable th = Mockito.mock(Throwable.class);
Mockito.when(th.getMessage()).thenReturn("Failure");
CheckGuestOsMappingCommand cmd = new CheckGuestOsMappingCommand("CentOS 7.2", "centos64Guest", "6.0");
CheckGuestOsMappingAnswer answer = new CheckGuestOsMappingAnswer(cmd, th);
assertFalse(answer.getResult());
Assert.assertEquals("Failure", answer.getDetails());
}
}

View File

@ -0,0 +1,46 @@
//
// 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.agent.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import com.cloud.agent.api.CheckGuestOsMappingCommand;
import org.junit.Test;
import com.cloud.agent.api.AgentControlCommand;
public class CheckGuestOsMappingCommandTest {
@Test
public void testExecuteInSequence() {
CheckGuestOsMappingCommand cmd = new CheckGuestOsMappingCommand();
boolean b = cmd.executeInSequence();
assertFalse(b);
}
@Test
public void testCommandParams() {
CheckGuestOsMappingCommand cmd = new CheckGuestOsMappingCommand("CentOS 7.2", "centos64Guest", "6.0");
assertEquals("CentOS 7.2", cmd.getGuestOsName());
assertEquals("centos64Guest", cmd.getGuestOsHypervisorMappingName());
assertEquals("6.0", cmd.getHypervisorVersion());
}
}

View File

@ -141,6 +141,8 @@ public interface HostDao extends GenericDao<HostVO, Long>, StateDao<Status, Stat
HostVO findByName(String name);
HostVO findHostByHypervisorTypeAndVersion(HypervisorType hypervisorType, String hypervisorVersion);
List<HostVO> listHostsWithActiveVMs(long offeringId);
/**

View File

@ -116,6 +116,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
protected SearchBuilder<HostVO> ResourceStateSearch;
protected SearchBuilder<HostVO> NameLikeSearch;
protected SearchBuilder<HostVO> NameSearch;
protected SearchBuilder<HostVO> hostHypervisorTypeAndVersionSearch;
protected SearchBuilder<HostVO> SequenceSearch;
protected SearchBuilder<HostVO> DirectlyConnectedSearch;
protected SearchBuilder<HostVO> UnmanagedDirectConnectSearch;
@ -311,6 +312,13 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
NameSearch.and("name", NameSearch.entity().getName(), SearchCriteria.Op.EQ);
NameSearch.done();
hostHypervisorTypeAndVersionSearch = createSearchBuilder();
hostHypervisorTypeAndVersionSearch.and("hypervisorType", hostHypervisorTypeAndVersionSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ);
hostHypervisorTypeAndVersionSearch.and("hypervisorVersion", hostHypervisorTypeAndVersionSearch.entity().getHypervisorVersion(), SearchCriteria.Op.EQ);
hostHypervisorTypeAndVersionSearch.and("type", hostHypervisorTypeAndVersionSearch.entity().getType(), SearchCriteria.Op.EQ);
hostHypervisorTypeAndVersionSearch.and("status", hostHypervisorTypeAndVersionSearch.entity().getStatus(), SearchCriteria.Op.EQ);
hostHypervisorTypeAndVersionSearch.done();
SequenceSearch = createSearchBuilder();
SequenceSearch.and("id", SequenceSearch.entity().getId(), SearchCriteria.Op.EQ);
// SequenceSearch.addRetrieve("sequence", SequenceSearch.entity().getSequence());
@ -1420,6 +1428,16 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
return findOneBy(sc);
}
@Override
public HostVO findHostByHypervisorTypeAndVersion(HypervisorType hypervisorType, String hypervisorVersion) {
SearchCriteria<HostVO> sc = hostHypervisorTypeAndVersionSearch.create();
sc.setParameters("hypervisorType", hypervisorType);
sc.setParameters("hypervisorVersion", hypervisorVersion);
sc.setParameters("type", Host.Type.Routing);
sc.setParameters("status", Status.Up);
return findOneBy(sc);
}
private ResultSet executeSqlGetResultsetForMethodFindHostInZoneToExecuteCommand(HypervisorType hypervisorType, long zoneId, TransactionLegacy tx, String sql) throws SQLException {
PreparedStatement pstmt = tx.prepareAutoCloseStatement(sql);
pstmt.setString(1, Objects.toString(hypervisorType));

View File

@ -19,9 +19,12 @@ package com.cloud.storage.dao;
import com.cloud.storage.GuestOSVO;
import com.cloud.utils.db.GenericDao;
import java.util.List;
public interface GuestOSDao extends GenericDao<GuestOSVO, Long> {
GuestOSVO listByDisplayName(String displayName);
List<GuestOSVO> listLikeDisplayName(String displayName);
GuestOSVO findByCategoryIdAndDisplayNameOrderByCreatedDesc(long categoryId, String displayName);
}

View File

@ -33,12 +33,19 @@ public class GuestOSDaoImpl extends GenericDaoBase<GuestOSVO, Long> implements G
protected final SearchBuilder<GuestOSVO> Search;
protected final SearchBuilder<GuestOSVO> displayNameSearch;
public GuestOSDaoImpl() {
Search = createSearchBuilder();
Search.and("category_id", Search.entity().getCategoryId(), SearchCriteria.Op.EQ);
Search.and("display_name", Search.entity().getDisplayName(), SearchCriteria.Op.EQ);
Search.and("is_user_defined", Search.entity().getIsUserDefined(), SearchCriteria.Op.EQ);
Search.done();
displayNameSearch = createSearchBuilder();
displayNameSearch.and("display_name", displayNameSearch.entity().getDisplayName(), SearchCriteria.Op.LIKE);
displayNameSearch.done();
}
@Override
@ -48,6 +55,13 @@ public class GuestOSDaoImpl extends GenericDaoBase<GuestOSVO, Long> implements G
return findOneBy(sc);
}
@Override
public List<GuestOSVO> listLikeDisplayName(String displayName) {
SearchCriteria<GuestOSVO> sc = displayNameSearch.create();
sc.setParameters("display_name", "%" + displayName + "%");
return listBy(sc);
}
@Override
public GuestOSVO findByCategoryIdAndDisplayNameOrderByCreatedDesc(long categoryId, String displayName) {
SearchCriteria<GuestOSVO> sc = Search.create();
@ -56,9 +70,9 @@ public class GuestOSDaoImpl extends GenericDaoBase<GuestOSVO, Long> implements G
sc.setParameters("is_user_defined", false);
Filter orderByFilter = new Filter(GuestOSVO.class, "created", false, null, 1L);
List<GuestOSVO> guestOSes = listBy(sc, orderByFilter);
if (CollectionUtils.isNotEmpty(guestOSes)) {
return guestOSes.get(0);
List<GuestOSVO> guestOSlist = listBy(sc, orderByFilter);
if (CollectionUtils.isNotEmpty(guestOSlist)) {
return guestOSlist.get(0);
}
return null;
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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;
@ -94,7 +96,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);
@ -116,7 +118,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());
@ -198,4 +200,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.isAnyBlank(srcVersion, 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;
}
}

View File

@ -0,0 +1,84 @@
// 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.upgrade;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.storage.GuestOSHypervisorVO;
import com.cloud.storage.dao.GuestOSHypervisorDao;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.powermock.modules.junit4.PowerMockRunner;
import java.util.ArrayList;
import java.util.List;
@RunWith(PowerMockRunner.class)
public class GuestOsMapperTest {
@Spy
@InjectMocks
GuestOsMapper guestOsMapper = new GuestOsMapper();
@Mock
GuestOSHypervisorDao guestOSHypervisorDao;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testCopyGuestOSHypervisorMappingsFailures() {
boolean result = guestOsMapper.copyGuestOSHypervisorMappings(Hypervisor.HypervisorType.Any, "6.0", "7.0");
Assert.assertFalse(result);
result = guestOsMapper.copyGuestOSHypervisorMappings(Hypervisor.HypervisorType.None, "6.0", "7.0");
Assert.assertFalse(result);
result = guestOsMapper.copyGuestOSHypervisorMappings(Hypervisor.HypervisorType.XenServer, "", "7.0");
Assert.assertFalse(result);
result = guestOsMapper.copyGuestOSHypervisorMappings(Hypervisor.HypervisorType.XenServer, "6.0", "");
Assert.assertFalse(result);
Mockito.when(guestOSHypervisorDao.listByHypervisorTypeAndVersion(Mockito.anyString(), Mockito.anyString())).thenReturn(null);
result = guestOsMapper.copyGuestOSHypervisorMappings(Hypervisor.HypervisorType.XenServer, "6.0", "7.0");
Assert.assertFalse(result);
}
@Test
public void testCopyGuestOSHypervisorMappingsSuccess() {
GuestOSHypervisorVO guestOSHypervisorVO = Mockito.mock(GuestOSHypervisorVO.class);
List<GuestOSHypervisorVO> guestOSHypervisorVOS = new ArrayList<>();
guestOSHypervisorVOS.add(guestOSHypervisorVO);
Mockito.when(guestOSHypervisorDao.listByHypervisorTypeAndVersion(Mockito.anyString(), Mockito.anyString())).thenReturn(guestOSHypervisorVOS);
Mockito.when(guestOSHypervisorVO.getGuestOsName()).thenReturn("centos");
GuestOSHypervisorVO guestOsMapping = Mockito.mock(GuestOSHypervisorVO.class);
Mockito.when(guestOSHypervisorDao.persist(guestOsMapping)).thenReturn(guestOsMapping);
boolean result = guestOsMapper.copyGuestOSHypervisorMappings(Hypervisor.HypervisorType.XenServer, "6.0", "7.0");
Assert.assertTrue(result);
}
}

View File

@ -47,6 +47,10 @@ import java.util.stream.Collectors;
import javax.naming.ConfigurationException;
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;
@ -307,6 +311,7 @@ import com.vmware.vim25.DistributedVirtualSwitchPortCriteria;
import com.vmware.vim25.DynamicProperty;
import com.vmware.vim25.GuestInfo;
import com.vmware.vim25.GuestNicInfo;
import com.vmware.vim25.GuestOsDescriptor;
import com.vmware.vim25.HostCapability;
import com.vmware.vim25.HostConfigInfo;
import com.vmware.vim25.HostFileSystemMountInfo;
@ -605,6 +610,10 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
answer = execute((GetVmVncTicketCommand) cmd);
} else if (clz == GetAutoScaleMetricsCommand.class) {
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);
}
@ -7723,6 +7732,60 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
}
}
protected CheckGuestOsMappingAnswer execute(CheckGuestOsMappingCommand cmd) {
String guestOsName = cmd.getGuestOsName();
String guestOsMappingName = cmd.getGuestOsHypervisorMappingName();
s_logger.info("Checking guest os mapping name: " + guestOsMappingName + " for the guest os: " + guestOsName + " in the hypervisor");
try {
VmwareContext context = getServiceContext();
VmwareHypervisorHost hyperHost = getHyperHost(context);
GuestOsDescriptor guestOsDescriptor = hyperHost.getGuestOsDescriptor(guestOsMappingName);
if (guestOsDescriptor == null) {
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)) {
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);
return new CheckGuestOsMappingAnswer(cmd, e.getLocalizedMessage());
}
}
protected 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) {
String osDescriptorFullName = guestOsDescriptor.getFullName();
String osDescriptorId = guestOsDescriptor.getId();
if (StringUtils.isNotBlank(keyword)) {
if (osDescriptorFullName.toLowerCase().contains(keyword.toLowerCase()) || osDescriptorId.toLowerCase().contains(keyword.toLowerCase())) {
Pair<String, String> hypervisorGuestOs = new Pair<>(osDescriptorFullName, osDescriptorId);
hypervisorGuestOsNames.add(hypervisorGuestOs);
}
} else {
Pair<String, String> hypervisorGuestOs = new Pair<>(osDescriptorFullName, osDescriptorId);
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) {

View File

@ -53,6 +53,10 @@ import org.powermock.modules.junit4.PowerMockRunner;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
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.ScaleVmAnswer;
import com.cloud.agent.api.ScaleVmCommand;
import com.cloud.agent.api.routing.GetAutoScaleMetricsAnswer;
@ -79,6 +83,7 @@ import com.cloud.storage.resource.VmwareStorageSubsystemCommandHandler;
import com.cloud.utils.ExecutionResult;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.VmDetailConstants;
import com.vmware.vim25.GuestOsDescriptor;
import com.vmware.vim25.HostCapability;
import com.vmware.vim25.ManagedObjectReference;
import com.vmware.vim25.VimPortType;
@ -554,4 +559,102 @@ public class VmwareResourceTest {
assertEquals(1, stats.length);
assertEquals(lbStats[0], stats[0]);
}
@Test
public void testCheckGuestOsMappingCommandFailure() throws Exception {
CheckGuestOsMappingCommand cmd = Mockito.mock(CheckGuestOsMappingCommand.class);
when(cmd.getGuestOsName()).thenReturn("CentOS 7.2");
when(cmd.getGuestOsHypervisorMappingName()).thenReturn("centosWrongName");
when(_resource.getHyperHost(context, null)).thenReturn(hyperHost);
when(hyperHost.getGuestOsDescriptor("centosWrongName")).thenReturn(null);
CheckGuestOsMappingAnswer answer = _resource.execute(cmd);
assertFalse(answer.getResult());
}
@Test
public void testCheckGuestOsMappingCommandSuccess() throws Exception {
CheckGuestOsMappingCommand cmd = Mockito.mock(CheckGuestOsMappingCommand.class);
when(cmd.getGuestOsName()).thenReturn("CentOS 7.2");
when(cmd.getGuestOsHypervisorMappingName()).thenReturn("centos64Guest");
when(_resource.getHyperHost(context, null)).thenReturn(hyperHost);
GuestOsDescriptor guestOsDescriptor = Mockito.mock(GuestOsDescriptor.class);
when(hyperHost.getGuestOsDescriptor("centos64Guest")).thenReturn(guestOsDescriptor);
when(guestOsDescriptor.getFullName()).thenReturn("centos64Guest");
CheckGuestOsMappingAnswer answer = _resource.execute(cmd);
assertTrue(answer.getResult());
}
@Test
public void testCheckGuestOsMappingCommandException() {
CheckGuestOsMappingCommand cmd = Mockito.mock(CheckGuestOsMappingCommand.class);
when(cmd.getGuestOsName()).thenReturn("CentOS 7.2");
when(cmd.getGuestOsHypervisorMappingName()).thenReturn("centos64Guest");
when(_resource.getHyperHost(context, null)).thenReturn(null);
CheckGuestOsMappingAnswer answer = _resource.execute(cmd);
assertFalse(answer.getResult());
}
@Test
public void testGetHypervisorGuestOsNamesCommandFailure() throws Exception {
GetHypervisorGuestOsNamesCommand cmd = Mockito.mock(GetHypervisorGuestOsNamesCommand.class);
when(cmd.getKeyword()).thenReturn("CentOS");
when(_resource.getHyperHost(context, null)).thenReturn(hyperHost);
when(hyperHost.getGuestOsDescriptors()).thenReturn(null);
GetHypervisorGuestOsNamesAnswer answer = _resource.execute(cmd);
assertFalse(answer.getResult());
}
@Test
public void testGetHypervisorGuestOsNamesCommandSuccessWithKeyword() throws Exception {
GetHypervisorGuestOsNamesCommand cmd = Mockito.mock(GetHypervisorGuestOsNamesCommand.class);
when(cmd.getKeyword()).thenReturn("CentOS");
when(_resource.getHyperHost(context, null)).thenReturn(hyperHost);
GuestOsDescriptor guestOsDescriptor = Mockito.mock(GuestOsDescriptor.class);
when(guestOsDescriptor.getFullName()).thenReturn("centos64Guest");
when(guestOsDescriptor.getId()).thenReturn("centos64Guest");
List<GuestOsDescriptor> guestOsDescriptors = new ArrayList<>();
guestOsDescriptors.add(guestOsDescriptor);
when(hyperHost.getGuestOsDescriptors()).thenReturn(guestOsDescriptors);
GetHypervisorGuestOsNamesAnswer answer = _resource.execute(cmd);
assertTrue(answer.getResult());
assertEquals("centos64Guest", answer.getHypervisorGuestOsNames().get(0).first());
}
@Test
public void testGetHypervisorGuestOsNamesCommandSuccessWithoutKeyword() throws Exception {
GetHypervisorGuestOsNamesCommand cmd = Mockito.mock(GetHypervisorGuestOsNamesCommand.class);
when(_resource.getHyperHost(context, null)).thenReturn(hyperHost);
GuestOsDescriptor guestOsDescriptor = Mockito.mock(GuestOsDescriptor.class);
when(guestOsDescriptor.getFullName()).thenReturn("centos64Guest");
when(guestOsDescriptor.getId()).thenReturn("centos64Guest");
List<GuestOsDescriptor> guestOsDescriptors = new ArrayList<>();
guestOsDescriptors.add(guestOsDescriptor);
when(hyperHost.getGuestOsDescriptors()).thenReturn(guestOsDescriptors);
GetHypervisorGuestOsNamesAnswer answer = _resource.execute(cmd);
assertTrue(answer.getResult());
assertEquals("centos64Guest", answer.getHypervisorGuestOsNames().get(0).first());
}
@Test
public void testGetHypervisorGuestOsNamesCommandException() throws Exception {
GetHypervisorGuestOsNamesCommand cmd = Mockito.mock(GetHypervisorGuestOsNamesCommand.class);
when(cmd.getKeyword()).thenReturn("CentOS");
when(_resource.getHyperHost(context, null)).thenReturn(null);
GetHypervisorGuestOsNamesAnswer answer = _resource.execute(cmd);
assertFalse(answer.getResult());
}
}

View File

@ -0,0 +1,67 @@
//
// 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.Set;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CheckGuestOsMappingAnswer;
import com.cloud.agent.api.CheckGuestOsMappingCommand;
import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
import com.cloud.resource.CommandWrapper;
import com.cloud.resource.ResourceWrapper;
import com.xensource.xenapi.Connection;
import com.xensource.xenapi.VM;
@ResourceWrapper(handles = CheckGuestOsMappingCommand.class)
public final class CitrixCheckGuestOsMappingCommandWrapper extends CommandWrapper<CheckGuestOsMappingCommand, Answer, CitrixResourceBase> {
private static final Logger s_logger = Logger.getLogger(CitrixCheckGuestOsMappingCommandWrapper.class);
@Override
public Answer execute(final CheckGuestOsMappingCommand command, final CitrixResourceBase citrixResourceBase) {
final Connection conn = citrixResourceBase.getConnection();
String guestOsName = command.getGuestOsName();
String guestOsMappingName = command.getGuestOsHypervisorMappingName();
try {
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 (CollectionUtils.isEmpty(vms)) {
return new CheckGuestOsMappingAnswer(command, "Unable to match guest os mapping name: " + guestOsMappingName + " in the hypervisor");
}
for (VM vm : vms) {
if (vm != null && vm.getIsATemplate(conn) && guestOsMappingName.equalsIgnoreCase(vm.getNameLabel(conn))) {
if (guestOsName.equalsIgnoreCase(vm.getNameLabel(conn))) {
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, "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());
}
}
}

View File

@ -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 com.cloud.hypervisor.xenserver.resource.wrapper.xenbase;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.apache.commons.collections.CollectionUtils;
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 (CollectionUtils.isEmpty(vms)) {
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());
}
}
}

View File

@ -43,6 +43,7 @@ import org.apache.cloudstack.affinity.AffinityGroup;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
import org.apache.cloudstack.annotation.AnnotationService;
import org.apache.cloudstack.annotation.dao.AnnotationDao;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiConstants.DomainDetails;
import org.apache.cloudstack.api.ApiConstants.HostDetails;
import org.apache.cloudstack.api.ApiConstants.VMDetails;
@ -91,6 +92,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;
@ -3660,12 +3663,14 @@ public class ApiResponseHelper implements ResponseGenerator {
@Override
public GuestOSResponse createGuestOSResponse(GuestOS guestOS) {
GuestOSResponse response = new GuestOSResponse();
response.setName(guestOS.getDisplayName());
response.setDescription(guestOS.getDisplayName());
response.setId(guestOS.getUuid());
response.setIsUserDefined(guestOS.getIsUserDefined());
response.setIsUserDefined(String.valueOf(guestOS.getIsUserDefined()));
GuestOSCategoryVO category = ApiDBUtils.findGuestOsCategoryById(guestOS.getCategoryId());
if (category != null) {
response.setOsCategoryId(category.getUuid());
response.setOsCategoryName(category.getName());
}
response.setObjectName("ostype");
@ -3690,6 +3695,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.setGuestOSList(hypervisorGuestOsResponses);
response.setGuestOSCount(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(ApiConstants.GUEST_OS_LIST);
return hypervisorGuestOsResponse;
}
@Override
public SnapshotScheduleResponse createSnapshotScheduleResponse(SnapshotSchedule snapshotSchedule) {
SnapshotScheduleResponse response = new SnapshotScheduleResponse();

View File

@ -95,6 +95,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;
@ -620,8 +621,12 @@ import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.CheckGuestOsMappingAnswer;
import com.cloud.agent.api.CheckGuestOsMappingCommand;
import com.cloud.agent.api.GetVncPortAnswer;
import com.cloud.agent.api.GetVncPortCommand;
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;
@ -783,6 +788,7 @@ import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallbackNoReturn;
import com.cloud.utils.db.TransactionStatus;
import com.cloud.utils.db.UUIDManager;
import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.fsm.StateMachine2;
import com.cloud.utils.net.MacAddress;
@ -2634,6 +2640,17 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
if (id != null) {
sc.addAnd("id", SearchCriteria.Op.EQ, id);
} else {
GenericSearchBuilder<GuestOSVO, Long> sb = _guestOSDao.createSearchBuilder(Long.class);
sb.select(null, SearchCriteria.Func.MAX, sb.entity().getId());
sb.groupBy(sb.entity().getCategoryId(), sb.entity().getDisplayName());
sb.done();
final SearchCriteria<Long> scGuestOs = sb.create();
final List<Long> guestOSVOList = _guestOSDao.customSearch(scGuestOs, null);
if (CollectionUtils.isNotEmpty(guestOSVOList)) {
sc.addAnd("id", SearchCriteria.Op.IN, guestOSVOList.toArray());
}
}
if (osCategoryId != null) {
@ -2679,9 +2696,15 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
@Override
public Pair<List<? extends GuestOSHypervisor>, Integer> listGuestOSMappingByCriteria(final ListGuestOsMappingCmd cmd) {
final String guestOsId = "guestOsId";
final Filter searchFilter = new Filter(GuestOSHypervisorVO.class, "hypervisorType", true, cmd.getStartIndex(), cmd.getPageSizeVal());
searchFilter.addOrderBy(GuestOSHypervisorVO.class, "hypervisorVersion", false);
searchFilter.addOrderBy(GuestOSHypervisorVO.class, guestOsId, true);
searchFilter.addOrderBy(GuestOSHypervisorVO.class, "created", false);
final Long id = cmd.getId();
final Long osTypeId = cmd.getOsTypeId();
final String osDisplayName = cmd.getOsDisplayName();
final String osNameForHypervisor = cmd.getOsNameForHypervisor();
final String hypervisor = cmd.getHypervisor();
final String hypervisorVersion = cmd.getHypervisorVersion();
@ -2697,15 +2720,27 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
}
if (osTypeId != null) {
sc.addAnd("guestOsId", SearchCriteria.Op.EQ, osTypeId);
sc.addAnd(guestOsId, SearchCriteria.Op.EQ, osTypeId);
}
if (osNameForHypervisor != null) {
sc.addAnd("guestOsName", SearchCriteria.Op.LIKE, "%" + osNameForHypervisor + "%");
}
if (hypervisor != null) {
sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, hypervisor);
sc.addAnd("hypervisorType", SearchCriteria.Op.LIKE, "%" + hypervisor + "%");
}
if (hypervisorVersion != null) {
sc.addAnd("hypervisorVersion", SearchCriteria.Op.EQ, hypervisorVersion);
sc.addAnd("hypervisorVersion", SearchCriteria.Op.LIKE, "%" + hypervisorVersion + "%");
}
if (osDisplayName != null) {
List<GuestOSVO> guestOSVOS = _guestOSDao.listLikeDisplayName(osDisplayName);
if (CollectionUtils.isNotEmpty(guestOSVOS)) {
List<Long> guestOSids = guestOSVOS.stream().map(mo -> mo.getId()).collect(Collectors.toList());
sc.addAnd(guestOsId, SearchCriteria.Op.IN, guestOSids.toArray());
}
}
final Pair<List<GuestOSHypervisorVO>, Integer> result = _guestOSHypervisorDao.searchAndCount(sc, searchFilter);
@ -2723,7 +2758,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
final String osNameForHypervisor = cmd.getOsNameForHypervisor();
GuestOS guestOs = null;
if (osTypeId == null && (osStdName == null || osStdName.isEmpty())) {
if (osTypeId == null && StringUtils.isEmpty(osStdName)) {
throw new InvalidParameterValueException("Please specify either a guest OS name or UUID");
}
@ -2752,9 +2787,28 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
final GuestOSHypervisorVO duplicate = _guestOSHypervisorDao.findByOsIdAndHypervisorAndUserDefined(guestOs.getId(), hypervisorType.toString(), hypervisorVersion, true);
if (duplicate != null) {
throw new InvalidParameterValueException(
"Mapping from hypervisor : " + hypervisorType.toString() + ", version : " + hypervisorVersion + " and guest OS : " + guestOs.getDisplayName() + " already exists!");
if (!cmd.isForced()) {
throw new InvalidParameterValueException(
"Mapping from hypervisor : " + hypervisorType.toString() + ", version : " + hypervisorVersion + " and guest OS : " + guestOs.getDisplayName() + " already exists!");
}
if (Boolean.TRUE.equals(cmd.getOsMappingCheckEnabled())) {
checkGuestOSHypervisorMapping(hypervisorType, hypervisorVersion, guestOs.getDisplayName(), osNameForHypervisor);
}
final long guestOsId = duplicate.getId();
final GuestOSHypervisorVO guestOsHypervisor = _guestOSHypervisorDao.createForUpdate(guestOsId);
guestOsHypervisor.setGuestOsName(osNameForHypervisor);
if (_guestOSHypervisorDao.update(guestOsId, guestOsHypervisor)) {
return _guestOSHypervisorDao.findById(guestOsId);
}
return null;
}
if (Boolean.TRUE.equals(cmd.getOsMappingCheckEnabled())) {
checkGuestOSHypervisorMapping(hypervisorType, hypervisorVersion, guestOs.getDisplayName(), osNameForHypervisor);
}
final GuestOSHypervisorVO guestOsMapping = new GuestOSHypervisorVO();
guestOsMapping.setGuestOsId(guestOs.getId());
guestOsMapping.setGuestOsName(osNameForHypervisor);
@ -2762,7 +2816,24 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
guestOsMapping.setHypervisorVersion(hypervisorVersion);
guestOsMapping.setIsUserDefined(true);
return _guestOSHypervisorDao.persist(guestOsMapping);
}
private void checkGuestOSHypervisorMapping(HypervisorType hypervisorType, String hypervisorVersion, String guestOsName, String guestOsNameForHypervisor) {
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 %s hypervisor with version: %s exists, 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()) {
throw new CloudRuntimeException(String.format("Invalid hypervisor os mapping: %s for guest os: %s, hypervisor: %s and version: %s", guestOsNameForHypervisor, guestOsName, hypervisorType.toString(), hypervisorVersion));
}
}
private boolean canCheckGuestOsNameInHypervisor(HypervisorType hypervisorType) {
return (hypervisorType == HypervisorType.VMware || hypervisorType == HypervisorType.XenServer);
}
@Override
@ -2771,6 +2842,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 %s hypervisor with version: %s exists, 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 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)
@ -2892,6 +2982,14 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
throw new InvalidParameterValueException("Unable to modify system defined Guest OS mapping");
}
if (Boolean.TRUE.equals(cmd.getOsMappingCheckEnabled())) {
GuestOS guestOs = ApiDBUtils.findGuestOSById(guestOsHypervisorHandle.getGuestOsId());
if (guestOs == null) {
throw new InvalidParameterValueException("Unable to find the guest OS for the mapping");
}
checkGuestOSHypervisorMapping(HypervisorType.getType(guestOsHypervisorHandle.getHypervisorType()), guestOsHypervisorHandle.getHypervisorVersion(), guestOs.getDisplayName(), osNameForHypervisor);
}
final GuestOSHypervisorVO guestOsHypervisor = _guestOSHypervisorDao.createForUpdate(id);
guestOsHypervisor.setGuestOsName(osNameForHypervisor);
if (_guestOSHypervisorDao.update(id, guestOsHypervisor)) {
@ -3468,6 +3566,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);

View File

@ -0,0 +1,260 @@
# 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.
#All tests inherit from cloudstackTestCase
import unittest
from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.cloudstackAPI import listHosts
from marvin.cloudstackException import CloudstackAPIException
from marvin.lib.base import (VirtualMachine,
Account,
GuestOSCategory,
GuestOS,
GuestOsMapping,
NetworkOffering,
Network)
from marvin.lib.common import get_test_template, get_zone, list_virtual_machines
from marvin.lib.utils import (validateList, cleanup_resources)
from nose.plugins.attrib import attr
from marvin.codes import PASS,FAIL
class Services:
def __init__(self):
self.services = {
}
class TestGuestOS(cloudstackTestCase):
@classmethod
def setUpClass(cls):
super(TestGuestOS, cls)
cls.api_client = cls.testClient.getApiClient()
cls.services = Services().services
cls.hypervisor = cls.get_hypervisor_type()
@classmethod
def setUp(self):
self.apiclient = self.testClient.getApiClient()
#build cleanup list
self.cleanup = []
@classmethod
def tearDown(self):
try:
cleanup_resources(self.apiclient, self.cleanup)
except Exception as e:
self.debug("Warning! Exception in tearDown: %s" % e)
@classmethod
def get_hypervisor_type(cls):
"""Return the hypervisor available in setup"""
cmd = listHosts.listHostsCmd()
cmd.type = 'Routing'
cmd.listall = True
hosts = cls.api_client.listHosts(cmd)
hosts_list_validation_result = validateList(hosts)
assert hosts_list_validation_result[0] == PASS, "host list validation failed"
return hosts_list_validation_result[1]
@attr(tags=['advanced', 'simulator', 'basic', 'sg'], required_hardware=False)
def test_CRUD_operations_guest_OS(self):
"""Test add, list, update operations on guest OS
1. Add a guest OS
2. List the guest OS
3. Delete the added guest OS
"""
list_os_categories = GuestOSCategory.list(self.apiclient, name="CentOS", listall=True)
self.assertNotEqual(
len(list_os_categories),
0,
"List OS categories was empty"
)
os_category = list_os_categories[0]
self.guestos1 = GuestOS.add(
self.apiclient,
osdisplayname="testCentOS",
oscategoryid=os_category.id
)
list_guestos = GuestOS.list(self.apiclient, id=self.guestos1.id, listall=True)
self.assertNotEqual(
len(list_guestos),
0,
"List guest OS was empty"
)
guestos = list_guestos[0]
self.assertEqual(
guestos.id,
self.guestos1.id,
"Guest os ids do not match"
)
GuestOS.remove(
self.apiclient,
id=self.guestos1.id
)
@attr(tags=['advanced', 'simulator', 'basic', 'sg'], required_hardware=False)
def test_CRUD_operations_guest_OS_mapping(self):
"""Test add, list, update operations on guest OS mapping
1. Add a guest OS
2. Add a guest OS mapping
3. Delete the added guest OS and mappings
"""
list_os_categories = GuestOSCategory.list(self.apiclient, name="CentOS", listall=True)
os_category = list_os_categories[0]
self.guestos1 = GuestOS.add(
self.apiclient,
osdisplayname="testCentOS",
oscategoryid=os_category.id
)
if self.hypervisor.hypervisor.lower() not in ["xenserver", "vmware"]:
raise unittest.SkipTest("OS name check with hypervisor is supported only on XenServer and VMware")
self.guestosmapping1 = GuestOsMapping.add(
self.apiclient,
ostypeid=self.guestos1.id,
hypervisor=self.hypervisor.hypervisor,
hypervisorversion=self.hypervisor.hypervisorversion,
osnameforhypervisor="testOSMappingName"
)
list_guestos_mapping = GuestOsMapping.list(self.apiclient, id=self.guestosmapping1.id, listall=True)
self.assertNotEqual(
len(list_guestos_mapping),
0,
"List guest OS mapping was empty"
)
guestosmapping = list_guestos_mapping[0]
self.assertEqual(
guestosmapping.id,
self.guestosmapping1.id,
"Guest os mapping ids do not match"
)
GuestOsMapping.remove(
self.apiclient,
id=self.guestosmapping1.id
)
GuestOS.remove(
self.apiclient,
id=self.guestos1.id
)
@attr(tags=['advanced', 'simulator', 'basic', 'sg'], required_hardware=False)
def test_guest_OS_mapping_check_with_hypervisor(self):
"""Test add, list, update operations on guest OS mapping
1. Add a guest OS
2. Add a guest OS mapping with osmappingcheckenabled true
3. Delete the added guest OS and mappings
"""
list_os_categories = GuestOSCategory.list(self.apiclient, name="CentOS", listall=True)
os_category = list_os_categories[0]
self.guestos1 = GuestOS.add(
self.apiclient,
osdisplayname="testOSname1",
oscategoryid=os_category.id
)
if self.hypervisor.hypervisor.lower() not in ["xenserver", "vmware"]:
raise unittest.SkipTest("OS name check with hypervisor is supported only on XenServer and VMware")
if self.hypervisor.hypervisor.lower() == "xenserver":
testosname="Debian Squeeze 6.0 (32-bit)"
else:
testosname="debian4_64Guest"
self.guestosmapping1 = GuestOsMapping.add(
self.apiclient,
ostypeid=self.guestos1.id,
hypervisor=self.hypervisor.hypervisor,
hypervisorversion=self.hypervisor.hypervisorversion,
osnameforhypervisor=testosname,
osmappingcheckenabled=True
)
list_guestos_mapping = GuestOsMapping.list(self.apiclient, id=self.guestosmapping1.id, listall=True)
self.assertNotEqual(
len(list_guestos_mapping),
0,
"List guest OS mapping was empty"
)
guestosmapping = list_guestos_mapping[0]
self.assertEqual(
guestosmapping.id,
self.guestosmapping1.id,
"Guest os mapping ids do not match"
)
GuestOsMapping.remove(
self.apiclient,
id=self.guestosmapping1.id
)
GuestOS.remove(
self.apiclient,
id=self.guestos1.id
)
@attr(tags=['advanced', 'simulator', 'basic', 'sg'], required_hardware=False)
def test_guest_OS_mapping_check_with_hypervisor_failure(self):
"""Test add, list, update operations on guest OS mapping
1. Add a guest OS
2. Add a guest OS mapping with osmappingcheckenabled true
3. Delete the added guest OS and mappings
"""
list_os_categories = GuestOSCategory.list(self.apiclient, name="CentOS", listall=True)
os_category = list_os_categories[0]
self.guestos1 = GuestOS.add(
self.apiclient,
osdisplayname="testOSname2",
oscategoryid=os_category.id
)
if self.hypervisor.hypervisor.lower() not in ["xenserver", "vmware"]:
raise unittest.SkipTest("OS name check with hypervisor is supported only on XenServer and VMware")
testosname = "incorrectOSname"
try:
self.guestosmapping1 = GuestOsMapping.add(
self.apiclient,
ostypeid=self.guestos1.id,
hypervisor=self.hypervisor.hypervisor,
hypervisorversion=self.hypervisor.hypervisorversion,
osnameforhypervisor=testosname,
osmappingcheckenabled=True
)
GuestOsMapping.remove(
self.apiclient,
id=self.guestosmapping1.id
)
self.fail("Since os mapping name is wrong, this API should fail")
except CloudstackAPIException as e:
self.debug("Addition guest OS mapping failed as expected %s " % e)
GuestOS.remove(
self.apiclient,
id=self.guestos1.id
)
return

View File

@ -6522,6 +6522,145 @@ class PolicyRule:
cmd.ruleuuid = ruleuuid
return apiclient.removeTungstenFabricPolicyRule(cmd)
class GuestOSCategory:
"""Manage Guest OS Categories"""
def __init__(self, items, services):
self.__dict__.update(items)
@classmethod
def list(cls, apiclient, id=None, name=None, **kwargs):
"""List all Guest OS categories"""
cmd = listOsCategories.listOsCategoriesCmd()
[setattr(cmd, k, v) for k, v in list(kwargs.items())]
if 'account' in list(kwargs.keys()) and 'domainid' in list(kwargs.keys()):
cmd.listall = True
if id is not None:
cmd.id = id
if name is not None:
cmd.name = name
return (apiclient.listOsCategories(cmd))
class GuestOS:
"""Manage Guest OS"""
def __init__(self, items, services):
self.__dict__.update(items)
@classmethod
def add(cls, apiclient, osdisplayname=None,
oscategoryid=None, name=None, details=None):
"""Add Guest OS"""
cmd = addGuestOs.addGuestOsCmd()
cmd.osdisplayname = osdisplayname
cmd.oscategoryid = oscategoryid
if name is not None:
cmd.name = name
if details is not None:
cmd.details = details
return (apiclient.addGuestOs(cmd))
@classmethod
def remove(cls, apiclient, id):
"""Remove Guest OS"""
cmd = removeGuestOs.removeGuestOsCmd()
cmd.id = id
return apiclient.removeGuestOs(cmd)
@classmethod
def update(cls, apiclient, id, osdisplayname=None, details=None):
"""Update Guest OS"""
cmd = updateGuestOs.updateGuestOsCmd()
cmd.id = id
cmd.osdisplayname = osdisplayname
if details is not None:
cmd.details = details
return apiclient.updateGuestOs(cmd)
@classmethod
def list(cls, apiclient, id=None, oscategoryid=None, description=None, **kwargs):
"""List all Guest OS"""
cmd = listOsTypes.listOsTypesCmd()
[setattr(cmd, k, v) for k, v in list(kwargs.items())]
if 'account' in list(kwargs.keys()) and 'domainid' in list(kwargs.keys()):
cmd.listall = True
if id is not None:
cmd.id = id
if oscategoryid is not None:
cmd.oscategoryid = oscategoryid
if description is not None:
cmd.description = description
return (apiclient.listOsTypes(cmd))
class GuestOsMapping:
"""Manage Guest OS Mappings"""
def __init__(self, items, services):
self.__dict__.update(items)
@classmethod
def add(cls, apiclient, ostypeid=None,
hypervisor=None, hypervisorversion=None,
osnameforhypervisor=None, osmappingcheckenabled=None, forced=None):
"""Add Guest OS mapping"""
cmd = addGuestOsMapping.addGuestOsMappingCmd()
cmd.ostypeid = ostypeid
cmd.hypervisor = hypervisor
cmd.hypervisorversion = hypervisorversion
cmd.osnameforhypervisor = osnameforhypervisor
if osmappingcheckenabled is not None:
cmd.osmappingcheckenabled = osmappingcheckenabled
if forced is not None:
cmd.forced = forced
return (apiclient.addGuestOsMapping(cmd))
@classmethod
def remove(cls, apiclient, id):
"""Remove Guest OS mapping"""
cmd = removeGuestOsMapping.removeGuestOsMappingCmd()
cmd.id = id
return apiclient.removeGuestOsMapping(cmd)
@classmethod
def update(cls, apiclient, id, osnameforhypervisor=None, osmappingcheckenabled=None):
"""Update Guest OS mapping"""
cmd = updateGuestOsMapping.updateGuestOsMappingCmd()
cmd.id = id
cmd.osnameforhypervisor = osnameforhypervisor
if osmappingcheckenabled is not None:
cmd.osmappingcheckenabled = osmappingcheckenabled
return apiclient.updateGuestOsMapping(cmd)
@classmethod
def list(cls, apiclient, id=None, ostypeid=None, osdisplayname=None,
osnameforhypervisor=None, hypervisor=None, hypervisorversion=None, **kwargs):
"""List all Guest OS mappings"""
cmd = listGuestOsMapping.listGuestOsMappingCmd()
[setattr(cmd, k, v) for k, v in list(kwargs.items())]
if 'account' in list(kwargs.keys()) and 'domainid' in list(kwargs.keys()):
cmd.listall = True
if id is not None:
cmd.id = id
if ostypeid is not None:
cmd.ostypeid = ostypeid
if osdisplayname is not None:
cmd.osdisplayname = osdisplayname
if osnameforhypervisor is not None:
cmd.osnameforhypervisor = osnameforhypervisor
if hypervisor is not None:
cmd.hypervisor = hypervisor
if hypervisorversion is not None:
cmd.hypervisorversion = hypervisorversion
return (apiclient.listGuestOsMapping(cmd))
class VMSchedule:

View File

@ -288,6 +288,18 @@ def get_hypervisor_type(apiclient):
assert hosts_list_validation_result[0] == PASS, "host list validation failed"
return hosts_list_validation_result[1].hypervisor
def get_hypervisor_version(apiclient):
"""Return the hypervisor type of the hosts in setup"""
cmd = listHosts.listHostsCmd()
cmd.type = 'Routing'
cmd.listall = True
hosts = apiclient.listHosts(cmd)
hosts_list_validation_result = validateList(hosts)
assert hosts_list_validation_result[0] == PASS, "host list validation failed"
return hosts_list_validation_result[1].hypervisorversion
def is_snapshot_on_nfs(apiclient, dbconn, config, zoneid, snapshotid):
"""
Checks whether a snapshot with id (not UUID) `snapshotid` is present on the nfs storage

View File

@ -69,6 +69,8 @@
"label.action.delete.egress.firewall": "Delete egress firewall rule",
"label.action.delete.firewall": "Delete firewall rule",
"label.action.delete.interface.static.route": "Remove Tungsten Fabric interface static route",
"label.action.delete.guest.os": "Delete guest os",
"label.action.delete.guest.os.hypervisor.mapping": "Delete guest os hypervisor mapping",
"label.action.delete.ip.range": "Delete IP range",
"label.action.delete.iso": "Delete ISO",
"label.action.delete.load.balancer": "Delete load balancer rule",
@ -213,6 +215,8 @@
"label.add.firewall": "Add firewall rule",
"label.add.firewallrule": "Add Firewall Rule",
"label.add.guest.network": "Add guest network",
"label.add.guest.os": "Add guest os",
"label.add.guest.os.hypervisor.mapping": "Add guest os hypervisor mapping",
"label.add.host": "Add host",
"label.add.ingress.rule": "Add ingress rule",
"label.add.intermediate.certificate": "Add intermediate certificate",
@ -897,6 +901,8 @@
"label.guest.ip.range": "Guest IP range",
"label.guest.netmask": "Guest netmask",
"label.guest.networks": "Guest networks",
"label.guest.os": "Guest OS",
"label.guest.os.hypervisor.mappings": "Guest OS mappings",
"label.guest.start.ip": "Guest start IP",
"label.guest.traffic": "Guest traffic",
"label.guestcidraddress": "Guest CIDR",
@ -1080,6 +1086,7 @@
"label.issourcenat": "Source NAT",
"label.isstaticnat": "Static NAT",
"label.issystem": "Is system",
"label.isuserdefined": "User defined",
"label.isvolatile": "Volatile",
"label.items": "items",
"label.items.selected": "item(s) selected",
@ -1111,6 +1118,7 @@
"label.kubernetes.version.update": "Manage Kubernetes version",
"label.kubernetesversionid": "Kubernetes version",
"label.kubernetesversionname": "Kubernetes version",
"label.kvm": "KVM",
"label.kvmnetworklabel": "KVM traffic label",
"label.l2": "L2",
"label.l2gatewayserviceuuid": "L2 Gateway Service UUID",
@ -1174,6 +1182,7 @@
"label.logout": "Logout",
"label.lun": "LUN",
"label.lun.number": "LUN #",
"label.lxc": "LXC",
"label.lxcnetworklabel": "LXC traffic label",
"label.macaddress": "MAC address",
"label.macaddress.example": "The MAC address. Example: 01:23:45:67:89:ab",
@ -1387,7 +1396,12 @@
"label.operator.equal": "Equals to",
"label.optional": "Optional",
"label.order": "Order",
"label.oscategoryid": "OS preference",
"label.oscategoryid": "OS category",
"label.oscategoryname": "OS category name",
"label.osname": "OS name",
"label.osdisplayname": "OS name",
"label.osmappingcheckenabled": "Check OS name with hypervisor",
"label.osnameforhypervisor": "Hypervisor mapping name",
"label.ostypeid": "OS type",
"label.osdistribution": "OS distribution",
"label.ostypename": "OS type",
@ -1406,6 +1420,7 @@
"label.overridepublictraffic": "Override public-traffic",
"label.override.root.diskoffering": "Override root disk offering",
"label.ovf.properties": "vApp properties",
"label.ovm3": "OVM3",
"label.ovm3cluster": "Native Clustering",
"label.ovm3networklabel": "OVM3 traffic label",
"label.ovm3pool": "Native pooling",
@ -1741,6 +1756,7 @@
"label.select-view": "Select view",
"label.select.a.zone": "Select a zone",
"label.select.deployment.infrastructure": "Select deployment infrastructure",
"label.select.guest.os.type": "Please select the guest OS type",
"label.select.network": "Select Network",
"label.select.period": "Select period",
"label.select.project": "Select project",
@ -2142,6 +2158,7 @@
"label.vmscheduleactions": "Actions",
"label.vmstate": "VM state",
"label.vmtotal": "Total of VMs",
"label.vmware": "VMware",
"label.vmware.storage.policy": "VMWare storage policy",
"label.vmwaredcid": "VMware datacenter ID",
"label.vmwaredcname": "VMware datacenter name",
@ -2204,6 +2221,7 @@
"label.writeio": "Write (IO)",
"label.writethrough": "Write-through",
"label.xennetworklabel": "XenServer Traffic Label",
"label.xenserver": "XenServer",
"label.xenservertoolsversion61plus": "Original XS Version is 6.1+",
"label.yes": "Yes",
"label.yourinstance": "Your instance",
@ -2232,6 +2250,8 @@
"message.action.delete.external.firewall": "Please confirm that you would like to remove this external firewall. Warning: If you are planning to add back the same external firewall, you must reset usage data on the device.",
"message.action.delete.external.load.balancer": "Please confirm that you would like to remove this external load balancer. Warning: If you are planning to add back the same external load balancer, you must reset usage data on the device.",
"message.action.delete.ingress.rule": "Please confirm that you want to delete this ingress rule.",
"message.action.delete.guest.os": "Please confirm that you want to delete this guest os. System defined entry cannot be deleted.",
"message.action.delete.guest.os.hypervisor.mapping": "Please confirm that you want to delete this guest os hypervisor mapping. System defined entry cannot be deleted.",
"message.action.delete.instance.group": "Please confirm that you want to delete the instance group.",
"message.action.delete.interface.static.route": "Please confirm that you want to remove this interface Static Route?",
"message.action.delete.iso": "Please confirm that you want to delete this ISO.",

View File

@ -857,7 +857,7 @@ export default {
},
name () {
return this.resource.displayname || this.resource.name || this.resource.displaytext || this.resource.username ||
this.resource.ipaddress || this.resource.virtualmachinename || this.resource.templatetype
this.resource.ipaddress || this.resource.virtualmachinename || this.resource.osname || this.resource.osdisplayname || this.resource.templatetype
},
keypairs () {
if (!this.resource.keypairs) {

View File

@ -164,66 +164,81 @@
<template v-if="column.key === 'hypervisor'">
<span v-if="$route.name === 'hypervisorcapability'">
<router-link :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
</span>
<span v-else>{{ text }}</span>
</template>
<template v-if="column.key === 'state'">
<status v-if="$route.path.startsWith('/host')" :text="getHostState(record)" displayText />
<status v-else :text="text ? text : ''" displayText :styles="{ 'min-width': '80px' }" />
</template>
<template v-if="column.key === 'allocationstate'">
<status :text="text ? text : ''" displayText />
</template>
<template v-if="column.key === 'resourcestate'">
<status :text="text ? text : ''" displayText />
</template>
<template v-if="column.key === 'powerstate'">
<status :text="text ? text : ''" displayText />
</template>
<template v-if="column.key === 'agentstate'">
<status :text="text ? text : ''" displayText />
</template>
<template v-if="column.key === 'quotastate'">
<status :text="text ? text : ''" displayText />
</template>
<template v-if="column.key === 'vlan'">
<a href="javascript:;">
<router-link v-if="$route.path === '/guestvlans'" :to="{ path: '/guestvlans/' + record.id }">{{ text }}</router-link>
</a>
</template>
<template v-if="column.key === 'guestnetworkname'">
<router-link :to="{ path: '/guestnetwork/' + record.guestnetworkid }">{{ text }}</router-link>
</template>
<template v-if="column.key === 'associatednetworkname'">
<router-link :to="{ path: '/guestnetwork/' + record.associatednetworkid }">{{ text }}</router-link>
</template>
<template v-if="column.key === 'vpcname'">
<router-link :to="{ path: '/vpc/' + record.vpcid }">{{ text }}</router-link>
</template>
<template v-if="column.key === 'hostname'">
<router-link v-if="record.hostid" :to="{ path: '/host/' + record.hostid }">{{ text }}</router-link>
<router-link v-else-if="record.hostname" :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
<span v-else>{{ text }}</span>
</template>
<template v-if="column.key === 'storage'">
<router-link v-if="record.storageid" :to="{ path: '/storagepool/' + record.storageid }">{{ text }}</router-link>
<span v-else>{{ text }}</span>
</template>
<template v-for="(value, name) in thresholdMapping" :key="name">
<template v-if="column.key === name">
<span>
<span v-if="record[value.disable]" class="alert-disable-threshold">
{{ text }}
</span>
<span v-else-if="record[value.notification]" class="alert-notification-threshold">
{{ text }}
</span>
<span style="padding: 10%;" v-else>
{{ text }}
</span>
</span>
<span v-else-if="$route.name === 'guestoshypervisormapping'">
<QuickView
style="margin-left: 5px"
:actions="actions"
:resource="record"
:enabled="quickViewEnabled() && actions.length > 0 && columns && columns[0].dataIndex === 'hypervisor' "
@exec-action="$parent.execAction"/>
<router-link :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
</span>
<span v-else>{{ text }}</span>
</template>
<template v-if="column.key === 'osname'">
<span v-if="$route.name === 'guestos'">
<router-link :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
</span>
<span v-else>{{ text }}</span>
</template>
<template v-if="column.key === 'state'">
<status v-if="$route.path.startsWith('/host')" :text="getHostState(record)" displayText />
<status v-else :text="text ? text : ''" displayText :styles="{ 'min-width': '80px' }" />
</template>
<template v-if="column.key === 'allocationstate'">
<status :text="text ? text : ''" displayText />
</template>
<template v-if="column.key === 'resourcestate'">
<status :text="text ? text : ''" displayText />
</template>
<template v-if="column.key === 'powerstate'">
<status :text="text ? text : ''" displayText />
</template>
<template v-if="column.key === 'agentstate'">
<status :text="text ? text : ''" displayText />
</template>
<template v-if="column.key === 'quotastate'">
<status :text="text ? text : ''" displayText />
</template>
<template v-if="column.key === 'vlan'">
<a href="javascript:;">
<router-link v-if="$route.path === '/guestvlans'" :to="{ path: '/guestvlans/' + record.id }">{{ text }}</router-link>
</a>
</template>
<template v-if="column.key === 'guestnetworkname'">
<router-link :to="{ path: '/guestnetwork/' + record.guestnetworkid }">{{ text }}</router-link>
</template>
<template v-if="column.key === 'associatednetworkname'">
<router-link :to="{ path: '/guestnetwork/' + record.associatednetworkid }">{{ text }}</router-link>
</template>
<template v-if="column.key === 'vpcname'">
<router-link :to="{ path: '/vpc/' + record.vpcid }">{{ text }}</router-link>
</template>
<template v-if="column.key === 'hostname'">
<router-link v-if="record.hostid" :to="{ path: '/host/' + record.hostid }">{{ text }}</router-link>
<router-link v-else-if="record.hostname" :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
<span v-else>{{ text }}</span>
</template>
<template v-if="column.key === 'storage'">
<router-link v-if="record.storageid" :to="{ path: '/storagepool/' + record.storageid }">{{ text }}</router-link>
<span v-else>{{ text }}</span>
</template>
<template v-for="(value, name) in thresholdMapping" :key="name">
<template v-if="column.key === name">
<span>
<span v-if="record[value.disable]" class="alert-disable-threshold">
{{ text }}
</span>
</template>
<span v-else-if="record[value.notification]" class="alert-notification-threshold">
{{ text }}
</span>
<span style="padding: 10%;" v-else>
{{ text }}
</span>
</span>
</template>
</template>
<template v-if="column.key === 'level'">
<router-link :to="{ path: '/event/' + record.id }">{{ text }}</router-link>
@ -538,7 +553,7 @@ export default {
'/project', '/account',
'/zone', '/pod', '/cluster', '/host', '/storagepool', '/imagestore', '/systemvm', '/router', '/ilbvm', '/annotation',
'/computeoffering', '/systemoffering', '/diskoffering', '/backupoffering', '/networkoffering', '/vpcoffering',
'/tungstenfabric'].join('|'))
'/tungstenfabric', '/guestos', '/guestoshypervisormapping'].join('|'))
.test(this.$route.path)
},
enableGroupAction () {

View File

@ -40,7 +40,7 @@
</span>
</label>
<label v-else>
{{ resource.displayname || resource.name || resource.displaytext || resource.hostname || resource.username || resource.ipaddress || $route.params.id }}
{{ resource.displayname || resource.name || resource.displaytext || resource.hostname || resource.username || resource.ipaddress || resource.osname || resource.osdisplayname || $route.params.id }}
</label>
</span>
<span v-else>

View File

@ -87,6 +87,102 @@ export default {
args: ['maxguestslimit']
}
]
},
{
name: 'guestos',
title: 'label.guest.os',
docHelp: 'adminguide/guest_os.html#guest-os',
icon: 'laptop-outlined',
permission: ['listOsTypes', 'listOsCategories'],
columns: ['name', 'oscategoryname', 'isuserdefined'],
details: ['name', 'oscategoryname', 'isuserdefined'],
related: [{
name: 'guestoshypervisormapping',
title: 'label.guest.os.hypervisor.mappings',
param: 'ostypeid'
}],
actions: [
{
api: 'addGuestOs',
icon: 'plus-outlined',
label: 'label.add.guest.os',
listView: true,
dataView: false,
args: ['osdisplayname', 'oscategoryid'],
mapping: {
oscategoryid: {
api: 'listOsCategories',
params: (record) => { return { oscategoryid: record.id } }
}
}
},
{
api: 'updateGuestOs',
icon: 'edit-outlined',
label: 'label.edit',
dataView: true,
popup: true,
args: ['osdisplayname']
},
{
api: 'addGuestOsMapping',
icon: 'link-outlined',
label: 'label.add.guest.os.hypervisor.mapping',
dataView: true,
popup: true,
args: ['ostypeid', 'hypervisor', 'hypervisorversion', 'osnameforhypervisor', 'osmappingcheckenabled', 'forced'],
mapping: {
ostypeid: {
value: (record) => { return record.id }
}
}
},
{
api: 'removeGuestOs',
icon: 'delete-outlined',
label: 'label.action.delete.guest.os',
message: 'message.action.delete.guest.os',
dataView: true,
popup: true
}
]
},
{
name: 'guestoshypervisormapping',
title: 'label.guest.os.hypervisor.mappings',
docHelp: 'adminguide/guest_os.html#guest-os-hypervisor-mapping',
icon: 'api-outlined',
permission: ['listGuestOsMapping'],
columns: ['hypervisor', 'hypervisorversion', 'osdisplayname', 'osnameforhypervisor'],
details: ['hypervisor', 'hypervisorversion', 'osdisplayname', 'osnameforhypervisor', 'isuserdefined'],
filters: ['all', 'kvm', 'vmware', 'xenserver', 'lxc', 'ovm3'],
searchFilters: ['osdisplayname', 'osnameforhypervisor', 'hypervisor', 'hypervisorversion'],
actions: [
{
api: 'addGuestOsMapping',
icon: 'plus-outlined',
label: 'label.add.guest.os.hypervisor.mapping',
listView: true,
dataView: false,
args: ['ostypeid', 'hypervisor', 'hypervisorversion', 'osnameforhypervisor', 'osmappingcheckenabled', 'forced']
},
{
api: 'updateGuestOsMapping',
icon: 'edit-outlined',
label: 'label.edit',
dataView: true,
popup: true,
args: ['osnameforhypervisor', 'osmappingcheckenabled']
},
{
api: 'removeGuestOsMapping',
icon: 'delete-outlined',
label: 'label.action.delete.guest.os.hypervisor.mapping',
message: 'message.action.delete.guest.os.hypervisor.mapping',
dataView: true,
popup: true
}
]
}
]
}

View File

@ -119,6 +119,7 @@ import {
MoreOutlined,
NotificationOutlined,
NumberOutlined,
LaptopOutlined,
OrderedListOutlined,
PaperClipOutlined,
PauseCircleOutlined,
@ -274,6 +275,7 @@ export default {
app.component('MoreOutlined', MoreOutlined)
app.component('NotificationOutlined', NotificationOutlined)
app.component('NumberOutlined', NumberOutlined)
app.component('LaptopOutlined', LaptopOutlined)
app.component('OrderedListOutlined', OrderedListOutlined)
app.component('PaperClipOutlined', PaperClipOutlined)
app.component('PauseCircleOutlined', PauseCircleOutlined)

View File

@ -676,7 +676,7 @@ export default {
return this.$route.query.filter
}
const routeName = this.$route.name
if ((this.projectView && routeName === 'vm') || (['Admin', 'DomainAdmin'].includes(this.$store.getters.userInfo.roletype) && ['vm', 'iso', 'template', 'pod', 'cluster', 'host', 'systemvm', 'router', 'storagepool'].includes(routeName)) || ['account', 'guestnetwork', 'guestvlans'].includes(routeName)) {
if ((this.projectView && routeName === 'vm') || (['Admin', 'DomainAdmin'].includes(this.$store.getters.userInfo.roletype) && ['vm', 'iso', 'template', 'pod', 'cluster', 'host', 'systemvm', 'router', 'storagepool'].includes(routeName)) || ['account', 'guestnetwork', 'guestvlans', 'guestos', 'guestoshypervisormapping'].includes(routeName)) {
return 'all'
}
if (['publicip'].includes(routeName)) {
@ -1107,6 +1107,14 @@ export default {
description: self.$t('label.confirmpassword.description')
}
}
if (arg === 'ostypeid') {
return {
type: 'uuid',
name: 'ostypeid',
required: true,
description: self.$t('label.select.guest.os.type')
}
}
return paramFields.filter(function (param) {
return param.name.toLowerCase() === arg.toLowerCase()
})[0]
@ -1643,6 +1651,12 @@ export default {
} else {
delete query.archived
}
} else if (this.$route.name === 'guestoshypervisormapping') {
if (filter === 'all') {
delete query.hypervisor
} else {
query.hypervisor = filter
}
}
query.filter = filter
query.page = '1'
@ -1668,6 +1682,10 @@ export default {
query.templatetype = value
} else if (this.$route.name === 'globalsetting') {
query.name = value
} else if (this.$route.name === 'guestoshypervisormapping') {
query.hypervisor = value
} else if (this.$route.name === 'guestos') {
query.description = value
} else {
query.keyword = value
}

View File

@ -111,11 +111,11 @@
}"
:loading="osTypeLoading"
:placeholder="apiParams.ostypeid.description">
<a-select-option :value="opt.id" v-for="(opt, optIndex) in osTypes" :key="optIndex" :label="opt.name || opt.description">
<a-select-option :value="opt.id" v-for="(opt, optIndex) in osTypes" :key="optIndex" :label="opt.name">
<span>
<resource-icon v-if="opt.icon" :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
<global-outlined v-else style="margin-right: 5px" />
{{ opt.name || opt.description }}
{{ opt.name }}
</span>
</a-select-option>
</a-select>

View File

@ -575,7 +575,7 @@ export default {
const listOsTypes = json.listostypesresponse.ostype
this.osTypes.opts = listOsTypes
this.defaultOsType = this.osTypes.opts[1].description
this.defaultOsId = this.osTypes.opts[1].id
this.defaultOsId = this.osTypes.opts[1].name
}).finally(() => {
this.osTypes.loading = false
})

View File

@ -69,7 +69,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
//
public class ClusterMO extends BaseMO implements VmwareHypervisorHost {
private static final Logger s_logger = Logger.getLogger(ClusterMO.class);
private ManagedObjectReference _environmentBrowser = null;
protected ManagedObjectReference _environmentBrowser = null;
public ClusterMO(VmwareContext context, ManagedObjectReference morCluster) {
super(context, morCluster);
@ -740,4 +740,22 @@ public class ClusterMO extends BaseMO implements VmwareHypervisorHost {
throw new CloudRuntimeException(msg);
}
}
@Override
public GuestOsDescriptor getGuestOsDescriptor(String guestOsId) throws Exception {
VirtualMachineConfigOption vmConfigOption = _context.getService().queryConfigOption(getEnvironmentBrowser(), null, null);
List<GuestOsDescriptor> guestDescriptors = vmConfigOption.getGuestOSDescriptor();
for (GuestOsDescriptor descriptor : guestDescriptors) {
if (guestOsId != null && guestOsId.equalsIgnoreCase(descriptor.getId())) {
return descriptor;
}
}
return null;
}
@Override
public List<GuestOsDescriptor> getGuestOsDescriptors() throws Exception {
VirtualMachineConfigOption vmConfigOption = _context.getService().queryConfigOption(getEnvironmentBrowser(), null, null);
return vmConfigOption.getGuestOSDescriptor();
}
}

View File

@ -36,6 +36,7 @@ import com.vmware.vim25.ComputeResourceSummary;
import com.vmware.vim25.CustomFieldStringValue;
import com.vmware.vim25.DatastoreSummary;
import com.vmware.vim25.DynamicProperty;
import com.vmware.vim25.GuestOsDescriptor;
import com.vmware.vim25.HostConfigManager;
import com.vmware.vim25.HostConnectInfo;
import com.vmware.vim25.HostFirewallInfo;
@ -1165,6 +1166,26 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
return null;
}
@Override
public GuestOsDescriptor getGuestOsDescriptor(String guestOsId) throws Exception {
ManagedObjectReference morParent = getParentMor();
if (morParent.getType().equals("ClusterComputeResource")) {
ClusterMO clusterMo = new ClusterMO(_context, morParent);
return clusterMo.getGuestOsDescriptor(guestOsId);
}
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();

View File

@ -20,6 +20,7 @@ import java.util.List;
import com.vmware.vim25.ClusterDasConfigInfo;
import com.vmware.vim25.ComputeResourceSummary;
import com.vmware.vim25.GuestOsDescriptor;
import com.vmware.vim25.ManagedObjectReference;
import com.vmware.vim25.ObjectContent;
import com.vmware.vim25.VirtualMachineConfigSpec;
@ -91,5 +92,10 @@ public interface VmwareHypervisorHost {
ComputeResourceSummary getHyperHostHardwareSummary() throws Exception;
LicenseAssignmentManagerMO getLicenseAssignmentManager() throws Exception;
String getRecommendedDiskController(String guestOsId) throws Exception;
GuestOsDescriptor getGuestOsDescriptor(String guestOsId) throws Exception;
List<GuestOsDescriptor> getGuestOsDescriptors() throws Exception;
}

View File

@ -0,0 +1,113 @@
// 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.vmware.mo;
import com.cloud.hypervisor.vmware.util.VmwareClient;
import com.cloud.hypervisor.vmware.util.VmwareContext;
import com.vmware.vim25.GuestOsDescriptor;
import com.vmware.vim25.ManagedObjectReference;
import com.vmware.vim25.VimPortType;
import com.vmware.vim25.VirtualMachineConfigOption;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.util.ArrayList;
import java.util.List;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
@RunWith(PowerMockRunner.class)
@PrepareForTest(HostMO.class)
public class HostMOTest {
@Mock
VmwareContext _context ;
@Mock
VmwareClient _client;
@Mock
ManagedObjectReference _mor;
@Mock
ManagedObjectReference _environmentBrowser;
@Mock
VirtualMachineConfigOption vmConfigOption;
@Mock
GuestOsDescriptor guestOsDescriptor;
HostMO hostMO ;
ClusterMO clusterMO ;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
hostMO = new HostMO(_context, _mor);
clusterMO = new ClusterMO(_context, _mor);
clusterMO._environmentBrowser = _environmentBrowser;
when(_context.getVimClient()).thenReturn(_client);
when(_client.getDynamicProperty(any(ManagedObjectReference.class), eq("parent"))).thenReturn(_mor);
when(_mor.getType()).thenReturn("ClusterComputeResource");
}
@After
public void tearDown() throws Exception {
}
@Test
public void testGetGuestOsDescriptors() throws Exception {
VimPortType vimPortType = PowerMockito.mock(VimPortType.class);
Mockito.when(_context.getService()).thenReturn(vimPortType);
Mockito.when(vimPortType.queryConfigOption(_environmentBrowser, null, null)).thenReturn(vmConfigOption);
PowerMockito.whenNew(ClusterMO.class).withArguments(_context, _mor).thenReturn(clusterMO);
List<GuestOsDescriptor> guestOsDescriptors = new ArrayList<>();
guestOsDescriptors.add(guestOsDescriptor);
Mockito.when(clusterMO.getGuestOsDescriptors()).thenReturn(guestOsDescriptors);
List<GuestOsDescriptor> result = hostMO.getGuestOsDescriptors();
Assert.assertEquals(guestOsDescriptor, result.get(0));
}
@Test
public void testGetGuestOsDescriptor() throws Exception {
VimPortType vimPortType = PowerMockito.mock(VimPortType.class);
Mockito.when(_context.getService()).thenReturn(vimPortType);
Mockito.when(vimPortType.queryConfigOption(_environmentBrowser, null, null)).thenReturn(vmConfigOption);
PowerMockito.whenNew(ClusterMO.class).withArguments(_context, _mor).thenReturn(clusterMO);
Mockito.when(guestOsDescriptor.getId()).thenReturn("1");
List<GuestOsDescriptor> guestOsDescriptors = new ArrayList<>();
guestOsDescriptors.add(guestOsDescriptor);
Mockito.when(vmConfigOption.getGuestOSDescriptor()).thenReturn(guestOsDescriptors);
GuestOsDescriptor result = hostMO.getGuestOsDescriptor("1");
Assert.assertEquals(guestOsDescriptor, result);
}
}