Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support referrers to a missing manifest #491

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions conformance/03_discovery_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,18 @@ var test03ContentDiscovery = func() {
BeNumerically(">=", 200),
BeNumerically("<", 300)))
Expect(resp.Header().Get("OCI-Subject")).To(Equal(manifests[4].Digest))

// Populate registry with test references manifest to a non-existent subject
req = client.NewRequest(reggie.PUT, "/v2/<name>/manifests/<reference>",
reggie.WithReference(refsManifestCLayerArtifactDigest)).
SetHeader("Content-Type", "application/vnd.oci.image.manifest.v1+json").
SetBody(refsManifestCLayerArtifactContent)
resp, err = client.Do(req)
Expect(err).To(BeNil())
Expect(resp.StatusCode()).To(SatisfyAll(
BeNumerically(">=", 200),
BeNumerically("<", 300)))
Expect(resp.Header().Get("OCI-Subject")).To(Equal(manifests[3].Digest))
})
})

Expand Down Expand Up @@ -345,6 +357,22 @@ var test03ContentDiscovery = func() {
Warn("filtering by artifact-type is not implemented")
}
})

g.Specify("GET request to missing manifest should yield 200", func() {
SkipIfDisabled(contentDiscovery)
mikebrow marked this conversation as resolved.
Show resolved Hide resolved
req := client.NewRequest(reggie.GET, "/v2/<name>/referrers/<digest>",
reggie.WithDigest(manifests[3].Digest))
resp, err := client.Do(req)
Expect(err).To(BeNil())
Expect(resp.StatusCode()).To(Equal(http.StatusOK))
Expect(resp.Header().Get("Content-Type")).To(Equal("application/vnd.oci.image.index.v1+json"))

var index index
err = json.Unmarshal(resp.Body(), &index)
Expect(err).To(BeNil())
Expect(len(index.Manifests)).To(Equal(1))
Expect(index.Manifests[0].Digest.String()).To(Equal(refsManifestCLayerArtifactDigest))
})
})

g.Context("Teardown", func() {
Expand All @@ -361,6 +389,7 @@ var test03ContentDiscovery = func() {
testTagName,
refsManifestBConfigArtifactDigest,
refsManifestBLayerArtifactDigest,
refsManifestCLayerArtifactDigest,
}
for _, ref := range references {
req := client.NewRequest(reggie.DELETE, "/v2/<name>/manifests/<digest>", reggie.WithDigest(ref))
Expand Down Expand Up @@ -421,6 +450,7 @@ var test03ContentDiscovery = func() {
testTagName,
refsManifestBConfigArtifactDigest,
refsManifestBLayerArtifactDigest,
refsManifestCLayerArtifactDigest,
}
for _, ref := range references {
req := client.NewRequest(reggie.DELETE, "/v2/<name>/manifests/<digest>", reggie.WithDigest(ref))
Expand Down
29 changes: 29 additions & 0 deletions conformance/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ var (
refsManifestBConfigArtifactDigest string
refsManifestBLayerArtifactContent []byte
refsManifestBLayerArtifactDigest string
refsManifestCLayerArtifactContent []byte
refsManifestCLayerArtifactDigest string
refsIndexArtifactContent []byte
refsIndexArtifactDigest string
reportJUnitFilename string
Expand Down Expand Up @@ -440,6 +442,33 @@ func init() {

refsManifestBLayerArtifactDigest = godigest.FromBytes(refsManifestBLayerArtifactContent).String()

// ManifestCLayerArtifact is the same as B but based on a subject that has not been pushed
refsManifestCLayerArtifact := manifest{
SchemaVersion: 2,
MediaType: "application/vnd.oci.image.manifest.v1+json",
ArtifactType: testRefArtifactTypeB,
Config: emptyJSONDescriptor,
Subject: &descriptor{
MediaType: "application/vnd.oci.image.manifest.v1+json",
Size: int64(len(manifests[3].Content)),
Digest: godigest.FromBytes(manifests[3].Content),
},
Layers: []descriptor{
{
MediaType: testRefArtifactTypeB,
Size: int64(len(testRefBlobB)),
Digest: godigest.FromBytes(testRefBlobB),
},
},
}

refsManifestCLayerArtifactContent, err = json.MarshalIndent(&refsManifestCLayerArtifact, "", "\t")
if err != nil {
log.Fatal(err)
}

refsManifestCLayerArtifactDigest = godigest.FromBytes(refsManifestCLayerArtifactContent).String()

testRefArtifactTypeIndex = "application/vnd.food.stand"
refsIndexArtifact := index{
SchemaVersion: 2,
Expand Down
2 changes: 0 additions & 2 deletions spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -566,8 +566,6 @@ The descriptors MUST include an `artifactType` field that is set to the value of
If the `artifactType` is empty or missing in the image manifest, the value of `artifactType` MUST be set to the config descriptor `mediaType` value.
The descriptors MUST include annotations from the image manifest.
If a query results in no matching referrers, an empty manifest list MUST be returned.
If a manifest with the digest `<digest>` does not exist, a registry MAY return an empty manifest list.
After a manifest with the digest `<digest>` is pushed, the registry MUST include previously pushed entries in the referrers list.

```json
{
Expand Down