From 5bf78b82c01d213fd2ab4b4241c00ff2b22d2ad5 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Fri, 10 Jan 2014 10:26:08 -0800 Subject: [PATCH] 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. --- .../apache/cloudstack/api/ApiConstants.java | 1 + .../api/command/user/iso/ListIsosCmd.java | 7 +++++++ .../user/template/ListTemplatesCmd.java | 7 +++++++ .../com/cloud/api/query/QueryManagerImpl.java | 20 ++++++++++++++----- .../cloud/api/query/dao/TemplateJoinDao.java | 7 ++++++- .../api/query/dao/TemplateJoinDaoImpl.java | 20 ++++++++++++++++++- .../cloud/api/query/vo/TemplateJoinVO.java | 7 +++++++ setup/db/db/schema-421to430.sql | 11 +++++----- 8 files changed, 67 insertions(+), 13 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 0af19430024..287fff3035b 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -209,6 +209,7 @@ public class ApiConstants { public static final String SENT_BYTES = "sentbytes"; public static final String SERVICE_OFFERING_ID = "serviceofferingid"; public static final String SHOW_CAPACITIES = "showcapacities"; + public static final String SHOW_REMOVED = "showremoved"; public static final String SIZE = "size"; public static final String SNAPSHOT_ID = "snapshotid"; public static final String SNAPSHOT_POLICY_ID = "snapshotpolicyid"; diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java index 3e66e52249f..95b771fcc43 100644 --- a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java @@ -73,6 +73,9 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd { @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the ID of the zone") private Long zoneId; + @Parameter(name=ApiConstants.SHOW_REMOVED, type=CommandType.BOOLEAN, description="show removed ISOs as well") + private Boolean showRemoved; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -109,6 +112,10 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd { return zoneId; } + public Boolean getShowRemoved() { + return (showRemoved != null ? showRemoved : false); + } + public boolean listInReadyState() { Account account = CallContext.current().getCallingAccount(); // It is account specific if account is admin type and domainId and accountName are not null diff --git a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java index 7e347f3e32f..d393c6a5fdf 100644 --- a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java @@ -65,6 +65,9 @@ public class ListTemplatesCmd extends BaseListTaggedResourcesCmd { @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "list templates by zoneId") private Long zoneId; + @Parameter(name=ApiConstants.SHOW_REMOVED, type=CommandType.BOOLEAN, description="show removed templates as well") + private Boolean showRemoved; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -89,6 +92,10 @@ public class ListTemplatesCmd extends BaseListTaggedResourcesCmd { return zoneId; } + public Boolean getShowRemoved() { + return (showRemoved != null ? showRemoved : false); + } + public boolean listInReadyState() { Account account = CallContext.current().getCallingAccount(); diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index 89e911ae4be..7fe7b89452a 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -176,6 +176,7 @@ import com.cloud.storage.dao.VolumeDetailsDao; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.template.VirtualMachineTemplate.TemplateFilter; +import com.cloud.template.VirtualMachineTemplate.State; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.DomainManager; @@ -2716,6 +2717,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { TemplateFilter templateFilter = TemplateFilter.valueOf(cmd.getTemplateFilter()); Long id = cmd.getId(); Map tags = cmd.getTags(); + boolean showRemovedTmpl = cmd.getShowRemoved(); Account caller = CallContext.current().getCallingAccount(); boolean listAll = false; @@ -2740,12 +2742,12 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor()); return searchForTemplatesInternal(id, cmd.getTemplateName(), cmd.getKeyword(), templateFilter, false, null, cmd.getPageSizeVal(), cmd.getStartIndex(), - cmd.getZoneId(), hypervisorType, showDomr, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags); + cmd.getZoneId(), hypervisorType, showDomr, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedTmpl); } private Pair, Integer> searchForTemplatesInternal(Long templateId, String name, String keyword, TemplateFilter templateFilter, boolean isIso, Boolean bootable, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean showDomr, boolean onlyReady, List permittedAccounts, - Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags) { + Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags, boolean showRemovedTmpl) { // check if zone is configured, if not, just return empty list List hypers = null; @@ -2964,7 +2966,14 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { // sc.addAnd("removed", SearchCriteria.Op.NULL); // search unique templates and find details by Ids - Pair, Integer> uniqueTmplPair = _templateJoinDao.searchAndCount(sc, searchFilter); + Pair, Integer> uniqueTmplPair = null; + if(showRemovedTmpl){ + uniqueTmplPair = _templateJoinDao.searchIncludingRemovedAndCount(sc, searchFilter); + } else { + sc.addAnd("templateState", SearchCriteria.Op.EQ, State.Active); + uniqueTmplPair = _templateJoinDao.searchAndCount(sc, searchFilter); + } + Integer count = uniqueTmplPair.second(); if (count.intValue() == 0) { // empty result @@ -2976,7 +2985,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { for (TemplateJoinVO v : uniqueTmpls) { tzIds[i++] = v.getTempZonePair(); } - List vrs = _templateJoinDao.searchByTemplateZonePair(tzIds); + List vrs = _templateJoinDao.searchByTemplateZonePair(showRemovedTmpl, tzIds); return new Pair, Integer>(vrs, count); // TODO: revisit the special logic for iso search in @@ -3000,6 +3009,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { TemplateFilter isoFilter = TemplateFilter.valueOf(cmd.getIsoFilter()); Long id = cmd.getId(); Map tags = cmd.getTags(); + boolean showRemovedISO = cmd.getShowRemoved(); Account caller = CallContext.current().getCallingAccount(); boolean listAll = false; @@ -3023,7 +3033,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor()); return searchForTemplatesInternal(cmd.getId(), cmd.getIsoName(), cmd.getKeyword(), isoFilter, true, cmd.isBootable(), cmd.getPageSizeVal(), cmd.getStartIndex(), - cmd.getZoneId(), hypervisorType, true, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags); + cmd.getZoneId(), hypervisorType, true, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedISO); } @Override diff --git a/server/src/com/cloud/api/query/dao/TemplateJoinDao.java b/server/src/com/cloud/api/query/dao/TemplateJoinDao.java index f73f5bdea1e..cb1b13092f9 100644 --- a/server/src/com/cloud/api/query/dao/TemplateJoinDao.java +++ b/server/src/com/cloud/api/query/dao/TemplateJoinDao.java @@ -18,6 +18,9 @@ package com.cloud.api.query.dao; import java.util.List; +import com.cloud.utils.Pair; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.SearchCriteria; import org.apache.cloudstack.api.response.TemplateResponse; import com.cloud.api.query.vo.TemplateJoinVO; @@ -38,8 +41,10 @@ public interface TemplateJoinDao extends GenericDao { List newTemplateView(VirtualMachineTemplate tmpl, long zoneId, boolean readyOnly); - List searchByTemplateZonePair(String... pairs); + List searchByTemplateZonePair( Boolean showRemoved, String... pairs); List listActiveTemplates(long storeId); + Pair, Integer> searchIncludingRemovedAndCount(final SearchCriteria sc, final Filter filter); + } diff --git a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java index 792ac0998d7..53cb14a7ed3 100644 --- a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java @@ -47,6 +47,8 @@ import com.cloud.user.Account; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.Pair; +import com.cloud.utils.db.Filter; @Component @Local(value = {TemplateJoinDao.class}) @@ -68,6 +70,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im protected TemplateJoinDaoImpl() { tmpltIdPairSearch = createSearchBuilder(); + tmpltIdPairSearch.and("templateState", tmpltIdPairSearch.entity().getTemplateState(), SearchCriteria.Op.EQ); tmpltIdPairSearch.and("tempZonePairIN", tmpltIdPairSearch.entity().getTempZonePair(), SearchCriteria.Op.IN); tmpltIdPairSearch.done(); @@ -84,6 +87,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im activeTmpltSearch = createSearchBuilder(); activeTmpltSearch.and("store_id", activeTmpltSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); activeTmpltSearch.and("type", activeTmpltSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); + activeTmpltSearch.and("templateState", activeTmpltSearch.entity().getTemplateState(), SearchCriteria.Op.EQ); activeTmpltSearch.done(); // select distinct pair (template_id, zone_id) @@ -371,7 +375,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im } @Override - public List searchByTemplateZonePair(String... idPairs) { + public List searchByTemplateZonePair(Boolean showRemoved, String... idPairs) { // set detail batch query size int DETAILS_BATCH_SIZE = 2000; String batchCfg = _configDao.getValue("detail.batch.query.size"); @@ -389,6 +393,9 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im labels[k] = idPairs[j]; } SearchCriteria sc = tmpltIdPairSearch.create(); + if (!showRemoved) { + sc.setParameters("templateState", VirtualMachineTemplate.State.Active); + } sc.setParameters("tempZonePairIN", labels); List vms = searchIncludingRemoved(sc, null, null, false); if (vms != null) { @@ -404,6 +411,9 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im labels[k] = idPairs[j]; } SearchCriteria sc = tmpltIdPairSearch.create(); + if (!showRemoved) { + sc.setParameters("templateState", VirtualMachineTemplate.State.Active); + } sc.setParameters("tempZonePairIN", labels); List vms = searchIncludingRemoved(sc, null, null, false); if (vms != null) { @@ -418,7 +428,15 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im SearchCriteria sc = activeTmpltSearch.create(); sc.setParameters("store_id", storeId); sc.setParameters("type", TemplateType.USER); + sc.setParameters("templateState", VirtualMachineTemplate.State.Active); return searchIncludingRemoved(sc, null, null, false); } + @Override + public Pair, Integer> searchIncludingRemovedAndCount(final SearchCriteria sc, final Filter filter) { + List objects = searchIncludingRemoved(sc, filter, null, false); + Integer count = getCount(sc); + return new Pair, Integer>(objects, count); + } + } diff --git a/server/src/com/cloud/api/query/vo/TemplateJoinVO.java b/server/src/com/cloud/api/query/vo/TemplateJoinVO.java index e295272d748..c096279888d 100644 --- a/server/src/com/cloud/api/query/vo/TemplateJoinVO.java +++ b/server/src/com/cloud/api/query/vo/TemplateJoinVO.java @@ -27,6 +27,7 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; +import com.cloud.template.VirtualMachineTemplate.State; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -200,6 +201,10 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name = "size") private long size; + @Column(name = "template_state") + @Enumerated(EnumType.STRING) + private State templateState; + @Column(name = "destroyed") boolean destroyed = false; @@ -532,4 +537,6 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity { public String getTempZonePair() { return tempZonePair; } + + public State getTemplateState() { return templateState; } } diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql index 24e82237e76..e14f0dac6c1 100644 --- a/setup/db/db/schema-421to430.sql +++ b/setup/db/db/schema-421to430.sql @@ -232,6 +232,7 @@ CREATE VIEW `cloud`.`template_view` AS vm_template.display_text, vm_template.enable_password, vm_template.dynamically_scalable, + vm_template.state template_state, vm_template.guest_os_id, guest_os.uuid guest_os_uuid, guest_os.display_name guest_os_name, @@ -262,7 +263,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, + image_store.scope as store_scope, template_store_ref.state, template_store_ref.download_state, template_store_ref.download_pct, @@ -282,7 +283,7 @@ CREATE VIEW `cloud`.`template_view` AS resource_tags.resource_uuid tag_resource_uuid, resource_tags.resource_type tag_resource_type, resource_tags.customer tag_customer, - CONCAT(vm_template.id, '_', IFNULL(data_center.id, 0)) as temp_zone_pair + CONCAT(vm_template.id, '_', IFNULL(data_center.id, 0)) as temp_zone_pair from `cloud`.`vm_template` inner join @@ -301,7 +302,7 @@ CREATE VIEW `cloud`.`template_view` AS `cloud`.`template_store_ref` ON template_store_ref.template_id = vm_template.id and template_store_ref.store_role = 'Image' left join `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 + 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`.`data_center` ON (image_store.data_center_id = data_center.id OR template_zone_ref.zone_id = data_center.id) @@ -309,9 +310,7 @@ CREATE VIEW `cloud`.`template_view` AS `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') - where - vm_template.state='Active'; + and (resource_tags.resource_type = 'Template' or resource_tags.resource_type='ISO'); DROP VIEW IF EXISTS `cloud`.`volume_view`; CREATE VIEW `cloud`.`volume_view` AS