mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-8431: [Hyper-V] Fixed VM deployment failing when the stale vhd already exists Now generating guid when the template copy from secondary to primary storage requested instead of using it same as secondary
this closes #214
This commit is contained in:
parent
d9064ecfea
commit
aa265fe88f
@ -290,11 +290,11 @@ namespace HypervResource
|
||||
PrimaryDataStoreTO store = this.primaryDataStore;
|
||||
if (store.isLocal)
|
||||
{
|
||||
fileName = Path.Combine(store.Path, this.uuid);
|
||||
fileName = Path.Combine(store.Path, this.path);
|
||||
}
|
||||
else
|
||||
{
|
||||
fileName = @"\\" + store.uri.Host + store.uri.LocalPath + @"\" + this.uuid;
|
||||
fileName = @"\\" + store.uri.Host + store.uri.LocalPath + @"\" + this.path;
|
||||
}
|
||||
fileName = fileName + '.' + this.format.ToLowerInvariant();
|
||||
}
|
||||
|
||||
@ -1538,6 +1538,10 @@ namespace HypervResource
|
||||
string destFile = null;
|
||||
if (destTemplateObjectTO != null)
|
||||
{
|
||||
if (destTemplateObjectTO.path == null)
|
||||
{
|
||||
destTemplateObjectTO.path = System.Guid.NewGuid().ToString();
|
||||
}
|
||||
if (destTemplateObjectTO.primaryDataStore != null)
|
||||
{
|
||||
destFile = destTemplateObjectTO.FullFileName;
|
||||
@ -1548,242 +1552,222 @@ namespace HypervResource
|
||||
}
|
||||
}
|
||||
|
||||
// Template already downloaded?
|
||||
if (destFile != null && File.Exists(destFile) &&
|
||||
!String.IsNullOrEmpty(destTemplateObjectTO.checksum))
|
||||
// Create local copy of a template?
|
||||
if (srcTemplateObjectTO != null && destTemplateObjectTO != null)
|
||||
{
|
||||
// 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?
|
||||
logger.Debug(CloudStackTypes.CopyCommand + " calling VerifyChecksum to see if we already have the file at " + destFile);
|
||||
result = VerifyChecksum(destFile, destTemplateObjectTO.checksum);
|
||||
if (!result)
|
||||
// S3 download to primary storage?
|
||||
// NFS provider download to primary storage?
|
||||
if ((srcTemplateObjectTO.s3DataStoreTO != null || srcTemplateObjectTO.nfsDataStoreTO != null) && destTemplateObjectTO.primaryDataStore != null)
|
||||
{
|
||||
result = true;
|
||||
logger.Debug(CloudStackTypes.CopyCommand + " existing file has different checksum " + destFile);
|
||||
}
|
||||
}
|
||||
|
||||
// Do we have to create a new one?
|
||||
if (!result)
|
||||
{
|
||||
// Create local copy of a template?
|
||||
if (srcTemplateObjectTO != null && destTemplateObjectTO != null)
|
||||
{
|
||||
// S3 download to primary storage?
|
||||
// NFS provider download to primary storage?
|
||||
if ((srcTemplateObjectTO.s3DataStoreTO != null || srcTemplateObjectTO.nfsDataStoreTO != null) && destTemplateObjectTO.primaryDataStore != null)
|
||||
if (File.Exists(destFile))
|
||||
{
|
||||
if (File.Exists(destFile))
|
||||
{
|
||||
logger.Info("Deleting existing file " + destFile);
|
||||
File.Delete(destFile);
|
||||
}
|
||||
logger.Info("Deleting existing file " + destFile);
|
||||
File.Delete(destFile);
|
||||
}
|
||||
|
||||
if (srcTemplateObjectTO.s3DataStoreTO != null)
|
||||
{
|
||||
// Download from S3 to destination data storage
|
||||
DownloadS3ObjectToFile(srcTemplateObjectTO.path, srcTemplateObjectTO.s3DataStoreTO, destFile);
|
||||
}
|
||||
else if (srcTemplateObjectTO.nfsDataStoreTO != null)
|
||||
{
|
||||
// Download from S3 to destination data storage
|
||||
Utils.DownloadCifsFileToLocalFile(srcTemplateObjectTO.path, srcTemplateObjectTO.nfsDataStoreTO, destFile);
|
||||
}
|
||||
if (srcTemplateObjectTO.s3DataStoreTO != null)
|
||||
{
|
||||
// Download from S3 to destination data storage
|
||||
DownloadS3ObjectToFile(srcTemplateObjectTO.path, srcTemplateObjectTO.s3DataStoreTO, destFile);
|
||||
}
|
||||
else if (srcTemplateObjectTO.nfsDataStoreTO != null)
|
||||
{
|
||||
// Download from S3 to destination data storage
|
||||
Utils.DownloadCifsFileToLocalFile(srcTemplateObjectTO.path, srcTemplateObjectTO.nfsDataStoreTO, destFile);
|
||||
}
|
||||
|
||||
// Uncompress, as required
|
||||
if (srcTemplateObjectTO.path.EndsWith(".bz2"))
|
||||
// Uncompress, as required
|
||||
if (srcTemplateObjectTO.path.EndsWith(".bz2"))
|
||||
{
|
||||
String uncompressedFile = destFile + ".tmp";
|
||||
String compressedFile = destFile;
|
||||
using (var uncompressedOutStrm = new FileStream(uncompressedFile, FileMode.CreateNew, FileAccess.Write))
|
||||
{
|
||||
String uncompressedFile = destFile + ".tmp";
|
||||
String compressedFile = destFile;
|
||||
using (var uncompressedOutStrm = new FileStream(uncompressedFile, FileMode.CreateNew, FileAccess.Write))
|
||||
using (var compressedInStrm = new FileStream(destFile, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
using (var compressedInStrm = new FileStream(destFile, FileMode.Open, FileAccess.Read))
|
||||
using (var bz2UncompressorStrm = new Ionic.BZip2.BZip2InputStream(compressedInStrm, true) /* outer 'using' statement will close FileStream*/ )
|
||||
{
|
||||
using (var bz2UncompressorStrm = new Ionic.BZip2.BZip2InputStream(compressedInStrm, true) /* outer 'using' statement will close FileStream*/ )
|
||||
{
|
||||
int count = 0;
|
||||
int bufsize = 1024 * 1024;
|
||||
byte[] buf = new byte[bufsize];
|
||||
int count = 0;
|
||||
int bufsize = 1024 * 1024;
|
||||
byte[] buf = new byte[bufsize];
|
||||
|
||||
// EOF returns -1, see http://dotnetzip.codeplex.com/workitem/16069
|
||||
while (0 < (count = bz2UncompressorStrm.Read(buf, 0, bufsize)))
|
||||
{
|
||||
uncompressedOutStrm.Write(buf, 0, count);
|
||||
}
|
||||
// EOF returns -1, see http://dotnetzip.codeplex.com/workitem/16069
|
||||
while (0 < (count = bz2UncompressorStrm.Read(buf, 0, bufsize)))
|
||||
{
|
||||
uncompressedOutStrm.Write(buf, 0, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
File.Delete(compressedFile);
|
||||
File.Move(uncompressedFile, compressedFile);
|
||||
if (File.Exists(uncompressedFile))
|
||||
{
|
||||
String errMsg = "Extra file left around called " + uncompressedFile + " when creating " + destFile;
|
||||
logger.Error(errMsg);
|
||||
throw new IOException(errMsg);
|
||||
}
|
||||
}
|
||||
|
||||
// assert
|
||||
if (!File.Exists(destFile))
|
||||
File.Delete(compressedFile);
|
||||
File.Move(uncompressedFile, compressedFile);
|
||||
if (File.Exists(uncompressedFile))
|
||||
{
|
||||
String errMsg = "Failed to create " + destFile + " , because the file is missing";
|
||||
String errMsg = "Extra file left around called " + uncompressedFile + " when creating " + destFile;
|
||||
logger.Error(errMsg);
|
||||
throw new IOException(errMsg);
|
||||
}
|
||||
|
||||
FileInfo destFileInfo = new FileInfo(destFile);
|
||||
destTemplateObjectTO.size = destFileInfo.Length.ToString();
|
||||
destTemplateObjectTO.path = destTemplateObjectTO.uuid;
|
||||
JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.TemplateObjectTO, destTemplateObjectTO);
|
||||
newData = ansObj;
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
details = "Data store combination not supported";
|
||||
}
|
||||
}
|
||||
// Create volume from a template?
|
||||
else if (srcTemplateObjectTO != null && destVolumeObjectTO != null)
|
||||
{
|
||||
// VolumeObjectTO guesses file extension based on existing files
|
||||
// this can be wrong if the previous file had a different file type
|
||||
var guessedDestFile = destVolumeObjectTO.FullFileName;
|
||||
if (File.Exists(guessedDestFile))
|
||||
{
|
||||
logger.Info("Deleting existing file " + guessedDestFile);
|
||||
File.Delete(guessedDestFile);
|
||||
}
|
||||
|
||||
destVolumeObjectTO.format = srcTemplateObjectTO.format;
|
||||
destFile = destVolumeObjectTO.FullFileName;
|
||||
if (File.Exists(destFile))
|
||||
// assert
|
||||
if (!File.Exists(destFile))
|
||||
{
|
||||
logger.Info("Deleting existing file " + destFile);
|
||||
File.Delete(destFile);
|
||||
String errMsg = "Failed to create " + destFile + " , because the file is missing";
|
||||
logger.Error(errMsg);
|
||||
throw new IOException(errMsg);
|
||||
}
|
||||
|
||||
string srcFile = srcTemplateObjectTO.FullFileName;
|
||||
if (!File.Exists(srcFile))
|
||||
{
|
||||
details = "Local template file missing from " + srcFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: thin provision instead of copying the full file.
|
||||
File.Copy(srcFile, destFile);
|
||||
destVolumeObjectTO.path = destVolumeObjectTO.uuid;
|
||||
JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.VolumeObjectTO, destVolumeObjectTO);
|
||||
newData = ansObj;
|
||||
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);
|
||||
|
||||
if (srcVolumeObjectTO.nfsDataStore != null && srcVolumeObjectTO.primaryDataStore == null)
|
||||
{
|
||||
logger.Info("Copied volume from secondary data store to primary. Path: " + destVolumeObjectTO.path);
|
||||
}
|
||||
else if (srcVolumeObjectTO.primaryDataStore != null && srcVolumeObjectTO.nfsDataStore == null)
|
||||
{
|
||||
destVolumeObjectTO.path = destVolumeObjectTO.path + "/" + destVolumeObjectTO.uuid;
|
||||
if (destVolumeObjectTO.format != null)
|
||||
{
|
||||
destVolumeObjectTO.path += "." + destVolumeObjectTO.format.ToLower();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error("Destination volume path wasn't set. Unsupported source volume data store.");
|
||||
}
|
||||
|
||||
// Create volumeto object deserialize and send it
|
||||
JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.VolumeObjectTO, destVolumeObjectTO);
|
||||
newData = ansObj;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
else if (srcVolumeObjectTO != null && destTemplateObjectTO != null)
|
||||
{
|
||||
var guessedDestFile = destTemplateObjectTO.FullFileName;
|
||||
if (File.Exists(guessedDestFile))
|
||||
{
|
||||
logger.Info("Deleting existing file " + guessedDestFile);
|
||||
File.Delete(guessedDestFile);
|
||||
}
|
||||
|
||||
destTemplateObjectTO.format = srcVolumeObjectTO.format;
|
||||
destFile = destTemplateObjectTO.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);
|
||||
|
||||
FileInfo destFileInfo = new FileInfo(destFile);
|
||||
// Write the template.properties file
|
||||
PostCreateTemplate(Path.GetDirectoryName(destFile), destTemplateObjectTO.id, destTemplateObjectTO.name,
|
||||
destFileInfo.Length.ToString(), srcVolumeObjectTO.size.ToString(), destTemplateObjectTO.format);
|
||||
|
||||
TemplateObjectTO destTemplateObject = new TemplateObjectTO();
|
||||
destTemplateObject.size = srcVolumeObjectTO.size.ToString();
|
||||
destTemplateObject.format = srcVolumeObjectTO.format;
|
||||
destTemplateObject.path = destTemplateObjectTO.path + "/" + destTemplateObjectTO.uuid;
|
||||
if (destTemplateObject.format != null)
|
||||
{
|
||||
destTemplateObject.path += "." + destTemplateObject.format.ToLower();
|
||||
}
|
||||
destTemplateObject.nfsDataStoreTO = destTemplateObjectTO.nfsDataStoreTO;
|
||||
destTemplateObject.checksum = destTemplateObjectTO.checksum;
|
||||
JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.TemplateObjectTO, destTemplateObject);
|
||||
newData = ansObj;
|
||||
result = true;
|
||||
}
|
||||
FileInfo destFileInfo = new FileInfo(destFile);
|
||||
destTemplateObjectTO.size = destFileInfo.Length.ToString();
|
||||
JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.TemplateObjectTO, destTemplateObjectTO);
|
||||
newData = ansObj;
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
details = "Data store combination not supported";
|
||||
}
|
||||
}
|
||||
// Create volume from a template?
|
||||
else if (srcTemplateObjectTO != null && destVolumeObjectTO != null)
|
||||
{
|
||||
// VolumeObjectTO guesses file extension based on existing files
|
||||
// this can be wrong if the previous file had a different file type
|
||||
var guessedDestFile = destVolumeObjectTO.FullFileName;
|
||||
if (File.Exists(guessedDestFile))
|
||||
{
|
||||
logger.Info("Deleting existing file " + guessedDestFile);
|
||||
File.Delete(guessedDestFile);
|
||||
}
|
||||
|
||||
destVolumeObjectTO.format = srcTemplateObjectTO.format;
|
||||
destFile = destVolumeObjectTO.FullFileName;
|
||||
if (File.Exists(destFile))
|
||||
{
|
||||
logger.Info("Deleting existing file " + destFile);
|
||||
File.Delete(destFile);
|
||||
}
|
||||
|
||||
string srcFile = srcTemplateObjectTO.FullFileName;
|
||||
if (!File.Exists(srcFile))
|
||||
{
|
||||
details = "Local template file missing from " + srcFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: thin provision instead of copying the full file.
|
||||
File.Copy(srcFile, destFile);
|
||||
destVolumeObjectTO.path = destVolumeObjectTO.uuid;
|
||||
JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.VolumeObjectTO, destVolumeObjectTO);
|
||||
newData = ansObj;
|
||||
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);
|
||||
|
||||
if (srcVolumeObjectTO.nfsDataStore != null && srcVolumeObjectTO.primaryDataStore == null)
|
||||
{
|
||||
logger.Info("Copied volume from secondary data store to primary. Path: " + destVolumeObjectTO.path);
|
||||
}
|
||||
else if (srcVolumeObjectTO.primaryDataStore != null && srcVolumeObjectTO.nfsDataStore == null)
|
||||
{
|
||||
destVolumeObjectTO.path = destVolumeObjectTO.path + "/" + destVolumeObjectTO.uuid;
|
||||
if (destVolumeObjectTO.format != null)
|
||||
{
|
||||
destVolumeObjectTO.path += "." + destVolumeObjectTO.format.ToLower();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error("Destination volume path wasn't set. Unsupported source volume data store.");
|
||||
}
|
||||
|
||||
// Create volumeto object deserialize and send it
|
||||
JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.VolumeObjectTO, destVolumeObjectTO);
|
||||
newData = ansObj;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
else if (srcVolumeObjectTO != null && destTemplateObjectTO != null)
|
||||
{
|
||||
var guessedDestFile = destTemplateObjectTO.FullFileName;
|
||||
if (File.Exists(guessedDestFile))
|
||||
{
|
||||
logger.Info("Deleting existing file " + guessedDestFile);
|
||||
File.Delete(guessedDestFile);
|
||||
}
|
||||
|
||||
destTemplateObjectTO.format = srcVolumeObjectTO.format;
|
||||
destFile = destTemplateObjectTO.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);
|
||||
|
||||
FileInfo destFileInfo = new FileInfo(destFile);
|
||||
// Write the template.properties file
|
||||
PostCreateTemplate(Path.GetDirectoryName(destFile), destTemplateObjectTO.id, destTemplateObjectTO.name,
|
||||
destFileInfo.Length.ToString(), srcVolumeObjectTO.size.ToString(), destTemplateObjectTO.format);
|
||||
|
||||
TemplateObjectTO destTemplateObject = new TemplateObjectTO();
|
||||
destTemplateObject.size = srcVolumeObjectTO.size.ToString();
|
||||
destTemplateObject.format = srcVolumeObjectTO.format;
|
||||
destTemplateObject.path = destTemplateObjectTO.path + "/" + destTemplateObjectTO.uuid;
|
||||
if (destTemplateObject.format != null)
|
||||
{
|
||||
destTemplateObject.path += "." + destTemplateObject.format.ToLower();
|
||||
}
|
||||
destTemplateObject.nfsDataStoreTO = destTemplateObjectTO.nfsDataStoreTO;
|
||||
destTemplateObject.checksum = destTemplateObjectTO.checksum;
|
||||
JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.TemplateObjectTO, destTemplateObject);
|
||||
newData = ansObj;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
details = "Data store combination not supported";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user