CLOUDSTACK-5639: Cold storage migration doesn't work for hyper-v. Made

changes to make sure CopyCommand honours requests for volume copy from
primary to secondary storage and vice versa.
This commit is contained in:
Devdeep Singh 2013-12-25 21:58:59 +05:30
parent 03226ba539
commit 38d6c2ea60
2 changed files with 117 additions and 19 deletions

View File

@ -153,15 +153,34 @@ namespace HypervResource
get get
{ {
string fileName = null; string fileName = null;
if (this.primaryDataStore.isLocal) if (this.primaryDataStore != null)
{ {
fileName = Path.Combine(this.primaryDataStore.Path, this.name); PrimaryDataStoreTO store = this.primaryDataStore;
if (store.isLocal)
{
fileName = Path.Combine(store.Path, this.name);
} }
else else
{ {
fileName = @"\\" + this.primaryDataStore.uri.Host + this.primaryDataStore.uri.LocalPath + @"\" + this.name; fileName = @"\\" + store.uri.Host + store.uri.LocalPath + @"\" + this.name;
fileName = Utils.NormalizePath(fileName); fileName = Utils.NormalizePath(fileName);
} }
}
else if (this.nfsDataStore != null)
{
fileName = this.nfsDataStore.UncPath;
if (this.path != null)
{
fileName += @"\" + this.path;
}
fileName = Utils.NormalizePath(fileName + @"\" + this.name);
}
else
{
String errMsg = "Invalid dataStore in VolumeObjectTO spec";
logger.Error(errMsg);
throw new InvalidDataException(errMsg);
}
if (this.format != null) if (this.format != null)
{ {
@ -175,9 +194,11 @@ namespace HypervResource
public dynamic dataStore; public dynamic dataStore;
public string format; public string format;
public string name; public string name;
public string path;
public string uuid; public string uuid;
public ulong size; public ulong size;
public PrimaryDataStoreTO primaryDataStore; public PrimaryDataStoreTO primaryDataStore;
public NFSTO nfsDataStore;
public static VolumeObjectTO ParseJson(dynamic json) public static VolumeObjectTO ParseJson(dynamic json)
{ {
@ -196,15 +217,17 @@ namespace HypervResource
dataStore = volumeObjectTOJson.dataStore, dataStore = volumeObjectTOJson.dataStore,
format = ((string)volumeObjectTOJson.format), format = ((string)volumeObjectTOJson.format),
name = (string)volumeObjectTOJson.name, name = (string)volumeObjectTOJson.name,
path = volumeObjectTOJson.path,
uuid = (string)volumeObjectTOJson.uuid, uuid = (string)volumeObjectTOJson.uuid,
size = (ulong)volumeObjectTOJson.size size = (ulong)volumeObjectTOJson.size
}; };
result.primaryDataStore = PrimaryDataStoreTO.ParseJson(volumeObjectTOJson.dataStore); result.primaryDataStore = PrimaryDataStoreTO.ParseJson(volumeObjectTOJson.dataStore);
result.nfsDataStore = NFSTO.ParseJson(volumeObjectTOJson.dataStore);
// Assert // Assert
if (result.dataStore == null || result.primaryDataStore == null) if (result.dataStore == null || (result.primaryDataStore == null && result.nfsDataStore == null))
{ {
String errMsg = "VolumeObjectTO missing primary dataStore in spec " + volumeObjectTOJson.ToString(); String errMsg = "VolumeObjectTO missing dataStore in spec " + volumeObjectTOJson.ToString();
logger.Error(errMsg); logger.Error(errMsg);
throw new ArgumentNullException(errMsg); throw new ArgumentNullException(errMsg);
} }
@ -220,16 +243,41 @@ namespace HypervResource
{ {
logger.Info("No image format in VolumeObjectTO, going to use format from first file that matches " + volInfo.FullFileName); logger.Info("No image format in VolumeObjectTO, going to use format from first file that matches " + volInfo.FullFileName);
string path = volInfo.primaryDataStore.Path; string path = null;
if (!volInfo.primaryDataStore.isLocal) if (volInfo.primaryDataStore != null)
{
if (volInfo.primaryDataStore.isLocal)
{
path = volInfo.primaryDataStore.Path;
}
else
{ {
path = volInfo.primaryDataStore.UncPath; path = volInfo.primaryDataStore.UncPath;
} }
}
else if (volInfo.nfsDataStore != null)
{
path = volInfo.nfsDataStore.UncPath;
if (volInfo.path != null)
{
path += @"\" + volInfo.path;
}
}
else
{
String errMsg = "VolumeObjectTO missing dataStore in spec " + volInfo.ToString();
logger.Error(errMsg);
throw new ArgumentNullException(errMsg);
}
path = Utils.NormalizePath(path);
if (Directory.Exists(path))
{
string[] choices = choices = Directory.GetFiles(path, volInfo.name + ".vhd*"); string[] choices = choices = Directory.GetFiles(path, volInfo.name + ".vhd*");
if (choices.Length != 1) 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);
logger.Debug(errMsg); logger.Debug(errMsg);
} }
else else
@ -237,6 +285,7 @@ namespace HypervResource
string[] splitFileName = choices[0].Split(new char[] { '.' }); string[] splitFileName = choices[0].Split(new char[] { '.' });
volInfo.format = splitFileName[splitFileName.Length - 1]; volInfo.format = splitFileName[splitFileName.Length - 1];
} }
}
logger.Debug("Going to use file " + volInfo.FullFileName); logger.Debug("Going to use file " + volInfo.FullFileName);
} }
} }

View File

@ -688,7 +688,6 @@ namespace HypervResource
} }
// POST api/HypervResource/CheckHealthCommand // POST api/HypervResource/CheckHealthCommand
// TODO: create test
[HttpPost] [HttpPost]
[ActionName(CloudStackTypes.CheckHealthCommand)] [ActionName(CloudStackTypes.CheckHealthCommand)]
public JContainer CheckHealthCommand([FromBody]dynamic cmd) public JContainer CheckHealthCommand([FromBody]dynamic cmd)
@ -706,6 +705,24 @@ namespace HypervResource
} }
} }
// POST api/HypervResource/CheckOnHostCommand
[HttpPost]
[ActionName(CloudStackTypes.CheckOnHostCommand)]
public JContainer CheckOnHostCommand([FromBody]dynamic cmd)
{
using (log4net.NDC.Push(Guid.NewGuid().ToString()))
{
logger.Info(CloudStackTypes.CheckOnHostCommand + cmd.ToString());
object ansContent = new
{
result = true,
details = "resource is alive",
contextMap = contextMap
};
return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CheckOnHostAnswer);
}
}
// POST api/HypervResource/CheckSshCommand // POST api/HypervResource/CheckSshCommand
// TODO: create test // TODO: create test
[HttpPost] [HttpPost]
@ -1229,6 +1246,7 @@ namespace HypervResource
using (log4net.NDC.Push(Guid.NewGuid().ToString())) using (log4net.NDC.Push(Guid.NewGuid().ToString()))
{ {
// Log command *after* we've removed security details from the command. // Log command *after* we've removed security details from the command.
logger.Info(CloudStackTypes.CopyCommand + cmd.ToString());
bool result = false; bool result = false;
string details = null; string details = null;
@ -1240,10 +1258,9 @@ namespace HypervResource
TemplateObjectTO srcTemplateObjectTO = TemplateObjectTO.ParseJson(cmd.srcTO); TemplateObjectTO srcTemplateObjectTO = TemplateObjectTO.ParseJson(cmd.srcTO);
TemplateObjectTO destTemplateObjectTO = TemplateObjectTO.ParseJson(cmd.destTO); TemplateObjectTO destTemplateObjectTO = TemplateObjectTO.ParseJson(cmd.destTO);
VolumeObjectTO srcVolumeObjectTO = VolumeObjectTO.ParseJson(cmd.srcTO);
VolumeObjectTO destVolumeObjectTO = VolumeObjectTO.ParseJson(cmd.destTO); VolumeObjectTO destVolumeObjectTO = VolumeObjectTO.ParseJson(cmd.destTO);
logger.Info(CloudStackTypes.CopyCommand + cmd.ToString());
string destFile = null; string destFile = null;
if (destTemplateObjectTO != null && destTemplateObjectTO.primaryDataStore != null) if (destTemplateObjectTO != null && destTemplateObjectTO.primaryDataStore != null)
{ {
@ -1379,6 +1396,38 @@ namespace HypervResource
result = true; result = true;
} }
} }
else if (srcVolumeObjectTO != null && destVolumeObjectTO != null)
{
var guessedDestFile = destVolumeObjectTO.FullFileName;
if (File.Exists(guessedDestFile))
{
logger.Info("Deleting existing file " + guessedDestFile);
File.Delete(guessedDestFile);
}
destVolumeObjectTO.format = srcVolumeObjectTO.format;
destFile = destVolumeObjectTO.FullFileName;
if (File.Exists(destFile))
{
logger.Info("Deleting existing file " + destFile);
File.Delete(destFile);
}
string srcFile = srcVolumeObjectTO.FullFileName;
if (!File.Exists(srcFile))
{
details = "Local template file missing from " + srcFile;
}
else
{
// Create the directory before copying the files. CreateDirectory
// doesn't do anything if the directory is already present.
Directory.CreateDirectory(Path.GetDirectoryName(destFile));
File.Copy(srcFile, destFile);
newData = cmd.destTO;
result = true;
}
}
else else
{ {
details = "Data store combination not supported"; details = "Data store combination not supported";