CLOUDSTACK-3314: ListTemplates only show one entry for cross-zone

templates.
This commit is contained in:
Min Chen 2013-07-02 13:54:21 -07:00
parent 1f3a20cde7
commit 05f4680735
6 changed files with 142 additions and 121 deletions

View File

@ -18,7 +18,6 @@ package org.apache.cloudstack.api.response;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -137,8 +136,10 @@ public class TemplateResponse extends BaseResponse implements ControlledViewEnti
@SerializedName(ApiConstants.DETAILS) @Param(description="additional key/value details tied with template")
private Map details;
@SerializedName("zones") @Param(description="list of zones associated with tempate", responseObject = TemplateZoneResponse.class)
private Set<TemplateZoneResponse> zones;
// To avoid breaking backwards compatibility, we still treat a template at different zones as different templates, so not embedding
// template_zone information in this TemplateZoneResponse set.
// @SerializedName("zones") @Param(description="list of zones associated with tempate", responseObject = TemplateZoneResponse.class)
// private Set<TemplateZoneResponse> zones;
@SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with tempate", responseObject = ResourceTagResponse.class)
private Set<ResourceTagResponse> tags;
@ -150,7 +151,7 @@ public class TemplateResponse extends BaseResponse implements ControlledViewEnti
private Boolean isDynamicallyScalable;
public TemplateResponse(){
zones = new LinkedHashSet<TemplateZoneResponse>();
// zones = new LinkedHashSet<TemplateZoneResponse>();
tags = new LinkedHashSet<ResourceTagResponse>();
}
@ -176,6 +177,7 @@ public class TemplateResponse extends BaseResponse implements ControlledViewEnti
this.accountId = accountId;
}
@Override
public void setAccountName(String account) {
this.account = account;
}
@ -312,13 +314,6 @@ public class TemplateResponse extends BaseResponse implements ControlledViewEnti
this.tags.add(tag);
}
public void setZones(Set<TemplateZoneResponse> zones){
this.zones = zones;
}
public void addZone(TemplateZoneResponse zone){
this.zones.add(zone);
}
public void setSshKeyEnabled(boolean sshKeyEnabled) {
this.sshKeyEnabled = sshKeyEnabled;

View File

@ -27,7 +27,6 @@ import java.util.Set;
import javax.ejb.Local;
import javax.inject.Inject;
import com.cloud.storage.*;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
import org.apache.cloudstack.affinity.AffinityGroupVMMapVO;
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
@ -56,7 +55,28 @@ import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
import org.apache.cloudstack.api.command.user.volume.ListResourceDetailsCmd;
import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd;
import org.apache.cloudstack.api.response.*;
import org.apache.cloudstack.api.response.AccountResponse;
import org.apache.cloudstack.api.response.AsyncJobResponse;
import org.apache.cloudstack.api.response.DiskOfferingResponse;
import org.apache.cloudstack.api.response.DomainRouterResponse;
import org.apache.cloudstack.api.response.EventResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.ImageStoreResponse;
import org.apache.cloudstack.api.response.InstanceGroupResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.ProjectAccountResponse;
import org.apache.cloudstack.api.response.ProjectInvitationResponse;
import org.apache.cloudstack.api.response.ProjectResponse;
import org.apache.cloudstack.api.response.ResourceDetailResponse;
import org.apache.cloudstack.api.response.ResourceTagResponse;
import org.apache.cloudstack.api.response.SecurityGroupResponse;
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.TemplateResponse;
import org.apache.cloudstack.api.response.UserResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.api.response.VolumeResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState;
import org.apache.cloudstack.query.QueryService;
import org.apache.log4j.Logger;
@ -132,8 +152,14 @@ import com.cloud.server.ResourceTag.TaggedResourceType;
import com.cloud.server.TaggedResourceService;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.ScopeType;
import com.cloud.storage.Storage;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.TemplateType;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.Volume;
import com.cloud.storage.VolumeDetailVO;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VolumeDetailsDao;
import com.cloud.template.VirtualMachineTemplate.TemplateFilter;
@ -729,7 +755,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
// first search distinct vm id by using query criteria and pagination
SearchBuilder<UserVmJoinVO> sb = _userVmJoinDao.createSearchBuilder();
sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
// ids
// ids
_accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts,
listProjectResourcesCriteria);
@ -951,7 +977,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
cmd.getPageSizeVal());
SearchBuilder<SecurityGroupJoinVO> sb = _securityGroupJoinDao.createSearchBuilder();
sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
// ids
// ids
_accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts,
listProjectResourcesCriteria);
@ -1474,7 +1500,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
SearchBuilder<HostJoinVO> sb = _hostJoinDao.createSearchBuilder();
sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
// ids
// ids
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
sb.and("type", sb.entity().getType(), SearchCriteria.Op.LIKE);
@ -1935,7 +1961,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
SearchBuilder<StoragePoolJoinVO> sb = _poolJoinDao.createSearchBuilder();
sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
// ids
// ids
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
sb.and("path", sb.entity().getPath(), SearchCriteria.Op.EQ);
@ -2025,7 +2051,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
SearchBuilder<ImageStoreJoinVO> sb = _imageStoreJoinDao.createSearchBuilder();
sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
// ids
// ids
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
@ -2105,7 +2131,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
SearchBuilder<ImageStoreJoinVO> sb = _imageStoreJoinDao.createSearchBuilder();
sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
// ids
// ids
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
@ -2229,14 +2255,14 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
spc.addOr("domainId", SearchCriteria.Op.IN, domainIds.toArray());
spc.addOr("domainId", SearchCriteria.Op.NULL); // include public
// offering as where
// offering as where
sc.addAnd("domainId", SearchCriteria.Op.SC, spc);
sc.addAnd("systemUse", SearchCriteria.Op.EQ, false); // non-root
// users should
// not see
// system
// offering at
// all
// users should
// not see
// system
// offering at
// all
}
@ -2356,7 +2382,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
spc.addOr("domainId", SearchCriteria.Op.IN, domainIds.toArray());
spc.addOr("domainId", SearchCriteria.Op.NULL); // include public
// offering as where
// offering as where
sc.addAnd("domainId", SearchCriteria.Op.SC, spc);
} else {
@ -2439,8 +2465,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
Filter searchFilter = new Filter(DataCenterJoinVO.class, null, false, cmd.getStartIndex(), cmd.getPageSizeVal());
SearchCriteria<DataCenterJoinVO> sc = _dcJoinDao.createSearchCriteria();
if (networkType != null)
if (networkType != null) {
sc.addAnd("networkType", SearchCriteria.Op.EQ, networkType);
}
if (id != null) {
sc.addAnd("id", SearchCriteria.Op.EQ, id);
@ -2550,8 +2577,8 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
if (account != null) {
if ((available != null) && Boolean.FALSE.equals(available)) {
Set<Long> dcIds = new HashSet<Long>(); // data centers with
// at least one VM
// running
// at least one VM
// running
List<DomainRouterVO> routers = _routerDao.listBy(account.getId());
for (DomainRouterVO router : routers) {
dcIds.add(router.getDataCenterId());
@ -2664,6 +2691,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm"));
isAscending = (isAscending == null ? true : isAscending);
Filter searchFilter = new Filter(TemplateJoinVO.class, "sortKey", isAscending, startIndex, pageSize);
SearchBuilder<TemplateJoinVO> sb = _templateJoinDao.createSearchBuilder();
sb.select(null, Func.DISTINCT, sb.entity().getTempZonePair()); // select distinct (templateId, zoneId) pair
SearchCriteria<TemplateJoinVO> sc = _templateJoinDao.createSearchCriteria();
// verify templateId parameter and specially handle it
@ -2846,7 +2876,14 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
}
if (zoneId != null) {
sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
SearchCriteria<TemplateJoinVO> zoneSc = _templateJoinDao.createSearchCriteria();
zoneSc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
// handle the case where xs-tools.iso and vmware-tools.iso do not have data_center information in template_view
SearchCriteria<TemplateJoinVO> isoPerhostSc = _templateJoinDao.createSearchCriteria();
isoPerhostSc.addAnd("format", SearchCriteria.Op.EQ, ImageFormat.ISO);
isoPerhostSc.addAnd("templateType", SearchCriteria.Op.EQ, TemplateType.PERHOST);
zoneSc.addOr("templateType", SearchCriteria.Op.SC, isoPerhostSc);
sc.addAnd("dataCenterId", SearchCriteria.Op.SC, zoneSc);
}
if (!showDomr) {
@ -2867,12 +2904,12 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
return uniqueTmplPair;
}
List<TemplateJoinVO> uniqueTmpls = uniqueTmplPair.first();
Long[] vrIds = new Long[uniqueTmpls.size()];
String[] tzIds = new String[uniqueTmpls.size()];
int i = 0;
for (TemplateJoinVO v : uniqueTmpls) {
vrIds[i++] = v.getId();
tzIds[i++] = v.getTempZonePair();
}
List<TemplateJoinVO> vrs = _templateJoinDao.searchByIds(vrIds);
List<TemplateJoinVO> vrs = _templateJoinDao.searchByTemplateZonePair(tzIds);
return new Pair<List<TemplateJoinVO>, Integer>(vrs, count);
// TODO: revisit the special logic for iso search in
@ -2926,6 +2963,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags);
}
@Override
public ListResponse<AffinityGroupResponse> listAffinityGroups(Long affinityGroupId, String affinityGroupName,
String affinityGroupType, Long vmId, String accountName, Long domainId, boolean isRecursive,
boolean listAll, Long startIndex, Long pageSize) {
@ -2971,7 +3009,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
listProjectResourcesCriteria);
groupSearch.select(null, Func.DISTINCT, groupSearch.entity().getId()); // select
// distinct
// distinct
SearchCriteria<AffinityGroupJoinVO> sc = groupSearch.create();
_accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts,
@ -3026,6 +3064,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
return new Pair<List<AffinityGroupJoinVO>, Integer>(ags, count);
}
@Override
public List<ResourceDetailResponse> listResource(ListResourceDetailsCmd cmd) {
String key = cmd.getKey();

View File

@ -19,6 +19,7 @@ package com.cloud.api.query.dao;
import java.util.List;
import org.apache.cloudstack.api.response.TemplateResponse;
import com.cloud.api.query.vo.TemplateJoinVO;
import com.cloud.template.VirtualMachineTemplate;
import com.cloud.utils.db.GenericDao;
@ -37,8 +38,8 @@ public interface TemplateJoinDao extends GenericDao<TemplateJoinVO, Long> {
List<TemplateJoinVO> newTemplateView(VirtualMachineTemplate tmpl, long zoneId, boolean readyOnly);
List<TemplateJoinVO> searchByIds(Long... ids);
List<TemplateJoinVO> searchByTemplateZonePair(String... pairs);
List<TemplateJoinVO> listActiveTemplates(long storeId);
}
}

View File

@ -26,7 +26,6 @@ import javax.inject.Inject;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.response.TemplateResponse;
import org.apache.cloudstack.api.response.TemplateZoneResponse;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState;
import org.apache.log4j.Logger;
@ -60,7 +59,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase<TemplateJoinVO, Long> im
@Inject
private ConfigurationDao _configDao;
private final SearchBuilder<TemplateJoinVO> tmpltSearch;
private final SearchBuilder<TemplateJoinVO> tmpltIdPairSearch;
private final SearchBuilder<TemplateJoinVO> tmpltIdSearch;
@ -71,9 +70,9 @@ public class TemplateJoinDaoImpl extends GenericDaoBase<TemplateJoinVO, Long> im
protected TemplateJoinDaoImpl() {
tmpltSearch = createSearchBuilder();
tmpltSearch.and("idIN", tmpltSearch.entity().getId(), SearchCriteria.Op.IN);
tmpltSearch.done();
tmpltIdPairSearch = createSearchBuilder();
tmpltIdPairSearch.and("tempZonePairIN", tmpltIdPairSearch.entity().getTempZonePair(), SearchCriteria.Op.IN);
tmpltIdPairSearch.done();
tmpltIdSearch = createSearchBuilder();
tmpltIdSearch.and("id", tmpltIdSearch.entity().getId(), SearchCriteria.Op.EQ);
@ -91,7 +90,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase<TemplateJoinVO, Long> im
activeTmpltSearch.done();
// select distinct pair (template_id, zone_id)
this._count = "select count(distinct id) from template_view WHERE ";
this._count = "select count(distinct temp_zone_pair) from template_view WHERE ";
}
@ -172,6 +171,11 @@ public class TemplateJoinDaoImpl extends GenericDaoBase<TemplateJoinVO, Long> im
templateResponse.setStatus(templateStatus);
}
if ( template.getDataCenterId() > 0 ){
templateResponse.setZoneId(template.getDataCenterUuid());
templateResponse.setZoneName(template.getDataCenterName());
}
Long templateSize = template.getSize();
if (templateSize > 0) {
templateResponse.setSize(templateSize);
@ -183,26 +187,6 @@ public class TemplateJoinDaoImpl extends GenericDaoBase<TemplateJoinVO, Long> im
}
templateResponse.setTemplateTag(template.getTemplateTag());
// set template zone information
if (template.getDataCenterId() > 0 ){
TemplateZoneResponse tmplZoneResp = new TemplateZoneResponse(template.getDataCenterUuid(), template.getDataCenterName());
tmplZoneResp.setCreated(template.getCreatedOnStore());
if ( template.getFormat() == Storage.ImageFormat.BAREMETAL ){
// for baremetal template, we didn't download, but is ready to use.
tmplZoneResp.setReady(true);
}
else{
tmplZoneResp.setReady(template.getState() == ObjectInDataStoreStateMachine.State.Ready);
}
if ( templateStatus != null ){
tmplZoneResp.setStatus(templateStatus);
}
templateResponse.addZone(tmplZoneResp);
// set the first found associated zone directly in TemplateResponse
templateResponse.setZoneId(template.getDataCenterUuid());
templateResponse.setZoneName(template.getDataCenterName());
}
// set details map
if (template.getDetailName() != null){
Map<String, String> details = new HashMap<String, String>();
@ -274,30 +258,6 @@ public class TemplateJoinDaoImpl extends GenericDaoBase<TemplateJoinVO, Long> im
@Override
public TemplateResponse setTemplateResponse(TemplateResponse templateResponse, TemplateJoinVO template) {
// update template zone information
if (template.getDataCenterId() > 0 ){
TemplateZoneResponse tmplZoneResp = new TemplateZoneResponse(template.getDataCenterUuid(), template.getDataCenterName());
tmplZoneResp.setCreated(template.getCreatedOnStore());
if ( template.getFormat() == Storage.ImageFormat.BAREMETAL ){
// for baremetal template, we didn't download, but is ready to use.
tmplZoneResp.setReady(true);
}
else{
tmplZoneResp.setReady(template.getState() == ObjectInDataStoreStateMachine.State.Ready);
}
String templateStatus = getTemplateStatus(template);
if ( templateStatus != null ){
tmplZoneResp.setStatus(templateStatus);
}
templateResponse.addZone(tmplZoneResp);
if (templateResponse.getZoneId() == null) {
// set the first found associated zone directly in
// TemplateResponse
templateResponse.setZoneId(template.getDataCenterUuid());
templateResponse.setZoneName(template.getDataCenterName());
}
}
// update details map
if (template.getDetailName() != null){
Map<String, String> details = templateResponse.getDetails();
@ -354,15 +314,6 @@ public class TemplateJoinDaoImpl extends GenericDaoBase<TemplateJoinVO, Long> im
isoResponse.setDomainId(iso.getDomainUuid());
isoResponse.setDomainName(iso.getDomainName());
// set template zone information
if (iso.getDataCenterId() > 0 ){
TemplateZoneResponse tmplZoneResp = new TemplateZoneResponse(iso.getDataCenterUuid(), iso.getDataCenterName());
isoResponse.addZone(tmplZoneResp);
// set the first found associated zone directly in TemplateResponse
isoResponse.setZoneId(iso.getDataCenterUuid());
isoResponse.setZoneName(iso.getDataCenterName());
}
Account caller = UserContext.current().getCaller();
boolean isAdmin = false;
@ -393,6 +344,12 @@ public class TemplateJoinDaoImpl extends GenericDaoBase<TemplateJoinVO, Long> im
}
}
if ( iso.getDataCenterId() > 0 ){
isoResponse.setZoneId(iso.getDataCenterUuid());
isoResponse.setZoneName(iso.getDataCenterName());
}
Long isoSize = iso.getSize();
if (isoSize > 0) {
isoResponse.setSize(isoSize);
@ -433,7 +390,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase<TemplateJoinVO, Long> im
@Override
public List<TemplateJoinVO> searchByIds(Long... tmplIds) {
public List<TemplateJoinVO> searchByTemplateZonePair(String... idPairs) {
// set detail batch query size
int DETAILS_BATCH_SIZE = 2000;
String batchCfg = _configDao.getValue("detail.batch.query.size");
@ -444,14 +401,14 @@ public class TemplateJoinDaoImpl extends GenericDaoBase<TemplateJoinVO, Long> im
List<TemplateJoinVO> uvList = new ArrayList<TemplateJoinVO>();
// query details by batches
int curr_index = 0;
if ( tmplIds.length > DETAILS_BATCH_SIZE ){
while ( (curr_index + DETAILS_BATCH_SIZE ) <= tmplIds.length ) {
Long[] ids = new Long[DETAILS_BATCH_SIZE];
if ( idPairs.length > DETAILS_BATCH_SIZE ){
while ( (curr_index + DETAILS_BATCH_SIZE ) <= idPairs.length ) {
String[] labels = new String[DETAILS_BATCH_SIZE];
for (int k = 0, j = curr_index; j < curr_index + DETAILS_BATCH_SIZE; j++, k++) {
ids[k] = tmplIds[j];
labels[k] = idPairs[j];
}
SearchCriteria<TemplateJoinVO> sc = tmpltSearch.create();
sc.setParameters("idIN", ids);
SearchCriteria<TemplateJoinVO> sc = tmpltIdPairSearch.create();
sc.setParameters("tempZonePairIN", labels);
List<TemplateJoinVO> vms = searchIncludingRemoved(sc, null, null, false);
if (vms != null) {
uvList.addAll(vms);
@ -459,15 +416,14 @@ public class TemplateJoinDaoImpl extends GenericDaoBase<TemplateJoinVO, Long> im
curr_index += DETAILS_BATCH_SIZE;
}
}
if (curr_index < tmplIds.length) {
int batch_size = (tmplIds.length - curr_index);
// set the ids value
Long[] ids = new Long[batch_size];
if (curr_index < idPairs.length) {
int batch_size = (idPairs.length - curr_index);
String[] labels = new String[batch_size];
for (int k = 0, j = curr_index; j < curr_index + batch_size; j++, k++) {
ids[k] = tmplIds[j];
labels[k] = idPairs[j];
}
SearchCriteria<TemplateJoinVO> sc = tmpltSearch.create();
sc.setParameters("idIN", ids);
SearchCriteria<TemplateJoinVO> sc = tmpltIdPairSearch.create();
sc.setParameters("tempZonePairIN", labels);
List<TemplateJoinVO> vms = searchIncludingRemoved(sc, null, null, false);
if (vms != null) {
uvList.addAll(vms);

View File

@ -17,6 +17,7 @@
package com.cloud.api.query.vo;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
@ -27,8 +28,10 @@ import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.server.ResourceTag.TaggedResourceType;
import com.cloud.storage.ScopeType;
import com.cloud.storage.Storage;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.utils.db.GenericDao;
@ -175,6 +178,10 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity {
@Column(name="data_center_name")
private String dataCenterName;
@Column(name="store_scope")
@Enumerated(value = EnumType.STRING)
private ScopeType dataStoreScope;
@Column(name="store_id")
private Long dataStoreId; // this can be null for baremetal templates
@ -239,6 +246,9 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity {
@Enumerated(EnumType.STRING)
ObjectInDataStoreStateMachine.State state;
@Column(name="temp_zone_pair")
private String tempZonePair; // represent a distinct (templateId, data_center_id) pair
public TemplateJoinVO() {
}
@ -1027,4 +1037,26 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity {
}
public ScopeType getDataStoreScope() {
return dataStoreScope;
}
public void setDataStoreScope(ScopeType dataStoreScope) {
this.dataStoreScope = dataStoreScope;
}
public String getTempZonePair() {
return tempZonePair;
}
public void setTempZonePair(String tempZonePair) {
this.tempZonePair = tempZonePair;
}
}

View File

@ -1883,7 +1883,6 @@ CREATE VIEW `cloud`.`template_view` AS
vm_template.display_text,
vm_template.enable_password,
vm_template.guest_os_id,
-- vm_template.state,
guest_os.uuid guest_os_uuid,
guest_os.display_name guest_os_name,
vm_template.bootable,
@ -1913,6 +1912,7 @@ CREATE VIEW `cloud`.`template_view` AS
data_center.name data_center_name,
launch_permission.account_id lp_account_id,
template_store_ref.store_id,
image_store.scope as store_scope,
template_store_ref.state,
template_store_ref.download_state,
template_store_ref.download_pct,
@ -1931,7 +1931,8 @@ CREATE VIEW `cloud`.`template_view` AS
resource_tags.resource_id tag_resource_id,
resource_tags.resource_uuid tag_resource_uuid,
resource_tags.resource_type tag_resource_type,
resource_tags.customer tag_customer
resource_tags.customer tag_customer,
CONCAT(vm_template.id, '_', IFNULL(data_center.id, 0)) as temp_zone_pair
from
`cloud`.`vm_template`
inner join
@ -1945,24 +1946,21 @@ CREATE VIEW `cloud`.`template_view` AS
left join
`cloud`.`vm_template_details` ON vm_template_details.template_id = vm_template.id
left join
`cloud`.`vm_template` source_template ON source_template.id = vm_template.source_template_id
`cloud`.`vm_template` source_template ON source_template.id = vm_template.source_template_id
left join
`cloud`.`template_zone_ref` ON template_zone_ref.template_id = vm_template.id
AND template_zone_ref.removed is null
`cloud`.`template_store_ref` ON template_store_ref.template_id = vm_template.id
left join
`cloud`.`data_center` ON template_zone_ref.zone_id = data_center.id
`cloud`.`image_store` ON image_store.removed is NULL AND template_store_ref.store_id is not NULL AND image_store.id = template_store_ref.store_id
left join
`cloud`.`template_zone_ref` ON template_zone_ref.template_id = vm_template.id AND template_store_ref.store_id is NULL AND template_zone_ref.removed is null
left join
`cloud`.`image_store` ON image_store.removed is NULL AND (image_store.data_center_id = data_center.id OR image_store.scope = 'REGION')
left join
`cloud`.`template_store_ref` ON template_store_ref.template_id = vm_template.id AND template_store_ref.store_id = image_store.id
`cloud`.`data_center` ON (image_store.data_center_id = data_center.id OR template_zone_ref.zone_id = data_center.id)
left join
`cloud`.`launch_permission` ON launch_permission.template_id = vm_template.id
left join
`cloud`.`resource_tags` ON resource_tags.resource_id = vm_template.id
and (resource_tags.resource_type = 'Template' or resource_tags.resource_type='ISO');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network', 'DEFAULT', 'management-server', 'midonet.apiserver.address', 'http://localhost:8081', 'Specify the address at which the Midonet API server can be contacted (if using Midonet)');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network', 'DEFAULT', 'management-server', 'midonet.providerrouter.id', 'd7c5e6a3-e2f4-426b-b728-b7ce6a0448e5', 'Specifies the UUID of the Midonet provider router (if using Midonet)');