diff options
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container.go | 3 | ||||
-rw-r--r-- | libpod/container_easyjson.go | 12 | ||||
-rw-r--r-- | libpod/container_internal_linux.go | 41 | ||||
-rw-r--r-- | libpod/options.go | 12 |
4 files changed, 68 insertions, 0 deletions
diff --git a/libpod/container.go b/libpod/container.go index 4e17b1102..62db87fa0 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -346,6 +346,9 @@ type ContainerConfig struct { // IsInfra is a bool indicating whether this container is an infra container used for // sharing kernel namespaces in a pod IsInfra bool `json:"pause"` + + // Systemd tells libpod to setup the container in systemd mode + Systemd bool `json:"systemd"` } // ContainerStatus returns a string representation for users diff --git a/libpod/container_easyjson.go b/libpod/container_easyjson.go index f78366065..53ad5b7ee 100644 --- a/libpod/container_easyjson.go +++ b/libpod/container_easyjson.go @@ -1682,6 +1682,8 @@ func easyjson1dbef17bDecodeGithubComContainersLibpodLibpod2(in *jlexer.Lexer, ou } case "pause": out.IsInfra = bool(in.Bool()) + case "systemd": + out.Systemd = bool(in.Bool()) default: in.SkipRecursive() } @@ -2344,6 +2346,16 @@ func easyjson1dbef17bEncodeGithubComContainersLibpodLibpod2(out *jwriter.Writer, } out.Bool(bool(in.IsInfra)) } + { + const prefix string = ",\"systemd\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.Systemd)) + } out.RawByte('}') } diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 0353124dd..05604246f 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -188,6 +188,10 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { } } + if c.config.Systemd { + c.setupSystemd(g.Mounts(), g) + } + // Look up and add groups the user belongs to, if a group wasn't directly specified if !rootless.IsRootless() && !strings.Contains(c.config.User, ":") { groups, err := chrootuser.GetAdditionalGroupsForUser(c.state.Mountpoint, uint64(g.Config.Process.User.UID)) @@ -294,6 +298,43 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { return g.Config, nil } +// 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 (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) { + options := []string{"rw", "rprivate", "noexec", "nosuid", "nodev"} + for _, dest := range []string{"/run", "/run/lock"} { + if 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 MountExists(mounts, dest) { + continue + } + tmpfsMnt := spec.Mount{ + Destination: dest, + Type: "tmpfs", + Source: "tmpfs", + Options: append(options, "tmpcopyup"), + } + g.AddMount(tmpfsMnt) + } + systemdMnt := spec.Mount{ + Destination: "/sys/fs/cgroup/systemd", + Type: "bind", + Source: fmt.Sprintf("/sys/fs/cgroup/systemd%s/libpod-%s", CgroupfsDefaultCgroupParent, c.ID()), + Options: []string{"bind", "private"}, + } + g.AddMount(systemdMnt) +} + // Add an existing container's namespace to the spec func (c *Container) addNamespaceContainer(g *generate.Generator, ns LinuxNS, ctr string, specNS string) error { nsCtr, err := c.runtime.state.Container(ctr) diff --git a/libpod/options.go b/libpod/options.go index 9f966cead..228b38ba5 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -349,6 +349,18 @@ func WithShmDir(dir string) CtrCreateOption { } } +// WithSystemd turns on systemd mode in the container +func WithSystemd() CtrCreateOption { + return func(ctr *Container) error { + if ctr.valid { + return ErrCtrFinalized + } + + ctr.config.Systemd = true + return nil + } +} + // WithShmSize sets the size of /dev/shm tmpfs mount. func WithShmSize(size int64) CtrCreateOption { return func(ctr *Container) error { |