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.
This commit is contained in:
Devdeep Singh 2013-11-27 13:01:28 +05:30
parent 6c9edaf613
commit c781e3b668
4 changed files with 170 additions and 18 deletions

View File

@ -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;
}

View File

@ -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" />

View File

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

View File

@ -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);