mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
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:
parent
03226ba539
commit
38d6c2ea60
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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";
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user