Add ctr image prune
Signed-off-by: Jin Dong <jindon@amazon.com>
This commit is contained in:
parent
24020812bb
commit
8e0a3c51a5
@ -47,6 +47,7 @@ var Command = cli.Command{
|
|||||||
unmountCommand,
|
unmountCommand,
|
||||||
pullCommand,
|
pullCommand,
|
||||||
pushCommand,
|
pushCommand,
|
||||||
|
pruneCommand,
|
||||||
removeCommand,
|
removeCommand,
|
||||||
tagCommand,
|
tagCommand,
|
||||||
setLabelsCommand,
|
setLabelsCommand,
|
||||||
@ -355,3 +356,73 @@ var removeCommand = cli.Command{
|
|||||||
return exitErr
|
return exitErr
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pruneCommand = cli.Command{
|
||||||
|
Name: "prune",
|
||||||
|
Usage: "remove unused images",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "all", // TODO: add more filters
|
||||||
|
Usage: "remove all unused images, not just dangling ones (if all is not specified no images will be pruned)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// adapted from `nerdctl`:
|
||||||
|
// https://github.com/containerd/nerdctl/blob/272dc9c29fc1434839d3ec63194d7efa24d7c0ef/cmd/nerdctl/image_prune.go#L86
|
||||||
|
Action: func(context *cli.Context) error {
|
||||||
|
client, ctx, cancel, err := commands.NewClient(context)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
all := context.Bool("all")
|
||||||
|
if !all {
|
||||||
|
log.G(ctx).Warn("No images pruned. `image prune` requires --all to be specified.")
|
||||||
|
// NOP
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
imageStore = client.ImageService()
|
||||||
|
containerStore = client.ContainerService()
|
||||||
|
)
|
||||||
|
imageList, err := imageStore.List(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
containerList, err := containerStore.List(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
usedImages := make(map[string]struct{})
|
||||||
|
for _, container := range containerList {
|
||||||
|
usedImages[container.Image] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var removedImages []string
|
||||||
|
for _, image := range imageList {
|
||||||
|
if _, ok := usedImages[image.Name]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
removedImages = append(removedImages, image.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
var delOpts []images.DeleteOpt
|
||||||
|
for i, imageName := range removedImages {
|
||||||
|
// Delete the last image reference synchronously to trigger garbage collection.
|
||||||
|
// This is best effort. It is possible that the image reference is deleted by
|
||||||
|
// someone else before this point.
|
||||||
|
if i == len(removedImages)-1 {
|
||||||
|
delOpts = []images.DeleteOpt{images.SynchronousDelete()}
|
||||||
|
}
|
||||||
|
if err := imageStore.Delete(ctx, imageName, delOpts...); err != nil {
|
||||||
|
if !errdefs.IsNotFound(err) {
|
||||||
|
log.G(ctx).WithError(err).Warnf("failed to delete image %s", imageName)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
log.G(ctx).Infof("deleted image: %s\n", imageName)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user