Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
insert binary content here #9671
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"architecture":"","os":"","config":{},"rootfs":{"type":"","diff_ids":["sha256:6f06dd0e26608013eff30bb1e951cda7de3fdd9e78e907470e0dd5c0ed25e273"]}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test-payload
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"created": "2019-08-20T20:19:55.211423266Z",
"architecture": "amd64",
"os": "linux",
"config": {
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh"
]
},
"rootfs": {
"type": "layers",
"diff_ids": [
"sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0"
]
},
"history": [
{
"created": "2019-08-20T20:19:55.062606894Z",
"created_by": "/bin/sh -c #(nop) ADD file:fe64057fbb83dccb960efabbf1cd8777920ef279a7fa8dbca0a8801c651bdf7c in / "
},
{
"created": "2019-08-20T20:19:55.211423266Z",
"created_by": "/bin/sh -c #(nop) CMD [\"/bin/sh\"]",
"empty_layer": true
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"digest": "sha256:44353f0bf0dd9507c2e9daea7ad4f8a5f0e23bc16068d612227507e54599c18a",
"size": 147
},
"layers": [
{
"mediaType": "application/vnd.dev.cosign.simplesigning.v1+json",
"digest": "sha256:6f06dd0e26608013eff30bb1e951cda7de3fdd9e78e907470e0dd5c0ed25e273",
"size": 12,
"annotations": {
"dev.cosignproject.cosign/signature": "test-signature"
}
}
],
"subject": {
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:eaa95f3cfaac07c8a5153eb77c933269586ad0226c83405776be08547e4d2a18",
"size": 1506,
"annotations": {
"org.opencontainers.image.ref.name": "imageValue"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"digest": "sha256:a527179158cd5cebc11c152b8637b47ce96c838ba2aa0de66d14f45cedc11423",
"size": 585
},
"layers": [
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:0c8b263642b51b5c1dc40fe402ae2e97119c6007b6e52146419985ec1f0092dc",
"size": 33
}
]
}
21 changes: 21 additions & 0 deletions image/oci/layout/fixtures/delete_image_with_signature/index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"schemaVersion": 2,
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:eaa95f3cfaac07c8a5153eb77c933269586ad0226c83405776be08547e4d2a18",
"size": 476,
"annotations": {
"org.opencontainers.image.ref.name": "latest"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"size": 704,
"annotations": {
"org.opencontainers.image.ref.name": "sha256-eaa95f3cfaac07c8a5153eb77c933269586ad0226c83405776be08547e4d2a18.sig"
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"imageLayoutVersion": "1.0.0"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
insert binary content here #9671
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"created": "2019-08-20T20:19:55.211423266Z",
"architecture": "amd64",
"os": "linux",
"config": {
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh"
]
},
"rootfs": {
"type": "layers",
"diff_ids": [
"sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0"
]
},
"history": [
{
"created": "2019-08-20T20:19:55.062606894Z",
"created_by": "/bin/sh -c #(nop) ADD file:fe64057fbb83dccb960efabbf1cd8777920ef279a7fa8dbca0a8801c651bdf7c in / "
},
{
"created": "2019-08-20T20:19:55.211423266Z",
"created_by": "/bin/sh -c #(nop) CMD [\"/bin/sh\"]",
"empty_layer": true
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"digest": "sha256:a527179158cd5cebc11c152b8637b47ce96c838ba2aa0de66d14f45cedc11423",
"size": 585
},
"layers": [
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:0c8b263642b51b5c1dc40fe402ae2e97119c6007b6e52146419985ec1f0092dc",
"size": 33
}
]
}
13 changes: 13 additions & 0 deletions image/oci/layout/fixtures/single_image_layout/index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"schemaVersion": 2,
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:eaa95f3cfaac07c8a5153eb77c933269586ad0226c83405776be08547e4d2a18",
"size": 476,
"annotations": {
"org.opencontainers.image.ref.name": "latest"
}
}
]
}
1 change: 1 addition & 0 deletions image/oci/layout/fixtures/single_image_layout/oci-layout
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"imageLayoutVersion": "1.0.0"}
30 changes: 29 additions & 1 deletion image/oci/layout/oci_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package layout
import (
"context"
"encoding/json"
"errors"
"fmt"
"io/fs"
"os"
Expand Down Expand Up @@ -42,7 +43,15 @@ func (ref ociReference) DeleteImage(ctx context.Context, sys *types.SystemContex
return err
}

return ref.deleteReferenceFromIndex(descriptorIndex)
err = ref.deleteReferenceFromIndex(descriptorIndex)
if err != nil {
return err
}

if isSigstoreTag(ref.image) {
return nil
}
return ref.deleteSignatures(ctx, sys, descriptor.Digest)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t think unconditionally deleting signatures, and deleting signatures only for that digest, is correct:

  • (Because there is only one imgspecv1.AnnotationRefName annotation per index entry), there can be multiple manifests with the same digest in the top-level index; or the top-level index can contain multiple indices (multi-platform images) that all refer to the same per-platform manifest.
  • The ref parameter can refer to a multi-platform index, with each per-platform manifest individually signed; that would mean ~one *.sig-named manifest in the top-level index for each platform, and all of them should be deleted.

So this will need to be some kind of an extension to countBlobsForDescriptor+getBlobsToDelete, counting “references” from a manifest digest to a *.sig name; and deleting entries for those *.sig names that go from non-zero to zero references.

}

// countBlobsForDescriptor updates dest with usage counts of blobs required for descriptor, INCLUDING descriptor itself.
Expand Down Expand Up @@ -187,3 +196,22 @@ func saveJSON(path string, content any) (retErr error) {

return json.NewEncoder(file).Encode(content)
}

// deleteSignatures delete sigstore signatures of the given manifest digest.
func (ref ociReference) deleteSignatures(ctx context.Context, sys *types.SystemContext, d digest.Digest) error {
signTag, err := sigstoreAttachmentTag(d)
if err != nil {
return err
}

signRef, err := newReference(ref.dir, signTag, -1)
if err != nil {
return err
}

err = signRef.DeleteImage(ctx, sys)
if err != nil && errors.As(err, &ImageNotFoundError{}) {
return nil
}
return err
}
27 changes: 27 additions & 0 deletions image/oci/layout/oci_delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,33 @@ func TestReferenceDeleteImage_onlyOneImage(t *testing.T) {
require.Equal(t, 0, len(index.Manifests))
}

func TestReferenceDeleteImage_onlyOneImageWithSignatures(t *testing.T) {
tmpDir := loadFixture(t, "delete_image_with_signature")

ref, err := NewReference(tmpDir, "latest")
require.NoError(t, err)

ociRef, ok := ref.(ociReference)
require.True(t, ok)
index, err := ociRef.getIndex()
require.NoError(t, err)
require.Equal(t, 2, len(index.Manifests))

err = ref.DeleteImage(context.Background(), nil)
require.NoError(t, err)

// Check that all blobs were deleted
blobsDir := filepath.Join(tmpDir, "blobs")
files, err := os.ReadDir(filepath.Join(blobsDir, "sha256"))
require.NoError(t, err)
require.Empty(t, files)

// Check that the index is empty as there is only one image in the fixture
index, err = ociRef.getIndex()
require.NoError(t, err)
require.Equal(t, 0, len(index.Manifests))
}

func TestReferenceDeleteImage_onlyOneImage_emptyImageName(t *testing.T) {
tmpDir := loadFixture(t, "delete_image_only_one_image")

Expand Down
Loading