You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mc...@apache.org on 2013/05/09 07:12:18 UTC

git commit: updated refs/heads/object_store to fa11575

Updated Branches:
  refs/heads/object_store 545d2e4eb -> fa1157521


Add store_role to template_store_ref, and add search function to find
template_store_ref entry based on DataStoreRole and ZoneId.

Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/fa115752
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/fa115752
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/fa115752

Branch: refs/heads/object_store
Commit: fa1157521238d26bfa572c963adb5b3497f1a2c8
Parents: 545d2e4
Author: Min Chen <mi...@citrix.com>
Authored: Wed May 8 22:06:07 2013 -0700
Committer: Min Chen <mi...@citrix.com>
Committed: Wed May 8 22:06:07 2013 -0700

----------------------------------------------------------------------
 .../subsystem/api/storage/TemplateDataFactory.java |    5 +-
 .../storage/datastore/db/TemplateDataStoreDao.java |    5 +-
 .../storage/datastore/db/TemplateDataStoreVO.java  |  133 ++++++++-------
 .../storage/image/TemplateDataFactoryImpl.java     |   23 ++-
 .../storage/image/TemplateServiceImpl.java         |    9 +-
 .../cloudstack/storage/test/S3TemplateTest.java    |    4 +-
 .../cloudstack/storage/test/SnapshotTest.java      |   18 +-
 .../cloudstack/storage/test/TemplateTest.java      |    6 +-
 .../apache/cloudstack/storage/test/VolumeTest.java |   64 ++++----
 .../datastore/ObjectInDataStoreManagerImpl.java    |    4 +-
 .../storage/image/db/TemplateDataStoreDaoImpl.java |   34 ++++-
 .../src/com/cloud/storage/VolumeManagerImpl.java   |    4 +-
 .../storage/download/DownloadMonitorImpl.java      |    1 +
 .../com/cloud/template/TemplateManagerImpl.java    |    4 +-
 setup/db/db/schema-410to420.sql                    |    1 +
 15 files changed, 191 insertions(+), 124 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa115752/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java
index c2775a3..8916f66 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java
@@ -18,9 +18,12 @@
  */
 package org.apache.cloudstack.engine.subsystem.api.storage;
 
+import com.cloud.storage.DataStoreRole;
+
 
 public interface TemplateDataFactory {
     TemplateInfo getTemplate(long templateId, DataStore store);
     TemplateInfo getTemplate(DataObject obj, DataStore store);
-    TemplateInfo getTemplate(long templateId);
+    TemplateInfo getTemplate(long templateId, DataStoreRole storeRole);
+    TemplateInfo getTemplate(long templateId, DataStoreRole storeRole, Long zoneId);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa115752/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java
index f08f76d..dbb8dbd 100644
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java
@@ -23,6 +23,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
 
 
+import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.VMTemplateStorageResourceAssoc;
 import com.cloud.utils.db.GenericDao;
 import com.cloud.utils.fsm.StateDao;
@@ -50,7 +51,9 @@ public interface TemplateDataStoreDao extends GenericDao<TemplateDataStoreVO, Lo
 
     TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId, boolean lock);
 
-    TemplateDataStoreVO findByTemplate(long templateId);
+    TemplateDataStoreVO findByTemplate(long templateId, DataStoreRole role);
+
+    TemplateDataStoreVO findByTemplateZone(long templateId, Long zoneId, DataStoreRole role);
 
     List<TemplateDataStoreVO> listByTemplate(long templateId);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa115752/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
index 6347e61..ea50d88 100755
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
@@ -33,6 +33,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
 
+import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 
 import com.cloud.utils.db.GenericDaoBase;
@@ -55,6 +56,10 @@ public class TemplateDataStoreVO implements StateObject<ObjectInDataStoreStateMa
 	@Column(name="template_id")
 	private long templateId;
 
+    @Column(name="store_role")
+    @Enumerated(EnumType.STRING)
+    private DataStoreRole dataStoreRole;
+
 	@Column(name=GenericDaoBase.CREATED_COLUMN)
 	private Date created = null;
 
@@ -108,65 +113,7 @@ public class TemplateDataStoreVO implements StateObject<ObjectInDataStoreStateMa
     ObjectInDataStoreStateMachine.State state;
 
 
-	@Override
-    public String getInstallPath() {
-		return installPath;
-	}
-
 
-	@Override
-	public long getDataStoreId() {
-		return dataStoreId;
-	}
-
-	public void setDataStoreId(long storeId) {
-		this.dataStoreId = storeId;
-	}
-
-    public long getTemplateId() {
-		return templateId;
-	}
-
-    public void setTemplateId(long templateId) {
-		this.templateId = templateId;
-	}
-
-    public int getDownloadPercent() {
-		return downloadPercent;
-	}
-
-    public void setDownloadPercent(int downloadPercent) {
-		this.downloadPercent = downloadPercent;
-	}
-
-    public void setDownloadState(Status downloadState) {
-		this.downloadState = downloadState;
-	}
-
-    public long getId() {
-		return id;
-	}
-
-    public Date getCreated() {
-		return created;
-	}
-
-    public Date getLastUpdated() {
-		return lastUpdated;
-	}
-
-    public void setLastUpdated(Date date) {
-	    lastUpdated = date;
-	}
-
-    @Override
-    public void setInstallPath(String installPath) {
-	    this.installPath = installPath;
-	}
-
-    public Status getDownloadState() {
-		return downloadState;
-	}
 
 	public TemplateDataStoreVO(Long hostId, long templateId) {
 		super();
@@ -216,6 +163,65 @@ public class TemplateDataStoreVO implements StateObject<ObjectInDataStoreStateMa
 
 	}
 
+    @Override
+    public String getInstallPath() {
+        return installPath;
+    }
+
+
+    @Override
+    public long getDataStoreId() {
+        return dataStoreId;
+    }
+
+    public void setDataStoreId(long storeId) {
+        this.dataStoreId = storeId;
+    }
+
+    public long getTemplateId() {
+        return templateId;
+    }
+
+    public void setTemplateId(long templateId) {
+        this.templateId = templateId;
+    }
+
+    public int getDownloadPercent() {
+        return downloadPercent;
+    }
+
+    public void setDownloadPercent(int downloadPercent) {
+        this.downloadPercent = downloadPercent;
+    }
+
+    public void setDownloadState(Status downloadState) {
+        this.downloadState = downloadState;
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public Date getCreated() {
+        return created;
+    }
+
+    public Date getLastUpdated() {
+        return lastUpdated;
+    }
+
+    public void setLastUpdated(Date date) {
+        lastUpdated = date;
+    }
+
+    @Override
+    public void setInstallPath(String installPath) {
+        this.installPath = installPath;
+    }
+
+    public Status getDownloadState() {
+        return downloadState;
+    }
 
     public void setLocalDownloadPath(String localPath) {
 		this.localDownloadPath = localPath;
@@ -345,4 +351,15 @@ public class TemplateDataStoreVO implements StateObject<ObjectInDataStoreStateMa
     public State getObjectInStoreState() {
        return this.state;
     }
+
+    public DataStoreRole getDataStoreRole() {
+        return dataStoreRole;
+    }
+
+    public void setDataStoreRole(DataStoreRole dataStoreRole) {
+        this.dataStoreRole = dataStoreRole;
+    }
+
+
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa115752/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java
index 2f65b6b..6f20426 100644
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java
@@ -78,20 +78,31 @@ public class TemplateDataFactoryImpl implements TemplateDataFactory {
         return tmpl;
     }
 
-    // NOTE that this method can only be used for get template information stored in secondary storage
-    //TODO: this method is problematic, since one template can be stored in multiple image stores.
-    // need to see if we can get rid of this method or change to plural format, or restrict to 1:1 mapping
+
     @Override
-    public TemplateInfo getTemplate(long templateId) {
+    public TemplateInfo getTemplate(long templateId, DataStoreRole storeRole) {
         VMTemplateVO templ = imageDataDao.findById(templateId);
-        TemplateDataStoreVO tmplStore = templateStoreDao.findByTemplate(templateId);
+        TemplateDataStoreVO tmplStore = templateStoreDao.findByTemplate(templateId, storeRole);
         DataStore store = null;
         if ( tmplStore != null ){
-            store = this.storeMgr.getDataStore(tmplStore.getDataStoreId(), DataStoreRole.Image);
+            store = this.storeMgr.getDataStore(tmplStore.getDataStoreId(), storeRole);
         }
         return this.getTemplate(templateId, store);
     }
 
+
+    @Override
+    public TemplateInfo getTemplate(long templateId, DataStoreRole storeRole, Long zoneId) {
+        VMTemplateVO templ = imageDataDao.findById(templateId);
+        TemplateDataStoreVO tmplStore = templateStoreDao.findByTemplateZone(templateId, zoneId, storeRole);
+        DataStore store = null;
+        if ( tmplStore != null ){
+            store = this.storeMgr.getDataStore(tmplStore.getDataStoreId(), storeRole);
+        }
+        return this.getTemplate(templateId, store);
+    }
+
+
     @Override
     public TemplateInfo getTemplate(DataObject obj, DataStore store) {
         return this.getTemplate(obj.getId(), store);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa115752/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
----------------------------------------------------------------------
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 b8e8184..988aaa7 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
@@ -73,6 +73,7 @@ import com.cloud.exception.ResourceAllocationException;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.storage.StoragePool;
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.VMTemplateZoneVO;
 import com.cloud.storage.dao.VMTemplateDao;
@@ -189,7 +190,7 @@ public class TemplateServiceImpl implements TemplateService {
         for (VMTemplateVO template : toBeDownloaded) {
             TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId());
             if (tmpltHost == null || tmpltHost.getState() != ObjectInDataStoreStateMachine.State.Ready) {
-            	TemplateInfo tmplt = this._templateFactory.getTemplate(template.getId());
+            	TemplateInfo tmplt = this._templateFactory.getTemplate(template.getId(), DataStoreRole.Image);
                 this.createTemplateAsync(tmplt, store, null);
             }
         }
@@ -224,7 +225,7 @@ public class TemplateServiceImpl implements TemplateService {
             for (VMTemplateVO template: toBeDownloaded) {
                 TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId());
                 if (tmpltHost == null || tmpltHost.getState() != ObjectInDataStoreStateMachine.State.Ready) {
-                    TemplateInfo tmplt = this._templateFactory.getTemplate(template.getId());
+                    TemplateInfo tmplt = this._templateFactory.getTemplate(template.getId(), DataStoreRole.Image);
                     this.createTemplateAsync(tmplt, store, null);
                 }
             }
@@ -328,6 +329,7 @@ public class TemplateServiceImpl implements TemplateService {
                     tmpltStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, tmpltInfo.getInstallPath(), tmplt.getUrl());
                     tmpltStore.setSize(tmpltInfo.getSize());
                     tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize());
+                    tmpltStore.setDataStoreRole(store.getRole());
                     _vmTemplateStoreDao.persist(tmpltStore);
                     this.associateTemplateToZone(tmplt.getId(), zoneId);
                 }
@@ -381,7 +383,7 @@ public class TemplateServiceImpl implements TemplateService {
                     }
                     s_logger.debug("Template " + tmplt.getName() + " needs to be downloaded to " + store.getName());
                     //TODO: we should pass a callback here
-                    TemplateInfo tmpl = this._templateFactory.getTemplate(tmplt.getId());
+                    TemplateInfo tmpl = this._templateFactory.getTemplate(tmplt.getId(), DataStoreRole.Image);
                     this.createTemplateAsync(tmpl, store, null);
                 }
             }
@@ -580,6 +582,7 @@ public class TemplateServiceImpl implements TemplateService {
                 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());
                 tmpltStore.setSize(0);
                 tmpltStore.setPhysicalSize(0); // no size information for pre-seeded system vm templates
+                tmpltStore.setDataStoreRole(store.getRole());
                 _vmTemplateStoreDao.persist(tmpltStore);
             }
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa115752/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java
index 8c4eae5..07a63c9 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java
@@ -137,7 +137,7 @@ public class S3TemplateTest extends CloudStackTestNGBase {
 
 	@Test(priority = 1)
 	public void registerTemplate() {
-		TemplateInfo template = templateFactory.getTemplate(templateId);
+		TemplateInfo template = templateFactory.getTemplate(templateId, DataStoreRole.Image);
 		DataStore store = dataStoreMgr.getImageStore(dcId);
 		AsyncCallFuture<TemplateApiResult> future = new AsyncCallFuture<TemplateApiResult>();
 		templateSvr.createTemplateAsync(template, store, future);
@@ -157,7 +157,7 @@ public class S3TemplateTest extends CloudStackTestNGBase {
 
     @Test(priority = 2)
     public void copyTemplateToCache() {
-        TemplateInfo template = templateFactory.getTemplate(templateId);
+        TemplateInfo template = templateFactory.getTemplate(templateId, DataStoreRole.Image);
         DataObject cacheObj = this.cacheMgr.createCacheObject(template, new ZoneScope(dcId));
         assertNotNull(cacheObj, "failed to create cache object");
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa115752/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
index 9dc6854..acd32b4 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
@@ -240,7 +240,7 @@ public class SnapshotTest extends CloudStackTestNGBase {
 
 
         DataStore store = this.dataStoreMgr.getDataStore(imageStore.getId(), DataStoreRole.Image);
-        TemplateInfo template = templateFactory.getTemplate(image.getId());
+        TemplateInfo template = templateFactory.getTemplate(image.getId(), DataStoreRole.Image);
         DataObject templateOnStore = store.create(template);
         TemplateObjectTO to = new TemplateObjectTO();
         to.setPath(this.getImageInstallPath());
@@ -313,7 +313,7 @@ public class SnapshotTest extends CloudStackTestNGBase {
             return null;
         }
     }
-    
+
     private SnapshotVO createSnapshotInDb(VolumeInfo volume) {
         Snapshot.Type snapshotType = Snapshot.Type.MANUAL;
         SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), 2, 1, volume.getId(), 1L, UUID.randomUUID().toString(),
@@ -336,7 +336,7 @@ public class SnapshotTest extends CloudStackTestNGBase {
         primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
         VolumeVO volume = createVolume(image.getId(), primaryStore.getId());
         VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
-        AsyncCallFuture<VolumeApiResult> future = this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId()));
+        AsyncCallFuture<VolumeApiResult> future = this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId(), DataStoreRole.Image));
 
         VolumeApiResult result;
         try {
@@ -351,7 +351,7 @@ public class SnapshotTest extends CloudStackTestNGBase {
         }
         return null;
     }
-    
+
     @Test
     public void createSnapshot() {
         VolumeInfo vol = createCopyBaseImage();
@@ -363,11 +363,11 @@ public class SnapshotTest extends CloudStackTestNGBase {
             }
         }
     }
-    
+
     private VMTemplateVO createTemplateInDb() {
         image = new VMTemplateVO();
         image.setTemplateType(TemplateType.USER);
-      
+
         image.setUniqueName(UUID.randomUUID().toString());
         image.setName(UUID.randomUUID().toString());
         image.setPublicTemplate(true);
@@ -385,7 +385,7 @@ public class SnapshotTest extends CloudStackTestNGBase {
         image = imageDataDao.persist(image);
         return image;
     }
-    
+
     @Test
     public void createTemplateFromSnapshot() {
         VolumeInfo vol = createCopyBaseImage();
@@ -398,13 +398,13 @@ public class SnapshotTest extends CloudStackTestNGBase {
                 result = true;
             }
         }
-        
+
         AssertJUnit.assertTrue(result);
         LocalHostEndpoint ep = new LocalHostEndpoint();
         ep.setResource(new MockLocalNfsSecondaryStorageResource());
         Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep);
         VMTemplateVO templateVO = createTemplateInDb();
-        TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId());
+        TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId(), DataStoreRole.Image);
         DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId);
         this.imageService.createTemplateFromSnapshotAsync(snapshot, tmpl, imageStore);
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa115752/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java
index 294d4b5..ad4313a 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java
@@ -68,7 +68,7 @@ public class TemplateTest extends CloudStackTestNGBase {
 	@Test(priority = -1)
 	public void setUp() {
 		ComponentContext.initComponentsLifeCycle();
-	     
+
 		//create data center
 		DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null,  "10.0.0.1/24",
 				null, null, NetworkType.Basic, null, null, true,  true, null, null);
@@ -117,7 +117,7 @@ public class TemplateTest extends CloudStackTestNGBase {
 
 	@Test
 	public void registerTemplate() {
-		TemplateInfo template = templateFactory.getTemplate(templateId);
+		TemplateInfo template = templateFactory.getTemplate(templateId, DataStoreRole.Image);
 		DataStore store = dataStoreMgr.getImageStore(dcId);
 		AsyncCallFuture<TemplateApiResult> future = new AsyncCallFuture<TemplateApiResult>();
 		templateSvr.createTemplateAsync(template, store, future);
@@ -137,7 +137,7 @@ public class TemplateTest extends CloudStackTestNGBase {
 
    // @Test
     public void deleteTemplate() {
-        TemplateInfo template = templateFactory.getTemplate(templateId);
+        TemplateInfo template = templateFactory.getTemplate(templateId, DataStoreRole.Image);
         DataStore store = dataStoreMgr.getImageStore(dcId);
         AsyncCallFuture<TemplateApiResult> future = new AsyncCallFuture<TemplateApiResult>();
         templateSvr.deleteTemplateAsync(template);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa115752/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java
index a354959..fe62879 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java
@@ -146,7 +146,7 @@ public class VolumeTest extends CloudStackTestNGBase {
     @Test(priority = -1)
     public void setUp() {
         ComponentContext.initComponentsLifeCycle();
-  
+
         host = hostDao.findByGuid(this.getHostGuid());
         if (host != null) {
             dcId = host.getDataCenterId();
@@ -188,7 +188,7 @@ public class VolumeTest extends CloudStackTestNGBase {
             host.setClusterId(cluster.getId());
 
             host = hostDao.persist(host);
-            
+
             imageStore = new ImageStoreVO();
             imageStore.setName(imageStoreName);
             imageStore.setDataCenterId(dcId);
@@ -199,7 +199,7 @@ public class VolumeTest extends CloudStackTestNGBase {
             imageStore.setProtocol("nfs");
             imageStore = imageStoreDao.persist(imageStore);
         }
-       
+
         image = new VMTemplateVO();
         image.setTemplateType(TemplateType.USER);
         image.setUrl(this.getTemplateUrl());
@@ -219,9 +219,9 @@ public class VolumeTest extends CloudStackTestNGBase {
         image.setExtractable(true);
 
         image = imageDataDao.persist(image);
-        
+
         /*TemplateDataStoreVO templateStore = new TemplateDataStoreVO();
-        
+
         templateStore.setDataStoreId(imageStore.getId());
         templateStore.setDownloadPercent(100);
         templateStore.setDownloadState(Status.DOWNLOADED);
@@ -229,32 +229,32 @@ public class VolumeTest extends CloudStackTestNGBase {
         templateStore.setInstallPath(this.getImageInstallPath());
         templateStore.setTemplateId(image.getId());
         templateStoreDao.persist(templateStore);*/
-        
-        
+
+
         DataStore store = this.dataStoreMgr.getDataStore(imageStore.getId(), DataStoreRole.Image);
-        TemplateInfo template = templateFactory.getTemplate(image.getId());
+        TemplateInfo template = templateFactory.getTemplate(image.getId(), DataStoreRole.Image);
         DataObject templateOnStore = store.create(template);
         TemplateObjectTO to = new TemplateObjectTO();
         to.setPath(this.getImageInstallPath());
         CopyCmdAnswer answer = new CopyCmdAnswer(to);
         templateOnStore.processEvent(Event.CreateOnlyRequested);
         templateOnStore.processEvent(Event.OperationSuccessed, answer);
-        
-       
+
+
     }
-    
+
     @Override
     protected void injectMockito() {
         List<HostVO> hosts = new ArrayList<HostVO>();
         hosts.add(this.host);
         Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type) Mockito.any(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(hosts);
-        
+
         RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress());
         Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep);
         Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(ep);
         Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep);
     }
-    
+
     public DataStore createPrimaryDataStore() {
         try {
             String uuid = UUID.nameUUIDFromBytes(this.getPrimaryStorageUrl().getBytes()).toString();
@@ -262,7 +262,7 @@ public class VolumeTest extends CloudStackTestNGBase {
             if (pools.size() > 0) {
                 return this.dataStoreMgr.getPrimaryDataStore(pools.get(0).getId());
             }
-            
+
             /*DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("cloudstack primary data store provider");
             Map<String, Object> params = new HashMap<String, Object>();
             URI uri = new URI(this.getPrimaryStorageUrl());
@@ -283,7 +283,7 @@ public class VolumeTest extends CloudStackTestNGBase {
             DataStore store = lifeCycle.initialize(params);
             ClusterScope scope = new ClusterScope(clusterId, podId, dcId);
             lifeCycle.attachCluster(store, scope);*/
-            
+
             StoragePoolVO pool = new StoragePoolVO();
             pool.setClusterId(clusterId);
             pool.setDataCenterId(dcId);
@@ -305,14 +305,14 @@ public class VolumeTest extends CloudStackTestNGBase {
             return null;
         }
     }
-    
+
     private VolumeVO createVolume(Long templateId, long dataStoreId) {
         VolumeVO volume = new VolumeVO(1000, new RootDisk().toString(), UUID.randomUUID().toString(), templateId);
         volume.setPoolId(dataStoreId);
         volume = volumeDao.persist(volume);
         return volume;
     }
-    
+
     //@Test
     public void testCopyBaseImage() {
         DataStore primaryStore = createPrimaryDataStore();
@@ -320,12 +320,12 @@ public class VolumeTest extends CloudStackTestNGBase {
         primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
         VolumeVO volume = createVolume(image.getId(), primaryStore.getId());
         VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
-        AsyncCallFuture<VolumeApiResult> future = this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId()));
+        AsyncCallFuture<VolumeApiResult> future = this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId(), DataStoreRole.Image));
         try {
             VolumeApiResult result = future.get();
-        
+
             AssertJUnit.assertTrue(result.isSuccess());
-          
+
             VolumeInfo newVol = result.getVolume();
             this.volumeService.destroyVolume(newVol.getId());
             VolumeInfo vol = this.volFactory.getVolume(volume.getId());
@@ -341,7 +341,7 @@ public class VolumeTest extends CloudStackTestNGBase {
             e.printStackTrace();
         }
     }
-    
+
     @Test
     public void testCreateDataDisk() {
         DataStore primaryStore = createPrimaryDataStore();
@@ -351,7 +351,7 @@ public class VolumeTest extends CloudStackTestNGBase {
         VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
         this.volumeService.createVolumeAsync(volInfo, primaryStore);
     }
-    
+
     @Test
     public void testDeleteDisk() {
         DataStore primaryStore = createPrimaryDataStore();
@@ -363,7 +363,7 @@ public class VolumeTest extends CloudStackTestNGBase {
         try {
             VolumeApiResult result = future.get();
             VolumeInfo vol = result.getVolume();
-            
+
             this.volumeService.destroyVolume(volInfo.getId());
             volInfo = this.volFactory.getVolume(vol.getId());
             this.volumeService.expungeVolumeAsync(volInfo);
@@ -377,13 +377,13 @@ public class VolumeTest extends CloudStackTestNGBase {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
-        
+
     }
-    
+
     private VMTemplateVO createTemplateInDb() {
         image = new VMTemplateVO();
         image.setTemplateType(TemplateType.USER);
-      
+
         image.setUniqueName(UUID.randomUUID().toString());
         image.setName(UUID.randomUUID().toString());
         image.setPublicTemplate(true);
@@ -401,7 +401,7 @@ public class VolumeTest extends CloudStackTestNGBase {
         image = imageDataDao.persist(image);
         return image;
     }
-    
+
     @Test
     public void testCreateTemplateFromVolume() {
         DataStore primaryStore = createPrimaryDataStore();
@@ -412,13 +412,13 @@ public class VolumeTest extends CloudStackTestNGBase {
         AsyncCallFuture<VolumeApiResult> future = this.volumeService.createVolumeAsync(volInfo, primaryStore);
         try {
             VolumeApiResult result = future.get();
-            
+
             AssertJUnit.assertTrue(result.isSuccess());
             volInfo = result.getVolume();
             VMTemplateVO templateVO = createTemplateInDb();
-            TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId());
+            TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId(), DataStoreRole.Image);
             DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId);
-            
+
             this.imageService.createTemplateFromVolumeAsync(volInfo, tmpl, imageStore);
         } catch (InterruptedException e) {
             // TODO Auto-generated catch block
@@ -427,7 +427,7 @@ public class VolumeTest extends CloudStackTestNGBase {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
-        
-        
+
+
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa115752/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
index 462537f..f0b54e1 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
@@ -303,7 +303,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
             DataObjectInStore vo = null;
             switch (type){
             case TEMPLATE:
-                vo = templateDataStoreDao.findByTemplate(objId);
+                vo = templateDataStoreDao.findByTemplate(objId, role);
                 break;
             case SNAPSHOT:
                 vo = snapshotDataStoreDao.findBySnapshot(objId, role);
@@ -313,7 +313,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
                 break;
             }
             if (vo != null) {
-                store = this.storeMgr.getDataStore(vo.getDataStoreId(), DataStoreRole.Image);
+                store = this.storeMgr.getDataStore(vo.getDataStoreId(), role);
             }
         }
         return store;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa115752/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java
index aa84821..345098c 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java
@@ -35,6 +35,7 @@ import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
 
+import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 import com.cloud.utils.db.GenericDaoBase;
 import com.cloud.utils.db.SearchBuilder;
@@ -51,6 +52,7 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
     private SearchBuilder<TemplateDataStoreVO> updateStateSearch;
     private SearchBuilder<TemplateDataStoreVO> storeSearch;
     private SearchBuilder<TemplateDataStoreVO> templateSearch;
+    private SearchBuilder<TemplateDataStoreVO> templateRoleSearch;
     private SearchBuilder<TemplateDataStoreVO> storeTemplateSearch;
     private SearchBuilder<TemplateDataStoreVO> storeTemplateStateSearch;
     private SearchBuilder<TemplateDataStoreVO> storeTemplateDownloadStatusSearch;
@@ -73,6 +75,12 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
         templateSearch.and("destroyed", templateSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
         templateSearch.done();
 
+        templateRoleSearch = createSearchBuilder();
+        templateRoleSearch.and("template_id", templateRoleSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
+        templateRoleSearch.and("store_role", templateRoleSearch.entity().getDataStoreRole(), SearchCriteria.Op.EQ);
+        templateRoleSearch.and("destroyed", templateRoleSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
+        templateRoleSearch.done();
+
 
     	updateStateSearch = this.createSearchBuilder();
         updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ);
@@ -263,10 +271,12 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
             return lockOneRandomRow(sc, true);
     }
 
+
     @Override
-    public TemplateDataStoreVO findByTemplate(long templateId) {
-        SearchCriteria<TemplateDataStoreVO> sc = templateSearch.create();
+    public TemplateDataStoreVO findByTemplate(long templateId, DataStoreRole role) {
+        SearchCriteria<TemplateDataStoreVO> sc = templateRoleSearch.create();
         sc.setParameters("template_id", templateId);
+        sc.setParameters("store_role", role);
         sc.setParameters("destroyed", false);
         return findOneIncludingRemovedBy(sc);
     }
@@ -279,6 +289,24 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
         return search(sc, null);
     }
 
-
+    @Override
+    public TemplateDataStoreVO findByTemplateZone(long templateId, Long zoneId, DataStoreRole role) {
+        // get all elgible image stores
+        List<DataStore> imgStores = null;
+        if ( role == DataStoreRole.Image){
+            imgStores = this._storeMgr.getImageStoresByScope(new ZoneScope(zoneId));
+        } else if (role == DataStoreRole.ImageCache){
+            imgStores = this._storeMgr.getImageCacheStores(new ZoneScope(zoneId));
+        }
+        if ( imgStores != null ){
+            for (DataStore store : imgStores){
+                List<TemplateDataStoreVO> sRes = this.listByTemplateStore(templateId, store.getId());
+                if ( sRes != null && sRes.size() > 0){
+                    return sRes.get(0);
+                }
+            }
+        }
+        return null;
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa115752/server/src/com/cloud/storage/VolumeManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java
index 828f34a..90b2366 100644
--- a/server/src/com/cloud/storage/VolumeManagerImpl.java
+++ b/server/src/com/cloud/storage/VolumeManagerImpl.java
@@ -671,7 +671,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
         if (isNotCreatedFromTemplate) {
             future = this.volService.createVolumeAsync(volume, store);
         } else {
-            TemplateInfo templ = this.tmplFactory.getTemplate(template.getId());
+            TemplateInfo templ = this.tmplFactory.getTemplate(template.getId(), DataStoreRole.Image);
             future = this.volService.createVolumeFromTemplateAsync(volume, store.getId(), templ);
         }
         try {
@@ -2266,7 +2266,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
         if (templateId == null) {
             future = this.volService.createVolumeAsync(volume, destPool);
         } else {
-            TemplateInfo templ = this.tmplFactory.getTemplate(templateId);
+            TemplateInfo templ = this.tmplFactory.getTemplate(templateId, DataStoreRole.Image);
             future = this.volService.createVolumeFromTemplateAsync(volume, destPool.getId(), templ);
         }
         VolumeApiResult result = null;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa115752/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
index 09dbae3..9168aad 100755
--- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
+++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
@@ -174,6 +174,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
         if (vmTemplateStore == null) {
             vmTemplateStore = new TemplateDataStoreVO(store.getId(), template.getId(), new Date(), 0,
                     VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, template.getUri());
+            vmTemplateStore.setDataStoreRole(store.getRole());
             _vmTemplateStoreDao.persist(vmTemplateStore);
         } else if ((vmTemplateStore.getJobId() != null) && (vmTemplateStore.getJobId().length() > 2)) {
             downloadJobExists = true;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa115752/server/src/com/cloud/template/TemplateManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java
index 46c4c0a..20cdce1 100755
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java
@@ -1348,7 +1348,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         VolumeVO volume = null;
 
         try {
-            TemplateInfo tmplInfo = this._tmplFactory.getTemplate(templateId);
+            TemplateInfo tmplInfo = this._tmplFactory.getTemplate(templateId, DataStoreRole.Image);
             Long zoneId = null;
             if (snapshotId != null) {
                 snapshot = _snapshotDao.findById(snapshotId);
@@ -1384,7 +1384,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
                     s_logger.debug("Failed to create template" + result.getResult());
                     throw new CloudRuntimeException("Failed to create template" + result.getResult());
                 }
-                
+
                 VMTemplateZoneVO templateZone = new VMTemplateZoneVO(zoneId, templateId, new Date());
                 this._tmpltZoneDao.persist(templateZone);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa115752/setup/db/db/schema-410to420.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql
index a88af23..6ce0d2d 100644
--- a/setup/db/db/schema-410to420.sql
+++ b/setup/db/db/schema-410to420.sql
@@ -128,6 +128,7 @@ CREATE TABLE  `cloud`.`template_store_ref` (
   `job_id` varchar(255),
   `download_pct` int(10) unsigned,
   `size` bigint unsigned,
+  `store_role` varchar(255),  
   `physical_size` bigint unsigned DEFAULT 0,
   `download_state` varchar(255),
   `error_str` varchar(255),