private void CreateRemoteBlob() { var baseBlob = this.blobObjectFactory.Create(baseVhdBlobUri); if (!baseBlob.Exists()) { throw new InvalidOperationException(String.Format("Base image to patch doesn't exist in blob storage: {0}", baseVhdBlobUri.Uri)); } var blobVhdFooter = baseBlob.GetVhdFooter(); long blobSize; VhdFilePath localBaseVhdPath; IEnumerable<Guid> childrenVhdIds; using (var vhdFile = new VhdFileFactory().Create(localVhd.FullName)) { localBaseVhdPath = vhdFile.GetFilePathBy(blobVhdFooter.UniqueId); childrenVhdIds = vhdFile.GetChildrenIds(blobVhdFooter.UniqueId).ToArray(); blobSize = vhdFile.Footer.VirtualSize; } FileMetaData fileMetaData = GetFileMetaData(baseBlob, localBaseVhdPath); var md5Hash = baseBlob.GetBlobMd5Hash(); if (!md5Hash.SequenceEqual(fileMetaData.MD5Hash)) { var message = String.Format("Patching cannot proceed, MD5 hash of base image in blob storage ({0}) and base VHD file ({1}) does not match ", baseBlob.Uri, localBaseVhdPath); throw new InvalidOperationException(message); } Program.SyncOutput.MessageCreatingNewPageBlob(blobSize); CopyBaseImageToDestination(); using (var vds = new VirtualDiskStream(localVhd.FullName)) { var streamExtents = vds.Extents.ToArray(); var enumerable = streamExtents.Where(e => childrenVhdIds.Contains(e.Owner)).ToArray(); foreach (var streamExtent in enumerable) { var indexRange = streamExtent.Range; destinationBlob.ClearPages(indexRange.StartIndex, indexRange.Length); } } using (var bmds = new BlobMetaDataScope(destinationBlob)) { bmds.Current.RemoveBlobMd5Hash(); bmds.Current.SetUploadMetaData(OperationMetaData); bmds.Complete(); } }
public static FileMetaData Create(string filePath) { var fileInfo = new FileInfo(filePath); if (!fileInfo.Exists) { throw new FileNotFoundException(filePath); } using (var stream = new VirtualDiskStream(filePath)) { return new FileMetaData { FileFullName = fileInfo.FullName, CreatedDateUtc = DateTime.SpecifyKind(fileInfo.CreationTimeUtc, DateTimeKind.Utc), LastModifiedDateUtc = DateTime.SpecifyKind(fileInfo.LastWriteTimeUtc, DateTimeKind.Utc), Size = fileInfo.Length, VhdSize = stream.Length, MD5Hash = CalculateMd5Hash(stream, filePath) }; } }
public UploadParameters ValidateParameters() { BlobUri destinationUri; if (!BlobUri.TryParseUri(Destination, out destinationUri)) { throw new ArgumentOutOfRangeException("Destination", this.Destination.ToString()); } BlobUri baseImageUri = null; if (this.BaseImageUriToPatch != null) { if (!BlobUri.TryParseUri(BaseImageUriToPatch, out baseImageUri)) { throw new ArgumentOutOfRangeException("BaseImageUriToPatch", this.BaseImageUriToPatch.ToString()); } if (!String.IsNullOrEmpty(destinationUri.Uri.Query)) { var message = String.Format(Rsrc.AddAzureVhdCommandSASUriNotSupportedInPatchMode, destinationUri.Uri); throw new ArgumentOutOfRangeException("Destination", message); } } var storageCredentialsFactory = CreateStorageCredentialsFactory(); PathIntrinsics currentPath = SessionState.Path; var filePath = new FileInfo(currentPath.GetUnresolvedProviderPathFromPSPath(LocalFilePath.ToString())); using (var vds = new VirtualDiskStream(filePath.FullName)) { if (vds.DiskType == DiskType.Fixed) { long divisor = Convert.ToInt64(Math.Pow(2, 9)); long rem = 0; Math.DivRem(filePath.Length, divisor, out rem); if (rem != 0) { throw new ArgumentOutOfRangeException("LocalFilePath", "Given vhd file is a corrupted fixed vhd"); } } } var parameters = new UploadParameters( destinationUri, baseImageUri, filePath, OverWrite.IsPresent, (NumberOfUploaderThreads) ?? DefaultNumberOfUploaderThreads) { Cmdlet = this, BlobObjectFactory = new CloudPageBlobObjectFactory(storageCredentialsFactory, TimeSpan.FromMinutes(1)) }; return parameters; }
private static void AssertIfValidVhdSize(FileInfo fileInfo) { using (var stream = new VirtualDiskStream(fileInfo.FullName)) { if (stream.Length > OneTeraByte) { var lengthString = stream.Length.ToString("N0", CultureInfo.CurrentCulture); var expectedLengthString = OneTeraByte.ToString("N0", CultureInfo.CurrentCulture); string message = String.Format("VHD size is too large ('{0}'), maximum allowed size is '{1}'.", lengthString, expectedLengthString); throw new InvalidOperationException(message); } } }
protected static IEnumerable<DataWithRange> GetDataWithRangesToUpload(FileInfo vhdFile, UploadContext context) { var uploadableRanges = context.UploadableRanges; var manager = BufferManager.CreateBufferManager(Int32.MaxValue, MaxBufferSize); using (var vds = new VirtualDiskStream(vhdFile.FullName)) { foreach (var range in uploadableRanges) { var localRange = range; yield return new DataWithRange(manager) { Data = ReadBytes(vds, localRange, manager), Range = localRange }; } } yield break; }
protected static void PopulateContextWithUploadableRanges(FileInfo vhdFile, UploadContext context, bool resume) { using (var vds = new VirtualDiskStream(vhdFile.FullName)) { IEnumerable<IndexRange> ranges = vds.Extents.Select(e => e.Range).ToArray(); var bs = new BufferedStream(vds); if (resume) { var alreadyUploadedRanges = context.DestinationBlob.GetPageRanges().Select(pr => new IndexRange(pr.StartOffset, pr.EndOffset)); ranges = IndexRange.SubstractRanges(ranges, alreadyUploadedRanges); context.AlreadyUploadedDataSize = alreadyUploadedRanges.Sum(ir => ir.Length); } var uploadableRanges = IndexRangeHelper.ChunkRangesBySize(ranges, PageSizeInBytes).ToArray(); if (vds.DiskType == DiskType.Fixed) { var nonEmptyUploadableRanges = GetNonEmptyRanges(bs, uploadableRanges).ToArray(); context.UploadableDataSize = nonEmptyUploadableRanges.Sum(r => r.Length); context.UploadableRanges = nonEmptyUploadableRanges; } else { context.UploadableDataSize = uploadableRanges.Sum(r => r.Length); context.UploadableRanges = uploadableRanges; } } }