CLOUDSTACK-3852: fix upload volume

Conflicts:

        plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
        server/src/com/cloud/template/TemplateManagerImpl.java


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

Branch: refs/heads/master
Commit: ae534388c05db3c4de352152a9f41e9bc320864d
Parents: d64c318
Author: Edison Su <sudi...@gmail.com>
Authored: Mon Jul 29 11:49:59 2013 -0700
Committer: Edison Su <sudi...@gmail.com>
Committed: Mon Jul 29 11:50:16 2013 -0700

----------------------------------------------------------------------
 .../storage/CreateEntityDownloadURLCommand.java |  15 +-
 .../storage/resource/StoragePoolResource.java   |   2 -
 .../image/datastore/ImageStoreEntity.java       |   2 +-
 .../storage/image/store/ImageStoreImpl.java     |   4 +-
 .../storage/image/ImageStoreDriver.java         |   3 +-
 .../com/cloud/hypervisor/guru/VMwareGuru.java   |  16 ++
 .../vmware/manager/VmwareStorageManager.java    |   8 +-
 .../manager/VmwareStorageManagerImpl.java       | 205 +++++++++----------
 .../vmware/resource/VmwareResource.java         |  47 -----
 .../VmwareSecondaryStorageResourceHandler.java  |  34 +--
 .../resource/VmwareStorageProcessor.java        |   2 +-
 .../xen/resource/XenServerStorageProcessor.java |   4 +-
 .../driver/CloudStackImageStoreDriverImpl.java  |   5 +-
 .../driver/S3ImageStoreDriverImpl.java          |   3 +-
 .../driver/SampleImageStoreDriverImpl.java      |   3 +-
 .../driver/SwiftImageStoreDriverImpl.java       |   2 +-
 .../com/cloud/storage/VolumeManagerImpl.java    |  17 +-
 .../cloud/storage/upload/UploadMonitorImpl.java |   4 +-
 .../com/cloud/template/TemplateManagerImpl.java |   8 +-
 19 files changed, 164 insertions(+), 220 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae534388/core/src/com/cloud/agent/api/storage/CreateEntityDownloadURLCommand.java
----------------------------------------------------------------------
diff --git 
a/core/src/com/cloud/agent/api/storage/CreateEntityDownloadURLCommand.java 
b/core/src/com/cloud/agent/api/storage/CreateEntityDownloadURLCommand.java
index 98a957f..0723a6a 100755
--- a/core/src/com/cloud/agent/api/storage/CreateEntityDownloadURLCommand.java
+++ b/core/src/com/cloud/agent/api/storage/CreateEntityDownloadURLCommand.java
@@ -17,13 +17,16 @@
 package com.cloud.agent.api.storage;
 
 
+import com.cloud.agent.api.to.DataTO;
+
 public class CreateEntityDownloadURLCommand extends AbstractDownloadCommand {
 
-    public CreateEntityDownloadURLCommand(String parent, String installPath, 
String uuid) { // this constructor is for creating template download url
+    public CreateEntityDownloadURLCommand(String parent, String installPath, 
String uuid, DataTO data) { // this constructor is for creating template 
download url
         super();
         this.parent = parent; // parent is required as not the template can be 
child of one of many parents
         this.installPath = installPath;
         this.extractLinkUUID = uuid;
+        this.data = data;
     }
 
     public CreateEntityDownloadURLCommand(String installPath, String uuid) {
@@ -39,6 +42,16 @@ public class CreateEntityDownloadURLCommand extends 
AbstractDownloadCommand {
     private String parent;
     private String extractLinkUUID;
 
+    public DataTO getData() {
+        return data;
+    }
+
+    public void setData(DataTO data) {
+        this.data = data;
+    }
+
+    private DataTO data;
+
     @Override
     public boolean executeInSequence() {
         return false;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae534388/core/src/com/cloud/storage/resource/StoragePoolResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/StoragePoolResource.java 
b/core/src/com/cloud/storage/resource/StoragePoolResource.java
index fccfd0f..8dff97d 100644
--- a/core/src/com/cloud/storage/resource/StoragePoolResource.java
+++ b/core/src/com/cloud/storage/resource/StoragePoolResource.java
@@ -35,8 +35,6 @@ public interface StoragePoolResource {
     Answer execute(DestroyCommand cmd);
     
     CopyVolumeAnswer execute(CopyVolumeCommand cmd);
-    
-    CreateVolumeOVAAnswer execute(CreateVolumeOVACommand cmd);
 
     CreateAnswer execute(CreateCommand cmd);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae534388/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java
----------------------------------------------------------------------
diff --git 
a/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java
 
b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java
index 90deff9..43a0f75 100644
--- 
a/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java
+++ 
b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java
@@ -42,5 +42,5 @@ public interface ImageStoreEntity extends DataStore, 
ImageStore {
 
     String getMountPoint(); // get the mount point on ssvm.
 
-    String createEntityExtractUrl(String installPath, ImageFormat format);  // 
get the entity download URL
+    String createEntityExtractUrl(String installPath, ImageFormat format, 
DataObject dataObject);  // get the entity download URL
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae534388/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
 
b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
index 438ab69..855d8cb 100644
--- 
a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
+++ 
b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
@@ -190,8 +190,8 @@ public class ImageStoreImpl implements ImageStoreEntity {
     }
 
     @Override
-    public String createEntityExtractUrl(String installPath, ImageFormat 
format) {
-        return driver.createEntityExtractUrl(this, installPath, format);
+    public String createEntityExtractUrl(String installPath, ImageFormat 
format, DataObject dataObject) {
+        return driver.createEntityExtractUrl(this, installPath, format, 
dataObject);
     }
 
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae534388/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java 
b/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java
index 85a42ff..fa7ea37 100644
--- 
a/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java
+++ 
b/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java
@@ -18,11 +18,12 @@
  */
 package org.apache.cloudstack.storage.image;
 
+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.DataStoreDriver;
 
 import com.cloud.storage.Storage.ImageFormat;
 
 public interface ImageStoreDriver extends DataStoreDriver {
-    String createEntityExtractUrl(DataStore store, String installPath, 
ImageFormat format);
+    String createEntityExtractUrl(DataStore store, String installPath, 
ImageFormat format, DataObject dataObject);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae534388/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java 
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
index c589713..b870474 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
@@ -28,6 +28,11 @@ import java.util.UUID;
 import javax.ejb.Local;
 import javax.inject.Inject;
 
+
+import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
+import com.cloud.host.Host;
+import com.cloud.storage.Storage;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
 import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.storage.command.CopyCommand;
@@ -314,6 +319,17 @@ public class VMwareGuru extends HypervisorGuruBase 
implements HypervisorGuru {
             } else {
                 needDelegation = true;
             }
+        } else if (cmd instanceof CreateEntityDownloadURLCommand) {
+            DataTO srcData = ((CreateEntityDownloadURLCommand) cmd).getData();
+            if ((HypervisorType.VMware == srcData.getHypervisorType())) {
+                needDelegation = true;
+            }
+            if (srcData.getObjectType() == DataObjectType.VOLUME) {
+                VolumeObjectTO volumeObjectTO = (VolumeObjectTO)srcData;
+                if (Storage.ImageFormat.OVA == volumeObjectTO.getFormat()) {
+                    needDelegation = true;
+                }
+            }
         }
 
         if(!needDelegation) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae534388/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManager.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManager.java
 
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManager.java
index 8c0603e..1e45eb8 100644
--- 
a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManager.java
+++ 
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManager.java
@@ -24,10 +24,7 @@ import com.cloud.agent.api.CreateVMSnapshotCommand;
 import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
 import com.cloud.agent.api.DeleteVMSnapshotCommand;
 import com.cloud.agent.api.RevertToVMSnapshotCommand;
-import com.cloud.agent.api.storage.CopyVolumeCommand;
-import com.cloud.agent.api.storage.PrepareOVAPackingCommand;
-import com.cloud.agent.api.storage.CreateVolumeOVACommand;
-import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
+import com.cloud.agent.api.storage.*;
 
 public interface VmwareStorageManager {
     Answer execute(VmwareHostService hostService, 
PrimaryStorageDownloadCommand cmd);
@@ -35,10 +32,9 @@ public interface VmwareStorageManager {
     Answer execute(VmwareHostService hostService, 
CreatePrivateTemplateFromVolumeCommand cmd);
     Answer execute(VmwareHostService hostService, 
CreatePrivateTemplateFromSnapshotCommand cmd);
     Answer execute(VmwareHostService hostService, CopyVolumeCommand cmd);
-       Answer execute(VmwareHostService hostService, CreateVolumeOVACommand 
cmd);
-       Answer execute(VmwareHostService hostService, PrepareOVAPackingCommand 
cmd);
     Answer execute(VmwareHostService hostService, 
CreateVolumeFromSnapshotCommand cmd);
     Answer execute(VmwareHostService hostService, CreateVMSnapshotCommand cmd);
     Answer execute(VmwareHostService hostService, DeleteVMSnapshotCommand cmd);
     Answer execute(VmwareHostService hostService, RevertToVMSnapshotCommand 
cmd);
+    boolean execute(VmwareHostService hostService, 
CreateEntityDownloadURLCommand cmd);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae534388/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
 
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
index fee3e0a..69d7fdb 100644
--- 
a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
+++ 
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
@@ -29,6 +29,10 @@ import java.util.Properties;
 import java.util.Map;
 import java.util.UUID;
 
+import com.cloud.agent.api.storage.*;
+import com.cloud.agent.api.to.*;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.api.Answer;
@@ -44,17 +48,6 @@ import com.cloud.agent.api.DeleteVMSnapshotAnswer;
 import com.cloud.agent.api.DeleteVMSnapshotCommand;
 import com.cloud.agent.api.RevertToVMSnapshotAnswer;
 import com.cloud.agent.api.RevertToVMSnapshotCommand;
-import com.cloud.agent.api.storage.CopyVolumeAnswer;
-import com.cloud.agent.api.storage.CopyVolumeCommand;
-import com.cloud.agent.api.storage.PrepareOVAPackingAnswer;
-import com.cloud.agent.api.storage.PrepareOVAPackingCommand;
-import com.cloud.agent.api.storage.CreateVolumeOVAAnswer;
-import com.cloud.agent.api.storage.CreateVolumeOVACommand;
-import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
-import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
-import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
-import com.cloud.agent.api.to.StorageFilerTO;
-import com.cloud.agent.api.to.VolumeTO;
 import com.cloud.hypervisor.vmware.mo.CustomFieldConstants;
 import com.cloud.hypervisor.vmware.mo.DatacenterMO;
 import com.cloud.hypervisor.vmware.mo.DatastoreMO;
@@ -90,6 +83,25 @@ import com.vmware.vim25.VirtualMachineGuestOsIdentifier;
 import com.vmware.vim25.VirtualSCSISharing;
 
 public class VmwareStorageManagerImpl implements VmwareStorageManager {
+    @Override
+    public boolean execute(VmwareHostService hostService, 
CreateEntityDownloadURLCommand cmd) {
+        DataTO data = cmd.getData();
+        if (data == null) {
+            return false;
+        }
+
+        String newPath = null;
+        if (data.getObjectType() == DataObjectType.VOLUME) {
+            newPath = createOvaForVolume((VolumeObjectTO)data);
+        } else if (data.getObjectType() == DataObjectType.TEMPLATE) {
+            newPath = createOvaForTemplate((TemplateObjectTO)data);
+        }
+        if (newPath != null) {
+            cmd.setInstallPath(newPath);
+        }
+        return true;
+    }
+
     private static final Logger s_logger = 
Logger.getLogger(VmwareStorageManagerImpl.class);
 
     private final VmwareStorageMount _mountService;
@@ -109,108 +121,89 @@ public class VmwareStorageManagerImpl implements 
VmwareStorageManager {
         _timeout = NumbersUtil.parseInt(value, 1440) * 1000;
     }
 
-    //Fang note: use Answer here instead of the PrepareOVAPackingAnswer
-    @Override
-    public Answer execute(VmwareHostService hostService, 
PrepareOVAPackingCommand cmd) {
-               String secStorageUrl = ((PrepareOVAPackingCommand) 
cmd).getSecondaryStorageUrl();
-               assert (secStorageUrl != null);
-        String installPath = cmd.getTemplatePath();
-        String details = null;
-               boolean success = false;
-               String ovafileName = "";
-               s_logger.info("Fang: execute OVAPacking cmd at vmwareMngImpl. 
");
-           String secondaryMountPoint = 
_mountService.getMountPoint(secStorageUrl);
-            //   String installPath = 
getTemplateRelativeDirInSecStorage(accountId, templateId);
-           String installFullPath = secondaryMountPoint + "/" + installPath;
-
-           String templateName = installFullPath;   // should be a file ending 
.ova;
-           s_logger.info("Fang: execute vmwareMgrImpl: templateNAme " + 
templateName);
-               // Fang: Dir list, if there is ova file, done; Fang: add answer 
cmd;
-               // if not, from ova.meta, create a new OVA file;
-               // change the install path to *.ova , not ova.meta;
-           // VmwareContext context = hostService.getServiceContext(cmd);  
//Fang: we may not have the CTX here
-           try {
-               if (templateName.endsWith(".ova")) {
-                       if(new File(templateName).exists())  {
-                               details = "OVA files exists. succeed. ";
-                               return new Answer(cmd, true, details);
-                       } else {
-                               if (new File(templateName + ".meta").exists()) 
{ //Fang parse the meta file
-                                   //execute the tar command;
-                                       s_logger.info("Fang: execute 
vmwareMgrImpl: getfromMeta " + templateName);
-                                       ovafileName = 
getOVAFromMetafile(templateName + ".meta");
-                           details =  "OVA file in meta file is " + 
ovafileName;
-                           return  new Answer(cmd, true, details);
-                               }  else {
-                                   String msg = "Unable to find ova meta or 
ova file to prepare template (vmware)";
-                                   s_logger.error(msg);
-                                   throw new Exception(msg);
-                           }
-                  }
-               }
-            } catch (Throwable e) {
-                     if (e instanceof RemoteException) {
-                          //hostService.invalidateServiceContext(context); do 
not need context
-                          s_logger.error("Unable to connect to remote service 
");
-                          details = "Unable to connect to remote service ";
-                          return new Answer(cmd, false, details);
-                     }
-                    String msg = "Unable to execute PrepareOVAPackingCommand 
due to exception";
-                     s_logger.error(msg, e);
-                     return new Answer(cmd, false, details);
+    public String createOvaForTemplate(TemplateObjectTO template) {
+        DataStoreTO storeTO = template.getDataStore();
+        if (!(storeTO instanceof NfsTO)) {
+            s_logger.debug("can only handle nfs storage, when create ova from 
volume");
+            return null;
+        }
+        NfsTO nfsStore = (NfsTO)storeTO;
+        String secStorageUrl = nfsStore.getUrl();
+        assert (secStorageUrl != null);
+        String installPath = template.getPath();
+        String ovafileName = "";
+        String secondaryMountPoint = 
_mountService.getMountPoint(secStorageUrl);
+        String installFullPath = secondaryMountPoint + "/" + installPath;
+
+        String templateName = installFullPath;   // should be a file ending 
.ova;
+        try {
+            if (templateName.endsWith(".ova")) {
+                if(new File(templateName).exists())  {
+                    s_logger.debug("OVA files exists. succeed. ");
+                    return templateName;
+                } else {
+                    if (new File(templateName + ".meta").exists()) {
+                        ovafileName = getOVAFromMetafile(templateName + 
".meta");
+                        s_logger.debug("OVA file in meta file is " + 
ovafileName);
+                        return installPath;
+                    }  else {
+                        String msg = "Unable to find ova meta or ova file to 
prepare template (vmware)";
+                        s_logger.error(msg);
+                        throw new Exception(msg);
+                    }
+                }
             }
-               return new Answer(cmd, true, details);
+        } catch (Throwable e) {
+            s_logger.debug("Failed to create ova: " + e.toString());
+        }
+        return null;
     }
 
     //Fang: new command added;
     // Important! we need to sync file system before we can safely use tar to 
work around a linux kernal bug(or feature)
-    @Override
-    public Answer execute(VmwareHostService hostService, 
CreateVolumeOVACommand cmd) {
-               String secStorageUrl = ((CreateVolumeOVACommand) 
cmd).getSecondaryStorageUrl();
-               assert (secStorageUrl != null);
-        String installPath = cmd.getVolPath();
+    public String createOvaForVolume(VolumeObjectTO volume) {
+        DataStoreTO storeTO = volume.getDataStore();
+        if (!(storeTO instanceof NfsTO)) {
+            s_logger.debug("can only handle nfs storage, when create ova from 
volume");
+            return null;
+        }
+        NfsTO nfsStore = (NfsTO)storeTO;
+        String secStorageUrl = nfsStore.getUrl();
+        assert (secStorageUrl != null);
+        //Note the volume path is volumes/accountId/volumeId/uuid/, the actual 
volume is uuid/uuid.vmdk
+        String installPath = volume.getPath();
+        int index = installPath.lastIndexOf(File.separator);
+        String volumeUuid = installPath.substring(index + 1);
         String details = null;
-               boolean success = false;
+        boolean success = false;
 
-               s_logger.info("volss: execute CreateVolumeOVA cmd at 
vmwareMngImpl. ");
-           String secondaryMountPoint = 
_mountService.getMountPoint(secStorageUrl);
-            //   String installPath = 
getTemplateRelativeDirInSecStorage(accountId, templateId);
-           s_logger.info("volss: mountPoint: " + secondaryMountPoint + 
"installPath:" + installPath);
-           String installFullPath = secondaryMountPoint + "/" + installPath;
-
-           String volName = cmd.getVolName();   // should be a UUID, without 
ova ovf, etc;
-           s_logger.info("volss: execute vmwareMgrImpl: VolName " + volName);
-               // Fang: Dir list, if there is ova file, done; Note: add answer 
cmd;
-
-           try {
-               if(new File(volName + ".ova").exists())  {
-                               details = "OVA files exists. succeed. ";
-                               return new CreateVolumeOVAAnswer(cmd, true, 
details);
-           } else {
-             File ovaFile = new File(installFullPath);
-             String exportDir = ovaFile.getParent();
-
-              s_logger.info("Fang: exportDir is (for VolumeOVA): " + 
exportDir);
-          s_logger.info("Sync file system before we package OVA...");
-
-          Script commandSync = new Script(true, "sync", 0, s_logger);
-          commandSync.execute();
-
-          Script command = new Script(false, "tar", 0, s_logger);
-          command.setWorkDir(exportDir);
-          command.add("-cf", volName + ".ova");
-          command.add(volName + ".ovf");               // OVF file should be 
the first file in OVA archive
-          command.add(volName + "-disk0.vmdk");
-
-          s_logger.info("Package Volume OVA with commmand: " + 
command.toString());
-          command.execute();
-          return new CreateVolumeOVAAnswer(cmd, true, details);
-         }
-           } catch (Throwable e) {
-                s_logger.info("Exception for createVolumeOVA");
-           }
-             return new CreateVolumeOVAAnswer(cmd, true, "fail to pack OVA for 
volume");
-       }
+        String secondaryMountPoint = 
_mountService.getMountPoint(secStorageUrl);
+        //The real volume path
+        String volumePath = installPath + File.separator + volumeUuid + ".ova";
+        String installFullPath = secondaryMountPoint + "/" + installPath;
+
+        try {
+            if(new File(secondaryMountPoint + File.separator + 
volumePath).exists())  {
+                s_logger.debug("ova already exists:" + volumePath);
+                return volumePath;
+            } else {
+                Script commandSync = new Script(true, "sync", 0, s_logger);
+                commandSync.execute();
+
+                Script command = new Script(false, "tar", 0, s_logger);
+                command.setWorkDir(installFullPath);
+                command.add("-cf", volumeUuid + ".ova");
+                command.add(volumeUuid + ".ovf");              // OVF file 
should be the first file in OVA archive
+                command.add(volumeUuid + "-disk0.vmdk");
+
+                command.execute();
+                return volumePath;
+            }
+        } catch (Throwable e) {
+            s_logger.info("Exception for createVolumeOVA");
+        }
+        return null;
+    }
 
     @Override
     public Answer execute(VmwareHostService hostService, 
PrimaryStorageDownloadCommand cmd) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae534388/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
 
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index 260cfe0..a29b84b 100755
--- 
a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ 
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -474,10 +474,6 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                 answer = execute((DeleteStoragePoolCommand) cmd);
             } else if (clz == CopyVolumeCommand.class) {
                 answer = execute((CopyVolumeCommand) cmd);
-            } else if (clz == CreateVolumeOVACommand.class) {
-                answer = execute((CreateVolumeOVACommand) cmd);
-            } else if (clz == PrepareOVAPackingCommand.class)  {
-                answer = execute((PrepareOVAPackingCommand) cmd);
             } else if (clz == AttachVolumeCommand.class) {
                 answer = execute((AttachVolumeCommand) cmd);
             } else if (clz == AttachIsoCommand.class) {
@@ -5231,49 +5227,6 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
         }
     }
 
-    @Override
-    public CreateVolumeOVAAnswer execute(CreateVolumeOVACommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource CreateVolumeOVACommand: " + 
_gson.toJson(cmd));
-        }
-
-        try {
-            VmwareContext context = getServiceContext();
-            VmwareManager mgr = 
context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-            return (CreateVolumeOVAAnswer) 
mgr.getStorageManager().execute(this, cmd);
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, 
invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            String msg = "CreateVolumeOVACommand failed due to " + 
VmwareHelper.getExceptionMessage(e);
-            s_logger.error(msg, e);
-            return new CreateVolumeOVAAnswer(cmd, false, msg);
-        }
-    }
-
-    protected Answer execute(PrepareOVAPackingCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource PrepareOVAPackingCommand: " + 
_gson.toJson(cmd));
-        }
-
-        try {
-            VmwareContext context = getServiceContext();
-            VmwareManager mgr = 
context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-
-            return mgr.getStorageManager().execute(this, cmd);
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, 
invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            String details = "PrepareOVAPacking for template failed due to " + 
VmwareHelper.getExceptionMessage(e);
-            s_logger.error(details, e);
-            return new PrepareOVAPackingAnswer(cmd, false, details);
-        }
-    }
     private boolean createVMFullClone(VirtualMachineMO vmTemplate, 
DatacenterMO dcMo, DatastoreMO dsMo,
             String vmdkName, ManagedObjectReference morDatastore, 
ManagedObjectReference morPool) throws Exception {
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae534388/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
 
b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
index dddc805..3631e38 100644
--- 
a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
+++ 
b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
@@ -20,6 +20,8 @@ import java.util.List;
 
 import javax.naming.OperationNotSupportedException;
 
+import com.cloud.agent.api.storage.*;
+import com.cloud.agent.api.to.DataTO;
 import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
 import org.apache.cloudstack.storage.resource.SecondaryStorageResourceHandler;
 import org.apache.log4j.Logger;
@@ -30,11 +32,6 @@ import com.cloud.agent.api.Command;
 import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
 import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
 import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
-import com.cloud.agent.api.storage.CopyVolumeCommand;
-import com.cloud.agent.api.storage.CreateVolumeOVAAnswer;
-import com.cloud.agent.api.storage.CreateVolumeOVACommand;
-import com.cloud.agent.api.storage.PrepareOVAPackingCommand;
-import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
 import com.cloud.hypervisor.vmware.manager.VmwareHostService;
 import com.cloud.hypervisor.vmware.manager.VmwareStorageManager;
 import com.cloud.hypervisor.vmware.manager.VmwareStorageManagerImpl;
@@ -88,14 +85,12 @@ public class VmwareSecondaryStorageResourceHandler 
implements SecondaryStorageRe
             answer = execute((CreatePrivateTemplateFromSnapshotCommand) cmd);
         } else if (cmd instanceof CopyVolumeCommand) {
             answer = execute((CopyVolumeCommand) cmd);
-        } else if (cmd instanceof CreateVolumeOVACommand) {
-            answer = execute((CreateVolumeOVACommand) cmd);
-        } else if (cmd instanceof PrepareOVAPackingCommand) {
-            answer = execute((PrepareOVAPackingCommand) cmd);
         } else if (cmd instanceof CreateVolumeFromSnapshotCommand) {
             answer = execute((CreateVolumeFromSnapshotCommand) cmd);
         } else if (cmd instanceof StorageSubSystemCommand) {
             answer = 
storageSubsystemHandler.handleStorageCommands((StorageSubSystemCommand) cmd);
+        } else if (cmd instanceof CreateEntityDownloadURLCommand) {
+            answer = execute((CreateEntityDownloadURLCommand)cmd);
         } else {
             answer = _resource.defaultAction(cmd);
         }
@@ -115,6 +110,10 @@ public class VmwareSecondaryStorageResourceHandler 
implements SecondaryStorageRe
 
         return answer;
     }
+    protected Answer execute(CreateEntityDownloadURLCommand cmd) {
+        boolean result = _storageMgr.execute(this, cmd);
+        return _resource.defaultAction(cmd);
+    }
 
     private Answer execute(PrimaryStorageDownloadCommand cmd) {
         if (s_logger.isDebugEnabled()) {
@@ -156,23 +155,6 @@ public class VmwareSecondaryStorageResourceHandler 
implements SecondaryStorageRe
         return _storageMgr.execute(this, cmd);
     }
 
-    private Answer execute(PrepareOVAPackingCommand cmd) {
-        s_logger.info("Fang: VmwareSecStorageResourceHandler: exec cmd. cmd is 
 " + cmd.toString());
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Executing resource PrepareOVAPackingCommand: " + 
_gson.toJson(cmd));
-        }
-
-        return _storageMgr.execute(this, cmd);
-    }
-
-    private CreateVolumeOVAAnswer execute(CreateVolumeOVACommand cmd) {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Executing resource CreateVolumeOVACommand: " + 
_gson.toJson(cmd));
-        }
-
-        return (CreateVolumeOVAAnswer) _storageMgr.execute(this, cmd);
-    }
-
     private Answer execute(CreateVolumeFromSnapshotCommand cmd) {
         if (s_logger.isDebugEnabled()) {
             s_logger.debug("Executing resource 
CreateVolumeFromSnapshotCommand: " + _gson.toJson(cmd));

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae534388/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
 
b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
index 6f569e0..6451828 100644
--- 
a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
+++ 
b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
@@ -983,7 +983,7 @@ public class VmwareStorageProcessor implements 
StorageProcessor {
                        throw new Exception(msg);
                    }
 
-                   clonedVm.exportVm(exportPath, exportName, true, true);
+                   clonedVm.exportVm(exportPath, exportName, false, false);
                } finally {
                    if(clonedVm != null) {
                        clonedVm.detachAllDisks();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae534388/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
 
b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
index b7fdcca..69149ec 100644
--- 
a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
+++ 
b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
@@ -1187,8 +1187,7 @@ public class XenServerStorageProcessor implements 
StorageProcessor {
         String source = backupUuid + ".vhd";
         hypervisorResource.killCopyProcess(conn, source);
         s_logger.warn(errMsg);
-        return null;
-
+        throw new CloudRuntimeException(errMsg);
     }
 
     private boolean destroySnapshotOnPrimaryStorageExceptThis(Connection conn, 
String volumeUuid, String avoidSnapshotUuid){
@@ -1339,6 +1338,7 @@ public class XenServerStorageProcessor implements 
StorageProcessor {
                 } else {
                     snapshotBackupUuid = backupSnapshot(conn, 
primaryStorageSRUuid, localMountPoint, folder,
                              secondaryStorageMountPath, snapshotUuid, 
prevBackupUuid, isISCSI, wait);
+
                     finalPath = folder + File.separator + snapshotBackupUuid;
                 }
             }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae534388/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 aa2d533..6001c54 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
@@ -22,6 +22,7 @@ import java.util.UUID;
 
 import javax.inject.Inject;
 
+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.EndPoint;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
@@ -58,13 +59,13 @@ public class CloudStackImageStoreDriverImpl extends 
BaseImageStoreDriverImpl {
     }
 
     @Override
-    public String createEntityExtractUrl(DataStore store, String installPath, 
ImageFormat format) {
+    public String createEntityExtractUrl(DataStore store, String installPath, 
ImageFormat format, DataObject dataObject) {
         // find an endpoint to send command
         EndPoint ep = _epSelector.select(store);
         // Create Symlink at ssvm
         String path = installPath;
         String uuid = UUID.randomUUID().toString() + "." + 
format.getFileExtension();
-        CreateEntityDownloadURLCommand cmd = new 
CreateEntityDownloadURLCommand(((ImageStoreEntity) store).getMountPoint(), 
path, uuid);
+        CreateEntityDownloadURLCommand cmd = new 
CreateEntityDownloadURLCommand(((ImageStoreEntity) store).getMountPoint(), 
path, uuid, dataObject.getTO());
         Answer ans = ep.sendMessage(cmd);
         if (ans == null || !ans.getResult()) {
             String errorString = "Unable to create a link for entity at " + 
installPath + " on ssvm," + ans.getDetails();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae534388/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java
----------------------------------------------------------------------
diff --git 
a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java
 
b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java
index 85547ff..934e5bd 100644
--- 
a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java
+++ 
b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java
@@ -24,6 +24,7 @@ import java.util.Map;
 import javax.inject.Inject;
 
 import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
 import org.apache.cloudstack.storage.image.BaseImageStoreDriverImpl;
@@ -68,7 +69,7 @@ public class S3ImageStoreDriverImpl extends  
BaseImageStoreDriverImpl {
 
 
     @Override
-    public String createEntityExtractUrl(DataStore store, String installPath, 
ImageFormat format) {
+    public String createEntityExtractUrl(DataStore store, String installPath, 
ImageFormat format, DataObject dataObject) {
         // for S3, no need to do anything, just return template url for
         // extract template. but we need to set object acl as public_read to
         // make the url accessible

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae534388/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java
----------------------------------------------------------------------
diff --git 
a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java
 
b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java
index 66f4d77..10ff79b 100644
--- 
a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java
+++ 
b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java
@@ -20,6 +20,7 @@ package org.apache.cloudstack.storage.datastore.driver;
 
 import javax.inject.Inject;
 
+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.EndPointSelector;
 import org.apache.cloudstack.storage.image.BaseImageStoreDriverImpl;
@@ -43,7 +44,7 @@ public class SampleImageStoreDriverImpl extends 
BaseImageStoreDriverImpl {
     }
 
     @Override
-    public String createEntityExtractUrl(DataStore store, String installPath, 
ImageFormat format) {
+    public String createEntityExtractUrl(DataStore store, String installPath, 
ImageFormat format, DataObject dataObject) {
         return null;
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae534388/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java
----------------------------------------------------------------------
diff --git 
a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java
 
b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java
index 527d3aa..4a95844 100644
--- 
a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java
+++ 
b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java
@@ -65,7 +65,7 @@ public class SwiftImageStoreDriverImpl extends 
BaseImageStoreDriverImpl {
     }
 
     @Override
-    public String createEntityExtractUrl(DataStore store, String installPath, 
ImageFormat format) {
+    public String createEntityExtractUrl(DataStore store, String installPath, 
ImageFormat format, DataObject dataObject) {
         throw new UnsupportedServiceException("Extract entity url is not yet 
supported for Swift image store provider");
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae534388/server/src/com/cloud/storage/VolumeManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java 
b/server/src/com/cloud/storage/VolumeManagerImpl.java
index 6c14a19..5467c48 100644
--- a/server/src/com/cloud/storage/VolumeManagerImpl.java
+++ b/server/src/com/cloud/storage/VolumeManagerImpl.java
@@ -2823,23 +2823,8 @@ public class VolumeManagerImpl extends ManagerBase 
implements VolumeManager {
         }
 
         VolumeInfo vol = cvResult.getVolume();
-        String volumeLocalPath = vol.getPath();
-        String volumeName = 
StringUtils.substringBeforeLast(StringUtils.substringAfterLast(volumeLocalPath, 
"/"), ".");
-        // volss, handle the ova special case;
-        if (getFormatForPool(srcPool) == "ova") {
-            // TODO: need to handle this for S3 as secondary storage
-            CreateVolumeOVACommand cvOVACmd = new 
CreateVolumeOVACommand(secondaryStorageURL, volumeLocalPath, volumeName, 
srcPool, copyvolumewait);
-            CreateVolumeOVAAnswer OVAanswer = null;
 
-            try {
-                cvOVACmd.setContextParam("hypervisor", 
HypervisorType.VMware.toString());
-                // for extract volume, create the ova file here;
-                OVAanswer = (CreateVolumeOVAAnswer) 
storageMgr.sendToPool(srcPool, cvOVACmd);
-            } catch (StorageUnavailableException e) {
-                s_logger.debug("Storage unavailable");
-            }
-        }
-        String extractUrl = secStore.createEntityExtractUrl(vol.getPath(), 
vol.getFormat());
+        String extractUrl = secStore.createEntityExtractUrl(vol.getPath(), 
vol.getFormat(), vol);
         volumeStoreRef = _volumeStoreDao.findByVolume(volumeId);
         volumeStoreRef.setExtractUrl(extractUrl);
         _volumeStoreDao.update(volumeStoreRef.getId(), volumeStoreRef);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae534388/server/src/com/cloud/storage/upload/UploadMonitorImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java 
b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java
index a589e7d..b6dcc79 100755
--- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java
+++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java
@@ -250,7 +250,7 @@ public class UploadMonitorImpl extends ManagerBase 
implements UploadMonitor {
            // Create Symlink at ssvm
                String path = vmTemplateHost.getInstallPath();
                String uuid = UUID.randomUUID().toString() + "." + 
template.getFormat().getFileExtension(); // adding "." + vhd/ova... etc.
-               CreateEntityDownloadURLCommand cmd = new 
CreateEntityDownloadURLCommand(((ImageStoreEntity)store).getMountPoint(), path, 
uuid);
+               CreateEntityDownloadURLCommand cmd = new 
CreateEntityDownloadURLCommand(((ImageStoreEntity)store).getMountPoint(), path, 
uuid, null);
                Answer ans = ep.sendMessage(cmd);
                if (ans == null || !ans.getResult()) {
                errorString = "Unable to create a link for " +type+ " 
id:"+template.getId() + "," + ans.getDetails();
@@ -306,7 +306,7 @@ public class UploadMonitorImpl extends ManagerBase 
implements UploadMonitor {
                throw new CloudRuntimeException(errorString);
             }
 
-            CreateEntityDownloadURLCommand cmd = new 
CreateEntityDownloadURLCommand(((ImageStoreEntity)secStore).getMountPoint(), 
path, uuid);
+            CreateEntityDownloadURLCommand cmd = new 
CreateEntityDownloadURLCommand(((ImageStoreEntity)secStore).getMountPoint(), 
path, uuid, null);
             Answer ans = ep.sendMessage(cmd);
             if (ans == null || !ans.getResult()) {
                 errorString = "Unable to create a link for " +type+ " 
id:"+entityId + "," + ans.getDetails();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae534388/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 1076293..d26ebe2 100755
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java
@@ -49,6 +49,7 @@ import 
org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
 import org.apache.cloudstack.api.command.user.template.UpdateTemplateCmd;
 import 
org.apache.cloudstack.api.command.user.template.UpdateTemplatePermissionsCmd;
 import org.apache.cloudstack.context.CallContext;
+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;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
@@ -60,6 +61,7 @@ import 
org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
+
 import 
org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
@@ -478,11 +480,13 @@ public class TemplateManagerImpl extends ManagerBase 
implements TemplateManager,
             }
         }
 
-        if (tmpltStoreRef == null) {
+        if (tmpltStore == null) {
             throw new InvalidParameterValueException("The " + desc + " has not 
been downloaded ");
         }
 
-        return 
tmpltStore.createEntityExtractUrl(tmpltStoreRef.getInstallPath(), 
template.getFormat());
+        DataObject templateObject = _tmplFactory.getTemplate(templateId, 
tmpltStore);
+
+        return 
tmpltStore.createEntityExtractUrl(tmpltStoreRef.getInstallPath(), 
template.getFormat(), templateObject);
     }
 
     public void prepareTemplateInAllStoragePools(final VMTemplateVO template, 
long zoneId) {

Reply via email to