diff --git a/src/AzureSignTool/AzureSignTool.csproj b/src/AzureSignTool/AzureSignTool.csproj index a90c5f2..1746740 100644 --- a/src/AzureSignTool/AzureSignTool.csproj +++ b/src/AzureSignTool/AzureSignTool.csproj @@ -22,6 +22,7 @@ all + diff --git a/src/AzureSignTool/HRESULT.cs b/src/AzureSignTool/HRESULT.cs index 3f2adb3..0aae757 100644 --- a/src/AzureSignTool/HRESULT.cs +++ b/src/AzureSignTool/HRESULT.cs @@ -12,5 +12,7 @@ internal static class HRESULT public const int E_ALL_FAILED = unchecked((int)0xA0000002); public const int TRUST_E_SUBJECT_FORM_UNKNOWN = unchecked((int)0x800B0003); + + public const int E_VAULT_THROTTLING = unchecked((int)0x801901AD); } } diff --git a/src/AzureSignTool/SignCommand.cs b/src/AzureSignTool/SignCommand.cs index 07175b8..365428a 100644 --- a/src/AzureSignTool/SignCommand.cs +++ b/src/AzureSignTool/SignCommand.cs @@ -3,6 +3,8 @@ using McMaster.Extensions.CommandLineUtils.Abstractions; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Console; +using Polly.Retry; +using Polly; using RSAKeyVaultProvider; using System; @@ -104,6 +106,18 @@ internal sealed class SignCommand [Argument(0, "file", "The path to the file.")] public string[] Files { get; set; } = []; + // retry strategy for Keyvault throttling errors + // https://learn.microsoft.com/en-us/azure/key-vault/general/overview-throttling + private readonly ResiliencePipeline _resiliencePipeline = new ResiliencePipelineBuilder() + .AddRetry(new RetryStrategyOptions + { + ShouldHandle = new PredicateBuilder().HandleResult(result => (int)result == E_VAULT_THROTTLING), + BackoffType = DelayBackoffType.Exponential, + MaxRetryAttempts = 4, + Delay = TimeSpan.FromSeconds(2) + }) + .Build(); + private HashSet _allFiles; public HashSet AllFiles { @@ -321,9 +335,10 @@ public async Task OnExecuteAsync(IConsole console) { logger.LogInformation("Skipping already signed file."); return (state.succeeded + 1, state.failed); - } + } + + var result = _resiliencePipeline.Execute(() => signer.SignFile(filePath, Description, DescriptionUri, performPageHashing, logger, appendSignature)); - var result = signer.SignFile(filePath, Description, DescriptionUri, performPageHashing, logger, appendSignature); switch (result) { case COR_E_BADIMAGEFORMAT: