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) {