client: Add helper function which checks if an image is unpacked
Signed-off-by: Jess Valarezo <valarezo.jessica@gmail.com>
This commit is contained in:
parent
e2f9fbfe71
commit
1552ee23da
@ -177,8 +177,9 @@ var setLabelsCommand = cli.Command{
|
||||
var checkCommand = cli.Command{
|
||||
Name: "check",
|
||||
Usage: "check that an image has all content available locally",
|
||||
ArgsUsage: "<ref> [<ref>, ...]",
|
||||
ArgsUsage: "[flags] <ref> [<ref>, ...]",
|
||||
Description: "check that an image has all content available locally",
|
||||
Flags: commands.SnapshotterFlags,
|
||||
Action: func(context *cli.Context) error {
|
||||
var (
|
||||
exitErr error
|
||||
@ -189,14 +190,13 @@ var checkCommand = cli.Command{
|
||||
}
|
||||
defer cancel()
|
||||
var (
|
||||
imageStore = client.ImageService()
|
||||
contentStore = client.ContentStore()
|
||||
tw = tabwriter.NewWriter(os.Stdout, 1, 8, 1, ' ', 0)
|
||||
)
|
||||
fmt.Fprintln(tw, "REF\tTYPE\tDIGEST\tSTATUS\tSIZE\t")
|
||||
fmt.Fprintln(tw, "REF\tTYPE\tDIGEST\tSTATUS\tSIZE\tUNPACKED\t")
|
||||
|
||||
args := []string(context.Args())
|
||||
imageList, err := imageStore.List(ctx, args...)
|
||||
imageList, err := client.ListImages(ctx, args...)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed listing images")
|
||||
}
|
||||
@ -209,12 +209,12 @@ var checkCommand = cli.Command{
|
||||
presentSize int64
|
||||
)
|
||||
|
||||
available, required, present, missing, err := images.Check(ctx, contentStore, image.Target, platforms.Default())
|
||||
available, required, present, missing, err := images.Check(ctx, contentStore, image.Target(), platforms.Default())
|
||||
if err != nil {
|
||||
if exitErr == nil {
|
||||
exitErr = errors.Wrapf(err, "unable to check %v", image.Name)
|
||||
exitErr = errors.Wrapf(err, "unable to check %v", image.Name())
|
||||
}
|
||||
log.G(ctx).WithError(err).Errorf("unable to check %v", image.Name)
|
||||
log.G(ctx).WithError(err).Errorf("unable to check %v", image.Name())
|
||||
status = "error"
|
||||
}
|
||||
|
||||
@ -242,12 +242,21 @@ var checkCommand = cli.Command{
|
||||
size = "-"
|
||||
}
|
||||
|
||||
fmt.Fprintf(tw, "%v\t%v\t%v\t%v\t%v\t\n",
|
||||
image.Name,
|
||||
image.Target.MediaType,
|
||||
image.Target.Digest,
|
||||
unpacked, err := image.IsUnpacked(ctx, context.String("snapshotter"))
|
||||
if err != nil {
|
||||
if exitErr == nil {
|
||||
exitErr = errors.Wrapf(err, "unable to check unpack for %v", image.Name())
|
||||
}
|
||||
log.G(ctx).WithError(err).Errorf("unable to check unpack for %v", image.Name())
|
||||
}
|
||||
|
||||
fmt.Fprintf(tw, "%v\t%v\t%v\t%v\t%v\t%t\n",
|
||||
image.Name(),
|
||||
image.Target().MediaType,
|
||||
image.Target().Digest,
|
||||
status,
|
||||
size)
|
||||
size,
|
||||
unpacked)
|
||||
}
|
||||
tw.Flush()
|
||||
|
||||
|
23
image.go
23
image.go
@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/containerd/containerd/rootfs"
|
||||
@ -30,6 +31,8 @@ type Image interface {
|
||||
Size(ctx context.Context) (int64, error)
|
||||
// Config descriptor for the image.
|
||||
Config(ctx context.Context) (ocispec.Descriptor, error)
|
||||
// IsUnpacked returns whether or not an image is unpacked.
|
||||
IsUnpacked(context.Context, string) (bool, error)
|
||||
}
|
||||
|
||||
var _ = (Image)(&image{})
|
||||
@ -63,6 +66,26 @@ func (i *image) Config(ctx context.Context) (ocispec.Descriptor, error) {
|
||||
return i.i.Config(ctx, provider, platforms.Default())
|
||||
}
|
||||
|
||||
func (i *image) IsUnpacked(ctx context.Context, snapshotterName string) (bool, error) {
|
||||
sn := i.client.SnapshotService(snapshotterName)
|
||||
cs := i.client.ContentStore()
|
||||
|
||||
diffs, err := i.i.RootFS(ctx, cs, platforms.Default())
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
chainID := identity.ChainID(diffs)
|
||||
_, err = sn.Stat(ctx, chainID.String())
|
||||
if err == nil {
|
||||
return true, nil
|
||||
} else if !errdefs.IsNotFound(err) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (i *image) Unpack(ctx context.Context, snapshotterName string) error {
|
||||
layers, err := i.getLayers(ctx, platforms.Default())
|
||||
if err != nil {
|
||||
|
58
image_test.go
Normal file
58
image_test.go
Normal file
@ -0,0 +1,58 @@
|
||||
package containerd
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
)
|
||||
|
||||
func TestImageIsUnpacked(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
const imageName = "docker.io/library/busybox:latest"
|
||||
ctx, cancel := testContext()
|
||||
defer cancel()
|
||||
|
||||
client, err := newClient(t, address)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
// Cleanup
|
||||
err = client.ImageService().Delete(ctx, imageName)
|
||||
if err != nil && !errdefs.IsNotFound(err) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// By default pull does not unpack an image
|
||||
image, err := client.Pull(ctx, imageName)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Check that image is not unpacked
|
||||
unpacked, err := image.IsUnpacked(ctx, DefaultSnapshotter)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if unpacked {
|
||||
t.Fatalf("image should not be unpacked")
|
||||
}
|
||||
|
||||
// Check that image is unpacked
|
||||
err = image.Unpack(ctx, DefaultSnapshotter)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
unpacked, err = image.IsUnpacked(ctx, DefaultSnapshotter)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !unpacked {
|
||||
t.Fatalf("image should be unpacked")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user