summaryrefslogtreecommitdiff
path: root/cmd/podman
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/podman')
-rw-r--r--cmd/podman/common/completion.go2
-rw-r--r--cmd/podman/generate/systemd.go16
-rw-r--r--cmd/podman/healthcheck/run.go5
-rw-r--r--cmd/podman/inspect/inspect.go4
-rw-r--r--cmd/podman/machine/init.go6
-rw-r--r--cmd/podman/machine/list.go2
-rw-r--r--cmd/podman/machine/machine.go2
-rw-r--r--cmd/podman/machine/rm.go2
-rw-r--r--cmd/podman/machine/ssh.go2
-rw-r--r--cmd/podman/machine/start.go10
-rw-r--r--cmd/podman/machine/stop.go2
-rw-r--r--cmd/podman/networks/create.go9
-rw-r--r--cmd/podman/pods/inspect.go4
-rw-r--r--cmd/podman/pods/logs.go140
-rw-r--r--cmd/podman/secrets/list.go2
-rw-r--r--cmd/podman/system/unshare.go21
16 files changed, 207 insertions, 22 deletions
diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go
index 3966606e3..e925fb4f1 100644
--- a/cmd/podman/common/completion.go
+++ b/cmd/podman/common/completion.go
@@ -223,7 +223,7 @@ func getSecrets(cmd *cobra.Command, toComplete string) ([]string, cobra.ShellCom
cobra.CompErrorln(err.Error())
return nil, cobra.ShellCompDirectiveNoFileComp
}
- secrets, err := engine.SecretList(registry.GetContext())
+ secrets, err := engine.SecretList(registry.GetContext(), entities.SecretListRequest{})
if err != nil {
cobra.CompErrorln(err.Error())
return nil, cobra.ShellCompDirectiveNoFileComp
diff --git a/cmd/podman/generate/systemd.go b/cmd/podman/generate/systemd.go
index b76a71f0d..2ab33c26b 100644
--- a/cmd/podman/generate/systemd.go
+++ b/cmd/podman/generate/systemd.go
@@ -12,15 +12,22 @@ import (
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/utils"
"github.com/containers/podman/v3/pkg/domain/entities"
+ systemDefine "github.com/containers/podman/v3/pkg/systemd/define"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
+const (
+ restartPolicyFlagName = "restart-policy"
+ timeFlagName = "time"
+)
+
var (
files bool
format string
systemdTimeout uint
+ systemdRestart string
systemdOptions = entities.GenerateSystemdOptions{}
systemdDescription = `Generate systemd units for a pod or container.
The generated units can later be controlled via systemctl(1).`
@@ -47,7 +54,6 @@ func init() {
flags.BoolVarP(&systemdOptions.Name, "name", "n", false, "Use container/pod names instead of IDs")
flags.BoolVarP(&files, "files", "f", false, "Generate .service files instead of printing to stdout")
- timeFlagName := "time"
flags.UintVarP(&systemdTimeout, timeFlagName, "t", containerConfig.Engine.StopTimeout, "Stop timeout override")
_ = systemdCmd.RegisterFlagCompletionFunc(timeFlagName, completion.AutocompleteNone)
flags.BoolVarP(&systemdOptions.New, "new", "", false, "Create a new container or pod instead of starting an existing one")
@@ -65,8 +71,7 @@ func init() {
flags.StringVar(&systemdOptions.Separator, separatorFlagName, "-", "Systemd unit name separator between name/id and prefix")
_ = systemdCmd.RegisterFlagCompletionFunc(separatorFlagName, completion.AutocompleteNone)
- restartPolicyFlagName := "restart-policy"
- flags.StringVar(&systemdOptions.RestartPolicy, restartPolicyFlagName, "on-failure", "Systemd restart-policy")
+ flags.StringVar(&systemdRestart, restartPolicyFlagName, systemDefine.DefaultRestartPolicy, "Systemd restart-policy")
_ = systemdCmd.RegisterFlagCompletionFunc(restartPolicyFlagName, common.AutocompleteSystemdRestartOptions)
formatFlagName := "format"
@@ -77,9 +82,12 @@ func init() {
}
func systemd(cmd *cobra.Command, args []string) error {
- if cmd.Flags().Changed("time") {
+ if cmd.Flags().Changed(timeFlagName) {
systemdOptions.StopTimeout = &systemdTimeout
}
+ if cmd.Flags().Changed(restartPolicyFlagName) {
+ systemdOptions.RestartPolicy = &systemdRestart
+ }
if registry.IsRemote() {
logrus.Warnln("The generated units should be placed on your remote system")
diff --git a/cmd/podman/healthcheck/run.go b/cmd/podman/healthcheck/run.go
index fe8dc2573..b03a07bc4 100644
--- a/cmd/podman/healthcheck/run.go
+++ b/cmd/podman/healthcheck/run.go
@@ -6,6 +6,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/common"
"github.com/containers/podman/v3/cmd/podman/registry"
+ "github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/spf13/cobra"
)
@@ -34,9 +35,9 @@ func run(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
- if response.Status == "unhealthy" {
+ if response.Status == define.HealthCheckUnhealthy {
registry.SetExitCode(1)
+ fmt.Println(response.Status)
}
- fmt.Println(response.Status)
return err
}
diff --git a/cmd/podman/inspect/inspect.go b/cmd/podman/inspect/inspect.go
index bd3060882..4c7fa33a4 100644
--- a/cmd/podman/inspect/inspect.go
+++ b/cmd/podman/inspect/inspect.go
@@ -254,7 +254,9 @@ func printTmpl(typ, row string, data []interface{}) error {
if err != nil {
return err
}
- return t.Execute(w, data)
+ err = t.Execute(w, data)
+ w.Flush()
+ return err
}
func (i *inspector) inspectAll(ctx context.Context, namesOrIDs []string) ([]interface{}, []error, error) {
diff --git a/cmd/podman/machine/init.go b/cmd/podman/machine/init.go
index ac0d06a07..ec44a707d 100644
--- a/cmd/podman/machine/init.go
+++ b/cmd/podman/machine/init.go
@@ -1,4 +1,4 @@
-// +build amd64,linux arm64,linux amd64,darwin arm64,darwin
+// +build amd64,!windows arm64,!windows
package machine
@@ -40,7 +40,7 @@ func init() {
flags.Uint64Var(
&initOpts.CPUS,
cpusFlagName, 1,
- "Number of CPUs. The default is 1.",
+ "Number of CPUs",
)
_ = initCmd.RegisterFlagCompletionFunc(cpusFlagName, completion.AutocompleteNone)
@@ -57,7 +57,7 @@ func init() {
flags.Uint64VarP(
&initOpts.Memory,
memoryFlagName, "m", 2048,
- "Memory (in MB)",
+ "Memory in MB",
)
_ = initCmd.RegisterFlagCompletionFunc(memoryFlagName, completion.AutocompleteNone)
diff --git a/cmd/podman/machine/list.go b/cmd/podman/machine/list.go
index 134a081ab..d4360bb9b 100644
--- a/cmd/podman/machine/list.go
+++ b/cmd/podman/machine/list.go
@@ -1,4 +1,4 @@
-// +build amd64,linux arm64,linux amd64,darwin arm64,darwin
+// +build amd64,!windows arm64,!windows
package machine
diff --git a/cmd/podman/machine/machine.go b/cmd/podman/machine/machine.go
index b059afc38..8ff9055f0 100644
--- a/cmd/podman/machine/machine.go
+++ b/cmd/podman/machine/machine.go
@@ -1,4 +1,4 @@
-// +build amd64,linux arm64,linux amd64,darwin arm64,darwin
+// +build amd64,!windows arm64,!windows
package machine
diff --git a/cmd/podman/machine/rm.go b/cmd/podman/machine/rm.go
index 02e3dfeb8..c17399c78 100644
--- a/cmd/podman/machine/rm.go
+++ b/cmd/podman/machine/rm.go
@@ -1,4 +1,4 @@
-// +build amd64,linux arm64,linux amd64,darwin arm64,darwin
+// +build amd64,!windows arm64,!windows
package machine
diff --git a/cmd/podman/machine/ssh.go b/cmd/podman/machine/ssh.go
index f185948f5..84e9e88ab 100644
--- a/cmd/podman/machine/ssh.go
+++ b/cmd/podman/machine/ssh.go
@@ -1,4 +1,4 @@
-// +build amd64,linux arm64,linux amd64,darwin arm64,darwin
+// +build amd64,!windows arm64,!windows
package machine
diff --git a/cmd/podman/machine/start.go b/cmd/podman/machine/start.go
index f8f0eed09..4ae31e6de 100644
--- a/cmd/podman/machine/start.go
+++ b/cmd/podman/machine/start.go
@@ -1,8 +1,10 @@
-// +build amd64,linux arm64,linux amd64,darwin arm64,darwin
+// +build amd64,!windows arm64,!windows
package machine
import (
+ "fmt"
+
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/pkg/machine"
"github.com/containers/podman/v3/pkg/machine/qemu"
@@ -58,5 +60,9 @@ func start(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
- return vm.Start(vmName, machine.StartOptions{})
+ if err := vm.Start(vmName, machine.StartOptions{}); err != nil {
+ return err
+ }
+ fmt.Printf("Machine %q started successfully\n", vmName)
+ return nil
}
diff --git a/cmd/podman/machine/stop.go b/cmd/podman/machine/stop.go
index 2d5aa7b95..76ba85601 100644
--- a/cmd/podman/machine/stop.go
+++ b/cmd/podman/machine/stop.go
@@ -1,4 +1,4 @@
-// +build amd64,linux arm64,linux amd64,darwin arm64,darwin
+// +build amd64,!windows arm64,!windows
package machine
diff --git a/cmd/podman/networks/create.go b/cmd/podman/networks/create.go
index 1f3b321ba..b5ddd215f 100644
--- a/cmd/podman/networks/create.go
+++ b/cmd/podman/networks/create.go
@@ -11,6 +11,7 @@ import (
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
@@ -56,7 +57,8 @@ func networkCreateFlags(cmd *cobra.Command) {
macvlanFlagName := "macvlan"
flags.StringVar(&networkCreateOptions.MacVLAN, macvlanFlagName, "", "create a Macvlan connection based on this device")
- _ = cmd.RegisterFlagCompletionFunc(macvlanFlagName, completion.AutocompleteNone)
+ // This option is deprecated
+ flags.MarkHidden(macvlanFlagName)
labelFlagName := "label"
flags.StringArrayVar(&labels, labelFlagName, nil, "set metadata on a network")
@@ -100,6 +102,11 @@ func networkCreate(cmd *cobra.Command, args []string) error {
if err != nil {
return errors.Wrapf(err, "unable to process options")
}
+
+ if networkCreateOptions.MacVLAN != "" {
+ logrus.Warn("The --macvlan option is deprecated, use `--driver macvlan --opt parent=<device>` instead")
+ }
+
response, err := registry.ContainerEngine().NetworkCreate(registry.Context(), name, networkCreateOptions)
if err != nil {
return err
diff --git a/cmd/podman/pods/inspect.go b/cmd/podman/pods/inspect.go
index 4bb88f48a..96eaec3b9 100644
--- a/cmd/podman/pods/inspect.go
+++ b/cmd/podman/pods/inspect.go
@@ -80,5 +80,7 @@ func inspect(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
- return t.Execute(w, *responses)
+ err = t.Execute(w, *responses)
+ w.Flush()
+ return err
}
diff --git a/cmd/podman/pods/logs.go b/cmd/podman/pods/logs.go
new file mode 100644
index 000000000..fe5205669
--- /dev/null
+++ b/cmd/podman/pods/logs.go
@@ -0,0 +1,140 @@
+package pods
+
+import (
+ "os"
+
+ "github.com/containers/common/pkg/completion"
+ "github.com/containers/podman/v3/cmd/podman/common"
+ "github.com/containers/podman/v3/cmd/podman/registry"
+ "github.com/containers/podman/v3/cmd/podman/validate"
+ "github.com/containers/podman/v3/libpod/define"
+ "github.com/containers/podman/v3/pkg/domain/entities"
+ "github.com/containers/podman/v3/pkg/util"
+ "github.com/pkg/errors"
+ "github.com/spf13/cobra"
+)
+
+// logsOptionsWrapper wraps entities.LogsOptions and prevents leaking
+// CLI-only fields into the API types.
+type logsOptionsWrapper struct {
+ entities.PodLogsOptions
+
+ SinceRaw string
+
+ UntilRaw string
+}
+
+var (
+ logsPodOptions logsOptionsWrapper
+ logsPodDescription = `Displays logs for pod with one or more containers.`
+ logsPodCommand = &cobra.Command{
+ Use: "logs [options] POD",
+ Short: "Fetch logs for pod with one or more containers",
+ Long: logsPodDescription,
+ // We dont want users to invoke latest and pod togather
+ Args: func(cmd *cobra.Command, args []string) error {
+ switch {
+ case registry.IsRemote() && logsPodOptions.Latest:
+ return errors.New(cmd.Name() + " does not support 'latest' when run remotely")
+ case len(args) > 1:
+ return errors.New("requires exactly 1 arg")
+ case logsPodOptions.Latest && len(args) > 0:
+ return errors.New("--latest and pods cannot be used together")
+ case !logsPodOptions.Latest && len(args) < 1:
+ return errors.New("specify at least one pod name or ID to log")
+ }
+ return nil
+ },
+ RunE: logs,
+ ValidArgsFunction: common.AutocompletePods,
+ Example: `podman pod logs podID
+ podman pod logs -c ctrname podName
+ podman pod logs --tail 2 mywebserver
+ podman pod logs --follow=true --since 10m podID
+ podman pod logs mywebserver`,
+ }
+
+ containerLogsCommand = &cobra.Command{
+ Use: logsPodCommand.Use,
+ Short: logsPodCommand.Short,
+ Long: logsPodCommand.Long,
+ Args: logsPodCommand.Args,
+ RunE: logsPodCommand.RunE,
+ ValidArgsFunction: logsPodCommand.ValidArgsFunction,
+ Example: `podman pod logs podId
+ podman pod logs -c ctrname podName
+ podman pod logs --tail 2 mywebserver
+ podman pod logs --follow=true --since 10m podID`,
+ }
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Command: logsPodCommand,
+ })
+ logsFlags(logsPodCommand)
+ validate.AddLatestFlag(logsPodCommand, &logsPodOptions.Latest)
+
+ // container logs
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Command: containerLogsCommand,
+ Parent: podCmd,
+ })
+ logsFlags(containerLogsCommand)
+ validate.AddLatestFlag(containerLogsCommand, &logsPodOptions.Latest)
+}
+
+func logsFlags(cmd *cobra.Command) {
+ flags := cmd.Flags()
+
+ flags.BoolVar(&logsPodOptions.Details, "details", false, "Show extra details provided to the logs")
+ flags.BoolVarP(&logsPodOptions.Follow, "follow", "f", false, "Follow log output.")
+
+ containerNameFlag := "container"
+ flags.StringVarP(&logsPodOptions.ContainerName, containerNameFlag, "c", "", "Filter logs by container name or id which belongs to pod")
+ _ = cmd.RegisterFlagCompletionFunc(containerNameFlag, common.AutocompleteContainers)
+
+ sinceFlagName := "since"
+ flags.StringVar(&logsPodOptions.SinceRaw, sinceFlagName, "", "Show logs since TIMESTAMP")
+ _ = cmd.RegisterFlagCompletionFunc(sinceFlagName, completion.AutocompleteNone)
+
+ untilFlagName := "until"
+ flags.StringVar(&logsPodOptions.UntilRaw, untilFlagName, "", "Show logs until TIMESTAMP")
+ _ = cmd.RegisterFlagCompletionFunc(untilFlagName, completion.AutocompleteNone)
+
+ tailFlagName := "tail"
+ flags.Int64Var(&logsPodOptions.Tail, tailFlagName, -1, "Output the specified number of LINES at the end of the logs.")
+ _ = cmd.RegisterFlagCompletionFunc(tailFlagName, completion.AutocompleteNone)
+
+ flags.BoolVarP(&logsPodOptions.Timestamps, "timestamps", "t", false, "Output the timestamps in the log")
+ flags.SetInterspersed(false)
+ _ = flags.MarkHidden("details")
+}
+
+func logs(_ *cobra.Command, args []string) error {
+ if logsPodOptions.SinceRaw != "" {
+ // parse time, error out if something is wrong
+ since, err := util.ParseInputTime(logsPodOptions.SinceRaw, true)
+ if err != nil {
+ return errors.Wrapf(err, "error parsing --since %q", logsPodOptions.SinceRaw)
+ }
+ logsPodOptions.Since = since
+ }
+ if logsPodOptions.UntilRaw != "" {
+ // parse time, error out if something is wrong
+ until, err := util.ParseInputTime(logsPodOptions.UntilRaw, false)
+ if err != nil {
+ return errors.Wrapf(err, "error parsing --until %q", logsPodOptions.UntilRaw)
+ }
+ logsPodOptions.Until = until
+ }
+
+ // Remote can only process one container at a time
+ if registry.IsRemote() && logsPodOptions.ContainerName == "" {
+ return errors.Wrapf(define.ErrInvalidArg, "-c or --container cannot be empty")
+ }
+
+ logsPodOptions.StdoutWriter = os.Stdout
+ logsPodOptions.StderrWriter = os.Stderr
+ return registry.ContainerEngine().PodLogs(registry.GetContext(), args[0], logsPodOptions.PodLogsOptions)
+}
diff --git a/cmd/podman/secrets/list.go b/cmd/podman/secrets/list.go
index e64990c6f..f136de4ab 100644
--- a/cmd/podman/secrets/list.go
+++ b/cmd/podman/secrets/list.go
@@ -48,7 +48,7 @@ func init() {
}
func ls(cmd *cobra.Command, args []string) error {
- responses, err := registry.ContainerEngine().SecretList(context.Background())
+ responses, err := registry.ContainerEngine().SecretList(context.Background(), entities.SecretListRequest{})
if err != nil {
return err
}
diff --git a/cmd/podman/system/unshare.go b/cmd/podman/system/unshare.go
index f930d8b62..50230609e 100644
--- a/cmd/podman/system/unshare.go
+++ b/cmd/podman/system/unshare.go
@@ -2,6 +2,7 @@ package system
import (
"os"
+ "os/exec"
"github.com/containers/common/pkg/completion"
"github.com/containers/podman/v3/cmd/podman/registry"
@@ -50,5 +51,23 @@ func unshare(cmd *cobra.Command, args []string) error {
args = []string{shell}
}
- return registry.ContainerEngine().Unshare(registry.Context(), args, unshareOptions)
+ err := registry.ContainerEngine().Unshare(registry.Context(), args, unshareOptions)
+ if err != nil {
+ if exitError, ok := err.(*exec.ExitError); ok {
+ // the user command inside the unshare env has failed
+ // we set the exit code, do not return the error to the user
+ // otherwise "exit status X" will be printed
+ registry.SetExitCode(exitError.ExitCode())
+ return nil
+ }
+ // cmd.Run() can return fs.ErrNotExist, fs.ErrPermission or exec.ErrNotFound
+ // follow podman run/exec standard with the exit codes
+ if errors.Is(err, os.ErrNotExist) || errors.Is(err, exec.ErrNotFound) {
+ registry.SetExitCode(127)
+ } else if errors.Is(err, os.ErrPermission) {
+ registry.SetExitCode(126)
+ }
+ return err
+ }
+ return nil
}