Skip to content

Commit 4e622c2

Browse files
committed
Add --cgroup-conf option to run subcommand
Signed-off-by: Fabio Falzoi <[email protected]>
1 parent 8132154 commit 4e622c2

File tree

4 files changed

+47
-0
lines changed

4 files changed

+47
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ Cgroup flags:
310310
- :whale: `--cpuset-cpus`: CPUs in which to allow execution (0-3, 0,1)
311311
- :whale: `--memory`: Memory limit
312312
- :whale: `--pids-limit`: Tune container pids limit
313+
- :nerd_face: `--cgroup-conf`: Configure cgroup v2 (key=value)
313314
- :whale: `--cgroupns=(host|private)`: Cgroup namespace to use
314315
- Default: "private" on cgroup v2 hosts, "host" on cgroup v1 hosts
315316
- :whale: `--device`: Add a host device to the container

cmd/nerdctl/run.go

+1
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ func newRunCommand() *cobra.Command {
134134
return []string{"host"}, cobra.ShellCompDirectiveNoFileComp
135135
})
136136
runCommand.Flags().Int("pids-limit", -1, "Tune container pids limit (set -1 for unlimited)")
137+
runCommand.Flags().StringSlice("cgroup-conf", nil, "Configure cgroup v2 (key=value)")
137138
runCommand.Flags().String("cgroupns", defaults.CgroupnsMode(), `Cgroup namespace to use, the default depends on the cgroup version ("host"|"private")`)
138139
runCommand.RegisterFlagCompletionFunc("cgroupns", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
139140
return []string{"host", "private"}, cobra.ShellCompDirectiveNoFileComp

cmd/nerdctl/run_cgroup_linux.go

+34
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@
1717
package main
1818

1919
import (
20+
"context"
2021
"errors"
2122
"fmt"
2223
"path/filepath"
2324
"strings"
2425

26+
"github.com/containerd/containerd/containers"
2527
"github.com/containerd/containerd/oci"
28+
"github.com/containerd/nerdctl/pkg/infoutil"
2629
"github.com/containerd/nerdctl/pkg/rootlessutil"
2730
"github.com/docker/go-units"
2831
"github.com/opencontainers/runtime-spec/specs-go"
@@ -112,6 +115,24 @@ func generateCgroupOpts(cmd *cobra.Command, id string) ([]oci.SpecOpts, error) {
112115
opts = append(opts, oci.WithPidsLimit(int64(pidsLimit)))
113116
}
114117

118+
cgroupConf, err := cmd.Flags().GetStringSlice("cgroup-conf")
119+
if err != nil {
120+
return nil, err
121+
}
122+
if len(cgroupConf) > 0 && infoutil.CgroupsVersion() == "1" {
123+
return nil, errors.New("cannot use --cgroup-conf without cgroup v2")
124+
}
125+
126+
unifieds := make(map[string]string)
127+
for _, unified := range cgroupConf {
128+
splitUnified := strings.SplitN(unified, "=", 2)
129+
if len(splitUnified) < 2 {
130+
return nil, errors.New("--cgroup-conf must be formatted KEY=VALUE")
131+
}
132+
unifieds[splitUnified[0]] = splitUnified[1]
133+
}
134+
opts = append(opts, withUnified(unifieds))
135+
115136
cgroupns, err := cmd.Flags().GetString("cgroupns")
116137
if err != nil {
117138
return nil, err
@@ -190,3 +211,16 @@ func validateDeviceMode(mode string) error {
190211
}
191212
return nil
192213
}
214+
215+
func withUnified(unified map[string]string) oci.SpecOpts {
216+
return func(_ context.Context, _ oci.Client, _ *containers.Container, s *oci.Spec) (err error) {
217+
if unified == nil {
218+
return nil
219+
}
220+
s.Linux.Resources.Unified = make(map[string]string)
221+
for k, v := range unified {
222+
s.Linux.Resources.Unified[k] = v
223+
}
224+
return nil
225+
}
226+
}

cmd/nerdctl/run_test.go

+11
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"strings"
2828
"testing"
2929

30+
"github.com/containerd/cgroups"
3031
"github.com/containerd/nerdctl/pkg/testutil"
3132

3233
"gotest.tools/v3/assert"
@@ -198,6 +199,16 @@ func TestRunPidHost(t *testing.T) {
198199
base.Cmd("run", "--rm", "--pid=host", testutil.AlpineImage, "ps", "auxw").AssertOutContains(strconv.Itoa(pid))
199200
}
200201

202+
func TestRunCgroupConf(t *testing.T) {
203+
if cgroups.Mode() != cgroups.Unified {
204+
t.Skip("test requires cgroup v2")
205+
}
206+
base := testutil.NewBase(t)
207+
208+
base.Cmd("run", "--rm", "--cgroup-conf", "memory.high=33554432", testutil.AlpineImage,
209+
"sh", "-ec", "cd /sys/fs/cgroup && cat memory.high").AssertOutContains("33554432")
210+
}
211+
201212
func TestRunAddHost(t *testing.T) {
202213
base := testutil.NewBase(t)
203214
base.Cmd("run", "--rm", "--add-host", "testing.example.com:10.0.0.1", testutil.AlpineImage, "sh", "-c", "cat /etc/hosts").AssertOutWithFunc(func(stdout string) error {

0 commit comments

Comments
 (0)