NewFromLocal can return multiple images

If you use additional stores and pull the same image into
writable stores, you can end up with the situation where
you have the same image twice. This causes image exists
to return the wrong error.  It should return true in this
situation rather then an error.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh 2020-10-28 14:51:18 -04:00
parent e04e567b96
commit 99d3e2e9d7
No known key found for this signature in database
GPG key ID: A2DF901DABE2C028
4 changed files with 19 additions and 4 deletions

View file

@ -14,6 +14,9 @@ var (
// ErrNoSuchImage indicates the requested image does not exist
ErrNoSuchImage = errors.New("no such image")
// ErrMultipleImages found multiple name and tag matches
ErrMultipleImages = errors.New("found multiple name and tag matches")
// ErrNoSuchTag indicates the requested image tag does not exist
ErrNoSuchTag = errors.New("no such tag")

View file

@ -11,6 +11,7 @@ import (
"github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/signature"
"github.com/containers/image/v5/types"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/storage"
"github.com/pkg/errors"
)
@ -42,7 +43,7 @@ func findImageInRepotags(search imageParts, images []*Image) (*storage.Image, er
if len(results) == 0 {
return &storage.Image{}, errors.Errorf("unable to find a name and tag match for %s in repotags", searchName)
} else if len(results) > 1 {
return &storage.Image{}, errors.Errorf("found multiple name and tag matches for %s in repotags", searchName)
return &storage.Image{}, errors.Wrapf(define.ErrMultipleImages, searchName)
}
return results[0], nil
}

View file

@ -44,11 +44,16 @@ func ImageExists(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := utils.GetName(r)
_, err := runtime.ImageRuntime().NewFromLocal(name)
ir := abi.ImageEngine{Libpod: runtime}
report, err := ir.Exists(r.Context(), name)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusNotFound, errors.Wrapf(err, "failed to find image %s", name))
return
}
if !report.Value {
utils.Error(w, "Something went wrong.", http.StatusNotFound, errors.Wrapf(nil, "failed to find image %s", name))
return
}
utils.WriteResponse(w, http.StatusNoContent, "")
}

View file

@ -39,8 +39,14 @@ const SignatureStoreDir = "/var/lib/containers/sigstore"
func (ir *ImageEngine) Exists(_ context.Context, nameOrID string) (*entities.BoolReport, error) {
_, err := ir.Libpod.ImageRuntime().NewFromLocal(nameOrID)
if err != nil && errors.Cause(err) != define.ErrNoSuchImage {
return nil, err
if err != nil {
if errors.Cause(err) == define.ErrMultipleImages {
return &entities.BoolReport{Value: true}, nil
} else {
if errors.Cause(err) != define.ErrNoSuchImage {
return nil, err
}
}
}
return &entities.BoolReport{Value: err == nil}, nil
}