dotnet / sdk-container-builds

Libraries and build tooling to create container images from .NET projects using MSBuild
https://learn.microsoft.com/en-us/dotnet/core/docker/publish-as-container
MIT License
180 stars 31 forks source link

Support referencing a Layer by Digest #325

Open baronfel opened 1 year ago

baronfel commented 1 year ago

Part of #316.

Layers for an image can come from many places - the base image, the direct content of the project being packaged, or an arbitrary registry. We should support defining new Layers to be included in the final image via MSBuild, and how those layers should be retrieved and included in the final layer.

MSBuild

A Layer reference consists of three pieces of data: the Repository the layer belongs to, the Registry the Repository is stored in, and the Digest of the layer itself. We should support defining this in MSBuild. A proposed form of this could be:

<ItemGroup>
  <ContainerLayer Include="<digest value>" Repository="<repository name>" Registry="<registry reference>" />
</ItemGroup>

For example:

<ItemGroup>
  <ContainerLayer Include="sha256:b2b4751952d24fa810a91620aee5f49a1cdf7d05b472a209920f3310f1a84bc1" Repository="dotnet/aspnet" Registry="mcr.microsoft.com" />
</ItemGroup>

These Layers would be passed into the CreateNewImage Task and included in the image.

API

The Layer class has several static factories, and the end result is making a combination of a Descriptor for the Layer and assigning a BackingFile for the layer (which can be done from the descriptor). The data from the Descriptor should be able to be retrieved by issuing a HEAD request to the v2/{repository}/{digest} endpoint - the GET at that same location returns the content while the HEAD would just give the metadata.

Once the metadata is known, the actual Registry.Push/LocalDaemon.Load commands would be responsible for downloading and moving the layer across registries. This should be something already done by our current codepaths.

Open question

richlander commented 1 month ago

This proposed scenario seems wasteful: https://github.com/dotnet/dotnet-docker/discussions/5641#discussioncomment-9943798. Maintaining a base image that only additionally contains a NuGet package seems like a bad tradeoff of effort. Ideally, SDK publish could build multiple layers, one of the app and another for any NuGet packages that should be installed, particularly tools, installed to the regular places.