File: ManifestV2.cs
Web Access
Project: ..\..\..\src\Containers\Microsoft.NET.Build.Containers\Microsoft.NET.Build.Containers.csproj (Microsoft.NET.Build.Containers)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Text.Json;
using System.Text.Json.Serialization;
 
namespace Microsoft.NET.Build.Containers;
 
/// <summary>
/// The struct represents image manifest specification.
/// </summary>
/// <remarks>
/// https://github.com/opencontainers/image-spec/blob/main/manifest.md
/// </remarks>
public class ManifestV2
{
    [JsonIgnore]
    public string? KnownDigest { get; set; }
 
    /// <summary>
    /// This REQUIRED property specifies the image manifest schema version.
    /// For this version of the specification, this MUST be 2 to ensure backward compatibility with older versions of Docker.
    /// The value of this field will not change. This field MAY be removed in a future version of the specification.
    /// </summary>
    [JsonPropertyName("schemaVersion")]
    public required int SchemaVersion { get; init; }
 
    /// <summary>
    /// This property SHOULD be used and remain compatible with earlier versions of this specification and with other similar external formats.
    /// When used, this field MUST contain the media type application/vnd.oci.image.manifest.v1+json. This field usage differs from the descriptor use of mediaType.
    /// </summary>
    [JsonPropertyName("mediaType")]
    public string? MediaType { get; init; }
 
    /// <summary>
    /// This REQUIRED property references a configuration object for a container, by digest.
    /// </summary>
    [JsonPropertyName("config")]
    public required ManifestConfig Config { get; init; }
 
    /// <summary>
    /// Each item in the array MUST be a descriptor. The array MUST have the base layer at index 0.
    /// Subsequent layers MUST then follow in stack order (i.e. from layers[0] to layers[len(layers)-1]).
    /// The final filesystem layout MUST match the result of applying the layers to an empty directory.
    /// The ownership, mode, and other attributes of the initial empty directory are unspecified.
    /// </summary>
    [JsonPropertyName("layers")]
    public required List<ManifestLayer> Layers { get; init; }
 
    /// <summary>
    /// Gets the digest for this manifest.
    /// </summary>
    public string GetDigest() => KnownDigest ??= DigestUtils.GetDigest(JsonSerializer.SerializeToNode(this)?.ToJsonString() ?? string.Empty);
}
 
public record struct ManifestConfig(string mediaType, long size, string digest);
 
public record struct ManifestLayer(string mediaType, long size, string digest, [property: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)][field: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] string[]? urls);