void UploadManifest(ImportProgressCallback progressCallback = null)
{
if (string.IsNullOrEmpty(ManifestFileKey))
throw new InvalidOperationException("Expected ManifestFileKey to have been constructed");
using (var manifestStream = new MemoryStream())
{
if (progressCallback != null)
progressCallback("Creating import manifest...", null);
// Get as close to the xml sent by the existing ec2 cli as possible, so no namespaces,
// Unix linefeeds and a standalone instruction, plus indentation of 4 spaces. This makes
// comparison of the two manifests easier if needed for debugging.
var xmlContext = new XmlSerializer(typeof(ImportManifestRoot));
var namespaces = new XmlSerializerNamespaces();
namespaces.Add("", "");
var writerCfg = new XmlWriterSettings
{
Encoding = new UTF8Encoding(false),
NewLineChars = "\n",
NewLineHandling = NewLineHandling.Replace,
Indent = true,
IndentChars = " "
};
using (var writer = XmlWriter.Create(manifestStream, writerCfg))
{
writer.WriteProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"");
xmlContext.Serialize(writer, ImportManifest, namespaces);
}
if (progressCallback != null)
progressCallback("Creating and uploading import manifest...", null);
// even though this is the first artifact to be uploaded and as such, if it fails,
// there is nothing to clean up catch any exception so we can tell the user there
// is no clean up required (for users concerned about storage costs).
try
{
S3Client.UploadObjectFromStream(BucketName, ManifestFileKey, manifestStream, null);
}
catch (Exception e)
{
throw new DiskImageImporterException(DiskImportErrorStage.UploadingManifest,
"Upload of the image file manifest to Amazon S3 failed.\nThere are no orphaned objects requiring manual deletion.",
e);
}
}
}