diff options
Diffstat (limited to 'cmd/podman')
86 files changed, 553 insertions, 424 deletions
diff --git a/cmd/podman/attach.go b/cmd/podman/attach.go index 8b0fd7ffd..ed175bdf4 100644 --- a/cmd/podman/attach.go +++ b/cmd/podman/attach.go @@ -28,14 +28,13 @@ var ( func init() { attachCommand.Command = _attachCommand + attachCommand.SetUsageTemplate(UsageTemplate()) flags := attachCommand.Flags() flags.StringVar(&attachCommand.DetachKeys, "detach-keys", "", "Override the key sequence for detaching a container. Format is a single character [a-Z] or ctrl-<value> where <value> is one of: a-z, @, ^, [, , or _") flags.BoolVar(&attachCommand.NoStdin, "no-stdin", false, "Do not attach STDIN. The default is false") flags.BoolVar(&attachCommand.SigProxy, "sig-proxy", true, "Proxy received signals to the process (default true)") flags.BoolVarP(&attachCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - - rootCmd.AddCommand(attachCommand.Command) } func attachCmd(c *cliconfig.AttachValues) error { @@ -75,7 +74,7 @@ func attachCmd(c *cliconfig.AttachValues) error { inputStream = nil } - if err := startAttachCtr(ctr, os.Stdout, os.Stderr, inputStream, c.DetachKeys, c.SigProxy, false); err != nil { + if err := startAttachCtr(ctr, os.Stdout, os.Stderr, inputStream, c.DetachKeys, c.SigProxy, false); err != nil && errors.Cause(err) != libpod.ErrDetach { return errors.Wrapf(err, "error attaching to container %s", ctr.ID()) } diff --git a/cmd/podman/build.go b/cmd/podman/build.go index 20f621e84..30a734377 100644 --- a/cmd/podman/build.go +++ b/cmd/podman/build.go @@ -1,7 +1,6 @@ package main import ( - "io/ioutil" "os" "path/filepath" "strings" @@ -9,10 +8,9 @@ import ( "github.com/containers/buildah" "github.com/containers/buildah/imagebuildah" buildahcli "github.com/containers/buildah/pkg/cli" - "github.com/containers/buildah/pkg/parse" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/libpodruntime" - "github.com/containers/libpod/pkg/rootless" + "github.com/containers/libpod/libpod/adapter" + "github.com/docker/go-units" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -48,6 +46,7 @@ var ( func init() { buildCommand.Command = _buildCommand + buildCommand.SetUsageTemplate(UsageTemplate()) flags := buildCommand.Flags() flags.SetInterspersed(false) @@ -58,8 +57,6 @@ func init() { flags.AddFlagSet(&budFlags) flags.AddFlagSet(&fromAndBugFlags) - - rootCmd.AddCommand(buildCommand.Command) } func getDockerfiles(files []string) []string { @@ -77,7 +74,6 @@ func getDockerfiles(files []string) []string { func buildCmd(c *cliconfig.BuildValues) error { // The following was taken directly from containers/buildah/cmd/bud.go // TODO Find a away to vendor more of this in rather than copy from bud - output := "" tags := []string{} if c.Flag("tag").Changed { @@ -87,6 +83,7 @@ func buildCmd(c *cliconfig.BuildValues) error { tags = tags[1:] } } + pullPolicy := imagebuildah.PullNever if c.Pull { pullPolicy = imagebuildah.PullIfMissing @@ -174,16 +171,17 @@ func buildCmd(c *cliconfig.BuildValues) error { dockerfiles = append(dockerfiles, filepath.Join(contextDir, "Dockerfile")) } + runtime, err := adapter.GetRuntime(&c.PodmanCommand) + if err != nil { + return errors.Wrapf(err, "could not get runtime") + } + runtimeFlags := []string{} for _, arg := range c.RuntimeOpts { runtimeFlags = append(runtimeFlags, "--"+arg) } // end from buildah - runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand) - if err != nil { - return errors.Wrapf(err, "could not get runtime") - } defer runtime.Shutdown(false) var stdout, stderr, reporter *os.File @@ -202,72 +200,64 @@ func buildCmd(c *cliconfig.BuildValues) error { reporter = f } - systemContext, err := parse.SystemContextFromOptions(c.PodmanCommand.Command) - if err != nil { - return errors.Wrapf(err, "error building system context") - } - systemContext.AuthFilePath = getAuthFile(c.Authfile) - commonOpts, err := parse.CommonBuildOptions(c.PodmanCommand.Command) - if err != nil { - return err + var memoryLimit, memorySwap int64 + if c.Flags().Changed("memory") { + memoryLimit, err = units.RAMInBytes(c.Memory) + if err != nil { + return err + } } - namespaceOptions, networkPolicy, err := parse.NamespaceOptions(c.PodmanCommand.Command) - if err != nil { - return errors.Wrapf(err, "error parsing namespace-related options") - } - usernsOption, idmappingOptions, err := parse.IDMappingOptions(c.PodmanCommand.Command) - if err != nil { - return errors.Wrapf(err, "error parsing ID mapping options") + if c.Flags().Changed("memory-swap") { + memorySwap, err = units.RAMInBytes(c.MemorySwap) + if err != nil { + return err + } } - namespaceOptions.AddOrReplace(usernsOption...) - ociruntime := runtime.GetOCIRuntimePath() - if c.Flag("runtime").Changed { - ociruntime = c.Runtime + buildOpts := buildah.CommonBuildOptions{ + AddHost: c.AddHost, + CgroupParent: c.CgroupParent, + CPUPeriod: c.CPUPeriod, + CPUQuota: c.CPUQuota, + CPUShares: c.CPUShares, + CPUSetCPUs: c.CPUSetCPUs, + CPUSetMems: c.CPUSetMems, + Memory: memoryLimit, + MemorySwap: memorySwap, + ShmSize: c.ShmSize, + Ulimit: c.Ulimit, + Volumes: c.Volume, } + options := imagebuildah.BuildOptions{ - ContextDirectory: contextDir, - PullPolicy: pullPolicy, - Compression: imagebuildah.Gzip, - Quiet: c.Quiet, - SignaturePolicyPath: c.SignaturePolicy, - Args: args, - Output: output, + CommonBuildOpts: &buildOpts, AdditionalTags: tags, - Out: stdout, - Err: stderr, - ReportWriter: reporter, - Runtime: ociruntime, - RuntimeArgs: runtimeFlags, - OutputFormat: format, - SystemContext: systemContext, - NamespaceOptions: namespaceOptions, - ConfigureNetwork: networkPolicy, - CNIPluginPath: c.CNIPlugInPath, + Annotations: c.Annotation, + Args: args, CNIConfigDir: c.CNIConfigDir, - IDMappingOptions: idmappingOptions, - CommonBuildOpts: commonOpts, + CNIPluginPath: c.CNIPlugInPath, + Compression: imagebuildah.Gzip, + ContextDirectory: contextDir, DefaultMountsFilePath: c.GlobalFlags.DefaultMountsFile, + Err: stderr, + ForceRmIntermediateCtrs: c.ForceRm, IIDFile: c.Iidfile, - Squash: c.Squash, Labels: c.Label, - Annotations: c.Annotation, Layers: layers, NoCache: c.NoCache, + Out: stdout, + Output: output, + OutputFormat: format, + PullPolicy: pullPolicy, + Quiet: c.Quiet, RemoveIntermediateCtrs: c.Rm, - ForceRmIntermediateCtrs: c.ForceRm, - } - - if c.Quiet { - options.ReportWriter = ioutil.Discard - } - - if rootless.IsRootless() { - options.Isolation = buildah.IsolationOCIRootless + ReportWriter: reporter, + RuntimeArgs: runtimeFlags, + SignaturePolicyPath: c.SignaturePolicy, + Squash: c.Squash, } - - return runtime.Build(getContext(), options, dockerfiles...) + return runtime.Build(getContext(), c, options, dockerfiles) } // Tail returns a string slice after the first element unless there are diff --git a/cmd/podman/checkpoint.go b/cmd/podman/checkpoint.go index 2a978bea8..aa4034ccd 100644 --- a/cmd/podman/checkpoint.go +++ b/cmd/podman/checkpoint.go @@ -35,6 +35,7 @@ var ( func init() { checkpointCommand.Command = _checkpointCommand + checkpointCommand.SetUsageTemplate(UsageTemplate()) flags := checkpointCommand.Flags() flags.BoolVarP(&checkpointCommand.Keep, "keep", "k", false, "Keep all temporary checkpoint files") diff --git a/cmd/podman/cleanup.go b/cmd/podman/cleanup.go index 1a7617d5c..e465a30e6 100644 --- a/cmd/podman/cleanup.go +++ b/cmd/podman/cleanup.go @@ -32,10 +32,12 @@ var ( func init() { cleanupCommand.Command = _cleanupCommand + cleanupCommand.SetUsageTemplate(UsageTemplate()) flags := cleanupCommand.Flags() flags.BoolVarP(&cleanupCommand.All, "all", "a", false, "Cleans up all containers") flags.BoolVarP(&cleanupCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") + flags.BoolVar(&cleanupCommand.Remove, "rm", false, "After cleanup, remove the container entirely") } func cleanupCmd(c *cliconfig.CleanupValues) error { @@ -54,12 +56,25 @@ func cleanupCmd(c *cliconfig.CleanupValues) error { ctx := getContext() for _, ctr := range cleanupContainers { - if err = ctr.Cleanup(ctx); err != nil { - if lastError != nil { - fmt.Fprintln(os.Stderr, lastError) + hadError := false + if c.Remove { + if err := runtime.RemoveContainer(ctx, ctr, false, false); err != nil { + if lastError != nil { + fmt.Fprintln(os.Stderr, lastError) + } + lastError = errors.Wrapf(err, "failed to cleanup and remove container %v", ctr.ID()) + hadError = true } - lastError = errors.Wrapf(err, "failed to cleanup container %v", ctr.ID()) } else { + if err := ctr.Cleanup(ctx); err != nil { + if lastError != nil { + fmt.Fprintln(os.Stderr, lastError) + } + lastError = errors.Wrapf(err, "failed to cleanup container %v", ctr.ID()) + hadError = true + } + } + if !hadError { fmt.Println(ctr.ID()) } } diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go index b925d29ff..f38bcaa62 100644 --- a/cmd/podman/cliconfig/config.go +++ b/cmd/podman/cliconfig/config.go @@ -135,6 +135,11 @@ type PruneImagesValues struct { All bool } +type PruneContainersValues struct { + PodmanCommand + Force bool +} + type ImportValues struct { PodmanCommand Change []string @@ -531,6 +536,7 @@ type CleanupValues struct { PodmanCommand All bool Latest bool + Remove bool } type SystemPruneValues struct { diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go index e1eba1f31..baa49d2af 100644 --- a/cmd/podman/commands.go +++ b/cmd/podman/commands.go @@ -6,24 +6,65 @@ import ( "github.com/spf13/cobra" ) +// Commands that the local client implements +func getMainCommands() []*cobra.Command { + rootCommands := []*cobra.Command{ + _attachCommand, + _commitCommand, + _createCommand, + _diffCommand, + _execCommand, + _killCommand, + generateCommand.Command, + podCommand.Command, + _containerKubeCommand, + _psCommand, + _loadCommand, + _loginCommand, + _logoutCommand, + _logsCommand, + _mountCommand, + _pauseCommand, + _portCommand, + _refreshCommand, + _restartCommand, + _restoreCommand, + _rmCommand, + _runCommand, + _saveCommand, + _searchCommand, + _signCommand, + _startCommand, + _statsCommand, + _stopCommand, + _topCommand, + _umountCommand, + _unpauseCommand, + volumeCommand.Command, + _waitCommand, + } + + if len(_varlinkCommand.Use) > 0 { + rootCommands = append(rootCommands, _varlinkCommand) + } + return rootCommands +} + +// Commands that the local client implements func getImageSubCommands() []*cobra.Command { return []*cobra.Command{ - _buildCommand, - _importCommand, _loadCommand, - _pullCommand, - _rmiCommand, _saveCommand, _signCommand, } } +// Commands that the local client implements func getContainerSubCommands() []*cobra.Command { return []*cobra.Command{ _attachCommand, _checkpointCommand, _cleanupCommand, - _containerExistsCommand, _commitCommand, _createCommand, _diffCommand, @@ -40,7 +81,7 @@ func getContainerSubCommands() []*cobra.Command { _restartCommand, _restoreCommand, _rmCommand, - _runCommmand, + _runCommand, _runlabelCommand, _startCommand, _statsCommand, @@ -52,6 +93,7 @@ func getContainerSubCommands() []*cobra.Command { } } +// Commands that the local client implements func getPodSubCommands() []*cobra.Command { return []*cobra.Command{ _podCreateCommand, @@ -70,6 +112,7 @@ func getPodSubCommands() []*cobra.Command { } } +// Commands that the local client implements func getVolumeSubCommands() []*cobra.Command { return []*cobra.Command{ _volumeCreateCommand, @@ -80,18 +123,21 @@ func getVolumeSubCommands() []*cobra.Command { } } +// Commands that the local client implements func getGenerateSubCommands() []*cobra.Command { return []*cobra.Command{ _containerKubeCommand, } } +// Commands that the local client implements func getPlaySubCommands() []*cobra.Command { return []*cobra.Command{ _playKubeCommand, } } +// Commands that the local client implements func getTrustSubCommands() []*cobra.Command { return []*cobra.Command{ _setTrustCommand, @@ -99,9 +145,9 @@ func getTrustSubCommands() []*cobra.Command { } } +// Commands that the local client implements func getSystemSubCommands() []*cobra.Command { return []*cobra.Command{ - _infoCommand, _pruneSystemCommand, } } diff --git a/cmd/podman/commands_remoteclient.go b/cmd/podman/commands_remoteclient.go index 80083eab9..7bdba1c19 100644 --- a/cmd/podman/commands_remoteclient.go +++ b/cmd/podman/commands_remoteclient.go @@ -6,43 +6,57 @@ import ( "github.com/spf13/cobra" ) -//import "github.com/urfave/cli" -// +// commands that only the remoteclient implements +func getMainCommands() []*cobra.Command { + return []*cobra.Command{} +} + +// commands that only the remoteclient implements func getAppCommands() []*cobra.Command { return []*cobra.Command{} } +// commands that only the remoteclient implements func getImageSubCommands() []*cobra.Command { return []*cobra.Command{} } +// commands that only the remoteclient implements func getContainerSubCommands() []*cobra.Command { return []*cobra.Command{} } +// commands that only the remoteclient implements func getPodSubCommands() []*cobra.Command { return []*cobra.Command{} } +// commands that only the remoteclient implements func getVolumeSubCommands() []*cobra.Command { - return []*cobra.Command{} + return []*cobra.Command{ + _volumeCreateCommand, + _volumeRmCommand, + _volumeLsCommand, + _volumeInspectCommand, + } } +// commands that only the remoteclient implements func getGenerateSubCommands() []*cobra.Command { return []*cobra.Command{} } +// commands that only the remoteclient implements func getPlaySubCommands() []*cobra.Command { return []*cobra.Command{} } +// commands that only the remoteclient implements func getTrustSubCommands() []*cobra.Command { return []*cobra.Command{} } -//func getMainAppFlags() []cli.Flag { -// return []cli.Flag{} -//} +// commands that only the remoteclient implements func getSystemSubCommands() []*cobra.Command { return []*cobra.Command{} } diff --git a/cmd/podman/commit.go b/cmd/podman/commit.go index 6fd6b9761..dc53e68d1 100644 --- a/cmd/podman/commit.go +++ b/cmd/podman/commit.go @@ -39,6 +39,7 @@ var ( func init() { commitCommand.Command = _commitCommand + commitCommand.SetUsageTemplate(UsageTemplate()) flags := commitCommand.Flags() flags.StringSliceVarP(&commitCommand.Change, "change", "c", []string{}, fmt.Sprintf("Apply the following possible instructions to the created image (default []): %s", strings.Join(libpod.ChangeCmds, " | "))) flags.StringVarP(&commitCommand.Format, "format", "f", "oci", "`Format` of the image manifest and metadata") @@ -47,7 +48,6 @@ func init() { flags.BoolVarP(&commitCommand.Pause, "pause", "p", false, "Pause container during commit") flags.BoolVarP(&commitCommand.Quiet, "quiet", "q", false, "Suppress output") - rootCmd.AddCommand(commitCommand.Command) } func commitCmd(c *cliconfig.CommitValues) error { diff --git a/cmd/podman/common.go b/cmd/podman/common.go index 5fbdfce50..417e938b7 100644 --- a/cmd/podman/common.go +++ b/cmd/podman/common.go @@ -500,3 +500,27 @@ func scrubServer(server string) string { server = strings.TrimPrefix(server, "https://") return strings.TrimPrefix(server, "http://") } + +// UsageTemplate returns the usage template for podman commands +// This blocks the desplaying of the global options. The main podman +// command should not use this. +func UsageTemplate() string { + return `Usage:{{if .Runnable}} + {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}} + + {{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}} + +Aliases: + {{.NameAndAliases}}{{end}}{{if .HasExample}} + +Examples: +{{.Example}}{{end}}{{if .HasAvailableSubCommands}} + +Available Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}} + {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}} + +Flags: +{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}} +{{end}} +` +} diff --git a/cmd/podman/common_test.go b/cmd/podman/common_test.go index 042568d7e..a24173003 100644 --- a/cmd/podman/common_test.go +++ b/cmd/podman/common_test.go @@ -3,34 +3,8 @@ package main import ( "os/user" "testing" - - "flag" - - "github.com/urfave/cli" ) -func TestGetStore(t *testing.T) { - t.Skip("FIX THIS!") - - //cmd/podman/common_test.go:27: cannot use c (type *cli.Context) as type *libkpod.Config in argument to getStore - - // Make sure the tests are running as root - skipTestIfNotRoot(t) - - set := flag.NewFlagSet("test", 0) - globalSet := flag.NewFlagSet("test", 0) - globalSet.String("root", "", "path to the root directory in which data, including images, is stored") - globalCtx := cli.NewContext(nil, globalSet, nil) - command := cli.Command{Name: "imagesCommand"} - c := cli.NewContext(nil, set, globalCtx) - c.Command = command - - //_, err := getStore(c) - //if err != nil { - //t.Error(err) - //} -} - func skipTestIfNotRoot(t *testing.T) { u, err := user.Current() if err != nil { diff --git a/cmd/podman/container.go b/cmd/podman/container.go index 969cb2dc8..d2450fdd3 100644 --- a/cmd/podman/container.go +++ b/cmd/podman/container.go @@ -15,7 +15,14 @@ var containerCommand = cliconfig.PodmanCommand{ }, } +// Commands that are universally implemented. +var containerCommands = []*cobra.Command{ + _containerExistsCommand, +} + func init() { + containerCommand.AddCommand(containerCommands...) containerCommand.AddCommand(getContainerSubCommands()...) + containerCommand.SetUsageTemplate(UsageTemplate()) rootCmd.AddCommand(containerCommand.Command) } diff --git a/cmd/podman/containers_prune.go b/cmd/podman/containers_prune.go index 3f9b46035..bae578e1d 100644 --- a/cmd/podman/containers_prune.go +++ b/cmd/podman/containers_prune.go @@ -13,13 +13,12 @@ import ( ) var ( - pruneContainersCommand cliconfig.ContainersPrune + pruneContainersCommand cliconfig.PruneContainersValues pruneContainersDescription = ` podman container prune Removes all exited containers ` - _pruneContainersCommand = &cobra.Command{ Use: "prune", Short: "Remove all stopped containers", @@ -34,9 +33,12 @@ var ( func init() { pruneContainersCommand.Command = _pruneContainersCommand + pruneContainersCommand.SetUsageTemplate(UsageTemplate()) + flags := pruneContainersCommand.Flags() + flags.BoolVarP(&pruneContainersCommand.Force, "force", "f", false, "Force removal of a running container. The default is false") } -func pruneContainers(runtime *adapter.LocalRuntime, ctx context.Context, maxWorkers int, force bool) error { +func pruneContainers(runtime *adapter.LocalRuntime, ctx context.Context, maxWorkers int, force, volumes bool) error { var deleteFuncs []shared.ParallelWorkerInput filter := func(c *libpod.Container) bool { @@ -56,7 +58,7 @@ func pruneContainers(runtime *adapter.LocalRuntime, ctx context.Context, maxWork for _, container := range delContainers { con := container f := func() error { - return runtime.RemoveContainer(ctx, con, force) + return runtime.RemoveContainer(ctx, con, force, volumes) } deleteFuncs = append(deleteFuncs, shared.ParallelWorkerInput{ @@ -69,7 +71,7 @@ func pruneContainers(runtime *adapter.LocalRuntime, ctx context.Context, maxWork return printParallelOutput(deleteErrors, errCount) } -func pruneContainersCmd(c *cliconfig.ContainersPrune) error { +func pruneContainersCmd(c *cliconfig.PruneContainersValues) error { runtime, err := adapter.GetRuntime(&c.PodmanCommand) if err != nil { return errors.Wrapf(err, "could not get runtime") @@ -82,5 +84,5 @@ func pruneContainersCmd(c *cliconfig.ContainersPrune) error { } logrus.Debugf("Setting maximum workers to %d", maxWorkers) - return pruneContainers(runtime, getContext(), maxWorkers, c.Bool("force")) + return pruneContainers(runtime, getContext(), maxWorkers, c.Bool("force"), c.Bool("volumes")) } diff --git a/cmd/podman/create.go b/cmd/podman/create.go index 2f8742052..392163424 100644 --- a/cmd/podman/create.go +++ b/cmd/podman/create.go @@ -60,12 +60,12 @@ var ( func init() { createCommand.PodmanCommand.Command = _createCommand + createCommand.SetUsageTemplate(UsageTemplate()) getCreateFlags(&createCommand.PodmanCommand) flags := createCommand.Flags() flags.SetInterspersed(true) - rootCmd.AddCommand(createCommand.Command) } func createCmd(c *cliconfig.CreateValues) error { @@ -646,9 +646,10 @@ func parseCreateOpts(ctx context.Context, c *cliconfig.PodmanCommand, runtime *l } var ImageVolumes map[string]struct{} - if data != nil { + if data != nil && c.String("image-volume") != "ignore" { ImageVolumes = data.Config.Volumes } + var imageVolType = map[string]string{ "bind": "", "tmpfs": "", diff --git a/cmd/podman/diff.go b/cmd/podman/diff.go index 04a659ab6..7d4cc1b58 100644 --- a/cmd/podman/diff.go +++ b/cmd/podman/diff.go @@ -52,6 +52,7 @@ var ( func init() { diffCommand.Command = _diffCommand + diffCommand.SetUsageTemplate(UsageTemplate()) flags := diffCommand.Flags() flags.BoolVar(&diffCommand.Archive, "archive", true, "Save the diff as a tar archive") @@ -59,9 +60,8 @@ func init() { flags.MarkHidden("archive") - rootCmd.AddCommand(diffCommand.Command) - } + func formatJSON(output []diffOutputParams) (diffJSONOutput, error) { jsonStruct := diffJSONOutput{} for _, output := range output { diff --git a/cmd/podman/exec.go b/cmd/podman/exec.go index b4f66bc03..74808768e 100644 --- a/cmd/podman/exec.go +++ b/cmd/podman/exec.go @@ -35,6 +35,7 @@ var ( func init() { execCommand.Command = _execCommand + execCommand.SetUsageTemplate(UsageTemplate()) flags := execCommand.Flags() flags.SetInterspersed(false) flags.StringSliceVarP(&execCommand.Env, "env", "e", []string{}, "Set environment variables") @@ -46,7 +47,6 @@ func init() { flags.StringVarP(&execCommand.Workdir, "workdir", "w", "", "Working directory inside the container") - rootCmd.AddCommand(execCommand.Command) } func execCmd(c *cliconfig.ExecValues) error { diff --git a/cmd/podman/exists.go b/cmd/podman/exists.go index a21e8fcf8..15ddaec06 100644 --- a/cmd/podman/exists.go +++ b/cmd/podman/exists.go @@ -72,8 +72,11 @@ var ( func init() { imageExistsCommand.Command = _imageExistsCommand + imageExistsCommand.SetUsageTemplate(UsageTemplate()) containerExistsCommand.Command = _containerExistsCommand + containerExistsCommand.SetUsageTemplate(UsageTemplate()) podExistsCommand.Command = _podExistsCommand + podExistsCommand.SetUsageTemplate(UsageTemplate()) } func imageExistsCmd(c *cliconfig.ImageExistsValues) error { diff --git a/cmd/podman/export.go b/cmd/podman/export.go index bd9e38b0c..2ce8186a1 100644 --- a/cmd/podman/export.go +++ b/cmd/podman/export.go @@ -31,9 +31,9 @@ var ( func init() { exportCommand.Command = _exportCommand + exportCommand.SetUsageTemplate(UsageTemplate()) flags := exportCommand.Flags() flags.StringVarP(&exportCommand.Output, "output", "o", "/dev/stdout", "Write to a file, default is STDOUT") - rootCmd.AddCommand(exportCommand.Command) } // exportCmd saves a container to a tarball on disk diff --git a/cmd/podman/generate.go b/cmd/podman/generate.go index a5e15fdd6..66cb7a465 100644 --- a/cmd/podman/generate.go +++ b/cmd/podman/generate.go @@ -17,5 +17,5 @@ var generateCommand = cliconfig.PodmanCommand{ func init() { generateCommand.AddCommand(getGenerateSubCommands()...) - rootCmd.AddCommand(generateCommand.Command) + generateCommand.SetUsageTemplate(UsageTemplate()) } diff --git a/cmd/podman/generate_kube.go b/cmd/podman/generate_kube.go index 8e3432d12..ddb2daa34 100644 --- a/cmd/podman/generate_kube.go +++ b/cmd/podman/generate_kube.go @@ -31,6 +31,7 @@ var ( func init() { containerKubeCommand.Command = _containerKubeCommand + containerKubeCommand.SetUsageTemplate(UsageTemplate()) flags := containerKubeCommand.Flags() flags.BoolVarP(&containerKubeCommand.Service, "service", "s", false, "Generate YAML for kubernetes service object") } diff --git a/cmd/podman/history.go b/cmd/podman/history.go index 97e501947..6791257d9 100644 --- a/cmd/podman/history.go +++ b/cmd/podman/history.go @@ -53,6 +53,7 @@ var ( func init() { historyCommand.Command = _historyCommand + historyCommand.SetUsageTemplate(UsageTemplate()) flags := historyCommand.Flags() flags.StringVar(&historyCommand.Format, "format", "", "Change the output to JSON or a Go template") flags.BoolVarP(&historyCommand.Human, "human", "H", true, "Display sizes and dates in human readable format") @@ -60,9 +61,8 @@ func init() { flags.BoolVar(&historyCommand.NoTrunc, "no-trunc", false, "Do not truncate the output") flags.BoolVarP(&historyCommand.Quiet, "quiet", "q", false, "Display the numeric IDs only") - rootCmd.AddCommand(historyCommand.Command) - } + func historyCmd(c *cliconfig.HistoryValues) error { runtime, err := adapter.GetRuntime(&c.PodmanCommand) if err != nil { diff --git a/cmd/podman/image.go b/cmd/podman/image.go index ac7ff4944..4f9c7cd6a 100644 --- a/cmd/podman/image.go +++ b/cmd/podman/image.go @@ -18,18 +18,21 @@ var ( //imageSubCommands are implemented both in local and remote clients var imageSubCommands = []*cobra.Command{ + _buildCommand, _historyCommand, _imageExistsCommand, - _inspectCommand, _imagesCommand, + _importCommand, + _inspectCommand, _pruneImagesCommand, + _pullCommand, _pushCommand, _rmiCommand, _tagCommand, } func init() { + imageCommand.SetUsageTemplate(UsageTemplate()) imageCommand.AddCommand(imageSubCommands...) imageCommand.AddCommand(getImageSubCommands()...) - rootCmd.AddCommand(imageCommand.Command) } diff --git a/cmd/podman/images.go b/cmd/podman/images.go index 6f5a3e9f1..b269f6440 100644 --- a/cmd/podman/images.go +++ b/cmd/podman/images.go @@ -102,6 +102,7 @@ var ( func init() { imagesCommand.Command = _imagesCommand + imagesCommand.SetUsageTemplate(UsageTemplate()) flags := imagesCommand.Flags() flags.BoolVarP(&imagesCommand.All, "all", "a", false, "Show all images (default hides intermediate images)") flags.BoolVar(&imagesCommand.Digests, "digests", false, "Show digests") @@ -114,8 +115,6 @@ func init() { flags.BoolVarP(&imagesCommand.Quiet, "quiet", "q", false, "Display only image IDs") flags.StringVar(&imagesCommand.Sort, "sort", "created", "Sort by created, id, repository, size, or tag") - rootCmd.AddCommand(imagesCommand.Command) - } func imagesCmd(c *cliconfig.ImagesValues) error { @@ -248,8 +247,12 @@ func getImagesTemplateOutput(ctx context.Context, images []*adapter.ContainerIma } // get all specified repo:tag pairs and print them separately + repopairs, err := image.ReposToMap(img.Names()) + if err != nil { + logrus.Errorf("error finding tag/digest for %s", img.ID()) + } outer: - for repo, tags := range image.ReposToMap(img.Names()) { + for repo, tags := range repopairs { for _, tag := range tags { size, err := img.Size(ctx) var sizeStr string diff --git a/cmd/podman/images_prune.go b/cmd/podman/images_prune.go index ba99c5bde..cc0dcb99a 100644 --- a/cmd/podman/images_prune.go +++ b/cmd/podman/images_prune.go @@ -30,6 +30,7 @@ var ( func init() { pruneImagesCommand.Command = _pruneImagesCommand + pruneImagesCommand.SetUsageTemplate(UsageTemplate()) flags := pruneImagesCommand.Flags() flags.BoolVarP(&pruneImagesCommand.All, "all", "a", false, "Remove all unused images, not just dangling ones") } diff --git a/cmd/podman/import.go b/cmd/podman/import.go index 52d144eb3..32f79757b 100644 --- a/cmd/podman/import.go +++ b/cmd/podman/import.go @@ -31,12 +31,12 @@ var ( func init() { importCommand.Command = _importCommand + importCommand.SetUsageTemplate(UsageTemplate()) flags := importCommand.Flags() flags.StringSliceVarP(&importCommand.Change, "change", "c", []string{}, "Apply the following possible instructions to the created image (default []): CMD | ENTRYPOINT | ENV | EXPOSE | LABEL | STOPSIGNAL | USER | VOLUME | WORKDIR") flags.StringVarP(&importCommand.Message, "message", "m", "", "Set commit message for imported image") flags.BoolVarP(&importCommand.Quiet, "quiet", "q", false, "Suppress output") - rootCmd.AddCommand(importCommand.Command) } func importCmd(c *cliconfig.ImportValues) error { diff --git a/cmd/podman/info.go b/cmd/podman/info.go index 0896e16a4..d60b8f84f 100644 --- a/cmd/podman/info.go +++ b/cmd/podman/info.go @@ -32,12 +32,12 @@ var ( func init() { infoCommand.Command = _infoCommand + infoCommand.SetUsageTemplate(UsageTemplate()) flags := infoCommand.Flags() flags.BoolVarP(&infoCommand.Debug, "debug", "D", false, "Display additional debug information") flags.StringVarP(&infoCommand.Format, "format", "f", "", "Change the output format to JSON or a Go template") - rootCmd.AddCommand(infoCommand.Command) } func infoCmd(c *cliconfig.InfoValues) error { diff --git a/cmd/podman/inspect.go b/cmd/podman/inspect.go index b2979c6ae..a29eb790e 100644 --- a/cmd/podman/inspect.go +++ b/cmd/podman/inspect.go @@ -40,13 +40,13 @@ var ( func init() { inspectCommand.Command = _inspectCommand + inspectCommand.SetUsageTemplate(UsageTemplate()) flags := inspectCommand.Flags() flags.StringVarP(&inspectCommand.TypeObject, "type", "t", inspectAll, "Return JSON for specified type, (e.g image, container or task)") flags.StringVarP(&inspectCommand.Format, "format", "f", "", "Change the output format to a Go template") flags.BoolVarP(&inspectCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of if the type is a container") flags.BoolVarP(&inspectCommand.Size, "size", "s", false, "Display total file size if the type is container") - rootCmd.AddCommand(inspectCommand.Command) } func inspectCmd(c *cliconfig.InspectValues) error { diff --git a/cmd/podman/kill.go b/cmd/podman/kill.go index 04c0fd531..d922cf721 100644 --- a/cmd/podman/kill.go +++ b/cmd/podman/kill.go @@ -34,13 +34,13 @@ var ( func init() { killCommand.Command = _killCommand + killCommand.SetUsageTemplate(UsageTemplate()) flags := killCommand.Flags() flags.BoolVarP(&killCommand.All, "all", "a", false, "Signal all running containers") flags.StringVarP(&killCommand.Signal, "signal", "s", "KILL", "Signal to send to the container") flags.BoolVarP(&killCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - rootCmd.AddCommand(killCommand.Command) } // killCmd kills one or more containers with a signal diff --git a/cmd/podman/load.go b/cmd/podman/load.go index 90268ca8f..34a51cd0d 100644 --- a/cmd/podman/load.go +++ b/cmd/podman/load.go @@ -34,12 +34,12 @@ var ( func init() { loadCommand.Command = _loadCommand + loadCommand.SetUsageTemplate(UsageTemplate()) flags := loadCommand.Flags() flags.StringVarP(&loadCommand.Input, "input", "i", "/dev/stdin", "Read from archive file, default is STDIN") flags.BoolVarP(&loadCommand.Quiet, "quiet", "q", false, "Suppress the output") flags.StringVar(&loadCommand.SignaturePolicy, "signature-policy", "", "Pathname of signature policy file (not usually used)") - rootCmd.AddCommand(loadCommand.Command) } // loadCmd gets the image/file to be loaded from the command line diff --git a/cmd/podman/login.go b/cmd/podman/login.go index 5ab0713e5..0bd58ff78 100644 --- a/cmd/podman/login.go +++ b/cmd/podman/login.go @@ -35,6 +35,7 @@ var ( func init() { loginCommand.Command = _loginCommand + loginCommand.SetUsageTemplate(UsageTemplate()) flags := loginCommand.Flags() flags.StringVar(&loginCommand.Authfile, "authfile", "", "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json. Use REGISTRY_AUTH_FILE environment variable to override") @@ -44,7 +45,6 @@ func init() { flags.BoolVar(&loginCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries (default: true)") flags.StringVarP(&loginCommand.Username, "username", "u", "", "Username for registry") - rootCmd.AddCommand(loginCommand.Command) } // loginCmd uses the authentication package to store a user's authenticated credentials diff --git a/cmd/podman/logout.go b/cmd/podman/logout.go index 02bde7857..5fecf814e 100644 --- a/cmd/podman/logout.go +++ b/cmd/podman/logout.go @@ -28,11 +28,11 @@ var ( func init() { logoutCommand.Command = _logoutCommand + logoutCommand.SetUsageTemplate(UsageTemplate()) flags := logoutCommand.Flags() flags.BoolVarP(&logoutCommand.All, "all", "a", false, "Remove the cached credentials for all registries in the auth file") flags.StringVar(&logoutCommand.Authfile, "authfile", "", "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json. Use REGISTRY_AUTH_FILE environment variable to override") - rootCmd.AddCommand(logoutCommand.Command) } // logoutCmd uses the authentication package to remove the authenticated of a registry diff --git a/cmd/podman/logs.go b/cmd/podman/logs.go index 83f900e63..6962a1f6d 100644 --- a/cmd/podman/logs.go +++ b/cmd/podman/logs.go @@ -32,6 +32,7 @@ var ( func init() { logsCommand.Command = _logsCommand + logsCommand.SetUsageTemplate(UsageTemplate()) flags := logsCommand.Flags() flags.BoolVar(&logsCommand.Details, "details", false, "Show extra details provided to the logs") flags.BoolVarP(&logsCommand.Follow, "follow", "f", false, "Follow log output. The default is false") @@ -43,7 +44,6 @@ func init() { flags.SetInterspersed(false) - rootCmd.AddCommand(logsCommand.Command) } func logsCmd(c *cliconfig.LogsValues) error { diff --git a/cmd/podman/main.go b/cmd/podman/main.go index 32ecaede7..f9820c075 100644 --- a/cmd/podman/main.go +++ b/cmd/podman/main.go @@ -27,6 +27,26 @@ var ( exitCode = 125 ) +// Commands that the remote and local client have +// implemented. +var mainCommands = []*cobra.Command{ + _buildCommand, + _exportCommand, + _historyCommand, + _imagesCommand, + _importCommand, + _infoCommand, + _inspectCommand, + _killCommand, + _pullCommand, + _pushCommand, + _rmiCommand, + _tagCommand, + _versionCommand, + imageCommand.Command, + systemCommand.Command, +} + var cmdsNotRequiringRootless = map[*cobra.Command]bool{ _versionCommand: true, _createCommand: true, @@ -40,7 +60,7 @@ var cmdsNotRequiringRootless = map[*cobra.Command]bool{ _killCommand: true, _pauseCommand: true, _restartCommand: true, - _runCommmand: true, + _runCommand: true, _unpauseCommand: true, _searchCommand: true, _statsCommand: true, @@ -92,6 +112,8 @@ func init() { rootCmd.PersistentFlags().BoolVar(&MainGlobalOpts.Syslog, "syslog", false, "Output logging information to syslog as well as the console") rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.TmpDir, "tmpdir", "", "Path to the tmp directory") + rootCmd.AddCommand(mainCommands...) + rootCmd.AddCommand(getMainCommands()...) } func initConfig() { @@ -185,7 +207,7 @@ func main() { exitCode = status.ExitStatus() } } - fmt.Fprintln(os.Stderr, err.Error()) + fmt.Fprintln(os.Stderr, "Error:", err.Error()) } } else { // The exitCode modified from 125, indicates an application diff --git a/cmd/podman/mount.go b/cmd/podman/mount.go index 36ca8bcfb..ce7c22d60 100644 --- a/cmd/podman/mount.go +++ b/cmd/podman/mount.go @@ -39,13 +39,13 @@ var ( func init() { mountCommand.Command = _mountCommand + mountCommand.SetUsageTemplate(UsageTemplate()) flags := mountCommand.Flags() flags.BoolVarP(&mountCommand.All, "all", "a", false, "Mount all containers") flags.StringVar(&mountCommand.Format, "format", "", "Change the output format to Go template") flags.BoolVarP(&mountCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") flags.BoolVar(&mountCommand.NoTrunc, "notruncate", false, "Do not truncate output") - rootCmd.AddCommand(mountCommand.Command) } // jsonMountPoint stores info about each container diff --git a/cmd/podman/pause.go b/cmd/podman/pause.go index 466a3b136..a840cbe49 100644 --- a/cmd/podman/pause.go +++ b/cmd/podman/pause.go @@ -34,10 +34,10 @@ var ( func init() { pauseCommand.Command = _pauseCommand + pauseCommand.SetUsageTemplate(UsageTemplate()) flags := pauseCommand.Flags() flags.BoolVarP(&pauseCommand.All, "all", "a", false, "Pause all running containers") - rootCmd.AddCommand(pauseCommand.Command) } func pauseCmd(c *cliconfig.PauseValues) error { diff --git a/cmd/podman/play.go b/cmd/podman/play.go index ff8320a6b..495a1f170 100644 --- a/cmd/podman/play.go +++ b/cmd/podman/play.go @@ -5,19 +5,18 @@ import ( "github.com/spf13/cobra" ) -var playCommand cliconfig.PodmanCommand - -func init() { - var playDescription = "Play a pod and its containers from a structured file." - playCommand.Command = &cobra.Command{ +var ( + playCommand cliconfig.PodmanCommand + playDescription = "Play a pod and its containers from a structured file." + _playCommand = &cobra.Command{ Use: "play", Short: "Play a pod", Long: playDescription, } - -} +) func init() { + playCommand.Command = _playCommand + playCommand.SetUsageTemplate(UsageTemplate()) playCommand.AddCommand(getPlaySubCommands()...) - rootCmd.AddCommand(playCommand.Command) } diff --git a/cmd/podman/play_kube.go b/cmd/podman/play_kube.go index b314c1278..4ecd30cd4 100644 --- a/cmd/podman/play_kube.go +++ b/cmd/podman/play_kube.go @@ -43,6 +43,7 @@ var ( func init() { playKubeCommand.Command = _playKubeCommand + playKubeCommand.SetUsageTemplate(UsageTemplate()) flags := playKubeCommand.Flags() flags.StringVar(&playKubeCommand.Authfile, "authfile", "", "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json. Use REGISTRY_AUTH_FILE environment variable to override") flags.StringVar(&playKubeCommand.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys") diff --git a/cmd/podman/pod.go b/cmd/podman/pod.go index 4104c39c7..e988875ab 100644 --- a/cmd/podman/pod.go +++ b/cmd/podman/pod.go @@ -20,5 +20,5 @@ var podCommand = cliconfig.PodmanCommand{ func init() { podCommand.AddCommand(getPodSubCommands()...) - rootCmd.AddCommand(podCommand.Command) + podCommand.SetUsageTemplate(UsageTemplate()) } diff --git a/cmd/podman/pod_create.go b/cmd/podman/pod_create.go index 35e58df31..0a0b86aab 100644 --- a/cmd/podman/pod_create.go +++ b/cmd/podman/pod_create.go @@ -38,6 +38,7 @@ var ( func init() { podCreateCommand.Command = _podCreateCommand + podCreateCommand.SetUsageTemplate(UsageTemplate()) flags := podCreateCommand.Flags() flags.SetInterspersed(false) diff --git a/cmd/podman/pod_inspect.go b/cmd/podman/pod_inspect.go index f4c357e96..a0b691642 100644 --- a/cmd/podman/pod_inspect.go +++ b/cmd/podman/pod_inspect.go @@ -29,6 +29,7 @@ var ( func init() { podInspectCommand.Command = _podInspectCommand + podInspectCommand.SetUsageTemplate(UsageTemplate()) flags := podInspectCommand.Flags() flags.BoolVarP(&podInspectCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") diff --git a/cmd/podman/pod_kill.go b/cmd/podman/pod_kill.go index 43411a988..febc820cd 100644 --- a/cmd/podman/pod_kill.go +++ b/cmd/podman/pod_kill.go @@ -30,6 +30,7 @@ var ( func init() { podKillCommand.Command = _podKillCommand + podKillCommand.SetUsageTemplate(UsageTemplate()) flags := podKillCommand.Flags() flags.BoolVarP(&podKillCommand.All, "all", "a", false, "Kill all containers in all pods") flags.BoolVarP(&podKillCommand.Latest, "latest", "l", false, "Act on the latest pod podman is aware of") diff --git a/cmd/podman/pod_pause.go b/cmd/podman/pod_pause.go index a54783d88..2059727ae 100644 --- a/cmd/podman/pod_pause.go +++ b/cmd/podman/pod_pause.go @@ -27,6 +27,7 @@ var ( func init() { podPauseCommand.Command = _podPauseCommand + podPauseCommand.SetUsageTemplate(UsageTemplate()) flags := podPauseCommand.Flags() flags.BoolVarP(&podPauseCommand.All, "all", "a", false, "Pause all running pods") flags.BoolVarP(&podPauseCommand.Latest, "latest", "l", false, "Act on the latest pod podman is aware of") diff --git a/cmd/podman/pod_ps.go b/cmd/podman/pod_ps.go index 991e294bf..49af91a1e 100644 --- a/cmd/podman/pod_ps.go +++ b/cmd/podman/pod_ps.go @@ -131,6 +131,7 @@ var ( func init() { podPsCommand.Command = _podPsCommand + podPsCommand.SetUsageTemplate(UsageTemplate()) flags := podPsCommand.Flags() flags.BoolVar(&podPsCommand.CtrNames, "ctr-names", false, "Display the container names") flags.BoolVar(&podPsCommand.CtrIDs, "ctr-ids", false, "Display the container UUIDs. If no-trunc is not set they will be truncated") diff --git a/cmd/podman/pod_restart.go b/cmd/podman/pod_restart.go index 4d05205ea..f75d84956 100644 --- a/cmd/podman/pod_restart.go +++ b/cmd/podman/pod_restart.go @@ -28,6 +28,7 @@ var ( func init() { podRestartCommand.Command = _podRestartCommand + podRestartCommand.SetUsageTemplate(UsageTemplate()) flags := podRestartCommand.Flags() flags.BoolVarP(&podRestartCommand.All, "all", "a", false, "Restart all running pods") flags.BoolVarP(&podRestartCommand.Latest, "latest", "l", false, "Restart the latest pod podman is aware of") diff --git a/cmd/podman/pod_rm.go b/cmd/podman/pod_rm.go index 445a641df..389f44a20 100644 --- a/cmd/podman/pod_rm.go +++ b/cmd/podman/pod_rm.go @@ -32,6 +32,7 @@ If --force is specified, all containers will be stopped, then removed. func init() { podRmCommand.Command = _podRmCommand + podRmCommand.SetUsageTemplate(UsageTemplate()) flags := podRmCommand.Flags() flags.BoolVarP(&podRmCommand.All, "all", "a", false, "Remove all running pods") flags.BoolVarP(&podRmCommand.Force, "force", "f", false, "Force removal of a running pod by first stopping all containers, then removing all containers in the pod. The default is false") diff --git a/cmd/podman/pod_start.go b/cmd/podman/pod_start.go index 8b35d3e04..829fe2107 100644 --- a/cmd/podman/pod_start.go +++ b/cmd/podman/pod_start.go @@ -32,6 +32,7 @@ var ( func init() { podStartCommand.Command = _podStartCommand + podStartCommand.SetUsageTemplate(UsageTemplate()) flags := podStartCommand.Flags() flags.BoolVarP(&podStartCommand.All, "all", "a", false, "Start all pods") flags.BoolVarP(&podStartCommand.Latest, "latest", "l", false, "Start the latest pod podman is aware of") diff --git a/cmd/podman/pod_stats.go b/cmd/podman/pod_stats.go index 02dee68ac..7afab6be9 100644 --- a/cmd/podman/pod_stats.go +++ b/cmd/podman/pod_stats.go @@ -38,6 +38,7 @@ var ( func init() { podStatsCommand.Command = _podStatsCommand + podStatsCommand.SetUsageTemplate(UsageTemplate()) flags := podStatsCommand.Flags() flags.BoolVarP(&podStatsCommand.All, "all", "a", false, "Provide stats for all running pods") flags.StringVar(&podStatsCommand.Format, "format", "", "Pretty-print container statistics to JSON or using a Go template") diff --git a/cmd/podman/pod_stop.go b/cmd/podman/pod_stop.go index 63bd0f5cb..80082045d 100644 --- a/cmd/podman/pod_stop.go +++ b/cmd/podman/pod_stop.go @@ -33,6 +33,7 @@ var ( func init() { podStopCommand.Command = _podStopCommand + podStopCommand.SetUsageTemplate(UsageTemplate()) flags := podStopCommand.Flags() flags.BoolVarP(&podStopCommand.All, "all", "a", false, "Stop all running pods") flags.BoolVarP(&podStopCommand.Latest, "latest", "l", false, "Stop the latest pod podman is aware of") diff --git a/cmd/podman/pod_top.go b/cmd/podman/pod_top.go index f1db2fac5..411c782bd 100644 --- a/cmd/podman/pod_top.go +++ b/cmd/podman/pod_top.go @@ -39,6 +39,7 @@ the latest pod. func init() { podTopCommand.Command = _podTopCommand + podTopCommand.SetUsageTemplate(UsageTemplate()) flags := podTopCommand.Flags() flags.BoolVarP(&podTopCommand.Latest, "latest,", "l", false, "Act on the latest pod podman is aware of") flags.BoolVar(&podTopCommand.ListDescriptors, "list-descriptors", false, "") diff --git a/cmd/podman/pod_unpause.go b/cmd/podman/pod_unpause.go index 17b771d4a..a917919c3 100644 --- a/cmd/podman/pod_unpause.go +++ b/cmd/podman/pod_unpause.go @@ -28,6 +28,7 @@ var ( func init() { podUnpauseCommand.Command = _podUnpauseCommand + podUnpauseCommand.SetUsageTemplate(UsageTemplate()) flags := podUnpauseCommand.Flags() flags.BoolVarP(&podUnpauseCommand.All, "all", "a", false, "Unpause all running pods") flags.BoolVarP(&podUnpauseCommand.Latest, "latest", "l", false, "Unpause the latest pod podman is aware of") diff --git a/cmd/podman/port.go b/cmd/podman/port.go index 488ef2ffe..be84da065 100644 --- a/cmd/podman/port.go +++ b/cmd/podman/port.go @@ -34,12 +34,12 @@ var ( func init() { portCommand.Command = _portCommand + portCommand.SetUsageTemplate(UsageTemplate()) flags := portCommand.Flags() flags.BoolVarP(&portCommand.All, "all", "a", false, "Display port information for all containers") flags.BoolVarP(&portCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - rootCmd.AddCommand(portCommand.Command) } func portCmd(c *cliconfig.PortValues) error { @@ -125,8 +125,13 @@ func portCmd(c *cliconfig.PortValues) error { if c.All { fmt.Println(con.ID()) } + + portmappings, err := con.PortMappings() + if err != nil { + return err + } // Iterate mappings - for _, v := range con.Config().PortMappings { + for _, v := range portmappings { hostIP := v.HostIP // Set host IP to 0.0.0.0 if blank if hostIP == "" { diff --git a/cmd/podman/ps.go b/cmd/podman/ps.go index 002975b87..949f78a34 100644 --- a/cmd/podman/ps.go +++ b/cmd/podman/ps.go @@ -172,6 +172,7 @@ var ( func init() { psCommand.Command = _psCommand + psCommand.SetUsageTemplate(UsageTemplate()) flags := psCommand.Flags() flags.BoolVarP(&psCommand.All, "all", "a", false, "Show all the containers, default is only running containers") flags.StringSliceVarP(&psCommand.Filter, "filter", "f", []string{}, "Filter output based on conditions given") @@ -187,9 +188,8 @@ func init() { flags.StringVar(&psCommand.Sort, "sort", "created", "Sort output by command, created, id, image, names, runningfor, size, or status") flags.BoolVar(&psCommand.Sync, "sync", false, "Sync container state with OCI runtime") - rootCmd.AddCommand(psCommand.Command) - } + func psCmd(c *cliconfig.PsValues) error { var ( filterFuncs []libpod.ContainerFilter diff --git a/cmd/podman/pull.go b/cmd/podman/pull.go index d70719164..6d9d1a278 100644 --- a/cmd/podman/pull.go +++ b/cmd/podman/pull.go @@ -40,6 +40,7 @@ specified, the image with the 'latest' tag (if it exists) is pulled func init() { pullCommand.Command = _pullCommand + pullCommand.SetUsageTemplate(UsageTemplate()) flags := pullCommand.Flags() flags.StringVar(&pullCommand.Authfile, "authfile", "", "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json. Use REGISTRY_AUTH_FILE environment variable to override") flags.StringVar(&pullCommand.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys") @@ -48,7 +49,6 @@ func init() { flags.StringVar(&pullCommand.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)") flags.BoolVar(&pullCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries (default: true)") - rootCmd.AddCommand(pullCommand.Command) } // pullCmd gets the data from the command line and calls pullImage diff --git a/cmd/podman/push.go b/cmd/podman/push.go index a1ee00a65..bbe8a4027 100644 --- a/cmd/podman/push.go +++ b/cmd/podman/push.go @@ -2,8 +2,6 @@ package main import ( "fmt" - "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/spf13/cobra" "io" "os" "strings" @@ -11,11 +9,13 @@ import ( "github.com/containers/image/directory" "github.com/containers/image/manifest" "github.com/containers/image/types" - "github.com/containers/libpod/cmd/podman/libpodruntime" + "github.com/containers/libpod/cmd/podman/cliconfig" + "github.com/containers/libpod/libpod/adapter" "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/util" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" + "github.com/spf13/cobra" ) var ( @@ -40,6 +40,7 @@ var ( func init() { pushCommand.Command = _pushCommand + pushCommand.SetUsageTemplate(UsageTemplate()) flags := pushCommand.Flags() flags.MarkHidden("signature-policy") flags.StringVar(&pushCommand.Authfile, "authfile", "", "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json. Use REGISTRY_AUTH_FILE environment variable to override") @@ -52,7 +53,6 @@ func init() { flags.StringVar(&pushCommand.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)") flags.StringVar(&pushCommand.SignBy, "sign-by", "", "Add a signature at the destination using the specified key") flags.BoolVar(&pushCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries (default: true)") - rootCmd.AddCommand(pushCommand.Command) } func pushCmd(c *cliconfig.PushValues) error { @@ -93,7 +93,7 @@ func pushCmd(c *cliconfig.PushValues) error { registryCreds = creds } - runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand) + runtime, err := adapter.GetRuntime(&c.PodmanCommand) if err != nil { return errors.Wrapf(err, "could not create runtime") } @@ -131,12 +131,7 @@ func pushCmd(c *cliconfig.PushValues) error { SignBy: signBy, } - newImage, err := runtime.ImageRuntime().NewFromLocal(srcName) - if err != nil { - return err - } - authfile := getAuthFile(c.Authfile) - return newImage.PushImageToHeuristicDestination(getContext(), destName, manifestType, authfile, c.SignaturePolicy, writer, c.Compress, so, &dockerRegistryOptions, nil) + return runtime.Push(getContext(), srcName, destName, manifestType, authfile, c.SignaturePolicy, writer, c.Compress, so, &dockerRegistryOptions, nil) } diff --git a/cmd/podman/refresh.go b/cmd/podman/refresh.go index 3890188b4..641748452 100644 --- a/cmd/podman/refresh.go +++ b/cmd/podman/refresh.go @@ -27,7 +27,7 @@ var ( func init() { refreshCommand.Command = _refreshCommand - rootCmd.AddCommand(refreshCommand.Command) + refreshCommand.SetUsageTemplate(UsageTemplate()) } func refreshCmd(c *cliconfig.RefreshValues) error { diff --git a/cmd/podman/restart.go b/cmd/podman/restart.go index f94e745ed..235107b5c 100644 --- a/cmd/podman/restart.go +++ b/cmd/podman/restart.go @@ -32,6 +32,7 @@ var ( func init() { restartCommand.Command = _restartCommand + restartCommand.SetUsageTemplate(UsageTemplate()) flags := restartCommand.Flags() flags.BoolVarP(&restartCommand.All, "all", "a", false, "Restart all non-running containers") flags.BoolVarP(&restartCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") @@ -39,7 +40,6 @@ func init() { flags.UintVarP(&restartCommand.Timeout, "timeout", "t", libpod.CtrRemoveTimeout, "Seconds to wait for stop before killing the container") flags.UintVar(&restartCommand.Timeout, "time", libpod.CtrRemoveTimeout, "Seconds to wait for stop before killing the container") - rootCmd.AddCommand(restartCommand.Command) } func restartCmd(c *cliconfig.RestartValues) error { diff --git a/cmd/podman/restore.go b/cmd/podman/restore.go index daee635f0..556cdb774 100644 --- a/cmd/podman/restore.go +++ b/cmd/podman/restore.go @@ -35,6 +35,7 @@ var ( func init() { restoreCommand.Command = _restoreCommand + restoreCommand.SetUsageTemplate(UsageTemplate()) flags := restoreCommand.Flags() flags.BoolVarP(&restoreCommand.All, "all", "a", false, "Restore all checkpointed containers") flags.BoolVarP(&restoreCommand.Keep, "keep", "k", false, "Keep all temporary checkpoint files") @@ -42,7 +43,6 @@ func init() { // TODO: add ContainerStateCheckpointed flags.BoolVar(&restoreCommand.TcpEstablished, "tcp-established", false, "Checkpoint a container with established TCP connections") - rootCmd.AddCommand(restoreCommand.Command) } func restoreCmd(c *cliconfig.RestoreValues) error { diff --git a/cmd/podman/rm.go b/cmd/podman/rm.go index bb9a913c9..d170e5357 100644 --- a/cmd/podman/rm.go +++ b/cmd/podman/rm.go @@ -6,6 +6,7 @@ import ( "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/cmd/podman/shared" + "github.com/containers/libpod/libpod" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -33,13 +34,12 @@ Running containers will not be removed without the -f option. func init() { rmCommand.Command = _rmCommand + rmCommand.SetUsageTemplate(UsageTemplate()) flags := rmCommand.Flags() flags.BoolVarP(&rmCommand.All, "all", "a", false, "Remove all containers") flags.BoolVarP(&rmCommand.Force, "force", "f", false, "Force removal of a running container. The default is false") flags.BoolVarP(&rmCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - flags.BoolVarP(&rmCommand.Volumes, "volumes", "v", false, "Remove the volumes associated with the container (Not implemented yet)") - - rootCmd.AddCommand(rmCommand.Command) + flags.BoolVarP(&rmCommand.Volumes, "volumes", "v", false, "Remove the volumes associated with the container") } // saveCmd saves the image to either docker-archive or oci @@ -61,16 +61,24 @@ func rmCmd(c *cliconfig.RmValues) error { delContainers, err := getAllOrLatestContainers(&c.PodmanCommand, runtime, -1, "all") if err != nil { + if c.Force && len(c.InputArgs) > 0 { + if errors.Cause(err) == libpod.ErrNoSuchCtr { + err = nil + } + runtime.RemoveContainersFromStorage(c.InputArgs) + } if len(delContainers) == 0 { return err } - fmt.Println(err.Error()) + if err != nil { + fmt.Println(err.Error()) + } } for _, container := range delContainers { con := container f := func() error { - return runtime.RemoveContainer(ctx, con, c.Force) + return runtime.RemoveContainer(ctx, con, c.Force, c.Volumes) } deleteFuncs = append(deleteFuncs, shared.ParallelWorkerInput{ diff --git a/cmd/podman/rmi.go b/cmd/podman/rmi.go index 70f58e844..c5bd1e190 100644 --- a/cmd/podman/rmi.go +++ b/cmd/podman/rmi.go @@ -29,11 +29,10 @@ var ( func init() { rmiCommand.Command = _rmiCommand + rmiCommand.SetUsageTemplate(UsageTemplate()) flags := rmiCommand.Flags() flags.BoolVarP(&rmiCommand.All, "all", "a", false, "Remove all images") flags.BoolVarP(&rmiCommand.Force, "force", "f", false, "Force Removal of the image") - - rootCmd.AddCommand(rmiCommand.Command) } func rmiCmd(c *cliconfig.RmiValues) error { diff --git a/cmd/podman/run.go b/cmd/podman/run.go index 76b29cb84..64f8b6856 100644 --- a/cmd/podman/run.go +++ b/cmd/podman/run.go @@ -18,30 +18,29 @@ import ( ) var ( - runCommmand cliconfig.RunValues + runCommand cliconfig.RunValues runDescription = "Runs a command in a new container from the given image" - _runCommmand = &cobra.Command{ + _runCommand = &cobra.Command{ Use: "run", Short: "Run a command in a new container", Long: runDescription, RunE: func(cmd *cobra.Command, args []string) error { - runCommmand.InputArgs = args - runCommmand.GlobalFlags = MainGlobalOpts - return runCmd(&runCommmand) + runCommand.InputArgs = args + runCommand.GlobalFlags = MainGlobalOpts + return runCmd(&runCommand) }, Example: "IMAGE [COMMAND [ARG...]]", } ) func init() { - runCommmand.Command = _runCommmand - flags := runCommmand.Flags() + runCommand.Command = _runCommand + runCommand.SetUsageTemplate(UsageTemplate()) + flags := runCommand.Flags() flags.SetInterspersed(false) flags.Bool("sig-proxy", true, "Proxy received signals to the process (default true)") - getCreateFlags(&runCommmand.PodmanCommand) - - rootCmd.AddCommand(runCommmand.Command) + getCreateFlags(&runCommand.PodmanCommand) } func runCmd(c *cliconfig.RunValues) error { @@ -119,13 +118,21 @@ func runCmd(c *cliconfig.RunValues) error { } } if err := startAttachCtr(ctr, outputStream, errorStream, inputStream, c.String("detach-keys"), c.Bool("sig-proxy"), true); err != nil { + // We've manually detached from the container + // Do not perform cleanup, or wait for container exit code + // Just exit immediately + if errors.Cause(err) == libpod.ErrDetach { + exitCode = 0 + return nil + } + // This means the command did not exist exitCode = 127 if strings.Index(err.Error(), "permission denied") > -1 { exitCode = 126 } if c.IsSet("rm") { - if deleteError := runtime.RemoveContainer(ctx, ctr, true); deleteError != nil { + if deleteError := runtime.RemoveContainer(ctx, ctr, true, false); deleteError != nil { logrus.Errorf("unable to remove container %s after failing to start and attach to it", ctr.ID()) } } @@ -148,28 +155,12 @@ func runCmd(c *cliconfig.RunValues) error { exitCode = int(ecode) } - if createConfig.Rm { - return runtime.RemoveContainer(ctx, ctr, true) - } - - if err := ctr.Cleanup(ctx); err != nil { - // If the container has been removed already, no need to error on cleanup - // Also, if it was restarted, don't error either - if errors.Cause(err) == libpod.ErrNoSuchCtr || - errors.Cause(err) == libpod.ErrCtrRemoved || - errors.Cause(err) == libpod.ErrCtrStateInvalid { - return nil - } - - return err - } - return nil } // Read a container's exit file func readExitFile(runtimeTmp, ctrID string) (int, error) { - exitFile := filepath.Join(runtimeTmp, "exits", ctrID) + exitFile := filepath.Join(runtimeTmp, "exits", fmt.Sprintf("%s-old", ctrID)) logrus.Debugf("Attempting to read container %s exit code from file %s", ctrID, exitFile) diff --git a/cmd/podman/runlabel.go b/cmd/podman/runlabel.go index ff8a282d3..f1c61ebda 100644 --- a/cmd/podman/runlabel.go +++ b/cmd/podman/runlabel.go @@ -37,6 +37,7 @@ Executes a command as described by a container image label. func init() { runlabelCommand.Command = _runlabelCommand + runlabelCommand.SetUsageTemplate(UsageTemplate()) flags := runlabelCommand.Flags() flags.StringVar(&runlabelCommand.Authfile, "authfile", "", "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json. Use REGISTRY_AUTH_FILE environment variable to override") flags.StringVar(&runlabelCommand.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys") diff --git a/cmd/podman/save.go b/cmd/podman/save.go index 766561f1a..1ae1bc872 100644 --- a/cmd/podman/save.go +++ b/cmd/podman/save.go @@ -47,13 +47,12 @@ var ( func init() { saveCommand.Command = _saveCommand + saveCommand.SetUsageTemplate(UsageTemplate()) flags := saveCommand.Flags() flags.BoolVar(&saveCommand.Compress, "compress", false, "Compress tarball image layers when saving to a directory using the 'dir' transport. (default is same compression type as source)") flags.StringVar(&saveCommand.Format, "format", "", "Save image to oci-archive, oci-dir (directory with oci manifest type), docker-dir (directory with v2s2 manifest type)") flags.StringVarP(&saveCommand.Output, "output", "o", "/dev/stdout", "Write to a file, default is STDOUT") flags.BoolVarP(&saveCommand.Quiet, "quiet", "q", false, "Suppress the output") - - rootCmd.AddCommand(saveCommand.Command) } // saveCmd saves the image to either docker-archive or oci diff --git a/cmd/podman/search.go b/cmd/podman/search.go index b15da1f6d..2febee689 100644 --- a/cmd/podman/search.go +++ b/cmd/podman/search.go @@ -43,6 +43,7 @@ var ( func init() { searchCommand.Command = _searchCommand + searchCommand.SetUsageTemplate(UsageTemplate()) flags := searchCommand.Flags() flags.StringVar(&searchCommand.Authfile, "authfile", "", "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json. Use REGISTRY_AUTH_FILE environment variable to override") flags.StringSliceVarP(&searchCommand.Filter, "filter", "f", []string{}, "Filter output based on conditions provided (default [])") @@ -50,8 +51,6 @@ func init() { flags.IntVar(&searchCommand.Limit, "limit", 0, "Limit the number of results") flags.BoolVar(&searchCommand.NoTrunc, "no-trunc", false, "Do not truncate the output") flags.BoolVar(&searchCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries (default: true)") - - rootCmd.AddCommand(searchCommand.Command) } type searchParams struct { diff --git a/cmd/podman/shared/container.go b/cmd/podman/shared/container.go index c74d8fdce..81811e0f2 100644 --- a/cmd/podman/shared/container.go +++ b/cmd/podman/shared/container.go @@ -213,11 +213,16 @@ func NewBatchContainer(ctr *libpod.Container, opts PsOptions) (PsContainerOutput } } + ports, err := ctr.PortMappings() + if err != nil { + logrus.Errorf("unable to lookup namespace container for %s", ctr.ID()) + } + pso.ID = cid pso.Image = imageName pso.Command = command pso.Created = created - pso.Ports = portsToString(ctr.PortMappings()) + pso.Ports = portsToString(ports) pso.Names = ctr.Name() pso.IsInfra = ctr.IsInfra() pso.Status = status diff --git a/cmd/podman/sign.go b/cmd/podman/sign.go index a87c12556..ac0d985f5 100644 --- a/cmd/podman/sign.go +++ b/cmd/podman/sign.go @@ -38,12 +38,11 @@ var ( func init() { signCommand.Command = _signCommand + signCommand.SetUsageTemplate(UsageTemplate()) flags := signCommand.Flags() flags.StringVarP(&signCommand.Directory, "directory", "d", "", "Define an alternate directory to store signatures") flags.StringVar(&signCommand.SignBy, "sign-by", "", "Name of the signing key") - rootCmd.AddCommand(signCommand.Command) - } // SignatureStoreDir defines default directory to store signatures diff --git a/cmd/podman/start.go b/cmd/podman/start.go index 483ab4081..3a606d662 100644 --- a/cmd/podman/start.go +++ b/cmd/podman/start.go @@ -36,14 +36,13 @@ var ( func init() { startCommand.Command = _startCommand + startCommand.SetUsageTemplate(UsageTemplate()) flags := startCommand.Flags() flags.BoolVarP(&startCommand.Attach, "attach", "a", false, "Attach container's STDOUT and STDERR") flags.StringVar(&startCommand.DetachKeys, "detach-keys", "", "Override the key sequence for detaching a container. Format is a single character [a-Z] or ctrl-<value> where <value> is one of: a-z, @, ^, [, , or _") flags.BoolVarP(&startCommand.Interactive, "interactive", "i", false, "Keep STDIN open even if not attached") flags.BoolVarP(&startCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") flags.BoolVar(&startCommand.SigProxy, "sig-proxy", true, "Proxy received signals to the process (default true if attaching, false otherwise)") - - rootCmd.AddCommand(startCommand.Command) } func startCmd(c *cliconfig.StartValues) error { @@ -109,6 +108,13 @@ func startCmd(c *cliconfig.StartValues) error { // attach to the container and also start it not already running err = startAttachCtr(ctr, os.Stdout, os.Stderr, inputStream, c.DetachKeys, sigProxy, !ctrRunning) + if errors.Cause(err) == libpod.ErrDetach { + // User manually detached + // Exit cleanly immediately + exitCode = 0 + return nil + } + if ctrRunning { return err } @@ -138,7 +144,7 @@ func startCmd(c *cliconfig.StartValues) error { logrus.Errorf("unable to detect if container %s should be deleted", ctr.ID()) } if createArtifact.Rm { - if rmErr := runtime.RemoveContainer(ctx, ctr, true); rmErr != nil { + if rmErr := runtime.RemoveContainer(ctx, ctr, true, false); rmErr != nil { logrus.Errorf("unable to remove container %s after it failed to start", ctr.ID()) } } diff --git a/cmd/podman/stats.go b/cmd/podman/stats.go index 8c79ed290..af9bbad0e 100644 --- a/cmd/podman/stats.go +++ b/cmd/podman/stats.go @@ -47,14 +47,13 @@ var ( func init() { statsCommand.Command = _statsCommand + statsCommand.SetUsageTemplate(UsageTemplate()) flags := statsCommand.Flags() flags.BoolVarP(&statsCommand.All, "all", "a", false, "Show all containers. Only running containers are shown by default. The default is false") flags.StringVar(&statsCommand.Format, "format", "", "Pretty-print container statistics to JSON or using a Go template") flags.BoolVarP(&statsCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") flags.BoolVar(&statsCommand.NoReset, "no-reset", false, "Disable resetting the screen between intervals") flags.BoolVar(&statsCommand.NoStream, "no-stream", false, "Disable streaming stats and only pull the first result, default setting is false") - - rootCmd.AddCommand(statsCommand.Command) } func statsCmd(c *cliconfig.StatsValues) error { diff --git a/cmd/podman/stop.go b/cmd/podman/stop.go index e2c16fe20..134d8a069 100644 --- a/cmd/podman/stop.go +++ b/cmd/podman/stop.go @@ -37,13 +37,12 @@ var ( func init() { stopCommand.Command = _stopCommand + stopCommand.SetUsageTemplate(UsageTemplate()) flags := stopCommand.Flags() flags.BoolVarP(&stopCommand.All, "all", "a", false, "Stop all running containers") flags.BoolVarP(&stopCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") flags.UintVar(&stopCommand.Timeout, "time", libpod.CtrRemoveTimeout, "Seconds to wait for stop before killing the container") flags.UintVarP(&stopCommand.Timeout, "timeout", "t", libpod.CtrRemoveTimeout, "Seconds to wait for stop before killing the container") - - rootCmd.AddCommand(stopCommand.Command) } func stopCmd(c *cliconfig.StopValues) error { diff --git a/cmd/podman/system.go b/cmd/podman/system.go index f6b28fee1..741b79da5 100644 --- a/cmd/podman/system.go +++ b/cmd/podman/system.go @@ -17,7 +17,12 @@ var ( } ) +var systemCommands = []*cobra.Command{ + _infoCommand, +} + func init() { + systemCommand.AddCommand(systemCommands...) systemCommand.AddCommand(getSystemSubCommands()...) - rootCmd.AddCommand(systemCommand.Command) + systemCommand.SetUsageTemplate(UsageTemplate()) } diff --git a/cmd/podman/system_prune.go b/cmd/podman/system_prune.go index c918fbe3b..a91d7bf0a 100644 --- a/cmd/podman/system_prune.go +++ b/cmd/podman/system_prune.go @@ -34,8 +34,8 @@ var ( ) func init() { - pruneSystemCommand.Command = _pruneSystemCommand + pruneSystemCommand.SetUsageTemplate(UsageTemplate()) flags := pruneSystemCommand.Flags() flags.BoolVarP(&pruneSystemCommand.All, "all", "a", false, "Remove all unused data") flags.BoolVarP(&pruneSystemCommand.Force, "force", "f", false, "Do not prompt for confirmation") @@ -76,7 +76,7 @@ Are you sure you want to continue? [y/N] `, volumeString) ctx := getContext() fmt.Println("Deleted Containers") - lasterr := pruneContainers(runtime, ctx, shared.Parallelize("rm"), false) + lasterr := pruneContainers(runtime, ctx, shared.Parallelize("rm"), false, false) if c.Bool("volumes") { fmt.Println("Deleted Volumes") err := volumePrune(runtime, getContext()) diff --git a/cmd/podman/tag.go b/cmd/podman/tag.go index 2c7cf4abb..135c2f7a0 100644 --- a/cmd/podman/tag.go +++ b/cmd/podman/tag.go @@ -26,8 +26,7 @@ var ( func init() { tagCommand.Command = _tagCommand - rootCmd.AddCommand(tagCommand.Command) - + tagCommand.SetUsageTemplate(UsageTemplate()) } func tagCmd(c *cliconfig.TagValues) error { diff --git a/cmd/podman/top.go b/cmd/podman/top.go index a03830ee5..51b813e5a 100644 --- a/cmd/podman/top.go +++ b/cmd/podman/top.go @@ -48,12 +48,11 @@ the latest container. func init() { topCommand.Command = _topCommand + topCommand.SetUsageTemplate(UsageTemplate()) flags := topCommand.Flags() flags.BoolVar(&topCommand.ListDescriptors, "list-descriptors", false, "") flags.MarkHidden("list-descriptors") flags.BoolVarP(&topCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - - rootCmd.AddCommand(topCommand.Command) } func topCmd(c *cliconfig.TopValues) error { diff --git a/cmd/podman/trust.go b/cmd/podman/trust.go index 6304586c3..8b02dcdc6 100644 --- a/cmd/podman/trust.go +++ b/cmd/podman/trust.go @@ -16,6 +16,7 @@ var ( ) func init() { + trustCommand.SetUsageTemplate(UsageTemplate()) trustCommand.AddCommand(getTrustSubCommands()...) imageCommand.AddCommand(trustCommand.Command) } diff --git a/cmd/podman/trust_set_show.go b/cmd/podman/trust_set_show.go index cd9438220..f3d1cadce 100644 --- a/cmd/podman/trust_set_show.go +++ b/cmd/podman/trust_set_show.go @@ -49,9 +49,10 @@ var ( ) func init() { - setTrustCommand.Command = _setTrustCommand + setTrustCommand.SetUsageTemplate(UsageTemplate()) showTrustCommand.Command = _showTrustCommand + showTrustCommand.SetUsageTemplate(UsageTemplate()) setFlags := setTrustCommand.Flags() setFlags.StringVar(&setTrustCommand.PolicyPath, "policypath", "", "") setFlags.MarkHidden("policypath") diff --git a/cmd/podman/umount.go b/cmd/podman/umount.go index 4622e8276..20ea410c2 100644 --- a/cmd/podman/umount.go +++ b/cmd/podman/umount.go @@ -37,12 +37,11 @@ An unmount can be forced with the --force flag. func init() { umountCommand.Command = _umountCommand + umountCommand.SetUsageTemplate(UsageTemplate()) flags := umountCommand.Flags() flags.BoolVarP(&umountCommand.All, "all", "a", false, "Umount all of the currently mounted containers") flags.BoolVarP(&umountCommand.Force, "force", "f", false, "Force the complete umount all of the currently mounted containers") flags.BoolVarP(&umountCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - - rootCmd.AddCommand(umountCommand.Command) } func umountCmd(c *cliconfig.UmountValues) error { diff --git a/cmd/podman/unpause.go b/cmd/podman/unpause.go index fb3a7b57a..c8f85cfd3 100644 --- a/cmd/podman/unpause.go +++ b/cmd/podman/unpause.go @@ -35,10 +35,9 @@ var ( func init() { unpauseCommand.Command = _unpauseCommand + unpauseCommand.SetUsageTemplate(UsageTemplate()) flags := unpauseCommand.Flags() flags.BoolVarP(&unpauseCommand.All, "all", "a", false, "Unpause all paused containers") - - rootCmd.AddCommand(unpauseCommand.Command) } func unpauseCmd(c *cliconfig.UnpauseValues) error { diff --git a/cmd/podman/varlink.go b/cmd/podman/varlink.go index 2b76e034e..ce54cfa85 100644 --- a/cmd/podman/varlink.go +++ b/cmd/podman/varlink.go @@ -1,4 +1,4 @@ -// +build varlink +// +build varlink,!remoteclient package main @@ -38,10 +38,9 @@ var ( func init() { varlinkCommand.Command = _varlinkCommand + varlinkCommand.SetUsageTemplate(UsageTemplate()) flags := varlinkCommand.Flags() flags.Int64VarP(&varlinkCommand.Timeout, "timeout", "t", 1000, "Time until the varlink session expires in milliseconds. Use 0 to disable the timeout") - - rootCmd.AddCommand(varlinkCommand.Command) } func varlinkCmd(c *cliconfig.VarlinkValues) error { @@ -84,7 +83,7 @@ func varlinkCmd(c *cliconfig.VarlinkValues) error { logrus.Infof("varlink service expired (use --timeout to increase session time beyond %d ms, 0 means never timeout)", c.Int64("timeout")) return nil default: - return errors.Errorf("unable to start varlink service") + return errors.Wrapf(err, "unable to start varlink service") } } diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink index 101232b0c..3b7a11fc3 100644 --- a/cmd/podman/varlink/io.podman.varlink +++ b/cmd/podman/varlink/io.podman.varlink @@ -2,15 +2,13 @@ # in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in the upstream libpod repository. interface io.podman - -# Version is the structure returned by GetVersion -type Version ( - version: string, - go_version: string, - git_commit: string, - built: int, - os_arch: string, - remote_api_version: int +type Volume ( + name: string, + labels: [string]string, + mountPoint: string, + driver: string, + options: [string]string, + scope: string ) type NotImplemented ( @@ -20,6 +18,7 @@ type NotImplemented ( type StringResponse ( message: string ) + # ContainerChanges describes the return struct for ListContainerChanges type ContainerChanges ( changed: []string, @@ -27,14 +26,25 @@ type ContainerChanges ( deleted: []string ) -# ImageInList describes the structure that is returned in -# ListImages. -type ImageInList ( +type VolumeCreateOpts ( + volumeName: string, + driver: string, + labels: [string]string, + options: [string]string +) + +type VolumeRemoveOpts ( + volumes: []string, + all: bool, + force: bool +) + +type Image ( id: string, parentId: string, repoTags: []string, repoDigests: []string, - created: string, + created: string, # as RFC3339 size: int, virtualSize: int, containers: int, @@ -45,16 +55,15 @@ type ImageInList ( # ImageHistory describes the returned structure from ImageHistory. type ImageHistory ( id: string, - created: string, + created: string, # as RFC3339 createdBy: string, tags: []string, size: int, comment: string ) -# ImageSearch is the returned structure for SearchImage. It is returned -# in array form. -type ImageSearch ( +# Represents a single search result from SearchImages +type ImageSearchResult ( description: string, is_official: bool, is_automated: bool, @@ -62,13 +71,12 @@ type ImageSearch ( star_count: int ) -# ListContainerData is the returned struct for an individual container -type ListContainerData ( +type Container ( id: string, image: string, imageid: string, command: []string, - createdat: string, + createdat: string, # as RFC3339 runningfor: string, status: string, ports: []ContainerPortMappings, @@ -303,37 +311,54 @@ type IDMap ( size: int ) +# BuildOptions are are used to describe describe physical attributes of the build +type BuildOptions ( + addHosts: []string, + cgroupParent: string, + cpuPeriod: int, + cpuQuota: int, + cpuShares: int, + cpusetCpus: string, + cpusetMems: string, + memory: int, + memorySwap: int, + shmSize: string, + ulimit: []string, + volume: []string +) + # BuildInfo is used to describe user input for building images type BuildInfo ( - # paths to one or more dockerfiles - dockerfile: []string, - tags: []string, - add_hosts: []string, - cgroup_parent: string, - cpu_period: int, - cpu_quota: int, - cpu_shares: int, - cpuset_cpus: string, - cpuset_mems: string, - memory: string, - memory_swap: string, - security_opts: []string, - shm_size: string, - ulimit: []string, - volume: []string, - squash: bool, - pull: bool, - pull_always: bool, - force_rm: bool, - rm: bool, - label: []string, + additionalTags: []string, annotations: []string, - build_args: [string]string, - image_format: string + buildArgs: [string]string, + buildOptions: BuildOptions, + cniConfigDir: string, + cniPluginDir: string, + compression: string, + contextDir: string, + defaultsMountFilePath: string, + dockerfiles: []string, + err: string, + forceRmIntermediateCtrs: bool, + iidfile: string, + label: []string, + layers: bool, + nocache: bool, + out: string, + output: string, + outputFormat: string, + pullPolicy: string, + quiet: bool, + remoteIntermediateCtrs: bool, + reportWriter: string, + runtimeArgs: []string, + signaturePolicyPath: string, + squash: bool ) -# BuildResponse is used to describe the responses for building images -type BuildResponse ( +# MoreResponse is a struct for when responses from varlink requires longer output +type MoreResponse ( logs: []string, id: string ) @@ -393,34 +418,29 @@ type Runlabel( opts: [string]string ) -# Ping provides a response for developers to ensure their varlink setup is working. -# #### Example -# ~~~ -# $ varlink call -m unix:/run/podman/io.podman/io.podman.Ping -# { -# "ping": { -# "message": "OK" -# } -# } -# ~~~ -method Ping() -> (ping: StringResponse) - -# GetVersion returns a Version structure describing the libpod setup on their -# system. -method GetVersion() -> (version: Version) +# GetVersion returns version and build information of the podman service +method GetVersion() -> ( + version: string, + go_version: string, + git_commit: string, + built: string, # as RFC3339 + os_arch: string, + remote_api_version: int +) # GetInfo returns a [PodmanInfo](#PodmanInfo) struct that describes podman and its host such as storage stats, # build information of Podman, and system-wide registries. method GetInfo() -> (info: PodmanInfo) -# ListContainers returns a list of containers in no particular order. There are -# returned as an array of ListContainerData structs. See also [GetContainer](#GetContainer). -method ListContainers() -> (containers: []ListContainerData) +# ListContainers returns information about all containers. +# See also [GetContainer](#GetContainer). +method ListContainers() -> (containers: []Container) -# GetContainer takes a name or ID of a container and returns single ListContainerData -# structure. A [ContainerNotFound](#ContainerNotFound) error will be returned if the container cannot be found. -# See also [ListContainers](ListContainers) and [InspectContainer](#InspectContainer). -method GetContainer(name: string) -> (container: ListContainerData) +# 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 +# [InspectContainer](#InspectContainer). +method GetContainer(id: string) -> (container: Container) # CreateContainer creates a new container from an image. It uses a [Create](#Create) type for input. The minimum # input required for CreateContainer is an image name. If the image name is not found, an [ImageNotFound](#ImageNotFound) @@ -508,7 +528,7 @@ method ExportContainer(name: string, path: string) -> (tarfile: string) method GetContainerStats(name: string) -> (container: ContainerStats) # This method has not be implemented yet. -method ResizeContainerTty() -> (notimplemented: NotImplemented) +# method ResizeContainerTty() -> (notimplemented: NotImplemented) # StartContainer starts a created or stopped container. It takes the name or ID of container. It returns # the container ID once started. If the container cannot be found, a [ContainerNotFound](#ContainerNotFound) @@ -540,10 +560,10 @@ method RestartContainer(name: string, timeout: int) -> (container: string) method KillContainer(name: string, signal: int) -> (container: string) # This method has not be implemented yet. -method UpdateContainer() -> (notimplemented: NotImplemented) +# method UpdateContainer() -> (notimplemented: NotImplemented) # This method has not be implemented yet. -method RenameContainer() -> (notimplemented: NotImplemented) +# method RenameContainer() -> (notimplemented: NotImplemented) # PauseContainer takes the name or ID of container and pauses it. If the container cannot be found, # a [ContainerNotFound](#ContainerNotFound) error will be returned; otherwise the ID of the container is returned. @@ -556,7 +576,7 @@ method PauseContainer(name: string) -> (container: string) method UnpauseContainer(name: string) -> (container: string) # This method has not be implemented yet. -method AttachToContainer() -> (notimplemented: NotImplemented) +# method AttachToContainer() -> (notimplemented: NotImplemented) # GetAttachSockets takes the name or ID of an existing container. It returns file paths for two sockets needed # to properly communicate with a container. The first is the actual I/O socket that the container uses. The @@ -580,7 +600,7 @@ method GetAttachSockets(name: string) -> (sockets: Sockets) # a [ContainerNotFound](#ContainerNotFound) error is returned. method WaitContainer(name: string) -> (exitcode: int) -# RemoveContainer takes requires the name or ID of container as well a boolean representing whether a running +# RemoveContainer takes requires the name or ID of container as well a boolean representing whether a running and a boolean indicating whether to remove builtin volumes # container can be stopped and removed. Upon successful removal of the container, its ID is returned. If the # container cannot be found by name or ID, a [ContainerNotFound](#ContainerNotFound) error will be returned. # #### Example @@ -590,7 +610,7 @@ method WaitContainer(name: string) -> (exitcode: int) # "container": "62f4fd98cb57f529831e8f90610e54bba74bd6f02920ffb485e15376ed365c20" # } # ~~~ -method RemoveContainer(name: string, force: bool) -> (container: string) +method RemoveContainer(name: string, force: bool, removeVolumes: bool) -> (container: string) # DeleteStoppedContainers will delete all containers that are not running. It will return a list the deleted # container IDs. See also [RemoveContainer](RemoveContainer). @@ -608,21 +628,21 @@ method RemoveContainer(name: string, force: bool) -> (container: string) # ~~~ method DeleteStoppedContainers() -> (containers: []string) -# ListImages returns an array of ImageInList structures which provide basic information about -# an image currently in storage. See also [InspectImage](InspectImage). -method ListImages() -> (images: []ImageInList) +# ListImages returns information about the images that are currently in storage. +# See also [InspectImage](InspectImage). +method ListImages() -> (images: []Image) -# GetImage returns a single image in an [ImageInList](#ImageInList) struct. You must supply an image name as a string. -# If the image cannot be found, an [ImageNotFound](#ImageNotFound) error will be returned. -method GetImage(name: string) -> (image: ImageInList) +# GetImage returns information about a single image in storage. +# If the image caGetImage returns be found, [ImageNotFound](#ImageNotFound) will be returned. +method GetImage(id: string) -> (image: Image) # BuildImage takes a [BuildInfo](#BuildInfo) structure and builds an image. At a minimum, you must provide the -# 'dockerfile' and 'tags' options in the BuildInfo structure. It will return a [BuildResponse](#BuildResponse) structure +# 'dockerfile' and 'tags' options in the BuildInfo structure. It will return a [MoreResponse](#MoreResponse) structure # that contains the build logs and resulting image ID. -method BuildImage(build: BuildInfo) -> (image: BuildResponse) +method BuildImage(build: BuildInfo) -> (image: MoreResponse) # This function is not implemented yet. -method CreateImage() -> (notimplemented: NotImplemented) +# method CreateImage() -> (notimplemented: NotImplemented) # InspectImage takes the name or ID of an image and returns a string respresentation of data associated with the #image. You must serialize the string into JSON to use it further. An [ImageNotFound](#ImageNotFound) error will @@ -637,8 +657,8 @@ method HistoryImage(name: string) -> (history: []ImageHistory) # PushImage takes three input arguments: the name or ID of an image, the fully-qualified destination name of the image, # and a boolean as to whether tls-verify should be used (with false disabling TLS, not affecting the default behavior). # It will return an [ImageNotFound](#ImageNotFound) error if -# the image cannot be found in local storage; otherwise the ID of the image will be returned on success. -method PushImage(name: string, tag: string, tlsverify: bool, signaturePolicy: string, creds: string, certDir: string, compress: bool, format: string, removeSignatures: bool, signBy: string) -> (image: string) +# the image cannot be found in local storage; otherwise it will return a [MoreResponse](#MoreResponse) +method PushImage(name: string, tag: string, tlsverify: bool, signaturePolicy: string, creds: string, certDir: string, compress: bool, format: string, removeSignatures: bool, signBy: string) -> (reply: MoreResponse) # TagImage takes the name or ID of an image in local storage as well as the desired tag name. If the image cannot # be found, an [ImageNotFound](#ImageNotFound) error will be returned; otherwise, the ID of the image is returned on success. @@ -656,10 +676,10 @@ method TagImage(name: string, tagged: string) -> (image: string) # ~~~ method RemoveImage(name: string, force: bool) -> (image: string) -# SearchImage takes the string of an image name and a limit of searches from each registries to be returned. SearchImage -# will then use a glob-like match to find the image you are searching for. The images are returned in an array of -# ImageSearch structures which contain information about the image as well as its fully-qualified name. -method SearchImage(name: string, limit: int) -> (images: []ImageSearch) +# SearchImages searches available registries for images that contain the +# contents of "query" in their name. If "limit" is given, limits the amount of +# search results per registry. +method SearchImages(query: string, limit: ?int) -> (results: []ImageSearchResult) # DeleteUnusedImages deletes any images not associated with a container. The IDs of the deleted images are returned # in a string array. @@ -913,10 +933,10 @@ method UnpausePod(name: string) -> (pod: string) method RemovePod(name: string, force: bool) -> (pod: string) # This method has not be implemented yet. -method WaitPod() -> (notimplemented: NotImplemented) +# method WaitPod() -> (notimplemented: NotImplemented) # This method has not been implemented yet. -method TopPod() -> (notimplemented: NotImplemented) +# method TopPod() -> (notimplemented: NotImplemented) # GetPodStats takes the name or ID of a pod and returns a pod name and slice of ContainerStats structure which # contains attributes like memory and cpu usage. If the pod cannot be found, a [PodNotFound](#PodNotFound) @@ -1020,19 +1040,19 @@ method UnmountContainer(name: string, force: bool) -> () method ImagesPrune(all: bool) -> (pruned: []string) # This function is not implemented yet. -method ListContainerPorts(name: string) -> (notimplemented: NotImplemented) +# method ListContainerPorts(name: string) -> (notimplemented: NotImplemented) # GenerateKube generates a Kubernetes v1 Pod description of a Podman container or pod # and its containers. The description is in YAML. See also [ReplayKube](ReplayKube). -method GenerateKube() -> (notimplemented: NotImplemented) +# method GenerateKube() -> (notimplemented: NotImplemented) # GenerateKubeService generates a Kubernetes v1 Service description of a Podman container or pod # and its containers. The description is in YAML. See also [GenerateKube](GenerateKube). -method GenerateKubeService() -> (notimplemented: NotImplemented) +# method GenerateKubeService() -> (notimplemented: NotImplemented) # ReplayKube recreates a pod and its containers based on a Kubernetes v1 Pod description (in YAML) # like that created by GenerateKube. See also [GenerateKube](GenerateKube). -method ReplayKube() -> (notimplemented: NotImplemented) +# method ReplayKube() -> (notimplemented: NotImplemented) # ContainerConfig returns a container's config in string form. This call is for # development of Podman only and generally should not be used. @@ -1053,11 +1073,17 @@ method ContainerStateData(name: string) -> (config: string) method SendFile(type: string, length: int) -> (file_handle: string) method ReceiveFile(path: string, delete: bool) -> (len: int) +method VolumeCreate(options: VolumeCreateOpts) -> (volumeName: string) + +method VolumeRemove(options: VolumeRemoveOpts) -> (volumeNames: []string) + +method GetVolumes(args: []string, all: bool) -> (volumes: []Volume) + # ImageNotFound means the image could not be found by the provided name or ID in local storage. -error ImageNotFound (name: string) +error ImageNotFound (id: string) # ContainerNotFound means the container could not be found by the provided name or ID in local storage. -error ContainerNotFound (name: string) +error ContainerNotFound (id: string) # NoContainerRunning means none of the containers requested are running in a command that requires a running container. error NoContainerRunning () diff --git a/cmd/podman/varlink_dummy.go b/cmd/podman/varlink_dummy.go index 8d7a7e8ca..430511d72 100644 --- a/cmd/podman/varlink_dummy.go +++ b/cmd/podman/varlink_dummy.go @@ -2,8 +2,10 @@ package main -import ( - "github.com/containers/libpod/cmd/podman/cliconfig" -) +import "github.com/spf13/cobra" -var varlinkCommand *cliconfig.PodmanCommand +var ( + _varlinkCommand = &cobra.Command{ + Use: "", + } +) diff --git a/cmd/podman/version.go b/cmd/podman/version.go index 0e7cd43d5..c65ba94f9 100644 --- a/cmd/podman/version.go +++ b/cmd/podman/version.go @@ -28,9 +28,9 @@ var ( func init() { versionCommand.Command = _versionCommand + versionCommand.SetUsageTemplate(UsageTemplate()) flags := versionCommand.Flags() flags.StringVarP(&versionCommand.Format, "format", "f", "", "Change the output format to JSON or a Go template") - rootCmd.AddCommand(versionCommand.Command) } // versionCmd gets and prints version info for version command diff --git a/cmd/podman/volume.go b/cmd/podman/volume.go index bae778e52..36798a19e 100644 --- a/cmd/podman/volume.go +++ b/cmd/podman/volume.go @@ -19,5 +19,5 @@ var volumeCommand = cliconfig.PodmanCommand{ func init() { volumeCommand.AddCommand(getVolumeSubCommands()...) - rootCmd.AddCommand(volumeCommand.Command) + volumeCommand.SetUsageTemplate(UsageTemplate()) } diff --git a/cmd/podman/volume_create.go b/cmd/podman/volume_create.go index e0ff4c341..fe5d69e0b 100644 --- a/cmd/podman/volume_create.go +++ b/cmd/podman/volume_create.go @@ -4,8 +4,7 @@ import ( "fmt" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/libpodruntime" - "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/adapter" "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -33,6 +32,7 @@ be created at.` func init() { volumeCreateCommand.Command = _volumeCreateCommand + volumeCreateCommand.SetUsageTemplate(UsageTemplate()) flags := volumeCreateCommand.Flags() flags.StringVar(&volumeCreateCommand.Driver, "driver", "", "Specify volume driver name (default local)") flags.StringSliceVarP(&volumeCreateCommand.Label, "label", "l", []string{}, "Set metadata for a volume (default [])") @@ -41,13 +41,7 @@ func init() { } func volumeCreateCmd(c *cliconfig.VolumeCreateValues) error { - var ( - options []libpod.VolumeCreateOption - err error - volName string - ) - - runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand) + runtime, err := adapter.GetRuntime(&c.PodmanCommand) if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } @@ -57,36 +51,19 @@ func volumeCreateCmd(c *cliconfig.VolumeCreateValues) error { return errors.Errorf("too many arguments, create takes at most 1 argument") } - if len(c.InputArgs) > 0 { - volName = c.InputArgs[0] - options = append(options, libpod.WithVolumeName(volName)) - } - - if c.Flag("driver").Changed { - options = append(options, libpod.WithVolumeDriver(c.String("driver"))) - } - labels, err := getAllLabels([]string{}, c.Label) if err != nil { return errors.Wrapf(err, "unable to process labels") } - if len(labels) != 0 { - options = append(options, libpod.WithVolumeLabels(labels)) - } opts, err := getAllLabels([]string{}, c.Opt) if err != nil { return errors.Wrapf(err, "unable to process options") } - if len(options) != 0 { - options = append(options, libpod.WithVolumeOptions(opts)) - } - vol, err := runtime.NewVolume(getContext(), options...) - if err != nil { - return err + volumeName, err := runtime.CreateVolume(getContext(), c, labels, opts) + if err == nil { + fmt.Println(volumeName) } - fmt.Printf("%s\n", vol.Name()) - - return nil + return err } diff --git a/cmd/podman/volume_inspect.go b/cmd/podman/volume_inspect.go index 7cb5703da..928ef37d0 100644 --- a/cmd/podman/volume_inspect.go +++ b/cmd/podman/volume_inspect.go @@ -2,9 +2,8 @@ package main import ( "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/libpodruntime" + "github.com/containers/libpod/libpod/adapter" "github.com/pkg/errors" - "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -31,6 +30,7 @@ from JSON to a Go template. func init() { volumeInspectCommand.Command = _volumeInspectCommand + volumeInspectCommand.SetUsageTemplate(UsageTemplate()) flags := volumeInspectCommand.Flags() flags.BoolVarP(&volumeInspectCommand.All, "all", "a", false, "Inspect all volumes") flags.StringVarP(&volumeInspectCommand.Format, "format", "f", "json", "Format volume output using Go template") @@ -38,22 +38,19 @@ func init() { } func volumeInspectCmd(c *cliconfig.VolumeInspectValues) error { - var err error + if (c.All && len(c.InputArgs) > 0) || (!c.All && len(c.InputArgs) < 1) { + return errors.New("provide one or more volume names or use --all") + } - runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand) + runtime, err := adapter.GetRuntime(&c.PodmanCommand) if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } defer runtime.Shutdown(false) - opts := volumeLsOptions{ - Format: c.Format, - } - - vols, lastError := getVolumesFromContext(&c.PodmanCommand, runtime) - if lastError != nil { - logrus.Errorf("%q", lastError) + vols, err := runtime.InspectVolumes(getContext(), c) + if err != nil { + return err } - - return generateVolLsOutput(vols, opts, runtime) + return generateVolLsOutput(vols, volumeLsOptions{Format: c.Format}) } diff --git a/cmd/podman/volume_ls.go b/cmd/podman/volume_ls.go index 78fdfed64..0edadc5ac 100644 --- a/cmd/podman/volume_ls.go +++ b/cmd/podman/volume_ls.go @@ -6,8 +6,7 @@ import ( "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/formats" - "github.com/containers/libpod/cmd/podman/libpodruntime" - "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/adapter" "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -62,6 +61,7 @@ and the output format can be changed to JSON or a user specified Go template. func init() { volumeLsCommand.Command = _volumeLsCommand + volumeLsCommand.SetUsageTemplate(UsageTemplate()) flags := volumeLsCommand.Flags() flags.StringVarP(&volumeLsCommand.Filter, "filter", "f", "", "Filter volume output") @@ -70,7 +70,7 @@ func init() { } func volumeLsCmd(c *cliconfig.VolumeLsValues) error { - runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand) + runtime, err := adapter.GetRuntime(&c.PodmanCommand) if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } @@ -86,7 +86,7 @@ func volumeLsCmd(c *cliconfig.VolumeLsValues) error { opts.Format = genVolLsFormat(c) // Get the filter functions based on any filters set - var filterFuncs []libpod.VolumeFilter + var filterFuncs []adapter.VolumeFilter if c.Filter != "" { filters := strings.Split(c.Filter, ",") for _, f := range filters { @@ -94,7 +94,7 @@ func volumeLsCmd(c *cliconfig.VolumeLsValues) error { if len(filterSplit) < 2 { return errors.Errorf("filter input must be in the form of filter=value: %s is invalid", f) } - generatedFunc, err := generateVolumeFilterFuncs(filterSplit[0], filterSplit[1], runtime) + generatedFunc, err := generateVolumeFilterFuncs(filterSplit[0], filterSplit[1]) if err != nil { return errors.Wrapf(err, "invalid filter") } @@ -102,13 +102,12 @@ func volumeLsCmd(c *cliconfig.VolumeLsValues) error { } } - volumes, err := runtime.GetAllVolumes() + volumes, err := runtime.Volumes(getContext()) if err != nil { return err } - // Get the volumes that match the filter - volsFiltered := make([]*libpod.Volume, 0, len(volumes)) + volsFiltered := make([]*adapter.Volume, 0, len(volumes)) for _, vol := range volumes { include := true for _, filter := range filterFuncs { @@ -119,7 +118,7 @@ func volumeLsCmd(c *cliconfig.VolumeLsValues) error { volsFiltered = append(volsFiltered, vol) } } - return generateVolLsOutput(volsFiltered, opts, runtime) + return generateVolLsOutput(volsFiltered, opts) } // generate the template based on conditions given @@ -205,7 +204,7 @@ func getVolTemplateOutput(lsParams []volumeLsJSONParams, opts volumeLsOptions) ( } // getVolJSONParams returns the volumes in JSON format -func getVolJSONParams(volumes []*libpod.Volume, opts volumeLsOptions, runtime *libpod.Runtime) ([]volumeLsJSONParams, error) { +func getVolJSONParams(volumes []*adapter.Volume) []volumeLsJSONParams { var lsOutput []volumeLsJSONParams for _, volume := range volumes { @@ -220,25 +219,19 @@ func getVolJSONParams(volumes []*libpod.Volume, opts volumeLsOptions, runtime *l lsOutput = append(lsOutput, params) } - return lsOutput, nil + return lsOutput } // generateVolLsOutput generates the output based on the format, JSON or Go Template, and prints it out -func generateVolLsOutput(volumes []*libpod.Volume, opts volumeLsOptions, runtime *libpod.Runtime) error { +func generateVolLsOutput(volumes []*adapter.Volume, opts volumeLsOptions) error { if len(volumes) == 0 && opts.Format != formats.JSONString { return nil } - lsOutput, err := getVolJSONParams(volumes, opts, runtime) - if err != nil { - return err - } + lsOutput := getVolJSONParams(volumes) var out formats.Writer switch opts.Format { case formats.JSONString: - if err != nil { - return errors.Wrapf(err, "unable to create JSON for volume output") - } out = formats.JSONStructArray{Output: volLsToGeneric([]volumeLsTemplateParams{}, lsOutput)} default: lsOutput, err := getVolTemplateOutput(lsOutput, opts) @@ -251,18 +244,18 @@ func generateVolLsOutput(volumes []*libpod.Volume, opts volumeLsOptions, runtime } // generateVolumeFilterFuncs returns the true if the volume matches the filter set, otherwise it returns false. -func generateVolumeFilterFuncs(filter, filterValue string, runtime *libpod.Runtime) (func(volume *libpod.Volume) bool, error) { +func generateVolumeFilterFuncs(filter, filterValue string) (func(volume *adapter.Volume) bool, error) { switch filter { case "name": - return func(v *libpod.Volume) bool { + return func(v *adapter.Volume) bool { return strings.Contains(v.Name(), filterValue) }, nil case "driver": - return func(v *libpod.Volume) bool { + return func(v *adapter.Volume) bool { return v.Driver() == filterValue }, nil case "scope": - return func(v *libpod.Volume) bool { + return func(v *adapter.Volume) bool { return v.Scope() == filterValue }, nil case "label": @@ -273,7 +266,7 @@ func generateVolumeFilterFuncs(filter, filterValue string, runtime *libpod.Runti } else { filterValue = "" } - return func(v *libpod.Volume) bool { + return func(v *adapter.Volume) bool { for labelKey, labelValue := range v.Labels() { if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) { return true @@ -289,7 +282,7 @@ func generateVolumeFilterFuncs(filter, filterValue string, runtime *libpod.Runti } else { filterValue = "" } - return func(v *libpod.Volume) bool { + return func(v *adapter.Volume) bool { for labelKey, labelValue := range v.Options() { if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) { return true diff --git a/cmd/podman/volume_prune.go b/cmd/podman/volume_prune.go index 29dc6ead4..74228fa5b 100644 --- a/cmd/podman/volume_prune.go +++ b/cmd/podman/volume_prune.go @@ -37,6 +37,7 @@ using force. func init() { volumePruneCommand.Command = _volumePruneCommand + volumePruneCommand.SetUsageTemplate(UsageTemplate()) flags := volumePruneCommand.Flags() flags.BoolVarP(&volumePruneCommand.Force, "force", "f", false, "Do not prompt for confirmation") diff --git a/cmd/podman/volume_rm.go b/cmd/podman/volume_rm.go index b02a06ed9..f301749e9 100644 --- a/cmd/podman/volume_rm.go +++ b/cmd/podman/volume_rm.go @@ -4,9 +4,8 @@ import ( "fmt" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/libpodruntime" + "github.com/containers/libpod/libpod/adapter" "github.com/pkg/errors" - "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -35,6 +34,7 @@ not being used by any containers. To remove the volumes anyways, use the func init() { volumeRmCommand.Command = _volumeRmCommand + volumeRmCommand.SetUsageTemplate(UsageTemplate()) flags := volumeRmCommand.Flags() flags.BoolVarP(&volumeRmCommand.All, "all", "a", false, "Remove all volumes") flags.BoolVarP(&volumeRmCommand.Force, "force", "f", false, "Remove a volume by force, even if it is being used by a container") @@ -43,25 +43,28 @@ func init() { func volumeRmCmd(c *cliconfig.VolumeRmValues) error { var err error - runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand) + if (len(c.InputArgs) > 0 && c.All) || (len(c.InputArgs) < 1 && !c.All) { + return errors.New("choose either one or more volumes or all") + } + + runtime, err := adapter.GetRuntime(&c.PodmanCommand) if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } defer runtime.Shutdown(false) - - ctx := getContext() - - vols, lastError := getVolumesFromContext(&c.PodmanCommand, runtime) - for _, vol := range vols { - err = runtime.RemoveVolume(ctx, vol, c.Force, false) - if err != nil { - if lastError != nil { - logrus.Errorf("%q", lastError) - } - lastError = errors.Wrapf(err, "failed to remove volume %q", vol.Name()) - } else { - fmt.Println(vol.Name()) + deletedVolumeNames, err := runtime.RemoveVolumes(getContext(), c) + if err != nil { + if len(deletedVolumeNames) > 0 { + printDeleteVolumes(deletedVolumeNames) + return err } } - return lastError + printDeleteVolumes(deletedVolumeNames) + return err +} + +func printDeleteVolumes(volumes []string) { + for _, v := range volumes { + fmt.Println(v) + } } diff --git a/cmd/podman/wait.go b/cmd/podman/wait.go index fa195b7ce..616c8feb5 100644 --- a/cmd/podman/wait.go +++ b/cmd/podman/wait.go @@ -34,11 +34,10 @@ var ( func init() { waitCommand.Command = _waitCommand + waitCommand.SetUsageTemplate(UsageTemplate()) flags := waitCommand.Flags() flags.UintVarP(&waitCommand.Interval, "interval", "i", 250, "Milliseconds to wait before polling for completion") flags.BoolVarP(&waitCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - - rootCmd.AddCommand(waitCommand.Command) } func waitCmd(c *cliconfig.WaitValues) error { |