summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel J Walsh <dwalsh@redhat.com>2018-10-15 15:42:12 -0400
committerDaniel J Walsh <dwalsh@redhat.com>2018-10-15 16:19:11 -0400
commit57a8c2e5e844ee403c9a703c621780de7c7343f0 (patch)
tree20a2acfd315cdfcc1f472c18508cd53b1dfedc47
parent2bc9a3c4bbaade50264b1dbf348d1521cdd8d8b5 (diff)
downloadpodman-57a8c2e5e844ee403c9a703c621780de7c7343f0.tar.gz
podman-57a8c2e5e844ee403c9a703c621780de7c7343f0.tar.bz2
podman-57a8c2e5e844ee403c9a703c621780de7c7343f0.zip
Mount proper cgroup for systemd to manage inside of the container.
We are still requiring oci-systemd-hook to be installed in order to run systemd within a container. This patch properly mounts /sys/fs/cgroup/systemd/libpod_parent/libpod-UUID on /sys/fs/cgroup/systemd inside of container. Since we need the UUID of the container, we needed to move Systemd to be a config option of the container. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
-rw-r--r--libpod/container.go3
-rw-r--r--libpod/container_easyjson.go12
-rw-r--r--libpod/container_internal_linux.go41
-rw-r--r--libpod/options.go12
-rw-r--r--pkg/spec/createconfig.go4
-rw-r--r--pkg/spec/spec.go50
6 files changed, 72 insertions, 50 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 {
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index d34b21189..6ac9d82da 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -319,6 +319,10 @@ func (c *CreateConfig) GetContainerCreateOptions(runtime *libpod.Runtime) ([]lib
if c.Interactive {
options = append(options, libpod.WithStdin())
}
+ if c.Systemd && (strings.HasSuffix(c.Command[0], "init") ||
+ strings.HasSuffix(c.Command[0], "systemd")) {
+ options = append(options, libpod.WithSystemd())
+ }
if c.Name != "" {
logrus.Debugf("appending name %s", c.Name)
options = append(options, libpod.WithName(c.Name))
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index 4c855d659..b1cca2c9e 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -5,7 +5,6 @@ import (
"path"
"strings"
- "github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/rootless"
"github.com/docker/docker/daemon/caps"
"github.com/docker/docker/pkg/mount"
@@ -261,12 +260,6 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
addedResources = true
}
- 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 {
// Default options if nothing passed
options := []string{"rw", "rprivate", "noexec", "nosuid", "nodev", "size=65536k"}
@@ -408,49 +401,6 @@ 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", "rprivate", "noexec", "nosuid", "nodev"}
- for _, dest := range []string{"/run", "/run/lock"} {
- 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)
- }
- tmpfsMnt := spec.Mount{
- Destination: "/sys/fs/cgroup/systemd",
- Type: "tmpfs",
- Source: "tmpfs",
- Options: append(options, "size=65536k"),
- }
- g.AddMount(tmpfsMnt)
- return nil
-}
-
func addPidNS(config *CreateConfig, g *generate.Generator) error {
pidMode := config.PidMode
if IsNS(string(pidMode)) {