mirror of
https://github.com/containers/podman.git
synced 2025-06-20 00:51:16 +08:00
V2 podman image rm | podman rmi [IMAGE]
* Add support for rm and rmi commands * Support for registry.ExitCode * Support for N-errors from domain layer * Add log-level support * Add syslog support Signed-off-by: Jhon Honce <jhonce@redhat.com>
This commit is contained in:
@ -13,10 +13,10 @@ var (
|
|||||||
Use: "exists IMAGE",
|
Use: "exists IMAGE",
|
||||||
Short: "Check if an image exists in local storage",
|
Short: "Check if an image exists in local storage",
|
||||||
Long: `If the named image exists in local storage, podman image exists exits with 0, otherwise the exit code will be 1.`,
|
Long: `If the named image exists in local storage, podman image exists exits with 0, otherwise the exit code will be 1.`,
|
||||||
Example: `podman image exists ID
|
|
||||||
podman image exists IMAGE && podman pull IMAGE`,
|
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
RunE: exists,
|
RunE: exists,
|
||||||
|
Example: `podman image exists ID
|
||||||
|
podman image exists IMAGE && podman pull IMAGE`,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -28,6 +28,8 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func preRunE(cmd *cobra.Command, args []string) error {
|
func preRunE(cmd *cobra.Command, args []string) error {
|
||||||
_, err := registry.NewImageEngine(cmd, args)
|
if _, err := registry.NewImageEngine(cmd, args); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -15,7 +15,7 @@ var (
|
|||||||
Args: listCmd.Args,
|
Args: listCmd.Args,
|
||||||
Short: listCmd.Short,
|
Short: listCmd.Short,
|
||||||
Long: listCmd.Long,
|
Long: listCmd.Long,
|
||||||
PersistentPreRunE: preRunE,
|
PreRunE: listCmd.PreRunE,
|
||||||
RunE: listCmd.RunE,
|
RunE: listCmd.RunE,
|
||||||
Example: strings.Replace(listCmd.Example, "podman image list", "podman images", -1),
|
Example: strings.Replace(listCmd.Example, "podman image list", "podman images", -1),
|
||||||
}
|
}
|
||||||
|
70
cmd/podmanV2/images/rm.go
Normal file
70
cmd/podmanV2/images/rm.go
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package images
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/containers/libpod/cmd/podmanV2/registry"
|
||||||
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
rmDescription = "Removes one or more previously pulled or locally created images."
|
||||||
|
rmCmd = &cobra.Command{
|
||||||
|
Use: "rm [flags] IMAGE [IMAGE...]",
|
||||||
|
Short: "Removes one or more images from local storage",
|
||||||
|
Long: rmDescription,
|
||||||
|
PreRunE: preRunE,
|
||||||
|
RunE: rm,
|
||||||
|
Example: `podman image rm imageID
|
||||||
|
podman image rm --force alpine
|
||||||
|
podman image rm c4dfb1609ee2 93fd78260bd1 c0ed59d05ff7`,
|
||||||
|
}
|
||||||
|
|
||||||
|
imageOpts = entities.ImageDeleteOptions{}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||||
|
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
|
||||||
|
Command: rmCmd,
|
||||||
|
Parent: imageCmd,
|
||||||
|
})
|
||||||
|
|
||||||
|
flags := rmCmd.Flags()
|
||||||
|
flags.BoolVarP(&imageOpts.All, "all", "a", false, "Remove all images")
|
||||||
|
flags.BoolVarP(&imageOpts.Force, "force", "f", false, "Force Removal of the image")
|
||||||
|
}
|
||||||
|
|
||||||
|
func rm(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
|
if len(args) < 1 && !imageOpts.All {
|
||||||
|
return errors.Errorf("image name or ID must be specified")
|
||||||
|
}
|
||||||
|
if len(args) > 0 && imageOpts.All {
|
||||||
|
return errors.Errorf("when using the --all switch, you may not pass any images names or IDs")
|
||||||
|
}
|
||||||
|
|
||||||
|
report, err := registry.ImageEngine().Delete(registry.GetContext(), args, imageOpts)
|
||||||
|
if err != nil {
|
||||||
|
switch {
|
||||||
|
case report != nil && report.ImageNotFound != nil:
|
||||||
|
fmt.Fprintln(os.Stderr, err.Error())
|
||||||
|
registry.SetExitCode(2)
|
||||||
|
case report != nil && report.ImageInUse != nil:
|
||||||
|
fmt.Fprintln(os.Stderr, err.Error())
|
||||||
|
default:
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, u := range report.Untagged {
|
||||||
|
fmt.Println("Untagged: " + u)
|
||||||
|
}
|
||||||
|
for _, d := range report.Deleted {
|
||||||
|
fmt.Println("Deleted: " + d)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
30
cmd/podmanV2/images/rmi.go
Normal file
30
cmd/podmanV2/images/rmi.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package images
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/containers/libpod/cmd/podmanV2/registry"
|
||||||
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
rmiCmd = &cobra.Command{
|
||||||
|
Use: strings.Replace(rmCmd.Use, "rm ", "rmi ", 1),
|
||||||
|
Args: rmCmd.Args,
|
||||||
|
Short: rmCmd.Short,
|
||||||
|
Long: rmCmd.Long,
|
||||||
|
PreRunE: rmCmd.PreRunE,
|
||||||
|
RunE: rmCmd.RunE,
|
||||||
|
Example: strings.Replace(rmCmd.Example, "podman image rm", "podman rmi", -1),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||||
|
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
|
||||||
|
Command: rmiCmd,
|
||||||
|
})
|
||||||
|
rmiCmd.SetHelpTemplate(registry.HelpTemplate())
|
||||||
|
rmiCmd.SetUsageTemplate(registry.UsageTemplate())
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
@ -16,7 +15,6 @@ import (
|
|||||||
"github.com/containers/libpod/libpod"
|
"github.com/containers/libpod/libpod"
|
||||||
"github.com/containers/libpod/pkg/domain/entities"
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -24,10 +22,7 @@ func init() {
|
|||||||
logrus.Errorf(err.Error())
|
logrus.Errorf(err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
initCobra()
|
|
||||||
}
|
|
||||||
|
|
||||||
func initCobra() {
|
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "darwin":
|
case "darwin":
|
||||||
fallthrough
|
fallthrough
|
||||||
@ -46,12 +41,9 @@ func initCobra() {
|
|||||||
registry.EngineOptions.EngineMode = entities.TunnelMode
|
registry.EngineOptions.EngineMode = entities.TunnelMode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cobra.OnInitialize(func() {})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Fprintf(os.Stderr, "Number of commands: %d\n", len(registry.Commands))
|
|
||||||
for _, c := range registry.Commands {
|
for _, c := range registry.Commands {
|
||||||
if Contains(registry.EngineOptions.EngineMode, c.Mode) {
|
if Contains(registry.EngineOptions.EngineMode, c.Mode) {
|
||||||
parent := rootCmd
|
parent := rootCmd
|
||||||
|
@ -10,6 +10,8 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type CobraFuncs func(cmd *cobra.Command, args []string) error
|
||||||
|
|
||||||
type CliCommand struct {
|
type CliCommand struct {
|
||||||
Mode []entities.EngineMode
|
Mode []entities.EngineMode
|
||||||
Command *cobra.Command
|
Command *cobra.Command
|
||||||
|
@ -2,25 +2,36 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log/syslog"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
"github.com/containers/libpod/cmd/podmanV2/registry"
|
"github.com/containers/libpod/cmd/podmanV2/registry"
|
||||||
"github.com/containers/libpod/libpod/define"
|
"github.com/containers/libpod/libpod/define"
|
||||||
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
"github.com/containers/libpod/version"
|
"github.com/containers/libpod/version"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
logrusSyslog "github.com/sirupsen/logrus/hooks/syslog"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var (
|
||||||
|
rootCmd = &cobra.Command{
|
||||||
Use: path.Base(os.Args[0]),
|
Use: path.Base(os.Args[0]),
|
||||||
Long: "Manage pods, containers and images",
|
Long: "Manage pods, containers and images",
|
||||||
SilenceUsage: true,
|
SilenceUsage: true,
|
||||||
SilenceErrors: true,
|
SilenceErrors: true,
|
||||||
TraverseChildren: true,
|
TraverseChildren: true,
|
||||||
|
PersistentPreRunE: preRunE,
|
||||||
RunE: registry.SubCommandExists,
|
RunE: registry.SubCommandExists,
|
||||||
Version: version.Version,
|
Version: version.Version,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logLevels = entities.NewStringSet("debug", "info", "warn", "error", "fatal", "panic")
|
||||||
|
logLevel = "error"
|
||||||
|
useSyslog bool
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// Override default --help information of `--version` global flag}
|
// Override default --help information of `--version` global flag}
|
||||||
var dummyVersion bool
|
var dummyVersion bool
|
||||||
@ -28,6 +39,49 @@ func init() {
|
|||||||
rootCmd.PersistentFlags().BoolVar(&dummyVersion, "version", false, "Version of Podman")
|
rootCmd.PersistentFlags().BoolVar(&dummyVersion, "version", false, "Version of Podman")
|
||||||
rootCmd.PersistentFlags().StringVarP(®istry.EngineOptions.Uri, "remote", "r", "", "URL to access Podman service")
|
rootCmd.PersistentFlags().StringVarP(®istry.EngineOptions.Uri, "remote", "r", "", "URL to access Podman service")
|
||||||
rootCmd.PersistentFlags().StringSliceVar(®istry.EngineOptions.Identities, "identity", []string{}, "path to SSH identity file")
|
rootCmd.PersistentFlags().StringSliceVar(®istry.EngineOptions.Identities, "identity", []string{}, "path to SSH identity file")
|
||||||
|
rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "error", fmt.Sprintf("Log messages above specified level (%s)", logLevels.String()))
|
||||||
|
rootCmd.PersistentFlags().BoolVar(&useSyslog, "syslog", false, "Output logging information to syslog as well as the console (default false)")
|
||||||
|
|
||||||
|
cobra.OnInitialize(
|
||||||
|
logging,
|
||||||
|
syslogHook,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func preRunE(cmd *cobra.Command, args []string) error {
|
||||||
|
cmd.SetHelpTemplate(registry.HelpTemplate())
|
||||||
|
cmd.SetUsageTemplate(registry.UsageTemplate())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func logging() {
|
||||||
|
if !logLevels.Contains(logLevel) {
|
||||||
|
fmt.Fprintf(os.Stderr, "Log Level \"%s\" is not supported, choose from: %s\n", logLevel, logLevels.String())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
level, err := logrus.ParseLevel(logLevel)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
logrus.SetLevel(level)
|
||||||
|
|
||||||
|
if logrus.IsLevelEnabled(logrus.InfoLevel) {
|
||||||
|
logrus.Infof("%s filtering at log level %s", os.Args[0], logrus.GetLevel())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func syslogHook() {
|
||||||
|
if useSyslog {
|
||||||
|
hook, err := logrusSyslog.NewSyslogHook("", "", syslog.LOG_INFO, "")
|
||||||
|
if err != nil {
|
||||||
|
logrus.WithError(err).Error("Failed to initialize syslog hook")
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
logrus.AddHook(hook)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Execute() {
|
func Execute() {
|
||||||
|
@ -36,17 +36,23 @@ func RemoveImage(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = runtime.RemoveImage(r.Context(), newImage, query.Force)
|
results, err := runtime.RemoveImage(r.Context(), newImage, query.Force)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// TODO
|
|
||||||
// This will need to be fixed for proper response, like Deleted: and Untagged:
|
response := make([]map[string]string, 0, len(results.Untagged)+1)
|
||||||
m := make(map[string]string)
|
deleted := make(map[string]string, 1)
|
||||||
m["Deleted"] = newImage.ID()
|
deleted["Deleted"] = results.Deleted
|
||||||
foo := []map[string]string{}
|
response = append(response, deleted)
|
||||||
foo = append(foo, m)
|
|
||||||
utils.WriteResponse(w, http.StatusOK, foo)
|
for _, u := range results.Untagged {
|
||||||
|
untagged := make(map[string]string, 1)
|
||||||
|
untagged["Untagged"] = u
|
||||||
|
response = append(response, untagged)
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.WriteResponse(w, http.StatusOK, response)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ImageEngine interface {
|
type ImageEngine interface {
|
||||||
Delete(ctx context.Context, nameOrId string, opts ImageDeleteOptions) (*ImageDeleteReport, error)
|
Delete(ctx context.Context, nameOrId []string, opts ImageDeleteOptions) (*ImageDeleteReport, error)
|
||||||
Exists(ctx context.Context, nameOrId string) (*BoolReport, error)
|
Exists(ctx context.Context, nameOrId string) (*BoolReport, error)
|
||||||
History(ctx context.Context, nameOrId string, opts ImageHistoryOptions) (*ImageHistoryReport, error)
|
History(ctx context.Context, nameOrId string, opts ImageHistoryOptions) (*ImageHistoryReport, error)
|
||||||
List(ctx context.Context, opts ImageListOptions) ([]*ImageSummary, error)
|
List(ctx context.Context, opts ImageListOptions) ([]*ImageSummary, error)
|
||||||
|
@ -81,14 +81,18 @@ func (i *ImageSummary) IsDangling() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ImageDeleteOptions struct {
|
type ImageDeleteOptions struct {
|
||||||
|
All bool
|
||||||
Force bool
|
Force bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImageDeleteResponse is the response for removing an image from storage and containers
|
// ImageDeleteResponse is the response for removing one or more image(s) from storage
|
||||||
// what was untagged vs actually removed
|
// and containers what was untagged vs actually removed
|
||||||
type ImageDeleteReport struct {
|
type ImageDeleteReport struct {
|
||||||
Untagged []string `json:"untagged"`
|
Untagged []string `json:",omitempty"`
|
||||||
Deleted string `json:"deleted"`
|
Deleted []string `json:",omitempty"`
|
||||||
|
Errors []error
|
||||||
|
ImageNotFound error
|
||||||
|
ImageInUse error
|
||||||
}
|
}
|
||||||
|
|
||||||
type ImageHistoryOptions struct{}
|
type ImageHistoryOptions struct{}
|
||||||
|
@ -4,10 +4,12 @@ package abi
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
libpodImage "github.com/containers/libpod/libpod/image"
|
libpodImage "github.com/containers/libpod/libpod/image"
|
||||||
"github.com/containers/libpod/pkg/domain/entities"
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
"github.com/containers/libpod/pkg/domain/utils"
|
"github.com/containers/storage"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (ir *ImageEngine) Exists(_ context.Context, nameOrId string) (*entities.BoolReport, error) {
|
func (ir *ImageEngine) Exists(_ context.Context, nameOrId string) (*entities.BoolReport, error) {
|
||||||
@ -17,24 +19,76 @@ func (ir *ImageEngine) Exists(_ context.Context, nameOrId string) (*entities.Boo
|
|||||||
return &entities.BoolReport{Value: true}, nil
|
return &entities.BoolReport{Value: true}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ir *ImageEngine) Delete(ctx context.Context, nameOrId string, opts entities.ImageDeleteOptions) (*entities.ImageDeleteReport, error) {
|
func (ir *ImageEngine) Delete(ctx context.Context, nameOrId []string, opts entities.ImageDeleteOptions) (*entities.ImageDeleteReport, error) {
|
||||||
image, err := ir.Libpod.ImageRuntime().NewFromLocal(nameOrId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
results, err := ir.Libpod.RemoveImage(ctx, image, opts.Force)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
report := entities.ImageDeleteReport{}
|
report := entities.ImageDeleteReport{}
|
||||||
if err := utils.DeepCopy(&report, results); err != nil {
|
|
||||||
return nil, err
|
if opts.All {
|
||||||
|
var previousTargets []*libpodImage.Image
|
||||||
|
repeatRun:
|
||||||
|
targets, err := ir.Libpod.ImageRuntime().GetRWImages()
|
||||||
|
if err != nil {
|
||||||
|
return &report, errors.Wrapf(err, "unable to query local images")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(targets) > 0 && len(targets) == len(previousTargets) {
|
||||||
|
return &report, errors.New("unable to delete all images; re-run the rmi command again.")
|
||||||
|
}
|
||||||
|
previousTargets = targets
|
||||||
|
|
||||||
|
for _, img := range targets {
|
||||||
|
isParent, err := img.IsParent(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return &report, err
|
||||||
|
}
|
||||||
|
if isParent {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
err = ir.deleteImage(ctx, img, opts, report)
|
||||||
|
report.Errors = append(report.Errors, err)
|
||||||
|
}
|
||||||
|
if len(targets) >= 0 || len(previousTargets) != 1 {
|
||||||
|
goto repeatRun
|
||||||
}
|
}
|
||||||
return &report, nil
|
return &report, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, id := range nameOrId {
|
||||||
|
image, err := ir.Libpod.ImageRuntime().NewFromLocal(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ir.deleteImage(ctx, image, opts, report)
|
||||||
|
if err != nil {
|
||||||
|
return &report, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &report, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ir *ImageEngine) deleteImage(ctx context.Context, img *libpodImage.Image, opts entities.ImageDeleteOptions, report entities.ImageDeleteReport) error {
|
||||||
|
results, err := ir.Libpod.RemoveImage(ctx, img, opts.Force)
|
||||||
|
switch errors.Cause(err) {
|
||||||
|
case nil:
|
||||||
|
break
|
||||||
|
case storage.ErrImageUsedByContainer:
|
||||||
|
report.ImageInUse = errors.New(
|
||||||
|
fmt.Sprintf("A container associated with containers/storage, i.e. via Buildah, CRI-O, etc., may be associated with this image: %-12.12s\n", img.ID()))
|
||||||
|
return nil
|
||||||
|
case libpodImage.ErrNoSuchImage:
|
||||||
|
report.ImageNotFound = err
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
report.Deleted = append(report.Deleted, results.Deleted)
|
||||||
|
for _, e := range results.Untagged {
|
||||||
|
report.Untagged = append(report.Untagged, e)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ir *ImageEngine) Prune(ctx context.Context, opts entities.ImagePruneOptions) (*entities.ImagePruneReport, error) {
|
func (ir *ImageEngine) Prune(ctx context.Context, opts entities.ImagePruneOptions) (*entities.ImagePruneReport, error) {
|
||||||
results, err := ir.Libpod.ImageRuntime().PruneImages(ctx, opts.All, []string{})
|
results, err := ir.Libpod.ImageRuntime().PruneImages(ctx, opts.All, []string{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -14,27 +14,25 @@ func (ir *ImageEngine) Exists(_ context.Context, nameOrId string) (*entities.Boo
|
|||||||
return &entities.BoolReport{Value: found}, err
|
return &entities.BoolReport{Value: found}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ir *ImageEngine) Delete(ctx context.Context, nameOrId string, opts entities.ImageDeleteOptions) (*entities.ImageDeleteReport, error) {
|
func (ir *ImageEngine) Delete(ctx context.Context, nameOrId []string, opts entities.ImageDeleteOptions) (*entities.ImageDeleteReport, error) {
|
||||||
results, err := images.Remove(ir.ClientCxt, nameOrId, &opts.Force)
|
report := entities.ImageDeleteReport{}
|
||||||
|
|
||||||
|
for _, id := range nameOrId {
|
||||||
|
results, err := images.Remove(ir.ClientCxt, id, &opts.Force)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
report := entities.ImageDeleteReport{
|
|
||||||
Untagged: nil,
|
|
||||||
Deleted: "",
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, e := range results {
|
for _, e := range results {
|
||||||
if a, ok := e["Deleted"]; ok {
|
if a, ok := e["Deleted"]; ok {
|
||||||
report.Deleted = a
|
report.Deleted = append(report.Deleted, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
if a, ok := e["Untagged"]; ok {
|
if a, ok := e["Untagged"]; ok {
|
||||||
report.Untagged = append(report.Untagged, a)
|
report.Untagged = append(report.Untagged, a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &report, err
|
}
|
||||||
|
return &report, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) ([]*entities.ImageSummary, error) {
|
func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) ([]*entities.ImageSummary, error) {
|
||||||
|
Reference in New Issue
Block a user