diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
index ea0bad98868..699fd6bd63f 100644
--- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
+++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
@@ -222,6 +222,7 @@
+
@@ -259,7 +260,6 @@
-
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
index 59c338e2803..a3cb76fe123 100644
--- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
+++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
@@ -114,4 +114,6 @@ public interface PrimaryDataStoreDao extends GenericDao {
List findZoneWideStoragePoolsByTags(long dcId, String[] tags);
List findZoneWideStoragePoolsByHypervisor(long dataCenterId, HypervisorType hypervisorType);
+
+ List findLocalStoragePoolsByHostAndTags(long hostId, String[] tags);
}
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
index d35aa440f74..eea07628af8 100644
--- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
+++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
@@ -24,19 +24,21 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import javax.annotation.PostConstruct;
import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
-import org.springframework.stereotype.Component;
-
import com.cloud.host.Status;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.ScopeType;
+import com.cloud.storage.StoragePoolHostVO;
import com.cloud.storage.StoragePoolStatus;
+import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.JoinBuilder;
import com.cloud.utils.db.QueryBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
@@ -45,7 +47,6 @@ import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.TransactionLegacy;
import com.cloud.utils.exception.CloudRuntimeException;
-
@Local(value = { PrimaryDataStoreDao.class })
@DB()
public class PrimaryDataStoreDaoImpl extends GenericDaoBase implements PrimaryDataStoreDao {
@@ -54,8 +55,12 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase
protected final SearchBuilder DcPodAnyClusterSearch;
protected final SearchBuilder DeleteLvmSearch;
protected final GenericSearchBuilder StatusCountSearch;
+ protected SearchBuilder HostSearch;
+ protected SearchBuilder HostPoolSearch;
+ protected SearchBuilder TagPoolSearch;
@Inject protected StoragePoolDetailsDao _detailsDao;
+ @Inject protected StoragePoolHostDao _hostDao;
private final String DetailsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_details ON storage_pool.id = storage_pool_details.pool_id WHERE storage_pool.removed is null and storage_pool.status = 'Up' and storage_pool.data_center_id = ? and (storage_pool.pod_id = ? or storage_pool.pod_id is null) and storage_pool.scope = ? and (";
private final String DetailsSqlSuffix = ") GROUP BY storage_pool_details.pool_id HAVING COUNT(storage_pool_details.name) >= ?";
@@ -112,6 +117,26 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase
}
+ @PostConstruct
+ void init() {
+ HostSearch = createSearchBuilder();
+ TagPoolSearch = _detailsDao.createSearchBuilder();
+ HostPoolSearch = _hostDao.createSearchBuilder();
+ // Search for pools on the host
+ HostPoolSearch.and("hostId", HostPoolSearch.entity().getHostId(), Op.EQ);
+ // Set criteria for pools
+ HostSearch.and("scope", HostSearch.entity().getScope(), Op.EQ);
+ HostSearch.and("removed", HostSearch.entity().getRemoved(), Op.NULL);
+ HostSearch.and("status", HostSearch.entity().getStatus(), Op.EQ);
+ HostSearch.join("hostJoin", HostPoolSearch, HostSearch.entity().getId(), HostPoolSearch.entity().getPoolId(), JoinBuilder.JoinType.INNER);
+ // Set criteria for tags
+ TagPoolSearch.and("name", TagPoolSearch.entity().getName(), Op.EQ);
+ TagPoolSearch.and("value", TagPoolSearch.entity().getValue(), Op.EQ);
+
+ HostSearch.join("tagJoin", TagPoolSearch, HostSearch.entity().getId(), TagPoolSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
+ HostSearch.done();
+ }
+
@Override
public List findPoolByName(String name) {
SearchCriteria sc = AllFieldSearch.create();
@@ -353,6 +378,23 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase
}
}
+ @Override
+ public List findLocalStoragePoolsByHostAndTags(long hostId, String[] tags) {
+
+ SearchCriteria sc = HostSearch.create();
+ sc.setJoinParameters("hostJoin", "hostId", hostId );
+ sc.setParameters("scope", ScopeType.HOST.toString());
+ sc.setParameters("status", Status.Up.toString());
+ if (!(tags == null || tags.length == 0 )) {
+ Map details = tagsToDetails(tags);
+ for (Map.Entry detail : details.entrySet()) {
+ sc.setJoinParameters("tagJoin","name", detail.getKey());
+ sc.setJoinParameters("tagJoin", "value", detail.getValue());
+ }
+ }
+ return listBy(sc);
+ }
+
@Override
@DB
public List searchForStoragePoolDetails(long poolId, String value) {
diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java
index 1f61e8b948d..51ab0feb047 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java
@@ -28,7 +28,6 @@ import javax.naming.ConfigurationException;
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
@@ -73,14 +72,13 @@ public class LocalStoragePoolAllocator extends AbstractStoragePoolAllocator {
if (!dskCh.useLocalStorage()) {
return null;
}
-
List suitablePools = new ArrayList();
// data disk and host identified from deploying vm (attach volume case)
if (dskCh.getType() == Volume.Type.DATADISK && plan.getHostId() != null) {
- List hostPools = _poolHostDao.listByHostId(plan.getHostId());
- for (StoragePoolHostVO hostPool : hostPools) {
- StoragePoolVO pool = _storagePoolDao.findById(hostPool.getPoolId());
+ List hostTagsPools = null;
+ hostTagsPools =_storagePoolDao.findLocalStoragePoolsByHostAndTags(plan.getHostId(), dskCh.getTags());
+ for (StoragePoolVO pool : hostTagsPools) {
if (pool != null && pool.isLocal()) {
StoragePool storagePool = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(pool.getId());
if (filter(avoid, storagePool, dskCh, plan)) {
diff --git a/server/test/resources/createNetworkOffering.xml b/server/test/resources/createNetworkOffering.xml
index c6228dab707..6ae739309b9 100644
--- a/server/test/resources/createNetworkOffering.xml
+++ b/server/test/resources/createNetworkOffering.xml
@@ -46,4 +46,6 @@
+
+