summaryrefslogtreecommitdiff
path: root/cmd/podman
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/podman')
-rw-r--r--cmd/podman/common/create.go5
-rw-r--r--cmd/podman/common/create_opts.go1
-rw-r--r--cmd/podman/common/default.go2
-rw-r--r--cmd/podman/common/specgen.go13
-rw-r--r--cmd/podman/common/util.go57
-rw-r--r--cmd/podman/containers/attach.go4
-rw-r--r--cmd/podman/containers/container.go2
-rw-r--r--cmd/podman/containers/diff.go2
-rw-r--r--cmd/podman/containers/exec.go8
-rw-r--r--cmd/podman/containers/ps.go2
-rw-r--r--cmd/podman/containers/stats.go10
-rw-r--r--cmd/podman/containers/stop.go3
-rw-r--r--cmd/podman/containers/wait.go4
-rw-r--r--cmd/podman/diff.go2
-rw-r--r--cmd/podman/images/image.go2
-rw-r--r--cmd/podman/images/list.go4
-rw-r--r--cmd/podman/networks/list.go14
-rw-r--r--cmd/podman/parse/common.go55
-rw-r--r--cmd/podman/play/kube.go34
-rw-r--r--cmd/podman/pods/create.go14
-rw-r--r--cmd/podman/pods/pod.go2
-rw-r--r--cmd/podman/pods/ps.go10
-rw-r--r--cmd/podman/pods/rm.go25
-rw-r--r--cmd/podman/pods/start.go22
-rw-r--r--cmd/podman/pods/stats.go4
-rw-r--r--cmd/podman/pods/stop.go35
-rw-r--r--cmd/podman/registry/json.go4
-rw-r--r--cmd/podman/report/report.go2
-rw-r--r--cmd/podman/root.go8
-rw-r--r--cmd/podman/system/df.go6
-rw-r--r--cmd/podman/system/events.go6
-rw-r--r--cmd/podman/system/service.go4
-rw-r--r--cmd/podman/system/system.go2
-rw-r--r--cmd/podman/validate/args.go4
-rw-r--r--cmd/podman/validate/choice.go16
-rw-r--r--cmd/podman/volumes/create.go2
-rw-r--r--cmd/podman/volumes/volume.go2
37 files changed, 287 insertions, 105 deletions
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go
index 86cd51643..e79c5c20b 100644
--- a/cmd/podman/common/create.go
+++ b/cmd/podman/common/create.go
@@ -338,6 +338,11 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet {
"pod", "",
"Run container in an existing pod",
)
+ createFlags.StringVar(
+ &cf.PodIDFile,
+ "pod-id-file", "",
+ "Read the pod ID from the file",
+ )
createFlags.BoolVar(
&cf.Privileged,
"privileged", false,
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go
index 4cba5daf7..98dc6744c 100644
--- a/cmd/podman/common/create_opts.go
+++ b/cmd/podman/common/create_opts.go
@@ -68,6 +68,7 @@ type ContainerCLIOpts struct {
PID string
PIDsLimit int64
Pod string
+ PodIDFile string
Privileged bool
PublishAll bool
Pull string
diff --git a/cmd/podman/common/default.go b/cmd/podman/common/default.go
index 7233b2091..6e5994b18 100644
--- a/cmd/podman/common/default.go
+++ b/cmd/podman/common/default.go
@@ -16,5 +16,5 @@ var (
// DefaultImageVolume default value
DefaultImageVolume = "bind"
// Pull in configured json library
- json = registry.JsonLibrary()
+ json = registry.JSONLibrary()
)
diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go
index 26003b40f..fee9d8c7b 100644
--- a/cmd/podman/common/specgen.go
+++ b/cmd/podman/common/specgen.go
@@ -254,6 +254,17 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
s.PublishExposedPorts = c.PublishAll
s.Pod = c.Pod
+ if len(c.PodIDFile) > 0 {
+ if len(s.Pod) > 0 {
+ return errors.New("Cannot specify both --pod and --pod-id-file")
+ }
+ podID, err := ReadPodIDFile(c.PodIDFile)
+ if err != nil {
+ return err
+ }
+ s.Pod = podID
+ }
+
expose, err := createExpose(c.Expose)
if err != nil {
return err
@@ -669,7 +680,7 @@ func makeHealthCheckFromCli(inCmd, interval string, retries uint, timeout, start
hc.Interval = intervalDuration
if retries < 1 {
- return nil, errors.New("healthcheck-retries must be greater than 0.")
+ return nil, errors.New("healthcheck-retries must be greater than 0")
}
hc.Retries = int(retries)
timeoutDuration, err := time.ParseDuration(timeout)
diff --git a/cmd/podman/common/util.go b/cmd/podman/common/util.go
index a3626b4e4..ce323a4ba 100644
--- a/cmd/podman/common/util.go
+++ b/cmd/podman/common/util.go
@@ -1,6 +1,7 @@
package common
import (
+ "io/ioutil"
"net"
"strconv"
"strings"
@@ -10,6 +11,30 @@ import (
"github.com/sirupsen/logrus"
)
+// ReadPodIDFile reads the specified file and returns its content (i.e., first
+// line).
+func ReadPodIDFile(path string) (string, error) {
+ content, err := ioutil.ReadFile(path)
+ if err != nil {
+ return "", errors.Wrap(err, "error reading pod ID file")
+ }
+ return strings.Split(string(content), "\n")[0], nil
+}
+
+// ReadPodIDFiles reads the specified files and returns their content (i.e.,
+// first line).
+func ReadPodIDFiles(files []string) ([]string, error) {
+ ids := []string{}
+ for _, file := range files {
+ id, err := ReadPodIDFile(file)
+ if err != nil {
+ return nil, err
+ }
+ ids = append(ids, id)
+ }
+ return ids, nil
+}
+
// createExpose parses user-provided exposed port definitions and converts them
// into SpecGen format.
// TODO: The SpecGen format should really handle ranges more sanely - we could
@@ -71,14 +96,44 @@ func createPortBindings(ports []string) ([]specgen.PortMapping, error) {
return nil, errors.Errorf("invalid port format - protocol can only be specified once")
}
- splitPort := strings.Split(splitProto[0], ":")
+ remainder := splitProto[0]
+ haveV6 := false
+
+ // Check for an IPv6 address in brackets
+ splitV6 := strings.Split(remainder, "]")
+ switch len(splitV6) {
+ case 1:
+ // Do nothing, proceed as before
+ case 2:
+ // We potentially have an IPv6 address
+ haveV6 = true
+ if !strings.HasPrefix(splitV6[0], "[") {
+ return nil, errors.Errorf("invalid port format - IPv6 addresses must be enclosed by []")
+ }
+ if !strings.HasPrefix(splitV6[1], ":") {
+ return nil, errors.Errorf("invalid port format - IPv6 address must be followed by a colon (':')")
+ }
+ ipNoPrefix := strings.TrimPrefix(splitV6[0], "[")
+ hostIP = &ipNoPrefix
+ remainder = strings.TrimPrefix(splitV6[1], ":")
+ default:
+ return nil, errors.Errorf("invalid port format - at most one IPv6 address can be specified in a --publish")
+ }
+
+ splitPort := strings.Split(remainder, ":")
switch len(splitPort) {
case 1:
+ if haveV6 {
+ return nil, errors.Errorf("invalid port format - must provide host and destination port if specifying an IP")
+ }
ctrPort = splitPort[0]
case 2:
hostPort = &(splitPort[0])
ctrPort = splitPort[1]
case 3:
+ if haveV6 {
+ return nil, errors.Errorf("invalid port format - when v6 address specified, must be [ipv6]:hostPort:ctrPort")
+ }
hostIP = &(splitPort[0])
hostPort = &(splitPort[1])
ctrPort = splitPort[2]
diff --git a/cmd/podman/containers/attach.go b/cmd/podman/containers/attach.go
index 9f29d1664..9ef9d79f0 100644
--- a/cmd/podman/containers/attach.go
+++ b/cmd/podman/containers/attach.go
@@ -18,7 +18,7 @@ var (
Short: "Attach to a running container",
Long: attachDescription,
RunE: attach,
- Args: validate.IdOrLatestArgs,
+ Args: validate.IDOrLatestArgs,
Example: `podman attach ctrID
podman attach 1234
podman attach --no-stdin foobar`,
@@ -29,7 +29,7 @@ var (
Short: attachCommand.Short,
Long: attachCommand.Long,
RunE: attachCommand.RunE,
- Args: validate.IdOrLatestArgs,
+ Args: validate.IDOrLatestArgs,
Example: `podman container attach ctrID
podman container attach 1234
podman container attach --no-stdin foobar`,
diff --git a/cmd/podman/containers/container.go b/cmd/podman/containers/container.go
index a102318fb..3ff341dcd 100644
--- a/cmd/podman/containers/container.go
+++ b/cmd/podman/containers/container.go
@@ -10,7 +10,7 @@ import (
var (
// Pull in configured json library
- json = registry.JsonLibrary()
+ json = registry.JSONLibrary()
// Command: podman _container_
containerCmd = &cobra.Command{
diff --git a/cmd/podman/containers/diff.go b/cmd/podman/containers/diff.go
index 59b788010..33b1c1126 100644
--- a/cmd/podman/containers/diff.go
+++ b/cmd/podman/containers/diff.go
@@ -13,7 +13,7 @@ var (
// podman container _diff_
diffCmd = &cobra.Command{
Use: "diff [flags] CONTAINER",
- Args: validate.IdOrLatestArgs,
+ Args: validate.IDOrLatestArgs,
Short: "Inspect changes on container's file systems",
Long: `Displays changes on a container filesystem. The container will be compared to its parent layer.`,
RunE: diff,
diff --git a/cmd/podman/containers/exec.go b/cmd/podman/containers/exec.go
index 41f100768..ce48af618 100644
--- a/cmd/podman/containers/exec.go
+++ b/cmd/podman/containers/exec.go
@@ -84,7 +84,7 @@ func init() {
}
func exec(cmd *cobra.Command, args []string) error {
- var nameOrId string
+ var nameOrID string
if len(args) == 0 && !execOpts.Latest {
return errors.New("exec requires the name or ID of a container or the --latest flag")
@@ -92,7 +92,7 @@ func exec(cmd *cobra.Command, args []string) error {
execOpts.Cmd = args
if !execOpts.Latest {
execOpts.Cmd = args[1:]
- nameOrId = args[0]
+ nameOrID = args[0]
}
// Validate given environment variables
execOpts.Envs = make(map[string]string)
@@ -122,12 +122,12 @@ func exec(cmd *cobra.Command, args []string) error {
streams.AttachOutput = true
streams.AttachError = true
- exitCode, err := registry.ContainerEngine().ContainerExec(registry.GetContext(), nameOrId, execOpts, streams)
+ exitCode, err := registry.ContainerEngine().ContainerExec(registry.GetContext(), nameOrID, execOpts, streams)
registry.SetExitCode(exitCode)
return err
}
- id, err := registry.ContainerEngine().ContainerExecDetached(registry.GetContext(), nameOrId, execOpts)
+ id, err := registry.ContainerEngine().ContainerExecDetached(registry.GetContext(), nameOrID, execOpts)
if err != nil {
return err
}
diff --git a/cmd/podman/containers/ps.go b/cmd/podman/containers/ps.go
index 4d12d2534..a29b4da3d 100644
--- a/cmd/podman/containers/ps.go
+++ b/cmd/podman/containers/ps.go
@@ -67,7 +67,7 @@ func listFlagSet(flags *pflag.FlagSet) {
flags.BoolVar(&listOpts.Sync, "sync", false, "Sync container state with OCI runtime")
flags.UintVarP(&listOpts.Watch, "watch", "w", 0, "Watch the ps output on an interval in seconds")
- sort := validate.ChoiceValue(&listOpts.Sort, "command", "created", "id", "image", "names", "runningfor", "size", "status")
+ sort := validate.Value(&listOpts.Sort, "command", "created", "id", "image", "names", "runningfor", "size", "status")
flags.Var(sort, "sort", "Sort output by: "+sort.Choices())
if registry.IsRemote() {
diff --git a/cmd/podman/containers/stats.go b/cmd/podman/containers/stats.go
index c61b161e4..11aa3a4d2 100644
--- a/cmd/podman/containers/stats.go
+++ b/cmd/podman/containers/stats.go
@@ -87,13 +87,13 @@ func init() {
func checkStatOptions(cmd *cobra.Command, args []string) error {
opts := 0
if statsOptions.All {
- opts += 1
+ opts++
}
if statsOptions.Latest {
- opts += 1
+ opts++
}
if len(args) > 0 {
- opts += 1
+ opts++
}
if opts > 1 {
return errors.Errorf("--all, --latest and containers cannot be used together")
@@ -219,9 +219,9 @@ func combineHumanValues(a, b uint64) string {
func outputJSON(stats []*containerStats) error {
type jstat struct {
- Id string `json:"id"`
+ Id string `json:"id"` //nolint
Name string `json:"name"`
- CpuPercent string `json:"cpu_percent"`
+ CpuPercent string `json:"cpu_percent"` //nolint
MemUsage string `json:"mem_usage"`
MemPerc string `json:"mem_percent"`
NetIO string `json:"net_io"`
diff --git a/cmd/podman/containers/stop.go b/cmd/podman/containers/stop.go
index 22c487961..0f2a91af0 100644
--- a/cmd/podman/containers/stop.go
+++ b/cmd/podman/containers/stop.go
@@ -85,9 +85,8 @@ func stop(cmd *cobra.Command, args []string) error {
var (
errs utils.OutputErrors
)
- stopOptions.Timeout = containerConfig.Engine.StopTimeout
if cmd.Flag("time").Changed {
- stopOptions.Timeout = stopTimeout
+ stopOptions.Timeout = &stopTimeout
}
responses, err := registry.ContainerEngine().ContainerStop(context.Background(), args, stopOptions)
diff --git a/cmd/podman/containers/wait.go b/cmd/podman/containers/wait.go
index ca3883091..115bb3eea 100644
--- a/cmd/podman/containers/wait.go
+++ b/cmd/podman/containers/wait.go
@@ -23,7 +23,7 @@ var (
Short: "Block on one or more containers",
Long: waitDescription,
RunE: wait,
- Args: validate.IdOrLatestArgs,
+ Args: validate.IDOrLatestArgs,
Example: `podman wait --interval 5000 ctrID
podman wait ctrID1 ctrID2`,
}
@@ -33,7 +33,7 @@ var (
Short: waitCommand.Short,
Long: waitCommand.Long,
RunE: waitCommand.RunE,
- Args: validate.IdOrLatestArgs,
+ Args: validate.IDOrLatestArgs,
Example: `podman container wait --interval 5000 ctrID
podman container wait ctrID1 ctrID2`,
}
diff --git a/cmd/podman/diff.go b/cmd/podman/diff.go
index 1ff2fce40..d635ea57a 100644
--- a/cmd/podman/diff.go
+++ b/cmd/podman/diff.go
@@ -18,7 +18,7 @@ var (
diffDescription = `Displays changes on a container or image's filesystem. The container or image will be compared to its parent layer.`
diffCmd = &cobra.Command{
Use: "diff [flags] {CONTAINER_ID | IMAGE_ID}",
- Args: validate.IdOrLatestArgs,
+ Args: validate.IDOrLatestArgs,
Short: "Display the changes of object's file system",
Long: diffDescription,
TraverseChildren: true,
diff --git a/cmd/podman/images/image.go b/cmd/podman/images/image.go
index 790c16c05..ebef126c0 100644
--- a/cmd/podman/images/image.go
+++ b/cmd/podman/images/image.go
@@ -9,7 +9,7 @@ import (
var (
// Pull in configured json library
- json = registry.JsonLibrary()
+ json = registry.JSONLibrary()
// Command: podman _image_
imageCmd = &cobra.Command{
diff --git a/cmd/podman/images/list.go b/cmd/podman/images/list.go
index 23757104b..236ae15b4 100644
--- a/cmd/podman/images/list.go
+++ b/cmd/podman/images/list.go
@@ -100,7 +100,7 @@ func images(cmd *cobra.Command, args []string) error {
switch {
case listFlag.quiet:
- return writeId(summaries)
+ return writeID(summaries)
case cmd.Flag("format").Changed && listFlag.format == "json":
return writeJSON(summaries)
default:
@@ -108,7 +108,7 @@ func images(cmd *cobra.Command, args []string) error {
}
}
-func writeId(imageS []*entities.ImageSummary) error {
+func writeID(imageS []*entities.ImageSummary) error {
var ids = map[string]struct{}{}
for _, e := range imageS {
i := "sha256:" + e.ID
diff --git a/cmd/podman/networks/list.go b/cmd/podman/networks/list.go
index 24604c055..498a4dc18 100644
--- a/cmd/podman/networks/list.go
+++ b/cmd/podman/networks/list.go
@@ -33,8 +33,8 @@ var (
var (
networkListOptions entities.NetworkListOptions
- headers string = "NAME\tVERSION\tPLUGINS\n"
- defaultListRow string = "{{.Name}}\t{{.Version}}\t{{.Plugins}}\n"
+ headers = "NAME\tVERSION\tPLUGINS\n"
+ defaultListRow = "{{.Name}}\t{{.Version}}\t{{.Plugins}}\n"
)
func networkListFlags(flags *pflag.FlagSet) {
@@ -57,7 +57,7 @@ func init() {
func networkList(cmd *cobra.Command, args []string) error {
var (
- nlprs []NetworkListPrintReports
+ nlprs []ListPrintReports
)
// validate the filter pattern.
@@ -83,7 +83,7 @@ func networkList(cmd *cobra.Command, args []string) error {
}
for _, r := range responses {
- nlprs = append(nlprs, NetworkListPrintReports{r})
+ nlprs = append(nlprs, ListPrintReports{r})
}
row := networkListOptions.Format
@@ -125,14 +125,14 @@ func jsonOut(responses []*entities.NetworkListReport) error {
return nil
}
-type NetworkListPrintReports struct {
+type ListPrintReports struct {
*entities.NetworkListReport
}
-func (n NetworkListPrintReports) Version() string {
+func (n ListPrintReports) Version() string {
return n.CNIVersion
}
-func (n NetworkListPrintReports) Plugins() string {
+func (n ListPrintReports) Plugins() string {
return network.GetCNIPlugins(n.NetworkConfigList)
}
diff --git a/cmd/podman/parse/common.go b/cmd/podman/parse/common.go
index 13f425b6d..b3aa88da2 100644
--- a/cmd/podman/parse/common.go
+++ b/cmd/podman/parse/common.go
@@ -5,6 +5,10 @@ import (
"github.com/spf13/cobra"
)
+// TODO: the two functions here are almost identical. It may be worth looking
+// into generalizing the two a bit more and share code but time is scarce and
+// we only live once.
+
// CheckAllLatestAndCIDFile checks that --all and --latest are used correctly.
// If cidfile is set, also check for the --cidfile flag.
func CheckAllLatestAndCIDFile(c *cobra.Command, args []string, ignoreArgLen bool, cidfile bool) error {
@@ -55,3 +59,54 @@ func CheckAllLatestAndCIDFile(c *cobra.Command, args []string, ignoreArgLen bool
}
return nil
}
+
+// CheckAllLatestAndPodIDFile checks that --all and --latest are used correctly.
+// If withIDFile is set, also check for the --pod-id-file flag.
+func CheckAllLatestAndPodIDFile(c *cobra.Command, args []string, ignoreArgLen bool, withIDFile bool) error {
+ argLen := len(args)
+ if c.Flags().Lookup("all") == nil || c.Flags().Lookup("latest") == nil {
+ if !withIDFile {
+ return errors.New("unable to lookup values for 'latest' or 'all'")
+ } else if c.Flags().Lookup("pod-id-file") == nil {
+ return errors.New("unable to lookup values for 'latest', 'all' or 'pod-id-file'")
+ }
+ }
+
+ specifiedAll, _ := c.Flags().GetBool("all")
+ specifiedLatest, _ := c.Flags().GetBool("latest")
+ specifiedPodIDFile := false
+ if pid, _ := c.Flags().GetStringArray("pod-id-file"); len(pid) > 0 {
+ specifiedPodIDFile = true
+ }
+
+ if specifiedPodIDFile && (specifiedAll || specifiedLatest) {
+ return errors.Errorf("--all, --latest and --pod-id-file cannot be used together")
+ } else if specifiedAll && specifiedLatest {
+ return errors.Errorf("--all and --latest cannot be used together")
+ }
+
+ if (argLen > 0) && specifiedAll {
+ return errors.Errorf("no arguments are needed with --all")
+ }
+
+ if ignoreArgLen {
+ return nil
+ }
+
+ if argLen > 0 {
+ if specifiedLatest {
+ return errors.Errorf("no arguments are needed with --latest")
+ } else if withIDFile && (specifiedLatest || specifiedPodIDFile) {
+ return errors.Errorf("no arguments are needed with --latest or --pod-id-file")
+ }
+ }
+
+ if specifiedPodIDFile {
+ return nil
+ }
+
+ if argLen < 1 && !specifiedAll && !specifiedLatest && !specifiedPodIDFile {
+ return errors.Errorf("you must provide at least one name or id")
+ }
+ return nil
+}
diff --git a/cmd/podman/play/kube.go b/cmd/podman/play/kube.go
index 1fbf24d5e..c26ca9853 100644
--- a/cmd/podman/play/kube.go
+++ b/cmd/podman/play/kube.go
@@ -92,21 +92,29 @@ func kube(cmd *cobra.Command, args []string) error {
return err
}
- for _, l := range report.Logs {
- fmt.Fprintf(os.Stderr, l)
+ for _, pod := range report.Pods {
+ for _, l := range pod.Logs {
+ fmt.Fprintf(os.Stderr, l)
+ }
}
- fmt.Printf("Pod:\n%s\n", report.Pod)
- switch len(report.Containers) {
- case 0:
- return nil
- case 1:
- fmt.Printf("Container:\n")
- default:
- fmt.Printf("Containers:\n")
- }
- for _, ctr := range report.Containers {
- fmt.Println(ctr)
+ for _, pod := range report.Pods {
+ fmt.Printf("Pod:\n")
+ fmt.Println(pod.ID)
+
+ switch len(pod.Containers) {
+ case 0:
+ continue
+ case 1:
+ fmt.Printf("Container:\n")
+ default:
+ fmt.Printf("Containers:\n")
+ }
+ for _, ctr := range pod.Containers {
+ fmt.Println(ctr)
+ }
+ // Empty line for space for next block
+ fmt.Println()
}
return nil
diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go
index 62b5b849e..51b7a7d52 100644
--- a/cmd/podman/pods/create.go
+++ b/cmd/podman/pods/create.go
@@ -53,6 +53,7 @@ func init() {
flags.AddFlagSet(common.GetNetFlags())
flags.StringVar(&createOptions.CGroupParent, "cgroup-parent", "", "Set parent cgroup for the pod")
flags.BoolVar(&createOptions.Infra, "infra", true, "Create an infra container associated with the pod to share namespaces with")
+ flags.StringVar(&createOptions.InfraConmonPidFile, "infra-conmon-pidfile", "", "Path to the file that will receive the POD of the infra container's conmon")
flags.StringVar(&createOptions.InfraImage, "infra-image", containerConfig.Engine.InfraImage, "The image of the infra container to associate with the pod")
flags.StringVar(&createOptions.InfraCommand, "infra-command", containerConfig.Engine.InfraCommand, "The command to run on the infra container when the pod is started")
flags.StringSliceVar(&labelFile, "label-file", []string{}, "Read in a line delimited file of labels")
@@ -73,8 +74,8 @@ func aliasNetworkFlag(_ *pflag.FlagSet, name string) pflag.NormalizedName {
func create(cmd *cobra.Command, args []string) error {
var (
- err error
- podIdFile *os.File
+ err error
+ podIDFD *os.File
)
createOptions.Labels, err = parse.GetAllLabels(labelFile, labels)
if err != nil {
@@ -83,6 +84,9 @@ func create(cmd *cobra.Command, args []string) error {
if !createOptions.Infra {
logrus.Debugf("Not creating an infra container")
+ if cmd.Flag("infra-conmon-pidfile").Changed {
+ return errors.New("cannot set infra-conmon-pid without an infra container")
+ }
if cmd.Flag("infra-command").Changed {
return errors.New("cannot set infra-command without an infra container")
}
@@ -101,15 +105,15 @@ func create(cmd *cobra.Command, args []string) error {
}
if cmd.Flag("pod-id-file").Changed {
- podIdFile, err = util.OpenExclusiveFile(podIDFile)
+ podIDFD, err = util.OpenExclusiveFile(podIDFile)
if err != nil && os.IsExist(err) {
return errors.Errorf("pod id file exists. Ensure another pod is not using it or delete %s", podIDFile)
}
if err != nil {
return errors.Errorf("error opening pod-id-file %s", podIDFile)
}
- defer errorhandling.CloseQuiet(podIdFile)
- defer errorhandling.SyncQuiet(podIdFile)
+ defer errorhandling.CloseQuiet(podIDFD)
+ defer errorhandling.SyncQuiet(podIDFD)
}
createOptions.Net, err = common.NetFlagsToNetOptions(cmd)
diff --git a/cmd/podman/pods/pod.go b/cmd/podman/pods/pod.go
index ed265ef90..9dc538c71 100644
--- a/cmd/podman/pods/pod.go
+++ b/cmd/podman/pods/pod.go
@@ -10,7 +10,7 @@ import (
var (
// Pull in configured json library
- json = registry.JsonLibrary()
+ json = registry.JSONLibrary()
// Command: podman _pod_
podCmd = &cobra.Command{
diff --git a/cmd/podman/pods/ps.go b/cmd/podman/pods/ps.go
index 1385ff270..bcd1db84c 100644
--- a/cmd/podman/pods/ps.go
+++ b/cmd/podman/pods/ps.go
@@ -195,7 +195,7 @@ func (l ListPodReporter) ID() string {
}
// Id returns the Pod id
-func (l ListPodReporter) Id() string {
+func (l ListPodReporter) Id() string { //nolint
if noTrunc {
return l.ListPodsReport.Id
}
@@ -209,7 +209,7 @@ func (l ListPodReporter) InfraID() string {
// InfraId returns the infra container id for the pod
// depending on trunc
-func (l ListPodReporter) InfraId() string {
+func (l ListPodReporter) InfraId() string { //nolint
if len(l.ListPodsReport.InfraId) == 0 {
return ""
}
@@ -252,7 +252,7 @@ func sortPodPsOutput(sortBy string, lprs []*entities.ListPodsReport) error {
case "created":
sort.Sort(podPsSortedCreated{lprs})
case "id":
- sort.Sort(podPsSortedId{lprs})
+ sort.Sort(podPsSortedID{lprs})
case "name":
sort.Sort(podPsSortedName{lprs})
case "number":
@@ -276,9 +276,9 @@ func (a podPsSortedCreated) Less(i, j int) bool {
return a.lprSort[i].Created.After(a.lprSort[j].Created)
}
-type podPsSortedId struct{ lprSort }
+type podPsSortedID struct{ lprSort }
-func (a podPsSortedId) Less(i, j int) bool { return a.lprSort[i].Id < a.lprSort[j].Id }
+func (a podPsSortedID) Less(i, j int) bool { return a.lprSort[i].Id < a.lprSort[j].Id }
type podPsSortedNumber struct{ lprSort }
diff --git a/cmd/podman/pods/rm.go b/cmd/podman/pods/rm.go
index 4b9882f8a..8de0bce9e 100644
--- a/cmd/podman/pods/rm.go
+++ b/cmd/podman/pods/rm.go
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
+ "github.com/containers/libpod/cmd/podman/common"
"github.com/containers/libpod/cmd/podman/parse"
"github.com/containers/libpod/cmd/podman/registry"
"github.com/containers/libpod/cmd/podman/utils"
@@ -11,7 +12,15 @@ import (
"github.com/spf13/cobra"
)
+// allows for splitting API and CLI-only options
+type podRmOptionsWrapper struct {
+ entities.PodRmOptions
+
+ PodIDFiles []string
+}
+
var (
+ rmOptions = podRmOptionsWrapper{}
podRmDescription = fmt.Sprintf(`podman rm will remove one or more stopped pods and their containers from the host.
The pod name or ID can be used. A pod with containers will not be removed without --force. If --force is specified, all containers will be stopped, then removed.`)
@@ -21,7 +30,7 @@ var (
Long: podRmDescription,
RunE: rm,
Args: func(cmd *cobra.Command, args []string) error {
- return parse.CheckAllLatestAndCIDFile(cmd, args, false, false)
+ return parse.CheckAllLatestAndPodIDFile(cmd, args, false, true)
},
Example: `podman pod rm mywebserverpod
podman pod rm -f 860a4b23
@@ -29,10 +38,6 @@ var (
}
)
-var (
- rmOptions = entities.PodRmOptions{}
-)
-
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
@@ -45,6 +50,7 @@ func init() {
flags.BoolVarP(&rmOptions.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")
flags.BoolVarP(&rmOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified pod is missing")
flags.BoolVarP(&rmOptions.Latest, "latest", "l", false, "Remove the latest pod podman is aware of")
+ flags.StringArrayVarP(&rmOptions.PodIDFiles, "pod-id-file", "", nil, "Read the pod ID from the file")
if registry.IsRemote() {
_ = flags.MarkHidden("latest")
_ = flags.MarkHidden("ignore")
@@ -55,7 +61,14 @@ func rm(cmd *cobra.Command, args []string) error {
var (
errs utils.OutputErrors
)
- responses, err := registry.ContainerEngine().PodRm(context.Background(), args, rmOptions)
+
+ ids, err := common.ReadPodIDFiles(rmOptions.PodIDFiles)
+ if err != nil {
+ return err
+ }
+ args = append(args, ids...)
+
+ responses, err := registry.ContainerEngine().PodRm(context.Background(), args, rmOptions.PodRmOptions)
if err != nil {
return err
}
diff --git a/cmd/podman/pods/start.go b/cmd/podman/pods/start.go
index d0150a3c2..97020b360 100644
--- a/cmd/podman/pods/start.go
+++ b/cmd/podman/pods/start.go
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
+ "github.com/containers/libpod/cmd/podman/common"
"github.com/containers/libpod/cmd/podman/parse"
"github.com/containers/libpod/cmd/podman/registry"
"github.com/containers/libpod/cmd/podman/utils"
@@ -11,6 +12,13 @@ import (
"github.com/spf13/cobra"
)
+// allows for splitting API and CLI-only options
+type podStartOptionsWrapper struct {
+ entities.PodStartOptions
+
+ PodIDFiles []string
+}
+
var (
podStartDescription = `The pod name or ID can be used.
@@ -21,7 +29,7 @@ var (
Long: podStartDescription,
RunE: start,
Args: func(cmd *cobra.Command, args []string) error {
- return parse.CheckAllLatestAndCIDFile(cmd, args, false, false)
+ return parse.CheckAllLatestAndPodIDFile(cmd, args, false, true)
},
Example: `podman pod start podID
podman pod start --latest
@@ -30,7 +38,7 @@ var (
)
var (
- startOptions = entities.PodStartOptions{}
+ startOptions = podStartOptionsWrapper{}
)
func init() {
@@ -43,6 +51,7 @@ func init() {
flags := startCommand.Flags()
flags.BoolVarP(&startOptions.All, "all", "a", false, "Restart all running pods")
flags.BoolVarP(&startOptions.Latest, "latest", "l", false, "Restart the latest pod podman is aware of")
+ flags.StringArrayVarP(&startOptions.PodIDFiles, "pod-id-file", "", nil, "Read the pod ID from the file")
if registry.IsRemote() {
_ = flags.MarkHidden("latest")
}
@@ -52,7 +61,14 @@ func start(cmd *cobra.Command, args []string) error {
var (
errs utils.OutputErrors
)
- responses, err := registry.ContainerEngine().PodStart(context.Background(), args, startOptions)
+
+ ids, err := common.ReadPodIDFiles(startOptions.PodIDFiles)
+ if err != nil {
+ return err
+ }
+ args = append(args, ids...)
+
+ responses, err := registry.ContainerEngine().PodStart(context.Background(), args, startOptions.PodStartOptions)
if err != nil {
return err
}
diff --git a/cmd/podman/pods/stats.go b/cmd/podman/pods/stats.go
index d3950fdbc..d14632f01 100644
--- a/cmd/podman/pods/stats.go
+++ b/cmd/podman/pods/stats.go
@@ -71,7 +71,7 @@ func stats(cmd *cobra.Command, args []string) error {
}
format := statsOptions.Format
- doJson := strings.ToLower(format) == formats.JSONString
+ doJSON := strings.ToLower(format) == formats.JSONString
header := getPodStatsHeader(format)
for {
@@ -80,7 +80,7 @@ func stats(cmd *cobra.Command, args []string) error {
return err
}
// Print the stats in the requested format and configuration.
- if doJson {
+ if doJSON {
if err := printJSONPodStats(reports); err != nil {
return err
}
diff --git a/cmd/podman/pods/stop.go b/cmd/podman/pods/stop.go
index daf05d640..628e8a536 100644
--- a/cmd/podman/pods/stop.go
+++ b/cmd/podman/pods/stop.go
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
+ "github.com/containers/libpod/cmd/podman/common"
"github.com/containers/libpod/cmd/podman/parse"
"github.com/containers/libpod/cmd/podman/registry"
"github.com/containers/libpod/cmd/podman/utils"
@@ -11,7 +12,18 @@ import (
"github.com/spf13/cobra"
)
+// allows for splitting API and CLI-only options
+type podStopOptionsWrapper struct {
+ entities.PodStopOptions
+
+ PodIDFiles []string
+ TimeoutCLI uint
+}
+
var (
+ stopOptions = podStopOptionsWrapper{
+ PodStopOptions: entities.PodStopOptions{Timeout: -1},
+ }
podStopDescription = `The pod name or ID can be used.
This command will stop all running containers in each of the specified pods.`
@@ -22,7 +34,7 @@ var (
Long: podStopDescription,
RunE: stop,
Args: func(cmd *cobra.Command, args []string) error {
- return parse.CheckAllLatestAndCIDFile(cmd, args, false, false)
+ return parse.CheckAllLatestAndPodIDFile(cmd, args, false, true)
},
Example: `podman pod stop mywebserverpod
podman pod stop --latest
@@ -30,13 +42,6 @@ var (
}
)
-var (
- stopOptions = entities.PodStopOptions{
- Timeout: -1,
- }
- timeout uint
-)
-
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
@@ -47,7 +52,8 @@ func init() {
flags.BoolVarP(&stopOptions.All, "all", "a", false, "Stop all running pods")
flags.BoolVarP(&stopOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified pod is missing")
flags.BoolVarP(&stopOptions.Latest, "latest", "l", false, "Stop the latest pod podman is aware of")
- flags.UintVarP(&timeout, "time", "t", containerConfig.Engine.StopTimeout, "Seconds to wait for pod stop before killing the container")
+ flags.UintVarP(&stopOptions.TimeoutCLI, "time", "t", containerConfig.Engine.StopTimeout, "Seconds to wait for pod stop before killing the container")
+ flags.StringArrayVarP(&stopOptions.PodIDFiles, "pod-id-file", "", nil, "Read the pod ID from the file")
if registry.IsRemote() {
_ = flags.MarkHidden("latest")
_ = flags.MarkHidden("ignore")
@@ -60,9 +66,16 @@ func stop(cmd *cobra.Command, args []string) error {
errs utils.OutputErrors
)
if cmd.Flag("time").Changed {
- stopOptions.Timeout = int(timeout)
+ stopOptions.Timeout = int(stopOptions.TimeoutCLI)
+ }
+
+ ids, err := common.ReadPodIDFiles(stopOptions.PodIDFiles)
+ if err != nil {
+ return err
}
- responses, err := registry.ContainerEngine().PodStop(context.Background(), args, stopOptions)
+ args = append(args, ids...)
+
+ responses, err := registry.ContainerEngine().PodStop(context.Background(), args, stopOptions.PodStopOptions)
if err != nil {
return err
}
diff --git a/cmd/podman/registry/json.go b/cmd/podman/registry/json.go
index f25406c3c..a8a1623f5 100644
--- a/cmd/podman/registry/json.go
+++ b/cmd/podman/registry/json.go
@@ -11,8 +11,8 @@ var (
jsonSync sync.Once
)
-// JsonLibrary provides a "encoding/json" compatible API
-func JsonLibrary() jsoniter.API {
+// JSONLibrary provides a "encoding/json" compatible API
+func JSONLibrary() jsoniter.API {
jsonSync.Do(func() {
json = jsoniter.ConfigCompatibleWithStandardLibrary
})
diff --git a/cmd/podman/report/report.go b/cmd/podman/report/report.go
index 8392f10e0..ce349ef35 100644
--- a/cmd/podman/report/report.go
+++ b/cmd/podman/report/report.go
@@ -3,4 +3,4 @@ package report
import "github.com/containers/libpod/cmd/podman/registry"
// Pull in configured json library
-var json = registry.JsonLibrary()
+var json = registry.JSONLibrary()
diff --git a/cmd/podman/root.go b/cmd/podman/root.go
index b62ee144a..4f834e87d 100644
--- a/cmd/podman/root.go
+++ b/cmd/podman/root.go
@@ -119,10 +119,10 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error {
}
if cmd.Flag("cpu-profile").Changed {
- f, err := os.Create(cfg.CpuProfile)
+ f, err := os.Create(cfg.CPUProfile)
if err != nil {
return errors.Wrapf(err, "unable to create cpu profiling file %s",
- cfg.CpuProfile)
+ cfg.CPUProfile)
}
if err := pprof.StartCPUProfile(f); err != nil {
return err
@@ -212,13 +212,13 @@ func rootFlags(opts *entities.PodmanConfig, flags *pflag.FlagSet) {
// V2 flags
flags.BoolVarP(&opts.Remote, "remote", "r", false, "Access remote Podman service (default false)")
// TODO Read uri from containers.config when available
- flags.StringVar(&opts.Uri, "url", registry.DefaultAPIAddress(), "URL to access Podman service (CONTAINER_HOST)")
+ flags.StringVar(&opts.URI, "url", registry.DefaultAPIAddress(), "URL to access Podman service (CONTAINER_HOST)")
flags.StringSliceVar(&opts.Identities, "identity", []string{}, "path to SSH identity file, (CONTAINER_SSHKEY)")
flags.StringVar(&opts.PassPhrase, "passphrase", "", "passphrase for identity file (not secure, CONTAINER_PASSPHRASE), ssh-agent always supported")
cfg := opts.Config
flags.StringVar(&cfg.Engine.CgroupManager, "cgroup-manager", cfg.Engine.CgroupManager, "Cgroup manager to use (\"cgroupfs\"|\"systemd\")")
- flags.StringVar(&opts.CpuProfile, "cpu-profile", "", "Path for the cpu profiling results")
+ flags.StringVar(&opts.CPUProfile, "cpu-profile", "", "Path for the cpu profiling results")
flags.StringVar(&opts.ConmonPath, "conmon", "", "Path of the conmon binary")
flags.StringVar(&cfg.Engine.NetworkCmdPath, "network-cmd-path", cfg.Engine.NetworkCmdPath, "Path to the command for configuring the network")
flags.StringVar(&cfg.Network.NetworkConfigDir, "cni-config-dir", cfg.Network.NetworkConfigDir, "Path of the configuration directory for CNI networks")
diff --git a/cmd/podman/system/df.go b/cmd/podman/system/df.go
index 8fe035209..9318bba12 100644
--- a/cmd/podman/system/df.go
+++ b/cmd/podman/system/df.go
@@ -63,7 +63,7 @@ func printSummary(reports *entities.SystemDfReport, userFormat string) error {
dfSummaries []*dfSummary
active int
size, reclaimable int64
- format string = "{{.Type}}\t{{.Total}}\t{{.Active}}\t{{.Size}}\t{{.Reclaimable}}\n"
+ format = "{{.Type}}\t{{.Total}}\t{{.Active}}\t{{.Size}}\t{{.Reclaimable}}\n"
w io.Writer = os.Stdout
)
@@ -74,7 +74,7 @@ func printSummary(reports *entities.SystemDfReport, userFormat string) error {
for _, i := range reports.Images {
if i.Containers > 0 {
- active += 1
+ active++
}
size += i.Size
if i.Containers < 1 {
@@ -99,7 +99,7 @@ func printSummary(reports *entities.SystemDfReport, userFormat string) error {
)
for _, c := range reports.Containers {
if c.Status == "running" {
- conActive += 1
+ conActive++
} else {
conReclaimable += c.RWSize
}
diff --git a/cmd/podman/system/events.go b/cmd/podman/system/events.go
index 27e80138e..c401c5a92 100644
--- a/cmd/podman/system/events.go
+++ b/cmd/podman/system/events.go
@@ -17,8 +17,10 @@ import (
)
var (
- eventsDescription = "Monitor podman events"
- eventsCommand = &cobra.Command{
+ eventsDescription = `Monitor podman events.
+
+ By default, streaming mode is used, printing new events as they occur. Previous events can be listed via --since and --until.`
+ eventsCommand = &cobra.Command{
Use: "events",
Args: validate.NoArgs,
Short: "Show podman events",
diff --git a/cmd/podman/system/service.go b/cmd/podman/system/service.go
index 1b07ee301..ecd17c251 100644
--- a/cmd/podman/system/service.go
+++ b/cmd/podman/system/service.go
@@ -64,7 +64,7 @@ func aliasTimeoutFlag(_ *pflag.FlagSet, name string) pflag.NormalizedName {
}
func service(cmd *cobra.Command, args []string) error {
- apiURI, err := resolveApiURI(args)
+ apiURI, err := resolveAPIURI(args)
if err != nil {
return err
}
@@ -103,7 +103,7 @@ func service(cmd *cobra.Command, args []string) error {
return restService(opts, cmd.Flags(), registry.PodmanConfig())
}
-func resolveApiURI(_url []string) (string, error) {
+func resolveAPIURI(_url []string) (string, error) {
// When determining _*THE*_ listening endpoint --
// 1) User input wins always
// 2) systemd socket activation
diff --git a/cmd/podman/system/system.go b/cmd/podman/system/system.go
index d9691ad2a..acf41a32d 100644
--- a/cmd/podman/system/system.go
+++ b/cmd/podman/system/system.go
@@ -9,7 +9,7 @@ import (
var (
// Pull in configured json library
- json = registry.JsonLibrary()
+ json = registry.JSONLibrary()
// Command: podman _system_
systemCmd = &cobra.Command{
diff --git a/cmd/podman/validate/args.go b/cmd/podman/validate/args.go
index 14b4d7897..69240798f 100644
--- a/cmd/podman/validate/args.go
+++ b/cmd/podman/validate/args.go
@@ -23,8 +23,8 @@ func SubCommandExists(cmd *cobra.Command, args []string) error {
return errors.Errorf("missing command '%[1]s COMMAND'\nTry '%[1]s --help' for more information.", cmd.CommandPath())
}
-// IdOrLatestArgs used to validate a nameOrId was provided or the "--latest" flag
-func IdOrLatestArgs(cmd *cobra.Command, args []string) error {
+// IDOrLatestArgs used to validate a nameOrId was provided or the "--latest" flag
+func IDOrLatestArgs(cmd *cobra.Command, args []string) error {
if len(args) > 1 || (len(args) == 0 && !cmd.Flag("latest").Changed) {
return fmt.Errorf("`%s` requires a name, id or the \"--latest\" flag", cmd.CommandPath())
}
diff --git a/cmd/podman/validate/choice.go b/cmd/podman/validate/choice.go
index 572c5f4a5..8bb21c591 100644
--- a/cmd/podman/validate/choice.go
+++ b/cmd/podman/validate/choice.go
@@ -6,28 +6,28 @@ import (
)
// Honors cobra.Value interface
-type choiceValue struct {
+type ChoiceValue struct {
value *string
choices []string
}
-// ChoiceValue may be used in cobra FlagSet methods Var/VarP/VarPF() to select from a set of values
+// Value may be used in cobra FlagSet methods Var/VarP/VarPF() to select from a set of values
//
// Example:
// created := validate.ChoiceValue(&opts.Sort, "command", "created", "id", "image", "names", "runningfor", "size", "status")
// flags.Var(created, "sort", "Sort output by: "+created.Choices())
-func ChoiceValue(p *string, choices ...string) *choiceValue {
- return &choiceValue{
+func Value(p *string, choices ...string) *ChoiceValue {
+ return &ChoiceValue{
value: p,
choices: choices,
}
}
-func (c *choiceValue) String() string {
+func (c *ChoiceValue) String() string {
return *c.value
}
-func (c *choiceValue) Set(value string) error {
+func (c *ChoiceValue) Set(value string) error {
for _, v := range c.choices {
if v == value {
*c.value = value
@@ -37,10 +37,10 @@ func (c *choiceValue) Set(value string) error {
return fmt.Errorf("%q is not a valid value. Choose from: %q", value, c.Choices())
}
-func (c *choiceValue) Choices() string {
+func (c *ChoiceValue) Choices() string {
return strings.Join(c.choices, ", ")
}
-func (c *choiceValue) Type() string {
+func (c *ChoiceValue) Type() string {
return "choice"
}
diff --git a/cmd/podman/volumes/create.go b/cmd/podman/volumes/create.go
index 1bec8d0e7..16ac3771e 100644
--- a/cmd/podman/volumes/create.go
+++ b/cmd/podman/volumes/create.go
@@ -67,6 +67,6 @@ func create(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
- fmt.Println(response.IdOrName)
+ fmt.Println(response.IDOrName)
return nil
}
diff --git a/cmd/podman/volumes/volume.go b/cmd/podman/volumes/volume.go
index 3e90d178c..12947a6b1 100644
--- a/cmd/podman/volumes/volume.go
+++ b/cmd/podman/volumes/volume.go
@@ -9,7 +9,7 @@ import (
var (
// Pull in configured json library
- json = registry.JsonLibrary()
+ json = registry.JSONLibrary()
// Command: podman _volume_
volumeCmd = &cobra.Command{