Skip to content

Commit

Permalink
Merge pull request #8102 from ashley-cui/inspect
Browse files Browse the repository at this point in the history
Add pod, volume, network to inspect package
  • Loading branch information
openshift-merge-robot authored Oct 27, 2020
2 parents 26c0929 + 61deec4 commit 7149a7c
Show file tree
Hide file tree
Showing 17 changed files with 360 additions and 127 deletions.
121 changes: 108 additions & 13 deletions cmd/podman/inspect/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,26 @@ import (
"github.com/containers/common/pkg/report"
"github.com/containers/podman/v2/cmd/podman/registry"
"github.com/containers/podman/v2/cmd/podman/validate"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/pkg/domain/entities"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

const (
// ImageType is the image type.
ImageType = "image"
// ContainerType is the container type.
ContainerType = "container"
// AllType can be of type ImageType or ContainerType.
AllType = "all"
// ContainerType is the container type.
ContainerType = "container"
// ImageType is the image type.
ImageType = "image"
//NetworkType is the network type
NetworkType = "network"
//PodType is the pod type.
PodType = "pod"
//VolumeType is the volume type
VolumeType = "volume"
)

// Pull in configured json library
Expand Down Expand Up @@ -58,15 +65,16 @@ type inspector struct {
containerEngine entities.ContainerEngine
imageEngine entities.ImageEngine
options entities.InspectOptions
podOptions entities.PodInspectOptions
}

// newInspector creates a new inspector based on the specified options.
func newInspector(options entities.InspectOptions) (*inspector, error) {
switch options.Type {
case ImageType, ContainerType, AllType:
case ImageType, ContainerType, AllType, PodType, NetworkType, VolumeType:
// Valid types.
default:
return nil, errors.Errorf("invalid type %q: must be %q, %q or %q", options.Type, ImageType, ContainerType, AllType)
return nil, errors.Errorf("invalid type %q: must be %q, %q, %q, %q, %q, or %q", options.Type, ImageType, ContainerType, PodType, NetworkType, VolumeType, AllType)
}
if options.Type == ImageType {
if options.Latest {
Expand All @@ -76,10 +84,18 @@ func newInspector(options entities.InspectOptions) (*inspector, error) {
return nil, errors.Errorf("size is not supported for type %q", ImageType)
}
}
if options.Type == PodType && options.Size {
return nil, errors.Errorf("size is not supported for type %q", PodType)
}
podOpts := entities.PodInspectOptions{
Latest: options.Latest,
Format: options.Format,
}
return &inspector{
containerEngine: registry.ContainerEngine(),
imageEngine: registry.ImageEngine(),
options: options,
podOptions: podOpts,
}, nil
}

Expand All @@ -91,17 +107,19 @@ func (i *inspector) inspect(namesOrIDs []string) error {
ctx := context.Background()

if len(namesOrIDs) == 0 {
if !i.options.Latest {
return errors.New("no containers or images specified")
if !i.options.Latest && !i.options.All {
return errors.New("no names or ids specified")
}
}

tmpType := i.options.Type
if i.options.Latest {
if len(namesOrIDs) > 0 {
return errors.New("--latest and containers cannot be used together")
return errors.New("--latest and arguments cannot be used together")
}
if i.options.Type == AllType {
tmpType = ContainerType // -l works with --type=all, defaults to containertype
}
tmpType = ContainerType // -l works with --type=all
}

// Inspect - note that AllType requires us to expensively query one-by-one.
Expand Down Expand Up @@ -131,10 +149,57 @@ func (i *inspector) inspect(namesOrIDs []string) error {
for i := range ctrData {
data = append(data, ctrData[i])
}
case PodType:
for _, pod := range namesOrIDs {
i.podOptions.NameOrID = pod
podData, err := i.containerEngine.PodInspect(ctx, i.podOptions)
if err != nil {
cause := errors.Cause(err)
if !strings.Contains(cause.Error(), define.ErrNoSuchPod.Error()) {
errs = []error{err}
} else {
return err
}
} else {
errs = nil
data = append(data, podData)
}
}
if i.podOptions.Latest { //latest means there are no names in the namesOrID array
podData, err := i.containerEngine.PodInspect(ctx, i.podOptions)
if err != nil {
cause := errors.Cause(err)
if !strings.Contains(cause.Error(), define.ErrNoSuchPod.Error()) {
errs = []error{err}
} else {
return err
}
} else {
errs = nil
data = append(data, podData)
}
}
case NetworkType:
networkData, allErrs, err := registry.ContainerEngine().NetworkInspect(ctx, namesOrIDs, i.options)
if err != nil {
return err
}
errs = allErrs
for i := range networkData {
data = append(data, networkData[i])
}
case VolumeType:
volumeData, allErrs, err := i.containerEngine.VolumeInspect(ctx, namesOrIDs, i.options)
if err != nil {
return err
}
errs = allErrs
for i := range volumeData {
data = append(data, volumeData[i])
}
default:
return errors.Errorf("invalid type %q: must be %q, %q or %q", i.options.Type, ImageType, ContainerType, AllType)
return errors.Errorf("invalid type %q: must be %q, %q, %q, %q, %q, or %q", i.options.Type, ImageType, ContainerType, PodType, NetworkType, VolumeType, AllType)
}

// Always print an empty array
if data == nil {
data = []interface{}{}
Expand Down Expand Up @@ -195,11 +260,41 @@ func (i *inspector) inspectAll(ctx context.Context, namesOrIDs []string) ([]inte
if err != nil {
return nil, nil, err
}
if len(errs) == 0 {
data = append(data, imgData[0])
continue
}
volumeData, errs, err := i.containerEngine.VolumeInspect(ctx, []string{name}, i.options)
if err != nil {
return nil, nil, err
}
if len(errs) == 0 {
data = append(data, volumeData[0])
continue
}
networkData, errs, err := registry.ContainerEngine().NetworkInspect(ctx, namesOrIDs, i.options)
if err != nil {
return nil, nil, err
}
if len(errs) == 0 {
data = append(data, networkData[0])
continue
}
i.podOptions.NameOrID = name
podData, err := i.containerEngine.PodInspect(ctx, i.podOptions)
if err != nil {
cause := errors.Cause(err)
if !strings.Contains(cause.Error(), define.ErrNoSuchPod.Error()) {
return nil, nil, err
}
} else {
data = append(data, podData)
continue
}
if len(errs) > 0 {
allErrs = append(allErrs, errors.Errorf("no such object: %q", name))
continue
}
data = append(data, imgData[0])
}
return data, allErrs, nil
}
Expand Down
44 changes: 6 additions & 38 deletions cmd/podman/networks/inspect.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
package network

import (
"encoding/json"
"fmt"
"os"
"text/tabwriter"
"text/template"

"github.com/containers/common/pkg/report"
"github.com/containers/podman/v2/cmd/podman/inspect"
"github.com/containers/podman/v2/cmd/podman/registry"
"github.com/containers/podman/v2/pkg/domain/entities"
"github.com/spf13/cobra"
Expand All @@ -23,10 +17,7 @@ var (
Example: `podman network inspect podman`,
Args: cobra.MinimumNArgs(1),
}
)

var (
networkInspectOptions entities.NetworkInspectOptions
inspectOpts *entities.InspectOptions
)

func init() {
Expand All @@ -35,36 +26,13 @@ func init() {
Command: networkinspectCommand,
Parent: networkCmd,
})
inspectOpts = new(entities.InspectOptions)
flags := networkinspectCommand.Flags()
flags.StringVarP(&networkInspectOptions.Format, "format", "f", "", "Pretty-print network to JSON or using a Go template")
flags.StringVarP(&inspectOpts.Format, "format", "f", "", "Pretty-print network to JSON or using a Go template")
}

func networkInspect(_ *cobra.Command, args []string) error {
responses, err := registry.ContainerEngine().NetworkInspect(registry.Context(), args, entities.NetworkInspectOptions{})
if err != nil {
return err
}

switch {
case report.IsJSON(networkInspectOptions.Format) || networkInspectOptions.Format == "":
b, err := json.MarshalIndent(responses, "", " ")
if err != nil {
return err
}
fmt.Println(string(b))
default:
row := report.NormalizeFormat(networkInspectOptions.Format)
// There can be more than 1 in the inspect output.
row = "{{range . }}" + row + "{{end}}"
tmpl, err := template.New("inspectNetworks").Parse(row)
if err != nil {
return err
}
inspectOpts.Type = inspect.NetworkType
return inspect.Inspect(args, *inspectOpts)

w := tabwriter.NewWriter(os.Stdout, 8, 2, 0, ' ', 0)
defer w.Flush()

return tmpl.Execute(w, responses)
}
return nil
}
40 changes: 8 additions & 32 deletions cmd/podman/volumes/inspect.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
package volumes

import (
"fmt"
"os"
"text/template"

"github.com/containers/common/pkg/report"
"github.com/containers/podman/v2/cmd/podman/inspect"
"github.com/containers/podman/v2/cmd/podman/registry"
"github.com/containers/podman/v2/pkg/domain/entities"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"golang.org/x/net/context"
)

var (
Expand All @@ -21,16 +16,15 @@ var (
Use: "inspect [options] VOLUME [VOLUME...]",
Short: "Display detailed information on one or more volumes",
Long: volumeInspectDescription,
RunE: inspect,
RunE: volumeInspect,
Example: `podman volume inspect myvol
podman volume inspect --all
podman volume inspect --format "{{.Driver}} {{.Scope}}" myvol`,
}
)

var (
inspectOpts = entities.VolumeInspectOptions{}
inspectFormat string
inspectOpts *entities.InspectOptions
)

func init() {
Expand All @@ -39,34 +33,16 @@ func init() {
Command: inspectCommand,
Parent: volumeCmd,
})
inspectOpts = new(entities.InspectOptions)
flags := inspectCommand.Flags()
flags.BoolVarP(&inspectOpts.All, "all", "a", false, "Inspect all volumes")
flags.StringVarP(&inspectFormat, "format", "f", "json", "Format volume output using Go template")
flags.StringVarP(&inspectOpts.Format, "format", "f", "json", "Format volume output using Go template")
}

func inspect(cmd *cobra.Command, args []string) error {
func volumeInspect(cmd *cobra.Command, args []string) error {
if (inspectOpts.All && len(args) > 0) || (!inspectOpts.All && len(args) < 1) {
return errors.New("provide one or more volume names or use --all")
}
responses, err := registry.ContainerEngine().VolumeInspect(context.Background(), args, inspectOpts)
if err != nil {
return err
}

switch {
case report.IsJSON(inspectFormat), inspectFormat == "":
jsonOut, err := json.MarshalIndent(responses, "", " ")
if err != nil {
return errors.Wrapf(err, "error marshalling inspect JSON")
}
fmt.Println(string(jsonOut))
default:
row := "{{range . }}" + report.NormalizeFormat(inspectFormat) + "{{end}}"
tmpl, err := template.New("volumeInspect").Parse(row)
if err != nil {
return err
}
return tmpl.Execute(os.Stdout, responses)
}
return nil
inspectOpts.Type = inspect.VolumeType
return inspect.Inspect(args, *inspectOpts)
}
Loading

0 comments on commit 7149a7c

Please sign in to comment.