summaryrefslogtreecommitdiff
path: root/cmd/podman
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/podman')
-rw-r--r--cmd/podman/common/specgen.go274
-rw-r--r--cmd/podman/containers/attach.go35
-rw-r--r--cmd/podman/containers/commit.go36
-rw-r--r--cmd/podman/containers/cp.go55
-rw-r--r--cmd/podman/containers/create.go32
-rw-r--r--cmd/podman/containers/exec.go36
-rw-r--r--cmd/podman/containers/export.go25
-rw-r--r--cmd/podman/containers/kill.go36
-rw-r--r--cmd/podman/containers/mount.go28
-rw-r--r--cmd/podman/containers/pause.go25
-rw-r--r--cmd/podman/containers/port.go123
-rw-r--r--cmd/podman/containers/restart.go36
-rw-r--r--cmd/podman/containers/rm.go36
-rw-r--r--cmd/podman/containers/run.go35
-rw-r--r--cmd/podman/containers/start.go34
-rw-r--r--cmd/podman/containers/stop.go36
-rw-r--r--cmd/podman/containers/top.go38
-rw-r--r--cmd/podman/containers/unmount.go30
-rw-r--r--cmd/podman/containers/unpause.go26
-rw-r--r--cmd/podman/containers/wait.go37
-rw-r--r--cmd/podman/images/inspect.go8
21 files changed, 831 insertions, 190 deletions
diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go
index 1eb8fc0bd..12fd16551 100644
--- a/cmd/podman/common/specgen.go
+++ b/cmd/podman/common/specgen.go
@@ -23,49 +23,135 @@ import (
"github.com/pkg/errors"
)
-func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string) error {
- var (
- err error
- //namespaces map[string]string
- )
+func getCPULimits(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string) (*specs.LinuxCPU, error) {
+ cpu := &specs.LinuxCPU{}
+ hasLimits := false
- // validate flags as needed
- if err := c.validate(); err != nil {
- return nil
+ if c.CPUShares > 0 {
+ cpu.Shares = &c.CPUShares
+ hasLimits = true
+ }
+ if c.CPUPeriod > 0 {
+ cpu.Period = &c.CPUPeriod
+ hasLimits = true
+ }
+ if c.CPUSetCPUs != "" {
+ cpu.Cpus = c.CPUSetCPUs
+ hasLimits = true
+ }
+ if c.CPUSetMems != "" {
+ cpu.Mems = c.CPUSetMems
+ hasLimits = true
+ }
+ if c.CPUQuota > 0 {
+ cpu.Quota = &c.CPUQuota
+ hasLimits = true
+ }
+ if c.CPURTPeriod > 0 {
+ cpu.RealtimePeriod = &c.CPURTPeriod
+ hasLimits = true
+ }
+ if c.CPURTRuntime > 0 {
+ cpu.RealtimeRuntime = &c.CPURTRuntime
+ hasLimits = true
}
- s.User = c.User
- inputCommand := args[1:]
- if len(c.HealthCmd) > 0 {
- s.HealthConfig, err = makeHealthCheckFromCli(c.HealthCmd, c.HealthInterval, c.HealthRetries, c.HealthTimeout, c.HealthStartPeriod)
+ if !hasLimits {
+ return nil, nil
+ }
+ return cpu, nil
+}
+
+func getIOLimits(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string) (*specs.LinuxBlockIO, error) {
+ var err error
+ io := &specs.LinuxBlockIO{}
+ hasLimits := false
+ if b := c.BlkIOWeight; len(b) > 0 {
+ u, err := strconv.ParseUint(b, 10, 16)
if err != nil {
- return err
+ return nil, errors.Wrapf(err, "invalid value for blkio-weight")
}
+ nu := uint16(u)
+ io.Weight = &nu
+ hasLimits = true
}
- s.IDMappings, err = util.ParseIDMapping(ns.UsernsMode(c.UserNS), c.UIDMap, c.GIDMap, c.SubUIDName, c.SubGIDName)
- if err != nil {
- return err
+ if len(c.BlkIOWeightDevice) > 0 {
+ if err := parseWeightDevices(c.BlkIOWeightDevice, s); err != nil {
+ return nil, err
+ }
+ hasLimits = true
}
- if s.ResourceLimits == nil {
- s.ResourceLimits = &specs.LinuxResources{}
+
+ if bps := c.DeviceReadBPs; len(bps) > 0 {
+ if s.ThrottleReadBpsDevice, err = parseThrottleBPSDevices(bps); err != nil {
+ return nil, err
+ }
+ hasLimits = true
+ }
+
+ if bps := c.DeviceWriteBPs; len(bps) > 0 {
+ if s.ThrottleWriteBpsDevice, err = parseThrottleBPSDevices(bps); err != nil {
+ return nil, err
+ }
+ hasLimits = true
+ }
+
+ if iops := c.DeviceReadIOPs; len(iops) > 0 {
+ if s.ThrottleReadIOPSDevice, err = parseThrottleIOPsDevices(iops); err != nil {
+ return nil, err
+ }
+ hasLimits = true
+ }
+
+ if iops := c.DeviceWriteIOPs; len(iops) > 0 {
+ if s.ThrottleWriteIOPSDevice, err = parseThrottleIOPsDevices(iops); err != nil {
+ return nil, err
+ }
+ hasLimits = true
+ }
+
+ if !hasLimits {
+ return nil, nil
+ }
+ return io, nil
+}
+
+func getPidsLimits(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string) (*specs.LinuxPids, error) {
+ pids := &specs.LinuxPids{}
+ hasLimits := false
+ if c.PIDsLimit > 0 {
+ pids.Limit = c.PIDsLimit
+ hasLimits = true
+ }
+ if c.CGroups == "disabled" && c.PIDsLimit > 0 {
+ s.ResourceLimits.Pids.Limit = -1
}
- if s.ResourceLimits.Memory == nil {
- s.ResourceLimits.Memory = &specs.LinuxMemory{}
+ if !hasLimits {
+ return nil, nil
}
+ return pids, nil
+}
+
+func getMemoryLimits(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string) (*specs.LinuxMemory, error) {
+ var err error
+ memory := &specs.LinuxMemory{}
+ hasLimits := false
if m := c.Memory; len(m) > 0 {
ml, err := units.RAMInBytes(m)
if err != nil {
- return errors.Wrapf(err, "invalid value for memory")
+ return nil, errors.Wrapf(err, "invalid value for memory")
}
- s.ResourceLimits.Memory.Limit = &ml
+ memory.Limit = &ml
+ hasLimits = true
}
if m := c.MemoryReservation; len(m) > 0 {
mr, err := units.RAMInBytes(m)
if err != nil {
- return errors.Wrapf(err, "invalid value for memory")
+ return nil, errors.Wrapf(err, "invalid value for memory")
}
- s.ResourceLimits.Memory.Reservation = &mr
+ memory.Reservation = &mr
+ hasLimits = true
}
if m := c.MemorySwap; len(m) > 0 {
var ms int64
@@ -75,28 +161,58 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
} else {
ms, err = units.RAMInBytes(m)
if err != nil {
- return errors.Wrapf(err, "invalid value for memory")
+ return nil, errors.Wrapf(err, "invalid value for memory")
}
}
- s.ResourceLimits.Memory.Swap = &ms
+ memory.Swap = &ms
+ hasLimits = true
}
if m := c.KernelMemory; len(m) > 0 {
mk, err := units.RAMInBytes(m)
if err != nil {
- return errors.Wrapf(err, "invalid value for kernel-memory")
+ return nil, errors.Wrapf(err, "invalid value for kernel-memory")
}
- s.ResourceLimits.Memory.Kernel = &mk
+ memory.Kernel = &mk
+ hasLimits = true
}
- if s.ResourceLimits.BlockIO == nil {
- s.ResourceLimits.BlockIO = &specs.LinuxBlockIO{}
+ if c.MemorySwappiness >= 0 {
+ swappiness := uint64(c.MemorySwappiness)
+ memory.Swappiness = &swappiness
+ hasLimits = true
}
- if b := c.BlkIOWeight; len(b) > 0 {
- u, err := strconv.ParseUint(b, 10, 16)
+ if c.OOMKillDisable {
+ memory.DisableOOMKiller = &c.OOMKillDisable
+ hasLimits = true
+ }
+ if !hasLimits {
+ return nil, nil
+ }
+ return memory, nil
+}
+
+func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string) error {
+ var (
+ err error
+ //namespaces map[string]string
+ )
+
+ // validate flags as needed
+ if err := c.validate(); err != nil {
+ return nil
+ }
+
+ s.User = c.User
+ inputCommand := args[1:]
+ if len(c.HealthCmd) > 0 {
+ s.HealthConfig, err = makeHealthCheckFromCli(c.HealthCmd, c.HealthInterval, c.HealthRetries, c.HealthTimeout, c.HealthStartPeriod)
if err != nil {
- return errors.Wrapf(err, "invalid value for blkio-weight")
+ return err
}
- nu := uint16(u)
- s.ResourceLimits.BlockIO.Weight = &nu
+ }
+
+ s.IDMappings, err = util.ParseIDMapping(ns.UsernsMode(c.UserNS), c.UIDMap, c.GIDMap, c.SubUIDName, c.SubGIDName)
+ if err != nil {
+ return err
}
s.Terminal = c.TTY
@@ -268,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 {
@@ -328,12 +446,24 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
if s.ResourceLimits == nil {
s.ResourceLimits = &specs.LinuxResources{}
}
- if s.ResourceLimits.Memory == nil {
- s.ResourceLimits.Memory = &specs.LinuxMemory{}
+ s.ResourceLimits.Memory, err = getMemoryLimits(s, c, args)
+ if err != nil {
+ return err
}
- if c.MemorySwappiness >= 0 {
- swappiness := uint64(c.MemorySwappiness)
- s.ResourceLimits.Memory.Swappiness = &swappiness
+ s.ResourceLimits.BlockIO, err = getIOLimits(s, c, args)
+ if err != nil {
+ return err
+ }
+ s.ResourceLimits.Pids, err = getPidsLimits(s, c, args)
+ if err != nil {
+ return err
+ }
+ s.ResourceLimits.CPU, err = getCPULimits(s, c, args)
+ if err != nil {
+ return err
+ }
+ if s.ResourceLimits.CPU == nil && s.ResourceLimits.Pids == nil && s.ResourceLimits.BlockIO == nil && s.ResourceLimits.Memory == nil {
+ s.ResourceLimits = nil
}
if s.LogConfiguration == nil {
@@ -343,15 +473,6 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
if ld := c.LogDriver; len(ld) > 0 {
s.LogConfiguration.Driver = ld
}
- if s.ResourceLimits.Pids == nil {
- s.ResourceLimits.Pids = &specs.LinuxPids{}
- }
- if c.PIDsLimit > 0 {
- s.ResourceLimits.Pids.Limit = c.PIDsLimit
- }
- if c.CGroups == "disabled" && c.PIDsLimit > 0 {
- s.ResourceLimits.Pids.Limit = -1
- }
// TODO WTF
//cgroup := &cc.CgroupConfig{
// Cgroups: c.String("cgroups"),
@@ -457,32 +578,6 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
// quiet
//DeviceCgroupRules: c.StringSlice("device-cgroup-rule"),
- if bps := c.DeviceReadBPs; len(bps) > 0 {
- if s.ThrottleReadBpsDevice, err = parseThrottleBPSDevices(bps); err != nil {
- return err
- }
- }
-
- if bps := c.DeviceWriteBPs; len(bps) > 0 {
- if s.ThrottleWriteBpsDevice, err = parseThrottleBPSDevices(bps); err != nil {
- return err
- }
- }
-
- if iops := c.DeviceReadIOPs; len(iops) > 0 {
- if s.ThrottleReadIOPSDevice, err = parseThrottleIOPsDevices(iops); err != nil {
- return err
- }
- }
-
- if iops := c.DeviceWriteIOPs; len(iops) > 0 {
- if s.ThrottleWriteIOPSDevice, err = parseThrottleIOPsDevices(iops); err != nil {
- return err
- }
- }
-
- s.ResourceLimits.Memory.DisableOOMKiller = &c.OOMKillDisable
-
// Rlimits/Ulimits
for _, u := range c.Ulimit {
if u == "host" {
@@ -517,35 +612,6 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
s.LogConfiguration.Options = logOpts
s.Name = c.Name
- if err := parseWeightDevices(c.BlkIOWeightDevice, s); err != nil {
- return err
- }
-
- if s.ResourceLimits.CPU == nil {
- s.ResourceLimits.CPU = &specs.LinuxCPU{}
- }
- if c.CPUShares > 0 {
- s.ResourceLimits.CPU.Shares = &c.CPUShares
- }
- if c.CPUPeriod > 0 {
- s.ResourceLimits.CPU.Period = &c.CPUPeriod
- }
-
- if c.CPUSetCPUs != "" {
- s.ResourceLimits.CPU.Cpus = c.CPUSetCPUs
- }
- if c.CPUSetMems != "" {
- s.ResourceLimits.CPU.Mems = c.CPUSetMems
- }
- if c.CPUQuota > 0 {
- s.ResourceLimits.CPU.Quota = &c.CPUQuota
- }
- if c.CPURTPeriod > 0 {
- s.ResourceLimits.CPU.RealtimePeriod = &c.CPURTPeriod
- }
- if c.CPURTRuntime > 0 {
- s.ResourceLimits.CPU.RealtimeRuntime = &c.CPURTRuntime
- }
s.OOMScoreAdj = &c.OOMScoreAdj
s.RestartPolicy = c.Restart
s.Remove = c.Rm
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 {