c8d/resolveImage: Fix Digested and Named reference
When resolving a reference that is both a Named and Digested, it could be resolved to an image that has the same digest, but completely different repository name. Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com> (cherry picked from commit 48fc306764fc5c39d4284021520a0337ef7e0cb0) Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
parent
8ab6d025f6
commit
3c5c192baf
2 changed files with 53 additions and 0 deletions
|
@ -274,6 +274,24 @@ func (i *ImageService) resolveImage(ctx context.Context, refOrID string) (contai
|
|||
return containerdimages.Image{}, images.ErrImageDoesNotExist{Ref: parsed}
|
||||
}
|
||||
|
||||
// If reference is both Named and Digested, make sure we don't match
|
||||
// images with a different repository even if digest matches.
|
||||
// For example, busybox@sha256:abcdef..., shouldn't match asdf@sha256:abcdef...
|
||||
if parsedNamed, ok := parsed.(reference.Named); ok {
|
||||
for _, img := range imgs {
|
||||
imgNamed, err := reference.ParseNormalizedNamed(img.Name)
|
||||
if err != nil {
|
||||
logrus.WithError(err).WithField("image", img.Name).Warn("image with invalid name encountered")
|
||||
continue
|
||||
}
|
||||
|
||||
if parsedNamed.Name() == imgNamed.Name() {
|
||||
return img, nil
|
||||
}
|
||||
}
|
||||
return containerdimages.Image{}, images.ErrImageDoesNotExist{Ref: parsed}
|
||||
}
|
||||
|
||||
return imgs[0], nil
|
||||
}
|
||||
|
||||
|
|
|
@ -6,9 +6,11 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/integration/internal/container"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
"gotest.tools/v3/skip"
|
||||
)
|
||||
|
||||
func TestRemoveImageOrphaning(t *testing.T) {
|
||||
|
@ -57,3 +59,36 @@ func TestRemoveImageOrphaning(t *testing.T) {
|
|||
_, _, err = client.ImageInspectWithRaw(ctx, commitResp2.ID)
|
||||
assert.Check(t, is.ErrorContains(err, "No such image:"))
|
||||
}
|
||||
|
||||
func TestRemoveByDigest(t *testing.T) {
|
||||
skip.If(t, !testEnv.UsingSnapshotter(), "RepoDigests doesn't include tags when using graphdrivers")
|
||||
|
||||
defer setupTest(t)()
|
||||
ctx := context.Background()
|
||||
client := testEnv.APIClient()
|
||||
|
||||
err := client.ImageTag(ctx, "busybox", "test-remove-by-digest:latest")
|
||||
assert.NilError(t, err)
|
||||
|
||||
inspect, _, err := client.ImageInspectWithRaw(ctx, "test-remove-by-digest")
|
||||
assert.NilError(t, err)
|
||||
|
||||
id := ""
|
||||
for _, ref := range inspect.RepoDigests {
|
||||
if strings.Contains(ref, "test-remove-by-digest") {
|
||||
id = ref
|
||||
break
|
||||
}
|
||||
}
|
||||
assert.Assert(t, id != "")
|
||||
|
||||
t.Logf("removing %s", id)
|
||||
_, err = client.ImageRemove(ctx, id, types.ImageRemoveOptions{})
|
||||
assert.NilError(t, err)
|
||||
|
||||
inspect, _, err = client.ImageInspectWithRaw(ctx, "busybox")
|
||||
assert.Check(t, err, "busybox image got deleted")
|
||||
|
||||
inspect, _, err = client.ImageInspectWithRaw(ctx, "test-remove-by-digest")
|
||||
assert.Check(t, is.ErrorType(err, errdefs.IsNotFound))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue