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:
Anshul Gangwar 2015-04-24 15:23:18 +05:30 committed by Rajesh Battala
parent d9064ecfea
commit aa265fe88f
2 changed files with 194 additions and 210 deletions

View File

@ -290,11 +290,11 @@ namespace HypervResource
PrimaryDataStoreTO store = this.primaryDataStore; PrimaryDataStoreTO store = this.primaryDataStore;
if (store.isLocal) if (store.isLocal)
{ {
fileName = Path.Combine(store.Path, this.uuid); fileName = Path.Combine(store.Path, this.path);
} }
else else
{ {
fileName = @"\\" + store.uri.Host + store.uri.LocalPath + @"\" + this.uuid; fileName = @"\\" + store.uri.Host + store.uri.LocalPath + @"\" + this.path;
} }
fileName = fileName + '.' + this.format.ToLowerInvariant(); fileName = fileName + '.' + this.format.ToLowerInvariant();
} }

View File

@ -1538,6 +1538,10 @@ namespace HypervResource
string destFile = null; string destFile = null;
if (destTemplateObjectTO != null) if (destTemplateObjectTO != null)
{ {
if (destTemplateObjectTO.path == null)
{
destTemplateObjectTO.path = System.Guid.NewGuid().ToString();
}
if (destTemplateObjectTO.primaryDataStore != null) if (destTemplateObjectTO.primaryDataStore != null)
{ {
destFile = destTemplateObjectTO.FullFileName; destFile = destTemplateObjectTO.FullFileName;
@ -1548,242 +1552,222 @@ namespace HypervResource
} }
} }
// Template already downloaded? // Create local copy of a template?
if (destFile != null && File.Exists(destFile) && if (srcTemplateObjectTO != null && destTemplateObjectTO != null)
!String.IsNullOrEmpty(destTemplateObjectTO.checksum))
{ {
// TODO: checksum fails us, because it is of the compressed image. // S3 download to primary storage?
// ASK: should we store the compressed or uncompressed version or is the checksum not calculated correctly? // NFS provider download to primary storage?
logger.Debug(CloudStackTypes.CopyCommand + " calling VerifyChecksum to see if we already have the file at " + destFile); if ((srcTemplateObjectTO.s3DataStoreTO != null || srcTemplateObjectTO.nfsDataStoreTO != null) && destTemplateObjectTO.primaryDataStore != null)
result = VerifyChecksum(destFile, destTemplateObjectTO.checksum);
if (!result)
{ {
result = true; if (File.Exists(destFile))
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)) logger.Info("Deleting existing file " + destFile);
{ File.Delete(destFile);
logger.Info("Deleting existing file " + destFile); }
File.Delete(destFile);
}
if (srcTemplateObjectTO.s3DataStoreTO != null) if (srcTemplateObjectTO.s3DataStoreTO != null)
{ {
// Download from S3 to destination data storage // Download from S3 to destination data storage
DownloadS3ObjectToFile(srcTemplateObjectTO.path, srcTemplateObjectTO.s3DataStoreTO, destFile); DownloadS3ObjectToFile(srcTemplateObjectTO.path, srcTemplateObjectTO.s3DataStoreTO, destFile);
} }
else if (srcTemplateObjectTO.nfsDataStoreTO != null) else if (srcTemplateObjectTO.nfsDataStoreTO != null)
{ {
// Download from S3 to destination data storage // Download from S3 to destination data storage
Utils.DownloadCifsFileToLocalFile(srcTemplateObjectTO.path, srcTemplateObjectTO.nfsDataStoreTO, destFile); Utils.DownloadCifsFileToLocalFile(srcTemplateObjectTO.path, srcTemplateObjectTO.nfsDataStoreTO, destFile);
} }
// Uncompress, as required // Uncompress, as required
if (srcTemplateObjectTO.path.EndsWith(".bz2")) 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"; using (var compressedInStrm = new FileStream(destFile, FileMode.Open, FileAccess.Read))
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 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;
int count = 0; byte[] buf = new byte[bufsize];
int bufsize = 1024 * 1024;
byte[] buf = new byte[bufsize];
// EOF returns -1, see http://dotnetzip.codeplex.com/workitem/16069 // EOF returns -1, see http://dotnetzip.codeplex.com/workitem/16069
while (0 < (count = bz2UncompressorStrm.Read(buf, 0, bufsize))) while (0 < (count = bz2UncompressorStrm.Read(buf, 0, bufsize)))
{ {
uncompressedOutStrm.Write(buf, 0, count); 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);
}
} }
File.Delete(compressedFile);
// assert File.Move(uncompressedFile, compressedFile);
if (!File.Exists(destFile)) 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); logger.Error(errMsg);
throw new IOException(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; // assert
destFile = destVolumeObjectTO.FullFileName; if (!File.Exists(destFile))
if (File.Exists(destFile))
{ {
logger.Info("Deleting existing file " + destFile); String errMsg = "Failed to create " + destFile + " , because the file is missing";
File.Delete(destFile); logger.Error(errMsg);
throw new IOException(errMsg);
} }
string srcFile = srcTemplateObjectTO.FullFileName; FileInfo destFileInfo = new FileInfo(destFile);
if (!File.Exists(srcFile)) destTemplateObjectTO.size = destFileInfo.Length.ToString();
{ JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.TemplateObjectTO, destTemplateObjectTO);
details = "Local template file missing from " + srcFile; newData = ansObj;
} result = true;
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 else
{ {
details = "Data store combination not supported"; 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) catch (Exception ex)
{ {