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 489b37d04b7..bd9226ee53f 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
@@ -221,6 +221,7 @@
+
@@ -258,7 +259,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 2c4369d0475..a976bfbf6fe 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
@@ -113,4 +113,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 57afa16b501..7e558f81ea7 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,6 +24,7 @@ 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;
@@ -31,10 +32,13 @@ import javax.naming.ConfigurationException;
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;
@@ -51,9 +55,14 @@ 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 (";
@@ -111,6 +120,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();
@@ -314,6 +343,23 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase
return storagePools;
}
+ @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
public List findZoneWideStoragePoolsByTags(long dcId, String[] tags) {
List storagePools = null;
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 678b2a38073..e988327ce0f 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java
@@ -25,19 +25,17 @@ import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
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;
import com.cloud.capacity.dao.CapacityDao;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.StoragePool;
-import com.cloud.storage.StoragePoolHostVO;
import com.cloud.storage.Volume;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.utils.NumbersUtil;
@@ -76,9 +74,9 @@ public class LocalStoragePoolAllocator extends AbstractStoragePoolAllocator {
// 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 6ae1978f40f..887a8af7245 100644
--- a/server/test/resources/createNetworkOffering.xml
+++ b/server/test/resources/createNetworkOffering.xml
@@ -48,4 +48,6 @@
+
+