CLOUDSTACK-2701 - Enable storage migration for VMware resources Fixing attach volume and delete volume cases for volumes that are moved off original path in datastore when created. If volume is not found in root directory or datastore, do search in sub folders.
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/eac87e8b Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/eac87e8b Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/eac87e8b Branch: refs/heads/vmware-storage-motion Commit: eac87e8bfead2ee30b1fb7c348cb5276c0213d70 Parents: 429015b Author: Sateesh Chodapuneedi <sate...@apache.org> Authored: Mon May 27 20:14:58 2013 +0530 Committer: Sateesh Chodapuneedi <sate...@apache.org> Committed: Tue May 28 16:55:38 2013 +0530 ---------------------------------------------------------------------- .../vmware/manager/VmwareStorageManagerImpl.java | 8 ++- .../hypervisor/vmware/resource/VmwareResource.java | 4 +- .../cloud/hypervisor/vmware/mo/DatastoreMO.java | 44 ++++++++++++++- .../vmware/mo/HostDatastoreBrowserMO.java | 20 ++++--- 4 files changed, 62 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eac87e8b/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 9f1351e..43b2f73 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 @@ -328,7 +328,9 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { workerVm = vmMo; // attach volume to worker VM - String datastoreVolumePath = String.format("[%s] %s.vmdk", dsMo.getName(), volumePath); + String datastoreVolumePath = dsMo.searchFileInSubFolders(volumePath + ".vmdk", true); + assert (datastoreVolumePath != null) : "Virtual disk file must be present in the datastore to attach it to VM."; + vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs); } } @@ -1059,7 +1061,9 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } //attach volume to worker VM - String datastoreVolumePath = String.format("[%s] %s.vmdk", dsMo.getName(), volumePath); + String datastoreVolumePath = dsMo.searchFileInSubFolders(volumePath + ".vmdk", true); + assert (datastoreVolumePath != null) : "Virtual disk file must be present in the datastore to attach it to VM."; + workerVm.attachDisk(new String[] { datastoreVolumePath }, morDs); vmMo = workerVm; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eac87e8b/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 0a41a24..1baec6c 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 @@ -259,6 +259,7 @@ import com.vmware.vim25.DatastoreSummary; import com.vmware.vim25.DynamicProperty; import com.vmware.vim25.GuestInfo; import com.vmware.vim25.HostCapability; +import com.vmware.vim25.HostDatastoreBrowserSearchResults; import com.vmware.vim25.HostFirewallInfo; import com.vmware.vim25.HostFirewallRuleset; import com.vmware.vim25.HostNetworkTrafficShapingPolicy; @@ -3773,7 +3774,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } DatastoreMO dsMo = new DatastoreMO(getServiceContext(), morDs); - String datastoreVolumePath = String.format("[%s] %s.vmdk", dsMo.getName(), cmd.getVolumePath()); + String datastoreVolumePath = dsMo.searchFileInSubFolders(cmd.getVolumePath() + ".vmdk", true); + assert (datastoreVolumePath != null) : "Virtual disk file must exist in specified datastore for attach/detach operations."; AttachVolumeAnswer answer = new AttachVolumeAnswer(cmd, cmd.getDeviceId()); if (cmd.getAttach()) { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eac87e8b/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatastoreMO.java ---------------------------------------------------------------------- diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatastoreMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatastoreMO.java index c79605d..b7c8c1b 100755 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatastoreMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatastoreMO.java @@ -133,8 +133,14 @@ public class DatastoreMO extends BaseMO { fullPath = String.format("[%s] %s", datastoreName, path); try { - if(testExistence && !fileExists(fullPath)) - return true; + if(testExistence && !fileExists(fullPath)) { + String searchResult = searchFileInSubFolders(fullPath.split(" ")[1], true); + if (searchResult == null) { + return true; + } else { + fullPath = searchResult; + } + } } catch(Exception e) { s_logger.info("Unable to test file existence due to exception " + e.getClass().getName() + ", skip deleting of it"); return true; @@ -315,4 +321,38 @@ public class DatastoreMO extends BaseMO { s_logger.info("Folder " + folderName + " does not exist on datastore"); return false; } + + public String searchFileInSubFolders(String fileName, boolean caseInsensitive) throws Exception { + String datastorePath = "[" + getName() + "]"; + String rootDirectoryFilePath = String.format("[%s] %s", datastorePath, fileName); + if(fileExists(rootDirectoryFilePath)) { + return rootDirectoryFilePath; + } + + String parentFolderPath = null; + String absoluteFileName = null; + s_logger.info("Searching file " + fileName + " in " + datastorePath); + + HostDatastoreBrowserMO browserMo = getHostDatastoreBrowserMO(); + ArrayList<HostDatastoreBrowserSearchResults> results = browserMo.searchDatastoreSubFolders("[" + getName() + "]", fileName, caseInsensitive); + if (results.size() > 1) { + s_logger.warn("Multiple files with name " + fileName + " exists in datastore " + datastorePath + ". Trying to choose first file found in search attempt."); + } + for (HostDatastoreBrowserSearchResults result : results) { + if (result != null) { + List<FileInfo> info = result.getFile(); + if (info != null && info.size() > 0) { + for (FileInfo fi : info) { + absoluteFileName = parentFolderPath = result.getFolderPath(); + s_logger.info("Found file " + fileName + " in datastore at " + absoluteFileName); + if(parentFolderPath.endsWith("]")) + absoluteFileName += " "; + absoluteFileName += fi.getPath(); + break; + } + } + } + } + return absoluteFileName; + } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/eac87e8b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostDatastoreBrowserMO.java ---------------------------------------------------------------------- diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostDatastoreBrowserMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostDatastoreBrowserMO.java index 59e754c..209aeed 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostDatastoreBrowserMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostDatastoreBrowserMO.java @@ -16,6 +16,8 @@ // under the License. package com.cloud.hypervisor.vmware.mo; +import java.util.ArrayList; + import org.apache.log4j.Logger; import com.cloud.hypervisor.vmware.util.VmwareContext; @@ -76,7 +78,8 @@ public class HostDatastoreBrowserMO extends BaseMO { return searchDatastore(datastorePath, spec); } - public HostDatastoreBrowserSearchResults searchDatastoreSubFolders(String datastorePath, HostDatastoreBrowserSearchSpec searchSpec) throws Exception { + @SuppressWarnings("unchecked") + public ArrayList<HostDatastoreBrowserSearchResults> searchDatastoreSubFolders(String datastorePath, HostDatastoreBrowserSearchSpec searchSpec) throws Exception { if(s_logger.isTraceEnabled()) s_logger.trace("vCenter API trace - searchDatastoreSubFolders(). target mor: " + _mor.getValue() + ", file datastore path: " + datastorePath); @@ -87,7 +90,7 @@ public class HostDatastoreBrowserMO extends BaseMO { if(result) { _context.waitForTaskProgressDone(morTask); - return (HostDatastoreBrowserSearchResults)_context.getVimClient().getDynamicProperty(morTask, "info.result"); + return (ArrayList<HostDatastoreBrowserSearchResults>) _context.getVimClient().getDynamicProperty(morTask, "info.result"); } else { s_logger.error("VMware searchDaastoreSubFolders_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask)); } @@ -99,12 +102,11 @@ public class HostDatastoreBrowserMO extends BaseMO { return null; } - public HostDatastoreBrowserSearchResults searchDatastoreSubFolders(String datastorePath, String folderName, boolean caseInsensitive) throws Exception { - HostDatastoreBrowserSearchSpec spec = new HostDatastoreBrowserSearchSpec(); - spec.setSearchCaseInsensitive(caseInsensitive); - spec.getMatchPattern().add(folderName); + public ArrayList<HostDatastoreBrowserSearchResults> searchDatastoreSubFolders(String datastorePath, String fileName, boolean caseInsensitive) throws Exception { + HostDatastoreBrowserSearchSpec spec = new HostDatastoreBrowserSearchSpec(); + spec.setSearchCaseInsensitive(caseInsensitive); + spec.getMatchPattern().add(fileName); - return searchDatastore(datastorePath, spec); - } + return searchDatastoreSubFolders(datastorePath, spec); + } } -