예제 #1
0
        public UploadContext Create()
        {
            AssertIfValidhVhd(localVhd);
            AssertIfValidVhdSize(localVhd);

            this.blobObjectFactory.CreateContainer(blobDestination);

            UploadContext context   = null;
            bool          completed = false;

            try
            {
                context = new UploadContext
                {
                    DestinationBlob     = destinationBlob,
                    SingleInstanceMutex = AcquireSingleInstanceMutex(destinationBlob.Uri)
                };

                if (overWrite)
                {
                    destinationBlob.DeleteIfExistsAsync(DeleteSnapshotsOption.IncludeSnapshots, null, requestOptions, operationContext: null)
                    .ConfigureAwait(false).GetAwaiter().GetResult();
                }

                if (destinationBlob.Exists(requestOptions))
                {
                    Program.SyncOutput.MessageResumingUpload();

                    if (destinationBlob.GetBlobMd5Hash(requestOptions) != null)
                    {
                        throw new InvalidOperationException(
                                  "An image already exists in blob storage with this name. If you want to upload again, use the Overwrite option.");
                    }
                    var metaData = destinationBlob.GetUploadMetaData();

                    AssertMetaDataExists(metaData);
                    AssertMetaDataMatch(metaData, OperationMetaData);

                    PopulateContextWithUploadableRanges(localVhd, context, true);
                    PopulateContextWithDataToUpload(localVhd, context);
                }
                else
                {
                    CreateRemoteBlobAndPopulateContext(context);
                }
                context.Md5HashOfLocalVhd = MD5HashOfLocalVhd;
                completed = true;
            }
            finally
            {
                if (!completed && context != null)
                {
                    context.Dispose();
                }
            }
            return(context);
        }
        /// <summary>
        /// Tries to resize the VHD file, using the parameters specified.
        /// </summary>
        /// <param name="newSizeInGb">The new size of the VHD file, in gigabytes.</param>
        /// <param name="blobUri">The <see cref="Uri"/> to locate the VHD in the Azure Storage account.</param>
        /// <param name="accountName">The name of the Azure Storage account.</param>
        /// <param name="accountKey">The key of the Azure Storage account.</param>
        /// <returns>Returns <see cref="ResizeResult.Error"/> if there were issues while trying to do the resize operation.
        /// Returns <see cref="ResizeResult.Shrink"/> if this is a shrink operation which needs user confirmation.
        /// Returns <see cref="ResizeResult.Success"/> if everything went fine.</returns>
        public ResizeResult ResizeVhdBlob(int newSizeInGb, Uri blobUri, string accountName, string accountKey)
        {
            NewSize = ByteSize.FromGigaBytes(newSizeInGb);

            // Check if blob exists
            blob = new CloudPageBlob(blobUri);
            if (!string.IsNullOrEmpty(accountName) && !string.IsNullOrEmpty(accountKey))
            {
                blob = new CloudPageBlob(blobUri, new StorageCredentials(accountName, accountKey));
            }
            try
            {
                if (!blob.Exists())
                {
                    Console.WriteLine("The specified blob does not exist.");
                    return(ResizeResult.Error);
                }
            }
            catch (StorageException ex)
            {
                Console.WriteLine("The specified storage account credentials are invalid. " + ex.ToString());
                return(ResizeResult.Error);
            }

            // Determine blob attributes
            Console.WriteLine("[{0}] Determining blob size...", DateTime.Now.ToShortTimeString());
            blob.FetchAttributes();
            originalLength = blob.Properties.Length;

            // Read current footer
            Console.WriteLine("[{0}] Reading VHD file format footer...", DateTime.Now.ToShortTimeString());
            footer = new byte[512];
            using (var stream = new MemoryStream())
            {
                blob.DownloadRangeToStream(stream, originalLength - 512, 512);
                stream.Position = 0;
                stream.Read(footer, 0, 512);
                stream.Close();
            }

            footerInstance = Footer.FromBytes(footer, 0);

            // Make sure this is a "fixed" disk
            if (footerInstance.DiskType != FileType.Fixed)
            {
                Console.WriteLine("The specified VHD blob is not a fixed-size disk. WindowsAzureDiskResizer can only resize fixed-size VHD files.");
                return(ResizeResult.Error);
            }
            if (footerInstance.CurrentSize >= (long)NewSize.Bytes)
            {
                // The specified VHD blob is larger than the specified new size. Shrinking disks is a potentially dangerous operation
                // Ask the user for confirmation
                return(ResizeResult.Shrink);
            }
            return(DoResizeVhdBlob());
        }
        public PageBlobReadStream(CloudPageBlob blob)
        {
            _blob = blob;

            if (!_blob.Exists())
            {
                throw new ArgumentException();
            }

            _reader = new BinaryReader(_blob.OpenRead());
        }
예제 #4
0
        public static void KillJob(string account, string key, string containerName, string jobDirectory)
        {
            CloudBlobContainer container = InitContainer(account, key, containerName, false);
            string             blobName  = jobDirectory.TrimEnd('/') + "/kill";
            CloudPageBlob      killBlob  = container.GetPageBlobReference(blobName);

            if (!killBlob.Exists())
            {
                killBlob.Create(512);
            }
        }
예제 #5
0
        public void Init()
        {
            if (!_blob.Exists())
            {
                //var nextSize = NextSize(0);
                _blob.Create(0, AccessCondition.GenerateIfNoneMatchCondition("*"));
            }

            _size = _blob.Properties.Length;
            _etag = _blob.Properties.ETag;
        }
        public Aligned_PageBlobStream(CloudPageBlob blob)
        {
            _blob = blob;

            if (!_blob.Exists())
            {
                throw new ArgumentException();
            }
            //_stream = _blob.OpenRead();
            // _reader = new BinaryReader(_blob.OpenRead());
        }
        /// <summary>
        /// Returns the size of the VHD file specified, in bytes.
        /// </summary>
        /// <param name="vhdFileUri">The location of the VHD file in the storage account, as a <see cref="Uri"/> object.</param>
        /// <param name="useDevelopment">True to use the Azure Storage Emulator, False to connect to the storage account using the other parameters.</param>
        /// <param name="accountName">The name of the account to use, if useDevelopment is false.</param>
        /// <param name="accountKey">The key of the account to use, if useDevelopment is false.</param>
        /// <returns></returns>
        public static long GetVhdSizeInContainer(Uri vhdFileUri, bool useDevelopment = true, string accountName = null, string accountKey = null)
        {
            var account = GetStorageAccount(useDevelopment, accountName, accountKey);
            var client  = account.CreateCloudBlobClient();
            var blob    = new CloudPageBlob(vhdFileUri, client);

            if (blob.Exists())
            {
                blob.FetchAttributes();
                return(blob.Properties.Length);
            }
            else
            {
                return(0L);
            }
        }
예제 #8
0
        public long GetOrInitPosition()
        {
            // blob.Exists actually fetches metadata
            if (!_blob.Exists())
            {
                _blob.Metadata[CloudSetup.CheckpointMetadataName] = "0";
                _blob.Create(0, AccessCondition.GenerateIfNoneMatchCondition("*"));
                _etag = _blob.Properties.ETag;
                return(0);
            }
            var position = _blob.Metadata[CloudSetup.CheckpointMetadataName];

            _etag = _blob.Properties.ETag;
            var result = long.Parse(position);

            Ensure.ZeroOrGreater("position", result);
            return(result);
        }
예제 #9
0
        public PageBlobAppendStream(CloudPageBlob blob)
        {
            _blob = blob;
            if (blob == null)
            {
                throw new ArgumentNullException("blob");
            }

            _reader = new BinaryReader(_blob.OpenRead());
            if (!blob.Exists())
            {
                _blob.Create(0);
                _lastPageIndex = -1;
                return;
            }

            _blobLength    = _blob.Properties.Length;
            _lastPageIndex = (_blobLength / PageSize) - 1;
        }
예제 #10
0
        /// <summary>
        /// Wait for the VHD Blob to disappear in order to confirm the VM and its OS disk were deleted.
        /// </summary>
        /// <param name="pollIntervalSeconds"></param>
        /// <param name="action"></param>
        internal void PollVHDBlob(int pollIntervalSeconds, Action action)
        {
            //var account = new CloudStorageAccount(new Microsoft.WindowsAzure.Storage.Auth.StorageCredentials(_parameters.StorageAccountName, _primaryKey), true);
            //var client = account.CreateCloudBlobClient();
            var blobName = String.Format("https://{0}.blob.core.windows.net/vhds/{1}", _parameters.StorageAccountName, _parameters.VMName);
            var blob     = new CloudPageBlob(new Uri(blobName), new Microsoft.WindowsAzure.Storage.Auth.StorageCredentials(_parameters.StorageAccountName, _primaryKey));

            while (true)
            {
                // Break if the Blob has disappeared
                if (!blob.Exists())
                {
                    break;
                }
                // Execute the action
                action();
                // Wait a while
                System.Threading.Thread.Sleep(pollIntervalSeconds * 1000);
            }
        }
예제 #11
0
 public long Read()
 {
     try {
         // blob exists will actually fetch attributes but suppress error on 404
         if (!_blob.Exists())
         {
             return(0);
         }
         var s      = _blob.Metadata[CloudSetup.CheckpointMetadataName];
         var result = long.Parse(s);
         Ensure.ZeroOrGreater("result", result);
         return(result);
     }
     catch (StorageException ex) {
         // if forbidden, then we might have an expired SAS token
         if (ex.RequestInformation != null && ex.RequestInformation.HttpStatusCode == 403)
         {
             throw new ForbiddenException("Can't read blob", ex);
         }
         throw;
     }
 }
예제 #12
0
        static async Task HeartBeat(ILogger logger, PersistentProcessManager server, Task <int> exited, string jobName)
        {
            try
            {
                DateTime startTime = DateTime.UtcNow;

                if (jobDirectoryUri.Scheme != "azureblob")
                {
                    logger.Log("Can't send heartbeat to non-Azure dfs " + jobDirectoryUri.AbsoluteUri);
                    return;
                }

                string account, key, container, directoryName;
                Azure.Utils.FromAzureUri(jobDirectoryUri, out account, out key, out container, out directoryName);

                // get the full name of the blob from the job directory
                string heartbeatBlobName = directoryName + "heartbeat";
                string killBlobName      = directoryName + "kill";

                using (Azure.AzureDfsClient client = new Azure.AzureDfsClient(account, key, container))
                {
                    CloudPageBlob killBlob      = client.Container.GetPageBlobReference(killBlobName);
                    CloudPageBlob heartbeatBlob = client.Container.GetPageBlobReference(heartbeatBlobName);

                    await heartbeatBlob.CreateAsync(512);

                    heartbeatBlob.Metadata["status"]    = "running";
                    heartbeatBlob.Metadata["starttime"] = startTime.ToString();
                    if (jobName != null)
                    {
                        jobName = jobName.Replace('\r', ' ').Replace('\n', ' ');
                        try
                        {
                            heartbeatBlob.Metadata["jobname"] = jobName;
                        }
                        catch (Exception e)
                        {
                            logger.Log("Got exception trying to set jobname metadata to '" + jobName + "': " + e.ToString());
                            heartbeatBlob.Metadata["jobname"] = "[got exception setting job name]";
                        }
                    }

                    while (true)
                    {
                        logger.Log("Uploading heartbeat properties");
                        heartbeatBlob.Metadata["heartbeat"] = DateTime.UtcNow.ToString();
                        await heartbeatBlob.SetMetadataAsync();

                        logger.Log("Heartbeat sleeping");

                        Task <int> t = await Task.WhenAny(exited, Task.Delay(1000).ContinueWith((d) => { return(259); }));

                        int    exitCode = t.Result;
                        string status   = null;

                        if (t == exited)
                        {
                            status = (exitCode == 0) ? "success" : "failure";
                        }
                        else if (killBlob.Exists())
                        {
                            exitCode = 1;
                            status   = "killed";
                            server.TriggerFullShutdown(1, "job was cancelled");
                        }

                        if (status != null)
                        {
                            logger.Log("Uploading final heartbeat properties " + exitCode + " " + status);
                            heartbeatBlob.Metadata["status"] = status;
                            await heartbeatBlob.SetMetadataAsync();

                            logger.Log("Heartbeat exiting");
                            return;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                logger.Log("Heartbeat got exception " + e.ToString());
            }
        }