Fix handling of systemd.

Systemd enablement has to happen on the server side, since we need
check if the image is running systemd.

Also need to make sure user setting the StopSignal is not overriden on the
server side. But if not set and using systemd, we set it correctly.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh 2020-06-05 10:44:16 -04:00
parent c448c03269
commit c8f57b71a4
No known key found for this signature in database
GPG Key ID: A2DF901DABE2C028
6 changed files with 46 additions and 40 deletions

View File

@ -424,7 +424,7 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet {
"Sysctl options", "Sysctl options",
) )
createFlags.StringVar( createFlags.StringVar(
&cf.SystemdD, &cf.Systemd,
"systemd", "true", "systemd", "true",
`Run container in systemd mode ("true"|"false"|"always")`, `Run container in systemd mode ("true"|"false"|"always")`,
) )

View File

@ -85,7 +85,7 @@ type ContainerCLIOpts struct {
SubUIDName string SubUIDName string
SubGIDName string SubGIDName string
Sysctl []string Sysctl []string
SystemdD string Systemd string
TmpFS []string TmpFS []string
TTY bool TTY bool
UIDMap []string UIDMap []string

View File

@ -3,7 +3,6 @@ package common
import ( import (
"fmt" "fmt"
"os" "os"
"path/filepath"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -285,16 +284,13 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
s.NetNS = c.Net.Network s.NetNS = c.Net.Network
} }
// STOP SIGNAL
signalString := "TERM"
if sig := c.StopSignal; len(sig) > 0 { if sig := c.StopSignal; len(sig) > 0 {
signalString = sig stopSignal, err := util.ParseSignal(sig)
if err != nil {
return err
}
s.StopSignal = &stopSignal
} }
stopSignal, err := util.ParseSignal(signalString)
if err != nil {
return err
}
s.StopSignal = &stopSignal
// ENVIRONMENT VARIABLES // ENVIRONMENT VARIABLES
// //
@ -439,25 +435,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
s.ImageVolumeMode = "anonymous" s.ImageVolumeMode = "anonymous"
} }
systemd := c.SystemdD == "always" s.Systemd = c.Systemd
if !systemd && command != nil {
x, err := strconv.ParseBool(c.SystemdD)
if err != nil {
return errors.Wrapf(err, "cannot parse bool %s", c.SystemdD)
}
if x && (command[0] == "/usr/sbin/init" || command[0] == "/sbin/init" || (filepath.Base(command[0]) == "systemd")) {
systemd = true
}
}
if systemd {
if s.StopSignal == nil {
stopSignal, err = util.ParseSignal("RTMIN+3")
if err != nil {
return errors.Wrapf(err, "error parsing systemd signal")
}
s.StopSignal = &stopSignal
}
}
if s.ResourceLimits == nil { if s.ResourceLimits == nil {
s.ResourceLimits = &specs.LinuxResources{} s.ResourceLimits = &specs.LinuxResources{}
} }

View File

@ -38,7 +38,7 @@ func (s *SpecGenerator) Validate() error {
} }
// systemd values must be true, false, or always // systemd values must be true, false, or always
if len(s.ContainerBasicConfig.Systemd) > 0 && !util.StringInSlice(strings.ToLower(s.ContainerBasicConfig.Systemd), SystemDValues) { if len(s.ContainerBasicConfig.Systemd) > 0 && !util.StringInSlice(strings.ToLower(s.ContainerBasicConfig.Systemd), SystemDValues) {
return errors.Wrapf(ErrInvalidSpecConfig, "SystemD values must be one of %s", strings.Join(SystemDValues, ",")) return errors.Wrapf(ErrInvalidSpecConfig, "--systemd values must be one of %q", strings.Join(SystemDValues, ", "))
} }
// //

View File

@ -3,12 +3,14 @@ package generate
import ( import (
"context" "context"
"os" "os"
"path/filepath"
"github.com/containers/common/pkg/config" "github.com/containers/common/pkg/config"
"github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/libpod/image" "github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/specgen" "github.com/containers/libpod/pkg/specgen"
"github.com/containers/libpod/pkg/util"
"github.com/containers/storage" "github.com/containers/storage"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -128,7 +130,41 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
if s.Stdin { if s.Stdin {
options = append(options, libpod.WithStdin()) options = append(options, libpod.WithStdin())
} }
if len(s.Systemd) > 0 {
useSystemd := false
switch s.Systemd {
case "always":
useSystemd = true
case "false":
break
case "", "true":
command := s.Command
if len(command) == 0 {
command, err = img.Cmd(ctx)
if err != nil {
return nil, err
}
}
if len(command) > 0 {
if command[0] == "/usr/sbin/init" || command[0] == "/sbin/init" || (filepath.Base(command[0]) == "systemd") {
useSystemd = true
}
}
default:
return nil, errors.Wrapf(err, "invalid value %q systemd option requires 'true, false, always'", s.Systemd)
}
if useSystemd {
// is StopSignal was not set by the user then set it to systemd
// expected StopSigal
if s.StopSignal == nil {
stopSignal, err := util.ParseSignal("RTMIN+3")
if err != nil {
return nil, errors.Wrapf(err, "error parsing systemd signal")
}
s.StopSignal = &stopSignal
}
options = append(options, libpod.WithSystemd()) options = append(options, libpod.WithSystemd())
} }
if len(s.Name) > 0 { if len(s.Name) > 0 {

View File

@ -8,7 +8,6 @@ import (
"strings" "strings"
"time" "time"
"github.com/containers/libpod/pkg/cgroups"
. "github.com/containers/libpod/test/utils" . "github.com/containers/libpod/test/utils"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
@ -82,13 +81,6 @@ WantedBy=multi-user.target
}) })
It("podman run container with systemd PID1", func() { It("podman run container with systemd PID1", func() {
cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
Expect(err).To(BeNil())
if cgroupsv2 {
// TODO: Find a way to enable this for v2
Skip("systemd test does not work in cgroups V2 mode yet")
}
systemdImage := "fedora" systemdImage := "fedora"
pull := podmanTest.Podman([]string{"pull", systemdImage}) pull := podmanTest.Podman([]string{"pull", systemdImage})
pull.WaitWithDefaultTimeout() pull.WaitWithDefaultTimeout()