summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/generate/systemd.go16
-rw-r--r--cmd/podman/machine/init.go2
-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.go2
-rw-r--r--cmd/podman/machine/stop.go2
-rw-r--r--cmd/podman/pods/logs.go140
-rw-r--r--docs/source/markdown/podman-pod-logs.1.md88
-rw-r--r--docs/source/markdown/podman-pod.1.md5
-rw-r--r--docs/source/pod.rst2
-rw-r--r--pkg/api/handlers/libpod/generate.go18
-rw-r--r--pkg/api/server/register_containers.go3
-rw-r--r--pkg/domain/entities/engine_container.go1
-rw-r--r--pkg/domain/entities/generate.go2
-rw-r--r--pkg/domain/entities/pods.go27
-rw-r--r--pkg/domain/infra/abi/pods.go40
-rw-r--r--pkg/domain/infra/tunnel/generate.go5
-rw-r--r--pkg/domain/infra/tunnel/pods.go10
-rw-r--r--pkg/machine/config.go2
-rw-r--r--pkg/machine/connection.go2
-rw-r--r--pkg/machine/fcos.go2
-rw-r--r--pkg/machine/ignition.go2
-rw-r--r--pkg/machine/ignition_schema.go2
-rw-r--r--pkg/machine/keys.go2
-rw-r--r--pkg/machine/pull.go2
-rw-r--r--pkg/machine/qemu/config.go2
-rw-r--r--pkg/machine/qemu/machine.go2
-rw-r--r--pkg/machine/qemu/options_darwin.go4
-rw-r--r--pkg/systemd/define/const.go11
-rw-r--r--pkg/systemd/generate/common.go5
-rw-r--r--pkg/systemd/generate/common_test.go4
-rw-r--r--pkg/systemd/generate/containers.go37
-rw-r--r--pkg/systemd/generate/containers_test.go139
-rw-r--r--pkg/systemd/generate/pods.go9
-rw-r--r--pkg/systemd/generate/pods_test.go10
-rw-r--r--pkg/util/utils_supported.go2
-rw-r--r--test/e2e/play_kube_test.go34
-rw-r--r--test/system/250-systemd.bats23
40 files changed, 531 insertions, 136 deletions
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/machine/init.go b/cmd/podman/machine/init.go
index 3a89cfb87..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
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 b52a48faf..85101a641 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..a5ba74599 100644
--- a/cmd/podman/machine/start.go
+++ b/cmd/podman/machine/start.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/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/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/docs/source/markdown/podman-pod-logs.1.md b/docs/source/markdown/podman-pod-logs.1.md
new file mode 100644
index 000000000..8378f2eea
--- /dev/null
+++ b/docs/source/markdown/podman-pod-logs.1.md
@@ -0,0 +1,88 @@
+% podman-pod-logs(1)
+
+## NAME
+podman\-pod\-logs - Displays logs for pod with one or more containers
+
+## SYNOPSIS
+**podman pod logs** [*options*] *pod*
+
+## DESCRIPTION
+The podman pod logs command batch-retrieves whatever logs are present with all the containers of a pod. Pod logs can be filtered by container name or id using flag **-c** or **--container** if needed.
+
+Note: Long running command of `podman pod log` with a `-f` or `--follow` needs to be reinvoked if new container is added to the pod dynamically otherwise logs of newly added containers would not be visible in log stream.
+
+## OPTIONS
+
+#### **--container**, **-c**
+
+By default `podman pod logs` retrives logs for all the containers available within the pod differentiate by field `container`. However there are use-cases where user would want to limit the log stream only to a particular container of a pod for such cases `-c` can be used like `podman pod logs -c ctrNameorID podname`.
+
+#### **--follow**, **-f**
+
+Follow log output. Default is false.
+
+Note: If you are following a pod which is removed `podman pod rm`, then there is a
+chance the the log file will be removed before `podman pod logs` reads the final content.
+
+#### **--latest**, **-l**
+
+Instead of providing the pod name or id, get logs of the last created pod. (This option is not available with the remote Podman client)
+
+#### **--since**=*TIMESTAMP*
+
+Show logs since TIMESTAMP. The --since option can be Unix timestamps, date formatted timestamps, or Go duration
+strings (e.g. 10m, 1h30m) computed relative to the client machine's time. Supported formats for date formatted
+time stamps include RFC3339Nano, RFC3339, 2006-01-02T15:04:05, 2006-01-02T15:04:05.999999999, 2006-01-02Z07:00,
+and 2006-01-02.
+
+#### **--until**=*TIMESTAMP*
+
+Show logs until TIMESTAMP. The --until option can be Unix timestamps, date formatted timestamps, or Go duration
+strings (e.g. 10m, 1h30m) computed relative to the client machine's time. Supported formats for date formatted
+time stamps include RFC3339Nano, RFC3339, 2006-01-02T15:04:05, 2006-01-02T15:04:05.999999999, 2006-01-02Z07:00,
+and 2006-01-02.
+
+
+#### **--tail**=*LINES*
+
+Output the specified number of LINES at the end of the logs. LINES must be an integer. Defaults to -1,
+which prints all lines
+
+#### **--timestamps**, **-t**
+
+Show timestamps in the log outputs. The default is false
+
+## EXAMPLE
+
+To view a pod's logs:
+```
+podman pod logs -t podIdorName
+```
+
+To view logs of a specific container on the pod
+```
+podman pod logs -c ctrIdOrName podIdOrName
+```
+
+To view all pod logs:
+```
+podman pod logs -t --since 0 myserver-pod-1
+```
+
+To view a pod's logs since a certain time:
+```
+podman pod logs -t --since 2017-08-07T10:10:09.055837383-04:00 myserver-pod-1
+```
+
+To view a pod's logs generated in the last 10 minutes:
+```
+podman pod logs --since 10m myserver-pod-1
+```
+
+To view a pod's logs until 30 minutes ago:
+```
+podman pod logs --until 30m myserver-pod-1
+```
+
+## SEE ALSO
+podman(1), podman-pod-start(1), podman-pod-rm(1), podman-logs(1)
diff --git a/docs/source/markdown/podman-pod.1.md b/docs/source/markdown/podman-pod.1.md
index e5a8207e9..9de2442bd 100644
--- a/docs/source/markdown/podman-pod.1.md
+++ b/docs/source/markdown/podman-pod.1.md
@@ -17,11 +17,12 @@ podman pod is a set of subcommands that manage pods, or groups of containers.
| exists | [podman-pod-exists(1)](podman-pod-exists.1.md) | Check if a pod exists in local storage. |
| inspect | [podman-pod-inspect(1)](podman-pod-inspect.1.md) | Displays information describing a pod. |
| kill | [podman-pod-kill(1)](podman-pod-kill.1.md) | Kill the main process of each container in one or more pods. |
+| logs | [podman-pod-logs(1)](podman-pod-logs.1.md) | Displays logs for pod with one or more containers. |
| pause | [podman-pod-pause(1)](podman-pod-pause.1.md) | Pause one or more pods. |
-| prune | [podman-pod-prune(1)](podman-pod-prune.1.md) | Remove all stopped pods and their containers. |
+| prune | [podman-pod-prune(1)](podman-pod-prune.1.md) | Remove all stopped pods and their containers. |
| ps | [podman-pod-ps(1)](podman-pod-ps.1.md) | Prints out information about pods. |
| restart | [podman-pod-restart(1)](podman-pod-restart.1.md) | Restart one or more pods. |
-| rm | [podman-pod-rm(1)](podman-pod-rm.1.md) | Remove one or more stopped pods and containers. |
+| rm | [podman-pod-rm(1)](podman-pod-rm.1.md) | Remove one or more stopped pods and containers. |
| start | [podman-pod-start(1)](podman-pod-start.1.md) | Start one or more pods. |
| stats | [podman-pod-stats(1)](podman-pod-stats.1.md) | Display a live stream of resource usage stats for containers in one or more pods. |
| stop | [podman-pod-stop(1)](podman-pod-stop.1.md) | Stop one or more pods. |
diff --git a/docs/source/pod.rst b/docs/source/pod.rst
index 2df377762..d9ad07d83 100644
--- a/docs/source/pod.rst
+++ b/docs/source/pod.rst
@@ -9,6 +9,8 @@ Pod
:doc:`kill <markdown/podman-pod-kill.1>` Send the specified signal or SIGKILL to containers in pod
+:doc:`logs <markdown/podman-pod-logs.1>` Displays logs for pod with one or more containers
+
:doc:`pause <markdown/podman-pause.1>` Pause one or more pods
:doc:`prune <markdown/podman-pod-prune.1>` Remove all stopped pods and their containers
diff --git a/pkg/api/handlers/libpod/generate.go b/pkg/api/handlers/libpod/generate.go
index 0e6e9100a..8a2b93d0e 100644
--- a/pkg/api/handlers/libpod/generate.go
+++ b/pkg/api/handlers/libpod/generate.go
@@ -16,16 +16,15 @@ func GenerateSystemd(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
- Name bool `schema:"useName"`
- New bool `schema:"new"`
- NoHeader bool `schema:"noHeader"`
- RestartPolicy string `schema:"restartPolicy"`
- StopTimeout uint `schema:"stopTimeout"`
- ContainerPrefix string `schema:"containerPrefix"`
- PodPrefix string `schema:"podPrefix"`
- Separator string `schema:"separator"`
+ Name bool `schema:"useName"`
+ New bool `schema:"new"`
+ NoHeader bool `schema:"noHeader"`
+ RestartPolicy *string `schema:"restartPolicy"`
+ StopTimeout uint `schema:"stopTimeout"`
+ ContainerPrefix string `schema:"containerPrefix"`
+ PodPrefix string `schema:"podPrefix"`
+ Separator string `schema:"separator"`
}{
- RestartPolicy: "on-failure",
StopTimeout: util.DefaultContainerConfig().Engine.StopTimeout,
ContainerPrefix: "container",
PodPrefix: "pod",
@@ -49,6 +48,7 @@ func GenerateSystemd(w http.ResponseWriter, r *http.Request) {
PodPrefix: query.PodPrefix,
Separator: query.Separator,
}
+
report, err := containerEngine.GenerateSystemd(r.Context(), utils.GetName(r), options)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error generating systemd units"))
diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go
index b36cb75f1..2a32966cc 100644
--- a/pkg/api/server/register_containers.go
+++ b/pkg/api/server/register_containers.go
@@ -1028,7 +1028,8 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// - in: query
// name: t
// type: integer
- // description: timeout before sending kill signal to container
+ // default: 10
+ // description: number of seconds to wait before killing container
// produces:
// - application/json
// responses:
diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go
index bd011d309..93fa7a20f 100644
--- a/pkg/domain/entities/engine_container.go
+++ b/pkg/domain/entities/engine_container.go
@@ -72,6 +72,7 @@ type ContainerEngine interface {
PodExists(ctx context.Context, nameOrID string) (*BoolReport, error)
PodInspect(ctx context.Context, options PodInspectOptions) (*PodInspectReport, error)
PodKill(ctx context.Context, namesOrIds []string, options PodKillOptions) ([]*PodKillReport, error)
+ PodLogs(ctx context.Context, pod string, options PodLogsOptions) error
PodPause(ctx context.Context, namesOrIds []string, options PodPauseOptions) ([]*PodPauseReport, error)
PodPrune(ctx context.Context, options PodPruneOptions) ([]*PodPruneReport, error)
PodPs(ctx context.Context, options PodPSOptions) ([]*ListPodsReport, error)
diff --git a/pkg/domain/entities/generate.go b/pkg/domain/entities/generate.go
index 8a437061f..7809c5241 100644
--- a/pkg/domain/entities/generate.go
+++ b/pkg/domain/entities/generate.go
@@ -9,7 +9,7 @@ type GenerateSystemdOptions struct {
// New - create a new container instead of starting a new one.
New bool
// RestartPolicy - systemd restart policy.
- RestartPolicy string
+ RestartPolicy *string
// StopTimeout - time when stopping the container.
StopTimeout *uint
// ContainerPrefix - systemd unit name prefix for containers
diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go
index 10bd7e5ce..d9dd0c532 100644
--- a/pkg/domain/entities/pods.go
+++ b/pkg/domain/entities/pods.go
@@ -133,6 +133,14 @@ type PodCreateOptions struct {
Userns specgen.Namespace
}
+// PodLogsOptions describes the options to extract pod logs.
+type PodLogsOptions struct {
+ // Other fields are exactly same as ContainerLogOpts
+ ContainerLogsOptions
+ // If specified will only fetch the logs of specified container
+ ContainerName string
+}
+
type ContainerCreateOptions struct {
Annotation []string
Attach []string
@@ -426,3 +434,22 @@ func ValidatePodStatsOptions(args []string, options *PodStatsOptions) error {
return errors.New("--all, --latest and arguments cannot be used together")
}
}
+
+// Converts PodLogOptions to ContainerLogOptions
+func PodLogsOptionsToContainerLogsOptions(options PodLogsOptions) ContainerLogsOptions {
+ // PodLogsOptions are similar but contains few extra fields like ctrName
+ // So cast other values as is so we can re-use the code
+ containerLogsOpts := ContainerLogsOptions{
+ Details: options.Details,
+ Latest: options.Latest,
+ Follow: options.Follow,
+ Names: options.Names,
+ Since: options.Since,
+ Until: options.Until,
+ Tail: options.Tail,
+ Timestamps: options.Timestamps,
+ StdoutWriter: options.StdoutWriter,
+ StderrWriter: options.StderrWriter,
+ }
+ return containerLogsOpts
+}
diff --git a/pkg/domain/infra/abi/pods.go b/pkg/domain/infra/abi/pods.go
index 98233f60d..6b432c214 100644
--- a/pkg/domain/infra/abi/pods.go
+++ b/pkg/domain/infra/abi/pods.go
@@ -83,6 +83,46 @@ func (ic *ContainerEngine) PodKill(ctx context.Context, namesOrIds []string, opt
return reports, nil
}
+func (ic *ContainerEngine) PodLogs(ctx context.Context, nameOrID string, options entities.PodLogsOptions) error {
+ // Implementation accepts slice
+ podName := []string{nameOrID}
+ pod, err := getPodsByContext(false, options.Latest, podName, ic.Libpod)
+ if err != nil {
+ return err
+ }
+ // Get pod containers
+ podCtrs, err := pod[0].AllContainers()
+ if err != nil {
+ return err
+ }
+
+ ctrNames := []string{}
+ // Check if `kubectl pod logs -c ctrname <podname>` alike command is used
+ if options.ContainerName != "" {
+ ctrFound := false
+ for _, ctr := range podCtrs {
+ if ctr.ID() == options.ContainerName || ctr.Name() == options.ContainerName {
+ ctrNames = append(ctrNames, options.ContainerName)
+ ctrFound = true
+ }
+ }
+ if !ctrFound {
+ return errors.Wrapf(define.ErrNoSuchCtr, "container %s is not in pod %s", options.ContainerName, nameOrID)
+ }
+ } else {
+ // No container name specified select all containers
+ for _, ctr := range podCtrs {
+ ctrNames = append(ctrNames, ctr.Name())
+ }
+ }
+
+ // PodLogsOptions are similar but contains few extra fields like ctrName
+ // So cast other values as is so we can re-use the code
+ containerLogsOpts := entities.PodLogsOptionsToContainerLogsOptions(options)
+
+ return ic.ContainerLogs(ctx, ctrNames, containerLogsOpts)
+}
+
func (ic *ContainerEngine) PodPause(ctx context.Context, namesOrIds []string, options entities.PodPauseOptions) ([]*entities.PodPauseReport, error) {
reports := []*entities.PodPauseReport{}
pods, err := getPodsByContext(options.All, options.Latest, namesOrIds, ic.Libpod)
diff --git a/pkg/domain/infra/tunnel/generate.go b/pkg/domain/infra/tunnel/generate.go
index 3d3cd52be..9f69abb1a 100644
--- a/pkg/domain/infra/tunnel/generate.go
+++ b/pkg/domain/infra/tunnel/generate.go
@@ -9,7 +9,10 @@ import (
func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string, opts entities.GenerateSystemdOptions) (*entities.GenerateSystemdReport, error) {
options := new(generate.SystemdOptions).WithUseName(opts.Name).WithContainerPrefix(opts.ContainerPrefix).WithNew(opts.New).WithNoHeader(opts.NoHeader)
- options.WithPodPrefix(opts.PodPrefix).WithRestartPolicy(opts.RestartPolicy).WithSeparator(opts.Separator)
+ options.WithPodPrefix(opts.PodPrefix).WithSeparator(opts.Separator)
+ if opts.RestartPolicy != nil {
+ options.WithRestartPolicy(*opts.RestartPolicy)
+ }
if to := opts.StopTimeout; to != nil {
options.WithStopTimeout(*opts.StopTimeout)
}
diff --git a/pkg/domain/infra/tunnel/pods.go b/pkg/domain/infra/tunnel/pods.go
index 480adb88a..8139216b3 100644
--- a/pkg/domain/infra/tunnel/pods.go
+++ b/pkg/domain/infra/tunnel/pods.go
@@ -42,6 +42,16 @@ func (ic *ContainerEngine) PodKill(ctx context.Context, namesOrIds []string, opt
return reports, nil
}
+func (ic *ContainerEngine) PodLogs(_ context.Context, nameOrIDs string, options entities.PodLogsOptions) error {
+ // PodLogsOptions are similar but contains few extra fields like ctrName
+ // So cast other values as is so we can re-use the code
+ containerLogsOpts := entities.PodLogsOptionsToContainerLogsOptions(options)
+
+ // interface only accepts slice, keep everything consistent
+ name := []string{options.ContainerName}
+ return ic.ContainerLogs(nil, name, containerLogsOpts)
+}
+
func (ic *ContainerEngine) PodPause(ctx context.Context, namesOrIds []string, options entities.PodPauseOptions) ([]*entities.PodPauseReport, error) {
foundPods, err := getPodsByContext(ic.ClientCtx, options.All, namesOrIds)
if err != nil {
diff --git a/pkg/machine/config.go b/pkg/machine/config.go
index db9bfa7de..cad71ba49 100644
--- a/pkg/machine/config.go
+++ b/pkg/machine/config.go
@@ -1,4 +1,4 @@
-// +build amd64,linux arm64,linux amd64,darwin arm64,darwin
+// +build amd64,!windows arm64,!windows
package machine
diff --git a/pkg/machine/connection.go b/pkg/machine/connection.go
index 3edcbd10e..ed1093264 100644
--- a/pkg/machine/connection.go
+++ b/pkg/machine/connection.go
@@ -1,4 +1,4 @@
-// +build amd64,linux arm64,linux amd64,darwin arm64,darwin
+// +build amd64,!windows arm64,!windows
package machine
diff --git a/pkg/machine/fcos.go b/pkg/machine/fcos.go
index 85cedcd5a..4ea965b7f 100644
--- a/pkg/machine/fcos.go
+++ b/pkg/machine/fcos.go
@@ -1,4 +1,4 @@
-// +build amd64,linux arm64,linux amd64,darwin arm64,darwin
+// +build amd64,!windows arm64,!windows
package machine
diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go
index 1d77083d0..a9289d6b3 100644
--- a/pkg/machine/ignition.go
+++ b/pkg/machine/ignition.go
@@ -1,4 +1,4 @@
-// +build amd64,linux arm64,linux amd64,darwin arm64,darwin
+// +build amd64,!windows arm64,!windows
package machine
diff --git a/pkg/machine/ignition_schema.go b/pkg/machine/ignition_schema.go
index 6ac8af826..aa4b8e060 100644
--- a/pkg/machine/ignition_schema.go
+++ b/pkg/machine/ignition_schema.go
@@ -1,4 +1,4 @@
-// +build amd64,linux arm64,linux amd64,darwin arm64,darwin
+// +build amd64,!windows arm64,!windows
package machine
diff --git a/pkg/machine/keys.go b/pkg/machine/keys.go
index 81ec44ea8..319fc2b4e 100644
--- a/pkg/machine/keys.go
+++ b/pkg/machine/keys.go
@@ -1,4 +1,4 @@
-// +build amd64,linux arm64,linux amd64,darwin arm64,darwin
+// +build amd64,!windows arm64,!windows
package machine
diff --git a/pkg/machine/pull.go b/pkg/machine/pull.go
index 662896de5..f79ac6ec4 100644
--- a/pkg/machine/pull.go
+++ b/pkg/machine/pull.go
@@ -1,4 +1,4 @@
-// +build amd64,linux arm64,linux amd64,darwin arm64,darwin
+// +build amd64,!windows arm64,!windows
package machine
diff --git a/pkg/machine/qemu/config.go b/pkg/machine/qemu/config.go
index 013f28960..3d0fa4094 100644
--- a/pkg/machine/qemu/config.go
+++ b/pkg/machine/qemu/config.go
@@ -1,4 +1,4 @@
-// +build amd64,linux arm64,linux amd64,darwin arm64,darwin
+// +build amd64,!windows arm64,!windows
package qemu
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index dc7703724..855a39c56 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -1,4 +1,4 @@
-// +build amd64,linux arm64,linux amd64,darwin arm64,darwin
+// +build amd64,!windows arm64,!windows
package qemu
diff --git a/pkg/machine/qemu/options_darwin.go b/pkg/machine/qemu/options_darwin.go
index 440937131..124358db8 100644
--- a/pkg/machine/qemu/options_darwin.go
+++ b/pkg/machine/qemu/options_darwin.go
@@ -2,14 +2,12 @@ package qemu
import (
"os"
-
- "github.com/pkg/errors"
)
func getRuntimeDir() (string, error) {
tmpDir, ok := os.LookupEnv("TMPDIR")
if !ok {
- return "", errors.New("unable to resolve TMPDIR")
+ tmpDir = "/tmp"
}
return tmpDir, nil
}
diff --git a/pkg/systemd/define/const.go b/pkg/systemd/define/const.go
index 1b50be5db..6bab8b629 100644
--- a/pkg/systemd/define/const.go
+++ b/pkg/systemd/define/const.go
@@ -1,8 +1,13 @@
package define
-// EnvVariable "PODMAN_SYSTEMD_UNIT" is set in all generated systemd units and
-// is set to the unit's (unique) name.
-const EnvVariable = "PODMAN_SYSTEMD_UNIT"
+const (
+ // Default restart policy for generated unit files.
+ DefaultRestartPolicy = "on-failure"
+
+ // EnvVariable "PODMAN_SYSTEMD_UNIT" is set in all generated systemd units and
+ // is set to the unit's (unique) name.
+ EnvVariable = "PODMAN_SYSTEMD_UNIT"
+)
// RestartPolicies includes all valid restart policies to be used in a unit
// file.
diff --git a/pkg/systemd/generate/common.go b/pkg/systemd/generate/common.go
index 49465fb30..3515bb3b7 100644
--- a/pkg/systemd/generate/common.go
+++ b/pkg/systemd/generate/common.go
@@ -71,12 +71,13 @@ func filterCommonContainerFlags(command []string, argCount int) []string {
case s == "--rm":
// Boolean flags support --flag and --flag={true,false}.
continue
- case s == "--sdnotify", s == "--cgroups", s == "--cidfile":
+ case s == "--sdnotify", s == "--cgroups", s == "--cidfile", s == "--restart":
i++
continue
case strings.HasPrefix(s, "--rm="),
strings.HasPrefix(s, "--cgroups="),
- strings.HasPrefix(s, "--cidfile="):
+ strings.HasPrefix(s, "--cidfile="),
+ strings.HasPrefix(s, "--restart="):
continue
}
processed = append(processed, s)
diff --git a/pkg/systemd/generate/common_test.go b/pkg/systemd/generate/common_test.go
index 80abebb26..45004ecb0 100644
--- a/pkg/systemd/generate/common_test.go
+++ b/pkg/systemd/generate/common_test.go
@@ -117,12 +117,12 @@ func TestFilterCommonContainerFlags(t *testing.T) {
1,
},
{
- []string{"podman", "run", "--cgroups=foo", "alpine"},
+ []string{"podman", "run", "--cgroups=foo", "--restart=foo", "alpine"},
[]string{"podman", "run", "alpine"},
1,
},
{
- []string{"podman", "run", "--cgroups=foo", "--rm", "alpine"},
+ []string{"podman", "run", "--cgroups=foo", "--rm", "--restart", "foo", "alpine"},
[]string{"podman", "run", "alpine"},
1,
},
diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go
index 188926115..037652a6d 100644
--- a/pkg/systemd/generate/containers.go
+++ b/pkg/systemd/generate/containers.go
@@ -10,6 +10,7 @@ import (
"time"
"github.com/containers/podman/v3/libpod"
+ libpodDefine "github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/systemd/define"
"github.com/containers/podman/v3/version"
@@ -34,6 +35,8 @@ type containerInfo struct {
StopTimeout uint
// RestartPolicy of the systemd unit (e.g., no, on-failure, always).
RestartPolicy string
+ // Custom number of restart attempts.
+ StartLimitBurst string
// PIDFile of the service. Required for forking services. Must point to the
// PID of the associated conmon process.
PIDFile string
@@ -101,6 +104,9 @@ Environment={{{{.EnvVariable}}}}=%n
Environment={{{{- range $index, $value := .ExtraEnvs -}}}}{{{{if $index}}}} {{{{end}}}}{{{{ $value }}}}{{{{end}}}}
{{{{- end}}}}
Restart={{{{.RestartPolicy}}}}
+{{{{- if .StartLimitBurst}}}}
+StartLimitBurst={{{{.StartLimitBurst}}}}
+{{{{- end}}}}
TimeoutStopSec={{{{.TimeoutStopSec}}}}
{{{{- if .ExecStartPre}}}}
ExecStartPre={{{{.ExecStartPre}}}}
@@ -175,7 +181,7 @@ func generateContainerInfo(ctr *libpod.Container, options entities.GenerateSyste
info := containerInfo{
ServiceName: serviceName,
ContainerNameOrID: nameOrID,
- RestartPolicy: options.RestartPolicy,
+ RestartPolicy: define.DefaultRestartPolicy,
PIDFile: conmonPidFile,
StopTimeout: timeout,
GenerateTimestamp: true,
@@ -202,8 +208,11 @@ func containerServiceName(ctr *libpod.Container, options entities.GenerateSystem
// containerInfo. Note that the containerInfo is also post processed and
// completed, which allows for an easier unit testing.
func executeContainerTemplate(info *containerInfo, options entities.GenerateSystemdOptions) (string, error) {
- if err := validateRestartPolicy(info.RestartPolicy); err != nil {
- return "", err
+ if options.RestartPolicy != nil {
+ if err := validateRestartPolicy(*options.RestartPolicy); err != nil {
+ return "", err
+ }
+ info.RestartPolicy = *options.RestartPolicy
}
// Make sure the executable is set.
@@ -275,6 +284,7 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
fs.Bool("replace", false, "")
fs.StringArrayP("env", "e", nil, "")
fs.String("sdnotify", "", "")
+ fs.String("restart", "", "")
fs.Parse(remainingCmd)
remainingCmd = filterCommonContainerFlags(remainingCmd, fs.NArg())
@@ -339,6 +349,27 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
}
}
+ // Unless the user explicitly set a restart policy, check
+ // whether the container was created with a custom one and use
+ // it instead of the default.
+ if options.RestartPolicy == nil {
+ restartPolicy, err := fs.GetString("restart")
+ if err != nil {
+ return "", err
+ }
+ if restartPolicy != "" {
+ if strings.HasPrefix(restartPolicy, "on-failure:") {
+ // Special case --restart=on-failure:5
+ spl := strings.Split(restartPolicy, ":")
+ restartPolicy = spl[0]
+ info.StartLimitBurst = spl[1]
+ } else if restartPolicy == libpodDefine.RestartPolicyUnlessStopped {
+ restartPolicy = libpodDefine.RestartPolicyAlways
+ }
+ info.RestartPolicy = restartPolicy
+ }
+ }
+
envs, err := fs.GetStringArray("env")
if err != nil {
return "", err
diff --git a/pkg/systemd/generate/containers_test.go b/pkg/systemd/generate/containers_test.go
index c60c301cc..f46513459 100644
--- a/pkg/systemd/generate/containers_test.go
+++ b/pkg/systemd/generate/containers_test.go
@@ -52,7 +52,7 @@ RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
-Restart=always
+Restart=on-failure
TimeoutStopSec=82
ExecStart=/usr/bin/podman start 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401
ExecStop=/usr/bin/podman stop -t 22 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401
@@ -78,7 +78,7 @@ RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
-Restart=always
+Restart=on-failure
TimeoutStopSec=70
ExecStart=/usr/bin/podman start foobar
ExecStop=/usr/bin/podman stop -t 10 foobar
@@ -104,7 +104,7 @@ After=a.service b.service c.service pod.service
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
-Restart=always
+Restart=on-failure
TimeoutStopSec=70
ExecStart=/usr/bin/podman start foobar
ExecStop=/usr/bin/podman stop -t 10 foobar
@@ -128,7 +128,7 @@ RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
-Restart=always
+Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman container run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d --replace --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN "foo=arg \"with \" space"
@@ -153,7 +153,7 @@ RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
-Restart=always
+Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman container run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm -d --replace --sdnotify=container --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN "foo=arg \"with \" space"
@@ -178,7 +178,7 @@ RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
-Restart=always
+Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon --replace -d --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN
@@ -203,7 +203,7 @@ RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
-Restart=always
+Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --pod-id-file %t/pod-foobar.pod-id-file --sdnotify=conmon --replace -d --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN
@@ -228,7 +228,7 @@ RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
-Restart=always
+Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon --replace --detach --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN
@@ -253,7 +253,7 @@ RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
-Restart=always
+Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d awesome-image:latest
@@ -279,7 +279,7 @@ RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
-Restart=always
+Restart=on-failure
TimeoutStopSec=102
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon ` +
@@ -308,7 +308,7 @@ RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
-Restart=always
+Restart=on-failure
TimeoutStopSec=102
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d --replace --name test -p 80:80 awesome-image:latest somecmd --detach=false
@@ -333,7 +333,7 @@ RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
-Restart=always
+Restart=on-failure
TimeoutStopSec=102
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman --events-backend none --runroot /root run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d awesome-image:latest
@@ -358,7 +358,7 @@ RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
-Restart=always
+Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman container run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d awesome-image:latest
@@ -383,7 +383,7 @@ RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
-Restart=always
+Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d --replace --name test --log-driver=journald --log-opt=tag={{.Name}} awesome-image:latest
@@ -408,7 +408,7 @@ RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
-Restart=always
+Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d --replace --name test awesome-image:latest sh -c "kill $$$$ && echo %%\\"
@@ -433,7 +433,7 @@ RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
-Restart=always
+Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d --conmon-pidfile=foo awesome-image:latest podman run --cgroups=foo --conmon-pidfile=foo --cidfile=foo alpine
@@ -458,7 +458,7 @@ RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
-Restart=always
+Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --pod-id-file %t/pod-foobar.pod-id-file --sdnotify=conmon -d --conmon-pidfile=foo awesome-image:latest podman run --cgroups=foo --conmon-pidfile=foo --cidfile=foo --pod-id-file /tmp/pod-foobar.pod-id-file alpine
@@ -484,7 +484,7 @@ RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Environment=FOO=abc "BAR=my test" USER=%%a
-Restart=always
+Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d --env FOO --env=BAR --env=MYENV=2 -e USER awesome-image:latest
@@ -496,6 +496,32 @@ NotifyAccess=all
[Install]
WantedBy=multi-user.target default.target
`
+
+ goodNewWithRestartPolicy := `# jadda-jadda.service
+# autogenerated by Podman CI
+
+[Unit]
+Description=Podman jadda-jadda.service
+Documentation=man:podman-generate-systemd(1)
+Wants=network-online.target
+After=network-online.target
+RequiresMountsFor=/var/run/containers/storage
+
+[Service]
+Environment=PODMAN_SYSTEMD_UNIT=%n
+Restart=on-failure
+StartLimitBurst=42
+TimeoutStopSec=70
+ExecStartPre=/bin/rm -f %t/%n.ctr-id
+ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d awesome-image:latest
+ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
+ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id
+Type=notify
+NotifyAccess=all
+
+[Install]
+WantedBy=multi-user.target default.target
+`
tests := []struct {
name string
info containerInfo
@@ -510,7 +536,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401",
ContainerNameOrID: "639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401",
- RestartPolicy: "always",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 22,
PodmanVersion: "CI",
@@ -528,7 +553,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401",
ContainerNameOrID: "639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401",
- RestartPolicy: "always",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 22,
PodmanVersion: "CI",
@@ -546,7 +570,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "container-foobar",
ContainerNameOrID: "foobar",
- RestartPolicy: "always",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
@@ -564,7 +587,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "container-foobar",
ContainerNameOrID: "foobar",
- RestartPolicy: "always",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
@@ -578,29 +600,11 @@ WantedBy=multi-user.target default.target
false,
false,
},
- {"bad restart policy",
- containerInfo{
- Executable: "/usr/bin/podman",
- ServiceName: "639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401",
- RestartPolicy: "never",
- PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
- StopTimeout: 10,
- PodmanVersion: "CI",
- EnvVariable: define.EnvVariable,
- GraphRoot: "/var/lib/containers/storage",
- RunRoot: "/var/run/containers/storage",
- },
- "",
- false,
- false,
- true,
- },
{"good with name and generic",
containerInfo{
Executable: "/usr/bin/podman",
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
- RestartPolicy: "always",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
@@ -619,7 +623,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
- RestartPolicy: "always",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
@@ -638,7 +641,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
- RestartPolicy: "always",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
@@ -657,7 +659,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
- RestartPolicy: "always",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
@@ -679,7 +680,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
- RestartPolicy: "always",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
@@ -698,7 +698,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401",
ContainerNameOrID: "639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401",
- RestartPolicy: "always",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
@@ -717,7 +716,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
- RestartPolicy: "always",
PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 42,
PodmanVersion: "CI",
@@ -736,7 +734,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
- RestartPolicy: "always",
PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 42,
PodmanVersion: "CI",
@@ -755,7 +752,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
- RestartPolicy: "always",
PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 42,
PodmanVersion: "CI",
@@ -774,7 +770,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
- RestartPolicy: "always",
PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 42,
PodmanVersion: "CI",
@@ -793,7 +788,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
- RestartPolicy: "always",
PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 42,
PodmanVersion: "CI",
@@ -812,26 +806,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
- RestartPolicy: "always",
- PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
- StopTimeout: 42,
- PodmanVersion: "CI",
- CreateCommand: []string{"I'll get stripped", "run", "-tid", "awesome-image:latest"},
- EnvVariable: define.EnvVariable,
- GraphRoot: "/var/lib/containers/storage",
- RunRoot: "/var/run/containers/storage",
- },
- genGoodNewDetach("-tid"),
- true,
- false,
- false,
- },
- {"good with root flags",
- containerInfo{
- Executable: "/usr/bin/podman",
- ServiceName: "jadda-jadda",
- ContainerNameOrID: "jadda-jadda",
- RestartPolicy: "always",
PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 42,
PodmanVersion: "CI",
@@ -850,7 +824,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
- RestartPolicy: "always",
PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
@@ -869,7 +842,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
- RestartPolicy: "always",
PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
@@ -888,7 +860,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
- RestartPolicy: "always",
PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
@@ -907,7 +878,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
- RestartPolicy: "always",
PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
@@ -926,7 +896,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
- RestartPolicy: "always",
PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
@@ -948,7 +917,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "jadda-jadda",
ContainerNameOrID: "jadda-jadda",
- RestartPolicy: "always",
PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
@@ -963,6 +931,24 @@ WantedBy=multi-user.target default.target
false,
false,
},
+ {"good with restart policy",
+ containerInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "jadda-jadda",
+ ContainerNameOrID: "jadda-jadda",
+ PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 10,
+ PodmanVersion: "CI",
+ GraphRoot: "/var/lib/containers/storage",
+ RunRoot: "/var/run/containers/storage",
+ CreateCommand: []string{"I'll get stripped", "create", "--restart", "on-failure:42", "awesome-image:latest"},
+ EnvVariable: define.EnvVariable,
+ },
+ goodNewWithRestartPolicy,
+ true,
+ false,
+ false,
+ },
}
for _, tt := range tests {
test := tt
@@ -971,6 +957,7 @@ WantedBy=multi-user.target default.target
New: test.new,
NoHeader: test.noHeader,
}
+ test.info.RestartPolicy = define.DefaultRestartPolicy
got, err := executeContainerTemplate(&test.info, opts)
if (err != nil) != test.wantErr {
t.Errorf("CreateContainerSystemdUnit() %s error = \n%v, wantErr \n%v", test.name, err, test.wantErr)
diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go
index 1b92649e8..e755b8eea 100644
--- a/pkg/systemd/generate/pods.go
+++ b/pkg/systemd/generate/pods.go
@@ -217,7 +217,6 @@ func generatePodInfo(pod *libpod.Pod, options entities.GenerateSystemdOptions) (
info := podInfo{
ServiceName: serviceName,
InfraNameOrID: ctrNameOrID,
- RestartPolicy: options.RestartPolicy,
PIDFile: conmonPidFile,
StopTimeout: timeout,
GenerateTimestamp: true,
@@ -230,8 +229,12 @@ func generatePodInfo(pod *libpod.Pod, options entities.GenerateSystemdOptions) (
// that the podInfo is also post processed and completed, which allows for an
// easier unit testing.
func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions) (string, error) {
- if err := validateRestartPolicy(info.RestartPolicy); err != nil {
- return "", err
+ info.RestartPolicy = define.DefaultRestartPolicy
+ if options.RestartPolicy != nil {
+ if err := validateRestartPolicy(*options.RestartPolicy); err != nil {
+ return "", err
+ }
+ info.RestartPolicy = *options.RestartPolicy
}
// Make sure the executable is set.
diff --git a/pkg/systemd/generate/pods_test.go b/pkg/systemd/generate/pods_test.go
index 4b8a9ffd5..c565a30ed 100644
--- a/pkg/systemd/generate/pods_test.go
+++ b/pkg/systemd/generate/pods_test.go
@@ -53,7 +53,7 @@ Before=container-1.service container-2.service
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
-Restart=always
+Restart=on-failure
TimeoutStopSec=102
ExecStart=/usr/bin/podman start jadda-jadda-infra
ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra
@@ -192,7 +192,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "pod-123abc",
InfraNameOrID: "jadda-jadda-infra",
- RestartPolicy: "always",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 42,
PodmanVersion: "CI",
@@ -211,7 +210,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "pod-123abc",
InfraNameOrID: "jadda-jadda-infra",
- RestartPolicy: "always",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 42,
PodmanVersion: "CI",
@@ -230,7 +228,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "pod-123abc",
InfraNameOrID: "jadda-jadda-infra",
- RestartPolicy: "always",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 42,
PodmanVersion: "CI",
@@ -249,7 +246,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "pod-123abc",
InfraNameOrID: "jadda-jadda-infra",
- RestartPolicy: "on-failure",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
@@ -268,7 +264,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "pod-123abc",
InfraNameOrID: "jadda-jadda-infra",
- RestartPolicy: "on-failure",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
@@ -287,7 +282,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "pod-123abc",
InfraNameOrID: "jadda-jadda-infra",
- RestartPolicy: "on-failure",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
@@ -306,7 +300,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "pod-123abc",
InfraNameOrID: "jadda-jadda-infra",
- RestartPolicy: "on-failure",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
@@ -325,7 +318,6 @@ WantedBy=multi-user.target default.target
Executable: "/usr/bin/podman",
ServiceName: "pod-123abc",
InfraNameOrID: "jadda-jadda-infra",
- RestartPolicy: "on-failure",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
diff --git a/pkg/util/utils_supported.go b/pkg/util/utils_supported.go
index cb992d8b6..6eba0bc3c 100644
--- a/pkg/util/utils_supported.go
+++ b/pkg/util/utils_supported.go
@@ -1,4 +1,4 @@
-// +build linux darwin
+// +build !windows
package util
diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go
index ab496f0eb..5d875effd 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -1289,6 +1289,40 @@ var _ = Describe("Podman play kube", func() {
Expect(logs.OutputToString()).To(ContainSubstring("hello world"))
})
+ It("podman pod logs test", func() {
+ SkipIfRemote("podman-remote pod logs -c is mandatory for remote machine")
+ p := getPod(withCtr(getCtr(withCmd([]string{"echo", "hello"}), withArg([]string{"world"}))))
+
+ err := generateKubeYaml("pod", p, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube).Should(Exit(0))
+
+ logs := podmanTest.Podman([]string{"pod", "logs", p.Name})
+ logs.WaitWithDefaultTimeout()
+ Expect(logs).Should(Exit(0))
+ Expect(logs.OutputToString()).To(ContainSubstring("hello world"))
+ })
+
+ It("podman-remote pod logs test", func() {
+ // -c or --container is required in podman-remote due to api limitation.
+ p := getPod(withCtr(getCtr(withCmd([]string{"echo", "hello"}), withArg([]string{"world"}))))
+
+ err := generateKubeYaml("pod", p, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube).Should(Exit(0))
+
+ logs := podmanTest.Podman([]string{"pod", "logs", "-c", getCtrNameInPod(p), p.Name})
+ logs.WaitWithDefaultTimeout()
+ Expect(logs).Should(Exit(0))
+ Expect(logs.OutputToString()).To(ContainSubstring("hello world"))
+ })
+
It("podman play kube test restartPolicy", func() {
// podName, set, expect
testSli := [][]string{
diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats
index 08fad5e7c..4578d9e60 100644
--- a/test/system/250-systemd.bats
+++ b/test/system/250-systemd.bats
@@ -136,6 +136,29 @@ function service_cleanup() {
service_cleanup
}
+# Regression test for #11438
+@test "podman generate systemd - restart policy" {
+ cname=$(random_string)
+ run_podman create --restart=always --name $cname $IMAGE
+ run_podman generate systemd --new $cname
+ is "$output" ".*Restart=always.*" "Use container's restart policy if set"
+ run_podman generate systemd --new --restart-policy=on-failure $cname
+ is "$output" ".*Restart=on-failure.*" "Override container's restart policy"
+
+ cname2=$(random_string)
+ run_podman create --restart=unless-stopped --name $cname2 $IMAGE
+ run_podman generate systemd --new $cname2
+ is "$output" ".*Restart=always.*" "unless-stopped translated to always"
+
+ cname3=$(random_string)
+ run_podman create --restart=on-failure:42 --name $cname3 $IMAGE
+ run_podman generate systemd --new $cname3
+ is "$output" ".*Restart=on-failure.*" "on-failure:xx is parsed correclty"
+ is "$output" ".*StartLimitBurst=42.*" "on-failure:xx is parsed correctly"
+
+ run_podman rm -f $cname $cname2 $cname3
+}
+
function set_listen_env() {
export LISTEN_PID="100" LISTEN_FDS="1" LISTEN_FDNAMES="listen_fdnames"
}