images: add context to GetParent/IsParent/Remove/Prune...

Add a context.Context parameter to Image.GetParent(), Image.IsParent(),
Image.GetChildren(), Image.Remove(), and Runtime.PruneImages().

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
This commit is contained in:
Nalin Dahyabhai
2019-04-22 16:41:17 -04:00
parent b01fdcbbd5
commit 5c81a117f1
11 changed files with 32 additions and 29 deletions

View File

@ -243,7 +243,7 @@ func getImagesTemplateOutput(ctx context.Context, images []*adapter.ContainerIma
// If all is false and the image doesn't have a name, check to see if the top layer of the image is a parent // If all is false and the image doesn't have a name, check to see if the top layer of the image is a parent
// to another image's top layer. If it is, then it is an intermediate image so don't print out if the --all flag // to another image's top layer. If it is, then it is an intermediate image so don't print out if the --all flag
// is not set. // is not set.
isParent, err := img.IsParent() isParent, err := img.IsParent(ctx)
if err != nil { if err != nil {
logrus.Errorf("error checking if image is a parent %q: %v", img.ID(), err) logrus.Errorf("error checking if image is a parent %q: %v", img.ID(), err)
} }

View File

@ -45,7 +45,7 @@ func pruneImagesCmd(c *cliconfig.PruneImagesValues) error {
// Call prune; if any cids are returned, print them and then // Call prune; if any cids are returned, print them and then
// return err in case an error also came up // return err in case an error also came up
pruneCids, err := runtime.PruneImages(c.All) pruneCids, err := runtime.PruneImages(getContext(), c.All)
if len(pruneCids) > 0 { if len(pruneCids) > 0 {
for _, cid := range pruneCids { for _, cid := range pruneCids {
fmt.Println(cid) fmt.Println(cid)

View File

@ -97,7 +97,7 @@ func rmiCmd(c *cliconfig.RmiValues) error {
return errors.New("unable to delete all images; re-run the rmi command again.") return errors.New("unable to delete all images; re-run the rmi command again.")
} }
for _, i := range imagesToDelete { for _, i := range imagesToDelete {
isParent, err := i.IsParent() isParent, err := i.IsParent(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -201,7 +201,7 @@ func imageUniqueSize(ctx context.Context, images []*image.Image) (map[string]uin
for _, img := range images { for _, img := range images {
parentImg := img parentImg := img
for { for {
next, err := parentImg.GetParent() next, err := parentImg.GetParent(ctx)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "error getting parent of image %s", parentImg.ID()) return nil, errors.Wrapf(err, "error getting parent of image %s", parentImg.ID())
} }
@ -246,11 +246,11 @@ func getImageDiskUsage(ctx context.Context, images []*image.Image, imageUsedbyCi
unreclaimableSize += imageUsedSize(img, imgUniqueSizeMap, imageUsedbyCintainerMap, imageUsedbyActiveContainerMap) unreclaimableSize += imageUsedSize(img, imgUniqueSizeMap, imageUsedbyCintainerMap, imageUsedbyActiveContainerMap)
isParent, err := img.IsParent() isParent, err := img.IsParent(ctx)
if err != nil { if err != nil {
return imageDiskUsage, err return imageDiskUsage, err
} }
parent, err := img.GetParent() parent, err := img.GetParent(ctx)
if err != nil { if err != nil {
return imageDiskUsage, errors.Wrapf(err, "error getting parent of image %s", img.ID()) return imageDiskUsage, errors.Wrapf(err, "error getting parent of image %s", img.ID())
} }
@ -437,11 +437,11 @@ func getImageVerboseDiskUsage(ctx context.Context, images []*image.Image, images
return imagesVerboseDiskUsage, errors.Wrapf(err, "error getting unique size of images") return imagesVerboseDiskUsage, errors.Wrapf(err, "error getting unique size of images")
} }
for _, img := range images { for _, img := range images {
isParent, err := img.IsParent() isParent, err := img.IsParent(ctx)
if err != nil { if err != nil {
return imagesVerboseDiskUsage, errors.Wrapf(err, "error checking if %s is a parent images", img.ID()) return imagesVerboseDiskUsage, errors.Wrapf(err, "error checking if %s is a parent images", img.ID())
} }
parent, err := img.GetParent() parent, err := img.GetParent(ctx)
if err != nil { if err != nil {
return imagesVerboseDiskUsage, errors.Wrapf(err, "error getting parent of image %s", img.ID()) return imagesVerboseDiskUsage, errors.Wrapf(err, "error getting parent of image %s", img.ID())
} }

View File

@ -110,7 +110,7 @@ Are you sure you want to continue? [y/N] `, volumeString)
// Call prune; if any cids are returned, print them and then // Call prune; if any cids are returned, print them and then
// return err in case an error also came up // return err in case an error also came up
pruneCids, err := runtime.PruneImages(c.All) pruneCids, err := runtime.PruneImages(ctx, c.All)
if len(pruneCids) > 0 { if len(pruneCids) > 0 {
fmt.Println("Deleted Images") fmt.Println("Deleted Images")
for _, cid := range pruneCids { for _, cid := range pruneCids {

View File

@ -353,8 +353,8 @@ func (i *Image) TopLayer() string {
// outside the context of images // outside the context of images
// TODO: the force param does nothing as of now. Need to move container // TODO: the force param does nothing as of now. Need to move container
// handling logic here eventually. // handling logic here eventually.
func (i *Image) Remove(force bool) error { func (i *Image) Remove(ctx context.Context, force bool) error {
parent, err := i.GetParent() parent, err := i.GetParent(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -363,11 +363,11 @@ func (i *Image) Remove(force bool) error {
} }
i.newImageEvent(events.Remove) i.newImageEvent(events.Remove)
for parent != nil { for parent != nil {
nextParent, err := parent.GetParent() nextParent, err := parent.GetParent(ctx)
if err != nil { if err != nil {
return err return err
} }
children, err := parent.GetChildren() children, err := parent.GetChildren(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -1006,8 +1006,8 @@ func splitString(input string) string {
// IsParent goes through the layers in the store and checks if i.TopLayer is // IsParent goes through the layers in the store and checks if i.TopLayer is
// the parent of any other layer in store. Double check that image with that // the parent of any other layer in store. Double check that image with that
// layer exists as well. // layer exists as well.
func (i *Image) IsParent() (bool, error) { func (i *Image) IsParent(ctx context.Context) (bool, error) {
children, err := i.GetChildren() children, err := i.GetChildren(ctx)
if err != nil { if err != nil {
return false, err return false, err
} }
@ -1015,7 +1015,7 @@ func (i *Image) IsParent() (bool, error) {
} }
// GetParent returns the image ID of the parent. Return nil if a parent is not found. // GetParent returns the image ID of the parent. Return nil if a parent is not found.
func (i *Image) GetParent() (*Image, error) { func (i *Image) GetParent(ctx context.Context) (*Image, error) {
images, err := i.imageruntime.GetImages() images, err := i.imageruntime.GetImages()
if err != nil { if err != nil {
return nil, err return nil, err
@ -1033,7 +1033,7 @@ func (i *Image) GetParent() (*Image, error) {
} }
// GetChildren returns a list of the imageIDs that depend on the image // GetChildren returns a list of the imageIDs that depend on the image
func (i *Image) GetChildren() ([]string, error) { func (i *Image) GetChildren(ctx context.Context) ([]string, error) {
var children []string var children []string
images, err := i.imageruntime.GetImages() images, err := i.imageruntime.GetImages()
if err != nil { if err != nil {

View File

@ -1,6 +1,8 @@
package image package image
import ( import (
"context"
"github.com/containers/libpod/libpod/events" "github.com/containers/libpod/libpod/events"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -34,14 +36,14 @@ func (ir *Runtime) GetPruneImages(all bool) ([]*Image, error) {
// PruneImages prunes dangling and optionally all unused images from the local // PruneImages prunes dangling and optionally all unused images from the local
// image store // image store
func (ir *Runtime) PruneImages(all bool) ([]string, error) { func (ir *Runtime) PruneImages(ctx context.Context, all bool) ([]string, error) {
var prunedCids []string var prunedCids []string
pruneImages, err := ir.GetPruneImages(all) pruneImages, err := ir.GetPruneImages(all)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "unable to get images to prune") return nil, errors.Wrap(err, "unable to get images to prune")
} }
for _, p := range pruneImages { for _, p := range pruneImages {
if err := p.Remove(true); err != nil { if err := p.Remove(ctx, true); err != nil {
return nil, errors.Wrap(err, "failed to prune image") return nil, errors.Wrap(err, "failed to prune image")
} }
defer p.newImageEvent(events.Prune) defer p.newImageEvent(events.Prune)

View File

@ -57,7 +57,7 @@ func (r *Runtime) RemoveImage(ctx context.Context, img *image.Image, force bool)
} }
} }
hasChildren, err := img.IsParent() hasChildren, err := img.IsParent(ctx)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -82,12 +82,12 @@ func (r *Runtime) RemoveImage(ctx context.Context, img *image.Image, force bool)
// reponames and no force is applied, we error out. // reponames and no force is applied, we error out.
return "", fmt.Errorf("unable to delete %s (must force) - image is referred to in multiple tags", img.ID()) return "", fmt.Errorf("unable to delete %s (must force) - image is referred to in multiple tags", img.ID())
} }
err = img.Remove(force) err = img.Remove(ctx, force)
if err != nil && errors.Cause(err) == storage.ErrImageUsedByContainer { if err != nil && errors.Cause(err) == storage.ErrImageUsedByContainer {
if errStorage := r.rmStorageContainers(force, img); errStorage == nil { if errStorage := r.rmStorageContainers(force, img); errStorage == nil {
// Containers associated with the image should be deleted now, // Containers associated with the image should be deleted now,
// let's try removing the image again. // let's try removing the image again.
err = img.Remove(force) err = img.Remove(ctx, force)
} else { } else {
err = errStorage err = errStorage
} }

View File

@ -119,8 +119,8 @@ func (r *LocalRuntime) RemoveImage(ctx context.Context, img *ContainerImage, for
} }
// PruneImages is wrapper into PruneImages within the image pkg // PruneImages is wrapper into PruneImages within the image pkg
func (r *LocalRuntime) PruneImages(all bool) ([]string, error) { func (r *LocalRuntime) PruneImages(ctx context.Context, all bool) ([]string, error) {
return r.ImageRuntime().PruneImages(all) return r.ImageRuntime().PruneImages(ctx, all)
} }
// Export is a wrapper to container export to a tarfile // Export is a wrapper to container export to a tarfile

View File

@ -256,7 +256,7 @@ func (r *LocalRuntime) New(ctx context.Context, name, signaturePolicyPath, authf
// IsParent goes through the layers in the store and checks if i.TopLayer is // IsParent goes through the layers in the store and checks if i.TopLayer is
// the parent of any other layer in store. Double check that image with that // the parent of any other layer in store. Double check that image with that
// layer exists as well. // layer exists as well.
func (ci *ContainerImage) IsParent() (bool, error) { func (ci *ContainerImage) IsParent(context.Context) (bool, error) {
return ci.remoteImage.isParent, nil return ci.remoteImage.isParent, nil
} }
@ -338,7 +338,7 @@ func (ci *ContainerImage) History(ctx context.Context) ([]*image.History, error)
} }
// PruneImages is the wrapper call for a remote-client to prune images // PruneImages is the wrapper call for a remote-client to prune images
func (r *LocalRuntime) PruneImages(all bool) ([]string, error) { func (r *LocalRuntime) PruneImages(ctx context.Context, all bool) ([]string, error) {
return iopodman.ImagesPrune().Call(r.Conn, all) return iopodman.ImagesPrune().Call(r.Conn, all)
} }

View File

@ -4,6 +4,7 @@ package varlinkapi
import ( import (
"bytes" "bytes"
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
@ -49,7 +50,7 @@ func (i *LibpodAPI) ListImages(call iopodman.VarlinkCall) error {
} }
size, _ := image.Size(getContext()) size, _ := image.Size(getContext())
isParent, err := image.IsParent() isParent, err := image.IsParent(context.TODO())
if err != nil { if err != nil {
return call.ReplyErrorOccurred(err.Error()) return call.ReplyErrorOccurred(err.Error())
} }
@ -503,7 +504,7 @@ func (i *LibpodAPI) DeleteUnusedImages(call iopodman.VarlinkCall) error {
return call.ReplyErrorOccurred(err.Error()) return call.ReplyErrorOccurred(err.Error())
} }
if len(containers) == 0 { if len(containers) == 0 {
if err := img.Remove(false); err != nil { if err := img.Remove(context.TODO(), false); err != nil {
return call.ReplyErrorOccurred(err.Error()) return call.ReplyErrorOccurred(err.Error())
} }
deletedImages = append(deletedImages, img.ID()) deletedImages = append(deletedImages, img.ID())
@ -739,7 +740,7 @@ func (i *LibpodAPI) ContainerRunlabel(call iopodman.VarlinkCall, input iopodman.
// ImagesPrune .... // ImagesPrune ....
func (i *LibpodAPI) ImagesPrune(call iopodman.VarlinkCall, all bool) error { func (i *LibpodAPI) ImagesPrune(call iopodman.VarlinkCall, all bool) error {
prunedImages, err := i.Runtime.ImageRuntime().PruneImages(all) prunedImages, err := i.Runtime.ImageRuntime().PruneImages(context.TODO(), all)
if err != nil { if err != nil {
return call.ReplyErrorOccurred(err.Error()) return call.ReplyErrorOccurred(err.Error())
} }