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/10/26 06:18:46 UTC
[3/8] git commit: updated refs/heads/object_store_migration to 9da56fe
Trigger syncing templates to S3 in case of copyTemplate and
extractTemplate.
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/184e5394
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/184e5394
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/184e5394
Branch: refs/heads/object_store_migration
Commit: 184e53940ae247a744c4a6c5222c20d331af7d2e
Parents: 1b07c33
Author: Min Chen <mi...@citrix.com>
Authored: Mon Oct 21 17:23:58 2013 -0700
Committer: Min Chen <mi...@citrix.com>
Committed: Mon Oct 21 17:23:58 2013 -0700
----------------------------------------------------------------------
.../api/storage/TemplateDataFactory.java | 2 +
.../subsystem/api/storage/TemplateService.java | 2 +
.../datastore/db/TemplateDataStoreDao.java | 2 +
.../storage/image/TemplateDataFactoryImpl.java | 22 +++++--
.../storage/image/TemplateServiceImpl.java | 68 ++++++++++++++++++++
.../image/db/TemplateDataStoreDaoImpl.java | 12 ++++
.../com/cloud/template/TemplateManagerImpl.java | 20 ++++--
7 files changed, 117 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/184e5394/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 0b78da0..980ed31 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
@@ -28,4 +28,6 @@ public interface TemplateDataFactory {
TemplateInfo getTemplate(long templateId, DataStoreRole storeRole);
TemplateInfo getTemplate(long templateId, DataStoreRole storeRole, Long zoneId);
+
+ TemplateInfo getReadyTemplateOnCache(long templateId);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/184e5394/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 0d8b3c1..185d254 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
@@ -54,6 +54,8 @@ public interface TemplateService {
AsyncCallFuture<TemplateApiResult> prepareTemplateOnPrimary(TemplateInfo srcTemplate, StoragePool pool);
+ void syncTemplateToRegionStore(long templateId, DataStore store);
+
void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId);
void handleTemplateSync(DataStore store);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/184e5394/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java
index ba569c1..fc61be5 100644
--- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java
+++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java
@@ -64,4 +64,6 @@ StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Even
List<TemplateDataStoreVO> listByTemplate(long templateId);
void duplicateCacheRecordsOnRegionStore(long storeId);
+
+ TemplateDataStoreVO findReadyOnCache(long templateId);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/184e5394/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 a67f08f..fe1c62c 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
@@ -20,6 +20,9 @@ package org.apache.cloudstack.storage.image;
import javax.inject.Inject;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
@@ -28,8 +31,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
import org.apache.cloudstack.storage.image.store.TemplateObject;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.VMTemplateStoragePoolVO;
@@ -87,7 +88,7 @@ public class TemplateDataFactoryImpl implements TemplateDataFactory {
TemplateDataStoreVO tmplStore = templateStoreDao.findByTemplate(templateId, storeRole);
DataStore store = null;
if (tmplStore != null) {
- store = this.storeMgr.getDataStore(tmplStore.getDataStoreId(), storeRole);
+ store = storeMgr.getDataStore(tmplStore.getDataStoreId(), storeRole);
}
return this.getTemplate(templateId, store);
}
@@ -97,7 +98,7 @@ public class TemplateDataFactoryImpl implements TemplateDataFactory {
TemplateDataStoreVO tmplStore = templateStoreDao.findByTemplateZone(templateId, zoneId, storeRole);
DataStore store = null;
if (tmplStore != null) {
- store = this.storeMgr.getDataStore(tmplStore.getDataStoreId(), storeRole);
+ store = storeMgr.getDataStore(tmplStore.getDataStoreId(), storeRole);
}
return this.getTemplate(templateId, store);
}
@@ -113,4 +114,17 @@ public class TemplateDataFactoryImpl implements TemplateDataFactory {
tmpObj.setUrl(origTmpl.getUrl());
return tmpObj;
}
+
+ @Override
+ public TemplateInfo getReadyTemplateOnCache(long templateId) {
+ TemplateDataStoreVO tmplStore = templateStoreDao.findReadyOnCache(templateId);
+ if (tmplStore != null) {
+ DataStore store = storeMgr.getDataStore(tmplStore.getDataStoreId(), DataStoreRole.ImageCache);
+ return getTemplate(templateId, store);
+ } else {
+ return null;
+ }
+
+ }
+
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/184e5394/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 06cb652..163c125 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.dc.dao.DataCenterDao;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.ScopeType;
import com.cloud.storage.Storage.TemplateType;
import com.cloud.storage.StoragePool;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
@@ -609,6 +610,73 @@ public class TemplateServiceImpl implements TemplateService {
return copyAsync(volume, template, store);
}
+ private AsyncCallFuture<TemplateApiResult> syncToRegionStoreAsync(TemplateInfo template, DataStore store) {
+ AsyncCallFuture<TemplateApiResult> future = new AsyncCallFuture<TemplateApiResult>();
+ // no need to create entry on template_store_ref here, since entries are already created when prepareSecondaryStorageForMigration is invoked.
+ TemplateInfo templateOnStore = _templateFactory.getTemplate(template, store);
+ TemplateOpContext<TemplateApiResult> context = new TemplateOpContext<TemplateApiResult>(null,
+ (TemplateObject)templateOnStore, future);
+ AsyncCallbackDispatcher<TemplateServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
+ caller.setCallback(caller.getTarget().syncTemplateCallBack(null, null)).setContext(context);
+ _motionSrv.copyAsync(template, templateOnStore, caller);
+ return future;
+ }
+
+ protected Void syncTemplateCallBack(AsyncCallbackDispatcher<TemplateServiceImpl, CopyCommandResult> callback,
+ TemplateOpContext<TemplateApiResult> context) {
+ TemplateInfo destTemplate = context.getTemplate();
+ CopyCommandResult result = callback.getResult();
+ AsyncCallFuture<TemplateApiResult> future = context.getFuture();
+ TemplateApiResult res = new TemplateApiResult(destTemplate);
+ try {
+ if (result.isFailed()) {
+ res.setResult(result.getResult());
+ // no change to existing template_store_ref, will try to re-sync later if other call triggers this sync operation, like copy template
+ } else {
+ // this will update install path properly, next time it will not sync anymore.
+ destTemplate.processEvent(Event.OperationSuccessed, result.getAnswer());
+ }
+ future.complete(res);
+ } catch (Exception e) {
+ s_logger.debug("Failed to process sync template callback", e);
+ res.setResult(e.toString());
+ future.complete(res);
+ }
+
+ return null;
+ }
+
+ // This routine is used to push templates currently on cache store, but not in region store to region store.
+ // used in migrating existing NFS secondary storage to S3.
+ @Override
+ public void syncTemplateToRegionStore(long templateId, DataStore store) {
+ if (store.getScope().getScopeType() == ScopeType.REGION) {
+ // if template is on region wide object store, check if it is really downloaded there (by checking install_path). Sync template to region
+ // wide store if it is not there physically.
+ TemplateInfo tmplOnStore = _templateFactory.getTemplate(templateId, store);
+ if (tmplOnStore == null) {
+ throw new CloudRuntimeException("Cannot find an entry in template_store_ref for template " + templateId + " on region store: " + store.getName());
+ }
+ if (tmplOnStore.getInstallPath() == null || tmplOnStore.getInstallPath().length() == 0) {
+ // template is not on region store yet, sync to region store
+ TemplateInfo srcTemplate = _templateFactory.getReadyTemplateOnCache(templateId);
+ if (srcTemplate == null) {
+ throw new CloudRuntimeException("Cannot find template " + templateId + " on cache store");
+ }
+ AsyncCallFuture<TemplateApiResult> future = syncToRegionStoreAsync(srcTemplate, store);
+ try {
+ TemplateApiResult result = future.get();
+ if (result.isFailed()) {
+ throw new CloudRuntimeException("sync template from cache to region wide store failed for image store " + store.getName() + ":"
+ + result.getResult());
+ }
+ } catch (Exception ex) {
+ throw new CloudRuntimeException("sync template from cache to region wide store failed for image store " + store.getName());
+ }
+ }
+ }
+ }
+
@Override
public AsyncCallFuture<TemplateApiResult> copyTemplate(TemplateInfo srcTemplate, DataStore destStore) {
// generate a URL from source template ssvm to download to destination data store
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/184e5394/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 008180f..25f3486 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
@@ -31,6 +31,7 @@ import org.springframework.stereotype.Component;
import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
@@ -94,6 +95,7 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
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.and("state", templateRoleSearch.entity().getState(), SearchCriteria.Op.EQ);
templateRoleSearch.done();
updateStateSearch = this.createSearchBuilder();
@@ -323,6 +325,16 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
}
@Override
+ public TemplateDataStoreVO findReadyOnCache(long templateId) {
+ SearchCriteria<TemplateDataStoreVO> sc = templateRoleSearch.create();
+ sc.setParameters("template_id", templateId);
+ sc.setParameters("store_role", DataStoreRole.ImageCache);
+ sc.setParameters("destroyed", false);
+ sc.setParameters("state", ObjectInDataStoreStateMachine.State.Ready);
+ return findOneIncludingRemovedBy(sc);
+ }
+
+ @Override
public List<TemplateDataStoreVO> listByTemplate(long templateId) {
SearchCriteria<TemplateDataStoreVO> sc = templateSearch.create();
sc.setParameters("template_id", templateId);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/184e5394/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 c1ce892..452e079 100755
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java
@@ -479,6 +479,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
throw new InvalidParameterValueException("The " + desc + " has not been downloaded ");
}
+ // Handle NFS to S3 object store migration case, we trigger template sync from NFS to S3 during extract template or copy template
+ _tmpltSvr.syncTemplateToRegionStore(templateId, tmpltStore);
+
DataObject templateObject = _tmplFactory.getTemplate(templateId, tmpltStore);
return tmpltStore.createEntityExtractUrl(tmpltStoreRef.getInstallPath(), template.getFormat(), templateObject);
@@ -698,7 +701,15 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
throw new InvalidParameterValueException("Unable to find template with id");
}
+ DataStore srcSecStore = getImageStore(sourceZoneId, templateId);
+ if (srcSecStore == null) {
+ throw new InvalidParameterValueException("There is no template " + templateId + " in zone " + sourceZoneId);
+ }
+
if (template.isCrossZones()){
+ //TODO: we may need UI still enable CopyTemplate in case of cross zone template to trigger sync to region store.
+ // sync template from cache store to region store if it is not there, for cases where we are going to migrate existing NFS to S3.
+ _tmpltSvr.syncTemplateToRegionStore(templateId, srcSecStore);
s_logger.debug("Template " + templateId + " is cross-zone, don't need to copy");
return template;
}
@@ -710,11 +721,6 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
return template;
}
- DataStore srcSecStore = getImageStore(sourceZoneId, templateId);
- if (srcSecStore == null) {
- throw new InvalidParameterValueException("There is no template " + templateId + " in zone " + sourceZoneId);
- }
-
_accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);
boolean success = copy(userId, template, srcSecStore, dstZone);
@@ -781,7 +787,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
}
try {
- StoragePool pool = (StoragePool) this._dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId());
+ StoragePool pool = (StoragePool) _dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId());
VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId());
if (s_logger.isDebugEnabled()) {
@@ -1830,6 +1836,6 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
@Inject
public void setTemplateAdapters(List<TemplateAdapter> adapters) {
- this._adapters = adapters;
+ _adapters = adapters;
}
}