in src/Cli/func/Actions/AzureActions/PublishFunctionAppAction.cs [1183:1245]
private async Task<string> UploadPackageToStorage(Stream package, string blobName, IDictionary<string, string> appSettings)
{
return await RetryHelper.Retry(
async () =>
{
// Setting position to zero, in case we retry, we want to reset the stream
package.Position = 0;
var packageMD5 = SecurityHelpers.CalculateMd5(package);
const string containerName = "function-releases";
CloudBlobContainer blobContainer = null;
try
{
var storageConnection = appSettings["AzureWebJobsStorage"];
var storageAccount = CloudStorageAccount.Parse(storageConnection);
var blobClient = storageAccount.CreateCloudBlobClient();
blobContainer = blobClient.GetContainerReference(containerName);
await blobContainer.CreateIfNotExistsAsync();
}
catch (Exception ex)
{
if (StaticSettings.IsDebug)
{
ColoredConsole.Error.WriteLine(ErrorColor(ex.ToString()));
}
throw new CliException($"Error creating a Blob container reference. Please make sure your connection string in \"AzureWebJobsStorage\" is valid");
}
var blob = blobContainer.GetBlockBlobReference(blobName);
using (var progress = new StorageProgressBar($"Uploading {Utilities.BytesToHumanReadable(package.Length)}", package.Length))
{
await blob.UploadFromStreamAsync(
package,
AccessCondition.GenerateEmptyCondition(),
new BlobRequestOptions(),
new OperationContext(),
progress,
CancellationToken.None);
}
var cloudMd5 = blob.Properties.ContentMD5;
if (!cloudMd5.Equals(packageMD5))
{
throw new CliException("Upload failed: Integrity error: MD5 hash mismatch between the local copy and the uploaded copy.");
}
var sasConstraints = new SharedAccessBlobPolicy();
sasConstraints.SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5);
sasConstraints.SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddYears(10);
sasConstraints.Permissions = SharedAccessBlobPermissions.Read;
var blobToken = blob.GetSharedAccessSignature(sasConstraints);
return blob.Uri + blobToken;
},
3,
TimeSpan.FromSeconds(1),
displayError: true);
}