move functions supporting rmi command to libkpod/image
Signed-off-by: Ryan Cole <rcyoalne@gmail.com>
This commit is contained in:
parent
0f44ff1d3b
commit
c1706475c0
6 changed files with 134 additions and 123 deletions
121
cmd/kpod/rmi.go
121
cmd/kpod/rmi.go
|
@ -3,10 +3,6 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"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/containers/storage"
|
||||||
libkpodimage "github.com/kubernetes-incubator/cri-o/libkpod/image"
|
libkpodimage "github.com/kubernetes-incubator/cri-o/libkpod/image"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
@ -49,7 +45,7 @@ func rmiCmd(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, id := range args {
|
for _, id := range args {
|
||||||
image, err := getImage(id, store)
|
image, err := libkpodimage.GetImage(store, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "could not get image %q", id)
|
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
|
// If it is forced, we have to untag the image so that it can be deleted
|
||||||
image.Names = image.Names[:0]
|
image.Names = image.Names[:0]
|
||||||
} else {
|
} else {
|
||||||
name, err2 := untagImage(id, image, store)
|
name, err2 := libkpodimage.UntagImage(store, image, id)
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -85,7 +81,7 @@ func rmiCmd(c *cli.Context) error {
|
||||||
if len(image.Names) > 0 {
|
if len(image.Names) > 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
id, err := removeImage(image, store)
|
id, err := libkpodimage.RemoveImage(image, store)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -96,69 +92,8 @@ func rmiCmd(c *cli.Context) error {
|
||||||
return nil
|
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
|
// 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) {
|
func runningContainers(image *storage.Image, store storage.Store) ([]string, error) {
|
||||||
ctrIDs := []string{}
|
ctrIDs := []string{}
|
||||||
ctrStore, err := store.ContainerStore()
|
ctrStore, err := store.ContainerStore()
|
||||||
|
@ -178,6 +113,7 @@ func runningContainers(image *storage.Image, store storage.Store) ([]string, err
|
||||||
return ctrIDs, nil
|
return ctrIDs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: replace this with something in libkpod
|
||||||
func removeContainers(ctrIDs []string, store storage.Store) error {
|
func removeContainers(ctrIDs []string, store storage.Store) error {
|
||||||
ctrStore, err := store.ContainerStore()
|
ctrStore, err := store.ContainerStore()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -190,50 +126,3 @@ func removeContainers(ctrIDs []string, store storage.Store) error {
|
||||||
}
|
}
|
||||||
return nil
|
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)
|
|
||||||
}
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ func ParseRegistryCreds(creds string) (*types.DockerAuthConfig, error) {
|
||||||
if creds == "" {
|
if creds == "" {
|
||||||
return nil, errors.New("no credentials supplied")
|
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")
|
return nil, errors.New("user name supplied, but no password supplied")
|
||||||
}
|
}
|
||||||
v := strings.SplitN(creds, ":", 2)
|
v := strings.SplitN(creds, ":", 2)
|
||||||
|
|
|
@ -211,7 +211,7 @@ func (c *CopyRef) NewImageSource(sc *types.SystemContext, manifestTypes []string
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Start reading the layer.
|
// Start reading the layer.
|
||||||
rc, err := i.store.Diff("", layerID, nil)
|
rc, err := c.store.Diff("", layerID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "error extracting layer %q", layerID)
|
return nil, errors.Wrapf(err, "error extracting layer %q", layerID)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
// MatchesID returns true if argID is a full or partial match for id
|
||||||
func MatchesID(id, argID string) bool {
|
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
|
// 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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if filter == nil {
|
|
||||||
return images, nil
|
|
||||||
}
|
|
||||||
for _, image := range images {
|
for _, image := range images {
|
||||||
names := []string{}
|
names := []string{}
|
||||||
if len(image.Names) > 0 {
|
if len(image.Names) > 0 {
|
||||||
|
@ -275,7 +272,7 @@ func GetImagesMatchingFilter(store storage.Store, filter *FilterParams, argName
|
||||||
names = append(names, "<none>")
|
names = append(names, "<none>")
|
||||||
}
|
}
|
||||||
for _, name := range 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 := image
|
||||||
newImage.Names = []string{name}
|
newImage.Names = []string{name}
|
||||||
filteredImages = append(filteredImages, newImage)
|
filteredImages = append(filteredImages, newImage)
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ImageData handles the data used when inspecting a container
|
// ImageData handles the data used when inspecting a container
|
||||||
|
// nolint
|
||||||
type ImageData struct {
|
type ImageData struct {
|
||||||
ID string
|
ID string
|
||||||
Names []string
|
Names []string
|
||||||
|
|
124
libkpod/image/rmi.go
Normal file
124
libkpod/image/rmi.go
Normal file
|
@ -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
|
||||||
|
}
|
Loading…
Reference in a new issue