diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java index 74822bcb2a9..b4376fd550e 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java @@ -50,6 +50,7 @@ public interface VMTemplateDao extends GenericDao, StateDao< public long addTemplateToZone(VMTemplateVO tmplt, long zoneId); public List listAllInZone(long dataCenterId); + public List listAllActive(); public List listByHypervisorType(List hyperTypes); public List publicIsoSearch(Boolean bootable, boolean listRemoved, Map tags); diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java index a8c2455e6ab..7bd8b6d88dc 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -110,6 +110,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem protected SearchBuilder AccountIdSearch; protected SearchBuilder NameSearch; protected SearchBuilder TmpltsInZoneSearch; + protected SearchBuilder ActiveTmpltSearch; private SearchBuilder PublicSearch; private SearchBuilder NameAccountIdSearch; private SearchBuilder PublicIsoSearch; @@ -368,6 +369,10 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem tmpltZoneSearch.done(); TmpltsInZoneSearch.done(); + ActiveTmpltSearch = createSearchBuilder(); + ActiveTmpltSearch.and("removed", ActiveTmpltSearch.entity().getRemoved(), SearchCriteria.Op.NULL); + + CountTemplatesByAccount = createSearchBuilder(Long.class); CountTemplatesByAccount.select(null, Func.COUNT, null); CountTemplatesByAccount.and("account", CountTemplatesByAccount.entity().getAccountId(), SearchCriteria.Op.EQ); @@ -556,12 +561,12 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem if ((templateFilter == TemplateFilter.featured) || (templateFilter == TemplateFilter.community)) { dataCenterJoin = " INNER JOIN data_center dc on (h.data_center_id = dc.id)"; } - + if (zoneType != null) { dataCenterJoin = " INNER JOIN template_host_ref thr on (t.id = thr.template_id) INNER JOIN host h on (thr.host_id = h.id)"; dataCenterJoin += " INNER JOIN data_center dc on (h.data_center_id = dc.id)"; } - + if (templateFilter == TemplateFilter.sharedexecutable || templateFilter == TemplateFilter.shared ){ lpjoin = " INNER JOIN launch_permission lp ON t.id = lp.template_id "; } @@ -749,7 +754,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem return templateZonePairList; } */ - + /* private String getExtrasWhere(TemplateFilter templateFilter, String name, String keyword, boolean isIso, Boolean bootable, HypervisorType hyperType, Long zoneId, boolean onlyReady, boolean showDomr, String zoneType) { String sql = ""; @@ -781,15 +786,15 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem sql += " AND h.data_center_id = " +zoneId; } }else if (zoneId != null){ - sql += " AND tzr.zone_id = " +zoneId+ " AND tzr.removed is null" ; + sql += " AND tzr.zone_id = " +zoneId+ " AND tzr.removed is null" ; }else{ sql += " AND tzr.removed is null "; } - - if (zoneType != null){ + + if (zoneType != null){ sql += " AND dc.networktype = '" + zoneType + "'"; - } - + } + if (!showDomr){ sql += " AND t.type != '" +Storage.TemplateType.SYSTEM.toString() + "'"; } @@ -854,7 +859,15 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem return listBy(sc); } + + @Override + public List listAllActive() { + SearchCriteria sc = ActiveTmpltSearch.create(); + return listBy(sc); + } + + @Override public List listDefaultBuiltinTemplates() { SearchCriteria sc = tmpltTypeSearch.create(); sc.setParameters("templateType", Storage.TemplateType.BUILTIN); diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 597bbbe060d..eb6e44c9c46 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -40,11 +40,13 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCallFuture; @@ -57,6 +59,7 @@ import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; +import org.apache.cloudstack.storage.image.manager.ImageDataManager; import org.apache.cloudstack.storage.image.store.TemplateObject; import com.cloud.agent.api.Answer; @@ -64,9 +67,12 @@ import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.ListTemplateAnswer; import com.cloud.agent.api.storage.ListTemplateCommand; import com.cloud.alert.AlertManager; +import com.cloud.api.query.dao.UserVmJoinDao; +import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; +import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceAllocationException; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.DataStoreRole; @@ -84,6 +90,7 @@ import com.cloud.storage.template.TemplateProp; import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; import com.cloud.utils.UriUtils; +import com.cloud.utils.fsm.NoTransitionException; import com.cloud.vm.UserVmVO; import com.cloud.vm.dao.UserVmDao; @@ -121,12 +128,17 @@ public class TemplateServiceImpl implements TemplateService { @Inject UserVmDao _userVmDao; @Inject + UserVmJoinDao _userVmJoinDao; + @Inject VolumeDao _volumeDao; @Inject TemplateDataFactory _templateFactory; @Inject VMTemplatePoolDao _tmpltPoolDao; @Inject EndPointSelector _epSelector; + @Inject + ImageDataManager imageMgr; + class TemplateOpContext extends AsyncRpcConext { final TemplateObject template; @@ -264,7 +276,7 @@ public class TemplateServiceImpl implements TemplateService { List allTemplates = null; if (zoneId == null){ // region wide store - allTemplates = _templateDao.listAll(); + allTemplates = _templateDao.listAllActive(); } else{ // zone wide store @@ -326,7 +338,7 @@ public class TemplateServiceImpl implements TemplateService { tmlpt.setSize(tmpltInfo.getSize()); _templateDao.update(tmplt.getId(), tmlpt); - if (tmpltInfo.getSize() > 0) { + if (tmpltInfo.getSize() > 0 && tmplt.getUrl() != null) { long accountId = tmplt.getAccountId(); try { _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId), @@ -418,7 +430,7 @@ public class TemplateServiceImpl implements TemplateService { for (String uniqueName : templateInfos.keySet()) { TemplateProp tInfo = templateInfos.get(uniqueName); - List userVmUsingIso = _userVmDao.listByIsoId(tInfo.getId()); + List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(tInfo.getId()); //check if there is any Vm using this ISO. if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { //TODO: we cannot directly call deleteTemplateSync here to reuse delete logic since in this case, our db does not have this template at all. @@ -610,6 +622,18 @@ public class TemplateServiceImpl implements TemplateService { long storeId = store.getId(); List rtngTmplts = _templateDao.listAllSystemVMTemplates(); for ( VMTemplateVO tmplt : rtngTmplts ) { + // set template ready state + if ( tmplt.getState() != TemplateState.Ready ){ + try { + imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.CreateRequested, null, + _templateDao); + imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.OperationSucceeded, null, + _templateDao); + } catch (NoTransitionException e) { + // non fatal though + s_logger.debug("failed to update system vm template state to Ready", e); + } + } TemplateDataStoreVO tmpltStore = _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId()); if ( tmpltStore == null ) { tmpltStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, TemplateConstants.DEFAULT_SYSTEM_VM_TEMPLATE_PATH + tmplt.getId() + File.separator, tmplt.getUrl()); diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 1c6e17e8e1b..3fd5930a86e 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -291,46 +291,35 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); } - List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId); - // check if there is any VM using this ISO. - if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { - // get installpath of this template on image store - TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); - String installPath = tmplStore.getInstallPath(); - if (installPath != null) { - DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId()); - EndPoint ep = _epSelector.select(templateObj); - Answer answer = ep.sendMessage(cmd); + // get installpath of this template on image store + TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); + String installPath = tmplStore.getInstallPath(); + if (installPath != null) { + DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId()); + EndPoint ep = _epSelector.select(templateObj); + Answer answer = ep.sendMessage(cmd); - if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to deleted template at store: " + store.getName()); - CommandResult result = new CommandResult(); - result.setSuccess(false); - result.setResult("Delete template failed"); - callback.complete(result); + if (answer == null || !answer.getResult()) { + s_logger.debug("Failed to deleted template at store: " + store.getName()); + CommandResult result = new CommandResult(); + result.setSuccess(false); + result.setResult("Delete template failed"); + callback.complete(result); - } else { - s_logger.debug("Deleted template at: " + installPath); - CommandResult result = new CommandResult(); - result.setSuccess(true); - callback.complete(result); - } + } else { + s_logger.debug("Deleted template at: " + installPath); + CommandResult result = new CommandResult(); + result.setSuccess(true); + callback.complete(result); + } - // for S3, a template can be associated with multiple zones - List templateZones = templateZoneDao - .listByZoneTemplate(sZoneId, templateId); - if (templateZones != null) { - for (VMTemplateZoneVO templateZone : templateZones) { - templateZoneDao.remove(templateZone.getId()); - } + // for S3, a template can be associated with multiple zones + List templateZones = templateZoneDao.listByZoneTemplate(sZoneId, templateId); + if (templateZones != null) { + for (VMTemplateZoneVO templateZone : templateZones) { + templateZoneDao.remove(templateZone.getId()); } } - } else{ - // cannot delete iso due to some VMs are using this - s_logger.debug("Cannot delete iso since some user vms are referencing it"); - CommandResult result = new CommandResult(); - result.setResult("Cannot delete iso since some user vms are referencing it"); - callback.complete(result); } } diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 590b653bdff..b8f666e4725 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -285,48 +285,37 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); } - List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId); - // check if there is any VM using this ISO. - if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { - // get installpath of this template on image store - TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); - String installPath = tmplStore.getInstallPath(); - if (installPath != null) { - DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId()); - EndPoint ep = _epSelector.select(templateObj); - Answer answer = ep.sendMessage(cmd); + // get installpath of this template on image store + TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); + String installPath = tmplStore.getInstallPath(); + if (installPath != null) { + DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId()); + EndPoint ep = _epSelector.select(templateObj); + Answer answer = ep.sendMessage(cmd); - if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to deleted template at store: " + store.getName()); - CommandResult result = new CommandResult(); - //result.setSucess(false); - result.setResult("Delete template failed"); - callback.complete(result); + if (answer == null || !answer.getResult()) { + s_logger.debug("Failed to deleted template at store: " + store.getName()); + CommandResult result = new CommandResult(); + // result.setSucess(false); + result.setResult("Delete template failed"); + callback.complete(result); - } else { - s_logger.debug("Deleted template at: " + installPath); - CommandResult result = new CommandResult(); - //result.setSucess(true); - callback.complete(result); - } + } else { + s_logger.debug("Deleted template at: " + installPath); + CommandResult result = new CommandResult(); + // result.setSucess(true); + callback.complete(result); + } - // for Swift, a template can be associated with multiple zones - List templateZones = templateZoneDao - .listByZoneTemplate(sZoneId, templateId); - if (templateZones != null) { - for (VMTemplateZoneVO templateZone : templateZones) { - templateZoneDao.remove(templateZone.getId()); - } + // for Swift, a template can be associated with multiple zones + List templateZones = templateZoneDao.listByZoneTemplate(sZoneId, templateId); + if (templateZones != null) { + for (VMTemplateZoneVO templateZone : templateZones) { + templateZoneDao.remove(templateZone.getId()); } } - } else{ - // cannot delete iso due to some VMs are using this - s_logger.debug("Cannot delete iso since some user vms are referencing it"); - CommandResult result = new CommandResult(); - result.setResult("Cannot delete iso since some user vms are referencing it"); - callback.complete(result); } - } + } private void deleteSnapshot(DataObject data, AsyncCompletionCallback callback) { SnapshotObject snapshotObj = (SnapshotObject)data; diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index c5e80b01ffe..3e3616fa96b 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -1155,7 +1155,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId); // check if there is any VM using this ISO. - if (!userVmUsingIso.isEmpty()) { + if (userVmUsingIso != null && !userVmUsingIso.isEmpty()) { throw new InvalidParameterValueException("Unable to delete iso, as it's used by other vms"); }