summaryrefslogtreecommitdiff
path: root/cmd/podman
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/podman')
-rw-r--r--cmd/podman/cliconfig/config.go3
-rw-r--r--cmd/podman/commands.go9
-rw-r--r--cmd/podman/commands_remoteclient.go5
-rw-r--r--cmd/podman/container.go1
-rw-r--r--cmd/podman/cp.go1
-rw-r--r--cmd/podman/generate.go5
-rw-r--r--cmd/podman/generate_systemd.go10
-rw-r--r--cmd/podman/healthcheck.go5
-rw-r--r--cmd/podman/libpodruntime/runtime.go19
-rw-r--r--cmd/podman/main_local.go2
-rw-r--r--cmd/podman/pod_create.go1
-rw-r--r--cmd/podman/push.go3
-rw-r--r--cmd/podman/shared/create.go2
-rw-r--r--cmd/podman/shared/funcs.go8
-rw-r--r--cmd/podman/shared/intermediate.go10
-rw-r--r--cmd/podman/stats.go6
-rw-r--r--cmd/podman/varlink.go4
-rw-r--r--cmd/podman/varlink/io.podman.varlink13
-rw-r--r--cmd/podman/volume_create.go1
-rw-r--r--cmd/podman/volume_inspect.go24
20 files changed, 83 insertions, 49 deletions
diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go
index 6327cbd51..98e7aed4b 100644
--- a/cmd/podman/cliconfig/config.go
+++ b/cmd/podman/cliconfig/config.go
@@ -156,6 +156,7 @@ type GenerateKubeValues struct {
type GenerateSystemdValues struct {
PodmanCommand
Name bool
+ Files bool
RestartPolicy string
StopTimeout int
}
@@ -300,6 +301,7 @@ type PodCreateValues struct {
LabelFile []string
Labels []string
Name string
+ Hostname string
PodIDFile string
Publish []string
Share string
@@ -422,6 +424,7 @@ type PushValues struct {
CertDir string
Compress bool
Creds string
+ Digestfile string
Format string
Quiet bool
RemoveSignatures bool
diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go
index 27f3fc214..77c76d1b7 100644
--- a/cmd/podman/commands.go
+++ b/cmd/podman/commands.go
@@ -11,6 +11,7 @@ const remoteclient = false
// Commands that the local client implements
func getMainCommands() []*cobra.Command {
rootCommands := []*cobra.Command{
+ _cpCommand,
_playCommand,
_loginCommand,
_logoutCommand,
@@ -39,6 +40,7 @@ func getImageSubCommands() []*cobra.Command {
func getContainerSubCommands() []*cobra.Command {
return []*cobra.Command{
+ _cpCommand,
_cleanupCommand,
_mountCommand,
_refreshCommand,
@@ -71,10 +73,3 @@ func getSystemSubCommands() []*cobra.Command {
_migrateCommand,
}
}
-
-// Commands that the local client implements
-func getHealthcheckSubCommands() []*cobra.Command {
- return []*cobra.Command{
- _healthcheckrunCommand,
- }
-}
diff --git a/cmd/podman/commands_remoteclient.go b/cmd/podman/commands_remoteclient.go
index 278fe229c..a278761c1 100644
--- a/cmd/podman/commands_remoteclient.go
+++ b/cmd/podman/commands_remoteclient.go
@@ -47,8 +47,3 @@ func getTrustSubCommands() []*cobra.Command {
func getSystemSubCommands() []*cobra.Command {
return []*cobra.Command{}
}
-
-// Commands that the remoteclient implements
-func getHealthcheckSubCommands() []*cobra.Command {
- return []*cobra.Command{}
-}
diff --git a/cmd/podman/container.go b/cmd/podman/container.go
index 557f5fafa..66b58f06e 100644
--- a/cmd/podman/container.go
+++ b/cmd/podman/container.go
@@ -55,7 +55,6 @@ var (
_commitCommand,
_containerExistsCommand,
_contInspectSubCommand,
- _cpCommand,
_diffCommand,
_execCommand,
_exportCommand,
diff --git a/cmd/podman/cp.go b/cmd/podman/cp.go
index ad7253ac0..5e1ca8312 100644
--- a/cmd/podman/cp.go
+++ b/cmd/podman/cp.go
@@ -55,7 +55,6 @@ func init() {
flags.BoolVar(&cpCommand.Pause, "pause", false, "Pause the container while copying")
cpCommand.SetHelpTemplate(HelpTemplate())
cpCommand.SetUsageTemplate(UsageTemplate())
- rootCmd.AddCommand(cpCommand.Command)
}
func cpCmd(c *cliconfig.CpValues) error {
diff --git a/cmd/podman/generate.go b/cmd/podman/generate.go
index 98bfb00a1..196556bc5 100644
--- a/cmd/podman/generate.go
+++ b/cmd/podman/generate.go
@@ -18,11 +18,14 @@ var (
// Commands that are universally implemented
generateCommands = []*cobra.Command{
_containerKubeCommand,
- _containerSystemdCommand,
}
)
func init() {
+ // Systemd-service generation is not supported for remote-clients.
+ if !remoteclient {
+ generateCommands = append(generateCommands, _containerSystemdCommand)
+ }
generateCommand.Command = _generateCommand
generateCommand.AddCommand(generateCommands...)
generateCommand.SetUsageTemplate(UsageTemplate())
diff --git a/cmd/podman/generate_systemd.go b/cmd/podman/generate_systemd.go
index 222fc4c98..aa202a68d 100644
--- a/cmd/podman/generate_systemd.go
+++ b/cmd/podman/generate_systemd.go
@@ -5,7 +5,6 @@ import (
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/pkg/adapter"
- "github.com/containers/libpod/pkg/systemdgen"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -40,7 +39,10 @@ func init() {
containerSystemdCommand.SetHelpTemplate(HelpTemplate())
containerSystemdCommand.SetUsageTemplate(UsageTemplate())
flags := containerSystemdCommand.Flags()
- flags.BoolVarP(&containerSystemdCommand.Name, "name", "n", false, "use the container name instead of ID")
+ flags.BoolVarP(&containerSystemdCommand.Name, "name", "n", false, "use the container/pod name instead of ID")
+ if !remoteclient {
+ flags.BoolVarP(&containerSystemdCommand.Files, "files", "f", false, "generate files instead of printing to stdout")
+ }
flags.IntVarP(&containerSystemdCommand.StopTimeout, "timeout", "t", -1, "stop timeout override")
flags.StringVar(&containerSystemdCommand.RestartPolicy, "restart-policy", "on-failure", "applicable systemd restart-policy")
}
@@ -56,10 +58,6 @@ func generateSystemdCmd(c *cliconfig.GenerateSystemdValues) error {
if c.Flag("timeout").Changed && c.StopTimeout < 0 {
return errors.New("timeout value must be 0 or greater")
}
- // Make sure the input restart policy is valid
- if err := systemdgen.ValidateRestartPolicy(c.RestartPolicy); err != nil {
- return err
- }
unit, err := runtime.GenerateSystemd(c)
if err != nil {
diff --git a/cmd/podman/healthcheck.go b/cmd/podman/healthcheck.go
index 9fb099ffa..140206dbe 100644
--- a/cmd/podman/healthcheck.go
+++ b/cmd/podman/healthcheck.go
@@ -16,11 +16,12 @@ var healthcheckCommand = cliconfig.PodmanCommand{
}
// Commands that are universally implemented
-var healthcheckCommands []*cobra.Command
+var healthcheckCommands = []*cobra.Command{
+ _healthcheckrunCommand,
+}
func init() {
healthcheckCommand.AddCommand(healthcheckCommands...)
- healthcheckCommand.AddCommand(getHealthcheckSubCommands()...)
healthcheckCommand.SetUsageTemplate(UsageTemplate())
rootCmd.AddCommand(healthcheckCommand.Command)
}
diff --git a/cmd/podman/libpodruntime/runtime.go b/cmd/podman/libpodruntime/runtime.go
index ee9e57966..a133549ea 100644
--- a/cmd/podman/libpodruntime/runtime.go
+++ b/cmd/podman/libpodruntime/runtime.go
@@ -15,25 +15,30 @@ import (
// GetRuntimeMigrate gets a libpod runtime that will perform a migration of existing containers
func GetRuntimeMigrate(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
- return getRuntime(ctx, c, false, true, false)
+ return getRuntime(ctx, c, false, true, false, true)
+}
+
+// GetRuntimeDisableFDs gets a libpod runtime that will disable sd notify
+func GetRuntimeDisableFDs(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
+ return getRuntime(ctx, c, false, false, false, false)
}
// GetRuntimeRenumber gets a libpod runtime that will perform a lock renumber
func GetRuntimeRenumber(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
- return getRuntime(ctx, c, true, false, false)
+ return getRuntime(ctx, c, true, false, false, true)
}
// GetRuntime generates a new libpod runtime configured by command line options
func GetRuntime(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
- return getRuntime(ctx, c, false, false, false)
+ return getRuntime(ctx, c, false, false, false, true)
}
// GetRuntimeNoStore generates a new libpod runtime configured by command line options
func GetRuntimeNoStore(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
- return getRuntime(ctx, c, false, false, true)
+ return getRuntime(ctx, c, false, false, true, true)
}
-func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, renumber, migrate, noStore bool) (*libpod.Runtime, error) {
+func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, renumber, migrate, noStore, withFDS bool) (*libpod.Runtime, error) {
options := []libpod.RuntimeOption{}
storageOpts := storage.StoreOptions{}
storageSet := false
@@ -165,6 +170,10 @@ func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, renumber, migra
infraCommand, _ := c.Flags().GetString("infra-command")
options = append(options, libpod.WithDefaultInfraCommand(infraCommand))
}
+
+ if withFDS {
+ options = append(options, libpod.WithEnableSDNotify())
+ }
if c.Flags().Changed("config") {
return libpod.NewRuntimeFromConfig(ctx, c.GlobalFlags.Config, options...)
}
diff --git a/cmd/podman/main_local.go b/cmd/podman/main_local.go
index 587c8260f..648dc166e 100644
--- a/cmd/podman/main_local.go
+++ b/cmd/podman/main_local.go
@@ -140,7 +140,7 @@ func setupRootless(cmd *cobra.Command, args []string) error {
became, ret, err := rootless.TryJoinFromFilePaths("", false, []string{pausePidPath})
if err != nil {
logrus.Errorf("cannot join pause process. You may need to remove %s and stop all containers", pausePidPath)
- logrus.Errorf("you can use `system migrate` to recreate the pause process")
+ logrus.Errorf("you can use `%s system migrate` to recreate the pause process", os.Args[0])
logrus.Errorf(err.Error())
os.Exit(1)
}
diff --git a/cmd/podman/pod_create.go b/cmd/podman/pod_create.go
index d04c85dba..ad3c00aa8 100644
--- a/cmd/podman/pod_create.go
+++ b/cmd/podman/pod_create.go
@@ -52,6 +52,7 @@ func init() {
flags.StringSliceVar(&podCreateCommand.LabelFile, "label-file", []string{}, "Read in a line delimited file of labels")
flags.StringSliceVarP(&podCreateCommand.Labels, "label", "l", []string{}, "Set metadata on pod (default [])")
flags.StringVarP(&podCreateCommand.Name, "name", "n", "", "Assign a name to the pod")
+ flags.StringVarP(&podCreateCommand.Hostname, "hostname", "", "", "Set a hostname to the pod")
flags.StringVar(&podCreateCommand.PodIDFile, "pod-id-file", "", "Write the pod ID to the file")
flags.StringSliceVarP(&podCreateCommand.Publish, "publish", "p", []string{}, "Publish a container's port, or a range of ports, to the host (default [])")
flags.StringVar(&podCreateCommand.Share, "share", shared.DefaultKernelNamespaces, "A comma delimited list of kernel namespaces the pod will share")
diff --git a/cmd/podman/push.go b/cmd/podman/push.go
index 43df8c2de..13ebe8a1f 100644
--- a/cmd/podman/push.go
+++ b/cmd/podman/push.go
@@ -51,6 +51,7 @@ func init() {
pushCommand.SetUsageTemplate(UsageTemplate())
flags := pushCommand.Flags()
flags.StringVar(&pushCommand.Creds, "creds", "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry")
+ flags.StringVar(&pushCommand.Digestfile, "digestfile", "", "After copying the image, write the digest of the resulting image to the file")
flags.StringVarP(&pushCommand.Format, "format", "f", "", "Manifest type (oci, v2s1, or v2s2) to use when pushing an image using the 'dir:' transport (default is manifest type of source)")
flags.BoolVarP(&pushCommand.Quiet, "quiet", "q", false, "Don't output progress information when pushing images")
flags.BoolVar(&pushCommand.RemoveSignatures, "remove-signatures", false, "Discard any pre-existing signatures in the image")
@@ -143,5 +144,5 @@ func pushCmd(c *cliconfig.PushValues) error {
SignBy: signBy,
}
- return runtime.Push(getContext(), srcName, destName, manifestType, c.Authfile, c.SignaturePolicy, writer, c.Compress, so, &dockerRegistryOptions, nil)
+ return runtime.Push(getContext(), srcName, destName, manifestType, c.Authfile, c.String("digestfile"), c.SignaturePolicy, writer, c.Compress, so, &dockerRegistryOptions, nil)
}
diff --git a/cmd/podman/shared/create.go b/cmd/podman/shared/create.go
index 094330e24..acbd53dba 100644
--- a/cmd/podman/shared/create.go
+++ b/cmd/podman/shared/create.go
@@ -81,7 +81,7 @@ func CreateContainer(ctx context.Context, c *GenericCLIResults, runtime *libpod.
if len(c.InputArgs) != 0 {
name = c.InputArgs[0]
} else {
- return nil, nil, errors.Errorf("error, no input arguments were provided")
+ return nil, nil, errors.Errorf("error, image name not provided")
}
pullType, err := util.ValidatePullType(c.String("pull"))
diff --git a/cmd/podman/shared/funcs.go b/cmd/podman/shared/funcs.go
index 2ceb9cdcb..bb4eed1e3 100644
--- a/cmd/podman/shared/funcs.go
+++ b/cmd/podman/shared/funcs.go
@@ -6,6 +6,7 @@ import (
"path/filepath"
"strings"
+ "github.com/containers/libpod/pkg/util"
"github.com/google/shlex"
)
@@ -13,13 +14,14 @@ func GetAuthFile(authfile string) string {
if authfile != "" {
return authfile
}
+
authfile = os.Getenv("REGISTRY_AUTH_FILE")
if authfile != "" {
return authfile
}
- runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
- if runtimeDir != "" {
- return filepath.Join(runtimeDir, "containers/auth.json")
+
+ if runtimeDir, err := util.GetRuntimeDir(); err == nil {
+ return filepath.Join(runtimeDir, "auth.json")
}
return ""
}
diff --git a/cmd/podman/shared/intermediate.go b/cmd/podman/shared/intermediate.go
index c6c32f8a9..5aaac8687 100644
--- a/cmd/podman/shared/intermediate.go
+++ b/cmd/podman/shared/intermediate.go
@@ -114,7 +114,7 @@ func (f GenericCLIResults) findResult(flag string) GenericCLIResult {
if ok {
return val
}
- logrus.Errorf("unable to find flag %s", flag)
+ logrus.Debugf("unable to find flag %s", flag)
return nil
}
@@ -366,12 +366,10 @@ func NewIntermediateLayer(c *cliconfig.PodmanCommand, remote bool) GenericCLIRes
m["add-host"] = newCRStringSlice(c, "add-host")
m["annotation"] = newCRStringSlice(c, "annotation")
m["attach"] = newCRStringSlice(c, "attach")
- m["authfile"] = newCRString(c, "authfile")
m["blkio-weight"] = newCRString(c, "blkio-weight")
m["blkio-weight-device"] = newCRStringSlice(c, "blkio-weight-device")
m["cap-add"] = newCRStringSlice(c, "cap-add")
m["cap-drop"] = newCRStringSlice(c, "cap-drop")
- m["cgroupns"] = newCRString(c, "cgroupns")
m["cgroup-parent"] = newCRString(c, "cgroup-parent")
m["cidfile"] = newCRString(c, "cidfile")
m["conmon-pidfile"] = newCRString(c, "conmon-pidfile")
@@ -395,7 +393,6 @@ func NewIntermediateLayer(c *cliconfig.PodmanCommand, remote bool) GenericCLIRes
m["dns-search"] = newCRStringSlice(c, "dns-search")
m["entrypoint"] = newCRString(c, "entrypoint")
m["env"] = newCRStringArray(c, "env")
- m["env-host"] = newCRBool(c, "env-host")
m["env-file"] = newCRStringSlice(c, "env-file")
m["expose"] = newCRStringSlice(c, "expose")
m["gidmap"] = newCRStringSlice(c, "gidmap")
@@ -407,7 +404,6 @@ func NewIntermediateLayer(c *cliconfig.PodmanCommand, remote bool) GenericCLIRes
m["healthcheck-start-period"] = newCRString(c, "health-start-period")
m["healthcheck-timeout"] = newCRString(c, "health-timeout")
m["hostname"] = newCRString(c, "hostname")
- m["http-proxy"] = newCRBool(c, "http-proxy")
m["image-volume"] = newCRString(c, "image-volume")
m["init"] = newCRBool(c, "init")
m["init-path"] = newCRString(c, "init-path")
@@ -465,6 +461,10 @@ func NewIntermediateLayer(c *cliconfig.PodmanCommand, remote bool) GenericCLIRes
m["workdir"] = newCRString(c, "workdir")
// global flag
if !remote {
+ m["authfile"] = newCRString(c, "authfile")
+ m["cgroupns"] = newCRString(c, "cgroupns")
+ m["env-host"] = newCRBool(c, "env-host")
+ m["http-proxy"] = newCRBool(c, "http-proxy")
m["trace"] = newCRBool(c, "trace")
m["syslog"] = newCRBool(c, "syslog")
}
diff --git a/cmd/podman/stats.go b/cmd/podman/stats.go
index 2f696445e..25514ec75 100644
--- a/cmd/podman/stats.go
+++ b/cmd/podman/stats.go
@@ -134,9 +134,13 @@ func statsCmd(c *cliconfig.StatsValues) error {
initialStats, err := ctr.GetContainerStats(&libpod.ContainerStats{})
if err != nil {
// when doing "all", dont worry about containers that are not running
- if c.All && errors.Cause(err) == define.ErrCtrRemoved || errors.Cause(err) == define.ErrNoSuchCtr || errors.Cause(err) == define.ErrCtrStateInvalid {
+ cause := errors.Cause(err)
+ if c.All && (cause == define.ErrCtrRemoved || cause == define.ErrNoSuchCtr || cause == define.ErrCtrStateInvalid) {
continue
}
+ if cause == cgroups.ErrCgroupV1Rootless {
+ err = cause
+ }
return err
}
containerStats[ctr.ID()] = initialStats
diff --git a/cmd/podman/varlink.go b/cmd/podman/varlink.go
index 92315cd6b..cd21e3574 100644
--- a/cmd/podman/varlink.go
+++ b/cmd/podman/varlink.go
@@ -53,7 +53,7 @@ func init() {
func varlinkCmd(c *cliconfig.VarlinkValues) error {
varlinkURI := adapter.DefaultAddress
if rootless.IsRootless() {
- xdg, err := util.GetRootlessRuntimeDir()
+ xdg, err := util.GetRuntimeDir()
if err != nil {
return err
}
@@ -79,7 +79,7 @@ func varlinkCmd(c *cliconfig.VarlinkValues) error {
timeout := time.Duration(c.Timeout) * time.Millisecond
// Create a single runtime for varlink
- runtime, err := libpodruntime.GetRuntime(getContext(), &c.PodmanCommand)
+ runtime, err := libpodruntime.GetRuntimeDisableFDs(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index 2e7dee94d..752e28256 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/cmd/podman/varlink/io.podman.varlink
@@ -7,8 +7,7 @@ type Volume (
labels: [string]string,
mountPoint: string,
driver: string,
- options: [string]string,
- scope: string
+ options: [string]string
)
type NotImplemented (
@@ -275,6 +274,8 @@ type Sockets(
)
# Create is an input structure for creating containers.
+# args[0] is the image name or id
+# args[1-] are the new commands if changed
type Create (
args: []string,
addHost: ?[]string,
@@ -545,6 +546,10 @@ method GetContainersByStatus(status: []string) -> (containerS: []Container)
method Top (nameOrID: string, descriptors: []string) -> (top: []string)
+# HealthCheckRun executes defined container's healthcheck command
+# and returns the container's health status.
+method HealthCheckRun (nameOrID: string) -> (healthCheckStatus: string)
+
# GetContainer returns information about a single container. If a container
# with the given id doesn't exist, a [ContainerNotFound](#ContainerNotFound)
# error will be returned. See also [ListContainers](ListContainers) and
@@ -1238,8 +1243,6 @@ method GetLayersMapWithImageInfo() -> (layerMap: string)
# BuildImageHierarchyMap is for the development of Podman and should not be used.
method BuildImageHierarchyMap(name: string) -> (imageInfo: string)
-method GenerateSystemd(name: string, restart: string, timeout: int, useName: bool) -> (unit: string)
-
# ImageNotFound means the image could not be found by the provided name or ID in local storage.
error ImageNotFound (id: string, reason: string)
@@ -1280,4 +1283,4 @@ error WantsMoreRequired (reason: string)
error ErrCtrStopped (id: string)
# This function requires CGroupsV2 to run in rootless mode.
-error ErrRequiresCgroupsV2ForRootless(reason: string) \ No newline at end of file
+error ErrRequiresCgroupsV2ForRootless(reason: string)
diff --git a/cmd/podman/volume_create.go b/cmd/podman/volume_create.go
index 0897ab705..617f701a4 100644
--- a/cmd/podman/volume_create.go
+++ b/cmd/podman/volume_create.go
@@ -38,7 +38,6 @@ func init() {
flags.StringVar(&volumeCreateCommand.Driver, "driver", "", "Specify volume driver name (default local)")
flags.StringSliceVarP(&volumeCreateCommand.Label, "label", "l", []string{}, "Set metadata for a volume (default [])")
flags.StringSliceVarP(&volumeCreateCommand.Opt, "opt", "o", []string{}, "Set driver specific options (default [])")
-
}
func volumeCreateCmd(c *cliconfig.VolumeCreateValues) error {
diff --git a/cmd/podman/volume_inspect.go b/cmd/podman/volume_inspect.go
index 1ebc5ce60..94c99a58c 100644
--- a/cmd/podman/volume_inspect.go
+++ b/cmd/podman/volume_inspect.go
@@ -1,6 +1,9 @@
package main
import (
+ "fmt"
+
+ "github.com/containers/buildah/pkg/formats"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/pkg/adapter"
"github.com/pkg/errors"
@@ -53,5 +56,24 @@ func volumeInspectCmd(c *cliconfig.VolumeInspectValues) error {
if err != nil {
return err
}
- return generateVolLsOutput(vols, volumeLsOptions{Format: c.Format})
+
+ switch c.Format {
+ case "", formats.JSONString:
+ // Normal format - JSON string
+ jsonOut, err := json.MarshalIndent(vols, "", " ")
+ if err != nil {
+ return errors.Wrapf(err, "error marshalling inspect JSON")
+ }
+ fmt.Println(string(jsonOut))
+ default:
+ // It's a Go template.
+ interfaces := make([]interface{}, len(vols))
+ for i, vol := range vols {
+ interfaces[i] = vol
+ }
+ out := formats.StdoutTemplateArray{Output: interfaces, Template: c.Format}
+ return out.Out()
+ }
+
+ return nil
}