diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java index 47d087b3551..6149aa0a15e 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -51,7 +51,6 @@ import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; -import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.MigrateVolumeAnswer; @@ -66,7 +65,6 @@ import com.cloud.host.Host; import com.cloud.host.dao.HostDao; import com.cloud.server.ManagementService; import com.cloud.storage.DataStoreRole; -import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.VolumeVO; @@ -139,8 +137,9 @@ AncientDataMotionStrategy implements DataMotionStrategy { DataTO destTO = destData.getTO(); DataStoreTO srcStoreTO = srcTO.getDataStore(); DataStoreTO destStoreTO = destTO.getDataStore(); - if (srcStoreTO instanceof NfsTO || srcStoreTO.getRole() == DataStoreRole.ImageCache || - (srcStoreTO instanceof PrimaryDataStoreTO && ((PrimaryDataStoreTO)srcStoreTO).getPoolType() == StoragePoolType.NetworkFilesystem)) { + if (srcStoreTO instanceof NfsTO || srcStoreTO.getRole() == DataStoreRole.ImageCache) { + //|| + // (srcStoreTO instanceof PrimaryDataStoreTO && ((PrimaryDataStoreTO)srcStoreTO).getPoolType() == StoragePoolType.NetworkFilesystem)) { return false; } 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 4121e858231..ce6198dc21e 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 @@ -616,7 +616,12 @@ public class TemplateServiceImpl implements TemplateService { private AsyncCallFuture syncToRegionStoreAsync(TemplateInfo template, DataStore store) { AsyncCallFuture future = new AsyncCallFuture(); // no need to create entry on template_store_ref here, since entries are already created when prepareSecondaryStorageForMigration is invoked. + // But we need to set default install path so that sync can be done in the right s3 path TemplateInfo templateOnStore = _templateFactory.getTemplate(template, store); + String installPath = TemplateConstants.DEFAULT_TMPLT_ROOT_DIR + "/" + + TemplateConstants.DEFAULT_TMPLT_FIRST_LEVEL_DIR + + template.getAccountId() + "/" + template.getId() + "/" + template.getUniqueName(); + ((TemplateObject)templateOnStore).setInstallPath(installPath); TemplateOpContext context = new TemplateOpContext(null, (TemplateObject)templateOnStore, future); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); @@ -649,11 +654,18 @@ public class TemplateServiceImpl implements TemplateService { return null; } + private boolean isRegionStore(DataStore store) { + if (store.getScope().getScopeType() == ScopeType.ZONE && store.getScope().getScopeId() == null) + return true; + else + return false; + } + // 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 (isRegionStore(store)) { // 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); diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index f0675f3ee27..0a5b60880e5 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -58,6 +58,7 @@ public class TemplateObject implements TemplateInfo { private VMTemplateVO imageVO; private DataStore dataStore; private String url; + private String installPath; // temporarily set installPath before passing to resource for entries with empty installPath for object store migration case @Inject VMTemplateDao imageDao; @Inject @@ -293,6 +294,9 @@ public class TemplateObject implements TemplateInfo { @Override public String getInstallPath() { + if (installPath != null) + return installPath; + if (dataStore == null) { return null; } @@ -300,6 +304,10 @@ public class TemplateObject implements TemplateInfo { return obj.getInstallPath(); } + public void setInstallPath(String installPath) { + this.installPath = installPath; + } + @Override public long getAccountId() { return imageVO.getAccountId(); diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java index 053c8060b0d..ee00dd5d0e9 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java @@ -258,8 +258,14 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase tmpls = listBy(sc); - // create an entry for each record, but with empty install path since the content is not yet on region-wide store yet + // create an entry for each template record, but with empty install path since the content is not yet on region-wide store yet if (tmpls != null) { s_logger.info("Duplicate " + tmpls.size() + " template cache store records to region store"); for (TemplateDataStoreVO tmpl : tmpls) { + long templateId = tmpl.getTemplateId(); + VMTemplateVO template = _tmpltDao.findById(templateId); + if (template == null) { + throw new CloudRuntimeException("No template is found for template id: " + templateId); + } + if (template.getTemplateType() == TemplateType.SYSTEM) { + s_logger.info("No need to duplicate system template since it will be automatically downloaded while adding region store"); + continue; + } + TemplateDataStoreVO tmpStore = findByStoreTemplate(storeId, tmpl.getTemplateId()); + if (tmpStore != null) { + s_logger.info("There is already entry for template " + tmpl.getTemplateId() + " on region store " + storeId); + continue; + } + s_logger.info("Persisting an entry for template " + tmpl.getTemplateId() + " on region store " + storeId); TemplateDataStoreVO ts = new TemplateDataStoreVO(); ts.setTemplateId(tmpl.getTemplateId()); ts.setDataStoreId(storeId); @@ -395,17 +411,12 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase accountNamesFinal = accountNames; + final List accountNamesFinal = accountNames; Transaction.execute(new TransactionCallbackNoReturn() { @Override public void doInTransactionWithoutResult(TransactionStatus status) {