Skip to content

Commit d403680

Browse files
committed
prefer changes from pr #48987 over #44953
1 parent 6b8e66a commit d403680

File tree

3 files changed

+59
-33
lines changed

3 files changed

+59
-33
lines changed

src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -248,11 +248,6 @@ private static async Task<int> PushToRemoteRegistryAsync(ILogger logger, BuiltIm
248248
logger.LogError(Resource.FormatString(nameof(Strings.UnableToDownloadFromRepository)), sourceImageReference);
249249
return 1;
250250
}
251-
catch (UnableToAccessRepositoryException)
252-
{
253-
logger.LogError(Resource.FormatString(nameof(Strings.UnableToAccessRepository), destinationImageReference.Repository, destinationImageReference.RemoteRegistry!.RegistryName));
254-
return 1;
255-
}
256251
catch (Exception e)
257252
{
258253
logger.LogError(Resource.FormatString(nameof(Strings.RegistryOutputPushFailed), e.Message));

src/Containers/Microsoft.NET.Build.Containers/Registry/Registry.cs

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -414,25 +414,40 @@ public async Task<string> DownloadBlobAsync(string repository, Descriptor descri
414414
// Assume file is up to date and just return it
415415
return localPath;
416416
}
417-
417+
418418
string tempTarballPath = ContentStore.GetTempFile();
419-
420-
try
419+
420+
int retryCount = 0;
421+
while (retryCount < MaxDownloadRetries)
421422
{
422-
// No local copy, so download one
423-
using Stream responseStream = await _registryAPI.Blob.GetStreamAsync(repository, descriptor.Digest, cancellationToken).ConfigureAwait(false);
424-
425-
using (FileStream fs = File.Create(tempTarballPath))
423+
try
426424
{
427-
await responseStream.CopyToAsync(fs, cancellationToken).ConfigureAwait(false);
425+
// No local copy, so download one
426+
using Stream responseStream = await _registryAPI.Blob.GetStreamAsync(repository, descriptor.Digest, cancellationToken).ConfigureAwait(false);
427+
428+
using (FileStream fs = File.Create(tempTarballPath))
429+
{
430+
await responseStream.CopyToAsync(fs, cancellationToken).ConfigureAwait(false);
431+
}
432+
433+
// Break the loop if successful
434+
break;
435+
}
436+
catch (Exception ex)
437+
{
438+
retryCount++;
439+
if (retryCount >= MaxDownloadRetries)
440+
{
441+
throw new UnableToDownloadFromRepositoryException(repository);
442+
}
443+
444+
_logger.LogTrace("Download attempt {0}/{1} for repository '{2}' failed. Error: {3}", retryCount, MaxDownloadRetries, repository, ex.ToString());
445+
446+
// Wait before retrying
447+
await Task.Delay(_retryDelayProvider(), cancellationToken).ConfigureAwait(false);
428448
}
429449
}
430-
catch (Exception)
431-
{
432-
throw new UnableToDownloadFromRepositoryException(repository);
433-
}
434-
cancellationToken.ThrowIfCancellationRequested();
435-
450+
436451
File.Move(tempTarballPath, localPath, overwrite: true);
437452

438453
return localPath;

test/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,9 +1433,10 @@ static string[] DecideEntrypoint(string rid, string appName, string workingDir)
14331433
}
14341434

14351435
[DockerAvailableFact]
1436-
public async Task CheckErrorMessageWhenSourceRepositoryThrows()
1436+
public async void CheckDownloadErrorMessageWhenSourceRepositoryThrows()
14371437
{
1438-
ILogger logger = _loggerFactory.CreateLogger(nameof(CheckErrorMessageWhenSourceRepositoryThrows));
1438+
var loggerFactory = new TestLoggerFactory(_testOutput);
1439+
var logger = loggerFactory.CreateLogger(nameof(CheckDownloadErrorMessageWhenSourceRepositoryThrows));
14391440
string rid = "win-x64";
14401441
string publishDirectory = BuildLocalApp(tfm: ToolsetInfo.CurrentTargetFramework, rid: rid);
14411442

@@ -1461,24 +1462,39 @@ public async Task CheckErrorMessageWhenSourceRepositoryThrows()
14611462

14621463
// Load the image into the local registry
14631464
var sourceReference = new SourceImageReference(registry, "some_random_image", DockerRegistryManager.Net9ImageTag, null);
1464-
var destinationReference = new DestinationImageReference(registry, NewImageName(), new[] { rid });
1465-
var sawMyException = false;
1466-
try
1467-
{
1468-
await new DockerCli(_loggerFactory).LoadAsync(builtImage, sourceReference, destinationReference, default).ConfigureAwait(false);
1469-
}
1470-
catch (UnableToDownloadFromRepositoryException e)
1471-
{
1472-
sawMyException = true;
1473-
Assert.Contains("The download of the image from repository some_random_image has failed", e.ToString());
1474-
}
1475-
Assert.True(sawMyException);
1465+
string archivePath = Path.Combine(TestSettings.TestArtifactsDirectory, nameof(CheckDownloadErrorMessageWhenSourceRepositoryThrows));
1466+
var destinationReference = new DestinationImageReference(new ArchiveFileRegistry(archivePath), NewImageName(), new[] { rid });
1467+
1468+
(var taskLog, var errors) = SetupTaskLog();
1469+
var telemetry = new Telemetry(sourceReference, destinationReference, taskLog);
1470+
1471+
await ImagePublisher.PublishImageAsync(builtImage, sourceReference, destinationReference, taskLog, telemetry, CancellationToken.None)
1472+
.ConfigureAwait(false);
1473+
1474+
// Assert the error message
1475+
Assert.True(taskLog.HasLoggedErrors);
1476+
Assert.NotNull(errors);
1477+
Assert.Single(errors);
1478+
Assert.Contains("Unable to download image from the repository", errors[0]);
14761479

14771480
static string[] DecideEntrypoint(string rid, string appName, string workingDir)
14781481
{
14791482
var binary = rid.StartsWith("win", StringComparison.Ordinal) ? $"{appName}.exe" : appName;
14801483
return new[] { $"{workingDir}/{binary}" };
14811484
}
1485+
1486+
static (Microsoft.Build.Utilities.TaskLoggingHelper, List<string?> errors) SetupTaskLog()
1487+
{
1488+
// We can use any Task, we just need TaskLoggingHelper
1489+
Tasks.CreateNewImage cni = new();
1490+
List<string?> errors = new();
1491+
IBuildEngine buildEngine = A.Fake<IBuildEngine>();
1492+
A.CallTo(() => buildEngine.LogWarningEvent(A<BuildWarningEventArgs>.Ignored)).Invokes((BuildWarningEventArgs e) => errors.Add(e.Message));
1493+
A.CallTo(() => buildEngine.LogErrorEvent(A<BuildErrorEventArgs>.Ignored)).Invokes((BuildErrorEventArgs e) => errors.Add(e.Message));
1494+
A.CallTo(() => buildEngine.LogMessageEvent(A<BuildMessageEventArgs>.Ignored)).Invokes((BuildMessageEventArgs e) => errors.Add(e.Message));
1495+
cni.BuildEngine = buildEngine;
1496+
return (cni.Log, errors);
1497+
}
14821498
}
14831499

14841500
[DockerAvailableFact(checkContainerdStoreAvailability: true)]

0 commit comments

Comments
 (0)