Merge pull request #27271 from lsm5/podman6-no-cgv1

Podman6: Remove cgroupsv1
This commit is contained in:
openshift-merge-bot[bot]
2025-11-14 17:03:59 +00:00
committed by GitHub
73 changed files with 162 additions and 907 deletions

View File

@@ -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

View File

@@ -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 {

View File

@@ -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() {

View 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")
}
}

View File

@@ -0,0 +1,7 @@
//go:build !linux
package main
func checkSupportedCgroups() {
// NOP on Non Linux
}

View File

@@ -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.

View File

@@ -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

View 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*

View File

@@ -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 ""

View File

@@ -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*

View File

@@ -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.

View File

@@ -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,

View File

@@ -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
}

View File

@@ -133,7 +133,6 @@ type ContainerStats struct {
AvgCPU float64
ContainerID string
Name string
PerCPU []uint64
CPU float64
CPUNano uint64
CPUSystemNano uint64

View File

@@ -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 == "" {

View File

@@ -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

View File

@@ -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")
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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,
},

View File

@@ -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"`

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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?

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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

View File

@@ -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

View File

@@ -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+:

View File

@@ -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())

View File

@@ -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") != ""

View File

@@ -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())

View File

@@ -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()

View File

@@ -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()

View File

@@ -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"

View File

@@ -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()

View File

@@ -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())
})
})

View File

@@ -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())

View File

@@ -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()

View File

@@ -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()

View File

@@ -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")
}
})

View File

@@ -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())

View File

@@ -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())

View File

@@ -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))

View File

@@ -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()

View File

@@ -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))

View File

@@ -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()

View File

@@ -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")
}

View File

@@ -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))

View File

@@ -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()

View File

@@ -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())

View File

@@ -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())

View File

@@ -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()

View File

@@ -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()

View File

@@ -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())

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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)"

View File

@@ -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)"

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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"

View File

@@ -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
##################################