diff --git a/cmd/kpod/rmi.go b/cmd/kpod/rmi.go index 9bab10bb..70e1a831 100644 --- a/cmd/kpod/rmi.go +++ b/cmd/kpod/rmi.go @@ -3,10 +3,6 @@ package main import ( "fmt" - is "github.com/containers/image/storage" - "github.com/containers/image/transports" - "github.com/containers/image/transports/alltransports" - "github.com/containers/image/types" "github.com/containers/storage" libkpodimage "github.com/kubernetes-incubator/cri-o/libkpod/image" "github.com/pkg/errors" @@ -49,7 +45,7 @@ func rmiCmd(c *cli.Context) error { } for _, id := range args { - image, err := getImage(id, store) + image, err := libkpodimage.GetImage(store, id) if err != nil { return errors.Wrapf(err, "could not get image %q", id) } @@ -75,7 +71,7 @@ func rmiCmd(c *cli.Context) error { // If it is forced, we have to untag the image so that it can be deleted image.Names = image.Names[:0] } else { - name, err2 := untagImage(id, image, store) + name, err2 := libkpodimage.UntagImage(store, image, id) if err2 != nil { return err } @@ -85,7 +81,7 @@ func rmiCmd(c *cli.Context) error { if len(image.Names) > 0 { continue } - id, err := removeImage(image, store) + id, err := libkpodimage.RemoveImage(image, store) if err != nil { return err } @@ -96,69 +92,8 @@ func rmiCmd(c *cli.Context) error { return nil } -func getImage(id string, store storage.Store) (*storage.Image, error) { - var ref types.ImageReference - ref, err := properImageRef(id) - if err != nil { - //logrus.Debug(err) - } - if ref == nil { - if ref, err = storageImageRef(store, id); err != nil { - //logrus.Debug(err) - } - } - if ref == nil { - if ref, err = storageImageID(store, id); err != nil { - //logrus.Debug(err) - } - } - if ref != nil { - image, err2 := is.Transport.GetStoreImage(store, ref) - if err2 != nil { - return nil, err2 - } - return image, nil - } - return nil, err -} - -func untagImage(imgArg string, image *storage.Image, store storage.Store) (string, error) { - // Remove name from image.Names and set the new name in the ImageStore - imgStore, err := store.ImageStore() - if err != nil { - return "", errors.Wrap(err, "could not untag image") - } - newNames := []string{} - removedName := "" - for _, name := range image.Names { - if libkpodimage.MatchesReference(name, imgArg) { - removedName = name - continue - } - newNames = append(newNames, name) - } - imgStore.SetNames(image.ID, newNames) - err = imgStore.Save() - return removedName, err -} - -func removeImage(image *storage.Image, store storage.Store) (string, error) { - imgStore, err := store.ImageStore() - if err != nil { - return "", errors.Wrapf(err, "could not open image store") - } - err = imgStore.Delete(image.ID) - if err != nil { - return "", errors.Wrapf(err, "could not remove image") - } - err = imgStore.Save() - if err != nil { - return "", errors.Wrapf(err, "could not save image store") - } - return image.ID, nil -} - // Returns a list of running containers associated with the given ImageReference +// TODO: replace this with something in libkpod func runningContainers(image *storage.Image, store storage.Store) ([]string, error) { ctrIDs := []string{} ctrStore, err := store.ContainerStore() @@ -178,6 +113,7 @@ func runningContainers(image *storage.Image, store storage.Store) ([]string, err return ctrIDs, nil } +// TODO: replace this with something in libkpod func removeContainers(ctrIDs []string, store storage.Store) error { ctrStore, err := store.ContainerStore() if err != nil { @@ -190,50 +126,3 @@ func removeContainers(ctrIDs []string, store storage.Store) error { } return nil } - -// If it's looks like a proper image reference, parse it and check if it -// corresponds to an image that actually exists. -func properImageRef(id string) (types.ImageReference, error) { - var ref types.ImageReference - var err error - if ref, err = alltransports.ParseImageName(id); err == nil { - if img, err2 := ref.NewImage(nil); err2 == nil { - img.Close() - return ref, nil - } - return nil, fmt.Errorf("error confirming presence of image reference %q: %v", transports.ImageName(ref), err) - } - return nil, fmt.Errorf("error parsing %q as an image reference: %v", id, err) -} - -// If it's looks like an image reference that's relative to our storage, parse -// it and check if it corresponds to an image that actually exists. -func storageImageRef(store storage.Store, id string) (types.ImageReference, error) { - var ref types.ImageReference - var err error - if ref, err = is.Transport.ParseStoreReference(store, id); err == nil { - if img, err2 := ref.NewImage(nil); err2 == nil { - img.Close() - return ref, nil - } - return nil, fmt.Errorf("error confirming presence of storage image reference %q: %v", transports.ImageName(ref), err) - } - return nil, fmt.Errorf("error parsing %q as a storage image reference: %v", id, err) -} - -// If it might be an ID that's relative to our storage, parse it and check if it -// corresponds to an image that actually exists. This _should_ be redundant, -// since we already tried deleting the image using the ID directly above, but it -// can't hurt either. -func storageImageID(store storage.Store, id string) (types.ImageReference, error) { - var ref types.ImageReference - var err error - if ref, err = is.Transport.ParseStoreReference(store, "@"+id); err == nil { - if img, err2 := ref.NewImage(nil); err2 == nil { - img.Close() - return ref, nil - } - return nil, fmt.Errorf("error confirming presence of storage image reference %q: %v", transports.ImageName(ref), err) - } - return nil, fmt.Errorf("error parsing %q as a storage image reference: %v", "@"+id, err) -} diff --git a/libkpod/common/common.go b/libkpod/common/common.go index bf847f4f..4d7a079a 100644 --- a/libkpod/common/common.go +++ b/libkpod/common/common.go @@ -77,7 +77,7 @@ func ParseRegistryCreds(creds string) (*types.DockerAuthConfig, error) { if creds == "" { return nil, errors.New("no credentials supplied") } - if strings.Index(creds, ":") < 0 { + if !strings.Contains(creds, ":") { return nil, errors.New("user name supplied, but no password supplied") } v := strings.SplitN(creds, ":", 2) diff --git a/libkpod/image/CopyRef.go b/libkpod/image/CopyRef.go index 1c7db726..d36c44fd 100644 --- a/libkpod/image/CopyRef.go +++ b/libkpod/image/CopyRef.go @@ -211,7 +211,7 @@ func (c *CopyRef) NewImageSource(sc *types.SystemContext, manifestTypes []string continue } // Start reading the layer. - rc, err := i.store.Diff("", layerID, nil) + rc, err := c.store.Diff("", layerID, nil) if err != nil { return nil, errors.Wrapf(err, "error extracting layer %q", layerID) } diff --git a/libkpod/image/image.go b/libkpod/image/image.go index 0db7bae3..f2896d17 100644 --- a/libkpod/image/image.go +++ b/libkpod/image/image.go @@ -150,7 +150,7 @@ func matchesSinceImage(image storage.Image, name string, params *FilterParams) b // MatchesID returns true if argID is a full or partial match for id func MatchesID(id, argID string) bool { - return strings.HasPrefix(id, argID) + return strings.HasPrefix(argID, id) } // MatchesReference returns true if argName is a full or partial match for name @@ -264,9 +264,6 @@ func GetImagesMatchingFilter(store storage.Store, filter *FilterParams, argName if err != nil { return nil, err } - if filter == nil { - return images, nil - } for _, image := range images { names := []string{} if len(image.Names) > 0 { @@ -275,7 +272,7 @@ func GetImagesMatchingFilter(store storage.Store, filter *FilterParams, argName names = append(names, "") } for _, name := range names { - if matchesFilter(store, image, name, filter) || MatchesReference(name, argName) { + if filter == nil || (matchesFilter(store, image, name, filter) || MatchesReference(name, argName)) { newImage := image newImage.Names = []string{name} filteredImages = append(filteredImages, newImage) diff --git a/libkpod/image/imageData.go b/libkpod/image/imageData.go index e8c3d2ea..eff4c484 100644 --- a/libkpod/image/imageData.go +++ b/libkpod/image/imageData.go @@ -12,6 +12,7 @@ import ( ) // ImageData handles the data used when inspecting a container +// nolint type ImageData struct { ID string Names []string diff --git a/libkpod/image/rmi.go b/libkpod/image/rmi.go new file mode 100644 index 00000000..886e6fe2 --- /dev/null +++ b/libkpod/image/rmi.go @@ -0,0 +1,124 @@ +package image + +import ( + "fmt" + + is "github.com/containers/image/storage" + "github.com/containers/image/transports" + "github.com/containers/image/transports/alltransports" + "github.com/containers/image/types" + "github.com/containers/storage" + "github.com/pkg/errors" +) + +// If it's looks like a proper image reference, parse it and check if it +// corresponds to an image that actually exists. +func properImageRef(id string) (types.ImageReference, error) { + var ref types.ImageReference + var err error + if ref, err = alltransports.ParseImageName(id); err == nil { + if img, err2 := ref.NewImage(nil); err2 == nil { + img.Close() + return ref, nil + } + return nil, fmt.Errorf("error confirming presence of image reference %q: %v", transports.ImageName(ref), err) + } + return nil, fmt.Errorf("error parsing %q as an image reference: %v", id, err) +} + +// If it's looks like an image reference that's relative to our storage, parse +// it and check if it corresponds to an image that actually exists. +func storageImageRef(store storage.Store, id string) (types.ImageReference, error) { + var ref types.ImageReference + var err error + if ref, err = is.Transport.ParseStoreReference(store, id); err == nil { + if img, err2 := ref.NewImage(nil); err2 == nil { + img.Close() + return ref, nil + } + return nil, fmt.Errorf("error confirming presence of storage image reference %q: %v", transports.ImageName(ref), err) + } + return nil, fmt.Errorf("error parsing %q as a storage image reference: %v", id, err) +} + +// If it might be an ID that's relative to our storage, parse it and check if it +// corresponds to an image that actually exists. This _should_ be redundant, +// since we already tried deleting the image using the ID directly above, but it +// can't hurt either. +func storageImageID(store storage.Store, id string) (types.ImageReference, error) { + var ref types.ImageReference + var err error + if ref, err = is.Transport.ParseStoreReference(store, "@"+id); err == nil { + if img, err2 := ref.NewImage(nil); err2 == nil { + img.Close() + return ref, nil + } + return nil, fmt.Errorf("error confirming presence of storage image reference %q: %v", transports.ImageName(ref), err) + } + return nil, fmt.Errorf("error parsing %q as a storage image reference: %v", "@"+id, err) +} + +// GetImage TODO: Ask Nalin if this or FindImage() is better +func GetImage(store storage.Store, id string) (*storage.Image, error) { + var ref types.ImageReference + ref, err := properImageRef(id) + if err != nil { + //logrus.Debug(err) + } + if ref == nil { + if ref, err = storageImageRef(store, id); err != nil { + //logrus.Debug(err) + } + } + if ref == nil { + if ref, err = storageImageID(store, id); err != nil { + //logrus.Debug(err) + } + } + if ref != nil { + image, err2 := is.Transport.GetStoreImage(store, ref) + if err2 != nil { + return nil, err2 + } + return image, nil + } + return nil, err +} + +// UntagImage removes the tag from the given image +func UntagImage(store storage.Store, image *storage.Image, imgArg string) (string, error) { + // Remove name from image.Names and set the new name in the ImageStore + imgStore, err := store.ImageStore() + if err != nil { + return "", errors.Wrap(err, "could not untag image") + } + newNames := []string{} + removedName := "" + for _, name := range image.Names { + if MatchesReference(name, imgArg) { + removedName = name + continue + } + newNames = append(newNames, name) + } + imgStore.SetNames(image.ID, newNames) + err = imgStore.Save() + return removedName, err +} + +// RemoveImage removes the given image from storage +func RemoveImage(image *storage.Image, store storage.Store) (string, error) { + imgStore, err := store.ImageStore() + if err != nil { + return "", errors.Wrapf(err, "could not open image store") + } + err = imgStore.Delete(image.ID) + if err != nil { + return "", errors.Wrapf(err, "could not remove image") + } + err = imgStore.Save() + if err != nil { + return "", errors.Wrapf(err, "could not save image store") + } + return image.ID, nil +}