Merge pull request #5645 from jwhonce/wip/inspect

V2 podman inspect
This commit is contained in:
OpenShift Merge Robot
2020-04-01 19:08:08 +02:00
committed by GitHub
19 changed files with 245 additions and 141 deletions

View File

@ -0,0 +1,18 @@
package common
import (
"github.com/containers/libpod/pkg/domain/entities"
"github.com/spf13/cobra"
)
// AddInspectFlagSet takes a command and adds the inspect flags and returns an InspectOptions object
// Since this cannot live in `package main` it lives here until a better home is found
func AddInspectFlagSet(cmd *cobra.Command) *entities.InspectOptions {
opts := entities.InspectOptions{}
flags := cmd.Flags()
flags.BoolVarP(&opts.Size, "size", "s", false, "Display total file size")
flags.StringVarP(&opts.Format, "format", "f", "", "Change the output format to a Go template")
return &opts
}

View File

@ -7,9 +7,11 @@ import (
"strings"
"text/template"
"github.com/containers/libpod/cmd/podmanV2/common"
"github.com/containers/libpod/cmd/podmanV2/registry"
"github.com/containers/libpod/pkg/domain/entities"
jsoniter "github.com/json-iterator/go"
json "github.com/json-iterator/go"
"github.com/spf13/cobra"
)
@ -24,10 +26,7 @@ var (
Example: `podman container inspect myCtr
podman container inspect -l --format '{{.Id}} {{.Config.Labels}}'`,
}
)
var (
inspectOptions entities.ContainerInspectOptions
inspectOpts *entities.InspectOptions
)
func init() {
@ -36,29 +35,29 @@ func init() {
Command: inspectCmd,
Parent: containerCmd,
})
inspectOpts = common.AddInspectFlagSet(inspectCmd)
flags := inspectCmd.Flags()
flags.StringVarP(&inspectOptions.Format, "format", "f", "", "Change the output format to a Go template")
flags.BoolVarP(&inspectOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
flags.BoolVarP(&inspectOptions.Size, "size", "s", false, "Display total file size")
if registry.IsRemote() {
_ = flags.MarkHidden("latest")
if !registry.IsRemote() {
flags.BoolVarP(&inspectOpts.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
}
}
func inspect(cmd *cobra.Command, args []string) error {
responses, err := registry.ContainerEngine().ContainerInspect(context.Background(), args, inspectOptions)
responses, err := registry.ContainerEngine().ContainerInspect(context.Background(), args, *inspectOpts)
if err != nil {
return err
}
if inspectOptions.Format == "" {
b, err := jsoniter.MarshalIndent(responses, "", " ")
if inspectOpts.Format == "" {
b, err := json.MarshalIndent(responses, "", " ")
if err != nil {
return err
}
fmt.Println(string(b))
return nil
}
format := inspectOptions.Format
format := inspectOpts.Format
if !strings.HasSuffix(format, "\n") {
format += "\n"
}
@ -73,3 +72,8 @@ func inspect(cmd *cobra.Command, args []string) error {
}
return nil
}
func Inspect(cmd *cobra.Command, args []string, options *entities.InspectOptions) error {
inspectOpts = options
return inspect(cmd, args)
}

View File

@ -1,71 +1,44 @@
package images
import (
"context"
"encoding/json"
"fmt"
"os"
"strings"
"text/tabwriter"
"text/template"
"github.com/containers/buildah/pkg/formats"
"github.com/containers/libpod/cmd/podmanV2/common"
"github.com/containers/libpod/cmd/podmanV2/registry"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/util"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
var (
inspectOpts = entities.ImageInspectOptions{}
// Command: podman image _inspect_
inspectCmd = &cobra.Command{
Use: "inspect [flags] IMAGE",
Short: "Display the configuration of an image",
Long: `Displays the low-level information on an image identified by name or ID.`,
PreRunE: populateEngines,
RunE: imageInspect,
RunE: inspect,
Example: `podman image inspect alpine`,
}
containerEngine entities.ContainerEngine
inspectOpts *entities.InspectOptions
)
// Inspect is unique in that it needs both an ImageEngine and a ContainerEngine
func populateEngines(cmd *cobra.Command, args []string) (err error) {
// Populate registry.ImageEngine
err = preRunE(cmd, args)
if err != nil {
return
}
// Populate registry.ContainerEngine
containerEngine, err = registry.NewContainerEngine(cmd, args)
return
}
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
Command: inspectCmd,
Parent: imageCmd,
})
flags := inspectCmd.Flags()
flags.BoolVarP(&inspectOpts.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
flags.BoolVarP(&inspectOpts.Size, "size", "s", false, "Display total file size")
flags.StringVarP(&inspectOpts.Format, "format", "f", "", "Change the output format to a Go template")
if registry.EngineOptions.EngineMode == entities.ABIMode {
// TODO: This is the same as V1. We could skip creating the flag altogether in V2...
_ = flags.MarkHidden("latest")
}
inspectOpts = common.AddInspectFlagSet(inspectCmd)
}
const (
inspectTypeContainer = "container"
inspectTypeImage = "image"
inspectAll = "all"
)
func imageInspect(cmd *cobra.Command, args []string) error {
inspectType := inspectTypeImage
func inspect(cmd *cobra.Command, args []string) error {
latestContainer := inspectOpts.Latest
if len(args) == 0 && !latestContainer {
@ -76,49 +49,61 @@ func imageInspect(cmd *cobra.Command, args []string) error {
return errors.Errorf("you cannot provide additional arguments with --latest")
}
if !util.StringInSlice(inspectType, []string{inspectTypeContainer, inspectTypeImage, inspectAll}) {
return errors.Errorf("the only recognized types are %q, %q, and %q", inspectTypeContainer, inspectTypeImage, inspectAll)
results, err := registry.ImageEngine().Inspect(context.Background(), args, *inspectOpts)
if err != nil {
return err
}
outputFormat := inspectOpts.Format
if strings.Contains(outputFormat, "{{.Id}}") {
outputFormat = strings.Replace(outputFormat, "{{.Id}}", formats.IDString, -1)
}
// These fields were renamed, so we need to provide backward compat for
// the old names.
if strings.Contains(outputFormat, ".Src") {
outputFormat = strings.Replace(outputFormat, ".Src", ".Source", -1)
}
if strings.Contains(outputFormat, ".Dst") {
outputFormat = strings.Replace(outputFormat, ".Dst", ".Destination", -1)
}
if strings.Contains(outputFormat, ".ImageID") {
outputFormat = strings.Replace(outputFormat, ".ImageID", ".Image", -1)
}
_ = outputFormat
// if latestContainer {
// lc, err := ctnrRuntime.GetLatestContainer()
// if err != nil {
// return err
// }
// args = append(args, lc.ID())
// inspectType = inspectTypeContainer
// }
if len(results.Images) > 0 {
if inspectOpts.Format == "" {
buf, err := json.MarshalIndent(results.Images, "", " ")
if err != nil {
return err
}
fmt.Println(string(buf))
// inspectedObjects, iterateErr := iterateInput(getContext(), c.Size, args, runtime, inspectType)
// if iterateErr != nil {
// return iterateErr
// }
//
// var out formats.Writer
// if outputFormat != "" && outputFormat != formats.JSONString {
// // template
// out = formats.StdoutTemplateArray{Output: inspectedObjects, Template: outputFormat}
// } else {
// // default is json output
// out = formats.JSONStructArray{Output: inspectedObjects}
// }
//
// return out.Out()
for id, e := range results.Errors {
fmt.Fprintf(os.Stderr, "%s: %s\n", id, e.Error())
}
return nil
}
row := inspectFormat(inspectOpts.Format)
format := "{{range . }}" + row + "{{end}}"
tmpl, err := template.New("inspect").Parse(format)
if err != nil {
return err
}
w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
defer func() { _ = w.Flush() }()
err = tmpl.Execute(w, results)
if err != nil {
return err
}
}
for id, e := range results.Errors {
fmt.Fprintf(os.Stderr, "%s: %s\n", id, e.Error())
}
return nil
}
func inspectFormat(row string) string {
r := strings.NewReplacer("{{.Id}}", formats.IDString,
".Src", ".Source",
".Dst", ".Destination",
".ImageID", ".Image",
)
row = r.Replace(row)
if !strings.HasSuffix(row, "\n") {
row += "\n"
}
return row
}
func Inspect(cmd *cobra.Command, args []string, options *entities.InspectOptions) error {
inspectOpts = options
return inspect(cmd, args)
}

View File

@ -152,7 +152,7 @@ func writeTemplate(imageS []*entities.ImageSummary, err error) error {
hdr, row := imageListFormat(listFlag)
format := hdr + "{{range . }}" + row + "{{end}}"
tmpl := template.Must(template.New("report").Funcs(report.PodmanTemplateFuncs()).Parse(format))
tmpl := template.Must(template.New("list").Funcs(report.PodmanTemplateFuncs()).Parse(format))
w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
defer w.Flush()
return tmpl.Execute(w, imgs)

62
cmd/podmanV2/inspect.go Normal file
View File

@ -0,0 +1,62 @@
package main
import (
"context"
"fmt"
"github.com/containers/libpod/cmd/podmanV2/common"
"github.com/containers/libpod/cmd/podmanV2/containers"
"github.com/containers/libpod/cmd/podmanV2/images"
"github.com/containers/libpod/cmd/podmanV2/registry"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/spf13/cobra"
)
// Inspect is one of the out layer commands in that it operates on images/containers/...
var (
inspectOpts *entities.InspectOptions
// Command: podman _inspect_ Object_ID
inspectCmd = &cobra.Command{
Use: "inspect [flags] {CONTAINER_ID | IMAGE_ID}",
Args: cobra.ExactArgs(1),
Short: "Display the configuration of object denoted by ID",
Long: "Displays the low-level information on an object identified by name or ID",
TraverseChildren: true,
RunE: inspect,
}
)
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
Command: inspectCmd,
})
inspectOpts = common.AddInspectFlagSet(inspectCmd)
}
func inspect(cmd *cobra.Command, args []string) error {
ie, err := registry.NewImageEngine(cmd, args)
if err != nil {
return err
}
if found, err := ie.Exists(context.Background(), args[0]); err != nil {
return err
} else if found.Value {
return images.Inspect(cmd, args, inspectOpts)
}
ce, err := registry.NewContainerEngine(cmd, args)
if err != nil {
return err
}
if found, err := ce.ContainerExists(context.Background(), args[0]); err != nil {
return err
} else if found.Value {
return containers.Inspect(cmd, args, inspectOpts)
}
return fmt.Errorf("%s not found on system", args[0])
}

View File

@ -3,7 +3,6 @@ package registry
import (
"context"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/domain/infra"
"github.com/pkg/errors"
@ -18,24 +17,24 @@ type CliCommand struct {
Parent *cobra.Command
}
const ExecErrorCodeGeneric = 125
var (
Commands []CliCommand
imageEngine entities.ImageEngine
containerEngine entities.ContainerEngine
cliCtx context.Context
containerEngine entities.ContainerEngine
exitCode = ExecErrorCodeGeneric
imageEngine entities.ImageEngine
Commands []CliCommand
EngineOptions entities.EngineOptions
ExitCode = define.ExecErrorCodeGeneric
)
func SetExitCode(code int) {
ExitCode = code
exitCode = code
}
func GetExitCode() int {
return ExitCode
return exitCode
}
// HelpTemplate returns the help template for podman commands

View File

@ -7,7 +7,6 @@ import (
"path"
"github.com/containers/libpod/cmd/podmanV2/registry"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/version"
"github.com/sirupsen/logrus"
@ -88,8 +87,8 @@ func Execute() {
o := registry.NewOptions(rootCmd.Context(), &registry.EngineOptions)
if err := rootCmd.ExecuteContext(o); err != nil {
fmt.Fprintln(os.Stderr, "Error:", err.Error())
} else if registry.GetExitCode() == define.ExecErrorCodeGeneric {
// The exitCode modified from define.ExecErrorCodeGeneric,
} else if registry.GetExitCode() == registry.ExecErrorCodeGeneric {
// The exitCode modified from registry.ExecErrorCodeGeneric,
// indicates an application
// running inside of a container failed, as opposed to the
// podman command failed. Must exit with that exit code

View File

@ -1,4 +1,4 @@
package images
package system
import (
"github.com/containers/libpod/cmd/podmanV2/registry"

2
go.sum
View File

@ -301,6 +301,7 @@ github.com/mtrmac/gpgme v0.1.2/go.mod h1:GYYHnGSuS7HK3zVS2n3y73y0okK/BeKzwnn5jgi
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@ -596,6 +597,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=

View File

@ -12,7 +12,6 @@ import (
"github.com/containers/libpod/pkg/api/handlers"
"github.com/containers/libpod/pkg/bindings"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/inspect"
)
// Exists a lightweight way to determine if an image exists in local storage. It returns a
@ -57,7 +56,7 @@ func List(ctx context.Context, all *bool, filters map[string][]string) ([]*entit
// Get performs an image inspect. To have the on-disk size of the image calculated, you can
// use the optional size parameter.
func GetImage(ctx context.Context, nameOrID string, size *bool) (*inspect.ImageData, error) {
func GetImage(ctx context.Context, nameOrID string, size *bool) (*entities.ImageData, error) {
conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
@ -66,7 +65,7 @@ func GetImage(ctx context.Context, nameOrID string, size *bool) (*inspect.ImageD
if size != nil {
params.Set("size", strconv.FormatBool(*size))
}
inspectedData := inspect.ImageData{}
inspectedData := entities.ImageData{}
response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/json", params, nameOrID)
if err != nil {
return &inspectedData, err

View File

@ -98,12 +98,6 @@ type RmReport struct {
Id string
}
type ContainerInspectOptions struct {
Format string
Latest bool
Size bool
}
type ContainerInspectReport struct {
*define.InspectContainerData
}

View File

@ -9,32 +9,30 @@ import (
type ContainerEngine interface {
ContainerCommit(ctx context.Context, nameOrId string, options CommitOptions) (*CommitReport, error)
ContainerExists(ctx context.Context, nameOrId string) (*BoolReport, error)
ContainerInspect(ctx context.Context, namesOrIds []string, options ContainerInspectOptions) ([]*ContainerInspectReport, error)
ContainerInspect(ctx context.Context, namesOrIds []string, options InspectOptions) ([]*ContainerInspectReport, error)
ContainerKill(ctx context.Context, namesOrIds []string, options KillOptions) ([]*KillReport, error)
ContainerPause(ctx context.Context, namesOrIds []string, options PauseUnPauseOptions) ([]*PauseUnpauseReport, error)
ContainerRestart(ctx context.Context, namesOrIds []string, options RestartOptions) ([]*RestartReport, error)
ContainerRm(ctx context.Context, namesOrIds []string, options RmOptions) ([]*RmReport, error)
ContainerUnpause(ctx context.Context, namesOrIds []string, options PauseUnPauseOptions) ([]*PauseUnpauseReport, error)
ContainerStop(ctx context.Context, namesOrIds []string, options StopOptions) ([]*StopReport, error)
ContainerWait(ctx context.Context, namesOrIds []string, options WaitOptions) ([]WaitReport, error)
ContainerTop(ctx context.Context, options TopOptions) (*StringSliceReport, error)
ContainerUnpause(ctx context.Context, namesOrIds []string, options PauseUnPauseOptions) ([]*PauseUnpauseReport, error)
ContainerWait(ctx context.Context, namesOrIds []string, options WaitOptions) ([]WaitReport, error)
HealthCheckRun(ctx context.Context, nameOrId string, options HealthCheckOptions) (*define.HealthCheckResults, error)
PodCreate(ctx context.Context, opts PodCreateOptions) (*PodCreateReport, error)
PodExists(ctx context.Context, nameOrId string) (*BoolReport, error)
PodKill(ctx context.Context, namesOrIds []string, options PodKillOptions) ([]*PodKillReport, error)
PodPause(ctx context.Context, namesOrIds []string, options PodPauseOptions) ([]*PodPauseReport, error)
PodPs(ctx context.Context, options PodPSOptions) ([]*ListPodsReport, error)
PodRestart(ctx context.Context, namesOrIds []string, options PodRestartOptions) ([]*PodRestartReport, error)
PodRm(ctx context.Context, namesOrIds []string, options PodRmOptions) ([]*PodRmReport, error)
PodStart(ctx context.Context, namesOrIds []string, options PodStartOptions) ([]*PodStartReport, error)
PodStop(ctx context.Context, namesOrIds []string, options PodStopOptions) ([]*PodStopReport, error)
PodRm(ctx context.Context, namesOrIds []string, options PodRmOptions) ([]*PodRmReport, error)
PodUnpause(ctx context.Context, namesOrIds []string, options PodunpauseOptions) ([]*PodUnpauseReport, error)
PodTop(ctx context.Context, options PodTopOptions) (*StringSliceReport, error)
PodUnpause(ctx context.Context, namesOrIds []string, options PodunpauseOptions) ([]*PodUnpauseReport, error)
VolumeCreate(ctx context.Context, opts VolumeCreateOptions) (*IdOrNameResponse, error)
VolumeInspect(ctx context.Context, namesOrIds []string, opts VolumeInspectOptions) ([]*VolumeInspectReport, error)
VolumeRm(ctx context.Context, namesOrIds []string, opts VolumeRmOptions) ([]*VolumeRmReport, error)
VolumePrune(ctx context.Context, opts VolumePruneOptions) ([]*VolumePruneReport, error)
VolumeList(ctx context.Context, opts VolumeListOptions) ([]*VolumeListReport, error)
HealthCheckRun(ctx context.Context, nameOrId string, options HealthCheckOptions) (*define.HealthCheckResults, error)
VolumePrune(ctx context.Context, opts VolumePruneOptions) ([]*VolumePruneReport, error)
VolumeRm(ctx context.Context, namesOrIds []string, opts VolumeRmOptions) ([]*VolumeRmReport, error)
}

View File

@ -8,6 +8,7 @@ type ImageEngine interface {
Delete(ctx context.Context, nameOrId []string, opts ImageDeleteOptions) (*ImageDeleteReport, error)
Exists(ctx context.Context, nameOrId string) (*BoolReport, error)
History(ctx context.Context, nameOrId string, opts ImageHistoryOptions) (*ImageHistoryReport, error)
Inspect(ctx context.Context, names []string, opts InspectOptions) (*ImageInspectReport, error)
List(ctx context.Context, opts ImageListOptions) ([]*ImageSummary, error)
Prune(ctx context.Context, opts ImagePruneOptions) (*ImagePruneReport, error)
Pull(ctx context.Context, rawImage string, opts ImagePullOptions) (*ImagePullReport, error)

View File

@ -5,6 +5,7 @@ import (
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/types"
"github.com/containers/libpod/pkg/inspect"
docker "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/opencontainers/go-digest"
@ -12,7 +13,6 @@ import (
)
type Image struct {
IdOrNamed
ID string `json:"Id"`
RepoTags []string `json:",omitempty"`
RepoDigests []string `json:",omitempty"`
@ -111,13 +111,6 @@ type ImageHistoryReport struct {
Layers []ImageHistoryLayer
}
type ImageInspectOptions struct {
TypeObject string `json:",omitempty"`
Format string `json:",omitempty"`
Size bool `json:",omitempty"`
Latest bool `json:",omitempty"`
}
// ImagePullOptions are the arguments for pulling images.
type ImagePullOptions struct {
// AllTags can be specified to pull all tags of the spiecifed image. Note
@ -157,10 +150,6 @@ type ImageListOptions struct {
Filters url.Values `json:"filters" schema:"filters"`
}
// type ImageListReport struct {
// Images []ImageSummary
// }
type ImagePruneOptions struct {
All bool `json:"all" schema:"all"`
Filter []string `json:"filter" schema:"filter"`
@ -174,3 +163,12 @@ type ImagePruneReport struct {
type ImageTagOptions struct{}
type ImageUntagOptions struct{}
type ImageData struct {
*inspect.ImageData
}
type ImageInspectReport struct {
Images []*ImageData
Errors map[string]error
}

View File

@ -42,3 +42,10 @@ type NetOptions struct {
StaticIP *net.IP
StaticMAC *net.HardwareAddr
}
// All CLI inspect commands and inspect sub-commands use the same options
type InspectOptions struct {
Format string `json:",omitempty"`
Latest bool `json:",omitempty"`
Size bool `json:",omitempty"`
}

View File

@ -243,7 +243,7 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
return reports, nil
}
func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.ContainerInspectOptions) ([]*entities.ContainerInspectReport, error) {
func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.InspectOptions) ([]*entities.ContainerInspectReport, error) {
var reports []*entities.ContainerInspectReport
ctrs, err := shortcuts.GetContainersByContext(false, options.Latest, namesOrIds, ic.Libpod)
if err != nil {

View File

@ -17,6 +17,7 @@ import (
"github.com/containers/libpod/libpod/image"
libpodImage "github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/domain/entities"
domainUtils "github.com/containers/libpod/pkg/domain/utils"
"github.com/containers/libpod/pkg/util"
"github.com/containers/storage"
"github.com/pkg/errors"
@ -234,6 +235,31 @@ func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entiti
return &entities.ImagePullReport{Images: foundIDs}, nil
}
func (ir *ImageEngine) Inspect(ctx context.Context, names []string, opts entities.InspectOptions) (*entities.ImageInspectReport, error) {
report := entities.ImageInspectReport{
Errors: make(map[string]error),
}
for _, id := range names {
img, err := ir.Libpod.ImageRuntime().NewFromLocal(id)
if err != nil {
report.Errors[id] = err
continue
}
results, err := img.Inspect(ctx)
if err != nil {
report.Errors[id] = err
continue
}
cookedResults := entities.ImageData{}
_ = domainUtils.DeepCopy(&cookedResults, results)
report.Images = append(report.Images, &cookedResults)
}
return &report, nil
}
// func (r *imageRuntime) Delete(ctx context.Context, nameOrId string, opts entities.ImageDeleteOptions) (*entities.ImageDeleteReport, error) {
// image, err := r.libpod.ImageEngine().NewFromLocal(nameOrId)
// if err != nil {
@ -246,7 +272,7 @@ func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entiti
// }
//
// report := entities.ImageDeleteReport{}
// if err := utils.DeepCopy(&report, results); err != nil {
// if err := domainUtils.DeepCopy(&report, results); err != nil {
// return nil, err
// }
// return &report, nil

View File

@ -142,7 +142,7 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
return reports, nil
}
func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.ContainerInspectOptions) ([]*entities.ContainerInspectReport, error) {
func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.InspectOptions) ([]*entities.ContainerInspectReport, error) {
var (
reports []*entities.ContainerInspectReport
)

View File

@ -145,3 +145,15 @@ func (ir *ImageEngine) Untag(ctx context.Context, nameOrId string, tags []string
}
return nil
}
func (ir *ImageEngine) Inspect(_ context.Context, names []string, opts entities.InspectOptions) (*entities.ImageInspectReport, error) {
report := entities.ImageInspectReport{}
for _, id := range names {
r, err := images.GetImage(ir.ClientCxt, id, &opts.Size)
if err != nil {
report.Errors[id] = err
}
report.Images = append(report.Images, r)
}
return &report, nil
}