Skip to content

Commit 5bf78b8

Browse files
Harikrishna Patnalanitinmeh
authored andcommitted
CLOUDSTACK-4904: Unable to see a derieved template if the
parent template is deleted. Modified template_view so that removed(or InActive) templates also be there in the view. Previous behavior of listing templates and state column in vm_templates will be the same.
1 parent 7053c22 commit 5bf78b8

8 files changed

Lines changed: 67 additions & 13 deletions

File tree

api/src/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ public class ApiConstants {
209209
public static final String SENT_BYTES = "sentbytes";
210210
public static final String SERVICE_OFFERING_ID = "serviceofferingid";
211211
public static final String SHOW_CAPACITIES = "showcapacities";
212+
public static final String SHOW_REMOVED = "showremoved";
212213
public static final String SIZE = "size";
213214
public static final String SNAPSHOT_ID = "snapshotid";
214215
public static final String SNAPSHOT_POLICY_ID = "snapshotpolicyid";

api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd {
7373
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the ID of the zone")
7474
private Long zoneId;
7575

76+
@Parameter(name=ApiConstants.SHOW_REMOVED, type=CommandType.BOOLEAN, description="show removed ISOs as well")
77+
private Boolean showRemoved;
78+
7679
/////////////////////////////////////////////////////
7780
/////////////////// Accessors ///////////////////////
7881
/////////////////////////////////////////////////////
@@ -109,6 +112,10 @@ public Long getZoneId() {
109112
return zoneId;
110113
}
111114

115+
public Boolean getShowRemoved() {
116+
return (showRemoved != null ? showRemoved : false);
117+
}
118+
112119
public boolean listInReadyState() {
113120
Account account = CallContext.current().getCallingAccount();
114121
// It is account specific if account is admin type and domainId and accountName are not null

api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ public class ListTemplatesCmd extends BaseListTaggedResourcesCmd {
6565
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "list templates by zoneId")
6666
private Long zoneId;
6767

68+
@Parameter(name=ApiConstants.SHOW_REMOVED, type=CommandType.BOOLEAN, description="show removed templates as well")
69+
private Boolean showRemoved;
70+
6871
/////////////////////////////////////////////////////
6972
/////////////////// Accessors ///////////////////////
7073
/////////////////////////////////////////////////////
@@ -89,6 +92,10 @@ public Long getZoneId() {
8992
return zoneId;
9093
}
9194

95+
public Boolean getShowRemoved() {
96+
return (showRemoved != null ? showRemoved : false);
97+
}
98+
9299
public boolean listInReadyState() {
93100

94101
Account account = CallContext.current().getCallingAccount();

server/src/com/cloud/api/query/QueryManagerImpl.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@
176176
import com.cloud.tags.ResourceTagVO;
177177
import com.cloud.tags.dao.ResourceTagDao;
178178
import com.cloud.template.VirtualMachineTemplate.TemplateFilter;
179+
import com.cloud.template.VirtualMachineTemplate.State;
179180
import com.cloud.user.Account;
180181
import com.cloud.user.AccountManager;
181182
import com.cloud.user.DomainManager;
@@ -2716,6 +2717,7 @@ private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(ListTempl
27162717
TemplateFilter templateFilter = TemplateFilter.valueOf(cmd.getTemplateFilter());
27172718
Long id = cmd.getId();
27182719
Map<String, String> tags = cmd.getTags();
2720+
boolean showRemovedTmpl = cmd.getShowRemoved();
27192721
Account caller = CallContext.current().getCallingAccount();
27202722

27212723
boolean listAll = false;
@@ -2740,12 +2742,12 @@ private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(ListTempl
27402742
HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor());
27412743

27422744
return searchForTemplatesInternal(id, cmd.getTemplateName(), cmd.getKeyword(), templateFilter, false, null, cmd.getPageSizeVal(), cmd.getStartIndex(),
2743-
cmd.getZoneId(), hypervisorType, showDomr, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags);
2745+
cmd.getZoneId(), hypervisorType, showDomr, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedTmpl);
27442746
}
27452747

27462748
private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(Long templateId, String name, String keyword, TemplateFilter templateFilter, boolean isIso,
27472749
Boolean bootable, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean showDomr, boolean onlyReady, List<Account> permittedAccounts,
2748-
Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, Map<String, String> tags) {
2750+
Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, Map<String, String> tags, boolean showRemovedTmpl) {
27492751

27502752
// check if zone is configured, if not, just return empty list
27512753
List<HypervisorType> hypers = null;
@@ -2964,7 +2966,14 @@ private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(Long temp
29642966
// sc.addAnd("removed", SearchCriteria.Op.NULL);
29652967

29662968
// search unique templates and find details by Ids
2967-
Pair<List<TemplateJoinVO>, Integer> uniqueTmplPair = _templateJoinDao.searchAndCount(sc, searchFilter);
2969+
Pair<List<TemplateJoinVO>, Integer> uniqueTmplPair = null;
2970+
if(showRemovedTmpl){
2971+
uniqueTmplPair = _templateJoinDao.searchIncludingRemovedAndCount(sc, searchFilter);
2972+
} else {
2973+
sc.addAnd("templateState", SearchCriteria.Op.EQ, State.Active);
2974+
uniqueTmplPair = _templateJoinDao.searchAndCount(sc, searchFilter);
2975+
}
2976+
29682977
Integer count = uniqueTmplPair.second();
29692978
if (count.intValue() == 0) {
29702979
// empty result
@@ -2976,7 +2985,7 @@ private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(Long temp
29762985
for (TemplateJoinVO v : uniqueTmpls) {
29772986
tzIds[i++] = v.getTempZonePair();
29782987
}
2979-
List<TemplateJoinVO> vrs = _templateJoinDao.searchByTemplateZonePair(tzIds);
2988+
List<TemplateJoinVO> vrs = _templateJoinDao.searchByTemplateZonePair(showRemovedTmpl, tzIds);
29802989
return new Pair<List<TemplateJoinVO>, Integer>(vrs, count);
29812990

29822991
// TODO: revisit the special logic for iso search in
@@ -3000,6 +3009,7 @@ private Pair<List<TemplateJoinVO>, Integer> searchForIsosInternal(ListIsosCmd cm
30003009
TemplateFilter isoFilter = TemplateFilter.valueOf(cmd.getIsoFilter());
30013010
Long id = cmd.getId();
30023011
Map<String, String> tags = cmd.getTags();
3012+
boolean showRemovedISO = cmd.getShowRemoved();
30033013
Account caller = CallContext.current().getCallingAccount();
30043014

30053015
boolean listAll = false;
@@ -3023,7 +3033,7 @@ private Pair<List<TemplateJoinVO>, Integer> searchForIsosInternal(ListIsosCmd cm
30233033
HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor());
30243034

30253035
return searchForTemplatesInternal(cmd.getId(), cmd.getIsoName(), cmd.getKeyword(), isoFilter, true, cmd.isBootable(), cmd.getPageSizeVal(), cmd.getStartIndex(),
3026-
cmd.getZoneId(), hypervisorType, true, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags);
3036+
cmd.getZoneId(), hypervisorType, true, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedISO);
30273037
}
30283038

30293039
@Override

server/src/com/cloud/api/query/dao/TemplateJoinDao.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818

1919
import java.util.List;
2020

21+
import com.cloud.utils.Pair;
22+
import com.cloud.utils.db.Filter;
23+
import com.cloud.utils.db.SearchCriteria;
2124
import org.apache.cloudstack.api.response.TemplateResponse;
2225

2326
import com.cloud.api.query.vo.TemplateJoinVO;
@@ -38,8 +41,10 @@ public interface TemplateJoinDao extends GenericDao<TemplateJoinVO, Long> {
3841

3942
List<TemplateJoinVO> newTemplateView(VirtualMachineTemplate tmpl, long zoneId, boolean readyOnly);
4043

41-
List<TemplateJoinVO> searchByTemplateZonePair(String... pairs);
44+
List<TemplateJoinVO> searchByTemplateZonePair( Boolean showRemoved, String... pairs);
4245

4346
List<TemplateJoinVO> listActiveTemplates(long storeId);
4447

48+
Pair<List<TemplateJoinVO>, Integer> searchIncludingRemovedAndCount(final SearchCriteria<TemplateJoinVO> sc, final Filter filter);
49+
4550
}

server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
import com.cloud.utils.db.GenericDaoBase;
4848
import com.cloud.utils.db.SearchBuilder;
4949
import com.cloud.utils.db.SearchCriteria;
50+
import com.cloud.utils.Pair;
51+
import com.cloud.utils.db.Filter;
5052

5153
@Component
5254
@Local(value = {TemplateJoinDao.class})
@@ -68,6 +70,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase<TemplateJoinVO, Long> im
6870
protected TemplateJoinDaoImpl() {
6971

7072
tmpltIdPairSearch = createSearchBuilder();
73+
tmpltIdPairSearch.and("templateState", tmpltIdPairSearch.entity().getTemplateState(), SearchCriteria.Op.EQ);
7174
tmpltIdPairSearch.and("tempZonePairIN", tmpltIdPairSearch.entity().getTempZonePair(), SearchCriteria.Op.IN);
7275
tmpltIdPairSearch.done();
7376

@@ -84,6 +87,7 @@ protected TemplateJoinDaoImpl() {
8487
activeTmpltSearch = createSearchBuilder();
8588
activeTmpltSearch.and("store_id", activeTmpltSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
8689
activeTmpltSearch.and("type", activeTmpltSearch.entity().getTemplateType(), SearchCriteria.Op.EQ);
90+
activeTmpltSearch.and("templateState", activeTmpltSearch.entity().getTemplateState(), SearchCriteria.Op.EQ);
8791
activeTmpltSearch.done();
8892

8993
// select distinct pair (template_id, zone_id)
@@ -371,7 +375,7 @@ public List<TemplateJoinVO> newTemplateView(VirtualMachineTemplate template, lon
371375
}
372376

373377
@Override
374-
public List<TemplateJoinVO> searchByTemplateZonePair(String... idPairs) {
378+
public List<TemplateJoinVO> searchByTemplateZonePair(Boolean showRemoved, String... idPairs) {
375379
// set detail batch query size
376380
int DETAILS_BATCH_SIZE = 2000;
377381
String batchCfg = _configDao.getValue("detail.batch.query.size");
@@ -389,6 +393,9 @@ public List<TemplateJoinVO> searchByTemplateZonePair(String... idPairs) {
389393
labels[k] = idPairs[j];
390394
}
391395
SearchCriteria<TemplateJoinVO> sc = tmpltIdPairSearch.create();
396+
if (!showRemoved) {
397+
sc.setParameters("templateState", VirtualMachineTemplate.State.Active);
398+
}
392399
sc.setParameters("tempZonePairIN", labels);
393400
List<TemplateJoinVO> vms = searchIncludingRemoved(sc, null, null, false);
394401
if (vms != null) {
@@ -404,6 +411,9 @@ public List<TemplateJoinVO> searchByTemplateZonePair(String... idPairs) {
404411
labels[k] = idPairs[j];
405412
}
406413
SearchCriteria<TemplateJoinVO> sc = tmpltIdPairSearch.create();
414+
if (!showRemoved) {
415+
sc.setParameters("templateState", VirtualMachineTemplate.State.Active);
416+
}
407417
sc.setParameters("tempZonePairIN", labels);
408418
List<TemplateJoinVO> vms = searchIncludingRemoved(sc, null, null, false);
409419
if (vms != null) {
@@ -418,7 +428,15 @@ public List<TemplateJoinVO> listActiveTemplates(long storeId) {
418428
SearchCriteria<TemplateJoinVO> sc = activeTmpltSearch.create();
419429
sc.setParameters("store_id", storeId);
420430
sc.setParameters("type", TemplateType.USER);
431+
sc.setParameters("templateState", VirtualMachineTemplate.State.Active);
421432
return searchIncludingRemoved(sc, null, null, false);
422433
}
423434

435+
@Override
436+
public Pair<List<TemplateJoinVO>, Integer> searchIncludingRemovedAndCount(final SearchCriteria<TemplateJoinVO> sc, final Filter filter) {
437+
List<TemplateJoinVO> objects = searchIncludingRemoved(sc, filter, null, false);
438+
Integer count = getCount(sc);
439+
return new Pair<List<TemplateJoinVO>, Integer>(objects, count);
440+
}
441+
424442
}

server/src/com/cloud/api/query/vo/TemplateJoinVO.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import javax.persistence.Temporal;
2828
import javax.persistence.TemporalType;
2929

30+
import com.cloud.template.VirtualMachineTemplate.State;
3031
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
3132

3233
import com.cloud.hypervisor.Hypervisor.HypervisorType;
@@ -200,6 +201,10 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity {
200201
@Column(name = "size")
201202
private long size;
202203

204+
@Column(name = "template_state")
205+
@Enumerated(EnumType.STRING)
206+
private State templateState;
207+
203208
@Column(name = "destroyed")
204209
boolean destroyed = false;
205210

@@ -532,4 +537,6 @@ public ScopeType getDataStoreScope() {
532537
public String getTempZonePair() {
533538
return tempZonePair;
534539
}
540+
541+
public State getTemplateState() { return templateState; }
535542
}

setup/db/db/schema-421to430.sql

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ CREATE VIEW `cloud`.`template_view` AS
232232
vm_template.display_text,
233233
vm_template.enable_password,
234234
vm_template.dynamically_scalable,
235+
vm_template.state template_state,
235236
vm_template.guest_os_id,
236237
guest_os.uuid guest_os_uuid,
237238
guest_os.display_name guest_os_name,
@@ -262,7 +263,7 @@ CREATE VIEW `cloud`.`template_view` AS
262263
data_center.name data_center_name,
263264
launch_permission.account_id lp_account_id,
264265
template_store_ref.store_id,
265-
image_store.scope as store_scope,
266+
image_store.scope as store_scope,
266267
template_store_ref.state,
267268
template_store_ref.download_state,
268269
template_store_ref.download_pct,
@@ -282,7 +283,7 @@ CREATE VIEW `cloud`.`template_view` AS
282283
resource_tags.resource_uuid tag_resource_uuid,
283284
resource_tags.resource_type tag_resource_type,
284285
resource_tags.customer tag_customer,
285-
CONCAT(vm_template.id, '_', IFNULL(data_center.id, 0)) as temp_zone_pair
286+
CONCAT(vm_template.id, '_', IFNULL(data_center.id, 0)) as temp_zone_pair
286287
from
287288
`cloud`.`vm_template`
288289
inner join
@@ -301,17 +302,15 @@ CREATE VIEW `cloud`.`template_view` AS
301302
`cloud`.`template_store_ref` ON template_store_ref.template_id = vm_template.id and template_store_ref.store_role = 'Image'
302303
left join
303304
`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
304-
left join
305+
left join
305306
`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
306307
left join
307308
`cloud`.`data_center` ON (image_store.data_center_id = data_center.id OR template_zone_ref.zone_id = data_center.id)
308309
left join
309310
`cloud`.`launch_permission` ON launch_permission.template_id = vm_template.id
310311
left join
311312
`cloud`.`resource_tags` ON resource_tags.resource_id = vm_template.id
312-
and (resource_tags.resource_type = 'Template' or resource_tags.resource_type='ISO')
313-
where
314-
vm_template.state='Active';
313+
and (resource_tags.resource_type = 'Template' or resource_tags.resource_type='ISO');
315314

316315
DROP VIEW IF EXISTS `cloud`.`volume_view`;
317316
CREATE VIEW `cloud`.`volume_view` AS

0 commit comments

Comments
 (0)