From 7f8964a78f90aca610dfca5b962b6839acbd745e Mon Sep 17 00:00:00 2001 From: Doug Rabson Date: Sun, 2 Oct 2022 14:24:31 +0100 Subject: [PATCH] libpod: Factor out cgroup validation from (*Runtime).NewPod This moves the code to runtime_pod_linux.go since cgroups are platform-specific. [NO NEW TESTS NEEDED] Signed-off-by: Doug Rabson --- libpod/runtime_pod_common.go | 74 +---------------------------- libpod/runtime_pod_linux.go | 90 ++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 72 deletions(-) create mode 100644 libpod/runtime_pod_linux.go diff --git a/libpod/runtime_pod_common.go b/libpod/runtime_pod_common.go index 24e9f3da71..b108d00906 100644 --- a/libpod/runtime_pod_common.go +++ b/libpod/runtime_pod_common.go @@ -7,15 +7,12 @@ import ( "context" "errors" "fmt" - "path" "path/filepath" - "strings" "github.com/containers/common/pkg/cgroups" "github.com/containers/common/pkg/config" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/events" - "github.com/containers/podman/v4/pkg/rootless" "github.com/containers/podman/v4/pkg/specgen" "github.com/hashicorp/go-multierror" "github.com/sirupsen/logrus" @@ -59,75 +56,8 @@ func (r *Runtime) NewPod(ctx context.Context, p specgen.PodSpecGenerator, option pod.valid = true - // Check Cgroup parent sanity, and set it if it was not set - if r.config.Cgroups() != "disabled" { - switch r.config.Engine.CgroupManager { - case config.CgroupfsCgroupsManager: - canUseCgroup := !rootless.IsRootless() || isRootlessCgroupSet(pod.config.CgroupParent) - if canUseCgroup { - // need to actually create parent here - if pod.config.CgroupParent == "" { - pod.config.CgroupParent = CgroupfsDefaultCgroupParent - } else if strings.HasSuffix(path.Base(pod.config.CgroupParent), ".slice") { - return nil, fmt.Errorf("systemd slice received as cgroup parent when using cgroupfs: %w", define.ErrInvalidArg) - } - // If we are set to use pod cgroups, set the cgroup parent that - // all containers in the pod will share - if pod.config.UsePodCgroup { - pod.state.CgroupPath = filepath.Join(pod.config.CgroupParent, pod.ID()) - if p.InfraContainerSpec != nil { - p.InfraContainerSpec.CgroupParent = pod.state.CgroupPath - // cgroupfs + rootless = permission denied when creating the cgroup. - if !rootless.IsRootless() { - res, err := GetLimits(p.ResourceLimits) - if err != nil { - return nil, err - } - // Need to both create and update the cgroup - // rather than create a new path in c/common for pod cgroup creation - // just create as if it is a ctr and then update figures out that we need to - // populate the resource limits on the pod level - cgc, err := cgroups.New(pod.state.CgroupPath, &res) - if err != nil { - return nil, err - } - err = cgc.Update(&res) - if err != nil { - return nil, err - } - } - } - } - } - case config.SystemdCgroupsManager: - if pod.config.CgroupParent == "" { - if rootless.IsRootless() { - pod.config.CgroupParent = SystemdDefaultRootlessCgroupParent - } else { - pod.config.CgroupParent = SystemdDefaultCgroupParent - } - } else if len(pod.config.CgroupParent) < 6 || !strings.HasSuffix(path.Base(pod.config.CgroupParent), ".slice") { - return nil, fmt.Errorf("did not receive systemd slice as cgroup parent when using systemd to manage cgroups: %w", define.ErrInvalidArg) - } - // If we are set to use pod cgroups, set the cgroup parent that - // all containers in the pod will share - if pod.config.UsePodCgroup { - cgroupPath, err := systemdSliceFromPath(pod.config.CgroupParent, fmt.Sprintf("libpod_pod_%s", pod.ID()), p.ResourceLimits) - if err != nil { - return nil, fmt.Errorf("unable to create pod cgroup for pod %s: %w", pod.ID(), err) - } - pod.state.CgroupPath = cgroupPath - if p.InfraContainerSpec != nil { - p.InfraContainerSpec.CgroupParent = pod.state.CgroupPath - } - } - default: - return nil, fmt.Errorf("unsupported Cgroup manager: %s - cannot validate cgroup parent: %w", r.config.Engine.CgroupManager, define.ErrInvalidArg) - } - } - - if pod.config.UsePodCgroup { - logrus.Debugf("Got pod cgroup as %s", pod.state.CgroupPath) + if err := r.platformMakePod(pod, p); err != nil { + return nil, err } if !pod.HasInfraContainer() && pod.SharesNamespaces() { diff --git a/libpod/runtime_pod_linux.go b/libpod/runtime_pod_linux.go new file mode 100644 index 0000000000..830d9e4ef4 --- /dev/null +++ b/libpod/runtime_pod_linux.go @@ -0,0 +1,90 @@ +package libpod + +import ( + "fmt" + "path" + "path/filepath" + "strings" + + "github.com/containers/common/pkg/cgroups" + "github.com/containers/common/pkg/config" + "github.com/containers/podman/v4/libpod/define" + "github.com/containers/podman/v4/pkg/rootless" + "github.com/containers/podman/v4/pkg/specgen" + "github.com/sirupsen/logrus" +) + +func (r *Runtime) platformMakePod(pod *Pod, p specgen.PodSpecGenerator) error { + // Check Cgroup parent sanity, and set it if it was not set + if r.config.Cgroups() != "disabled" { + switch r.config.Engine.CgroupManager { + case config.CgroupfsCgroupsManager: + canUseCgroup := !rootless.IsRootless() || isRootlessCgroupSet(pod.config.CgroupParent) + if canUseCgroup { + // need to actually create parent here + if pod.config.CgroupParent == "" { + pod.config.CgroupParent = CgroupfsDefaultCgroupParent + } else if strings.HasSuffix(path.Base(pod.config.CgroupParent), ".slice") { + return fmt.Errorf("systemd slice received as cgroup parent when using cgroupfs: %w", define.ErrInvalidArg) + } + // If we are set to use pod cgroups, set the cgroup parent that + // all containers in the pod will share + if pod.config.UsePodCgroup { + pod.state.CgroupPath = filepath.Join(pod.config.CgroupParent, pod.ID()) + if p.InfraContainerSpec != nil { + p.InfraContainerSpec.CgroupParent = pod.state.CgroupPath + // cgroupfs + rootless = permission denied when creating the cgroup. + if !rootless.IsRootless() { + res, err := GetLimits(p.ResourceLimits) + if err != nil { + return err + } + // Need to both create and update the cgroup + // rather than create a new path in c/common for pod cgroup creation + // just create as if it is a ctr and then update figures out that we need to + // populate the resource limits on the pod level + cgc, err := cgroups.New(pod.state.CgroupPath, &res) + if err != nil { + return err + } + err = cgc.Update(&res) + if err != nil { + return err + } + } + } + } + } + case config.SystemdCgroupsManager: + if pod.config.CgroupParent == "" { + if rootless.IsRootless() { + pod.config.CgroupParent = SystemdDefaultRootlessCgroupParent + } else { + pod.config.CgroupParent = SystemdDefaultCgroupParent + } + } else if len(pod.config.CgroupParent) < 6 || !strings.HasSuffix(path.Base(pod.config.CgroupParent), ".slice") { + return fmt.Errorf("did not receive systemd slice as cgroup parent when using systemd to manage cgroups: %w", define.ErrInvalidArg) + } + // If we are set to use pod cgroups, set the cgroup parent that + // all containers in the pod will share + if pod.config.UsePodCgroup { + cgroupPath, err := systemdSliceFromPath(pod.config.CgroupParent, fmt.Sprintf("libpod_pod_%s", pod.ID()), p.ResourceLimits) + if err != nil { + return fmt.Errorf("unable to create pod cgroup for pod %s: %w", pod.ID(), err) + } + pod.state.CgroupPath = cgroupPath + if p.InfraContainerSpec != nil { + p.InfraContainerSpec.CgroupParent = pod.state.CgroupPath + } + } + default: + return fmt.Errorf("unsupported Cgroup manager: %s - cannot validate cgroup parent: %w", r.config.Engine.CgroupManager, define.ErrInvalidArg) + } + } + + if pod.config.UsePodCgroup { + logrus.Debugf("Got pod cgroup as %s", pod.state.CgroupPath) + } + + return nil +}