diff options
Diffstat (limited to 'cmd/podman')
-rw-r--r-- | cmd/podman/common/specgen.go | 2 | ||||
-rw-r--r-- | cmd/podman/containers/attach.go | 35 | ||||
-rw-r--r-- | cmd/podman/containers/commit.go | 36 | ||||
-rw-r--r-- | cmd/podman/containers/cp.go | 55 | ||||
-rw-r--r-- | cmd/podman/containers/create.go | 32 | ||||
-rw-r--r-- | cmd/podman/containers/exec.go | 36 | ||||
-rw-r--r-- | cmd/podman/containers/export.go | 25 | ||||
-rw-r--r-- | cmd/podman/containers/kill.go | 36 | ||||
-rw-r--r-- | cmd/podman/containers/mount.go | 28 | ||||
-rw-r--r-- | cmd/podman/containers/pause.go | 25 | ||||
-rw-r--r-- | cmd/podman/containers/port.go | 123 | ||||
-rw-r--r-- | cmd/podman/containers/restart.go | 36 | ||||
-rw-r--r-- | cmd/podman/containers/rm.go | 36 | ||||
-rw-r--r-- | cmd/podman/containers/run.go | 35 | ||||
-rw-r--r-- | cmd/podman/containers/start.go | 34 | ||||
-rw-r--r-- | cmd/podman/containers/stop.go | 36 | ||||
-rw-r--r-- | cmd/podman/containers/top.go | 38 | ||||
-rw-r--r-- | cmd/podman/containers/unmount.go | 30 | ||||
-rw-r--r-- | cmd/podman/containers/unpause.go | 26 | ||||
-rw-r--r-- | cmd/podman/containers/wait.go | 37 | ||||
-rw-r--r-- | cmd/podman/images/inspect.go | 8 |
21 files changed, 663 insertions, 86 deletions
diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go index bf03463aa..12fd16551 100644 --- a/cmd/podman/common/specgen.go +++ b/cmd/podman/common/specgen.go @@ -384,6 +384,8 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string var command []string + s.Entrypoint = entrypoint + // Build the command // If we have an entry point, it goes first if len(entrypoint) > 0 { diff --git a/cmd/podman/containers/attach.go b/cmd/podman/containers/attach.go index 10ad80503..78b52ad1b 100644 --- a/cmd/podman/containers/attach.go +++ b/cmd/podman/containers/attach.go @@ -7,6 +7,7 @@ import ( "github.com/containers/libpod/pkg/domain/entities" "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) var ( @@ -26,18 +27,23 @@ var ( podman attach 1234 podman attach --no-stdin foobar`, } + + containerAttachCommand = &cobra.Command{ + Use: attachCommand.Use, + Short: attachCommand.Short, + Long: attachCommand.Long, + RunE: attachCommand.RunE, + Example: `podman container attach ctrID + podman container attach 1234 + podman container attach --no-stdin foobar`, + } ) var ( attachOpts entities.AttachOptions ) -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode}, - Command: attachCommand, - }) - flags := attachCommand.Flags() +func attachFlags(flags *pflag.FlagSet) { flags.StringVar(&attachOpts.DetachKeys, "detach-keys", containerConfig.DetachKeys(), "Select the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`") flags.BoolVar(&attachOpts.NoStdin, "no-stdin", false, "Do not attach STDIN. The default is false") flags.BoolVar(&attachOpts.SigProxy, "sig-proxy", true, "Proxy received signals to the process") @@ -47,6 +53,23 @@ func init() { } } +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode}, + Command: attachCommand, + }) + flags := attachCommand.Flags() + attachFlags(flags) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode}, + Command: containerAttachCommand, + Parent: containerCmd, + }) + containerAttachFlags := containerAttachCommand.Flags() + attachFlags(containerAttachFlags) +} + func attach(cmd *cobra.Command, args []string) error { attachOpts.Stdin = os.Stdin if attachOpts.NoStdin { diff --git a/cmd/podman/containers/commit.go b/cmd/podman/containers/commit.go index eaba07981..137e486eb 100644 --- a/cmd/podman/containers/commit.go +++ b/cmd/podman/containers/commit.go @@ -11,6 +11,7 @@ import ( "github.com/containers/libpod/pkg/domain/entities" "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) var ( @@ -28,6 +29,17 @@ var ( podman commit containerID`, } + containerCommitCommand = &cobra.Command{ + Use: commitCommand.Use, + Short: commitCommand.Short, + Long: commitCommand.Long, + RunE: commitCommand.RunE, + Example: `podman container commit -q --message "committing container to image" reverent_golick image-committed + podman container commit -q --author "firstName lastName" reverent_golick image-committed + podman container commit -q --pause=false containerID image-committed + podman container commit containerID`, + } + // ChangeCmds is the list of valid Changes commands to passed to the Commit call ChangeCmds = []string{"CMD", "ENTRYPOINT", "ENV", "EXPOSE", "LABEL", "ONBUILD", "STOPSIGNAL", "USER", "VOLUME", "WORKDIR"} ) @@ -39,12 +51,7 @@ var ( iidFile string ) -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: commitCommand, - }) - flags := commitCommand.Flags() +func commitFlags(flags *pflag.FlagSet) { flags.StringArrayVarP(&commitOptions.Changes, "change", "c", []string{}, "Apply the following possible instructions to the created image (default []): "+strings.Join(ChangeCmds, " | ")) flags.StringVarP(&commitOptions.Format, "format", "f", "oci", "`Format` of the image manifest and metadata") flags.StringVarP(&iidFile, "iidfile", "", "", "`file` to write the image ID to") @@ -53,8 +60,25 @@ func init() { flags.BoolVarP(&commitOptions.Pause, "pause", "p", false, "Pause container during commit") flags.BoolVarP(&commitOptions.Quiet, "quiet", "q", false, "Suppress output") flags.BoolVar(&commitOptions.IncludeVolumes, "include-volumes", false, "Include container volumes as image volumes") +} + +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: commitCommand, + }) + flags := commitCommand.Flags() + commitFlags(flags) + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: containerCommitCommand, + Parent: containerCmd, + }) + containerCommitFlags := containerCommitCommand.Flags() + commitFlags(containerCommitFlags) } + func commit(cmd *cobra.Command, args []string) error { container := args[0] if len(args) > 1 { diff --git a/cmd/podman/containers/cp.go b/cmd/podman/containers/cp.go new file mode 100644 index 000000000..f0f9a158d --- /dev/null +++ b/cmd/podman/containers/cp.go @@ -0,0 +1,55 @@ +package containers + +import ( + "github.com/containers/libpod/cmd/podman/registry" + "github.com/containers/libpod/pkg/cgroups" + "github.com/containers/libpod/pkg/domain/entities" + "github.com/containers/libpod/pkg/rootless" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var ( + cpDescription = `Command copies the contents of SRC_PATH to the DEST_PATH. + + You can copy from the container's file system to the local machine or the reverse, from the local filesystem to the container. If "-" is specified for either the SRC_PATH or DEST_PATH, you can also stream a tar archive from STDIN or to STDOUT. The CONTAINER can be a running or stopped container. The SRC_PATH or DEST_PATH can be a file or directory. +` + cpCommand = &cobra.Command{ + Use: "cp [flags] SRC_PATH DEST_PATH", + Short: "Copy files/folders between a container and the local filesystem", + Long: cpDescription, + Args: cobra.ExactArgs(2), + RunE: cp, + Example: "podman cp [CONTAINER:]SRC_PATH [CONTAINER:]DEST_PATH", + } +) + +var ( + cpOpts entities.ContainerCpOptions +) + +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode}, + Command: cpCommand, + }) + flags := cpCommand.Flags() + flags.BoolVar(&cpOpts.Extract, "extract", false, "Extract the tar file into the destination directory.") + flags.BoolVar(&cpOpts.Pause, "pause", copyPause(), "Pause the container while copying") +} + +func cp(cmd *cobra.Command, args []string) error { + _, err := registry.ContainerEngine().ContainerCp(registry.GetContext(), args[0], args[1], cpOpts) + return err +} + +func copyPause() bool { + if rootless.IsRootless() { + cgroupv2, _ := cgroups.IsCgroup2UnifiedMode() + if !cgroupv2 { + logrus.Debugf("defaulting to pause==false on rootless cp in cgroupv1 systems") + return false + } + } + return true +} diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go index 0843789eb..0c96f1a5c 100644 --- a/cmd/podman/containers/create.go +++ b/cmd/podman/containers/create.go @@ -11,6 +11,7 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) var ( @@ -27,12 +28,29 @@ var ( podman create --annotation HELLO=WORLD alpine ls podman create -t -i --name myctr alpine ls`, } + + containerCreateCommand = &cobra.Command{ + Use: createCommand.Use, + Short: createCommand.Short, + Long: createCommand.Long, + RunE: createCommand.RunE, + Example: `podman container create alpine ls + podman container create --annotation HELLO=WORLD alpine ls + podman container create -t -i --name myctr alpine ls`, + } ) var ( cliVals common.ContainerCLIOpts ) +func createFlags(flags *pflag.FlagSet) { + flags.SetInterspersed(false) + flags.AddFlagSet(common.GetCreateFlags(&cliVals)) + flags.AddFlagSet(common.GetNetFlags()) + flags.SetNormalizeFunc(common.AliasFlags) +} + func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, @@ -40,10 +58,16 @@ func init() { }) //common.GetCreateFlags(createCommand) flags := createCommand.Flags() - flags.SetInterspersed(false) - flags.AddFlagSet(common.GetCreateFlags(&cliVals)) - flags.AddFlagSet(common.GetNetFlags()) - flags.SetNormalizeFunc(common.AliasFlags) + createFlags(flags) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: containerCreateCommand, + Parent: containerCmd, + }) + + containerCreateFlags := containerCreateCommand.Flags() + createFlags(containerCreateFlags) } func create(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/containers/exec.go b/cmd/podman/containers/exec.go index aaee4ee1c..3749c934a 100644 --- a/cmd/podman/containers/exec.go +++ b/cmd/podman/containers/exec.go @@ -9,6 +9,7 @@ import ( envLib "github.com/containers/libpod/pkg/env" "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) var ( @@ -23,6 +24,16 @@ var ( podman exec -it -w /tmp myCtr pwd podman exec --user root ctrID ls`, } + + containerExecCommand = &cobra.Command{ + Use: execCommand.Use, + Short: execCommand.Short, + Long: execCommand.Long, + RunE: execCommand.RunE, + Example: `podman container exec -it ctrID ls + podman container exec -it -w /tmp myCtr pwd + podman container exec --user root ctrID ls`, + } ) var ( @@ -30,12 +41,7 @@ var ( execOpts entities.ExecOptions ) -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode}, - Command: execCommand, - }) - flags := execCommand.Flags() +func execFlags(flags *pflag.FlagSet) { flags.SetInterspersed(false) flags.StringVar(&execOpts.DetachKeys, "detach-keys", containerConfig.DetachKeys(), "Select 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.StringArrayVarP(&envInput, "env", "e", []string{}, "Set environment variables") @@ -51,8 +57,26 @@ func init() { _ = flags.MarkHidden("latest") _ = flags.MarkHidden("preserve-fds") } +} +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode}, + Command: execCommand, + }) + flags := execCommand.Flags() + execFlags(flags) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode}, + Command: containerExecCommand, + Parent: containerCommitCommand, + }) + + containerExecFlags := containerExecCommand.Flags() + execFlags(containerExecFlags) } + func exec(cmd *cobra.Command, args []string) error { var nameOrId string execOpts.Cmd = args diff --git a/cmd/podman/containers/export.go b/cmd/podman/containers/export.go index 5110812d1..fb5bd468f 100644 --- a/cmd/podman/containers/export.go +++ b/cmd/podman/containers/export.go @@ -9,6 +9,7 @@ import ( "github.com/containers/libpod/pkg/domain/entities" "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/spf13/pflag" "golang.org/x/crypto/ssh/terminal" ) @@ -25,19 +26,41 @@ var ( Example: `podman export ctrID > myCtr.tar podman export --output="myCtr.tar" ctrID`, } + + containerExportCommand = &cobra.Command{ + Use: exportCommand.Use, + Short: exportCommand.Short, + Long: exportCommand.Long, + RunE: exportCommand.RunE, + Example: `podman container export ctrID > myCtr.tar + podman container export --output="myCtr.tar" ctrID`, + } ) var ( exportOpts entities.ContainerExportOptions ) +func exportFlags(flags *pflag.FlagSet) { + flags.StringVarP(&exportOpts.Output, "output", "o", "", "Write to a specified file (default: stdout, which must be redirected)") +} + func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, Command: exportCommand, }) flags := exportCommand.Flags() - flags.StringVarP(&exportOpts.Output, "output", "o", "", "Write to a specified file (default: stdout, which must be redirected)") + exportFlags(flags) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: containerExportCommand, + Parent: containerCmd, + }) + + containerExportFlags := containerExportCommand.Flags() + exportFlags(containerExportFlags) } func export(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/containers/kill.go b/cmd/podman/containers/kill.go index 5341457fb..8b4a384fe 100644 --- a/cmd/podman/containers/kill.go +++ b/cmd/podman/containers/kill.go @@ -11,6 +11,7 @@ import ( "github.com/containers/libpod/pkg/domain/entities" "github.com/containers/libpod/pkg/signal" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) var ( @@ -27,18 +28,23 @@ var ( podman kill 860a4b23 podman kill --signal TERM ctrID`, } + + containerKillCommand = &cobra.Command{ + Use: killCommand.Use, + Short: killCommand.Short, + Long: killCommand.Long, + RunE: killCommand.RunE, + Example: `podman container kill mywebserver + podman container kill 860a4b23 + podman container kill --signal TERM ctrID`, + } ) var ( killOptions = entities.KillOptions{} ) -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: killCommand, - }) - flags := killCommand.Flags() +func killFlags(flags *pflag.FlagSet) { flags.BoolVarP(&killOptions.All, "all", "a", false, "Signal all running containers") flags.StringVarP(&killOptions.Signal, "signal", "s", "KILL", "Signal to send to the container") flags.BoolVarP(&killOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") @@ -47,6 +53,24 @@ func init() { } } +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: killCommand, + }) + flags := killCommand.Flags() + killFlags(flags) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: containerKillCommand, + Parent: containerCmd, + }) + + containerKillFlags := containerKillCommand.Flags() + killFlags(containerKillFlags) +} + func kill(cmd *cobra.Command, args []string) error { var ( err error diff --git a/cmd/podman/containers/mount.go b/cmd/podman/containers/mount.go index 25eec46ca..d0d132546 100644 --- a/cmd/podman/containers/mount.go +++ b/cmd/podman/containers/mount.go @@ -12,6 +12,7 @@ import ( "github.com/containers/libpod/cmd/podman/utils" "github.com/containers/libpod/pkg/domain/entities" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) var ( @@ -34,22 +35,41 @@ var ( registry.ParentNSRequired: "", }, } + + containerMountCommmand = &cobra.Command{ + Use: mountCommand.Use, + Short: mountCommand.Short, + Long: mountCommand.Long, + RunE: mountCommand.RunE, + } ) var ( mountOpts entities.ContainerMountOptions ) +func mountFlags(flags *pflag.FlagSet) { + flags.BoolVarP(&mountOpts.All, "all", "a", false, "Mount all containers") + flags.StringVar(&mountOpts.Format, "format", "", "Change the output format to Go template") + flags.BoolVarP(&mountOpts.Latest, "latest", "l", false, "Act on the latest container podman is aware of") + flags.BoolVar(&mountOpts.NoTruncate, "notruncate", false, "Do not truncate output") +} + func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ Mode: []entities.EngineMode{entities.ABIMode}, Command: mountCommand, }) flags := mountCommand.Flags() - flags.BoolVarP(&mountOpts.All, "all", "a", false, "Mount all containers") - flags.StringVar(&mountOpts.Format, "format", "", "Change the output format to Go template") - flags.BoolVarP(&mountOpts.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - flags.BoolVar(&mountOpts.NoTruncate, "notruncate", false, "Do not truncate output") + mountFlags(flags) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode}, + Command: containerMountCommmand, + Parent: containerCmd, + }) + containerMountFlags := containerMountCommmand.Flags() + mountFlags(containerMountFlags) } func mount(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/containers/pause.go b/cmd/podman/containers/pause.go index f3654b5c1..b932c4539 100644 --- a/cmd/podman/containers/pause.go +++ b/cmd/podman/containers/pause.go @@ -10,6 +10,7 @@ import ( "github.com/containers/libpod/pkg/rootless" "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) var ( @@ -24,16 +25,38 @@ var ( podman pause -a`, } + containerPauseCommand = &cobra.Command{ + Use: pauseCommand.Use, + Short: pauseCommand.Short, + Long: pauseCommand.Long, + RunE: pauseCommand.RunE, + Example: `podman container pause mywebserver + podman container pause 860a4b23 + podman container pause -a`, + } + pauseOpts = entities.PauseUnPauseOptions{} ) +func pauseFlags(flags *pflag.FlagSet) { + flags.BoolVarP(&pauseOpts.All, "all", "a", false, "Pause all running containers") +} + func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, Command: pauseCommand, }) flags := pauseCommand.Flags() - flags.BoolVarP(&pauseOpts.All, "all", "a", false, "Pause all running containers") + pauseFlags(flags) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: containerPauseCommand, + Parent: containerCmd, + }) + containerPauseFlags := containerPauseCommand.Flags() + pauseFlags(containerPauseFlags) } func pause(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/containers/port.go b/cmd/podman/containers/port.go new file mode 100644 index 000000000..0e50140ca --- /dev/null +++ b/cmd/podman/containers/port.go @@ -0,0 +1,123 @@ +package containers + +import ( + "fmt" + "strconv" + "strings" + + "github.com/containers/libpod/cmd/podman/parse" + "github.com/containers/libpod/cmd/podman/registry" + "github.com/containers/libpod/pkg/domain/entities" + "github.com/cri-o/ocicni/pkg/ocicni" + "github.com/pkg/errors" + "github.com/spf13/cobra" +) + +var ( + portDescription = `List port mappings for the CONTAINER, or lookup the public-facing port that is NAT-ed to the PRIVATE_PORT +` + portCommand = &cobra.Command{ + Use: "port [flags] CONTAINER [PORT]", + Short: "List port mappings or a specific mapping for the container", + Long: portDescription, + RunE: port, + Args: func(cmd *cobra.Command, args []string) error { + return parse.CheckAllLatestAndCIDFile(cmd, args, true, false) + }, + Example: `podman port --all + podman port ctrID 80/tcp + podman port --latest 80`, + } +) + +var ( + portOpts entities.ContainerPortOptions +) + +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode}, + Command: portCommand, + }) + flags := portCommand.Flags() + flags.BoolVarP(&portOpts.All, "all", "a", false, "Display port information for all containers") + flags.BoolVarP(&portOpts.Latest, "latest", "l", false, "Act on the latest container podman is aware of") + if registry.IsRemote() { + _ = flags.MarkHidden("latest") + } +} + +func port(cmd *cobra.Command, args []string) error { + var ( + container string + err error + userPort ocicni.PortMapping + ) + + if len(args) == 0 && !portOpts.Latest && !portOpts.All { + return errors.Errorf("you must supply a running container name or id") + } + if !portOpts.Latest && len(args) >= 1 { + container = args[0] + } + port := "" + if len(args) > 1 && !portOpts.Latest { + port = args[1] + } + if len(args) == 1 && portOpts.Latest { + port = args[0] + } + if len(port) > 0 { + fields := strings.Split(port, "/") + if len(fields) > 2 || len(fields) < 1 { + return errors.Errorf("port formats are port/protocol. '%s' is invalid", port) + } + if len(fields) == 1 { + fields = append(fields, "tcp") + } + + portNum, err := strconv.Atoi(fields[0]) + if err != nil { + return err + } + userPort = ocicni.PortMapping{ + HostPort: 0, + ContainerPort: int32(portNum), + Protocol: fields[1], + HostIP: "", + } + } + + reports, err := registry.ContainerEngine().ContainerPort(registry.GetContext(), container, portOpts) + if err != nil { + return err + } + var found bool + // Iterate mappings + for _, report := range reports { + for _, v := range report.Ports { + hostIP := v.HostIP + // Set host IP to 0.0.0.0 if blank + if hostIP == "" { + hostIP = "0.0.0.0" + } + if portOpts.All { + fmt.Printf("%s\t", report.Id[:12]) + } + // If not searching by port or port/proto, then dump what we see + if port == "" { + fmt.Printf("%d/%s -> %s:%d\n", v.ContainerPort, v.Protocol, hostIP, v.HostPort) + continue + } + if v == userPort { + fmt.Printf("%s:%d\n", hostIP, v.HostPort) + found = true + break + } + } + if !found && port != "" { + return errors.Errorf("failed to find published port %q", port) + } + } + return nil +} diff --git a/cmd/podman/containers/restart.go b/cmd/podman/containers/restart.go index 74df449a2..1a9d7f6c7 100644 --- a/cmd/podman/containers/restart.go +++ b/cmd/podman/containers/restart.go @@ -11,6 +11,7 @@ import ( "github.com/containers/libpod/pkg/domain/entities" "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) var ( @@ -30,6 +31,16 @@ var ( podman restart --latest podman restart ctrID1 ctrID2`, } + + containerRestartCommand = &cobra.Command{ + Use: restartCommand.Use, + Short: restartCommand.Short, + Long: restartCommand.Long, + RunE: restartCommand.RunE, + Example: `podman container restart ctrID + podman container restart --latest + podman container restart ctrID1 ctrID2`, + } ) var ( @@ -37,12 +48,7 @@ var ( restartTimeout uint ) -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: restartCommand, - }) - flags := restartCommand.Flags() +func restartFlags(flags *pflag.FlagSet) { flags.BoolVarP(&restartOptions.All, "all", "a", false, "Restart all non-running containers") flags.BoolVarP(&restartOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") flags.BoolVar(&restartOptions.Running, "running", false, "Restart only running containers when --all is used") @@ -53,6 +59,24 @@ func init() { flags.SetNormalizeFunc(utils.AliasFlags) } +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: restartCommand, + }) + flags := restartCommand.Flags() + restartFlags(flags) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: containerRestartCommand, + Parent: containerCmd, + }) + + containerRestartFlags := containerRestartCommand.Flags() + restartFlags(containerRestartFlags) +} + func restart(cmd *cobra.Command, args []string) error { var ( errs utils.OutputErrors diff --git a/cmd/podman/containers/rm.go b/cmd/podman/containers/rm.go index a22880d93..12a7a3d89 100644 --- a/cmd/podman/containers/rm.go +++ b/cmd/podman/containers/rm.go @@ -12,6 +12,7 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) var ( @@ -31,18 +32,24 @@ var ( podman rm --force --all podman rm -f c684f0d469f2`, } + + containerRmCommand = &cobra.Command{ + Use: rmCommand.Use, + Short: rmCommand.Use, + Long: rmCommand.Long, + RunE: rmCommand.RunE, + Example: `podman container rm imageID + podman container rm mywebserver myflaskserver 860a4b23 + podman container rm --force --all + podman container rm -f c684f0d469f2`, + } ) var ( rmOptions = entities.RmOptions{} ) -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: rmCommand, - }) - flags := rmCommand.Flags() +func rmFlags(flags *pflag.FlagSet) { flags.BoolVarP(&rmOptions.All, "all", "a", false, "Remove all containers") flags.BoolVarP(&rmOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified container is missing") flags.BoolVarP(&rmOptions.Force, "force", "f", false, "Force removal of a running or unusable container. The default is false") @@ -56,7 +63,24 @@ func init() { _ = flags.MarkHidden("cidfile") _ = flags.MarkHidden("storage") } +} + +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: rmCommand, + }) + flags := rmCommand.Flags() + rmFlags(flags) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: containerRmCommand, + Parent: containerCmd, + }) + containerRmFlags := containerRmCommand.Flags() + rmFlags(containerRmFlags) } func rm(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/containers/run.go b/cmd/podman/containers/run.go index 16a54e578..06b89b0fc 100644 --- a/cmd/podman/containers/run.go +++ b/cmd/podman/containers/run.go @@ -13,6 +13,7 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) var ( @@ -26,6 +27,16 @@ var ( podman run --network=host imageID dnf -y install java podman run --volume /var/hostdir:/var/ctrdir -i -t fedora /bin/bash`, } + + containerRunCommand = &cobra.Command{ + Use: runCommand.Use, + Short: runCommand.Short, + Long: runCommand.Long, + RunE: runCommand.RunE, + Example: `podman container run imageID ls -alF /etc + podman container run --network=host imageID dnf -y install java + podman container run --volume /var/hostdir:/var/ctrdir -i -t fedora /bin/bash`, + } ) var ( @@ -37,12 +48,7 @@ var ( runRmi bool ) -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode}, - Command: runCommand, - }) - flags := runCommand.Flags() +func runFlags(flags *pflag.FlagSet) { flags.SetInterspersed(false) flags.AddFlagSet(common.GetCreateFlags(&cliVals)) flags.AddFlagSet(common.GetNetFlags()) @@ -53,6 +59,23 @@ func init() { _ = flags.MarkHidden("authfile") } } +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode}, + Command: runCommand, + }) + flags := runCommand.Flags() + runFlags(flags) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode}, + Command: containerRunCommand, + Parent: containerCmd, + }) + + containerRunFlags := containerRunCommand.Flags() + runFlags(containerRunFlags) +} func run(cmd *cobra.Command, args []string) error { var err error diff --git a/cmd/podman/containers/start.go b/cmd/podman/containers/start.go index f2ee0f177..73f37e51f 100644 --- a/cmd/podman/containers/start.go +++ b/cmd/podman/containers/start.go @@ -10,6 +10,7 @@ import ( "github.com/containers/libpod/pkg/domain/entities" "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) var ( @@ -24,18 +25,23 @@ var ( podman start 860a4b231279 5421ab43b45 podman start --interactive --attach imageID`, } + + containerStartCommand = &cobra.Command{ + Use: startCommand.Use, + Short: startCommand.Short, + Long: startCommand.Long, + RunE: startCommand.RunE, + Example: `podman container start --latest + podman container start 860a4b231279 5421ab43b45 + podman container start --interactive --attach imageID`, + } ) var ( startOptions entities.ContainerStartOptions ) -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode}, - Command: startCommand, - }) - flags := startCommand.Flags() +func startFlags(flags *pflag.FlagSet) { flags.BoolVarP(&startOptions.Attach, "attach", "a", false, "Attach container's STDOUT and STDERR") flags.StringVar(&startOptions.DetachKeys, "detach-keys", containerConfig.DetachKeys(), "Select the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`") flags.BoolVarP(&startOptions.Interactive, "interactive", "i", false, "Keep STDIN open even if not attached") @@ -45,7 +51,23 @@ func init() { _ = flags.MarkHidden("latest") _ = flags.MarkHidden("sig-proxy") } +} +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode}, + Command: startCommand, + }) + flags := startCommand.Flags() + startFlags(flags) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode}, + Command: containerStartCommand, + Parent: containerCmd, + }) + containerStartFlags := containerStartCommand.Flags() + startFlags(containerStartFlags) } func start(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/containers/stop.go b/cmd/podman/containers/stop.go index 1856524c9..4a451134a 100644 --- a/cmd/podman/containers/stop.go +++ b/cmd/podman/containers/stop.go @@ -9,6 +9,7 @@ import ( "github.com/containers/libpod/cmd/podman/utils" "github.com/containers/libpod/pkg/domain/entities" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) var ( @@ -27,6 +28,16 @@ var ( podman stop --latest podman stop --time 2 mywebserver 6e534f14da9d`, } + + containerStopCommand = &cobra.Command{ + Use: stopCommand.Use, + Short: stopCommand.Short, + Long: stopCommand.Long, + RunE: stopCommand.RunE, + Example: `podman container stop ctrID + podman container stop --latest + podman container stop --time 2 mywebserver 6e534f14da9d`, + } ) var ( @@ -34,12 +45,7 @@ var ( stopTimeout uint ) -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: stopCommand, - }) - flags := stopCommand.Flags() +func stopFlags(flags *pflag.FlagSet) { flags.BoolVarP(&stopOptions.All, "all", "a", false, "Stop all running containers") flags.BoolVarP(&stopOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified container is missing") flags.StringArrayVarP(&stopOptions.CIDFiles, "cidfile", "", nil, "Read the container ID from the file") @@ -54,6 +60,24 @@ func init() { flags.SetNormalizeFunc(utils.AliasFlags) } +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: stopCommand, + }) + flags := stopCommand.Flags() + stopFlags(flags) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: containerStopCommand, + Parent: containerCmd, + }) + + containerStopFlags := containerStopCommand.Flags() + stopFlags(containerStopFlags) +} + func stop(cmd *cobra.Command, args []string) error { var ( errs utils.OutputErrors diff --git a/cmd/podman/containers/top.go b/cmd/podman/containers/top.go index db5213863..732a08623 100644 --- a/cmd/podman/containers/top.go +++ b/cmd/podman/containers/top.go @@ -12,6 +12,7 @@ import ( "github.com/containers/psgo" "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) var ( @@ -36,25 +37,46 @@ podman top --latest podman top ctrID pid seccomp args %C podman top ctrID -eo user,pid,comm`, } -) -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: topCommand, - }) + containerTopCommand = &cobra.Command{ + Use: topCommand.Use, + Short: topCommand.Short, + Long: topCommand.Long, + RunE: topCommand.RunE, + Example: `podman container top ctrID +podman container top --latest +podman container top ctrID pid seccomp args %C +podman container top ctrID -eo user,pid,comm`, + } +) - flags := topCommand.Flags() +func topFlags(flags *pflag.FlagSet) { flags.SetInterspersed(false) flags.BoolVar(&topOptions.ListDescriptors, "list-descriptors", false, "") flags.BoolVarP(&topOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - _ = flags.MarkHidden("list-descriptors") // meant only for bash completion if registry.IsRemote() { _ = flags.MarkHidden("latest") } } +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: topCommand, + }) + flags := topCommand.Flags() + topFlags(flags) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: containerTopCommand, + Parent: containerCmd, + }) + containerTopFlags := containerTopCommand.Flags() + topFlags(containerTopFlags) +} + func top(cmd *cobra.Command, args []string) error { if topOptions.ListDescriptors { fmt.Println(strings.Join(psgo.ListDescriptors(), "\n")) diff --git a/cmd/podman/containers/unmount.go b/cmd/podman/containers/unmount.go index 3dbfc1eae..a4550abbd 100644 --- a/cmd/podman/containers/unmount.go +++ b/cmd/podman/containers/unmount.go @@ -8,6 +8,7 @@ import ( "github.com/containers/libpod/cmd/podman/utils" "github.com/containers/libpod/pkg/domain/entities" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) var ( @@ -30,21 +31,44 @@ var ( podman umount ctrID1 ctrID2 ctrID3 podman umount --all`, } + + containerUnmountCommand = &cobra.Command{ + Use: umountCommand.Use, + Short: umountCommand.Short, + Long: umountCommand.Long, + RunE: umountCommand.RunE, + Example: `podman container umount ctrID + podman container umount ctrID1 ctrID2 ctrID3 + podman container umount --all`, + } ) var ( unmountOpts entities.ContainerUnmountOptions ) +func umountFlags(flags *pflag.FlagSet) { + flags.BoolVarP(&unmountOpts.All, "all", "a", false, "Umount all of the currently mounted containers") + flags.BoolVarP(&unmountOpts.Force, "force", "f", false, "Force the complete umount all of the currently mounted containers") + flags.BoolVarP(&unmountOpts.Latest, "latest", "l", false, "Act on the latest container podman is aware of") +} + func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ Mode: []entities.EngineMode{entities.ABIMode}, Command: umountCommand, }) flags := umountCommand.Flags() - flags.BoolVarP(&unmountOpts.All, "all", "a", false, "Umount all of the currently mounted containers") - flags.BoolVarP(&unmountOpts.Force, "force", "f", false, "Force the complete umount all of the currently mounted containers") - flags.BoolVarP(&unmountOpts.Latest, "latest", "l", false, "Act on the latest container podman is aware of") + umountFlags(flags) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode}, + Command: containerUnmountCommand, + Parent: containerCmd, + }) + + containerUmountFlags := containerUnmountCommand.Flags() + umountFlags(containerUmountFlags) } func unmount(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/containers/unpause.go b/cmd/podman/containers/unpause.go index ef874b042..adf8d12ee 100644 --- a/cmd/podman/containers/unpause.go +++ b/cmd/podman/containers/unpause.go @@ -10,6 +10,7 @@ import ( "github.com/containers/libpod/pkg/rootless" "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) var ( @@ -23,16 +24,37 @@ var ( podman unpause --all`, } unPauseOptions = entities.PauseUnPauseOptions{} + + containerUnpauseCommand = &cobra.Command{ + Use: unpauseCommand.Use, + Short: unpauseCommand.Short, + Long: unpauseCommand.Long, + RunE: unpauseCommand.RunE, + Example: `podman container unpause ctrID + podman container unpause --all`, + } ) +func unpauseFlags(flags *pflag.FlagSet) { + flags.BoolVarP(&unPauseOptions.All, "all", "a", false, "Pause all running containers") +} + func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, Command: unpauseCommand, - Parent: containerCmd, }) flags := unpauseCommand.Flags() - flags.BoolVarP(&unPauseOptions.All, "all", "a", false, "Pause all running containers") + unpauseFlags(flags) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: unpauseCommand, + Parent: containerCmd, + }) + + unpauseCommandFlags := containerUnpauseCommand.Flags() + unpauseFlags(unpauseCommandFlags) } func unpause(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/containers/wait.go b/cmd/podman/containers/wait.go index 47f28f4c6..da746361d 100644 --- a/cmd/podman/containers/wait.go +++ b/cmd/podman/containers/wait.go @@ -11,6 +11,7 @@ import ( "github.com/containers/libpod/pkg/domain/entities" "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) var ( @@ -26,6 +27,16 @@ var ( podman wait --interval 5000 ctrID podman wait ctrID1 ctrID2`, } + + containerWaitCommand = &cobra.Command{ + Use: waitCommand.Use, + Short: waitCommand.Short, + Long: waitCommand.Long, + RunE: waitCommand.RunE, + Example: `podman container wait --latest + podman container wait --interval 5000 ctrID + podman container wait ctrID1 ctrID2`, + } ) var ( @@ -33,13 +44,7 @@ var ( waitCondition string ) -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: waitCommand, - }) - - flags := waitCommand.Flags() +func waitFlags(flags *pflag.FlagSet) { flags.DurationVarP(&waitOptions.Interval, "interval", "i", time.Duration(250), "Milliseconds to wait before polling for completion") flags.BoolVarP(&waitOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") flags.StringVar(&waitCondition, "condition", "stopped", "Condition to wait on") @@ -49,6 +54,24 @@ func init() { } } +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: waitCommand, + }) + flags := waitCommand.Flags() + waitFlags(flags) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: containerWaitCommand, + Parent: containerCmd, + }) + + containerWaitFlags := containerWaitCommand.Flags() + waitFlags(containerWaitFlags) +} + func wait(cmd *cobra.Command, args []string) error { var ( err error diff --git a/cmd/podman/images/inspect.go b/cmd/podman/images/inspect.go index 11bef02ba..3190ab725 100644 --- a/cmd/podman/images/inspect.go +++ b/cmd/podman/images/inspect.go @@ -84,10 +84,14 @@ func inspect(cmd *cobra.Command, args []string) error { } } + var lastErr error for id, e := range results.Errors { - fmt.Fprintf(os.Stderr, "%s: %s\n", id, e.Error()) + if lastErr != nil { + fmt.Fprintf(os.Stderr, "%s: %s\n", id, lastErr.Error()) + } + lastErr = e } - return nil + return lastErr } func inspectFormat(row string) string { |