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) {