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/04/21 05:45:02 UTC

git commit: updated refs/heads/object_store to 0229c75

Updated Branches:
  refs/heads/object_store 86913ab4d -> 0229c75b5


Use data motion service for PrepareTemplateCmd to move template from
secondary storage to primary.

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

Branch: refs/heads/object_store
Commit: 0229c75b50a008a86ded801ff98617adb24c56da
Parents: 86913ab
Author: Min Chen <mi...@citrix.com>
Authored: Sat Apr 20 20:44:31 2013 -0700
Committer: Min Chen <mi...@citrix.com>
Committed: Sat Apr 20 20:44:31 2013 -0700

----------------------------------------------------------------------
 .../subsystem/api/storage/TemplateService.java     |    5 +-
 .../storage/image/TemplateServiceImpl.java         |   74 +++++++++-
 .../com/cloud/template/TemplateManagerImpl.java    |  126 +++++----------
 3 files changed, 118 insertions(+), 87 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0229c75b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java
index 2fc6d3d..d7010fd 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java
@@ -24,6 +24,7 @@ import org.apache.cloudstack.framework.async.AsyncCallFuture;
 
 
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.StoragePool;
 
 public interface TemplateService {
 
@@ -43,8 +44,8 @@ public interface TemplateService {
     AsyncCallFuture<TemplateApiResult> createTemplateFromSnapshotAsync(SnapshotInfo snapshot, TemplateInfo template, DataStore store);
     AsyncCallFuture<TemplateApiResult> createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, DataStore store);
     AsyncCallFuture<TemplateApiResult> deleteTemplateAsync(TemplateInfo template);
-    AsyncCallFuture<TemplateApiResult> copyTemplate(TemplateInfo srcTemplate,
-            DataStore destStore);
+    AsyncCallFuture<TemplateApiResult> copyTemplate(TemplateInfo srcTemplate, DataStore destStore);
+    AsyncCallFuture<TemplateApiResult> prepareTemplateOnPrimary(TemplateInfo srcTemplate, StoragePool pool );
 
     void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId);
     void handleTemplateSync(DataStore store);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0229c75b/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 ccdcc5a..04003bf 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
@@ -74,12 +74,14 @@ import com.cloud.exception.ResourceAllocationException;
 import com.cloud.host.HostVO;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.storage.StoragePool;
+import com.cloud.storage.VMTemplateStoragePoolVO;
 import com.cloud.storage.VMTemplateStorageResourceAssoc;
 import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.VMTemplateZoneVO;
 import com.cloud.storage.VolumeVO;
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VMTemplatePoolDao;
 import com.cloud.storage.dao.VMTemplateZoneDao;
 import com.cloud.storage.dao.VolumeDao;
 import com.cloud.storage.download.DownloadMonitor;
@@ -87,6 +89,7 @@ import com.cloud.storage.secondary.SecondaryStorageVmManager;
 import com.cloud.user.AccountManager;
 import com.cloud.user.ResourceLimitService;
 import com.cloud.utils.UriUtils;
+import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.fsm.NoTransitionException;
 import com.cloud.vm.UserVmVO;
 import com.cloud.vm.dao.UserVmDao;
@@ -132,6 +135,7 @@ public class TemplateServiceImpl implements TemplateService {
     VolumeDao _volumeDao;
     @Inject
     TemplateDataFactory _templateFactory;
+    @Inject VMTemplatePoolDao _tmpltPoolDao;
 
 
 
@@ -559,7 +563,7 @@ public class TemplateServiceImpl implements TemplateService {
             .setContext(context);
             this._motionSrv.copyAsync(srcTemplate, destTemplate, caller);
         } catch (Exception e) {
-            s_logger.debug("Failed to copy volume", e);
+            s_logger.debug("Failed to copy template", e);
             res.setResult(e.toString());
             future.complete(res);
         }
@@ -597,6 +601,74 @@ public class TemplateServiceImpl implements TemplateService {
         return null;
     }
 
+    protected Void prepareTemplateCallBack(AsyncCallbackDispatcher<TemplateServiceImpl, CopyCommandResult> callback,
+            CopyTemplateContext<TemplateApiResult> context) {
+        TemplateInfo srcTemplate = context.getSrcTemplate();
+        TemplateInfo destTemplate = context.getDestTemplate();
+        CopyCommandResult result = callback.getResult();
+        AsyncCallFuture<TemplateApiResult> future = context.getFuture();
+        TemplateApiResult res = new TemplateApiResult(destTemplate);
+        try {
+            if (result.isFailed()) {
+                res.setResult(result.getResult());
+                destTemplate.processEvent(Event.OperationFailed);
+                srcTemplate.processEvent(Event.OperationFailed);
+                // remove entry from template_spool_ref
+                VMTemplateStoragePoolVO destTmpltPool =  _tmpltPoolDao.findByPoolTemplate(context.getDestStore().getId(), destTemplate.getId());
+                _vmTemplateStoreDao.remove(destTmpltPool.getId());
+                future.complete(res);
+                return null;
+            }
+            srcTemplate.processEvent(Event.OperationSuccessed);
+            // update other information in template_spool_ref through templateObject event processing.
+            destTemplate.processEvent(Event.OperationSuccessed);
+            future.complete(res);
+            return null;
+        } catch (Exception e) {
+            s_logger.debug("Failed to process prepare template callback", e);
+            res.setResult(e.toString());
+            future.complete(res);
+        }
+
+        return null;
+    }
+
+    @Override
+    public AsyncCallFuture<TemplateApiResult> prepareTemplateOnPrimary(TemplateInfo srcTemplate, StoragePool pool) {
+        AsyncCallFuture<TemplateApiResult> future = new AsyncCallFuture<TemplateApiResult>();
+        TemplateApiResult res = new TemplateApiResult(srcTemplate);
+        long poolId = pool.getId();
+        long templateId = srcTemplate.getId();
+        try{
+            // create one entry in template_spool_ref
+            VMTemplateStoragePoolVO templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId);
+            if (templateStoragePoolRef == null) {
+                templateStoragePoolRef = new VMTemplateStoragePoolVO(poolId, templateId);
+                templateStoragePoolRef = _tmpltPoolDao.persist(templateStoragePoolRef);
+            }
+            DataStore destStore = (DataStore)pool;
+            TemplateInfo destTemplate = this._templateFactory.getTemplate(templateStoragePoolRef.getTemplateId(), destStore);
+            destTemplate.processEvent(Event.CreateOnlyRequested);
+            srcTemplate.processEvent(Event.CopyingRequested);
+
+            CopyTemplateContext<TemplateApiResult> context = new CopyTemplateContext<TemplateApiResult>(null, future, srcTemplate,
+                    destTemplate,
+                    destStore
+                    );
+            AsyncCallbackDispatcher<TemplateServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
+            caller.setCallback(caller.getTarget().prepareTemplateCallBack(null, null))
+            .setContext(context);
+            this._motionSrv.copyAsync(srcTemplate, destTemplate, caller);
+        } catch (Exception e) {
+            s_logger.debug("Failed to prepare template on storage pool", e);
+            res.setResult(e.toString());
+            future.complete(res);
+        }
+        return future;
+    }
+
+
+
     class CopyTemplateContext<T> extends AsyncRpcConext<T> {
         final TemplateInfo srcTemplate;
         final TemplateInfo destTemplate;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0229c75b/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 21d3f06..a8d524b 100755
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java
@@ -666,7 +666,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         long templateId = template.getId();
         long dcId = pool.getDataCenterId();
         VMTemplateStoragePoolVO templateStoragePoolRef = null;
-        VMTemplateHostVO templateHostRef = null;
+        TemplateDataStoreVO templateStoreRef = null;
         long templateStoragePoolRefId;
         String origUrl = null;
 
@@ -684,115 +684,73 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
 	        }
         }
 
-        templateHostRef = findVmTemplateHost(templateId, pool);
+        templateStoreRef = findVmTemplateImageStore(templateId, pool);
 
-        if (templateHostRef == null || templateHostRef.getDownloadState() != Status.DOWNLOADED) {
-            String result = downloadTemplateFromSwiftToSecondaryStorage(dcId, templateId);
-            if (result != null) {
-                s_logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
-                return null;
-            }
-            result = _s3Mgr.downloadTemplateFromS3ToSecondaryStorage(dcId,
-                    templateId, _primaryStorageDownloadWait);
-            if (result != null) {
-                s_logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
-                return null;
-            }
-            templateHostRef = findVmTemplateHost(templateId, pool);
-            if (templateHostRef == null || templateHostRef.getDownloadState() != Status.DOWNLOADED) {
-                s_logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
-                return null;
-            }
+        if (templateStoreRef == null) {
+            s_logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
+            return null;
         }
 
-        HostVO sh = _hostDao.findById(templateHostRef.getHostId());
+        List<StoragePoolHostVO> vos = _poolHostDao.listByHostStatus(poolId, com.cloud.host.Status.Up);
+        if (vos == null || vos.isEmpty()){
+             throw new CloudRuntimeException("Cannot download " + templateId + " to poolId " + poolId + " since there is no host in the Up state connected to this pool");
+        }
+
+        /*
+        HostVO sh = _hostDao.findById(templateStoreRef.getHostId());
         origUrl = sh.getStorageUrl();
         if (origUrl == null) {
             throw new CloudRuntimeException("Unable to find the orig.url from host " + sh.toString());
         }
+        */
 
         if (templateStoragePoolRef == null) {
             if (s_logger.isDebugEnabled()) {
                 s_logger.debug("Downloading template " + templateId + " to pool " + poolId);
             }
-            templateStoragePoolRef = new VMTemplateStoragePoolVO(poolId, templateId);
+            DataStore srcSecStore = this.dataStoreMgr.getDataStore(templateStoreRef.getDataStoreId(), DataStoreRole.Image);
+            TemplateInfo srcTemplate = this.tmplFactory.getTemplate(templateId, srcSecStore);
+
+            AsyncCallFuture<TemplateApiResult> future = this.tmpltSvr.prepareTemplateOnPrimary(srcTemplate, pool);
             try {
-                templateStoragePoolRef = _tmpltPoolDao.persist(templateStoragePoolRef);
-                templateStoragePoolRefId =  templateStoragePoolRef.getId();
-
-            } catch (Exception e) {
-                s_logger.debug("Assuming we're in a race condition: " + e.getMessage());
-                templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId);
-                if (templateStoragePoolRef == null) {
-                    throw new CloudRuntimeException("Unable to persist a reference for pool " + poolId + " and template " + templateId);
+                TemplateApiResult result = future.get();
+                if (result.isFailed()) {
+                    s_logger.debug("prepare template failed:" + result.getResult());
+                    return null;
                 }
-                templateStoragePoolRefId = templateStoragePoolRef.getId();
-            }
-        } else {
-            templateStoragePoolRefId = templateStoragePoolRef.getId();
-        }
 
-        List<StoragePoolHostVO> vos = _poolHostDao.listByHostStatus(poolId, com.cloud.host.Status.Up);
-        if (vos == null || vos.isEmpty()){
-        	 throw new CloudRuntimeException("Cannot download " + templateId + " to poolId " + poolId + " since there is no host in the Up state connected to this pool");
+                return _tmpltPoolDao.findByPoolTemplate(poolId, templateId);
+            }
+            catch (Exception ex) {
+                s_logger.debug("failed to copy template from image store:" + srcSecStore.getName() + " to primary storage");
+            }
         }
 
-        templateStoragePoolRef = _tmpltPoolDao.acquireInLockTable(templateStoragePoolRefId, _storagePoolMaxWaitSeconds);
-        if (templateStoragePoolRef == null) {
-            throw new CloudRuntimeException("Unable to acquire lock on VMTemplateStoragePool: " + templateStoragePoolRefId);
-        }
+        return null;
+    }
 
-        try {
-            if (templateStoragePoolRef.getDownloadState() == Status.DOWNLOADED) {
-                return templateStoragePoolRef;
-            }
-            String url = origUrl + "/" + templateHostRef.getInstallPath();
-            PrimaryStorageDownloadCommand dcmd = new PrimaryStorageDownloadCommand(template.getUniqueName(), url, template.getFormat(),
-                   template.getAccountId(), pool, _primaryStorageDownloadWait);
-            HostVO secondaryStorageHost = _hostDao.findById(templateHostRef.getHostId());
-            assert(secondaryStorageHost != null);
-            dcmd.setSecondaryStorageUrl(secondaryStorageHost.getStorageUrl());
+    private TemplateDataStoreVO findVmTemplateImageStore(long templateId,
+            StoragePool pool) {
+        long dcId = pool.getDataCenterId();
 
+        List<DataStore> secStores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(dcId));
 
-            for (int retry = 0; retry < 2; retry ++){
-            	Collections.shuffle(vos); // Shuffling to pick a random host in the vm deployment retries
-            	StoragePoolHostVO vo = vos.get(0);
-	            if (s_logger.isDebugEnabled()) {
-	                s_logger.debug("Downloading " + templateId + " via " + vo.getHostId());
-	            }
-	        	dcmd.setLocalPath(vo.getLocalPath());
-	        	// set 120 min timeout for this command
-
-	        	PrimaryStorageDownloadAnswer answer = (PrimaryStorageDownloadAnswer)_agentMgr.easySend(
-	                   _hvGuruMgr.getGuruProcessedCommandTargetHost(vo.getHostId(), dcmd), dcmd);
-	            if (answer != null && answer.getResult() ) {
-	        		templateStoragePoolRef.setDownloadPercent(100);
-	        		templateStoragePoolRef.setDownloadState(Status.DOWNLOADED);
-	        		templateStoragePoolRef.setLocalDownloadPath(answer.getInstallPath());
-	        		templateStoragePoolRef.setInstallPath(answer.getInstallPath());
-	        		templateStoragePoolRef.setTemplateSize(answer.getTemplateSize());
-	        		_tmpltPoolDao.update(templateStoragePoolRef.getId(), templateStoragePoolRef);
-	        		if (s_logger.isDebugEnabled()) {
-	        			s_logger.debug("Template " + templateId + " is downloaded via " + vo.getHostId());
-	        		}
-	        		return templateStoragePoolRef;
-	            } else {
-	                if (s_logger.isDebugEnabled()) {
-	                    s_logger.debug("Template " + templateId + " download to pool " + vo.getPoolId() + " failed due to " + (answer!=null?answer.getDetails():"return null"));                }
-	            }
-            }
-        } finally {
-            _tmpltPoolDao.releaseFromLockTable(templateStoragePoolRefId);
+        if ( secStores == null ){
+            s_logger.error("No image store found to download template " + templateId + " primary storage!");
+            return null;
         }
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Template " + templateId + " is not found on and can not be downloaded to pool " + poolId);
+        for (DataStore store : secStores ){
+            List<TemplateDataStoreVO> templStores =  this._tmplStoreDao.listByTemplateStoreDownloadStatus(templateId, store.getId(), VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
+            if (templStores != null && !templStores.isEmpty()) {
+                Collections.shuffle(templStores);
+                return templStores.get(0);
+            }
         }
+
         return null;
     }
 
 
-
-
     @Override
     public VMTemplateHostVO findVmTemplateHost(long templateId,
             StoragePool pool) {