Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
says, the destination is a path inside the container, and it is now used
as such. (#5556)

### Added ###
- New `--cgroup-manager` global option, to select the cgroup manager
(`cgroupfs` or `systemd`). This is compatible with crun. (#5570)

### Deprecated ###
- `libcontainer.Stats.Interfaces` and `types.Stats.NetworkInterfaces` (shown
as `network_interfaces` in `runc events --stats` output) are deprecated, as
they are always empty since the removal of veth network strategy in runc
1.0.0-rc6. (#5523)
- The `--systemd-cgroup` global option is deprecated in favor of
`--cgroup-manager=systemd`. It still works, and there are no plans to
remove it. (#5570)

### Changed ###
- A container configuration which uses `--no-pivot` or sets
Expand Down
6 changes: 6 additions & 0 deletions contrib/completions/bash/runc
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ _runc_runc() {
--systemd-cgroup
"
local options_with_args="
--cgroup-manager
--log
--log-format
--root
Expand Down Expand Up @@ -255,6 +256,11 @@ _runc_runc() {
return
;;

--cgroup-manager)
COMPREPLY=($(compgen -W 'cgroupfs systemd' -- "$cur"))
return
;;

$(__runc_to_extglob "$options_with_args"))
return
;;
Expand Down
4 changes: 2 additions & 2 deletions docs/cgroup-v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Kernel older than 5.2 is not recommended due to lack of freezer.
Notably, kernel older than 4.15 MUST NOT be used (unless you are running containers with user namespaces), as it lacks support for controlling permissions of devices.

### Systemd
On cgroup v2 hosts, it is highly recommended to run runc with the systemd cgroup driver (`runc --systemd-cgroup`), though not mandatory.
On cgroup v2 hosts, it is highly recommended to run runc with the systemd cgroup driver (`runc --cgroup-manager=systemd`), though not mandatory.

The recommended systemd version is 244 or later. Older systemd does not support delegation of `cpuset` controller.

Expand All @@ -45,7 +45,7 @@ On cgroup v2 hosts, rootless runc can talk to systemd to get cgroup permissions
```bash
runc spec --rootless
jq '.linux.cgroupsPath="user.slice:runc:foo"' config.json | sponge config.json
runc --systemd-cgroup run foo
runc --cgroup-manager=systemd run foo
```

The container processes are executed in a cgroup like `/user.slice/user-$(id -u).slice/user@$(id -u).service/user.slice/runc-foo.scope`.
Expand Down
6 changes: 3 additions & 3 deletions docs/systemd.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
## systemd cgroup driver

By default, runc creates cgroups and sets cgroup limits on its own (this mode
is known as fs cgroup driver). When `--systemd-cgroup` global option is given
(as in e.g. `runc --systemd-cgroup run ...`), runc switches to systemd cgroup
driver. This document describes its features and peculiarities.
is known as fs cgroup driver). When `--cgroup-manager=systemd` global option is
given (as in e.g. `runc --cgroup-manager=systemd run ...`), runc switches to
systemd cgroup driver. This document describes its features and peculiarities.

### systemd unit name and placement

Expand Down
10 changes: 9 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,14 @@ func main() {
Value: root,
Usage: "root directory for storage of container state (this should be located in tmpfs)",
},
&cli.StringFlag{
Name: "cgroup-manager",
Value: "cgroupfs",
Usage: "cgroup manager to use ('cgroupfs' or 'systemd'); the latter expects cgroupsPath to be of form \"slice:prefix:name\" for e.g. \"system.slice:runc:434234\"",
},
&cli.BoolFlag{
Name: "systemd-cgroup",
Usage: "enable systemd cgroup support, expects cgroupsPath to be of form \"slice:prefix:name\" for e.g. \"system.slice:runc:434234\"",
Usage: "same as --cgroup-manager=systemd (deprecated)",
},
&cli.StringFlag{
Name: "rootless",
Expand Down Expand Up @@ -169,6 +174,9 @@ func main() {
if err := reviseRootDir(cmd); err != nil {
return ctx, err
}
if err := reviseCgroupManager(cmd); err != nil {
return ctx, err
}

if err := configLogrus(cmd); err != nil {
return ctx, err
Expand Down
9 changes: 6 additions & 3 deletions man/runc.8.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,13 @@ These options can be used with any command, and must precede the **command**.
located on tmpfs. Default is */run/runc*, or *$XDG_RUNTIME_DIR/runc* for
rootless containers.

**--cgroup-manager** **cgroupfs**|**systemd**
: Set the cgroup manager to use (default is **cgroupfs**). With **systemd**,
the container spec (_config.json_) is expected to have **cgroupsPath** value
in the *slice:prefix:name* form (e.g. **system.slice:runc:434234**).

**--systemd-cgroup**
: Enable systemd cgroup support. If this is set, the container spec
(_config.json_) is expected to have **cgroupsPath** value in the
*slice:prefix:name* form (e.g. **system.slice:runc:434234**).
: Same as **--cgroup-manager=systemd**. Deprecated.

**--rootless** **true**|**false**|**auto**
: Enable or disable rootless mode. Default is **auto**, meaning to auto-detect
Expand Down
2 changes: 1 addition & 1 deletion rootless_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func shouldUseRootlessCgroupManager(cmd *cli.Command) (bool, error) {
//
// On error, we assume we are root. An error may happen during shelling out to `busctl` CLI,
// mostly when $DBUS_SESSION_BUS_ADDRESS is unset.
if cmd.Bool("systemd-cgroup") {
if cmd.String("cgroup-manager") == "systemd" {
ownerUID, err := systemd.DetectUID()
if err != nil {
logrus.WithError(err).Debug("failed to get the OwnerUID value, assuming the value to be 0")
Expand Down
2 changes: 1 addition & 1 deletion script/setup_host.sh
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ dnf clean all
# Setup rootless user.
"$SCRIPTDIR"/setup_rootless.sh

# Delegate all cgroup v2 controllers to rootless user via --systemd-cgroup
# Delegate all cgroup v2 controllers to rootless user via --cgroup-manager=systemd
if [ -e /sys/fs/cgroup/cgroup.controllers ]; then
mkdir -p /etc/systemd/system/user@.service.d
cat >/etc/systemd/system/user@.service.d/delegate.conf <<'EOF'
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/bin/runc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
set -u -e

opts=()
[ -v RUNC_USE_SYSTEMD ] && opts+=("--systemd-cgroup")
[ -v RUNC_USE_SYSTEMD ] && opts+=("--cgroup-manager=systemd")
[ -n "${ROOT:-}" ] && opts+=("--root" "$ROOT/state")

exec "$RUNC" "${opts[@]}" "$@"
21 changes: 21 additions & 0 deletions tests/integration/cgroups.bats
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,27 @@ function setup() {
run -0 runc run -d --console-socket "$CONSOLE_SOCKET" test_cgroups_permissions
}

@test "runc --cgroup-manager with an invalid value fails" {
run -1 runc --cgroup-manager=foo list
assert_output --partial 'invalid --cgroup-manager value'
}

@test "runc --systemd-cgroup conflicts with --cgroup-manager=cgroupfs" {
run -1 runc --systemd-cgroup --cgroup-manager=cgroupfs list
assert_output --partial "--systemd-cgroup conflicts with --cgroup-manager=cgroupfs"
}

@test "runc --systemd-cgroup is the same as --cgroup-manager=systemd" {
requires systemd
[ $EUID -ne 0 ] && requires rootless_cgroup

set_cgroups_path

# Not using the runc wrapper, as it adds --cgroup-manager=systemd.
run -0 "$RUNC" --root "$ROOT/state" --systemd-cgroup run -d --console-socket "$CONSOLE_SOCKET" test_cgroups_systemd
check_systemd_value "ActiveState" "active"
}

@test "runc create (rootless + no limits + cgrouppath + no permission) fails with permission error" {
requires rootless rootless_no_cgroup

Expand Down
18 changes: 18 additions & 0 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,24 @@ func reviseRootDir(cmd *cli.Command) error {
return cmd.Set("root", root)
}

// reviseCgroupManager checks the --cgroup-manager option argument, and
// converts the deprecated --systemd-cgroup option to --cgroup-manager=systemd.
func reviseCgroupManager(cmd *cli.Command) error {
manager := cmd.String("cgroup-manager")
switch manager {
case "cgroupfs", "systemd":
default:
return fmt.Errorf("invalid --cgroup-manager value %q (must be 'cgroupfs' or 'systemd')", manager)
}
if !cmd.Bool("systemd-cgroup") {
return nil
}
if cmd.IsSet("cgroup-manager") && manager != "systemd" {
return fmt.Errorf("--systemd-cgroup conflicts with --cgroup-manager=%s", manager)
}
return cmd.Set("cgroup-manager", "systemd")
}

// parseBoolOrAuto returns (nil, nil) if s is empty or "auto"
func parseBoolOrAuto(s string) (*bool, error) {
if s == "" || strings.ToLower(s) == "auto" {
Expand Down
2 changes: 1 addition & 1 deletion utils_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ func createContainer(cmd *cli.Command, id string, spec *specs.Spec) (*libcontain
}
config, err := specconv.CreateLibcontainerConfig(&specconv.CreateOpts{
CgroupName: id,
UseSystemdCgroup: cmd.Bool("systemd-cgroup"),
UseSystemdCgroup: cmd.String("cgroup-manager") == "systemd",
NoPivotRoot: cmd.Bool("no-pivot"),
NoNewKeyring: cmd.Bool("no-new-keyring"),
Spec: spec,
Expand Down