mirror of
https://github.com/containers/podman.git
synced 2025-10-25 18:25:59 +08:00
Add proper support for systemd inside of podman
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
@ -383,6 +383,10 @@ var createFlags = []cli.Flag{
|
|||||||
Name: "sysctl",
|
Name: "sysctl",
|
||||||
Usage: "Sysctl options (default [])",
|
Usage: "Sysctl options (default [])",
|
||||||
},
|
},
|
||||||
|
cli.BoolTFlag{
|
||||||
|
Name: "systemd",
|
||||||
|
Usage: "Run container in systemd mode if the command executable is systemd or init",
|
||||||
|
},
|
||||||
cli.StringSliceFlag{
|
cli.StringSliceFlag{
|
||||||
Name: "tmpfs",
|
Name: "tmpfs",
|
||||||
Usage: "Mount a temporary filesystem (`tmpfs`) into a container (default [])",
|
Usage: "Mount a temporary filesystem (`tmpfs`) into a container (default [])",
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -509,7 +510,7 @@ func parseCreateOpts(ctx context.Context, c *cli.Context, runtime *libpod.Runtim
|
|||||||
|
|
||||||
// STOP SIGNAL
|
// STOP SIGNAL
|
||||||
stopSignal := syscall.SIGTERM
|
stopSignal := syscall.SIGTERM
|
||||||
signalString := "SIGTERM"
|
signalString := ""
|
||||||
if data != nil {
|
if data != nil {
|
||||||
signalString = data.ContainerConfig.StopSignal
|
signalString = data.ContainerConfig.StopSignal
|
||||||
}
|
}
|
||||||
@ -648,6 +649,17 @@ func parseCreateOpts(ctx context.Context, c *cli.Context, runtime *libpod.Runtim
|
|||||||
return nil, errors.Errorf("invalid image-volume type %q. Pick one of bind, tmpfs, or ignore", c.String("image-volume"))
|
return nil, errors.Errorf("invalid image-volume type %q. Pick one of bind, tmpfs, or ignore", c.String("image-volume"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var systemd bool
|
||||||
|
if c.BoolT("systemd") && ((filepath.Base(command[0]) == "init") || (filepath.Base(command[0]) == "systemd")) {
|
||||||
|
systemd = true
|
||||||
|
if signalString == "" {
|
||||||
|
stopSignal, err = signal.ParseSignal("RTMIN+3")
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error parsing systemd signal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
config := &cc.CreateConfig{
|
config := &cc.CreateConfig{
|
||||||
Runtime: runtime,
|
Runtime: runtime,
|
||||||
Annotations: annotations,
|
Annotations: annotations,
|
||||||
@ -726,6 +738,7 @@ func parseCreateOpts(ctx context.Context, c *cli.Context, runtime *libpod.Runtim
|
|||||||
StopSignal: stopSignal,
|
StopSignal: stopSignal,
|
||||||
StopTimeout: c.Uint("stop-timeout"),
|
StopTimeout: c.Uint("stop-timeout"),
|
||||||
Sysctl: sysctl,
|
Sysctl: sysctl,
|
||||||
|
Systemd: systemd,
|
||||||
Tmpfs: c.StringSlice("tmpfs"),
|
Tmpfs: c.StringSlice("tmpfs"),
|
||||||
Tty: tty,
|
Tty: tty,
|
||||||
User: user,
|
User: user,
|
||||||
|
|||||||
@ -1494,6 +1494,7 @@ _podman_container_run() {
|
|||||||
--subgidname
|
--subgidname
|
||||||
--subuidname
|
--subuidname
|
||||||
--sysctl
|
--sysctl
|
||||||
|
--systemd
|
||||||
--uidmap
|
--uidmap
|
||||||
--ulimit
|
--ulimit
|
||||||
--user -u
|
--user -u
|
||||||
|
|||||||
@ -544,6 +544,19 @@ Network Namespace - current sysctls allowed:
|
|||||||
|
|
||||||
Note: if you use the --network=host option these sysctls will not be allowed.
|
Note: if you use the --network=host option these sysctls will not be allowed.
|
||||||
|
|
||||||
|
**--systemd**=*true*|*false*
|
||||||
|
|
||||||
|
Run container in systemd mode. The default is *true*.
|
||||||
|
|
||||||
|
If the command you running inside of the container is systemd or init, podman
|
||||||
|
will setup tmpfs mount points in the following directories:
|
||||||
|
|
||||||
|
/run, /run/lock, /tmp, /sys/fs/cgroup/systemd, /var/lib/journal
|
||||||
|
|
||||||
|
It will also set the default stop signal to SIGRTMIN+3.
|
||||||
|
|
||||||
|
This allow systemd to run in a confined container without any modifications.
|
||||||
|
|
||||||
**--tmpfs**=[] Create a tmpfs mount
|
**--tmpfs**=[] Create a tmpfs mount
|
||||||
|
|
||||||
Mount a temporary filesystem (`tmpfs`) mount into a container, for example:
|
Mount a temporary filesystem (`tmpfs`) mount into a container, for example:
|
||||||
|
|||||||
@ -578,6 +578,19 @@ Network Namespace - current sysctls allowed:
|
|||||||
|
|
||||||
Note: if you use the `--network=host` option these sysctls will not be allowed.
|
Note: if you use the `--network=host` option these sysctls will not be allowed.
|
||||||
|
|
||||||
|
**--systemd**=*true*|*false*
|
||||||
|
|
||||||
|
Run container in systemd mode. The default is *true*.
|
||||||
|
|
||||||
|
If the command you running inside of the container is systemd or init, podman
|
||||||
|
will setup tmpfs mount points in the following directories:
|
||||||
|
|
||||||
|
/run, /run/lock, /tmp, /sys/fs/cgroup/systemd, /var/lib/journal
|
||||||
|
|
||||||
|
It will also set the default stop signal to SIGRTMIN+3.
|
||||||
|
|
||||||
|
This allow systemd to run in a confined container without any modifications.
|
||||||
|
|
||||||
**--tmpfs**=[] Create a tmpfs mount
|
**--tmpfs**=[] Create a tmpfs mount
|
||||||
|
|
||||||
Mount a temporary filesystem (`tmpfs`) mount into a container, for example:
|
Mount a temporary filesystem (`tmpfs`) mount into a container, for example:
|
||||||
|
|||||||
@ -115,9 +115,10 @@ type CreateConfig struct {
|
|||||||
Resources CreateResourceConfig
|
Resources CreateResourceConfig
|
||||||
Rm bool //rm
|
Rm bool //rm
|
||||||
ShmDir string
|
ShmDir string
|
||||||
StopSignal syscall.Signal // stop-signal
|
StopSignal syscall.Signal // stop-signal
|
||||||
StopTimeout uint // stop-timeout
|
StopTimeout uint // stop-timeout
|
||||||
Sysctl map[string]string //sysctl
|
Sysctl map[string]string //sysctl
|
||||||
|
Systemd bool
|
||||||
Tmpfs []string // tmpfs
|
Tmpfs []string // tmpfs
|
||||||
Tty bool //tty
|
Tty bool //tty
|
||||||
UsernsMode container.UsernsMode //userns
|
UsernsMode container.UsernsMode //userns
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/containers/libpod/libpod"
|
||||||
"github.com/containers/libpod/pkg/rootless"
|
"github.com/containers/libpod/pkg/rootless"
|
||||||
"github.com/docker/docker/daemon/caps"
|
"github.com/docker/docker/daemon/caps"
|
||||||
"github.com/docker/docker/pkg/mount"
|
"github.com/docker/docker/pkg/mount"
|
||||||
@ -221,6 +222,12 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.Systemd && (strings.HasSuffix(config.Command[0], "init") ||
|
||||||
|
strings.HasSuffix(config.Command[0], "systemd")) {
|
||||||
|
if err := setupSystemd(config, &g); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to setup systemd")
|
||||||
|
}
|
||||||
|
}
|
||||||
for _, i := range config.Tmpfs {
|
for _, i := range config.Tmpfs {
|
||||||
// Default options if nothing passed
|
// Default options if nothing passed
|
||||||
options := []string{"rw", "private", "noexec", "nosuid", "nodev", "size=65536k"}
|
options := []string{"rw", "private", "noexec", "nosuid", "nodev", "size=65536k"}
|
||||||
@ -353,6 +360,42 @@ func blockAccessToKernelFilesystems(config *CreateConfig, g *generate.Generator)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// systemd expects to have /run, /run/lock and /tmp on tmpfs
|
||||||
|
// It also expects to be able to write to /sys/fs/cgroup/systemd and /var/log/journal
|
||||||
|
|
||||||
|
func setupSystemd(config *CreateConfig, g *generate.Generator) error {
|
||||||
|
mounts, err := config.GetVolumeMounts([]spec.Mount{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
options := []string{"rw", "private", "noexec", "nosuid", "nodev"}
|
||||||
|
for _, dest := range []string{"/run", "/run/lock", "/sys/fs/cgroup/systemd"} {
|
||||||
|
if libpod.MountExists(mounts, dest) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tmpfsMnt := spec.Mount{
|
||||||
|
Destination: dest,
|
||||||
|
Type: "tmpfs",
|
||||||
|
Source: "tmpfs",
|
||||||
|
Options: append(options, "tmpcopyup", "size=65536k"),
|
||||||
|
}
|
||||||
|
g.AddMount(tmpfsMnt)
|
||||||
|
}
|
||||||
|
for _, dest := range []string{"/tmp", "/var/log/journal"} {
|
||||||
|
if libpod.MountExists(mounts, dest) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tmpfsMnt := spec.Mount{
|
||||||
|
Destination: dest,
|
||||||
|
Type: "tmpfs",
|
||||||
|
Source: "tmpfs",
|
||||||
|
Options: append(options, "tmpcopyup"),
|
||||||
|
}
|
||||||
|
g.AddMount(tmpfsMnt)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func addPidNS(config *CreateConfig, g *generate.Generator) error {
|
func addPidNS(config *CreateConfig, g *generate.Generator) error {
|
||||||
pidMode := config.PidMode
|
pidMode := config.PidMode
|
||||||
if IsNS(string(pidMode)) {
|
if IsNS(string(pidMode)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user