image-spec icon indicating copy to clipboard operation
image-spec copied to clipboard

Support referrers responses in the Image Layout

Open sudo-bmitch opened this issue 1 year ago • 8 comments

This defines how referrers should be implemented with the Image Layout. Presently, they can be stored in the Layout using the fallback tag. That has issues for tooling that doesn't want to pollute the tag namespace. The proposed solution adds a org.opencontainers.image.referrer.subject annotation, which indicates the descriptor references a referrers response for the specified subject digest, as a drop in replacement for the fallback tag.

I've tested these annotations in a registry that is based on a filesystem of OCI Image Layout content.

sudo-bmitch avatar Feb 20 '24 21:02 sudo-bmitch

oras-go (versions >= v2.0.0) and oras (versions >= 1.0.0) support referrers natively for the image layout without the fallback tag. Basically, oras puts the referrer manifests in the index.json file without specifying a tag so that oras can traverse to that node without scanning all blobs. The benefits of this methods are

  • Clean: fallback tag is not required.
  • Backward compatible: backfill is not required. Backward compatible with existing image layout and tools.
  • Organized: index.json is de facto a manifest list where some of the manifests have a tag.
  • Performant: scanning the blobs folder is not required.

Here's a sample output using oras 1.2.0-beta.1.

$ echo foo > foo.txt
$ oras push --oci-layout hello:foo foo.txt
✓ Uploaded  foo.txt                                                                                4/4  B 100.00%    2ms
  └─ sha256:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c
✓ Uploaded  application/vnd.oci.empty.v1+json                                                      2/2  B 100.00%    2ms
  └─ sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a
✓ Uploaded  application/vnd.oci.image.manifest.v1+json                                         585/585  B 100.00%  992µs
  └─ sha256:7f1216714a7ecbe4525a55ec07c4bb1d06d32cc862f6e4c6598395aeb89e1be8
Pushed [oci-layout] hello:foo
Digest: sha256:7f1216714a7ecbe4525a55ec07c4bb1d06d32cc862f6e4c6598395aeb89e1be8
$ echo bar > bar.txt
$ oras attach --oci-layout --artifact-type application/bar hello:foo bar.txt
✓ Exists    application/vnd.oci.empty.v1+json                                                      2/2  B 100.00%     0s
  └─ sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a
✓ Uploaded  bar.txt                                                                                4/4  B 100.00%  826µs
  └─ sha256:7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730
✓ Uploaded  application/vnd.oci.image.manifest.v1+json                                         897/897  B 100.00%  444µs
  └─ sha256:0570b97df7a9bf4bcef65e724cc60d663f09b7650d5010d03a3ed4571d385e81
Attached to [oci-layout] hello@sha256:7f1216714a7ecbe4525a55ec07c4bb1d06d32cc862f6e4c6598395aeb89e1be8
Digest: sha256:0570b97df7a9bf4bcef65e724cc60d663f09b7650d5010d03a3ed4571d385e81
$ oras discover --oci-layout hello:foo
Discovered 1 artifact referencing foo
Digest: sha256:7f1216714a7ecbe4525a55ec07c4bb1d06d32cc862f6e4c6598395aeb89e1be8

Artifact Type     Digest
application/bar   sha256:0570b97df7a9bf4bcef65e724cc60d663f09b7650d5010d03a3ed4571d385e81
$ tree hello
hello
├── blobs
│   └── sha256
│       ├── 0570b97df7a9bf4bcef65e724cc60d663f09b7650d5010d03a3ed4571d385e81
│       ├── 44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a
│       ├── 7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730
│       ├── 7f1216714a7ecbe4525a55ec07c4bb1d06d32cc862f6e4c6598395aeb89e1be8
│       └── b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c
├── index.json
├── ingest
└── oci-layout

3 directories, 7 files

The resulted hello/index.json after formating is

{
  "schemaVersion": 2,
  "manifests": [
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:7f1216714a7ecbe4525a55ec07c4bb1d06d32cc862f6e4c6598395aeb89e1be8",
      "size": 585,
      "annotations": {
        "org.opencontainers.image.created": "2024-02-21T09:33:26Z",
        "org.opencontainers.image.ref.name": "foo"
      },
      "artifactType": "application/vnd.unknown.artifact.v1"
    },
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:0570b97df7a9bf4bcef65e724cc60d663f09b7650d5010d03a3ed4571d385e81",
      "size": 897,
      "annotations": {
        "org.opencontainers.image.created": "2024-02-21T09:34:11Z"
      },
      "artifactType": "application/bar"
    }
  ]
}

/cc @sajayantony

shizhMSFT avatar Feb 21 '24 09:02 shizhMSFT

Performant: scanning the blobs folder is not required.

Wouldn't oras discover need to read the manifest of every untagged index entry from the blob store? This proposal would eliminate that.

sudo-bmitch avatar Feb 21 '24 11:02 sudo-bmitch

Wouldn't oras discover need to read the manifest of every untagged index entry from the blob store?

Yes, oras does traverse all manifests to build a graph in the memory. BTW, reading from OCI image layout usually happens on local disk (with system-level file cache). Currently, we don't observe any performance issues yet.

shizhMSFT avatar Mar 04 '24 02:03 shizhMSFT

The inspiration for the annotation pointing to the referrers response, rather than each entry in the response, was to consolidate client workflows. It allows the OCI Layout to be treated the same as a distribution-spec 1.0 registry. By having the annotation on every entry, the client would need a separate workflow for handling an OCI Layout.

Some of this gets into how clients are treating the OCI Layout, whether it's a static transport for a batch process (export/import), or if it's treated like a repository. I think there will always be the first use case. The latter use case opens up a lot of efficiencies and security opportunities for things like CI pipelines that want to review and possibly add metadata before finally uploading it. For those latter use cases, the more an OCI Layout can look like a repository to the tooling, the easier the tooling is to write.

sudo-bmitch avatar Apr 25 '24 18:04 sudo-bmitch