diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index 3be9ced822c..b47421031be 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -47,8 +47,11 @@ import java.util.concurrent.Callable; import javax.naming.ConfigurationException; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; +import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.command.CopyCommand; +import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; @@ -222,7 +225,9 @@ SecondaryStorageResource { } } - protected Answer downloadFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, + + protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, + DataTO destData, NfsTO destImageStore) { final String storagePath = destImageStore.getUrl(); final String destPath = destData.getPath(); @@ -240,10 +245,10 @@ SecondaryStorageResource { + "download directory %1$s for download from S3.", downloadDirectory.getName() ); s_logger.error(errMsg); - return new Answer(cmd, false, errMsg); + return new CopyCmdAnswer(errMsg); } - getDirectory(s3, s3.getBucketName(), + List files = getDirectory(s3, s3.getBucketName(), destPath, downloadDirectory, new FileNamingStrategy() { @Override @@ -252,20 +257,42 @@ SecondaryStorageResource { } }); - return new Answer(cmd, true, format("Successfully downloaded " - + "from S3 to directory %2$s", - downloadDirectory.getName())); - + //find out template name + File destFile = null; + for (File f : files) { + if (!f.getName().endsWith(".properties")) { + destFile = f; + break; + } + } + + if (destFile == null) { + return new CopyCmdAnswer("Can't find template"); + } + + DataTO newDestTO = null; + + if (destData.getObjectType() == DataObjectType.TEMPLATE) { + TemplateObjectTO newTemplTO = new TemplateObjectTO(); + newTemplTO.setPath(destPath + File.separator + destFile.getName()); + newTemplTO.setName(destFile.getName()); + newDestTO = newTemplTO; + } else { + return new CopyCmdAnswer("not implemented yet"); + } + + return new CopyCmdAnswer(newDestTO); } catch (Exception e) { final String errMsg = format("Failed to download" + "due to $2%s", e.getMessage()); s_logger.error(errMsg, e); - return new Answer(cmd, false, errMsg); + return new CopyCmdAnswer(errMsg); } } - protected Answer downloadFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO srcImageStore, + protected Answer copyFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO srcImageStore, + DataTO destData, NfsTO destImageStore) { return Answer.createUnsupportedCommandAnswer(cmd); } @@ -286,10 +313,10 @@ SecondaryStorageResource { } if (srcDataStore instanceof S3TO) { - return downloadFromS3ToNfs(cmd, srcData, (S3TO)srcDataStore, + return copyFromS3ToNfs(cmd, srcData, (S3TO)srcDataStore, destData, (NfsTO)destDataStore); } else if (srcDataStore instanceof SwiftTO) { - return downloadFromSwiftToNfs(cmd, srcData, (SwiftTO)srcDataStore, + return copyFromSwiftToNfs(cmd, srcData, (SwiftTO)srcDataStore, destData, (NfsTO)destDataStore); } else { return Answer.createUnsupportedCommandAnswer(cmd); diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java index 53e082e6950..4105d624107 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java @@ -16,18 +16,23 @@ // under the License. package org.apache.cloudstack.storage.command; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; + import com.cloud.agent.api.Answer; -import com.cloud.agent.api.Command; public class CopyCmdAnswer extends Answer { - private final String path; + private DataTO newData; - public CopyCmdAnswer(Command cmd, String path) { - super(cmd); - this.path = path; + public CopyCmdAnswer(DataTO newData) { + super(null); + this.newData = newData; } - public String getPath() { - return this.path; + public DataTO getNewData() { + return this.newData; + } + + public CopyCmdAnswer(String errMsg) { + super(null, false, errMsg); } } diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java index fb280346793..5fe1cbed842 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java @@ -23,27 +23,13 @@ import com.cloud.agent.api.Command; public class CopyCommand extends Command implements StorageSubSystemCommand { private DataTO srcTO; private DataTO destTO; - private int timeout; - /** - * @return the timeout - */ - public int getTimeout() { - return timeout; - } - - /** - * @param timeout the timeout to set - */ - public void setTimeout(int timeout) { - this.timeout = timeout; - } public CopyCommand(DataTO srcUri, DataTO destUri, int timeout) { super(); this.srcTO = srcUri; this.destTO = destUri; - this.timeout = timeout; + this.setWait(timeout); } public DataTO getDestTO() { diff --git a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java index 513a1dd1b8f..1e72ea0bdea 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java @@ -25,12 +25,15 @@ import org.apache.cloudstack.storage.image.datastore.ImageStoreInfo; import com.cloud.agent.api.to.DataStoreTO; public class TemplateObjectTO implements DataTO { - private final String path; - private final String uuid; + private String path; + private String uuid; private DiskFormat diskType; - private final ImageStoreTO imageDataStore; - private final String name; + private ImageStoreTO imageDataStore; + private String name; + public TemplateObjectTO() { + + } public TemplateObjectTO(TemplateInfo template) { this.path = template.getUri(); this.uuid = template.getUuid(); @@ -72,4 +75,13 @@ public class TemplateObjectTO implements DataTO { public String getName() { return name; } + public void setPath(String path) { + this.path = path; + } + public void setUuid(String uuid) { + this.uuid = uuid; + } + public void setName(String name) { + this.name = name; + } } diff --git a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java index e556a3bd95b..1fecf68c091 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java @@ -24,13 +24,18 @@ import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType; public class VolumeObjectTO implements DataTO { - private final String uuid; - private final String path; - private VolumeType volumeType; - private DiskFormat diskType; + private String uuid; + private VolumeType volumeType; + private DiskFormat diskType; private PrimaryDataStoreTO dataStore; - private String name; - private final long size; + private String name; + private long size; + private String path; + + public VolumeObjectTO() { + + } + public VolumeObjectTO(VolumeInfo volume) { this.uuid = volume.getUuid(); this.path = volume.getUri(); @@ -80,4 +85,21 @@ public class VolumeObjectTO implements DataTO { public DataObjectType getObjectType() { return DataObjectType.VOLUME; } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public void setName(String name) { + this.name = name; + } + + public void setSize(long size) { + this.size = size; + } + + public void setPath(String path) { + this.path = path; + } + } diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java index 47fe4890220..d2aacdea076 100644 --- a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java +++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java @@ -26,6 +26,7 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; @@ -116,11 +117,11 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { private class CreateCacheObjectContext extends AsyncRpcConext { - final AsyncCallFuture future; + final AsyncCallFuture future; /** * @param callback */ - public CreateCacheObjectContext(AsyncCompletionCallback callback, AsyncCallFuture future) { + public CreateCacheObjectContext(AsyncCompletionCallback callback, AsyncCallFuture future) { super(callback); this.future = future; } @@ -131,22 +132,22 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { public DataObject createCacheObject(DataObject data, Scope scope) { DataStore cacheStore = this.getCacheStorage(scope); DataObject objOnCacheStore = cacheStore.create(data); - AsyncCallFuture future = new AsyncCallFuture(); - CreateCacheObjectContext context = new CreateCacheObjectContext(null, future); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + AsyncCallFuture future = new AsyncCallFuture(); + CreateCacheObjectContext context = new CreateCacheObjectContext(null, future); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setContext(context); - CopyCmdAnswer result = null; + CopyCommandResult result = null; try { objOnCacheStore.processEvent(Event.CreateOnlyRequested); dataMotionSvr.copyAsync(data, objOnCacheStore, caller); result = future.get(); - if (!result.getResult()) { + if (result.isFailed()) { cacheStore.delete(data); } else { - objOnCacheStore.processEvent(Event.OperationSuccessed, result); + objOnCacheStore.processEvent(Event.OperationSuccessed, result.getAnswer()); } } catch (InterruptedException e) { s_logger.debug("create cache storage failed: " + e.toString()); @@ -163,9 +164,9 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { return null; } - protected Void createCacheObjectCallBack(AsyncCallbackDispatcher callback, - CreateCacheObjectContext context) { - AsyncCallFuture future = context.future; + protected Void createCacheObjectCallBack(AsyncCallbackDispatcher callback, + CreateCacheObjectContext context) { + AsyncCallFuture future = context.future; future.complete(callback.getResult()); return null; } 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 8274fd75638..b0229d88640 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 @@ -317,51 +317,16 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } protected Answer cloneVolume(DataObject template, DataObject volume) { - VolumeInfo volInfo = (VolumeInfo)volume; - DiskOfferingVO offering = diskOfferingDao.findById(volInfo.getDiskOfferingId()); - VMTemplateStoragePoolVO tmpltStoredOn = templatePoolDao.findByPoolTemplate(template.getDataStore().getId(), template.getId()); - - DiskProfile diskProfile = new DiskProfile(volInfo, offering, - null); - CreateCommand cmd = new CreateCommand(diskProfile, - tmpltStoredOn.getLocalDownloadPath(), - new StorageFilerTO((StoragePool)template.getDataStore())); - Answer answer = null; + CopyCommand cmd = new CopyCommand(template.getTO(), volume.getTO(), 0); StoragePool pool = (StoragePool)volume.getDataStore(); - String errMsg = null; + try { - answer = storageMgr.sendToPool(pool, null, cmd); + Answer answer = storageMgr.sendToPool(pool, null, cmd); + return answer; } catch (StorageUnavailableException e) { s_logger.debug("Failed to send to storage pool", e); throw new CloudRuntimeException("Failed to send to storage pool", e); } - - if (answer.getResult()) { - VolumeVO vol = this.volDao.findById(volume.getId()); - CreateAnswer createAnswer = (CreateAnswer) answer; - vol.setFolder(pool.getPath()); - vol.setPath(createAnswer.getVolume().getPath()); - vol.setSize(createAnswer.getVolume().getSize()); - vol.setPoolType(pool.getPoolType()); - vol.setPoolId(pool.getId()); - vol.setPodId(pool.getPodId()); - this.volDao.update(vol.getId(), vol); - - } else { - if (tmpltStoredOn != null - && (answer instanceof CreateAnswer) - && ((CreateAnswer) answer) - .templateReloadRequested()) { - if (!templateMgr - .resetTemplateDownloadStateOnPool(tmpltStoredOn - .getId())) { - - } - } - errMsg = answer.getDetails(); - } - - return answer; } protected Answer copyVolumeBetweenPools(DataObject srcData, DataObject destData) { 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 3230724ba8c..3b19a80bba5 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 @@ -181,22 +181,24 @@ public class TemplateObject implements TemplateInfo { public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) { try { if (this.getDataStore().getRole() == DataStoreRole.Primary) { - if (answer != null && answer instanceof CopyCmdAnswer) { + if (answer instanceof CopyCmdAnswer) { CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer; + TemplateObjectTO newTemplate = (TemplateObjectTO)cpyAnswer.getNewData(); VMTemplateStoragePoolVO templatePoolRef = templatePoolDao.findByPoolTemplate(this.getDataStore().getId(), this.getId()); templatePoolRef.setDownloadPercent(100); templatePoolRef.setDownloadState(Status.DOWNLOADED); - templatePoolRef.setLocalDownloadPath(cpyAnswer.getPath()); - templatePoolRef.setInstallPath(cpyAnswer.getPath()); + templatePoolRef.setLocalDownloadPath(newTemplate.getPath()); + templatePoolRef.setInstallPath(newTemplate.getPath()); templatePoolDao.update(templatePoolRef.getId(), templatePoolRef); } } else if (this.getDataStore().getRole() == DataStoreRole.Image || this.getDataStore().getRole() == DataStoreRole.ImageCache) { - if (answer != null && answer instanceof CopyCmdAnswer) { + if (answer instanceof CopyCmdAnswer) { CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer; + TemplateObjectTO newTemplate = (TemplateObjectTO)cpyAnswer.getNewData(); TemplateDataStoreVO templateStoreRef = this.templateStoreDao.findByStoreTemplate(this.getDataStore().getId(), this.getId()); - templateStoreRef.setInstallPath(cpyAnswer.getPath()); + templateStoreRef.setInstallPath(newTemplate.getPath()); templateStoreDao.update(templateStoreRef.getId(), templateStoreRef); } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java index c5b5883e9a3..220a7b01f6f 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java @@ -187,6 +187,7 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa return null; } + @Override public boolean tapLoadingAgents(Long hostId, TapAgentsAction action) { // TODO Auto-generated method stub diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index 2834ed03407..d5f5fbcf6a9 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -27,6 +27,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; +import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.log4j.Logger; @@ -102,6 +103,7 @@ public class VolumeObject implements VolumeInfo { public boolean stateTransit(Volume.Event event) { boolean result = false; try { + volumeVO = volumeDao.findById(volumeVO.getId()); result = _volStateMachine.transitTo(volumeVO, event, null, volumeDao); volumeVO = volumeDao.findById(volumeVO.getId()); } catch (NoTransitionException e) { @@ -345,8 +347,18 @@ public class VolumeObject implements VolumeInfo { } @Override - public void processEvent(org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event event, Answer answer) { - // TODO Auto-generated method stub - + public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) { + if (this.dataStore.getRole() == DataStoreRole.Primary) { + if (answer instanceof CopyCmdAnswer) { + CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer; + VolumeVO vol = this.volumeDao.findById(this.getId()); + VolumeObjectTO newVol = (VolumeObjectTO)cpyAnswer.getNewData(); + vol.setPath(newVol.getPath()); + vol.setSize(newVol.getSize()); + volumeDao.update(vol.getId(), vol); + } + } + + this.processEvent(event); } } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 99ac50a10dd..3bf20369825 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -398,7 +398,7 @@ public class VolumeServiceImpl implements VolumeService { return null; } - templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed); + templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed, result.getAnswer()); createVolumeFromBaseImageAsync(context.volume, templateOnPrimaryStoreObj, context.dataStore, future); return null; } @@ -447,10 +447,7 @@ public class VolumeServiceImpl implements VolumeService { VolumeApiResult volResult = new VolumeApiResult(vo); if (result.isSuccess()) { - if (result.getPath() != null) { - vo.setPath(result.getPath()); - } - vo.processEvent(Event.OperationSuccessed); + vo.processEvent(Event.OperationSuccessed, result.getAnswer()); } else { vo.processEvent(Event.OperationFailed); volResult.setResult(result.getResult()); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java index 300daa597a2..4c25bfae0a9 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java @@ -55,15 +55,19 @@ import org.apache.xmlrpc.XmlRpcException; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; +import com.cloud.agent.api.storage.CreateAnswer; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.StorageFilerTO; +import com.cloud.agent.api.to.VolumeTO; import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType; import com.cloud.storage.DataStoreRole; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.storage.encoding.DecodedDataObject; import com.cloud.utils.storage.encoding.DecodedDataStore; import com.cloud.utils.storage.encoding.Decoder; +import com.cloud.vm.DiskProfile; import com.xensource.xenapi.Connection; import com.xensource.xenapi.Host; import com.xensource.xenapi.PBD; @@ -548,7 +552,7 @@ public class XenServerStorageResource { //downloadHttpToLocalFile(vdiPath, template.getPath()); hypervisorResource.callHostPlugin(conn, "storagePlugin", "downloadTemplateFromUrl", "destPath", vdiPath, "srcUrl", srcObj.getPath()); result = true; - return new CopyCmdAnswer(cmd, vdi.getUuid(conn)); + //return new CopyCmdAnswer(cmd, vdi.getUuid(conn)); } catch (BadServerResponse e) { s_logger.debug("Failed to download template", e); } catch (XenAPIException e) { @@ -673,7 +677,7 @@ public class XenServerStorageResource { return parentUuid; } - protected PrimaryStorageDownloadAnswer copyTemplateToPrimaryStorage(DataTO srcData, DataTO destData, int wait) { + protected CopyCmdAnswer copyTemplateToPrimaryStorage(DataTO srcData, DataTO destData, int wait) { DataStoreTO srcStore = srcData.getDataStore(); try { if (srcStore.getRole() == DataStoreRole.ImageCache && srcData.getObjectType() == DataObjectType.TEMPLATE) { @@ -681,7 +685,7 @@ public class XenServerStorageResource { TemplateObjectTO srcTemplate = (TemplateObjectTO)srcData; String storeUrl = srcImageStore.getUri(); if (!storeUrl.startsWith("nfs")) { - return new PrimaryStorageDownloadAnswer("only nfs image cache store supported"); + return new CopyCmdAnswer("only nfs image cache store supported"); } String tmplpath = storeUrl + ":" + srcData.getPath(); PrimaryDataStoreTO destStore = (PrimaryDataStoreTO)destData.getDataStore(); @@ -693,7 +697,7 @@ public class XenServerStorageResource { if (srs.size() != 1) { String msg = "There are " + srs.size() + " SRs with same name: " + poolName; s_logger.warn(msg); - return new PrimaryStorageDownloadAnswer(msg); + return new CopyCmdAnswer(msg); } else { poolsr = srs.iterator().next(); } @@ -713,66 +717,79 @@ public class XenServerStorageResource { Thread.sleep(5000); } catch (Exception e) { } - return new PrimaryStorageDownloadAnswer(snapshotvdi.getUuid(conn), phySize); + + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setUuid(snapshotvdi.getUuid(conn)); + newVol.setSize(phySize); + newVol.setPath(newVol.getUuid()); + return new CopyCmdAnswer(newVol); } }catch (Exception e) { String msg = "Catch Exception " + e.getClass().getName() + " for template + " + " due to " + e.toString(); s_logger.warn(msg, e); - return new PrimaryStorageDownloadAnswer(msg); + return new CopyCmdAnswer(msg); + } + return new CopyCmdAnswer("not implemented yet"); + } + + protected CreateObjectAnswer createVolume(DataTO data) { + /* + VDI.Record vdir = new VDI.Record(); + vdir.nameLabel = dskch.getName(); + vdir.SR = poolSr; + vdir.type = Types.VdiType.USER; + + vdir.virtualSize = dskch.getSize(); + vdi = VDI.create(conn, vdir); + VDI.Record vdir; + vdir = vdi.getRecord(conn); + s_logger.debug("Succesfully created VDI for " + cmd + ". Uuid = " + vdir.uuid);*/ + return null; + } + protected CopyCmdAnswer cloneVolumeFromBaseTemplate(DataTO srcData, DataTO destData) { + Connection conn = hypervisorResource.getConnection(); + PrimaryDataStoreTO pool = (PrimaryDataStoreTO)destData.getDataStore(); + VolumeObjectTO volume = (VolumeObjectTO)destData; + VDI vdi = null; + try { + VDI tmpltvdi = null; + + tmpltvdi = getVDIbyUuid(conn, srcData.getPath()); + vdi = tmpltvdi.createClone(conn, new HashMap()); + vdi.setNameLabel(conn, volume.getName()); + + + VDI.Record vdir; + vdir = vdi.getRecord(conn); + s_logger.debug("Succesfully created VDI: Uuid = " + vdir.uuid); + + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setName(vdir.nameLabel); + newVol.setSize(vdir.virtualSize); + newVol.setPath(vdir.uuid); + + return new CopyCmdAnswer(newVol); + } catch (Exception e) { + s_logger.warn("Unable to create volume; Pool=" + pool + "; Disk: ", e); + return new CopyCmdAnswer(e.toString()); } - return new PrimaryStorageDownloadAnswer("not implemented yet"); } protected Answer execute(CopyCommand cmd) { DataTO srcData = cmd.getSrcTO(); DataTO destData = cmd.getDestTO(); - - if (srcData.getObjectType() == DataObjectType.TEMPLATE && destData.getDataStore().getRole() == DataStoreRole.Primary) { + DataStoreTO srcDataStore = srcData.getDataStore(); + DataStoreTO destDataStore = destData.getDataStore(); + + if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcData.getDataStore().getRole() == DataStoreRole.ImageCache && destData.getDataStore().getRole() == DataStoreRole.Primary) { //copy template to primary storage - return copyTemplateToPrimaryStorage(srcData, destData, cmd.getTimeout()); + return copyTemplateToPrimaryStorage(srcData, destData, cmd.getWait()); + } else if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcDataStore.getRole() == DataStoreRole.Primary && destDataStore.getRole() == DataStoreRole.Primary) { + //clone template to a volume + return cloneVolumeFromBaseTemplate(srcData, destData); } - + return new Answer(cmd, false, "not implemented yet"); - /* - String tmplturl = cmd.getUrl(); - String poolName = cmd.getPoolUuid(); - int wait = cmd.getWait(); - try { - URI uri = new URI(tmplturl); - String tmplpath = uri.getHost() + ":" + uri.getPath(); - Connection conn = hypervisorResource.getConnection(); - SR poolsr = null; - Set srs = SR.getByNameLabel(conn, poolName); - if (srs.size() != 1) { - String msg = "There are " + srs.size() + " SRs with same name: " + poolName; - s_logger.warn(msg); - return new PrimaryStorageDownloadAnswer(msg); - } else { - poolsr = srs.iterator().next(); - } - String pUuid = poolsr.getUuid(conn); - boolean isISCSI = IsISCSI(poolsr.getType(conn)); - String uuid = copy_vhd_from_secondarystorage(conn, tmplpath, pUuid, wait); - VDI tmpl = getVDIbyUuid(conn, uuid); - VDI snapshotvdi = tmpl.snapshot(conn, new HashMap()); - String snapshotUuid = snapshotvdi.getUuid(conn); - snapshotvdi.setNameLabel(conn, "Template " + cmd.getName()); - String parentuuid = getVhdParent(conn, pUuid, snapshotUuid, isISCSI); - VDI parent = getVDIbyUuid(conn, parentuuid); - Long phySize = parent.getPhysicalUtilisation(conn); - tmpl.destroy(conn); - poolsr.scan(conn); - try{ - Thread.sleep(5000); - } catch (Exception e) { - } - return new PrimaryStorageDownloadAnswer(snapshotvdi.getUuid(conn), phySize); - } catch (Exception e) { - String msg = "Catch Exception " + e.getClass().getName() + " on host:" + _host.uuid + " for template: " - + tmplturl + " due to " + e.toString(); - s_logger.warn(msg, e); - return new PrimaryStorageDownloadAnswer(msg); - }*/ - } + } } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index d9113b47eec..4debdc3b73f 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -175,7 +175,8 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setContext(context); - caller.setCallback(this.createAsyncCallback(null, null)); + caller.setCallback(caller.getTarget().createAsyncCallback(null, null)); + if (data.getType() == DataObjectType.TEMPLATE) { TemplateObject tData = (TemplateObject)data;