You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ed...@apache.org on 2013/04/23 04:13:06 UTC

git commit: updated refs/heads/object_store to b8c5c67

Updated Branches:
  refs/heads/object_store 29687663e -> b8c5c67fb


add copycommand at resouce side


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

Branch: refs/heads/object_store
Commit: b8c5c67fbc074f4a2a015d28760fa0d2a7a35744
Parents: 2968766
Author: Edison Su <su...@gmail.com>
Authored: Mon Apr 22 19:12:50 2013 -0700
Committer: Edison Su <su...@gmail.com>
Committed: Mon Apr 22 19:12:50 2013 -0700

----------------------------------------------------------------------
 .../resource/NfsSecondaryStorageResource.java      |   49 +++++--
 .../cloudstack/storage/command/CopyCmdAnswer.java  |   19 ++-
 .../cloudstack/storage/command/CopyCommand.java    |   16 +--
 .../cloudstack/storage/to/TemplateObjectTO.java    |   20 ++-
 .../cloudstack/storage/to/VolumeObjectTO.java      |   34 ++++-
 .../cache/manager/StorageCacheManagerImpl.java     |   23 ++--
 .../storage/motion/AncientDataMotionStrategy.java  |   43 +-----
 .../storage/image/store/TemplateObject.java        |   12 +-
 .../storage/test/DirectAgentManagerSimpleImpl.java |    1 +
 .../cloudstack/storage/volume/VolumeObject.java    |   18 ++-
 .../storage/volume/VolumeServiceImpl.java          |    7 +-
 .../xen/resource/XenServerStorageResource.java     |  121 ++++++++------
 .../driver/CloudStackImageStoreDriverImpl.java     |    3 +-
 13 files changed, 207 insertions(+), 159 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b8c5c67f/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java
index 3be9ced..b474210 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<File> 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);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b8c5c67f/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java
----------------------------------------------------------------------
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 53e082e..4105d62 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(DataTO newData) {
+        super(null);
+        this.newData = newData;
+    }
     
-    public CopyCmdAnswer(Command cmd, String path) {
-        super(cmd);
-        this.path = path;
+    public DataTO getNewData() {
+        return this.newData;
     }
     
-    public String getPath() {
-        return this.path;
+    public CopyCmdAnswer(String errMsg) {
+        super(null, false, errMsg);
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b8c5c67f/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java
----------------------------------------------------------------------
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 fb28034..5fe1cbe 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() {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b8c5c67f/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java
----------------------------------------------------------------------
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 513a1dd..1e72ea0 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;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b8c5c67f/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java
----------------------------------------------------------------------
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 e556a3b..1fecf68 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;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b8c5c67f/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java
----------------------------------------------------------------------
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 47fe489..d2aacde 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<T> extends AsyncRpcConext<T> {
-        final AsyncCallFuture<CopyCmdAnswer> future;
+        final AsyncCallFuture<CopyCommandResult> future;
         /**
          * @param callback
          */
-        public CreateCacheObjectContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<CopyCmdAnswer> future) {
+        public CreateCacheObjectContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<CopyCommandResult> 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<CopyCmdAnswer> future = new AsyncCallFuture<CopyCmdAnswer>();
-		CreateCacheObjectContext<CopyCmdAnswer> context = new CreateCacheObjectContext<CopyCmdAnswer>(null, future);
-		AsyncCallbackDispatcher<StorageCacheManagerImpl, CopyCmdAnswer> caller = AsyncCallbackDispatcher.create(this); 
+		AsyncCallFuture<CopyCommandResult> future = new AsyncCallFuture<CopyCommandResult>();
+		CreateCacheObjectContext<CopyCommandResult> context = new CreateCacheObjectContext<CopyCommandResult>(null, future);
+		AsyncCallbackDispatcher<StorageCacheManagerImpl, CopyCommandResult> 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<StorageCacheManagerImpl, CopyCmdAnswer> callback, 
-	        CreateCacheObjectContext<CopyCmdAnswer> context) {
-	    AsyncCallFuture<CopyCmdAnswer> future = context.future;
+	protected Void createCacheObjectCallBack(AsyncCallbackDispatcher<StorageCacheManagerImpl, CopyCommandResult> callback, 
+	        CreateCacheObjectContext<CopyCommandResult> context) {
+	    AsyncCallFuture<CopyCommandResult> future = context.future;
 	    future.complete(callback.getResult());
 	    return null;
 	}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b8c5c67f/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
----------------------------------------------------------------------
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 8274fd7..b0229d8 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) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b8c5c67f/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java
----------------------------------------------------------------------
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 3230724..3b19a80 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);
         		}
         	}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b8c5c67f/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java
----------------------------------------------------------------------
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 c5b5883..220a7b0 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

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b8c5c67f/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
----------------------------------------------------------------------
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 2834ed0..d5f5fbc 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);
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b8c5c67f/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
----------------------------------------------------------------------
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 99ac50a..3bf2036 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());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b8c5c67f/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java
----------------------------------------------------------------------
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 300daa5..4c25bfa 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<String, String>());
+            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<SR> 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, String>());
-            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);
-        }*/
-        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b8c5c67f/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java
----------------------------------------------------------------------
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 d9113b4..4debdc3 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<CloudStackImageStoreDriverImpl, DownloadAnswer> 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;