mirror of
https://github.com/containers/podman.git
synced 2025-12-23 22:28:30 -05:00
Merge pull request #27271 from lsm5/podman6-no-cgv1
Podman6: Remove cgroupsv1
This commit is contained in:
@@ -44,8 +44,8 @@ srpm_build_deps:
|
||||
- make
|
||||
|
||||
actions:
|
||||
fix-spec-file: "bash .packit-copr-rpm.sh"
|
||||
pre-sync: "bash .packit-rpm-git-commit.sh"
|
||||
fix-spec-file: "bash contrib/packit-tmt/packit-copr-rpm.sh"
|
||||
pre-sync: "bash contrib/packit-tmt/packit-rpm-git-commit.sh"
|
||||
|
||||
jobs:
|
||||
- job: copr_build
|
||||
|
||||
@@ -2,7 +2,6 @@ package containers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -12,9 +11,7 @@ import (
|
||||
"github.com/containers/podman/v6/cmd/podman/utils"
|
||||
"github.com/containers/podman/v6/cmd/podman/validate"
|
||||
"github.com/containers/podman/v6/pkg/domain/entities"
|
||||
"github.com/containers/podman/v6/pkg/rootless"
|
||||
"github.com/spf13/cobra"
|
||||
"go.podman.io/common/pkg/cgroups"
|
||||
"go.podman.io/common/pkg/completion"
|
||||
)
|
||||
|
||||
@@ -91,13 +88,6 @@ func unpause(_ *cobra.Command, args []string) error {
|
||||
var errs utils.OutputErrors
|
||||
args = utils.RemoveSlash(args)
|
||||
|
||||
if rootless.IsRootless() && !registry.IsRemote() {
|
||||
cgroupv2, _ := cgroups.IsCgroup2UnifiedMode()
|
||||
if !cgroupv2 {
|
||||
return errors.New("unpause is not supported for cgroupv1 rootless containers")
|
||||
}
|
||||
}
|
||||
|
||||
for _, cidFile := range unpauseCidFiles {
|
||||
content, err := os.ReadFile(cidFile)
|
||||
if err != nil {
|
||||
|
||||
@@ -248,6 +248,8 @@ func setupRemoteConnection(podmanConfig *entities.PodmanConfig) string {
|
||||
func persistentPreRunE(cmd *cobra.Command, args []string) error {
|
||||
logrus.Debugf("Called %s.PersistentPreRunE(%s)", cmd.Name(), strings.Join(os.Args, " "))
|
||||
|
||||
checkSupportedCgroups()
|
||||
|
||||
// Help, completion and commands with subcommands are special cases, no need for more setup
|
||||
// Completion cmd is used to generate the shell scripts
|
||||
if cmd.Name() == "help" || cmd.Name() == "completion" || cmd.HasSubCommands() {
|
||||
|
||||
18
cmd/podman/root_cgroups_linux.go
Normal file
18
cmd/podman/root_cgroups_linux.go
Normal file
@@ -0,0 +1,18 @@
|
||||
//go:build linux
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.podman.io/common/pkg/cgroups"
|
||||
)
|
||||
|
||||
func checkSupportedCgroups() {
|
||||
unified, err := cgroups.IsCgroup2UnifiedMode()
|
||||
if err != nil {
|
||||
logrus.Fatalf("Error determining cgroups mode")
|
||||
}
|
||||
if !unified {
|
||||
logrus.Fatalf("Cgroups v1 not supported")
|
||||
}
|
||||
}
|
||||
7
cmd/podman/root_cgroups_unsupported.go
Normal file
7
cmd/podman/root_cgroups_unsupported.go
Normal file
@@ -0,0 +1,7 @@
|
||||
//go:build !linux
|
||||
|
||||
package main
|
||||
|
||||
func checkSupportedCgroups() {
|
||||
// NOP on Non Linux
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"github.com/containers/podman/v6/pkg/rootless"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.podman.io/common/pkg/cgroups"
|
||||
"go.podman.io/common/pkg/servicereaper"
|
||||
@@ -15,11 +14,6 @@ func maybeStartServiceReaper() {
|
||||
}
|
||||
|
||||
func maybeMoveToSubCgroup() {
|
||||
cgroupv2, _ := cgroups.IsCgroup2UnifiedMode()
|
||||
if rootless.IsRootless() && !cgroupv2 {
|
||||
logrus.Warnf("Running 'system service' in rootless mode without cgroup v2, containers won't survive a 'system service' restart")
|
||||
}
|
||||
|
||||
if err := cgroups.MaybeMoveToSubCgroup(); err != nil {
|
||||
// it is a best effort operation, so just print the
|
||||
// error for debugging purposes.
|
||||
|
||||
@@ -6,16 +6,19 @@
|
||||
|
||||
set -exo pipefail
|
||||
|
||||
. .packit-rpm-git-commit.sh
|
||||
TOP_GIT_DIR=$(git rev-parse --show-toplevel)
|
||||
|
||||
. "$TOP_GIT_DIR"/contrib/packit-tmt/packit-rpm-git-commit.sh
|
||||
|
||||
# Get Version from HEAD
|
||||
VERSION=$(grep '^const RawVersion' version/rawversion/version.go | cut -d\" -f2)
|
||||
|
||||
# RPM Version can't take "-"
|
||||
RPM_VERSION=$(echo $VERSION | sed -e 's/-/~/')
|
||||
# shellcheck disable=SC2001
|
||||
RPM_VERSION=$(echo "$VERSION" | sed -e 's/-/~/')
|
||||
|
||||
# Generate source tarball from HEAD
|
||||
git-archive-all -C $(git rev-parse --show-toplevel) --prefix=$PACKAGE-$VERSION/ rpm/$PACKAGE-$VERSION.tar.gz
|
||||
git-archive-all -C "$TOP_GIT_DIR" --prefix="$PACKAGE-$VERSION/" "$TOP_GIT_DIR/rpm/$PACKAGE-$VERSION.tar.gz"
|
||||
|
||||
# RPM Spec modifications
|
||||
|
||||
14
contrib/packit-tmt/podman-next-setup.sh
Normal file
14
contrib/packit-tmt/podman-next-setup.sh
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -exo pipefail
|
||||
|
||||
COPR_REPO_FILE="/etc/yum.repos.d/_copr:copr.fedorainfracloud.org:rhcontainerbot:podman-next.repo"
|
||||
if compgen -G "$COPR_REPO_FILE" > /dev/null; then
|
||||
# We want the priority bump appended to the file, we're not looking
|
||||
# to use a variable.
|
||||
# shellcheck disable=SC2016
|
||||
sed -i -n '/^priority=/!p;$apriority=1' "$COPR_REPO_FILE"
|
||||
fi
|
||||
# We want all dependencies from podman-next except podman as podman will be fetched
|
||||
# from the packit copr.
|
||||
dnf -y upgrade --allowerasing --exclude=podman*
|
||||
@@ -26352,16 +26352,9 @@ msgstr ""
|
||||
msgid "Display a live stream of one or more containers' resource usage statistics"
|
||||
msgstr ""
|
||||
|
||||
#: ../../source/markdown/podman-stats.1.md:15
|
||||
msgid ""
|
||||
"Note: Podman stats does not work in rootless environments that use "
|
||||
"CGroups V1. Podman stats relies on CGroup information for statistics, and"
|
||||
" CGroup v1 is not supported for rootless use cases."
|
||||
msgstr ""
|
||||
|
||||
#: ../../source/markdown/podman-stats.1.md:19
|
||||
msgid ""
|
||||
"Note: Rootless environments that use CGroups V2 are not able to report "
|
||||
"Note: Rootless environments are not able to report "
|
||||
"statistics about their networking usage."
|
||||
msgstr ""
|
||||
|
||||
@@ -26481,10 +26474,6 @@ msgstr ""
|
||||
msgid "Network Output"
|
||||
msgstr ""
|
||||
|
||||
#: ../../source/markdown/podman-stats.1.md:1
|
||||
msgid ".PerCPU"
|
||||
msgstr ""
|
||||
|
||||
#: ../../source/markdown/podman-stats.1.md:1
|
||||
msgid "CPU time consumed by all tasks [1]"
|
||||
msgstr ""
|
||||
@@ -26521,10 +26510,6 @@ msgstr ""
|
||||
msgid "Same as UpTime"
|
||||
msgstr ""
|
||||
|
||||
#: ../../source/markdown/podman-stats.1.md:64
|
||||
msgid "[1] Cgroups V1 only"
|
||||
msgstr ""
|
||||
|
||||
#: ../../source/markdown/podman-stats.1.md:68
|
||||
msgid "**--interval**, **-i**=*seconds*"
|
||||
msgstr ""
|
||||
|
||||
@@ -11,11 +11,7 @@ podman\-stats - Display a live stream of one or more container's resource usage
|
||||
## DESCRIPTION
|
||||
Display a live stream of one or more containers' resource usage statistics
|
||||
|
||||
Note: Podman stats does not work in rootless environments that use cgroups v1.
|
||||
Podman stats relies on cgroup information for statistics, and cgroup v1 is not
|
||||
supported for rootless use cases.
|
||||
|
||||
Note: Rootless environments that use cgroups v2 are not able to report statistics
|
||||
Note: Rootless environments are not able to report statistics
|
||||
about their networking usage.
|
||||
|
||||
## OPTIONS
|
||||
@@ -52,15 +48,12 @@ Valid placeholders for the Go template are listed below:
|
||||
| .Name | Container Name |
|
||||
| .NetIO | Network IO |
|
||||
| .Network ... | Network I/O, separated by network interface |
|
||||
| .PerCPU | CPU time consumed by all tasks [1] |
|
||||
| .PIDs | Number of PIDs |
|
||||
| .PIDS | Number of PIDs (yes, we know this is a dup) |
|
||||
| .SystemNano | Current system datetime, nanoseconds since epoch |
|
||||
| .Up | Duration (CPUNano), in human-readable form |
|
||||
| .UpTime | Same as Up |
|
||||
|
||||
[1] Cgroups V1 only
|
||||
|
||||
When using a Go template, precede the format with `table` to print headers.
|
||||
|
||||
#### **--interval**, **-i**=*seconds*
|
||||
|
||||
@@ -37,7 +37,6 @@ The CDI spec directory path (may be set multiple times). Default path is `/etc/c
|
||||
The CGroup manager to use for container cgroups. Supported values are __cgroupfs__ or __systemd__. Default is _systemd_ unless overridden in the containers.conf file.
|
||||
|
||||
Note: Setting this flag can cause certain commands to break when called on containers previously created by the other CGroup manager type.
|
||||
Note: CGroup manager is not supported in rootless mode when using CGroups Version V1.
|
||||
|
||||
#### **--config**
|
||||
Location of config file. Mainly for docker compatibility, only the authentication parts of the config are supported.
|
||||
|
||||
@@ -41,7 +41,6 @@ import (
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.podman.io/common/libnetwork/etchosts"
|
||||
"go.podman.io/common/pkg/cgroups"
|
||||
"go.podman.io/common/pkg/chown"
|
||||
"go.podman.io/common/pkg/config"
|
||||
"go.podman.io/common/pkg/hooks"
|
||||
@@ -1362,41 +1361,25 @@ func (c *Container) waitForHealthy(ctx context.Context) error {
|
||||
}
|
||||
|
||||
// Whether a container should use `all` when stopping
|
||||
func (c *Container) stopWithAll() (bool, error) {
|
||||
func (c *Container) stopWithAll() bool {
|
||||
// If the container is running in a PID Namespace, then killing the
|
||||
// primary pid is enough to kill the container. If it is not running in
|
||||
// a pid namespace then the OCI Runtime needs to kill ALL processes in
|
||||
// the container's cgroup in order to make sure the container is stopped.
|
||||
all := !c.hasNamespace(spec.PIDNamespace)
|
||||
// We can't use --all if Cgroups aren't present.
|
||||
// Rootless containers with Cgroups v1 and NoCgroups are both cases
|
||||
// where this can happen.
|
||||
if all {
|
||||
if c.config.NoCgroups {
|
||||
all = false
|
||||
} else if rootless.IsRootless() {
|
||||
// Only do this check if we need to
|
||||
unified, err := cgroups.IsCgroup2UnifiedMode()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !unified {
|
||||
all = false
|
||||
}
|
||||
}
|
||||
// Rootless containers with NoCgroups is a case where this can happen.
|
||||
if all && c.config.NoCgroups {
|
||||
all = false
|
||||
}
|
||||
|
||||
return all, nil
|
||||
return all
|
||||
}
|
||||
|
||||
// Internal, non-locking function to stop container
|
||||
func (c *Container) stop(timeout uint) error {
|
||||
logrus.Debugf("Stopping ctr %s (timeout %d)", c.ID(), timeout)
|
||||
|
||||
all, err := c.stopWithAll()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
all := c.stopWithAll()
|
||||
|
||||
// OK, the following code looks a bit weird but we have to make sure we can stop
|
||||
// containers with the restart policy always, to do this we have to set
|
||||
@@ -1503,7 +1486,7 @@ func (c *Container) waitForConmonToExitAndSave() error {
|
||||
// could open a pidfd on container PID1 before
|
||||
// this to get the real exit code... But I'm not
|
||||
// that dedicated.
|
||||
all, _ := c.stopWithAll()
|
||||
all := c.stopWithAll()
|
||||
if err := c.ociRuntime.StopContainer(c, 0, all); err != nil {
|
||||
logrus.Errorf("Error stopping container %s after Conmon exited prematurely: %v", c.ID(), err)
|
||||
}
|
||||
@@ -1560,16 +1543,6 @@ func (c *Container) pause() error {
|
||||
return fmt.Errorf("cannot pause without using Cgroups: %w", define.ErrNoCgroups)
|
||||
}
|
||||
|
||||
if rootless.IsRootless() {
|
||||
cgroupv2, err := cgroups.IsCgroup2UnifiedMode()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to determine cgroupversion: %w", err)
|
||||
}
|
||||
if !cgroupv2 {
|
||||
return fmt.Errorf("can not pause containers on rootless containers with cgroup V1: %w", define.ErrNoCgroups)
|
||||
}
|
||||
}
|
||||
|
||||
if c.state.HCUnitName != "" {
|
||||
if err := c.removeTransientFiles(context.Background(),
|
||||
c.config.StartupHealthCheckConfig != nil && !c.state.StartupHCPassed,
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
package libpod
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
@@ -222,7 +221,7 @@ func (c *Container) reloadNetwork() error {
|
||||
|
||||
// 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) error {
|
||||
func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) {
|
||||
var containerUUIDSet bool
|
||||
for _, s := range c.config.Spec.Process.Env {
|
||||
if strings.HasPrefix(s, "container_uuid=") {
|
||||
@@ -265,11 +264,6 @@ func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) erro
|
||||
g.AddMount(tmpfsMnt)
|
||||
}
|
||||
|
||||
unified, err := cgroups.IsCgroup2UnifiedMode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hasCgroupNs := false
|
||||
for _, ns := range c.config.Spec.Linux.Namespaces {
|
||||
if ns.Type == spec.CgroupNamespace {
|
||||
@@ -278,71 +272,25 @@ func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) erro
|
||||
}
|
||||
}
|
||||
|
||||
if unified {
|
||||
g.RemoveMount("/sys/fs/cgroup")
|
||||
g.RemoveMount("/sys/fs/cgroup")
|
||||
|
||||
var systemdMnt spec.Mount
|
||||
if hasCgroupNs {
|
||||
systemdMnt = spec.Mount{
|
||||
Destination: "/sys/fs/cgroup",
|
||||
Type: "cgroup",
|
||||
Source: "cgroup",
|
||||
Options: []string{"private", "rw"},
|
||||
}
|
||||
} else {
|
||||
systemdMnt = spec.Mount{
|
||||
Destination: "/sys/fs/cgroup",
|
||||
Type: define.TypeBind,
|
||||
Source: "/sys/fs/cgroup",
|
||||
Options: []string{define.TypeBind, "private", "rw"},
|
||||
}
|
||||
var systemdMnt spec.Mount
|
||||
if hasCgroupNs {
|
||||
systemdMnt = spec.Mount{
|
||||
Destination: "/sys/fs/cgroup",
|
||||
Type: "cgroup",
|
||||
Source: "cgroup",
|
||||
Options: []string{"private", "rw"},
|
||||
}
|
||||
g.AddMount(systemdMnt)
|
||||
} else {
|
||||
hasSystemdMount := MountExists(mounts, "/sys/fs/cgroup/systemd")
|
||||
if hasCgroupNs && !hasSystemdMount {
|
||||
return errors.New("cgroup namespace is not supported with cgroup v1 and systemd mode")
|
||||
}
|
||||
mountOptions := []string{define.TypeBind, "rprivate"}
|
||||
|
||||
if !hasSystemdMount {
|
||||
skipMount := hasSystemdMount
|
||||
var statfs unix.Statfs_t
|
||||
if err := unix.Statfs("/sys/fs/cgroup/systemd", &statfs); err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
// If the mount is missing on the host, we cannot bind mount it so
|
||||
// just skip it.
|
||||
skipMount = true
|
||||
}
|
||||
mountOptions = append(mountOptions, "nodev", "noexec", "nosuid")
|
||||
} else {
|
||||
if statfs.Flags&unix.MS_NODEV == unix.MS_NODEV {
|
||||
mountOptions = append(mountOptions, "nodev")
|
||||
}
|
||||
if statfs.Flags&unix.MS_NOEXEC == unix.MS_NOEXEC {
|
||||
mountOptions = append(mountOptions, "noexec")
|
||||
}
|
||||
if statfs.Flags&unix.MS_NOSUID == unix.MS_NOSUID {
|
||||
mountOptions = append(mountOptions, "nosuid")
|
||||
}
|
||||
if statfs.Flags&unix.MS_RDONLY == unix.MS_RDONLY {
|
||||
mountOptions = append(mountOptions, "ro")
|
||||
}
|
||||
}
|
||||
if !skipMount {
|
||||
systemdMnt := spec.Mount{
|
||||
Destination: "/sys/fs/cgroup/systemd",
|
||||
Type: define.TypeBind,
|
||||
Source: "/sys/fs/cgroup/systemd",
|
||||
Options: mountOptions,
|
||||
}
|
||||
g.AddMount(systemdMnt)
|
||||
g.AddLinuxMaskedPaths("/sys/fs/cgroup/systemd/release_agent")
|
||||
}
|
||||
systemdMnt = spec.Mount{
|
||||
Destination: "/sys/fs/cgroup",
|
||||
Type: define.TypeBind,
|
||||
Source: "/sys/fs/cgroup",
|
||||
Options: []string{define.TypeBind, "private", "rw"},
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
g.AddMount(systemdMnt)
|
||||
}
|
||||
|
||||
// Add an existing container's namespace to the spec
|
||||
@@ -383,16 +331,12 @@ func isRootlessCgroupSet(cgroup string) bool {
|
||||
}
|
||||
|
||||
func (c *Container) expectPodCgroup() (bool, error) {
|
||||
unified, err := cgroups.IsCgroup2UnifiedMode()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
cgroupManager := c.CgroupManager()
|
||||
switch {
|
||||
case c.config.NoCgroups:
|
||||
return false, nil
|
||||
case cgroupManager == config.SystemdCgroupsManager:
|
||||
return !rootless.IsRootless() || unified, nil
|
||||
return true, nil
|
||||
case cgroupManager == config.CgroupfsCgroupsManager:
|
||||
return !rootless.IsRootless(), nil
|
||||
default:
|
||||
@@ -402,10 +346,6 @@ func (c *Container) expectPodCgroup() (bool, error) {
|
||||
|
||||
// Get cgroup path in a format suitable for the OCI spec
|
||||
func (c *Container) getOCICgroupPath() (string, error) {
|
||||
unified, err := cgroups.IsCgroup2UnifiedMode()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
cgroupManager := c.CgroupManager()
|
||||
switch {
|
||||
case c.config.NoCgroups:
|
||||
@@ -423,7 +363,7 @@ func (c *Container) getOCICgroupPath() (string, error) {
|
||||
systemdCgroups := fmt.Sprintf("%s:libpod:%s", path.Base(c.config.CgroupParent), c.ID())
|
||||
logrus.Debugf("Setting Cgroups for container %s to %s", c.ID(), systemdCgroups)
|
||||
return systemdCgroups, nil
|
||||
case (rootless.IsRootless() && (cgroupManager == config.CgroupfsCgroupsManager || !unified)):
|
||||
case (rootless.IsRootless() && cgroupManager == config.CgroupfsCgroupsManager):
|
||||
if c.config.CgroupParent == "" || !isRootlessCgroupSet(c.config.CgroupParent) {
|
||||
return "", nil
|
||||
}
|
||||
@@ -458,9 +398,7 @@ func (c *Container) addNetworkNamespace(g *generate.Generator) error {
|
||||
|
||||
func (c *Container) addSystemdMounts(g *generate.Generator) error {
|
||||
if c.Systemd() {
|
||||
if err := c.setupSystemd(g.Mounts(), *g); err != nil {
|
||||
return err
|
||||
}
|
||||
c.setupSystemd(g.Mounts(), *g)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -133,7 +133,6 @@ type ContainerStats struct {
|
||||
AvgCPU float64
|
||||
ContainerID string
|
||||
Name string
|
||||
PerCPU []uint64
|
||||
CPU float64
|
||||
CPUNano uint64
|
||||
CPUSystemNano uint64
|
||||
|
||||
@@ -30,14 +30,10 @@ func (r *Runtime) setPlatformHostInfo(info *define.HostInfo) error {
|
||||
return fmt.Errorf("getting Seccomp profile path: %w", err)
|
||||
}
|
||||
|
||||
// Cgroups version
|
||||
unified, err := cgroups.IsCgroup2UnifiedMode()
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading cgroups mode: %w", err)
|
||||
}
|
||||
|
||||
// Get Map of all available controllers
|
||||
availableControllers, err := cgroups.AvailableControllers(nil, unified)
|
||||
// FIXME: AvailableControllers should be further simplified once CGv1 removal
|
||||
// in container-libs is complete.
|
||||
availableControllers, err := cgroups.AvailableControllers(nil, true)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting available cgroup controllers: %w", err)
|
||||
}
|
||||
@@ -55,11 +51,7 @@ func (r *Runtime) setPlatformHostInfo(info *define.HostInfo) error {
|
||||
}
|
||||
info.Slirp4NetNS = define.SlirpInfo{}
|
||||
|
||||
cgroupVersion := "v1"
|
||||
if unified {
|
||||
cgroupVersion = "v2"
|
||||
}
|
||||
info.CgroupsVersion = cgroupVersion
|
||||
info.CgroupsVersion = "v2"
|
||||
|
||||
slirp4netnsPath := r.config.Engine.NetworkCmdPath
|
||||
if slirp4netnsPath == "" {
|
||||
|
||||
@@ -10,10 +10,8 @@ import (
|
||||
"github.com/containers/podman/v6/libpod/define"
|
||||
"github.com/containers/podman/v6/libpod/events"
|
||||
"github.com/containers/podman/v6/pkg/parallel"
|
||||
"github.com/containers/podman/v6/pkg/rootless"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.podman.io/common/pkg/cgroups"
|
||||
)
|
||||
|
||||
// startInitContainers starts a pod's init containers.
|
||||
@@ -341,16 +339,6 @@ func (p *Pod) Pause(ctx context.Context) (map[string]error, error) {
|
||||
return nil, define.ErrPodRemoved
|
||||
}
|
||||
|
||||
if rootless.IsRootless() {
|
||||
cgroupv2, err := cgroups.IsCgroup2UnifiedMode()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to determine cgroupversion: %w", err)
|
||||
}
|
||||
if !cgroupv2 {
|
||||
return nil, fmt.Errorf("can not pause pods containing rootless containers with cgroup V1: %w", define.ErrNoCgroups)
|
||||
}
|
||||
}
|
||||
|
||||
allCtrs, err := p.runtime.state.PodContainers(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -34,7 +34,6 @@ import (
|
||||
"go.podman.io/common/libimage"
|
||||
"go.podman.io/common/libnetwork/network"
|
||||
nettypes "go.podman.io/common/libnetwork/types"
|
||||
"go.podman.io/common/pkg/cgroups"
|
||||
"go.podman.io/common/pkg/config"
|
||||
artStore "go.podman.io/common/pkg/libartifact/store"
|
||||
"go.podman.io/common/pkg/secrets"
|
||||
@@ -179,11 +178,7 @@ func newRuntimeFromConfig(ctx context.Context, conf *config.Config, options ...R
|
||||
runtime := new(Runtime)
|
||||
|
||||
if conf.Engine.OCIRuntime == "" {
|
||||
conf.Engine.OCIRuntime = "runc"
|
||||
// If we're running on cgroups v2, default to using crun.
|
||||
if onCgroupsv2, _ := cgroups.IsCgroup2UnifiedMode(); onCgroupsv2 {
|
||||
conf.Engine.OCIRuntime = "crun"
|
||||
}
|
||||
conf.Engine.OCIRuntime = "crun"
|
||||
}
|
||||
|
||||
runtime.config = conf
|
||||
@@ -543,8 +538,7 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) {
|
||||
// and no valid systemd session is present
|
||||
// warn only whenever new namespace is created
|
||||
if runtime.config.Engine.CgroupManager == config.SystemdCgroupsManager {
|
||||
unified, _ := cgroups.IsCgroup2UnifiedMode()
|
||||
if unified && rootless.IsRootless() && !systemd.IsSystemdSessionValid(rootless.GetRootlessUID()) {
|
||||
if rootless.IsRootless() && !systemd.IsSystemdSessionValid(rootless.GetRootlessUID()) {
|
||||
logrus.Debug("Invalid systemd user session for current user")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import (
|
||||
"github.com/opencontainers/runtime-tools/generate"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.podman.io/common/libnetwork/types"
|
||||
"go.podman.io/common/pkg/cgroups"
|
||||
"go.podman.io/common/pkg/config"
|
||||
"go.podman.io/storage"
|
||||
"go.podman.io/storage/pkg/stringid"
|
||||
@@ -856,18 +855,6 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, opts ctrRmO
|
||||
}
|
||||
|
||||
if c.state.State == define.ContainerStatePaused {
|
||||
isV2, err := cgroups.IsCgroup2UnifiedMode()
|
||||
if err != nil {
|
||||
retErr = err
|
||||
return removedCtrs, removedPods, retErr
|
||||
}
|
||||
// cgroups v1 and v2 handle signals on paused processes differently
|
||||
if !isV2 {
|
||||
if err := c.unpause(); err != nil {
|
||||
retErr = err
|
||||
return removedCtrs, removedPods, retErr
|
||||
}
|
||||
}
|
||||
if err := c.ociRuntime.KillContainer(c, 9, false); err != nil {
|
||||
retErr = err
|
||||
return removedCtrs, removedPods, retErr
|
||||
|
||||
@@ -12,21 +12,10 @@ import (
|
||||
"github.com/containers/podman/v6/pkg/rootless"
|
||||
"github.com/containers/podman/v6/pkg/systemd"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.podman.io/common/pkg/cgroups"
|
||||
)
|
||||
|
||||
func checkCgroups2UnifiedMode(runtime *Runtime) {
|
||||
unified, _ := cgroups.IsCgroup2UnifiedMode()
|
||||
// DELETE ON RHEL9
|
||||
if !unified {
|
||||
_, ok := os.LookupEnv("PODMAN_IGNORE_CGROUPSV1_WARNING")
|
||||
if !ok {
|
||||
logrus.Warn("Using cgroups-v1 which is deprecated in favor of cgroups-v2 with Podman v5 and will be removed in a future version. Set environment variable `PODMAN_IGNORE_CGROUPSV1_WARNING` to hide this warning.")
|
||||
}
|
||||
}
|
||||
// DELETE ON RHEL9
|
||||
|
||||
if unified && rootless.IsRootless() && !systemd.IsSystemdSessionValid(rootless.GetRootlessUID()) {
|
||||
if rootless.IsRootless() && !systemd.IsSystemdSessionValid(rootless.GetRootlessUID()) {
|
||||
// If user is rootless and XDG_RUNTIME_DIR is found, podman will not proceed with /tmp directory
|
||||
// it will try to use existing XDG_RUNTIME_DIR
|
||||
// if current user has no write access to XDG_RUNTIME_DIR we will fail later
|
||||
|
||||
@@ -122,7 +122,7 @@ func (p *Pod) removePodCgroup() error {
|
||||
// hard - instead, just log errors.
|
||||
conmonCgroupPath := filepath.Join(p.state.CgroupPath, "conmon")
|
||||
conmonCgroup, err := cgroups.Load(conmonCgroupPath)
|
||||
if err != nil && err != cgroups.ErrCgroupDeleted && err != cgroups.ErrCgroupV1Rootless {
|
||||
if err != nil && err != cgroups.ErrCgroupDeleted {
|
||||
return fmt.Errorf("retrieving pod %s conmon cgroup: %w", p.ID(), err)
|
||||
}
|
||||
if err == nil {
|
||||
@@ -131,7 +131,7 @@ func (p *Pod) removePodCgroup() error {
|
||||
}
|
||||
}
|
||||
cgroup, err := cgroups.Load(p.state.CgroupPath)
|
||||
if err != nil && err != cgroups.ErrCgroupDeleted && err != cgroups.ErrCgroupV1Rootless {
|
||||
if err != nil && err != cgroups.ErrCgroupDeleted {
|
||||
return fmt.Errorf("retrieving pod %s cgroup: %w", p.ID(), err)
|
||||
}
|
||||
if err == nil {
|
||||
|
||||
@@ -69,7 +69,6 @@ func (c *Container) getPlatformContainerStats(stats *define.ContainerStats, prev
|
||||
stats.CPUNano = cgroupStats.CpuStats.CpuUsage.TotalUsage
|
||||
stats.CPUSystemNano = cgroupStats.CpuStats.CpuUsage.UsageInKernelmode
|
||||
stats.SystemNano = now
|
||||
stats.PerCPU = cgroupStats.CpuStats.CpuUsage.PercpuUsage
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -21,13 +21,7 @@ import (
|
||||
)
|
||||
|
||||
func cgroupExist(path string) bool {
|
||||
cgroupv2, _ := cgroups.IsCgroup2UnifiedMode()
|
||||
var fullPath string
|
||||
if cgroupv2 {
|
||||
fullPath = filepath.Join("/sys/fs/cgroup", path)
|
||||
} else {
|
||||
fullPath = filepath.Join("/sys/fs/cgroup/memory", path)
|
||||
}
|
||||
fullPath := filepath.Join("/sys/fs/cgroup", path)
|
||||
return fileutils.Exists(fullPath) == nil
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ import (
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
"go.podman.io/common/libimage"
|
||||
"go.podman.io/common/libnetwork/types"
|
||||
"go.podman.io/common/pkg/cgroups"
|
||||
"go.podman.io/common/pkg/config"
|
||||
"go.podman.io/storage"
|
||||
"go.podman.io/storage/pkg/fileutils"
|
||||
@@ -575,11 +574,7 @@ func cliOpts(cc handlers.CreateContainerConfig, rtc *config.Config) (*entities.C
|
||||
cliOpts.MemoryReservation = strconv.Itoa(int(cc.HostConfig.MemoryReservation))
|
||||
}
|
||||
|
||||
cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if cc.HostConfig.MemorySwap > 0 && (!rootless.IsRootless() || (rootless.IsRootless() && cgroupsv2)) {
|
||||
if cc.HostConfig.MemorySwap > 0 {
|
||||
cliOpts.MemorySwap = strconv.Itoa(int(cc.HostConfig.MemorySwap))
|
||||
}
|
||||
|
||||
@@ -600,7 +595,7 @@ func cliOpts(cc handlers.CreateContainerConfig, rtc *config.Config) (*entities.C
|
||||
cliOpts.Restart = policy
|
||||
}
|
||||
|
||||
if cc.HostConfig.MemorySwappiness != nil && (!rootless.IsRootless() || rootless.IsRootless() && cgroupsv2 && rtc.Engine.CgroupManager == "systemd") {
|
||||
if cc.HostConfig.MemorySwappiness != nil && (!rootless.IsRootless() || rootless.IsRootless() && rtc.Engine.CgroupManager == "systemd") {
|
||||
cliOpts.MemorySwappiness = *cc.HostConfig.MemorySwappiness
|
||||
} else {
|
||||
cliOpts.MemorySwappiness = -1
|
||||
|
||||
@@ -20,7 +20,6 @@ func getPreCPUStats(stats *define.ContainerStats) CPUStats {
|
||||
return CPUStats{
|
||||
CPUUsage: container.CPUUsage{
|
||||
TotalUsage: stats.CPUNano,
|
||||
PercpuUsage: stats.PerCPU,
|
||||
UsageInKernelmode: stats.CPUSystemNano,
|
||||
UsageInUsermode: stats.CPUNano - stats.CPUSystemNano,
|
||||
},
|
||||
|
||||
@@ -4,7 +4,6 @@ package libpod
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
@@ -13,25 +12,14 @@ import (
|
||||
api "github.com/containers/podman/v6/pkg/api/types"
|
||||
"github.com/containers/podman/v6/pkg/domain/entities"
|
||||
"github.com/containers/podman/v6/pkg/domain/infra/abi"
|
||||
"github.com/containers/podman/v6/pkg/rootless"
|
||||
"github.com/gorilla/schema"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.podman.io/common/pkg/cgroups"
|
||||
)
|
||||
|
||||
func StatsContainer(w http.ResponseWriter, r *http.Request) {
|
||||
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
|
||||
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
|
||||
|
||||
// Check if service is running rootless (cheap check)
|
||||
if rootless.IsRootless() {
|
||||
// if so, then verify cgroup v2 available (more expensive check)
|
||||
if isV2, _ := cgroups.IsCgroup2UnifiedMode(); !isV2 {
|
||||
utils.Error(w, http.StatusConflict, errors.New("container stats resource only available for cgroup v2"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
query := struct {
|
||||
Containers []string `schema:"containers"`
|
||||
Stream bool `schema:"stream"`
|
||||
|
||||
@@ -34,7 +34,6 @@ import (
|
||||
"github.com/containers/podman/v6/pkg/util"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.podman.io/common/pkg/cgroups"
|
||||
"go.podman.io/common/pkg/config"
|
||||
"go.podman.io/image/v5/manifest"
|
||||
"go.podman.io/storage"
|
||||
@@ -1620,15 +1619,6 @@ func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []stri
|
||||
if options.Interval < 1 {
|
||||
return nil, errors.New("invalid interval, must be a positive number greater zero")
|
||||
}
|
||||
if rootless.IsRootless() {
|
||||
unified, err := cgroups.IsCgroup2UnifiedMode()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !unified {
|
||||
return nil, errors.New("stats is not supported in rootless mode without cgroups v2")
|
||||
}
|
||||
}
|
||||
statsChan = make(chan entities.ContainerStatsReport, 1)
|
||||
|
||||
var containerFunc func() ([]*libpod.Container, error)
|
||||
|
||||
@@ -11,23 +11,11 @@ import (
|
||||
"github.com/containers/podman/v6/libpod"
|
||||
"github.com/containers/podman/v6/libpod/define"
|
||||
"github.com/containers/podman/v6/pkg/domain/entities"
|
||||
"github.com/containers/podman/v6/pkg/rootless"
|
||||
"github.com/docker/go-units"
|
||||
"go.podman.io/common/pkg/cgroups"
|
||||
)
|
||||
|
||||
// PodStats implements printing stats about pods.
|
||||
func (ic *ContainerEngine) PodStats(_ context.Context, namesOrIds []string, options entities.PodStatsOptions) ([]*entities.PodStatsReport, error) {
|
||||
// Cgroups v2 check for rootless.
|
||||
if rootless.IsRootless() {
|
||||
unified, err := cgroups.IsCgroup2UnifiedMode()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !unified {
|
||||
return nil, errors.New("pod stats is not supported in rootless mode without cgroups v2")
|
||||
}
|
||||
}
|
||||
// Get the (running) pods and convert them to the entities format.
|
||||
pods, err := getPodsByContext(options.All, options.Latest, namesOrIds, ic.Libpod)
|
||||
if err != nil {
|
||||
|
||||
@@ -20,7 +20,6 @@ import (
|
||||
"github.com/containers/podman/v6/pkg/util"
|
||||
"github.com/sirupsen/logrus"
|
||||
flag "github.com/spf13/pflag"
|
||||
"go.podman.io/common/pkg/cgroups"
|
||||
"go.podman.io/storage/pkg/idtools"
|
||||
"go.podman.io/storage/types"
|
||||
)
|
||||
@@ -182,14 +181,6 @@ func getRuntime(ctx context.Context, fs *flag.FlagSet, opts *engineOpts) (*libpo
|
||||
|
||||
if fs.Changed("cgroup-manager") {
|
||||
options = append(options, libpod.WithCgroupManager(cfg.ContainersConf.Engine.CgroupManager))
|
||||
} else {
|
||||
unified, err := cgroups.IsCgroup2UnifiedMode()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rootless.IsRootless() && !unified {
|
||||
options = append(options, libpod.WithCgroupManager("cgroupfs"))
|
||||
}
|
||||
}
|
||||
|
||||
// TODO flag to set libpod static dir?
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"github.com/opencontainers/runtime-tools/generate"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.podman.io/common/libimage"
|
||||
"go.podman.io/common/pkg/cgroups"
|
||||
"go.podman.io/common/pkg/config"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
@@ -65,11 +64,6 @@ func getCgroupPermissions(unmask []string) string {
|
||||
rw := "rw"
|
||||
cgroup := "/sys/fs/cgroup"
|
||||
|
||||
cgroupv2, _ := cgroups.IsCgroup2UnifiedMode()
|
||||
if !cgroupv2 {
|
||||
return ro
|
||||
}
|
||||
|
||||
if len(unmask) != 0 && unmask[0] == "ALL" {
|
||||
return rw
|
||||
}
|
||||
|
||||
@@ -3,173 +3,17 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
|
||||
"github.com/containers/podman/v6/pkg/rootless"
|
||||
"github.com/containers/podman/v6/pkg/specgen"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"go.podman.io/common/pkg/cgroups"
|
||||
"go.podman.io/common/pkg/sysinfo"
|
||||
"go.podman.io/storage/pkg/fileutils"
|
||||
)
|
||||
|
||||
// Verify resource limits are sanely set when running on cgroup v1.
|
||||
func verifyContainerResourcesCgroupV1(s *specgen.SpecGenerator) ([]string, error) {
|
||||
warnings := []string{}
|
||||
|
||||
sysInfo := sysinfo.New(true)
|
||||
|
||||
// If ResourceLimits is nil, return without warning
|
||||
resourceNil := &specgen.SpecGenerator{}
|
||||
resourceNil.ResourceLimits = &specs.LinuxResources{}
|
||||
if s.ResourceLimits == nil || reflect.DeepEqual(s.ResourceLimits, resourceNil.ResourceLimits) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Cgroups V1 rootless system does not support Resource limits
|
||||
if rootless.IsRootless() {
|
||||
s.ResourceLimits = nil
|
||||
return []string{"Resource limits are not supported and ignored on cgroups V1 rootless systems"}, nil
|
||||
}
|
||||
|
||||
if s.ResourceLimits.Unified != nil {
|
||||
return nil, errors.New("cannot use --cgroup-conf without cgroup v2")
|
||||
}
|
||||
|
||||
// Memory checks
|
||||
if s.ResourceLimits.Memory != nil {
|
||||
memory := s.ResourceLimits.Memory
|
||||
if memory.Limit != nil && !sysInfo.MemoryLimit {
|
||||
warnings = append(warnings, "Your kernel does not support memory limit capabilities or the cgroup is not mounted. Limitation discarded.")
|
||||
memory.Limit = nil
|
||||
memory.Swap = nil
|
||||
}
|
||||
if memory.Limit != nil && memory.Swap != nil && !sysInfo.SwapLimit {
|
||||
warnings = append(warnings, "Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap.")
|
||||
memory.Swap = nil
|
||||
}
|
||||
if memory.Limit != nil && memory.Swap != nil && *memory.Swap < *memory.Limit {
|
||||
return warnings, errors.New("minimum memoryswap limit should be larger than memory limit, see usage")
|
||||
}
|
||||
if memory.Limit == nil && memory.Swap != nil {
|
||||
return warnings, errors.New("you should always set a memory limit when using a memoryswap limit, see usage")
|
||||
}
|
||||
if memory.Swappiness != nil {
|
||||
if !sysInfo.MemorySwappiness {
|
||||
warnings = append(warnings, "Your kernel does not support memory swappiness capabilities, or the cgroup is not mounted. Memory swappiness discarded.")
|
||||
memory.Swappiness = nil
|
||||
} else if *memory.Swappiness > 100 {
|
||||
return warnings, fmt.Errorf("invalid value: %v, valid memory swappiness range is 0-100", *memory.Swappiness)
|
||||
}
|
||||
}
|
||||
if memory.Reservation != nil && !sysInfo.MemoryReservation {
|
||||
warnings = append(warnings, "Your kernel does not support memory soft limit capabilities or the cgroup is not mounted. Limitation discarded.")
|
||||
memory.Reservation = nil
|
||||
}
|
||||
if memory.Limit != nil && memory.Reservation != nil && *memory.Limit < *memory.Reservation {
|
||||
return warnings, errors.New("minimum memory limit cannot be less than memory reservation limit, see usage")
|
||||
}
|
||||
if memory.DisableOOMKiller != nil && *memory.DisableOOMKiller && !sysInfo.OomKillDisable {
|
||||
warnings = append(warnings, "Your kernel does not support OomKillDisable. OomKillDisable discarded.")
|
||||
memory.DisableOOMKiller = nil
|
||||
}
|
||||
}
|
||||
|
||||
// Pids checks
|
||||
if s.ResourceLimits.Pids != nil {
|
||||
// TODO: Should this be 0, or checking that ResourceLimits.Pids
|
||||
// is set at all?
|
||||
if s.ResourceLimits.Pids.Limit >= 0 && !sysInfo.PidsLimit {
|
||||
warnings = append(warnings, "Your kernel does not support pids limit capabilities or the cgroup is not mounted. PIDs limit discarded.")
|
||||
s.ResourceLimits.Pids = nil
|
||||
}
|
||||
}
|
||||
|
||||
// CPU checks
|
||||
if s.ResourceLimits.CPU != nil {
|
||||
cpu := s.ResourceLimits.CPU
|
||||
if cpu.Shares != nil && !sysInfo.CPUShares {
|
||||
warnings = append(warnings, "Your kernel does not support CPU shares or the cgroup is not mounted. Shares discarded.")
|
||||
cpu.Shares = nil
|
||||
}
|
||||
if cpu.Period != nil && !sysInfo.CPUCfsPeriod {
|
||||
warnings = append(warnings, "Your kernel does not support CPU cfs period or the cgroup is not mounted. Period discarded.")
|
||||
cpu.Period = nil
|
||||
}
|
||||
if cpu.Period != nil && (*cpu.Period < 1000 || *cpu.Period > 1000000) {
|
||||
return warnings, errors.New("CPU cfs period cannot be less than 1ms (i.e. 1000) or larger than 1s (i.e. 1000000)")
|
||||
}
|
||||
if cpu.Quota != nil && !sysInfo.CPUCfsQuota {
|
||||
warnings = append(warnings, "Your kernel does not support CPU cfs quota or the cgroup is not mounted. Quota discarded.")
|
||||
cpu.Quota = nil
|
||||
}
|
||||
if cpu.Quota != nil && *cpu.Quota < 1000 {
|
||||
return warnings, errors.New("CPU cfs quota cannot be less than 1ms (i.e. 1000)")
|
||||
}
|
||||
if (cpu.Cpus != "" || cpu.Mems != "") && !sysInfo.Cpuset {
|
||||
warnings = append(warnings, "Your kernel does not support cpuset or the cgroup is not mounted. CPUset discarded.")
|
||||
cpu.Cpus = ""
|
||||
cpu.Mems = ""
|
||||
}
|
||||
|
||||
cpusAvailable, err := sysInfo.IsCpusetCpusAvailable(cpu.Cpus)
|
||||
if err != nil {
|
||||
return warnings, fmt.Errorf("invalid value %s for cpuset cpus", cpu.Cpus)
|
||||
}
|
||||
if !cpusAvailable {
|
||||
return warnings, fmt.Errorf("requested CPUs are not available - requested %s, available: %s", cpu.Cpus, sysInfo.Cpus)
|
||||
}
|
||||
|
||||
memsAvailable, err := sysInfo.IsCpusetMemsAvailable(cpu.Mems)
|
||||
if err != nil {
|
||||
return warnings, fmt.Errorf("invalid value %s for cpuset mems", cpu.Mems)
|
||||
}
|
||||
if !memsAvailable {
|
||||
return warnings, fmt.Errorf("requested memory nodes are not available - requested %s, available: %s", cpu.Mems, sysInfo.Mems)
|
||||
}
|
||||
}
|
||||
|
||||
// Blkio checks
|
||||
if s.ResourceLimits.BlockIO != nil {
|
||||
blkio := s.ResourceLimits.BlockIO
|
||||
if blkio.Weight != nil && !sysInfo.BlkioWeight {
|
||||
warnings = append(warnings, "Your kernel does not support Block I/O weight or the cgroup is not mounted. Weight discarded.")
|
||||
blkio.Weight = nil
|
||||
}
|
||||
if blkio.Weight != nil && (*blkio.Weight > 1000 || *blkio.Weight < 10) {
|
||||
return warnings, errors.New("range of blkio weight is from 10 to 1000")
|
||||
}
|
||||
if len(blkio.WeightDevice) > 0 && !sysInfo.BlkioWeightDevice {
|
||||
warnings = append(warnings, "Your kernel does not support Block I/O weight_device or the cgroup is not mounted. Weight-device discarded.")
|
||||
blkio.WeightDevice = nil
|
||||
}
|
||||
if len(blkio.ThrottleReadBpsDevice) > 0 && !sysInfo.BlkioReadBpsDevice {
|
||||
warnings = append(warnings, "Your kernel does not support BPS Block I/O read limit or the cgroup is not mounted. Block I/O BPS read limit discarded")
|
||||
blkio.ThrottleReadBpsDevice = nil
|
||||
}
|
||||
if len(blkio.ThrottleWriteBpsDevice) > 0 && !sysInfo.BlkioWriteBpsDevice {
|
||||
warnings = append(warnings, "Your kernel does not support BPS Block I/O write limit or the cgroup is not mounted. Block I/O BPS write limit discarded.")
|
||||
blkio.ThrottleWriteBpsDevice = nil
|
||||
}
|
||||
if len(blkio.ThrottleReadIOPSDevice) > 0 && !sysInfo.BlkioReadIOpsDevice {
|
||||
warnings = append(warnings, "Your kernel does not support IOPS Block read limit or the cgroup is not mounted. Block I/O IOPS read limit discarded.")
|
||||
blkio.ThrottleReadIOPSDevice = nil
|
||||
}
|
||||
if len(blkio.ThrottleWriteIOPSDevice) > 0 && !sysInfo.BlkioWriteIOpsDevice {
|
||||
warnings = append(warnings, "Your kernel does not support IOPS Block I/O write limit or the cgroup is not mounted. Block I/O IOPS write limit discarded.")
|
||||
blkio.ThrottleWriteIOPSDevice = nil
|
||||
}
|
||||
}
|
||||
|
||||
return warnings, nil
|
||||
}
|
||||
|
||||
// Verify resource limits are sanely set when running on cgroup v2.
|
||||
func verifyContainerResourcesCgroupV2(s *specgen.SpecGenerator) ([]string, error) {
|
||||
// Verify resource limits are sanely set, removing any limits that are not
|
||||
// possible with the current cgroups config.
|
||||
func verifyContainerResources(s *specgen.SpecGenerator) ([]string, error) {
|
||||
warnings := []string{}
|
||||
|
||||
if s.ResourceLimits == nil {
|
||||
@@ -221,16 +65,3 @@ func verifyContainerResourcesCgroupV2(s *specgen.SpecGenerator) ([]string, error
|
||||
}
|
||||
return warnings, nil
|
||||
}
|
||||
|
||||
// Verify resource limits are sanely set, removing any limits that are not
|
||||
// possible with the current cgroups config.
|
||||
func verifyContainerResources(s *specgen.SpecGenerator) ([]string, error) {
|
||||
cgroup2, err := cgroups.IsCgroup2UnifiedMode()
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
if cgroup2 {
|
||||
return verifyContainerResourcesCgroupV2(s)
|
||||
}
|
||||
return verifyContainerResourcesCgroupV1(s)
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/opencontainers/runtime-tools/generate"
|
||||
"go.podman.io/common/libnetwork/types"
|
||||
"go.podman.io/common/pkg/cgroups"
|
||||
"go.podman.io/common/pkg/config"
|
||||
"go.podman.io/storage/pkg/fileutils"
|
||||
"go.podman.io/storage/pkg/unshare"
|
||||
@@ -262,26 +261,14 @@ func ParseNamespace(ns string) (Namespace, error) {
|
||||
// ParseCgroupNamespace parses a cgroup namespace specification in string
|
||||
// form.
|
||||
func ParseCgroupNamespace(ns string) (Namespace, error) {
|
||||
toReturn := Namespace{}
|
||||
// Cgroup is host for v1, private for v2.
|
||||
// We can't trust c/common for this, as it only assumes private.
|
||||
cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
|
||||
if err != nil {
|
||||
return toReturn, err
|
||||
switch ns {
|
||||
case "host":
|
||||
return Namespace{NSMode: Host}, nil
|
||||
case "private", "":
|
||||
return Namespace{NSMode: Private}, nil
|
||||
default:
|
||||
return Namespace{}, fmt.Errorf("unrecognized cgroup namespace mode %s passed", ns)
|
||||
}
|
||||
if cgroupsv2 {
|
||||
switch ns {
|
||||
case "host":
|
||||
toReturn.NSMode = Host
|
||||
case "private", "":
|
||||
toReturn.NSMode = Private
|
||||
default:
|
||||
return toReturn, fmt.Errorf("unrecognized cgroup namespace mode %s passed", ns)
|
||||
}
|
||||
} else {
|
||||
toReturn.NSMode = Host
|
||||
}
|
||||
return toReturn, nil
|
||||
}
|
||||
|
||||
// ParseIPCNamespace parses an ipc namespace specification in string
|
||||
|
||||
@@ -15,6 +15,12 @@ discover:
|
||||
execute:
|
||||
how: tmt
|
||||
|
||||
prepare:
|
||||
when: initiator == packit
|
||||
how: shell
|
||||
script: bash $TMT_TREE/contrib/packit-tmt/podman-next-setup.sh
|
||||
order: 20
|
||||
|
||||
# not relevant for testing podman
|
||||
environment:
|
||||
TEST_AUDIT_NO_SELINUX: 1
|
||||
|
||||
@@ -16,12 +16,7 @@ prepare:
|
||||
order: 10
|
||||
- when: initiator == packit
|
||||
how: shell
|
||||
script: |
|
||||
COPR_REPO_FILE="/etc/yum.repos.d/*podman-next*.repo"
|
||||
if compgen -G $COPR_REPO_FILE > /dev/null; then
|
||||
sed -i -n '/^priority=/!p;$apriority=1' $COPR_REPO_FILE
|
||||
fi
|
||||
dnf -y upgrade --allowerasing
|
||||
script: bash $TMT_TREE/contrib/packit-tmt/podman-next-setup.sh
|
||||
order: 20
|
||||
|
||||
adjust+:
|
||||
|
||||
@@ -97,7 +97,6 @@ var _ = Describe("Podman container cleanup", func() {
|
||||
})
|
||||
|
||||
It("podman cleanup paused container", func() {
|
||||
SkipIfRootlessCgroupsV1("Pause is not supported in cgroups v1")
|
||||
session := podmanTest.RunTopContainer("paused")
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
|
||||
@@ -38,7 +38,6 @@ import (
|
||||
. "github.com/onsi/gomega"
|
||||
. "github.com/onsi/gomega/gexec"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.podman.io/common/pkg/cgroups"
|
||||
"go.podman.io/common/pkg/libartifact"
|
||||
"go.podman.io/storage/pkg/ioutils"
|
||||
"go.podman.io/storage/pkg/lockfile"
|
||||
@@ -53,7 +52,6 @@ var (
|
||||
CGROUP_MANAGER = "systemd"
|
||||
RESTORE_IMAGES = []string{ALPINE, BB, NGINX_IMAGE}
|
||||
defaultWaitTimeout = 90
|
||||
CGROUPSV2, _ = cgroups.IsCgroup2UnifiedMode()
|
||||
)
|
||||
|
||||
// PodmanTestIntegration struct for command line options
|
||||
@@ -1080,13 +1078,6 @@ func SkipIfRunc(p *PodmanTestIntegration, reason string) {
|
||||
}
|
||||
}
|
||||
|
||||
func SkipIfRootlessCgroupsV1(reason string) {
|
||||
checkReason(reason)
|
||||
if isRootless() && !CGROUPSV2 {
|
||||
Skip("[rootless]: " + reason)
|
||||
}
|
||||
}
|
||||
|
||||
func SkipIfRootless(reason string) {
|
||||
checkReason(reason)
|
||||
if isRootless() {
|
||||
@@ -1179,24 +1170,6 @@ func isRootless() bool {
|
||||
return os.Geteuid() != 0
|
||||
}
|
||||
|
||||
func isCgroupsV1() bool {
|
||||
return !CGROUPSV2
|
||||
}
|
||||
|
||||
func SkipIfCgroupV1(reason string) {
|
||||
checkReason(reason)
|
||||
if isCgroupsV1() {
|
||||
Skip(reason)
|
||||
}
|
||||
}
|
||||
|
||||
func SkipIfCgroupV2(reason string) {
|
||||
checkReason(reason)
|
||||
if CGROUPSV2 {
|
||||
Skip(reason)
|
||||
}
|
||||
}
|
||||
|
||||
func isContainerized() bool {
|
||||
// This is set to "podman" by podman automatically
|
||||
return os.Getenv("container") != ""
|
||||
|
||||
@@ -15,7 +15,6 @@ var _ = Describe("Podman container clone", func() {
|
||||
})
|
||||
|
||||
It("podman container clone basic test", func() {
|
||||
SkipIfRootlessCgroupsV1("starting a container with the memory limits not supported")
|
||||
create := podmanTest.Podman([]string{"create", ALPINE})
|
||||
create.WaitWithDefaultTimeout()
|
||||
Expect(create).To(ExitCleanly())
|
||||
@@ -68,7 +67,6 @@ var _ = Describe("Podman container clone", func() {
|
||||
})
|
||||
|
||||
It("podman container clone resource limits override", func() {
|
||||
SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1")
|
||||
create := podmanTest.Podman([]string{"create", "--cpus=5", ALPINE})
|
||||
create.WaitWithDefaultTimeout()
|
||||
Expect(create).To(ExitCleanly())
|
||||
@@ -143,7 +141,6 @@ var _ = Describe("Podman container clone", func() {
|
||||
})
|
||||
|
||||
It("podman container clone in a pod", func() {
|
||||
SkipIfRootlessCgroupsV1("starting a container with the memory limits not supported")
|
||||
run := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:1234", ALPINE, "sleep", "20"})
|
||||
run.WaitWithDefaultTimeout()
|
||||
Expect(run).To(ExitCleanly())
|
||||
|
||||
@@ -30,7 +30,6 @@ var _ = Describe("Verify podman containers.conf usage", func() {
|
||||
})
|
||||
|
||||
It("limits test", func() {
|
||||
SkipIfRootlessCgroupsV1("Setting limits not supported on cgroupv1 for rootless users")
|
||||
// containers.conf is set to "nofile=500:500"
|
||||
session := podmanTest.Podman([]string{"run", "--rm", fedoraMinimal, "ulimit", "-n"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
@@ -56,7 +55,6 @@ var _ = Describe("Verify podman containers.conf usage", func() {
|
||||
})
|
||||
|
||||
It("oom-score-adj", func() {
|
||||
SkipIfRootlessCgroupsV1("Setting limits not supported on cgroupv1 for rootless users")
|
||||
// containers.conf is set to "oom_score_adj=999"
|
||||
session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "cat", "/proc/self/oom_score_adj"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
@@ -86,9 +84,6 @@ var _ = Describe("Verify podman containers.conf usage", func() {
|
||||
})
|
||||
|
||||
It("cgroup_conf in containers.conf", func() {
|
||||
if isCgroupsV1() {
|
||||
Skip("Setting cgroup_confs not supported on cgroupv1")
|
||||
}
|
||||
// FIXME: Needs crun-1.8.2-2 to allow this with --cgroup-manager=cgroupfs, once this is available remove the skip below.
|
||||
SkipIfRootless("--cgroup-manager=cgoupfs and --cgroup-conf not supported in rootless mode with crun")
|
||||
conffile := filepath.Join(podmanTest.TempDir, "container.conf")
|
||||
@@ -147,7 +142,6 @@ var _ = Describe("Verify podman containers.conf usage", func() {
|
||||
})
|
||||
|
||||
It("add capabilities", func() {
|
||||
SkipIfRootlessCgroupsV1("Not supported for rootless + CGroupsV1")
|
||||
cap := podmanTest.Podman([]string{"run", ALPINE, "grep", "CapEff", "/proc/self/status"})
|
||||
cap.WaitWithDefaultTimeout()
|
||||
Expect(cap).Should(ExitCleanly())
|
||||
@@ -193,7 +187,6 @@ var _ = Describe("Verify podman containers.conf usage", func() {
|
||||
})
|
||||
|
||||
verifyNSHandling := func(nspath, option string) {
|
||||
SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1")
|
||||
os.Setenv("CONTAINERS_CONF", "config/containers-ns.conf")
|
||||
if IsRemote() {
|
||||
podmanTest.RestartRemoteService()
|
||||
|
||||
@@ -72,7 +72,6 @@ var _ = Describe("Podman cp", func() {
|
||||
|
||||
// Copy a file to the container, then back to the host in --pid=host
|
||||
It("podman cp --pid=host file", func() {
|
||||
SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1")
|
||||
srcFile, err := os.CreateTemp("", "")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
defer srcFile.Close()
|
||||
|
||||
@@ -426,7 +426,6 @@ var _ = Describe("Podman create", func() {
|
||||
})
|
||||
|
||||
It("podman create with -m 1000000 sets swap to 2000000", func() {
|
||||
SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1")
|
||||
numMem := 1000000
|
||||
ctrName := "testCtr"
|
||||
session := podmanTest.Podman([]string{"create", "-t", "-m", fmt.Sprintf("%db", numMem), "--name", ctrName, ALPINE, "/bin/sh"})
|
||||
@@ -441,7 +440,6 @@ var _ = Describe("Podman create", func() {
|
||||
})
|
||||
|
||||
It("podman create --cpus 5 sets nanocpus", func() {
|
||||
SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1")
|
||||
numCpus := 5
|
||||
nanoCPUs := numCpus * 1000000000
|
||||
ctrName := "testCtr"
|
||||
|
||||
@@ -609,7 +609,6 @@ var _ = Describe("Podman kube generate", func() {
|
||||
})
|
||||
|
||||
It("on pod with memory limit", func() {
|
||||
SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1")
|
||||
podName := "testMemoryLimit"
|
||||
podSession := podmanTest.Podman([]string{"pod", "create", "--name", podName})
|
||||
podSession.WaitWithDefaultTimeout()
|
||||
@@ -635,7 +634,6 @@ var _ = Describe("Podman kube generate", func() {
|
||||
})
|
||||
|
||||
It("on pod with cpu limit", func() {
|
||||
SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1")
|
||||
podName := "testCpuLimit"
|
||||
podSession := podmanTest.Podman([]string{"pod", "create", "--name", podName})
|
||||
podSession.WaitWithDefaultTimeout()
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
. "github.com/containers/podman/v6/test/utils"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
. "github.com/onsi/gomega/gexec"
|
||||
)
|
||||
|
||||
var _ = Describe("Podman generate spec", func() {
|
||||
@@ -23,7 +22,6 @@ var _ = Describe("Podman generate spec", func() {
|
||||
})
|
||||
|
||||
It("podman generate spec basic usage", func() {
|
||||
SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1")
|
||||
session := podmanTest.Podman([]string{"create", "--cpus", "5", "--name", "specgen", ALPINE})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
@@ -34,7 +32,6 @@ var _ = Describe("Podman generate spec", func() {
|
||||
})
|
||||
|
||||
It("podman generate spec file", func() {
|
||||
SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1")
|
||||
session := podmanTest.Podman([]string{"create", "--cpus", "5", "--name", "specgen", ALPINE})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
@@ -58,12 +55,6 @@ var _ = Describe("Podman generate spec", func() {
|
||||
|
||||
session = podmanTest.Podman([]string{"generate", "spec", "--compact", "podspecgen"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
||||
if isRootless() && !CGROUPSV2 {
|
||||
Expect(session).Should(Exit(0))
|
||||
Expect(session.ErrorToString()).Should(ContainSubstring("Resource limits are not supported and ignored on cgroups V1 rootless"))
|
||||
} else {
|
||||
Expect(session).Should(ExitCleanly())
|
||||
}
|
||||
Expect(session).Should(ExitCleanly())
|
||||
})
|
||||
})
|
||||
|
||||
@@ -133,7 +133,6 @@ var _ = Describe("Podman Info", func() {
|
||||
|
||||
It("Podman info must contain cgroupControllers with RelevantControllers", func() {
|
||||
SkipIfRootless("Hard to tell which controllers are going to be enabled for rootless")
|
||||
SkipIfRootlessCgroupsV1("Disable cgroups not supported on cgroupv1 for rootless users")
|
||||
session := podmanTest.Podman([]string{"info", "--format", "{{.Host.CgroupControllers}}"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).To(ExitCleanly())
|
||||
|
||||
@@ -107,7 +107,6 @@ var _ = Describe("Podman kill", func() {
|
||||
})
|
||||
|
||||
It("podman kill paused container", func() {
|
||||
SkipIfRootlessCgroupsV1("pause is not supported for cgroupv1 rootless")
|
||||
ctrName := "testctr"
|
||||
session := podmanTest.RunTopContainer(ctrName)
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
||||
@@ -49,7 +49,6 @@ var _ = Describe("Podman network connect and disconnect", func() {
|
||||
})
|
||||
|
||||
It("podman network disconnect", func() {
|
||||
SkipIfRootlessCgroupsV1("stats not supported under rootless CgroupsV1")
|
||||
netName := "aliasTest" + stringid.GenerateRandomID()
|
||||
session := podmanTest.Podman([]string{"network", "create", netName})
|
||||
session.WaitWithDefaultTimeout()
|
||||
@@ -170,7 +169,6 @@ var _ = Describe("Podman network connect and disconnect", func() {
|
||||
})
|
||||
|
||||
It("podman network connect", func() {
|
||||
SkipIfRootlessCgroupsV1("stats not supported under rootless CgroupsV1")
|
||||
netName := "aliasTest" + stringid.GenerateRandomID()
|
||||
session := podmanTest.Podman([]string{"network", "create", netName})
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
||||
@@ -18,19 +18,15 @@ var _ = Describe("Podman pause", func() {
|
||||
createdState := "created"
|
||||
|
||||
BeforeEach(func() {
|
||||
SkipIfRootlessCgroupsV1("Pause is not supported in cgroups v1")
|
||||
b, err := os.ReadFile("/proc/self/cgroup")
|
||||
if err != nil {
|
||||
Skip("cannot read self cgroup")
|
||||
}
|
||||
|
||||
if CGROUPSV2 {
|
||||
b, err := os.ReadFile("/proc/self/cgroup")
|
||||
if err != nil {
|
||||
Skip("cannot read self cgroup")
|
||||
}
|
||||
|
||||
path := filepath.Join("/sys/fs/cgroup", strings.TrimSuffix(strings.Replace(string(b), "0::", "", 1), "\n"), "cgroup.freeze")
|
||||
_, err = os.Stat(path)
|
||||
if err != nil {
|
||||
Skip("freezer controller not available on the current kernel")
|
||||
}
|
||||
path := filepath.Join("/sys/fs/cgroup", strings.TrimSuffix(strings.Replace(string(b), "0::", "", 1), "\n"), "cgroup.freeze")
|
||||
_, err = os.Stat(path)
|
||||
if err != nil {
|
||||
Skip("freezer controller not available on the current kernel")
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -1192,8 +1192,6 @@ ENTRYPOINT ["sleep","99999"]
|
||||
})
|
||||
|
||||
It("podman pod create --share-parent test", func() {
|
||||
SkipIfRootlessCgroupsV1("rootless cannot use cgroups with cgroupsv1")
|
||||
SkipIfCgroupV1("CgroupMode shows 'host' on CGv1, not CID (issue 15013, wontfix")
|
||||
podCreate := podmanTest.Podman([]string{"pod", "create", "--share-parent=false"})
|
||||
podCreate.WaitWithDefaultTimeout()
|
||||
Expect(podCreate).Should(ExitCleanly())
|
||||
|
||||
@@ -225,7 +225,6 @@ var _ = Describe("Podman pod create", func() {
|
||||
})
|
||||
|
||||
It("podman pod container can override pod pid NS", func() {
|
||||
SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1")
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--share", "pid"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
|
||||
@@ -107,7 +107,6 @@ var _ = Describe("Podman pod kill", func() {
|
||||
})
|
||||
|
||||
It("podman pod kill all", func() {
|
||||
SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1")
|
||||
_, ec, podid := podmanTest.CreatePod(nil)
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
|
||||
@@ -11,10 +11,6 @@ import (
|
||||
var _ = Describe("Podman pod pause", func() {
|
||||
pausedState := "Paused"
|
||||
|
||||
BeforeEach(func() {
|
||||
SkipIfRootlessCgroupsV1("Pause is not supported in cgroups v1")
|
||||
})
|
||||
|
||||
It("podman pod pause bogus pod", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "pause", "foobar"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
||||
@@ -155,7 +155,6 @@ var _ = Describe("Podman ps", func() {
|
||||
})
|
||||
|
||||
It("podman pod ps --ctr-names", func() {
|
||||
SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1")
|
||||
_, ec, podid := podmanTest.CreatePod(nil)
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
|
||||
@@ -9,13 +9,6 @@ import (
|
||||
)
|
||||
|
||||
var _ = Describe("Podman pod stats", func() {
|
||||
BeforeEach(func() {
|
||||
SkipIfRootlessCgroupsV1("Tests fail with both CGv1 + required --cgroup-manager=cgroupfs")
|
||||
if isContainerized() {
|
||||
SkipIfCgroupV1("All tests fail Error: unable to load cgroup at ...: cgroup deleted")
|
||||
}
|
||||
})
|
||||
|
||||
It("podman pod stats should run with no pods", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "stats", "--no-stream"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
||||
@@ -16,10 +16,6 @@ import (
|
||||
const cgroupRoot = "/sys/fs/cgroup"
|
||||
|
||||
var _ = Describe("Podman run with --cgroup-parent", func() {
|
||||
BeforeEach(func() {
|
||||
SkipIfRootlessCgroupsV1("cgroup parent is not supported in cgroups v1")
|
||||
})
|
||||
|
||||
Specify("valid --cgroup-parent using cgroupfs", func() {
|
||||
if !Containerized() {
|
||||
Skip("Must be containerized to run this test.")
|
||||
@@ -47,7 +43,6 @@ var _ = Describe("Podman run with --cgroup-parent", func() {
|
||||
})
|
||||
|
||||
Specify("always honor --cgroup-parent", func() {
|
||||
SkipIfCgroupV1("test not supported in cgroups v1")
|
||||
if Containerized() || podmanTest.CgroupManager == "cgroupfs" {
|
||||
Skip("Requires Systemd cgroup manager support")
|
||||
}
|
||||
|
||||
@@ -13,95 +13,49 @@ import (
|
||||
|
||||
var _ = Describe("Podman run cpu", func() {
|
||||
BeforeEach(func() {
|
||||
SkipIfRootlessCgroupsV1("Setting CPU not supported on cgroupv1 for rootless users")
|
||||
|
||||
if CGROUPSV2 {
|
||||
if err := os.WriteFile("/sys/fs/cgroup/cgroup.subtree_control", []byte("+cpuset"), 0o644); err != nil {
|
||||
Skip("cpuset controller not available on the current kernel")
|
||||
}
|
||||
if err := os.WriteFile("/sys/fs/cgroup/cgroup.subtree_control", []byte("+cpuset"), 0o644); err != nil {
|
||||
Skip("cpuset controller not available on the current kernel")
|
||||
}
|
||||
})
|
||||
|
||||
It("podman run cpu-period", func() {
|
||||
var result *PodmanSessionIntegration
|
||||
if CGROUPSV2 {
|
||||
result = podmanTest.Podman([]string{"run", "--rm", "--cpu-period=5000", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpu.max"})
|
||||
} else {
|
||||
result = podmanTest.Podman([]string{"run", "--rm", "--cpu-period=5000", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.cfs_period_us"})
|
||||
}
|
||||
result := podmanTest.Podman([]string{"run", "--rm", "--cpu-period=5000", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpu.max"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result).Should(ExitCleanly())
|
||||
Expect(result.OutputToString()).To(ContainSubstring("5000"))
|
||||
})
|
||||
|
||||
It("podman run cpu-quota", func() {
|
||||
var result *PodmanSessionIntegration
|
||||
|
||||
if CGROUPSV2 {
|
||||
result = podmanTest.Podman([]string{"run", "--rm", "--cpu-quota=5000", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpu.max"})
|
||||
} else {
|
||||
result = podmanTest.Podman([]string{"run", "--rm", "--cpu-quota=5000", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.cfs_quota_us"})
|
||||
}
|
||||
result := podmanTest.Podman([]string{"run", "--rm", "--cpu-quota=5000", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpu.max"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result).Should(ExitCleanly())
|
||||
Expect(result.OutputToString()).To(ContainSubstring("5000"))
|
||||
})
|
||||
|
||||
It("podman run cpus", func() {
|
||||
if CGROUPSV2 {
|
||||
result := podmanTest.Podman([]string{"run", "--rm", "--cpu-quota=5000", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpu.max"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result).Should(ExitCleanly())
|
||||
Expect(result.OutputToString()).To(Equal("5000 100000"))
|
||||
} else {
|
||||
result := podmanTest.Podman([]string{"run", "--rm", "--cpus=0.5", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.cfs_period_us"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result).Should(ExitCleanly())
|
||||
Expect(result.OutputToString()).To(Equal("100000"))
|
||||
|
||||
result = podmanTest.Podman([]string{"run", "--rm", "--cpus=0.5", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.cfs_quota_us"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result).Should(ExitCleanly())
|
||||
Expect(result.OutputToString()).To(Equal("50000"))
|
||||
}
|
||||
result := podmanTest.Podman([]string{"run", "--rm", "--cpu-quota=5000", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpu.max"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result).Should(ExitCleanly())
|
||||
Expect(result.OutputToString()).To(Equal("5000 100000"))
|
||||
})
|
||||
|
||||
It("podman run cpu-shares", func() {
|
||||
if CGROUPSV2 {
|
||||
// [2-262144] is mapped to [1-10000]
|
||||
result := podmanTest.Podman([]string{"run", "--rm", "--cpu-shares=262144", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpu.weight"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result).Should(ExitCleanly())
|
||||
Expect(result.OutputToString()).To(Equal("10000"))
|
||||
} else {
|
||||
result := podmanTest.Podman([]string{"run", "--rm", "-c", "2", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.shares"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result).Should(ExitCleanly())
|
||||
Expect(result.OutputToString()).To(Equal("2"))
|
||||
}
|
||||
// [2-262144] is mapped to [1-10000]
|
||||
result := podmanTest.Podman([]string{"run", "--rm", "--cpu-shares=262144", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpu.weight"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result).Should(ExitCleanly())
|
||||
Expect(result.OutputToString()).To(Equal("10000"))
|
||||
})
|
||||
|
||||
It("podman run cpuset-cpus", func() {
|
||||
var result *PodmanSessionIntegration
|
||||
|
||||
if CGROUPSV2 {
|
||||
result = podmanTest.Podman([]string{"run", "--rm", "--cpuset-cpus=0", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpuset.cpus.effective"})
|
||||
} else {
|
||||
result = podmanTest.Podman([]string{"run", "--rm", "--cpuset-cpus=0", ALPINE, "cat", "/sys/fs/cgroup/cpuset/cpuset.cpus"})
|
||||
}
|
||||
result := podmanTest.Podman([]string{"run", "--rm", "--cpuset-cpus=0", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpuset.cpus.effective"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result).Should(ExitCleanly())
|
||||
Expect(result.OutputToString()).To(Equal("0"))
|
||||
})
|
||||
|
||||
It("podman run cpuset-mems", func() {
|
||||
var result *PodmanSessionIntegration
|
||||
|
||||
if CGROUPSV2 {
|
||||
result = podmanTest.Podman([]string{"run", "--rm", "--cpuset-mems=0", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpuset.mems.effective"})
|
||||
} else {
|
||||
result = podmanTest.Podman([]string{"run", "--rm", "--cpuset-mems=0", ALPINE, "cat", "/sys/fs/cgroup/cpuset/cpuset.mems"})
|
||||
}
|
||||
result := podmanTest.Podman([]string{"run", "--rm", "--cpuset-mems=0", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpuset.mems.effective"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result).Should(ExitCleanly())
|
||||
Expect(result.OutputToString()).To(Equal("0"))
|
||||
@@ -120,7 +74,6 @@ var _ = Describe("Podman run cpu", func() {
|
||||
})
|
||||
|
||||
It("podman run invalid cpu-rt-period with cgroupsv2", func() {
|
||||
SkipIfCgroupV1("testing options that only work in cgroup v2")
|
||||
result := podmanTest.Podman([]string{"run", "--rm", "--cpu-rt-period=5000", ALPINE, "ls"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result).Should(Exit(0))
|
||||
@@ -128,7 +81,6 @@ var _ = Describe("Podman run cpu", func() {
|
||||
})
|
||||
|
||||
It("podman run invalid cpu-rt-runtime with cgroupsv2", func() {
|
||||
SkipIfCgroupV1("testing options that only work in cgroup v2")
|
||||
result := podmanTest.Podman([]string{"run", "--rm", "--cpu-rt-runtime=5000", ALPINE, "ls"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result).Should(Exit(0))
|
||||
|
||||
@@ -3,40 +3,21 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
. "github.com/containers/podman/v6/test/utils"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Podman run memory", func() {
|
||||
BeforeEach(func() {
|
||||
SkipIfRootlessCgroupsV1("Setting Memory not supported on cgroupv1 for rootless users")
|
||||
})
|
||||
|
||||
It("podman run memory test", func() {
|
||||
var session *PodmanSessionIntegration
|
||||
|
||||
if CGROUPSV2 {
|
||||
session = podmanTest.Podman([]string{"run", "--memory=40m", "--net=none", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/memory.max"})
|
||||
} else {
|
||||
session = podmanTest.Podman([]string{"run", "--memory=40m", ALPINE, "cat", "/sys/fs/cgroup/memory/memory.limit_in_bytes"})
|
||||
}
|
||||
session := podmanTest.Podman([]string{"run", "--memory=40m", "--net=none", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/memory.max"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
Expect(session.OutputToString()).To(Equal("41943040"))
|
||||
})
|
||||
|
||||
It("podman run memory-reservation test", func() {
|
||||
var session *PodmanSessionIntegration
|
||||
|
||||
if CGROUPSV2 {
|
||||
session = podmanTest.Podman([]string{"run", "--memory-reservation=40m", "--net=none", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/memory.low"})
|
||||
} else {
|
||||
session = podmanTest.Podman([]string{"run", "--memory-reservation=40m", ALPINE, "cat", "/sys/fs/cgroup/memory/memory.soft_limit_in_bytes"})
|
||||
}
|
||||
|
||||
session := podmanTest.Podman([]string{"run", "--memory-reservation=40m", "--net=none", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/memory.low"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
Expect(session.OutputToString()).To(Equal("41943040"))
|
||||
@@ -48,29 +29,13 @@ var _ = Describe("Podman run memory", func() {
|
||||
expect string
|
||||
)
|
||||
|
||||
if CGROUPSV2 {
|
||||
session = podmanTest.Podman([]string{"run", "--memory=20m", "--memory-swap=30M", "--net=none", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/memory.swap.max"})
|
||||
expect = "10485760"
|
||||
} else {
|
||||
session = podmanTest.Podman([]string{"run", "--memory=20m", "--memory-swap=30M", ALPINE, "cat", "/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes"})
|
||||
expect = "31457280"
|
||||
}
|
||||
session = podmanTest.Podman([]string{"run", "--memory=20m", "--memory-swap=30M", "--net=none", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/memory.swap.max"})
|
||||
expect = "10485760"
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
Expect(session.OutputToString()).To(Equal(expect))
|
||||
})
|
||||
|
||||
for _, limit := range []string{"0", "15", "100"} {
|
||||
testName := fmt.Sprintf("podman run memory-swappiness test(%s)", limit)
|
||||
It(testName, func() {
|
||||
SkipIfCgroupV2("memory-swappiness not supported on cgroupV2")
|
||||
session := podmanTest.Podman([]string{"run", fmt.Sprintf("--memory-swappiness=%s", limit), ALPINE, "cat", "/sys/fs/cgroup/memory/memory.swappiness"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
Expect(session.OutputToString()).To(Equal(limit))
|
||||
})
|
||||
}
|
||||
|
||||
It("podman run memory test on oomkilled container", func() {
|
||||
mem := SystemExec("cat", []string{"/proc/sys/vm/overcommit_memory"})
|
||||
mem.WaitWithDefaultTimeout()
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
|
||||
var _ = Describe("Podman run ns", func() {
|
||||
It("podman run pidns test", func() {
|
||||
SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1")
|
||||
session := podmanTest.Podman([]string{"run", fedoraMinimal, "bash", "-c", "echo $$"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
@@ -92,7 +91,6 @@ var _ = Describe("Podman run ns", func() {
|
||||
})
|
||||
|
||||
It("podman run --ipc=host --pid=host", func() {
|
||||
SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1")
|
||||
cmd := exec.Command("ls", "-l", "/proc/self/ns/pid")
|
||||
res, err := cmd.Output()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
@@ -239,7 +239,6 @@ var _ = Describe("Podman run", func() {
|
||||
})
|
||||
|
||||
It("podman test --pid=host", func() {
|
||||
SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1")
|
||||
session := podmanTest.Podman([]string{"run", "--pid=host", ALPINE, "cat", "/proc/self/attr/current"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -523,7 +525,6 @@ var _ = Describe("Podman run", func() {
|
||||
})
|
||||
|
||||
It("podman run security-opt unmask on /sys/fs/cgroup", func() {
|
||||
SkipIfCgroupV1("podman umask on /sys/fs/cgroup will fail with cgroups V1")
|
||||
SkipIfRootless("/sys/fs/cgroup rw access is needed")
|
||||
rwOnCgroups := "/sys/fs/cgroup cgroup2 rw"
|
||||
session := podmanTest.Podman([]string{"run", "--security-opt", "unmask=ALL", "--security-opt", "mask=/sys/fs/cgroup", ALPINE, "cat", "/proc/mounts"})
|
||||
@@ -734,8 +735,6 @@ USER bin`, BB)
|
||||
})
|
||||
|
||||
It("podman run limits test", func() {
|
||||
SkipIfRootlessCgroupsV1("Setting limits not supported on cgroupv1 for rootless users")
|
||||
|
||||
if !isRootless() {
|
||||
session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "rtprio=99", "--cap-add=sys_nice", fedoraMinimal, "cat", "/proc/self/sched"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
@@ -752,13 +751,6 @@ USER bin`, BB)
|
||||
Expect(session).Should(ExitCleanly())
|
||||
Expect(session.OutputToString()).To(ContainSubstring("1024"))
|
||||
|
||||
if !CGROUPSV2 {
|
||||
// --oom-kill-disable not supported on cgroups v2.
|
||||
session = podmanTest.Podman([]string{"run", "--rm", "--oom-kill-disable=true", fedoraMinimal, "echo", "memory-hog"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
}
|
||||
|
||||
session = podmanTest.Podman([]string{"run", "--rm", "--oom-score-adj=999", fedoraMinimal, "cat", "/proc/self/oom_score_adj"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
@@ -833,106 +825,60 @@ USER bin`, BB)
|
||||
})
|
||||
|
||||
It("podman run blkio-weight test", func() {
|
||||
SkipIfRootlessCgroupsV1("Setting blkio-weight not supported on cgroupv1 for rootless users")
|
||||
SkipIfRootless("By default systemd doesn't delegate io to rootless users")
|
||||
if CGROUPSV2 {
|
||||
if _, err := os.Stat("/sys/fs/cgroup/io.stat"); os.IsNotExist(err) {
|
||||
Skip("Kernel does not have io.stat")
|
||||
}
|
||||
if _, err := os.Stat("/sys/fs/cgroup/system.slice/io.bfq.weight"); os.IsNotExist(err) {
|
||||
Skip("Kernel does not support BFQ IO scheduler")
|
||||
}
|
||||
session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/io.bfq.weight"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
// there was a documentation issue in the kernel that reported a different range [1-10000] for the io controller.
|
||||
// older versions of crun/runc used it. For the time being allow both versions to pass the test.
|
||||
// FIXME: drop "|51" once all the runtimes we test have the fix in place.
|
||||
Expect(strings.Replace(session.OutputToString(), "default ", "", 1)).To(MatchRegexp("15|51"))
|
||||
} else {
|
||||
if _, err := os.Stat("/sys/fs/cgroup/blkio/blkio.weight"); os.IsNotExist(err) {
|
||||
Skip("Kernel does not support blkio.weight")
|
||||
}
|
||||
session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.weight"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
Expect(session.OutputToString()).To(ContainSubstring("15"))
|
||||
if _, err := os.Stat("/sys/fs/cgroup/io.stat"); errors.Is(err, fs.ErrNotExist) {
|
||||
Skip("Kernel does not have io.stat")
|
||||
}
|
||||
if _, err := os.Stat("/sys/fs/cgroup/system.slice/io.bfq.weight"); errors.Is(err, fs.ErrNotExist) {
|
||||
Skip("Kernel does not support BFQ IO scheduler")
|
||||
}
|
||||
session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/io.bfq.weight"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
// there was a documentation issue in the kernel that reported a different range [1-10000] for the io controller.
|
||||
// older versions of crun/runc used it. For the time being allow both versions to pass the test.
|
||||
// FIXME: drop "|51" once all the runtimes we test have the fix in place.
|
||||
Expect(strings.Replace(session.OutputToString(), "default ", "", 1)).To(MatchRegexp("15|51"))
|
||||
})
|
||||
|
||||
It("podman run device-read-bps test", func() {
|
||||
SkipIfRootless("Setting device-read-bps not supported for rootless users")
|
||||
skipWithoutDevNullb0()
|
||||
|
||||
var session *PodmanSessionIntegration
|
||||
|
||||
if CGROUPSV2 {
|
||||
session = podmanTest.Podman([]string{"run", "--rm", "--device-read-bps=/dev/nullb0:1mb", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
|
||||
} else {
|
||||
session = podmanTest.Podman([]string{"run", "--rm", "--device-read-bps=/dev/nullb0:1mb", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_bps_device"})
|
||||
}
|
||||
|
||||
session := podmanTest.Podman([]string{"run", "--rm", "--device-read-bps=/dev/nullb0:1mb", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
|
||||
Expect(session.OutputToString()).To(ContainSubstring("1048576"))
|
||||
}
|
||||
// FIXME: https://github.com/containers/podman/commit/9b9789c207d8b84ee37e9c37c613879369a8690c
|
||||
})
|
||||
|
||||
It("podman run device-write-bps test", func() {
|
||||
SkipIfRootless("Setting device-write-bps not supported for rootless users")
|
||||
skipWithoutDevNullb0()
|
||||
|
||||
var session *PodmanSessionIntegration
|
||||
|
||||
if CGROUPSV2 {
|
||||
session = podmanTest.Podman([]string{"run", "--rm", "--device-write-bps=/dev/nullb0:1mb", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
|
||||
} else {
|
||||
session = podmanTest.Podman([]string{"run", "--rm", "--device-write-bps=/dev/nullb0:1mb", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.write_bps_device"})
|
||||
}
|
||||
session := podmanTest.Podman([]string{"run", "--rm", "--device-write-bps=/dev/nullb0:1mb", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
|
||||
Expect(session.OutputToString()).To(ContainSubstring("1048576"))
|
||||
}
|
||||
// FIXME: https://github.com/containers/podman/commit/9b9789c207d8b84ee37e9c37c613879369a8690c
|
||||
})
|
||||
|
||||
It("podman run device-read-iops test", func() {
|
||||
SkipIfRootless("Setting device-read-iops not supported for rootless users")
|
||||
skipWithoutDevNullb0()
|
||||
|
||||
var session *PodmanSessionIntegration
|
||||
|
||||
if CGROUPSV2 {
|
||||
session = podmanTest.Podman([]string{"run", "--rm", "--device-read-iops=/dev/nullb0:100", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
|
||||
} else {
|
||||
session = podmanTest.Podman([]string{"run", "--rm", "--device-read-iops=/dev/nullb0:100", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_iops_device"})
|
||||
}
|
||||
|
||||
session := podmanTest.Podman([]string{"run", "--rm", "--device-read-iops=/dev/nullb0:100", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
|
||||
Expect(session.OutputToString()).To(ContainSubstring("100"))
|
||||
}
|
||||
// FIXME: https://github.com/containers/podman/commit/9b9789c207d8b84ee37e9c37c613879369a8690c
|
||||
})
|
||||
|
||||
It("podman run device-write-iops test", func() {
|
||||
SkipIfRootless("Setting device-write-iops not supported for rootless users")
|
||||
skipWithoutDevNullb0()
|
||||
|
||||
var session *PodmanSessionIntegration
|
||||
|
||||
if CGROUPSV2 {
|
||||
session = podmanTest.Podman([]string{"run", "--rm", "--device-write-iops=/dev/nullb0:100", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
|
||||
} else {
|
||||
session = podmanTest.Podman([]string{"run", "--rm", "--device-write-iops=/dev/nullb0:100", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.write_iops_device"})
|
||||
}
|
||||
|
||||
session := podmanTest.Podman([]string{"run", "--rm", "--device-write-iops=/dev/nullb0:100", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
|
||||
Expect(session.OutputToString()).To(ContainSubstring("100"))
|
||||
}
|
||||
// FIXME: https://github.com/containers/podman/commit/9b9789c207d8b84ee37e9c37c613879369a8690c
|
||||
})
|
||||
|
||||
It("podman run notify_socket", func() {
|
||||
@@ -1734,7 +1680,6 @@ VOLUME %s`, ALPINE, volPath, volPath)
|
||||
|
||||
It("podman run with cgroups=split", func() {
|
||||
SkipIfNotSystemd(podmanTest.CgroupManager, "do not test --cgroups=split if not running on systemd")
|
||||
SkipIfRootlessCgroupsV1("Disable cgroups not supported on cgroupv1 for rootless users")
|
||||
SkipIfRemote("--cgroups=split cannot be used in remote mode")
|
||||
|
||||
checkLines := func(lines []string) {
|
||||
@@ -1744,14 +1689,6 @@ VOLUME %s`, ALPINE, volPath, volPath)
|
||||
if len(parts) < 2 {
|
||||
continue
|
||||
}
|
||||
if !CGROUPSV2 {
|
||||
// ignore unified on cgroup v1.
|
||||
// both runc and crun do not set it.
|
||||
// crun does not set named hierarchies.
|
||||
if parts[1] == "" || strings.Contains(parts[1], "name=") {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if parts[2] == "/" {
|
||||
continue
|
||||
}
|
||||
@@ -1788,7 +1725,6 @@ VOLUME %s`, ALPINE, volPath, volPath)
|
||||
})
|
||||
|
||||
It("podman run with cgroups=disabled runs without cgroups", func() {
|
||||
SkipIfRootlessCgroupsV1("Disable cgroups not supported on cgroupv1 for rootless users")
|
||||
// Only works on crun
|
||||
if !strings.Contains(podmanTest.OCIRuntime, "crun") {
|
||||
Skip("Test only works on crun")
|
||||
@@ -1822,7 +1758,6 @@ VOLUME %s`, ALPINE, volPath, volPath)
|
||||
})
|
||||
|
||||
It("podman run with cgroups=enabled makes cgroups", func() {
|
||||
SkipIfRootlessCgroupsV1("Enable cgroups not supported on cgroupv1 for rootless users")
|
||||
// Only works on crun
|
||||
if !strings.Contains(podmanTest.OCIRuntime, "crun") {
|
||||
Skip("Test only works on crun")
|
||||
@@ -1970,7 +1905,6 @@ VOLUME %s`, ALPINE, volPath, volPath)
|
||||
})
|
||||
|
||||
It("podman run verify pids-limit", func() {
|
||||
SkipIfCgroupV1("pids-limit not supported on cgroup V1")
|
||||
limit := "4321"
|
||||
session := podmanTest.Podman([]string{"run", "--pids-limit", limit, "--net=none", "--rm", ALPINE, "cat", "/sys/fs/cgroup/pids.max"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
||||
@@ -15,13 +15,6 @@ import (
|
||||
// TODO: we need to check the output. Currently, we only check the exit codes
|
||||
// which is not enough.
|
||||
var _ = Describe("Podman stats", func() {
|
||||
BeforeEach(func() {
|
||||
SkipIfRootlessCgroupsV1("stats not supported on cgroupv1 for rootless users")
|
||||
if isContainerized() {
|
||||
SkipIfCgroupV1("stats not supported inside cgroupv1 container environment")
|
||||
}
|
||||
})
|
||||
|
||||
It("podman stats with bogus container", func() {
|
||||
session := podmanTest.Podman([]string{"stats", "--no-stream", "123"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
||||
@@ -41,10 +41,6 @@ var _ = Describe("Podman systemd", func() {
|
||||
Expect(conData).To(HaveLen(1))
|
||||
Expect(conData[0].Config).To(HaveField("SystemdMode", true))
|
||||
|
||||
// stats not supported w/ CGv1 rootless or containerized
|
||||
if isCgroupsV1() && (isRootless() || isContainerized()) {
|
||||
return
|
||||
}
|
||||
stats := podmanTest.Podman([]string{"stats", "--no-stream", ctrName})
|
||||
stats.WaitWithDefaultTimeout()
|
||||
Expect(stats).Should(ExitCleanly())
|
||||
|
||||
@@ -109,7 +109,6 @@ var _ = Describe("Toolbox-specific testing", func() {
|
||||
if podmanTest.RemoteTest {
|
||||
Skip("Shm size check does not work with a remote client")
|
||||
}
|
||||
SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1")
|
||||
var session *PodmanSessionIntegration
|
||||
var cmd *exec.Cmd
|
||||
var hostShmSize, containerShmSize int
|
||||
|
||||
@@ -7,61 +7,11 @@ import (
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
. "github.com/onsi/gomega/gexec"
|
||||
"go.podman.io/common/pkg/cgroupv2"
|
||||
"go.podman.io/storage/pkg/fileutils"
|
||||
)
|
||||
|
||||
var _ = Describe("Podman update", func() {
|
||||
It("podman update container all options v1", func() {
|
||||
SkipIfCgroupV2("testing flags that only work in cgroup v1")
|
||||
SkipIfRootless("many of these handlers are not enabled while rootless in CI")
|
||||
session := podmanTest.Podman([]string{"run", "-dt", ALPINE})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
|
||||
ctrID := session.OutputToString()
|
||||
|
||||
commonArgs := []string{
|
||||
"update",
|
||||
"--cpus", "5",
|
||||
"--cpuset-cpus", "0",
|
||||
"--cpu-shares", "123",
|
||||
"--cpuset-mems", "0",
|
||||
"--memory", "1G",
|
||||
"--memory-swap", "2G",
|
||||
"--memory-reservation", "2G",
|
||||
"--memory-swappiness", "50",
|
||||
"--pids-limit", "123", ctrID,
|
||||
}
|
||||
|
||||
session = podmanTest.Podman(commonArgs)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
|
||||
// checking cpu quota from --cpus
|
||||
podmanTest.CheckFileInContainerSubstring(ctrID, "/sys/fs/cgroup/cpu/cpu.cfs_quota_us", "500000")
|
||||
|
||||
// checking cpuset-cpus
|
||||
podmanTest.CheckFileInContainer(ctrID, "/sys/fs/cgroup/cpuset/cpuset.cpus", "0")
|
||||
|
||||
// checking cpuset-mems
|
||||
podmanTest.CheckFileInContainer(ctrID, "/sys/fs/cgroup/cpuset/cpuset.mems", "0")
|
||||
|
||||
// checking memory limit
|
||||
podmanTest.CheckFileInContainerSubstring(ctrID, "/sys/fs/cgroup/memory/memory.limit_in_bytes", "1073741824")
|
||||
|
||||
// checking memory-swap
|
||||
podmanTest.CheckFileInContainerSubstring(ctrID, "/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes", "2147483648")
|
||||
|
||||
// checking cpu-shares
|
||||
podmanTest.CheckFileInContainerSubstring(ctrID, "/sys/fs/cgroup/cpu/cpu.shares", "123")
|
||||
|
||||
// checking pids-limit
|
||||
podmanTest.CheckFileInContainerSubstring(ctrID, "/sys/fs/cgroup/pids/pids.max", "123")
|
||||
})
|
||||
|
||||
It("podman update container unspecified pid limit", func() {
|
||||
SkipIfCgroupV1("testing flags that only work in cgroup v2")
|
||||
SkipIfRootless("many of these handlers are not enabled while rootless in CI")
|
||||
session := podmanTest.Podman([]string{"run", "-dt", "--pids-limit", "-1", ALPINE})
|
||||
session.WaitWithDefaultTimeout()
|
||||
@@ -86,7 +36,6 @@ var _ = Describe("Podman update", func() {
|
||||
})
|
||||
|
||||
It("podman update container all options v2", func() {
|
||||
SkipIfCgroupV1("testing flags that only work in cgroup v2")
|
||||
SkipIfRootless("many of these handlers are not enabled while rootless in CI")
|
||||
skipWithoutDevNullb0()
|
||||
session := podmanTest.Podman([]string{"run", "-dt", ALPINE})
|
||||
@@ -167,16 +116,10 @@ var _ = Describe("Podman update", func() {
|
||||
|
||||
ctrID := session.OutputToString()
|
||||
|
||||
path := "/sys/fs/cgroup/cpu/cpu.cfs_quota_us"
|
||||
if v2, _ := cgroupv2.Enabled(); v2 {
|
||||
path = "/sys/fs/cgroup/cpu.max"
|
||||
}
|
||||
|
||||
podmanTest.CheckFileInContainerSubstring(ctrID, path, "500000")
|
||||
podmanTest.CheckFileInContainerSubstring(ctrID, "/sys/fs/cgroup/cpu.max", "500000")
|
||||
})
|
||||
|
||||
It("podman update persists changes", func() {
|
||||
SkipIfCgroupV1("testing flags that only work in cgroup v2")
|
||||
SkipIfRootless("many of these handlers are not enabled while rootless in CI")
|
||||
|
||||
memoryInspect := ".HostConfig.Memory"
|
||||
|
||||
@@ -122,7 +122,6 @@ EOF
|
||||
|
||||
# bats test_tags=ci:parallel
|
||||
@test "podman run - uidmapping has no /sys/kernel mounts" {
|
||||
skip_if_cgroupsv1 "run --uidmap fails on cgroups v1 (issue 15025, wontfix)"
|
||||
skip_if_rootless "cannot umount as rootless"
|
||||
|
||||
run_podman run --rm --uidmap 0:100:10000 $IMAGE mount
|
||||
@@ -1081,7 +1080,6 @@ EOF
|
||||
# rhbz#1902979 : podman run fails to update /etc/hosts when --uidmap is provided
|
||||
# bats test_tags=ci:parallel
|
||||
@test "podman run update /etc/hosts" {
|
||||
skip_if_cgroupsv1 "run --uidmap fails on cgroups v1 (issue 15025, wontfix)"
|
||||
HOST=$(random_string 25)
|
||||
run_podman run --uidmap 0:10001:10002 --rm --hostname ${HOST} $IMAGE grep ${HOST} /etc/hosts
|
||||
is "${lines[0]}" ".*${HOST}.*"
|
||||
@@ -1451,21 +1449,13 @@ EOF
|
||||
|
||||
# bats test_tags=ci:parallel
|
||||
@test "podman run --net=host --cgroupns=host with read only cgroupfs" {
|
||||
skip_if_rootless_cgroupsv1
|
||||
# verify that the last /sys/fs/cgroup mount is read-only
|
||||
run_podman run --net=host --cgroupns=host --rm $IMAGE sh -c "grep ' / /sys/fs/cgroup ' /proc/self/mountinfo | tail -n 1"
|
||||
assert "$output" =~ "/sys/fs/cgroup ro"
|
||||
|
||||
if is_cgroupsv1; then
|
||||
# verify that the memory controller is mounted read-only
|
||||
run_podman run --net=host --cgroupns=host --rm $IMAGE cat /proc/self/mountinfo
|
||||
assert "$output" =~ "/sys/fs/cgroup/memory ro.* cgroup cgroup"
|
||||
else
|
||||
# verify that the last /sys/fs/cgroup mount is read-only
|
||||
run_podman run --net=host --cgroupns=host --rm $IMAGE sh -c "grep ' / /sys/fs/cgroup ' /proc/self/mountinfo | tail -n 1"
|
||||
assert "$output" =~ "/sys/fs/cgroup ro"
|
||||
|
||||
# verify that it works also with a cgroupns
|
||||
run_podman run --net=host --cgroupns=private --rm $IMAGE sh -c "grep ' / /sys/fs/cgroup ' /proc/self/mountinfo | tail -n 1"
|
||||
assert "$output" =~ "/sys/fs/cgroup ro"
|
||||
fi
|
||||
# verify that it works also with a cgroupns
|
||||
run_podman run --net=host --cgroupns=private --rm $IMAGE sh -c "grep ' / /sys/fs/cgroup ' /proc/self/mountinfo | tail -n 1"
|
||||
assert "$output" =~ "/sys/fs/cgroup ro"
|
||||
}
|
||||
|
||||
# bats test_tags=ci:parallel
|
||||
|
||||
@@ -33,7 +33,6 @@ function _require_crun() {
|
||||
|
||||
# bats test_tags=ci:parallel
|
||||
@test "podman --group-add without keep-groups while in a userns" {
|
||||
skip_if_cgroupsv1 "run --uidmap fails on cgroups v1 (issue 15025, wontfix)"
|
||||
skip_if_rootless "chroot is not allowed in rootless mode"
|
||||
skip_if_remote "--group-add keep-groups not supported in remote mode"
|
||||
run chroot --groups 1234,5678 / ${PODMAN} run --rm --uidmap 0:200000:5000 --group-add 457 $IMAGE id
|
||||
@@ -42,7 +41,6 @@ function _require_crun() {
|
||||
|
||||
# bats test_tags=ci:parallel
|
||||
@test "rootful pod with custom ID mapping" {
|
||||
skip_if_cgroupsv1 "run --uidmap fails on cgroups v1 (issue 15025, wontfix)"
|
||||
skip_if_rootless "does not work rootless - rootful feature"
|
||||
random_pod_name=p_$(safename)
|
||||
run_podman pod create --uidmap 0:200000:5000 --name=$random_pod_name
|
||||
|
||||
@@ -535,7 +535,6 @@ spec:
|
||||
@test "pod resource limits" {
|
||||
skip_if_remote "resource limits only implemented on non-remote"
|
||||
skip_if_rootless "resource limits only work with root"
|
||||
skip_if_cgroupsv1 "resource limits only meaningful on cgroups V2"
|
||||
|
||||
# create loopback device
|
||||
lofile=${PODMAN_TMPDIR}/disk.img
|
||||
@@ -762,7 +761,6 @@ function thingy_with_unique_id() {
|
||||
# bats test_tags=ci:parallel
|
||||
@test "podman pod cleans cgroup and keeps limits" {
|
||||
skip_if_remote "we cannot check cgroup settings"
|
||||
skip_if_rootless_cgroupsv1 "rootless cannot use cgroups on v1"
|
||||
|
||||
for infra in true false; do
|
||||
run_podman pod create --infra=$infra --memory=256M
|
||||
|
||||
@@ -316,13 +316,6 @@ LISTEN_FDNAMES=listen_fdnames" | sort)
|
||||
run_podman rm $cname
|
||||
}
|
||||
|
||||
@test "podman --systemd fails on cgroup v1 with a private cgroupns" {
|
||||
skip_if_cgroupsv2
|
||||
|
||||
run_podman 126 run --systemd=always --cgroupns=private $IMAGE true
|
||||
assert "$output" =~ ".*cgroup namespace is not supported with cgroup v1 and systemd mode"
|
||||
}
|
||||
|
||||
# https://github.com/containers/podman/issues/13153
|
||||
@test "podman rootless-netns processes should be in different cgroup" {
|
||||
is_rootless || skip "only meaningful for rootless"
|
||||
|
||||
@@ -20,7 +20,6 @@ function start_time() {
|
||||
|
||||
function setup() {
|
||||
skip_if_remote "quadlet tests are meaningless over remote"
|
||||
skip_if_rootless_cgroupsv1 "Can't use --cgroups=split w/ CGv1 (issue 17456, wontfix)"
|
||||
skip_if_journald_unavailable "Needed for RHEL. FIXME: we might be able to re-enable a subset of tests."
|
||||
|
||||
test -x "$QUADLET" || die "Cannot run quadlet tests without executable \$QUADLET ($QUADLET)"
|
||||
|
||||
@@ -10,7 +10,6 @@ load helpers.systemd
|
||||
|
||||
function setup() {
|
||||
skip_if_remote "podman quadlet is not implemented for remote setup yet"
|
||||
skip_if_rootless_cgroupsv1 "Can't use --cgroups=split w/ CGv1 (issue 17456, wontfix)"
|
||||
skip_if_journald_unavailable "Needed for RHEL. FIXME: we might be able to re-enable a subset of tests."
|
||||
|
||||
test -x "$QUADLET" || die "Cannot run quadlet tests without executable \$QUADLET ($QUADLET)"
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
load helpers
|
||||
|
||||
@test "podman container storage is not accessible by unprivileged users" {
|
||||
skip_if_cgroupsv1 "run --uidmap fails on cgroups v1 (issue 15025, wontfix)"
|
||||
skip_if_rootless "test meaningless without suid"
|
||||
skip_if_remote
|
||||
|
||||
|
||||
@@ -152,10 +152,6 @@ function check_label() {
|
||||
@test "podman selinux: shared context in (some) namespaces" {
|
||||
skip_if_no_selinux
|
||||
|
||||
# rootless users have no usable cgroups with cgroupsv1, so containers
|
||||
# must use a pid namespace and not join an existing one.
|
||||
skip_if_rootless_cgroupsv1
|
||||
|
||||
if [[ $(podman_runtime) == "runc" ]]; then
|
||||
skip "some sort of runc bug, not worth fixing (issue 11784, wontfix)"
|
||||
fi
|
||||
|
||||
@@ -9,8 +9,6 @@ load helpers
|
||||
@test "podman run, preserves initial --cgroup-manager" {
|
||||
skip_if_remote "podman-remote does not support --cgroup-manager"
|
||||
|
||||
skip_if_rootless_cgroupsv1
|
||||
|
||||
# Find out our default cgroup manager, and from that, get the non-default
|
||||
run_podman info --format '{{.Host.CgroupManager}}'
|
||||
case "$output" in
|
||||
@@ -41,7 +39,6 @@ load helpers
|
||||
# bats test_tags=ci:parallel
|
||||
@test "podman run --cgroups=disabled keeps the current cgroup" {
|
||||
skip_if_remote "podman-remote does not support --cgroups=disabled"
|
||||
skip_if_rootless_cgroupsv1
|
||||
runtime=$(podman_runtime)
|
||||
if [[ $runtime != "crun" ]]; then
|
||||
skip "runtime is $runtime; --cgroups=disabled requires crun"
|
||||
|
||||
@@ -114,7 +114,6 @@ load helpers.network
|
||||
# Issue #5466 - port-forwarding doesn't work with this option and -d
|
||||
# FIXME: random_rfc1918_subnet is not parallel-safe
|
||||
@test "podman networking: port with --userns=keep-id for rootless or --uidmap=* for rootful" {
|
||||
skip_if_cgroupsv1 "run --uidmap fails on cgroups v1 (issue 15025, wontfix)"
|
||||
for cidr in "" "$(random_rfc1918_subnet).0/24"; do
|
||||
myport=$(random_free_port 52000-52999)
|
||||
if [[ -z $cidr ]]; then
|
||||
@@ -878,7 +877,6 @@ EOF
|
||||
|
||||
# bats test_tags=ci:parallel
|
||||
@test "podman run /etc/* permissions" {
|
||||
skip_if_cgroupsv1 "run --uidmap fails on cgroups v1 (issue 15025, wontfix)"
|
||||
userns="--userns=keep-id"
|
||||
if ! is_rootless; then
|
||||
userns="--uidmap=0:1111111:65536 --gidmap=0:1111111:65536"
|
||||
@@ -992,8 +990,6 @@ EOF
|
||||
# Test for https://github.com/containers/podman/issues/18615
|
||||
# CANNOT BE PARALLELIZED due to strict checking of /run/netns
|
||||
@test "podman network cleanup --userns + --restart" {
|
||||
skip_if_cgroupsv1 "run --uidmap fails on cgroups v1 (issue 15025, wontfix)"
|
||||
|
||||
local net1=net-a-$(safename)
|
||||
# use /29 subnet to limit available ip space, a 29 gives 5 usable addresses (6 - 1 for the gw)
|
||||
local subnet="$(random_rfc1918_subnet).0/29"
|
||||
|
||||
@@ -938,36 +938,6 @@ function skip_if_no_selinux() {
|
||||
fi
|
||||
}
|
||||
|
||||
#######################
|
||||
# skip_if_cgroupsv1 # ...with an optional message
|
||||
#######################
|
||||
function skip_if_cgroupsv1() {
|
||||
if ! is_cgroupsv2; then
|
||||
skip "${1:-test requires cgroupsv2}"
|
||||
fi
|
||||
}
|
||||
|
||||
#######################
|
||||
# skip_if_cgroupsv2 # ...with an optional message
|
||||
#######################
|
||||
function skip_if_cgroupsv2() {
|
||||
if is_cgroupsv2; then
|
||||
skip "${1:-test requires cgroupsv1}"
|
||||
fi
|
||||
}
|
||||
|
||||
######################
|
||||
# skip_if_rootless_cgroupsv1 # ...with an optional message
|
||||
######################
|
||||
function skip_if_rootless_cgroupsv1() {
|
||||
if is_rootless; then
|
||||
if ! is_cgroupsv2; then
|
||||
local msg=$(_add_label_if_missing "$1" "rootless cgroupvs1")
|
||||
skip "${msg:-not supported as rootless under cgroupsv1}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
##################################
|
||||
# skip_if_journald_unavailable # rhbz#1895105: rootless journald permissions
|
||||
##################################
|
||||
|
||||
Reference in New Issue
Block a user