From 7f709163e73e78405ecb7e3a0a92ce9f6816340c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jim=20Br=C3=A4nnlund?= Date: Sat, 26 Oct 2024 11:44:02 +0000 Subject: [PATCH] Add support for using Digest for base image Add support for using image digest (sha256) for the base image when using the `PublishContainer` target. For example: `mcr.microsoft.com/dotnet/aspnet@sha256:6cec36412a215aad2a033cfe259890482be0a1dcb680e81fccc393b2d4069455` --- .../ContainerBuilder.cs | 8 +++-- .../KnownStrings.cs | 1 + .../PublicAPI/net472/PublicAPI.Unshipped.txt | 5 ++- .../PublicAPI/net9.0/PublicAPI.Unshipped.txt | 5 ++- .../SourceImageReference.cs | 33 +++++++++++++++---- .../Tasks/CreateNewImage.Interface.cs | 7 ++++ .../Tasks/CreateNewImage.cs | 7 ++-- .../Tasks/CreateNewImageToolTask.cs | 4 +++ .../Tasks/ParseContainerProperties.cs | 8 ++++- .../containerize/ContainerizeCommand.cs | 9 +++++ .../Microsoft.NET.Build.Containers.targets | 2 ++ .../CreateNewImageTests.cs | 2 +- .../DockerRegistryManager.cs | 4 +-- .../DockerRegistryTests.cs | 2 +- .../EndToEndTests.cs | 8 ++--- 15 files changed, 81 insertions(+), 24 deletions(-) diff --git a/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs b/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs index 48867a93de6b..a89bf37b3321 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs @@ -14,6 +14,7 @@ internal static async Task ContainerizeAsync( string baseRegistry, string baseImageName, string baseImageTag, + string? baseImageDigest, string[] entrypoint, string[] entrypointArgs, string[] defaultArgs, @@ -47,7 +48,7 @@ internal static async Task ContainerizeAsync( bool isLocalPull = string.IsNullOrEmpty(baseRegistry); RegistryMode sourceRegistryMode = baseRegistry.Equals(outputRegistry, StringComparison.InvariantCultureIgnoreCase) ? RegistryMode.PullFromOutput : RegistryMode.Pull; Registry? sourceRegistry = isLocalPull ? null : new Registry(baseRegistry, logger, sourceRegistryMode); - SourceImageReference sourceImageReference = new(sourceRegistry, baseImageName, baseImageTag); + SourceImageReference sourceImageReference = new(sourceRegistry, baseImageName, baseImageTag, baseImageDigest); DestinationImageReference destinationImageReference = DestinationImageReference.CreateFromSettings( imageName, @@ -62,17 +63,18 @@ internal static async Task ContainerizeAsync( { try { + string imageReference = !string.IsNullOrEmpty(baseImageDigest) ? baseImageDigest : baseImageTag; var ridGraphPicker = new RidGraphManifestPicker(ridGraphPath); imageBuilder = await registry.GetImageManifestAsync( baseImageName, - baseImageTag, + imageReference, containerRuntimeIdentifier, ridGraphPicker, cancellationToken).ConfigureAwait(false); } catch (RepositoryNotFoundException) { - logger.LogError(Resource.FormatString(nameof(Strings.RepositoryNotFound), baseImageName, baseImageTag, registry.RegistryName)); + logger.LogError(Resource.FormatString(nameof(Strings.RepositoryNotFound), baseImageName, baseImageTag, baseImageDigest, registry.RegistryName)); return 1; } catch (UnableToAccessRepositoryException) diff --git a/src/Containers/Microsoft.NET.Build.Containers/KnownStrings.cs b/src/Containers/Microsoft.NET.Build.Containers/KnownStrings.cs index 492027a1f41d..172358b16874 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/KnownStrings.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/KnownStrings.cs @@ -31,6 +31,7 @@ public static class Properties public static readonly string ContainerBaseRegistry = nameof(ContainerBaseRegistry); public static readonly string ContainerBaseName = nameof(ContainerBaseName); public static readonly string ContainerBaseTag = nameof(ContainerBaseTag); + public static readonly string ContainerBaseDigest = nameof(ContainerBaseDigest); public static readonly string ContainerGenerateLabels = nameof(ContainerGenerateLabels); diff --git a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net472/PublicAPI.Unshipped.txt b/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net472/PublicAPI.Unshipped.txt index 6dd6551ddb37..5972149a0fca 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net472/PublicAPI.Unshipped.txt +++ b/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net472/PublicAPI.Unshipped.txt @@ -29,6 +29,8 @@ Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseImageName.get -> string! Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseImageName.set -> void Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseImageTag.get -> string! Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseImageTag.set -> void +Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseImageDigest.get -> string! +Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseImageDigest.set -> void Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseRegistry.get -> string! Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseRegistry.set -> void Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ContainerEnvironmentVariables.get -> Microsoft.Build.Framework.ITaskItem![]! @@ -111,6 +113,7 @@ Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ParseContainerProp Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ParsedContainerImage.get -> string! Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ParsedContainerRegistry.get -> string! Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ParsedContainerTag.get -> string! +Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ParsedContainerDigest.get -> string! override Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.Execute() -> bool static Microsoft.NET.Build.Containers.ContainerHelpers.TryParsePort(string! input, out Microsoft.NET.Build.Containers.Port? port, out Microsoft.NET.Build.Containers.ContainerHelpers.ParsePortError? error) -> bool static Microsoft.NET.Build.Containers.ContainerHelpers.TryParsePort(string? portNumber, string? portType, out Microsoft.NET.Build.Containers.Port? port, out Microsoft.NET.Build.Containers.ContainerHelpers.ParsePortError? error) -> bool @@ -134,4 +137,4 @@ Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.SdkVersion.get Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.SdkVersion.set -> void Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.TargetFrameworkVersion.get -> string! Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.TargetFrameworkVersion.set -> void -override Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.Execute() -> bool \ No newline at end of file +override Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.Execute() -> bool diff --git a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net9.0/PublicAPI.Unshipped.txt b/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net9.0/PublicAPI.Unshipped.txt index 8e7f42f35d3f..543be75b1dd7 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net9.0/PublicAPI.Unshipped.txt +++ b/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net9.0/PublicAPI.Unshipped.txt @@ -148,6 +148,8 @@ Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseImageName.get -> string! Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseImageName.set -> void Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseImageTag.get -> string! Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseImageTag.set -> void +Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseImageDigest.get -> string! +Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseImageDigest.set -> void Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseRegistry.get -> string! Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseRegistry.set -> void Microsoft.NET.Build.Containers.Tasks.CreateNewImage.Cancel() -> void @@ -232,6 +234,7 @@ Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ParseContainerProp Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ParsedContainerImage.get -> string! Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ParsedContainerRegistry.get -> string! Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ParsedContainerTag.get -> string! +Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ParsedContainerDigest.get -> string! override Microsoft.NET.Build.Containers.Tasks.CreateNewImage.Execute() -> bool override Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.Execute() -> bool static Microsoft.NET.Build.Containers.ContainerHelpers.TryParsePort(string! input, out Microsoft.NET.Build.Containers.Port? port, out Microsoft.NET.Build.Containers.ContainerHelpers.ParsePortError? error) -> bool @@ -284,4 +287,4 @@ static Microsoft.NET.Build.Containers.ImageIndexV1.operator ==(Microsoft.NET.Bui override Microsoft.NET.Build.Containers.ImageIndexV1.GetHashCode() -> int ~override Microsoft.NET.Build.Containers.ImageIndexV1.Equals(object obj) -> bool Microsoft.NET.Build.Containers.ImageIndexV1.Equals(Microsoft.NET.Build.Containers.ImageIndexV1 other) -> bool -Microsoft.NET.Build.Containers.ImageIndexV1.Deconstruct(out int schemaVersion, out string! mediaType, out Microsoft.NET.Build.Containers.PlatformSpecificManifest[]! manifests) -> void \ No newline at end of file +Microsoft.NET.Build.Containers.ImageIndexV1.Deconstruct(out int schemaVersion, out string! mediaType, out Microsoft.NET.Build.Containers.PlatformSpecificManifest[]! manifests) -> void diff --git a/src/Containers/Microsoft.NET.Build.Containers/SourceImageReference.cs b/src/Containers/Microsoft.NET.Build.Containers/SourceImageReference.cs index 0775f853dad1..f584f7ff0e23 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/SourceImageReference.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/SourceImageReference.cs @@ -4,19 +4,33 @@ namespace Microsoft.NET.Build.Containers; /// -/// Represents a reference to a Docker image. A reference is made of a registry, a repository (aka the image name) and a tag. +/// Represents a reference to a Docker image. A reference is made of a registry, a repository (aka the image name) and a tag or digest. /// -internal readonly record struct SourceImageReference(Registry? Registry, string Repository, string Tag) +internal readonly record struct SourceImageReference(Registry? Registry, string Repository, string Tag, string? Digest) { public override string ToString() { - if (Registry is { } reg) + if (Registry is { } reg) { - return $"{reg.RegistryName}/{Repository}:{Tag}"; - } - else + if (Digest is { } dig) + { + return $"{reg.RegistryName}/{Repository}@{dig}"; + } + else + { + return $"{reg.RegistryName}/{Repository}:{Tag}"; + } + } + else { - return RepositoryAndTag; + if (Digest is { } dig) + { + return RepositoryAndDigest; + } + else + { + return RepositoryAndTag; + } } } @@ -24,4 +38,9 @@ public override string ToString() /// Returns the repository and tag as a formatted string. Used in cases /// public readonly string RepositoryAndTag => $"{Repository}:{Tag}"; + + /// + /// Returns the repository and digest as a formatted string. + /// + public readonly string RepositoryAndDigest => $"{Repository}@{Digest}"; } diff --git a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.Interface.cs b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.Interface.cs index 4f69658c66d2..a74adeaa0845 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.Interface.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.Interface.cs @@ -37,6 +37,12 @@ partial class CreateNewImage [Required] public string BaseImageTag { get; set; } + /// + /// The base image digest. + /// Ex: sha256:12345... + /// + public string BaseImageDigest { get; set; } + /// /// The registry to push to. /// @@ -184,6 +190,7 @@ public CreateNewImage() BaseRegistry = ""; BaseImageName = ""; BaseImageTag = ""; + BaseImageDigest = ""; OutputRegistry = ""; ArchiveOutputPath = ""; Repository = ""; diff --git a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs index e6537b3160af..dee12ce7b8b1 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs @@ -62,7 +62,7 @@ internal async Task ExecuteAsync(CancellationToken cancellationToken) RegistryMode sourceRegistryMode = BaseRegistry.Equals(OutputRegistry, StringComparison.InvariantCultureIgnoreCase) ? RegistryMode.PullFromOutput : RegistryMode.Pull; Registry? sourceRegistry = IsLocalPull ? null : new Registry(BaseRegistry, logger, sourceRegistryMode); - SourceImageReference sourceImageReference = new(sourceRegistry, BaseImageName, BaseImageTag); + SourceImageReference sourceImageReference = new(sourceRegistry, BaseImageName, BaseImageTag, BaseImageDigest); DestinationImageReference destinationImageReference = DestinationImageReference.CreateFromSettings( Repository, @@ -79,10 +79,11 @@ internal async Task ExecuteAsync(CancellationToken cancellationToken) { try { + string imageReference = !string.IsNullOrEmpty(BaseImageDigest) ? BaseImageDigest : BaseImageTag; var picker = new RidGraphManifestPicker(RuntimeIdentifierGraphPath); imageBuilder = await registry.GetImageManifestAsync( BaseImageName, - BaseImageTag, + imageReference, ContainerRuntimeIdentifier, picker, cancellationToken).ConfigureAwait(false); @@ -90,7 +91,7 @@ internal async Task ExecuteAsync(CancellationToken cancellationToken) catch (RepositoryNotFoundException) { telemetry.LogUnknownRepository(); - Log.LogErrorWithCodeFromResources(nameof(Strings.RepositoryNotFound), BaseImageName, BaseImageTag, registry.RegistryName); + Log.LogErrorWithCodeFromResources(nameof(Strings.RepositoryNotFound), BaseImageName, BaseImageTag, BaseImageDigest, registry.RegistryName); return !Log.HasLoggedErrors; } catch (UnableToAccessRepositoryException) diff --git a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImageToolTask.cs b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImageToolTask.cs index 698cea555c10..c1bc8fc24af8 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImageToolTask.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImageToolTask.cs @@ -107,6 +107,10 @@ internal string GenerateCommandLineCommandsInt() { builder.AppendSwitchIfNotNull("--baseimagetag ", BaseImageTag); } + if (!string.IsNullOrWhiteSpace(BaseImageDigest)) + { + builder.AppendSwitchIfNotNull("--baseimagedigest ", BaseImageDigest); + } if (!string.IsNullOrWhiteSpace(OutputRegistry)) { builder.AppendSwitchIfNotNull("--outputregistry ", OutputRegistry); diff --git a/src/Containers/Microsoft.NET.Build.Containers/Tasks/ParseContainerProperties.cs b/src/Containers/Microsoft.NET.Build.Containers/Tasks/ParseContainerProperties.cs index 0efe65781c85..bab45e1c1ce1 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Tasks/ParseContainerProperties.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Tasks/ParseContainerProperties.cs @@ -48,6 +48,9 @@ public sealed class ParseContainerProperties : Microsoft.Build.Utilities.Task [Output] public string ParsedContainerTag { get; private set; } + [Output] + public string ParsedContainerDigest { get; private set; } + [Output] public string NewContainerRegistry { get; private set; } @@ -71,6 +74,7 @@ public ParseContainerProperties() ParsedContainerRegistry = ""; ParsedContainerImage = ""; ParsedContainerTag = ""; + ParsedContainerDigest = ""; NewContainerRegistry = ""; NewContainerRepository = ""; NewContainerTags = Array.Empty(); @@ -132,7 +136,7 @@ public override bool Execute() out string? outputReg, out string? outputImage, out string? outputTag, - out string? _outputDigest, + out string? outputDigest, out bool isRegistrySpecified)) { Log.LogErrorWithCodeFromResources(nameof(Strings.BaseImageNameParsingFailed), nameof(FullyQualifiedBaseImageName), FullyQualifiedBaseImageName); @@ -163,6 +167,7 @@ public override bool Execute() ParsedContainerRegistry = outputReg ?? ""; ParsedContainerImage = outputImage ?? ""; ParsedContainerTag = outputTag ?? ""; + ParsedContainerDigest = outputDigest ?? ""; NewContainerRegistry = ContainerRegistry; NewContainerTags = validTags; @@ -172,6 +177,7 @@ public override bool Execute() Log.LogMessage(MessageImportance.Low, "Host: {0}", ParsedContainerRegistry); Log.LogMessage(MessageImportance.Low, "Image: {0}", ParsedContainerImage); Log.LogMessage(MessageImportance.Low, "Tag: {0}", ParsedContainerTag); + Log.LogMessage(MessageImportance.Low, "Digest: {0}", ParsedContainerDigest); Log.LogMessage(MessageImportance.Low, "Image Name: {0}", NewContainerRepository); Log.LogMessage(MessageImportance.Low, "Image Tags: {0}", string.Join(", ", NewContainerTags)); } diff --git a/src/Containers/containerize/ContainerizeCommand.cs b/src/Containers/containerize/ContainerizeCommand.cs index cba5b0a012b7..fd47e728142c 100644 --- a/src/Containers/containerize/ContainerizeCommand.cs +++ b/src/Containers/containerize/ContainerizeCommand.cs @@ -35,6 +35,12 @@ internal class ContainerizeCommand : CliRootCommand DefaultValueFactory = (_) => "latest" }; + internal CliOption BaseImageDigestOption { get; } = new("--baseimagedigest") + { + Description = "The base image digest. Ex: sha256:6cec3641...", + Required = false + }; + internal CliOption OutputRegistryOption { get; } = new("--outputregistry") { Description = "The registry to push to.", @@ -204,6 +210,7 @@ internal ContainerizeCommand() : base("Containerize an application without Docke Options.Add(BaseRegistryOption); Options.Add(BaseImageNameOption); Options.Add(BaseImageTagOption); + Options.Add(BaseImageDigestOption); Options.Add(OutputRegistryOption); Options.Add(ArchiveOutputPathOption); Options.Add(RepositoryOption); @@ -232,6 +239,7 @@ internal ContainerizeCommand() : base("Containerize an application without Docke string _baseReg = parseResult.GetValue(BaseRegistryOption)!; string _baseName = parseResult.GetValue(BaseImageNameOption)!; string _baseTag = parseResult.GetValue(BaseImageTagOption)!; + string? _baseDigest = parseResult.GetValue(BaseImageDigestOption); string? _outputReg = parseResult.GetValue(OutputRegistryOption); string? _archiveOutputPath = parseResult.GetValue(ArchiveOutputPathOption); string _name = parseResult.GetValue(RepositoryOption)!; @@ -264,6 +272,7 @@ await ContainerBuilder.ContainerizeAsync( _baseReg, _baseName, _baseTag, + _baseDigest, _entrypoint, _entrypointArgs, _defaultArgs, diff --git a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets index 9f4796558438..857020f07035 100644 --- a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets +++ b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets @@ -119,6 +119,7 @@ + @@ -244,6 +245,7 @@ BaseRegistry="$(ContainerBaseRegistry)" BaseImageName="$(ContainerBaseName)" BaseImageTag="$(ContainerBaseTag)" + BaseImageDigest="$(ContainerBaseDigest)" LocalRegistry="$(LocalRegistry)" OutputRegistry="$(ContainerRegistry)" ArchiveOutputPath="$(ContainerArchiveOutputPath)" diff --git a/test/Microsoft.NET.Build.Containers.IntegrationTests/CreateNewImageTests.cs b/test/Microsoft.NET.Build.Containers.IntegrationTests/CreateNewImageTests.cs index 66733c52896c..96eea015e986 100644 --- a/test/Microsoft.NET.Build.Containers.IntegrationTests/CreateNewImageTests.cs +++ b/test/Microsoft.NET.Build.Containers.IntegrationTests/CreateNewImageTests.cs @@ -240,7 +240,7 @@ public async System.Threading.Tasks.Task CreateNewImage_RootlessBaseImage() BuiltImage builtImage = imageBuilder.Build(); - var sourceReference = new SourceImageReference(registry, DockerRegistryManager.RuntimeBaseImage, DockerRegistryManager.Net8ImageTag); + var sourceReference = new SourceImageReference(registry, DockerRegistryManager.RuntimeBaseImage, DockerRegistryManager.Net8ImageTag, null); var destinationReference = new DestinationImageReference(registry, RootlessBase, new[] { "latest" }); await registry.PushAsync(builtImage, sourceReference, destinationReference, cancellationToken: default).ConfigureAwait(false); diff --git a/test/Microsoft.NET.Build.Containers.IntegrationTests/DockerRegistryManager.cs b/test/Microsoft.NET.Build.Containers.IntegrationTests/DockerRegistryManager.cs index cc7aa1abc878..49730208382b 100644 --- a/test/Microsoft.NET.Build.Containers.IntegrationTests/DockerRegistryManager.cs +++ b/test/Microsoft.NET.Build.Containers.IntegrationTests/DockerRegistryManager.cs @@ -25,7 +25,7 @@ public class DockerRegistryManager internal class SameArchManifestPicker : IManifestPicker { - public PlatformSpecificManifest? PickBestManifestForRid(IReadOnlyDictionary manifestList, string runtimeIdentifier) + public PlatformSpecificManifest? PickBestManifestForRid(IReadOnlyDictionary manifestList, string runtimeIdentifier) { return manifestList.Values.SingleOrDefault(m => m.platform.os == "linux" && m.platform.architecture == "amd64"); } @@ -74,7 +74,7 @@ public static async Task StartAndPopulateDockerRegistry(ITestOutputHelper testOu var ridjson = Path.Combine(Path.GetDirectoryName(dotnetdll)!, "RuntimeIdentifierGraph.json"); var image = await pullRegistry.GetImageManifestAsync(RuntimeBaseImage, tag, "linux-x64", new SameArchManifestPicker(), CancellationToken.None); - var source = new SourceImageReference(pullRegistry, RuntimeBaseImage, tag); + var source = new SourceImageReference(pullRegistry, RuntimeBaseImage, tag, null); var dest = new DestinationImageReference(pushRegistry, RuntimeBaseImage, [tag]); logger.LogInformation($"Pushing image for {BaseImageSource}/{RuntimeBaseImage}:{tag}"); await pushRegistry.PushAsync(image.Build(), source, dest, CancellationToken.None); diff --git a/test/Microsoft.NET.Build.Containers.IntegrationTests/DockerRegistryTests.cs b/test/Microsoft.NET.Build.Containers.IntegrationTests/DockerRegistryTests.cs index a992e06b4e8c..64404c07fed8 100644 --- a/test/Microsoft.NET.Build.Containers.IntegrationTests/DockerRegistryTests.cs +++ b/test/Microsoft.NET.Build.Containers.IntegrationTests/DockerRegistryTests.cs @@ -79,7 +79,7 @@ public async Task WriteToPrivateBasicRegistry() var ridgraphfile = ToolsetUtils.GetRuntimeGraphFilePath(); Registry mcr = new(DockerRegistryManager.BaseImageSource, logger, RegistryMode.Pull); - var sourceImage = new SourceImageReference(mcr, DockerRegistryManager.RuntimeBaseImage, DockerRegistryManager.Net6ImageTag); + var sourceImage = new SourceImageReference(mcr, DockerRegistryManager.RuntimeBaseImage, DockerRegistryManager.Net6ImageTag, null); var destinationImage = new DestinationImageReference(localAuthed, DockerRegistryManager.RuntimeBaseImage, new[] { DockerRegistryManager.Net6ImageTag }); ImageBuilder? downloadedImage = await mcr.GetImageManifestAsync( DockerRegistryManager.RuntimeBaseImage, diff --git a/test/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs b/test/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs index 8507aeff567b..96e342b90526 100644 --- a/test/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs +++ b/test/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs @@ -66,7 +66,7 @@ public async Task ApiEndToEndWithRegistryPushAndPull() BuiltImage builtImage = imageBuilder.Build(); // Push the image back to the local registry - var sourceReference = new SourceImageReference(registry, DockerRegistryManager.RuntimeBaseImage, DockerRegistryManager.Net9PreviewImageTag); + var sourceReference = new SourceImageReference(registry, DockerRegistryManager.RuntimeBaseImage, DockerRegistryManager.Net9PreviewImageTag, null); var destinationReference = new DestinationImageReference(registry, NewImageName(), new[] { "latest", "1.0" }); await registry.PushAsync(builtImage, sourceReference, destinationReference, cancellationToken: default).ConfigureAwait(false); @@ -112,7 +112,7 @@ public async Task ApiEndToEndWithLocalLoad() BuiltImage builtImage = imageBuilder.Build(); // Load the image into the local registry - var sourceReference = new SourceImageReference(registry, DockerRegistryManager.RuntimeBaseImage, DockerRegistryManager.Net9PreviewImageTag); + var sourceReference = new SourceImageReference(registry, DockerRegistryManager.RuntimeBaseImage, DockerRegistryManager.Net9PreviewImageTag, null); var destinationReference = new DestinationImageReference(registry, NewImageName(), new[] { "latest", "1.0" }); await new DockerCli(_loggerFactory).LoadAsync(builtImage, sourceReference, destinationReference, default).ConfigureAwait(false); @@ -155,7 +155,7 @@ public async Task ApiEndToEndWithArchiveWritingAndLoad() // Write the image to disk var archiveFile = Path.Combine(TestSettings.TestArtifactsDirectory, nameof(ApiEndToEndWithArchiveWritingAndLoad), "app.tar.gz"); - var sourceReference = new SourceImageReference(registry, DockerRegistryManager.RuntimeBaseImage, DockerRegistryManager.Net9PreviewImageTag); + var sourceReference = new SourceImageReference(registry, DockerRegistryManager.RuntimeBaseImage, DockerRegistryManager.Net9PreviewImageTag, null); var destinationReference = new DestinationImageReference(new ArchiveFileRegistry(archiveFile), NewImageName(), new[] { "latest", "1.0" }); await destinationReference.LocalRegistry!.LoadAsync(builtImage, sourceReference, destinationReference, default).ConfigureAwait(false); @@ -583,7 +583,7 @@ public async Task CanPackageForAllSupportedContainerRIDs(string dockerPlatform, BuiltImage builtImage = imageBuilder.Build(); // Load the image into the local registry - var sourceReference = new SourceImageReference(registry, DockerRegistryManager.RuntimeBaseImage, DockerRegistryManager.Net9PreviewImageTag); + var sourceReference = new SourceImageReference(registry, DockerRegistryManager.RuntimeBaseImage, DockerRegistryManager.Net9PreviewImageTag, null); var destinationReference = new DestinationImageReference(registry, NewImageName(), new[] { rid }); await new DockerCli(_loggerFactory).LoadAsync(builtImage, sourceReference, destinationReference, default).ConfigureAwait(false);