diff options
46 files changed, 305 insertions, 179 deletions
@@ -5,7 +5,7 @@ Podman (the POD MANager) is a tool for managing containers and images, volumes mounted into those containers, and pods made from groups of containers. Podman is based on libpod, a library for container lifecycle management that is also contained in this repository. The libpod library provides APIs for managing containers, pods, container images, and volumes. -* [Latest Version: 3.3.0](https://github.com/containers/podman/releases/latest) +* [Latest Version: 3.3.1](https://github.com/containers/podman/releases/latest) * Latest Remote client for Windows * Latest Remote client for macOS * Latest Static Remote client for Linux diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 9649e7abb..b9b94dbb3 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,17 @@ # Release Notes +## 3.3.1 +### Bugfixes +- Fixed a bug where unit files created by `podman generate systemd` could not cleanup shut down containers when stopped by `systemctl stop` ([#11304](https://github.com/containers/podman/issues/11304)). +- Fixed a bug where `podman machine` commands would not properly locate the `gvproxy` binary in some circumstances. +- Fixed a bug where containers created as part of a pod using the `--pod-id-file` option would not join the pod's network namespace ([#11303](https://github.com/containers/podman/issues/11303)). +- Fixed a bug where Podman, when using the systemd cgroups driver, could sometimes leak dbus sessions. +- Fixed a bug where the `until` filter to `podman logs` and `podman events` was improperly handled, requiring input to be negated ([#11158](https://github.com/containers/podman/issues/11158)). +- Fixed a bug where rootless containers using CNI networking run on systems using `systemd-resolved` for DNS would fail to start if resolved symlinked `/etc/resolv.conf` to an absolute path ([#11358](https://github.com/containers/podman/issues/11358)). + +### API +- A large number of potential file descriptor leaks from improperly closing client connections have been fixed. + ## 3.3.0 ### Features - Containers inside VMs created by `podman machine` will now automatically handle port forwarding - containers in `podman machine` VMs that publish ports via `--publish` or `--publish-all` will have these ports not just forwarded on the VM, but also on the host system. 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/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/docs/source/markdown/podman-network-create.1.md b/docs/source/markdown/podman-network-create.1.md index d110c4ceb..04290c188 100644 --- a/docs/source/markdown/podman-network-create.1.md +++ b/docs/source/markdown/podman-network-create.1.md @@ -25,7 +25,8 @@ resolution. #### **--driver**, **-d** -Driver to manage the network (default "bridge"). Currently only `bridge` is supported. +Driver to manage the network. Currently `bridge` and `macvlan` is supported. Defaults to `bridge`. +As rootless the `macvlan` driver has no access to the host network interfaces because rootless networking requires a separate network namespace. #### **--opt**=*option*, **-o** @@ -54,13 +55,6 @@ must be used with a *subnet* option. Set metadata for a network (e.g., --label mykey=value). -#### **--macvlan** - -*This option is being deprecated* - -Create a *Macvlan* based connection rather than a classic bridge. You must pass an interface name from the host for the -Macvlan connection. - #### **--subnet** The subnet in CIDR notation. diff --git a/docs/tutorials/podman_tutorial.md b/docs/tutorials/podman_tutorial.md index 7419f445e..92d0c41b1 100644 --- a/docs/tutorials/podman_tutorial.md +++ b/docs/tutorials/podman_tutorial.md @@ -50,11 +50,11 @@ Note: The -l is a convenience argument for **latest container**. You can also u of -l. ### Testing the httpd server -Now that we have the IP address of the container, we can test the network communication between the host +As we do not have the IP address of the container, we can test the network communication between the host operating system and the container using curl. The following command should display the index page of our containerized httpd server. ```console -curl http://<IP_address>:8080 +curl http://localhost:8080 ``` ### Viewing the container's logs diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 847122929..cafa3c642 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -1,3 +1,4 @@ +//go:build linux // +build linux package libpod @@ -1942,9 +1943,24 @@ func (c *Container) generateHosts(path string) (string, error) { } hosts := string(orig) hosts += c.getHosts() + + hosts = c.appendLocalhost(hosts) + return c.writeStringToRundir("hosts", hosts) } +// based on networking mode we may want to append the localhost +// if there isn't any record for it and also this shoud happen +// in slirp4netns and similar network modes. +func (c *Container) appendLocalhost(hosts string) string { + if !strings.Contains(hosts, "localhost") && + !c.config.NetMode.IsHost() { + hosts += "127.0.0.1\tlocalhost\n::1\tlocalhost\n" + } + + return hosts +} + // appendHosts appends a container's config and state pertaining to hosts to a container's // local hosts file. netCtr is the container from which the netNS information is // taken. diff --git a/libpod/container_internal_linux_test.go b/libpod/container_internal_linux_test.go index 1465ffbea..899f9bffd 100644 --- a/libpod/container_internal_linux_test.go +++ b/libpod/container_internal_linux_test.go @@ -1,3 +1,4 @@ +//go:build linux // +build linux package libpod @@ -7,6 +8,7 @@ import ( "os" "testing" + "github.com/containers/podman/v3/pkg/namespaces" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/stretchr/testify/assert" ) @@ -68,3 +70,30 @@ func TestGenerateUserGroupEntry(t *testing.T) { } assert.Equal(t, group, "567:x:567:567\n") } + +func TestAppendLocalhost(t *testing.T) { + { + c := Container{ + config: &ContainerConfig{ + ContainerNetworkConfig: ContainerNetworkConfig{ + NetMode: namespaces.NetworkMode("slirp4netns"), + }, + }, + } + + assert.Equal(t, "127.0.0.1\tlocalhost\n::1\tlocalhost\n", c.appendLocalhost("")) + assert.Equal(t, "127.0.0.1\tlocalhost", c.appendLocalhost("127.0.0.1\tlocalhost")) + } + { + c := Container{ + config: &ContainerConfig{ + ContainerNetworkConfig: ContainerNetworkConfig{ + NetMode: namespaces.NetworkMode("host"), + }, + }, + } + + assert.Equal(t, "", c.appendLocalhost("")) + assert.Equal(t, "127.0.0.1\tlocalhost", c.appendLocalhost("127.0.0.1\tlocalhost")) + } +} diff --git a/libpod/container_log.go b/libpod/container_log.go index 3988bb654..89dd5e8b0 100644 --- a/libpod/container_log.go +++ b/libpod/container_log.go @@ -107,16 +107,18 @@ func (c *Container) readFromLogFile(ctx context.Context, options *logs.LogOption // until EOF. state, err := c.State() if err != nil || state != define.ContainerStateRunning { - // Make sure to wait at least for the poll duration - // before stopping the file logger (see #10675). - time.Sleep(watch.POLL_DURATION) - tailError := t.StopAtEOF() - if tailError != nil && fmt.Sprintf("%v", tailError) != "tail: stop at eof" { - logrus.Errorf("Error stopping logger: %v", tailError) - } if err != nil && errors.Cause(err) != define.ErrNoSuchCtr { logrus.Errorf("Error getting container state: %v", err) } + go func() { + // Make sure to wait at least for the poll duration + // before stopping the file logger (see #10675). + time.Sleep(watch.POLL_DURATION) + tailError := t.StopAtEOF() + if tailError != nil && tailError.Error() != "tail: stop at eof" { + logrus.Errorf("Error stopping logger: %v", tailError) + } + }() return nil } 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/cgroups/cgroups.go b/pkg/cgroups/cgroups.go index 9cb32a364..4bb8de69b 100644 --- a/pkg/cgroups/cgroups.go +++ b/pkg/cgroups/cgroups.go @@ -231,7 +231,10 @@ func getCgroupPathForCurrentProcess() (string, error) { for s.Scan() { text := s.Text() procEntries := strings.SplitN(text, "::", 2) - cgroupPath = procEntries[1] + // set process cgroupPath only if entry is valid + if len(procEntries) > 1 { + cgroupPath = procEntries[1] + } } if err := s.Err(); err != nil { return cgroupPath, err 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/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/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/libvirt/config.go b/pkg/machine/libvirt/config.go deleted file mode 100644 index 1ce5ab154..000000000 --- a/pkg/machine/libvirt/config.go +++ /dev/null @@ -1,6 +0,0 @@ -// +build amd64,linux arm64,linux amd64,darwin arm64,darwin - -package libvirt - -type MachineVM struct { -} diff --git a/pkg/machine/libvirt/machine.go b/pkg/machine/libvirt/machine.go deleted file mode 100644 index e1aa1569b..000000000 --- a/pkg/machine/libvirt/machine.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build amd64,linux arm64,linux amd64,darwin arm64,darwin - -package libvirt - -import "github.com/containers/podman/v3/pkg/machine" - -func (v *MachineVM) Init(name string, opts machine.InitOptions) error { - return nil -} - -func (v *MachineVM) Start(name string) error { - return nil -} - -func (v *MachineVM) Stop(name string) error { - return nil -} diff --git a/pkg/machine/libvirt/machine_unsupported.go b/pkg/machine/libvirt/machine_unsupported.go deleted file mode 100644 index 8b54440fe..000000000 --- a/pkg/machine/libvirt/machine_unsupported.go +++ /dev/null @@ -1,3 +0,0 @@ -// +build !amd64 amd64,windows - -package libvirt 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 38a16c3ef..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 @@ -278,6 +278,9 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error { time.Sleep(wait) wait++ } + if err != nil { + return err + } fd, err := qemuSocketConn.(*net.UnixConn).File() if err != nil { diff --git a/pkg/machine/qemu/options_darwin_amd64.go b/pkg/machine/qemu/options_darwin_amd64.go index ee1036291..ff8d10db1 100644 --- a/pkg/machine/qemu/options_darwin_amd64.go +++ b/pkg/machine/qemu/options_darwin_amd64.go @@ -5,7 +5,7 @@ var ( ) func (v *MachineVM) addArchOptions() []string { - opts := []string{"-machine", "q35,accel=hvf:tcg"} + opts := []string{"-machine", "q35,accel=hvf:tcg", "-cpu", "host"} return opts } diff --git a/pkg/machine/qemu/options_darwin_arm64.go b/pkg/machine/qemu/options_darwin_arm64.go index 7513b3048..8c651584e 100644 --- a/pkg/machine/qemu/options_darwin_arm64.go +++ b/pkg/machine/qemu/options_darwin_arm64.go @@ -13,6 +13,7 @@ func (v *MachineVM) addArchOptions() []string { ovmfDir := getOvmfDir(v.ImagePath, v.Name) opts := []string{ "-accel", "hvf", + "-accel", "tcg", "-cpu", "cortex-a57", "-M", "virt,highmem=off", "-drive", "file=/usr/local/share/qemu/edk2-aarch64-code.fd,if=pflash,format=raw,readonly=on", 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/system/035-logs.bats b/test/system/035-logs.bats index 32282c8e1..a04d2ac74 100644 --- a/test/system/035-logs.bats +++ b/test/system/035-logs.bats @@ -174,4 +174,31 @@ $s_after" _log_test_until journald } +function _log_test_follow() { + local driver=$1 + cname=$(random_string) + contentA=$(random_string) + contentB=$(random_string) + contentC=$(random_string) + + # Note: it seems we need at least three log lines to hit #11461. + run_podman run --log-driver=$driver --name $cname $IMAGE sh -c "echo $contentA; echo $contentB; echo $contentC" + run_podman logs -f $cname + is "$output" "$contentA +$contentB +$contentC" "logs -f on exitted container works" + + run_podman rm -f $cname +} + +@test "podman logs - --follow k8s-file" { + _log_test_follow k8s-file +} + +@test "podman logs - --follow journald" { + # We can't use journald on RHEL as rootless: rhbz#1895105 + skip_if_journald_unavailable + + _log_test_follow journald +} # vim: filetype=sh 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" } diff --git a/test/system/255-auto-update.bats b/test/system/255-auto-update.bats index b172bb917..bb4b5c13f 100644 --- a/test/system/255-auto-update.bats +++ b/test/system/255-auto-update.bats @@ -339,6 +339,8 @@ EOF } @test "podman auto-update using systemd" { + skip_if_journald_unavailable + generate_service alpine image cat >$UNIT_DIR/podman-auto-update-$cname.timer <<EOF @@ -386,7 +388,9 @@ EOF done if [[ -n "$failed_start" ]]; then - die "Did not find expected string '$expect' in journalctl output for $cname" + echo "journalctl output:" + sed -e 's/^/ /' <<<"$output" + die "Did not find expected string '$expect' in journalctl output for $cname" fi _confirm_update $cname $ori_image |