engine/schema: fix duplicated guest OSes in 4.18.0.0 (#7799)

Co-authored-by: Daan Hoogland <daan@onecht.net>
This commit is contained in:
Wei Zhou 2023-08-23 09:44:34 +02:00 committed by GitHub
parent 0e9a19f24d
commit e4117e68d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 295 additions and 61 deletions

View File

@ -34,4 +34,6 @@ public interface GuestOS extends InternalIdentity, Identity {
Date getRemoved();
boolean getIsUserDefined();
boolean getForDisplay();
}

View File

@ -27,6 +27,7 @@ import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.GuestOSCategoryResponse;
import org.apache.cloudstack.api.response.GuestOSResponse;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.context.CallContext;
import com.cloud.event.EventTypes;
@ -60,6 +61,8 @@ public class AddGuestOsCmd extends BaseAsyncCreateCmd {
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, required = false, description = "Map of (key/value pairs)")
private Map details;
@Parameter(name="forDisplay", type=CommandType.BOOLEAN, description="whether this guest OS is available for end users", authorized = {RoleType.Admin})
private Boolean display;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
@ -78,7 +81,7 @@ public class AddGuestOsCmd extends BaseAsyncCreateCmd {
}
public Map getDetails() {
Map<String, String> detailsMap = new HashMap<String, String>();
Map<String, String> detailsMap = new HashMap<>();
if (!details.isEmpty()) {
Collection<?> servicesCollection = details.values();
Iterator<?> iter = servicesCollection.iterator();
@ -92,6 +95,9 @@ public class AddGuestOsCmd extends BaseAsyncCreateCmd {
return detailsMap;
}
public Boolean getForDisplay() {
return display;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////

View File

@ -26,6 +26,7 @@ import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.GuestOSResponse;
import org.apache.cloudstack.acl.RoleType;
import com.cloud.event.EventTypes;
import com.cloud.storage.GuestOS;
@ -56,8 +57,10 @@ public class UpdateGuestOsCmd extends BaseAsyncCmd {
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, required = true, description = "Map of (key/value pairs)")
private Map details;
@Parameter(name="forDisplay", type=CommandType.BOOLEAN, description="whether this guest OS is available for end users", authorized = {RoleType.Admin})
private Boolean display;
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -70,7 +73,7 @@ public class UpdateGuestOsCmd extends BaseAsyncCmd {
}
public Map getDetails() {
Map<String, String> detailsMap = new HashMap<String, String>();;
Map<String, String> detailsMap = new HashMap<>();;
if (!details.isEmpty()) {
Collection<?> servicesCollection = details.values();
Iterator<?> iter = servicesCollection.iterator();
@ -84,6 +87,10 @@ public class UpdateGuestOsCmd extends BaseAsyncCmd {
return detailsMap;
}
public Boolean getForDisplay() {
return display;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -19,8 +19,10 @@ package org.apache.cloudstack.api.command.user.guest;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.log4j.Logger;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseListCmd;
@ -51,6 +53,10 @@ public class ListGuestOsCmd extends BaseListCmd {
@Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, description = "list os by description", since = "3.0.1")
private String description;
@Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter",
since = "4.18.1", authorized = {RoleType.Admin})
private Boolean display;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -67,6 +73,10 @@ public class ListGuestOsCmd extends BaseListCmd {
return description;
}
public Boolean getDisplay() {
return BooleanUtils.toBooleanDefaultIfNull(display, true);
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@ -74,8 +84,8 @@ public class ListGuestOsCmd extends BaseListCmd {
@Override
public void execute() {
Pair<List<? extends GuestOS>, Integer> result = _mgr.listGuestOSByCriteria(this);
ListResponse<GuestOSResponse> response = new ListResponse<GuestOSResponse>();
List<GuestOSResponse> osResponses = new ArrayList<GuestOSResponse>();
ListResponse<GuestOSResponse> response = new ListResponse<>();
List<GuestOSResponse> osResponses = new ArrayList<>();
for (GuestOS guestOS : result.first()) {
GuestOSResponse guestOSResponse = _responseGenerator.createGuestOSResponse(guestOS);
osResponses.add(guestOSResponse);

View File

@ -43,6 +43,10 @@ public class GuestOSResponse extends BaseResponse {
@Param(description = "is the guest OS user defined")
private Boolean isUserDefined;
@SerializedName(ApiConstants.FOR_DISPLAY)
@Param(description = "is the guest OS visible for the users")
private Boolean forDisplay;
public String getId() {
return id;
}
@ -75,4 +79,12 @@ public class GuestOSResponse extends BaseResponse {
this.isUserDefined = isUserDefined;
}
public Boolean getForDisplay() {
return this.forDisplay;
}
public void setForDisplay(final Boolean forDisplay) {
this.forDisplay = forDisplay;
}
}

View File

@ -57,6 +57,9 @@ public class GuestOSVO implements GuestOS {
@Column(name = "is_user_defined")
private boolean isUserDefined;
@Column(name = "display", updatable = true, nullable = false)
protected boolean display = true;
@Override
public long getId() {
return id;
@ -120,4 +123,15 @@ public class GuestOSVO implements GuestOS {
public void setIsUserDefined(boolean isUserDefined) {
this.isUserDefined = isUserDefined;
}
public boolean getForDisplay() {
return isDisplay();
}
public boolean isDisplay() {
return display;
}
public void setDisplay(boolean display) {
this.display = display;
}
}

View File

@ -16,12 +16,23 @@
// under the License.
package com.cloud.storage.dao;
import com.cloud.storage.GuestOS;
import com.cloud.storage.GuestOSVO;
import com.cloud.utils.Pair;
import com.cloud.utils.db.GenericDao;
import java.util.List;
import java.util.Set;
public interface GuestOSDao extends GenericDao<GuestOSVO, Long> {
GuestOSVO listByDisplayName(String displayName);
GuestOSVO findOneByDisplayName(String displayName);
GuestOSVO findByCategoryIdAndDisplayNameOrderByCreatedDesc(long categoryId, String displayName);
Set<String> findDoubleNames();
List<GuestOSVO> listByDisplayName(String displayName);
Pair<List<? extends GuestOS>, Integer> listGuestOSByCriteria(Long startIndex, Long pageSize, Long id, Long osCategoryId, String description, String keyword, Boolean forDisplay);
}

View File

@ -17,8 +17,19 @@
package com.cloud.storage.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.cloud.storage.GuestOS;
import com.cloud.utils.Pair;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.TransactionLegacy;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;
@ -42,7 +53,7 @@ public class GuestOSDaoImpl extends GenericDaoBase<GuestOSVO, Long> implements G
}
@Override
public GuestOSVO listByDisplayName(String displayName) {
public GuestOSVO findOneByDisplayName(String displayName) {
SearchCriteria<GuestOSVO> sc = Search.create();
sc.setParameters("display_name", displayName);
return findOneBy(sc);
@ -62,4 +73,69 @@ public class GuestOSDaoImpl extends GenericDaoBase<GuestOSVO, Long> implements G
}
return null;
}
/**
+ "select display_name from"
+ "(select display_name, count(1) as count from guest_os go1 where removed is null group by display_name having count > 1) tab0";
*
* @return
*/
@Override
@DB
public Set<String> findDoubleNames() {
String selectSql = "SELECT display_name FROM (SELECT display_name, count(1) AS count FROM guest_os go1 WHERE removed IS NULL GROUP BY display_name HAVING count > 1) tab0";
Set<String> names = new HashSet<>();
Connection conn = TransactionLegacy.getStandaloneConnection();
try {
PreparedStatement stmt = conn.prepareStatement(selectSql);
ResultSet rs = stmt.executeQuery();
while (rs != null && rs.next()) {
names.add(rs.getString(1));
}
} catch (SQLException ex) {
throw new CloudRuntimeException("Error while trying to find duplicate guest OSses", ex);
}
return names;
}
/**
* get all with a certain display name
* @param displayName
* @return a list with GuestOS objects
*/
@Override
public List<GuestOSVO> listByDisplayName(String displayName) {
SearchCriteria<GuestOSVO> sc = Search.create();
sc.setParameters("display_name", displayName);
return listBy(sc);
}
public Pair<List<? extends GuestOS>, Integer> listGuestOSByCriteria(Long startIndex, Long pageSize, Long id, Long osCategoryId, String description, String keyword, Boolean forDisplay) {
final Filter searchFilter = new Filter(GuestOSVO.class, "displayName", true, startIndex, pageSize);
final SearchCriteria<GuestOSVO> sc = createSearchCriteria();
if (id != null) {
sc.addAnd("id", SearchCriteria.Op.EQ, id);
}
if (osCategoryId != null) {
sc.addAnd("categoryId", SearchCriteria.Op.EQ, osCategoryId);
}
if (description != null) {
sc.addAnd("displayName", SearchCriteria.Op.LIKE, "%" + description + "%");
}
if (keyword != null) {
sc.addAnd("displayName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
}
if (forDisplay != null) {
sc.addAnd("display", SearchCriteria.Op.EQ, forDisplay);
}
final Pair<List<GuestOSVO>, Integer> result = searchAndCount(sc, searchFilter);
return new Pair<>(result.first(), result.second());
}
}

View File

@ -16,7 +16,6 @@
// under the License.
package com.cloud.storage.dao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.GuestOSHypervisorVO;
import com.cloud.utils.db.GenericDao;
@ -24,7 +23,12 @@ import java.util.List;
public interface GuestOSHypervisorDao extends GenericDao<GuestOSHypervisorVO, Long> {
HypervisorType findHypervisorTypeByGuestOsId(long guestOsId);
/**
* list all the mappings for a guesos id
* @param guestOsId the guestos to look for
* @return a list of mappings
*/
List<GuestOSHypervisorVO> listByGuestOsId(long guestOsId);
GuestOSHypervisorVO findByOsIdAndHypervisor(long guestOsId, String hypervisorType, String hypervisorVersion);

View File

@ -20,13 +20,12 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.cloud.utils.db.QueryBuilder;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.GuestOSHypervisorVO;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.QueryBuilder;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
@ -82,11 +81,10 @@ public class GuestOSHypervisorDaoImpl extends GenericDaoBase<GuestOSHypervisorVO
}
@Override
public HypervisorType findHypervisorTypeByGuestOsId(long guestOsId) {
public List<GuestOSHypervisorVO> listByGuestOsId(long guestOsId) {
SearchCriteria<GuestOSHypervisorVO> sc = guestOsSearch.create();
sc.setParameters("guest_os_id", guestOsId);
GuestOSHypervisorVO goh = findOneBy(sc);
return HypervisorType.getType(goh.getHypervisorType());
return listBy(sc);
}
@Override

View File

@ -23,7 +23,9 @@ import org.apache.log4j.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.inject.Inject;
@ -53,6 +55,89 @@ public class GuestOsMapper {
guestOSDao = new GuestOSDaoImpl();
}
public void mergeDuplicates() {
LOG.info("merging duplicate guest osses");
Set<Set<GuestOSVO>> duplicates = findDuplicates();
LOG.debug(String.format("merging %d sets of duplicates", duplicates.size()));
for (Set<GuestOSVO> setOfGuestOSes : duplicates) {
// decide which to (mark as) remove(d)
// # highest/lowest id
// # or is user_defined == false
GuestOSVO guestOSVO = highestIdFrom(setOfGuestOSes);
LOG.info(String.format("merging %d duplicates for %s ", setOfGuestOSes.size(), guestOSVO.getDisplayName()));
makeNormative(guestOSVO, setOfGuestOSes);
}
}
public void makeNormative(GuestOSVO guestOSVO, Set<GuestOSVO> setOfGuestOSes) {
for (GuestOSVO oldGuestOs : setOfGuestOSes) {
if (guestOSVO.getId() != oldGuestOs.getId()) {
List<GuestOSHypervisorVO> mappings = guestOSHypervisorDao.listByGuestOsId(oldGuestOs.getId());
copyMappings(guestOSVO, mappings);
makeHidden(oldGuestOs);
}
}
}
private void makeHidden(GuestOSVO guestOSVO) {
guestOSVO.setDisplay(false);
guestOSDao.update(guestOSVO.getId(),guestOSVO);
}
private void copyMappings(GuestOSVO guestOSVO, List<GuestOSHypervisorVO> mappings) {
for (GuestOSHypervisorVO mapping : mappings) {
if (null == guestOSHypervisorDao.findByOsIdAndHypervisor(guestOSVO.getId(), mapping.getHypervisorType(), mapping.getHypervisorVersion())) {
GuestOSHypervisorVO newMap = new GuestOSHypervisorVO();
newMap.setGuestOsId(guestOSVO.getId());
newMap.setGuestOsName(mapping.getGuestOsName());
newMap.setHypervisorType(mapping.getHypervisorType());
newMap.setHypervisorVersion(mapping.getHypervisorVersion());
guestOSHypervisorDao.persist(newMap);
}
}
}
private GuestOSVO highestIdFrom(Set<GuestOSVO> setOfGuestOSes) {
GuestOSVO rc = null;
for (GuestOSVO guestOSVO: setOfGuestOSes) {
if (rc == null || (guestOSVO.getId() > rc.getId() && !guestOSVO.getIsUserDefined())) {
rc = guestOSVO;
break;
}
}
return rc;
}
/**
*
¨¨¨
select * from guest_os go2
where display_name
in (select display_name from
(select display_name, count(1) as count from guest_os go1 group by display_name having count > 1) tab0);
¨¨¨
* and group them by display_name
*
*
* @return a list of sets of duplicate
*/
private Set<Set<GuestOSVO>> findDuplicates() {
Set<Set<GuestOSVO>> rc = new HashSet<>();
Set<String> names = guestOSDao.findDoubleNames();
for (String name : names) {
List<GuestOSVO> guestOsses = guestOSDao.listByDisplayName(name);
if (CollectionUtils.isNotEmpty(guestOsses)) {
rc.add(new HashSet<>(guestOsses));
}
}
return rc;
}
public List<GuestOSVO> listByDisplayName(String displayName) {
return guestOSDao.listByDisplayName(displayName);
}
private long getGuestOsId(long categoryId, String displayName) {
GuestOSVO guestOS = guestOSDao.findByCategoryIdAndDisplayNameOrderByCreatedDesc(categoryId, displayName);
long id = 0l;
@ -76,26 +161,33 @@ public class GuestOsMapper {
}
public void addGuestOsAndHypervisorMappings(long categoryId, String displayName, List<GuestOSHypervisorMapping> mappings) {
if (!addGuestOs(categoryId, displayName)) {
LOG.warn("Couldn't add the guest OS with category id: " + categoryId + " and display name: " + displayName);
return;
long guestOsId = getGuestOsId(categoryId, displayName);
if (guestOsId == 0) {
LOG.debug("No guest OS found with category id: " + categoryId + " and display name: " + displayName);
if (!addGuestOs(categoryId, displayName)) {
LOG.warn("Couldn't add the guest OS with category id: " + categoryId + " and display name: " + displayName);
return;
}
guestOsId = getGuestOsId(categoryId, displayName);
} else {
updateToSystemDefined(guestOsId);
}
if (CollectionUtils.isEmpty(mappings)) {
return;
}
long guestOsId = getGuestOsId(categoryId, displayName);
if (guestOsId == 0) {
LOG.debug("No guest OS found with category id: " + categoryId + " and display name: " + displayName);
return;
}
for (final GuestOSHypervisorMapping mapping : mappings) {
addGuestOsHypervisorMapping(mapping, guestOsId);
}
}
private void updateToSystemDefined(long guestOsId) {
GuestOSVO guestOsVo = guestOSDao.findById(guestOsId);
guestOsVo.setIsUserDefined(false);
guestOSDao.update(guestOsId, guestOsVo);// TODO: update is_user_defined to false
}
public boolean addGuestOs(long categoryId, String displayName) {
LOG.debug("Adding guest OS with category id: " + categoryId + " and display name: " + displayName);
GuestOSVO guestOS = new GuestOSVO();

View File

@ -19,6 +19,7 @@ package com.cloud.upgrade.dao;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.storage.GuestOSHypervisorMapping;
import com.cloud.upgrade.GuestOsMapper;
import com.cloud.storage.GuestOSVO;
import com.cloud.upgrade.SystemVmTemplateRegistration;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.log4j.Logger;
@ -26,10 +27,13 @@ import org.apache.log4j.Logger;
import java.io.InputStream;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
public class Upgrade41800to41810 implements DbUpgrade, DbUpgradeSystemVmTemplate {
final static Logger LOG = Logger.getLogger(Upgrade41800to41810.class);
private GuestOsMapper guestOsMapper = new GuestOsMapper();
private SystemVmTemplateRegistration systemVmTemplateRegistration;
@Override
@ -64,6 +68,14 @@ public class Upgrade41800to41810 implements DbUpgrade, DbUpgradeSystemVmTemplate
updateGuestOsMappings(conn);
copyGuestOsMappingsToVMware80u1();
addForeignKeyToAutoscaleVmprofiles(conn);
mergeDuplicateGuestOSes();
}
private void mergeDuplicateGuestOSes() {
guestOsMapper.mergeDuplicates();
List<GuestOSVO> nines = guestOsMapper.listByDisplayName("Red Hat Enterprise Linux 9");
GuestOSVO nineDotZero = guestOsMapper.listByDisplayName("Red Hat Enterprise Linux 9.0").get(0);
guestOsMapper.makeNormative(nineDotZero, new HashSet<>(nines));
}
@Override

View File

@ -1568,4 +1568,6 @@ UPDATE
SET
usage_type = 22
WHERE
usage_type = 24 AND usage_display like '% io write';
usage_type = 24 AND usage_display like '% io write';
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.guest_os', 'display', 'tinyint(1) DEFAULT ''1'' COMMENT ''should this guest_os be shown to the end user'' ');

View File

@ -43,3 +43,7 @@ CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.autoscale_vmprofiles', 'user_data_de
UPDATE `cloud`.`service_offering` so
SET so.limit_cpu_use = 0
WHERE so.default_use = 1 AND so.vm_type IN ('domainrouter', 'secondarystoragevm', 'consoleproxy', 'internalloadbalancervm', 'elasticloadbalancervm');
-- fix erronous commas in guest_os names
UPDATE `cloud`.`guest_os_hypervisor` SET guest_os_name = 'rhel9_64Guest' WHERE guest_os_name = 'rhel9_64Guest,';
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.guest_os', 'display', 'tinyint(1) DEFAULT ''1'' COMMENT ''should this guest_os be shown to the end user'' ');

View File

@ -456,8 +456,8 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
*/
private Long getImportingVMGuestOs(VirtualMachineConfigSummary configSummary) {
String guestFullName = configSummary.getGuestFullName();
GuestOSVO os = _guestOsDao.listByDisplayName(guestFullName);
return os != null ? os.getId() : _guestOsDao.listByDisplayName("Other (64-bit)").getId();
GuestOSVO os = _guestOsDao.findOneByDisplayName(guestFullName);
return os != null ? os.getId() : _guestOsDao.findOneByDisplayName("Other (64-bit)").getId();
}
/**

View File

@ -1104,7 +1104,7 @@ public class ApiDBUtils {
}
public static GuestOS findGuestOSByDisplayName(String displayName) {
return s_guestOSDao.listByDisplayName(displayName);
return s_guestOSDao.findOneByDisplayName(displayName);
}
public static HostVO findHostById(Long hostId) {

View File

@ -3646,6 +3646,7 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setDescription(guestOS.getDisplayName());
response.setId(guestOS.getUuid());
response.setIsUserDefined(guestOS.getIsUserDefined());
response.setForDisplay(guestOS.getForDisplay());
GuestOSCategoryVO category = ApiDBUtils.findGuestOsCategoryById(guestOS.getCategoryId());
if (category != null) {
response.setOsCategoryId(category.getUuid());

View File

@ -2625,32 +2625,15 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
@Override
public Pair<List<? extends GuestOS>, Integer> listGuestOSByCriteria(final ListGuestOsCmd cmd) {
final Filter searchFilter = new Filter(GuestOSVO.class, "displayName", true, cmd.getStartIndex(), cmd.getPageSizeVal());
final Long id = cmd.getId();
final Long osCategoryId = cmd.getOsCategoryId();
final String description = cmd.getDescription();
final String keyword = cmd.getKeyword();
final Long startIndex = cmd.getStartIndex();
final Long pageSize = cmd.getPageSizeVal();
Boolean forDisplay = cmd.getDisplay();
final SearchCriteria<GuestOSVO> sc = _guestOSDao.createSearchCriteria();
if (id != null) {
sc.addAnd("id", SearchCriteria.Op.EQ, id);
}
if (osCategoryId != null) {
sc.addAnd("categoryId", SearchCriteria.Op.EQ, osCategoryId);
}
if (description != null) {
sc.addAnd("displayName", SearchCriteria.Op.LIKE, "%" + description + "%");
}
if (keyword != null) {
sc.addAnd("displayName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
}
final Pair<List<GuestOSVO>, Integer> result = _guestOSDao.searchAndCount(sc, searchFilter);
return new Pair<List<? extends GuestOS>, Integer>(result.first(), result.second());
return _guestOSDao.listGuestOSByCriteria(startIndex, pageSize, id, osCategoryId, description, keyword, forDisplay);
}
@Override
@ -2796,18 +2779,20 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
guestOsVo.setDisplayName(displayName);
guestOsVo.setName(name);
guestOsVo.setIsUserDefined(true);
guestOsVo.setDisplay(cmd.getForDisplay() == null ? true : cmd.getForDisplay());
final GuestOS guestOsPersisted = _guestOSDao.persist(guestOsVo);
if (cmd.getDetails() != null && !cmd.getDetails().isEmpty()) {
Map<String, String> detailsMap = cmd.getDetails();
for (Object key : detailsMap.keySet()) {
_guestOsDetailsDao.addDetail(guestOsPersisted.getId(), (String)key, detailsMap.get(key), false);
}
}
persistGuestOsDetails(cmd.getDetails(), guestOsPersisted.getId());
return guestOsPersisted;
}
private void persistGuestOsDetails(Map<String, String> details, long guestOsPersistedId) {
for (Object key : details.keySet()) {
_guestOsDetailsDao.addDetail(guestOsPersistedId, (String)key, details.get(key), false);
}
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_ADD, eventDescription = "Adding a new guest OS type", async = true)
public GuestOS getAddedGuestOs(final Long guestOsId) {
@ -2831,12 +2816,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
throw new InvalidParameterValueException("Unable to modify system defined guest OS");
}
if (cmd.getDetails() != null && !cmd.getDetails().isEmpty()) {
Map<String, String> detailsMap = cmd.getDetails();
for (Object key : detailsMap.keySet()) {
_guestOsDetailsDao.addDetail(id, (String)key, detailsMap.get(key), false);
}
}
persistGuestOsDetails(cmd.getDetails(), id);
//Check if update is needed
if (displayName.equals(guestOsHandle.getDisplayName())) {
@ -2850,6 +2830,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
}
final GuestOSVO guestOs = _guestOSDao.createForUpdate(id);
guestOs.setDisplayName(displayName);
if (cmd.getForDisplay() != null) {
guestOs.setDisplay(cmd.getForDisplay());
}
if (_guestOSDao.update(id, guestOs)) {
return _guestOSDao.findById(id);
} else {

View File

@ -1214,7 +1214,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
String osName = unmanagedInstance.getOperatingSystem();
GuestOS guestOS = null;
if (StringUtils.isNotEmpty(osName)) {
guestOS = guestOSDao.listByDisplayName(osName);
guestOS = guestOSDao.findOneByDisplayName(osName);
}
GuestOSHypervisor guestOSHypervisor = null;
if (guestOS != null) {