diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java index c3d44bdb6aa..700ccf574b6 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java @@ -66,7 +66,7 @@ public interface VMTemplateDao extends GenericDao { VMTemplateVO findSystemVMTemplate(long zoneId); - VMTemplateVO findSystemVMTemplate(long zoneId, HypervisorType hType); + VMTemplateVO findSystemVMReadyTemplate(long zoneId, HypervisorType hypervisorType); VMTemplateVO findRoutingTemplate(HypervisorType type, String templateName); diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java index 9e7599052a7..924322583f0 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -23,11 +23,15 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Collections; import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.storage.VMTemplateStorageResourceAssoc; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -75,6 +79,8 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem DomainDao _domainDao; @Inject DataCenterDao _dcDao; + @Inject + TemplateDataStoreDao _templateDataStoreDao; private static final String SELECT_S3_CANDIDATE_TEMPLATES = "SELECT t.id, t.unique_name, t.name, t.public, t.featured, " + "t.type, t.hvm, t.bits, t.url, t.format, t.created, t.account_id, t.checksum, t.display_text, " @@ -87,6 +93,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem protected SearchBuilder UniqueNameSearch; protected SearchBuilder tmpltTypeSearch; protected SearchBuilder tmpltTypeHyperSearch; + protected SearchBuilder readySystemTemplateSearch; protected SearchBuilder tmpltTypeHyperSearch2; protected SearchBuilder AccountIdSearch; @@ -326,6 +333,23 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem hostHyperSearch.done(); tmpltTypeHyperSearch.done(); + readySystemTemplateSearch = createSearchBuilder(); + readySystemTemplateSearch.and("templateType", readySystemTemplateSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); + SearchBuilder templateDownloadSearch = _templateDataStoreDao.createSearchBuilder(); + templateDownloadSearch.and("downloadState", templateDownloadSearch.entity().getDownloadState(), SearchCriteria.Op.EQ); + readySystemTemplateSearch.join("vmTemplateJoinTemplateStoreRef", templateDownloadSearch, templateDownloadSearch.entity().getTemplateId(), + readySystemTemplateSearch.entity().getId(), JoinBuilder.JoinType.INNER); + SearchBuilder hostHyperSearch2 = _hostDao.createSearchBuilder(); + hostHyperSearch2.and("type", hostHyperSearch2.entity().getType(), SearchCriteria.Op.EQ); + hostHyperSearch2.and("zoneId", hostHyperSearch2.entity().getDataCenterId(), SearchCriteria.Op.EQ); + hostHyperSearch2.and("removed", hostHyperSearch2.entity().getRemoved(), SearchCriteria.Op.NULL); + hostHyperSearch2.groupBy(hostHyperSearch2.entity().getHypervisorType()); + + readySystemTemplateSearch.join("tmplHyper", hostHyperSearch2, hostHyperSearch2.entity().getHypervisorType(), + readySystemTemplateSearch.entity().getHypervisorType(), JoinBuilder.JoinType.INNER); + hostHyperSearch2.done(); + readySystemTemplateSearch.done(); + tmpltTypeHyperSearch2 = createSearchBuilder(); tmpltTypeHyperSearch2.and("templateType", tmpltTypeHyperSearch2.entity().getTemplateType(), SearchCriteria.Op.EQ); @@ -764,22 +788,27 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem } @Override - public VMTemplateVO findSystemVMTemplate(long zoneId, HypervisorType hType) { - SearchCriteria sc = tmpltTypeHyperSearch.create(); + public VMTemplateVO findSystemVMReadyTemplate(long zoneId, HypervisorType hypervisorType) { + SearchCriteria sc = readySystemTemplateSearch.create(); sc.setParameters("templateType", Storage.TemplateType.SYSTEM); sc.setJoinParameters("tmplHyper", "type", Host.Type.Routing); sc.setJoinParameters("tmplHyper", "zoneId", zoneId); + sc.setJoinParameters("vmTemplateJoinTemplateStoreRef", "downloadState", VMTemplateStorageResourceAssoc.Status.DOWNLOADED); // order by descending order of id List tmplts = listBy(sc, new Filter(VMTemplateVO.class, "id", false, null, null)); - for (VMTemplateVO tmplt : tmplts) { - if (tmplt.getHypervisorType() == hType) { - return tmplt; + if (tmplts.size() > 0) { + if (hypervisorType == HypervisorType.Any) { + Collections.shuffle(tmplts); + return tmplts.get(0); } - } - if (tmplts.size() > 0 && hType == HypervisorType.Any) { - return tmplts.get(0); + for (VMTemplateVO tmplt : tmplts) { + if (tmplt.getHypervisorType() == hypervisorType) { + return tmplt; + } + } + } return null; } diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 7c6fbd0677b..adc7ef727d6 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -656,9 +656,22 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy s_logger.warn("The number of launched console proxy on zone " + dataCenterId + " has reached to limit"); return null; } - HypervisorType defaultHype = _resourceMgr.getAvailableHypervisor(dataCenterId); - Map context = createProxyInstance(dataCenterId, defaultHype); + VMTemplateVO template = null; + HypervisorType defaultHypervisor = _resourceMgr.getDefaultHypervisor(dataCenterId); + if (defaultHypervisor != HypervisorType.None) { + template = _templateDao.findSystemVMReadyTemplate(dataCenterId, defaultHypervisor); + if (template == null) { + throw new CloudRuntimeException("Not able to find the System template or not downloaded in zone " + dataCenterId + " corresponding to default System vm hypervisor " + defaultHypervisor); + } + } else { + template = _templateDao.findSystemVMReadyTemplate(dataCenterId, HypervisorType.Any); + if (template == null) { + throw new CloudRuntimeException("Not able to find the System templates or not downloaded in zone " + dataCenterId); + } + } + + Map context = createProxyInstance(dataCenterId, template); long proxyVmId = (Long) context.get("proxyVmId"); if (proxyVmId == 0) { @@ -684,7 +697,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy return null; } - protected Map createProxyInstance(long dataCenterId, HypervisorType desiredHyp) throws ConcurrentOperationException { + protected Map createProxyInstance(long dataCenterId, VMTemplateVO template) throws ConcurrentOperationException { long id = _consoleProxyDao.getNextInSequence(Long.class, "id"); String name = VirtualMachineName.getConsoleProxyName(id, _instance); @@ -727,12 +740,6 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy networks.add(new Pair(_networkMgr.setupNetwork(systemAcct, offering, plan, null, null, false).get(0), null)); } - VMTemplateVO template = _templateDao.findSystemVMTemplate(dataCenterId, desiredHyp); - if (template == null) { - s_logger.debug("Can't find a template to start"); - throw new CloudRuntimeException("Insufficient capacity exception"); - } - ConsoleProxyVO proxy = new ConsoleProxyVO(id, _serviceOffering.getId(), name, template.getId(), template.getHypervisorType(), template.getGuestOSId(), dataCenterId, systemAcct.getDomainId(), systemAcct.getId(), 0, _serviceOffering.getOfferHA()); proxy.setDynamicallyScalable(template.isDynamicallyScalable()); diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index b10fb7a8d38..b7a73933c02 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -37,6 +37,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.utils.identity.ManagementServerNode; import com.cloud.agent.AgentManager; @@ -233,6 +234,8 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar DataStoreManager _dataStoreMgr; @Inject ImageStoreDao _imageStoreDao; + @Inject + TemplateDataStoreDao _tmplStoreDao; private long _capacityScanInterval = DEFAULT_CAPACITY_SCAN_INTERVAL; private int _secStorageVmMtuSize; @@ -563,12 +566,18 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar return new HashMap(); } - HypervisorType hypeType = _resourceMgr.getAvailableHypervisor(dataCenterId); - - VMTemplateVO template = _templateDao.findSystemVMTemplate(dataCenterId, hypeType); - if (template == null) { - s_logger.debug("Can't find a template to start"); - throw new CloudRuntimeException("Insufficient capacity exception"); + VMTemplateVO template = null; + HypervisorType defaultHypervisor = _resourceMgr.getDefaultHypervisor(dataCenterId); + if (defaultHypervisor != HypervisorType.None) { + template = _templateDao.findSystemVMReadyTemplate(dataCenterId, defaultHypervisor); + if (template == null) { + throw new CloudRuntimeException("Not able to find the System template or not downloaded in zone " + dataCenterId + " corresponding to default System vm hypervisor " + defaultHypervisor); + } + } else { + template = _templateDao.findSystemVMReadyTemplate(dataCenterId, HypervisorType.Any); + if (template == null) { + throw new CloudRuntimeException("Not able to find the System templates or not downloaded in zone " + dataCenterId); + } } SecondaryStorageVmVO secStorageVm = new SecondaryStorageVmVO(id, _serviceOffering.getId(), name, template.getId(), template.getHypervisorType(), template.getGuestOSId(), dataCenterId,