Updated Branches: refs/heads/master 6c9edaf61 -> c781e3b66
Fixing creation of VM with virtual disks on a shared storage for hyperv. The shared storage path wasn't getting interpreted correctly by the agent. Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/c781e3b6 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/c781e3b6 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/c781e3b6 Branch: refs/heads/master Commit: c781e3b668c9b4562bed74d7f314c59a1af5826e Parents: 6c9edaf Author: Devdeep Singh <devd...@gmail.com> Authored: Wed Nov 27 13:01:28 2013 +0530 Committer: Devdeep Singh <devd...@gmail.com> Committed: Wed Nov 27 13:04:16 2013 +0530 ---------------------------------------------------------------------- .../HypervResource/CloudStackTypes.cs | 133 +++++++++++++++++-- .../HypervResource/HypervResource.csproj | 1 + .../HypervResource/HypervResourceController.cs | 48 ++++++- .../ServerResource/HypervResource/WmiCallsV2.cs | 6 +- 4 files changed, 170 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c781e3b6/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs index dfc3e20..af8c61f 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs @@ -31,23 +31,114 @@ namespace HypervResource { public class PrimaryDataStoreTO { - public string path; + private string path; + public string host; + private string poolType; + public Uri uri; + public string _role; + + public string Path + { + get + { + if (this.isLocal) + { + return path; + } + else + { + return this.UncPath; + } + } + set + { + this.path = value; + } + } + + public string UncPath + { + get + { + string uncPath = null; + if (uri.Scheme.Equals("cifs") || uri.Scheme.Equals("networkfilesystem")) + { + uncPath = @"\\" + uri.Host + uri.LocalPath; + } + return uncPath; + } + } + + public string User + { + get + { + var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query); + return System.Web.HttpUtility.UrlDecode(queryDictionary["user"]); + } + } + + public string Password + { + get + { + var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query); + return System.Web.HttpUtility.UrlDecode(queryDictionary["password"]); + } + } + + public string Domain + { + get + { + var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query); + if (queryDictionary["domain"] != null) + { + return System.Web.HttpUtility.UrlDecode(queryDictionary["domain"]); + } + else return uri.Host; + } + } + + public Boolean isLocal + { + get + { + if (poolType.Equals("Filesystem")) + { + return true; + } + else + { + return false; + } + } + } public static PrimaryDataStoreTO ParseJson(dynamic json) { PrimaryDataStoreTO result = null; - if (json == null) { return result; } + dynamic primaryDataStoreTOJson = json[CloudStackTypes.PrimaryDataStoreTO]; if (primaryDataStoreTOJson != null) { result = new PrimaryDataStoreTO() { - path = (string)primaryDataStoreTOJson.path + path = (string)primaryDataStoreTOJson.path, + host = (string)primaryDataStoreTOJson.host, + poolType = (string)primaryDataStoreTOJson.poolType }; + + if (!result.isLocal) + { + // Delete security credentials in original command. Prevents logger from spilling the beans, as it were. + String uriStr = @"cifs://" + result.host + result.path; + result.uri = new Uri(uriStr); + } } return result; } @@ -61,12 +152,22 @@ namespace HypervResource { get { - String result = Path.Combine(this.primaryDataStore.path, this.name); + string fileName = null; + if (this.primaryDataStore.isLocal) + { + fileName = Path.Combine(this.primaryDataStore.Path, this.name); + } + else + { + fileName = @"\\" + this.primaryDataStore.uri.Host + this.primaryDataStore.uri.LocalPath + @"\" + this.name; + } + if (this.format != null) { - result = result + "." + this.format.ToLowerInvariant(); + fileName = fileName + "." + this.format.ToLowerInvariant(); } - return result; + + return fileName; } } @@ -116,11 +217,16 @@ namespace HypervResource { logger.Info("No image format in VolumeObjectTO, going to use format from first file that matches " + volInfo.FullFileName); - string[] choices = Directory.GetFiles(volInfo.primaryDataStore.path, volInfo.name + ".vhd*"); + string path = volInfo.primaryDataStore.Path; + if (!volInfo.primaryDataStore.isLocal) + { + path = volInfo.primaryDataStore.UncPath; + } + string[] choices = choices = Directory.GetFiles(path, volInfo.name + ".vhd*"); if (choices.Length != 1) { - String errMsg = "Tried to guess file extension, but cannot find file corresponding to " + Path.Combine(volInfo.primaryDataStore.path, volInfo.name); // format being guessed. + String errMsg = "Tried to guess file extension, but cannot find file corresponding to " + Path.Combine(volInfo.primaryDataStore.Path, volInfo.name); // format being guessed. logger.Debug(errMsg); } else @@ -145,7 +251,16 @@ namespace HypervResource { if (String.IsNullOrEmpty(this.path)) { - return Path.Combine(this.primaryDataStore.path, this.name) + '.' + this.format.ToLowerInvariant(); + string fileName = null; + if (this.primaryDataStore.isLocal) + { + fileName = Path.Combine(this.primaryDataStore.Path, this.name); + } + else + { + fileName = @"\\" + this.primaryDataStore.uri.Host + this.primaryDataStore.uri.LocalPath + @"\" + this.name; + } + return fileName +'.' + this.format.ToLowerInvariant(); } return this.path; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c781e3b6/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResource.csproj ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResource.csproj b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResource.csproj index 05a0f51..a2dc323 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResource.csproj +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResource.csproj @@ -63,6 +63,7 @@ <HintPath>..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll</HintPath> </Reference> <Reference Include="System" /> + <Reference Include="System.Configuration" /> <Reference Include="System.Core" /> <Reference Include="System.Management" /> <Reference Include="System.Net.Http" /> http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c781e3b6/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs index 0d56fef..a5c54a6 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs @@ -23,7 +23,10 @@ using Microsoft.CSharp.RuntimeBinder; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; +using System.Collections; +using System.Collections.Specialized; using System.Collections.Generic; +using System.Configuration; using System.IO; using System.Linq; using System.Net; @@ -78,6 +81,31 @@ namespace HypervResource public ulong ParentPartitionMinMemoryMb; public string LocalSecondaryStoragePath; public string systemVmIso; + + private string getPrimaryKey(string id) + { + return "primary_storage_" + id; + } + + public string getPrimaryStorage(string id) + { + NameValueCollection settings = ConfigurationManager.AppSettings; + return settings.Get(getPrimaryKey(id)); + } + + public void setPrimaryStorage(string id, string path) + { + Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); + KeyValueConfigurationCollection settings = config.AppSettings.Settings; + string key = getPrimaryKey(id); + if (settings[key] != null) + { + settings.Remove(key); + } + settings.Add(key, path); + config.Save(ConfigurationSaveMode.Modified); + ConfigurationManager.RefreshSection("appSettings"); + } } /// <summary> @@ -1092,14 +1120,24 @@ namespace HypervResource logger.Info(CloudStackTypes.CopyCommand + cmd.ToString()); + string destFile = null; + if (destTemplateObjectTO != null && destTemplateObjectTO.primaryDataStore != null) + { + destFile = destTemplateObjectTO.FullFileName; + if (!destTemplateObjectTO.primaryDataStore.isLocal) + { + PrimaryDataStoreTO primary = destTemplateObjectTO.primaryDataStore; + Utils.ConnectToRemote(primary.UncPath, primary.Domain, primary.User, primary.Password); + } + } + // Already exists? - if (destTemplateObjectTO != null && - File.Exists(destTemplateObjectTO.FullFileName) && + if (destFile != null && File.Exists(destFile) && !String.IsNullOrEmpty(destTemplateObjectTO.checksum)) { // TODO: checksum fails us, because it is of the compressed image. // ASK: should we store the compressed or uncompressed version or is the checksum not calculated correctly? - result = VerifyChecksum(destTemplateObjectTO.FullFileName, destTemplateObjectTO.checksum); + result = VerifyChecksum(destFile, destTemplateObjectTO.checksum); } // Do we have to create a new one? @@ -1112,8 +1150,6 @@ namespace HypervResource // NFS provider download to primary storage? if ((srcTemplateObjectTO.s3DataStoreTO != null || srcTemplateObjectTO.nfsDataStoreTO != null) && destTemplateObjectTO.primaryDataStore != null) { - string destFile = destTemplateObjectTO.FullFileName; - if (File.Exists(destFile)) { logger.Info("Deleting existing file " + destFile); @@ -1187,7 +1223,7 @@ namespace HypervResource { destVolumeObjectTO.format = srcTemplateObjectTO.format; } - string destFile = destVolumeObjectTO.FullFileName; + destFile = destVolumeObjectTO.FullFileName; string srcFile = srcTemplateObjectTO.FullFileName; if (!File.Exists(srcFile)) http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c781e3b6/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs index 0a3f008..ca49bd9 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs @@ -286,13 +286,13 @@ namespace HypervResource throw new ArgumentException(errMsg); } errMsg = vmName + ": Malformed PrimaryDataStore for disk " + diskDrive.ToString(); - if (String.IsNullOrEmpty(volInfo.primaryDataStore.path)) + if (String.IsNullOrEmpty(volInfo.primaryDataStore.Path)) { logger.Error(errMsg); throw new ArgumentException(errMsg); } - errMsg = vmName + ": Missing folder PrimaryDataStore for disk " + diskDrive.ToString() + ", missing path: " + volInfo.primaryDataStore.path; - if (!Directory.Exists(volInfo.primaryDataStore.path)) + errMsg = vmName + ": Missing folder PrimaryDataStore for disk " + diskDrive.ToString() + ", missing path: " + volInfo.primaryDataStore.Path; + if (!Directory.Exists(volInfo.primaryDataStore.Path)) { logger.Error(errMsg); throw new ArgumentException(errMsg);