From 2e20b09ca04ad380a1afe77e4f78f037a76d9594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Correa=20G=C3=B3mez?= Date: Sun, 1 May 2022 13:19:22 +0200 Subject: [PATCH 1/2] config: Add ulimit option like docker driver --- CHANGELOG.md | 1 + README.md | 9 +++++++++ config.go | 2 ++ driver.go | 41 +++++++++++++++++++++++++++++++++++++++++ driver_test.go | 27 +++++++++++++++++++++++++++ 5 files changed, 80 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94f8da5..6a36bd9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ FEATURES: * config: Privileged containers. * config: Add `cpu_hard_limit` and `cpu_cfs_period` options [[GH-149](https://github.com/hashicorp/nomad-driver-podman/pull/149)] * config: Allow mounting rootfs as read-only. [[GH-133](https://github.com/hashicorp/nomad-driver-podman/pull/133)] +* config: Allow setting ulimit configuration. BUG FIXES: * log: Use error key context to log errors rather than Go err style. [[GH-126](https://github.com/hashicorp/nomad-driver-podman/pull/126)] diff --git a/README.md b/README.md index 1f4177b..cb93b98 100644 --- a/README.md +++ b/README.md @@ -425,6 +425,15 @@ config { } ``` +* **ulimit** - (Optional) A key-value map of ulimit configurations to set to the containers to start. +```hcl +config { + ulimit { + nproc = "4242" + nofile = "2048:4096" + } +} +``` ## Network Configuration diff --git a/config.go b/config.go index 5d4ee2a..122d3d0 100644 --- a/config.go +++ b/config.go @@ -74,6 +74,7 @@ var ( "sysctl": hclspec.NewAttr("sysctl", "list(map(string))", false), "tmpfs": hclspec.NewAttr("tmpfs", "list(string)", false), "tty": hclspec.NewAttr("tty", "bool", false), + "ulimit": hclspec.NewAttr("ulimit", "list(map(string))", false), "volumes": hclspec.NewAttr("volumes", "list(string)", false), "force_pull": hclspec.NewAttr("force_pull", "bool", false), "readonly_rootfs": hclspec.NewAttr("readonly_rootfs", "bool", false), @@ -137,6 +138,7 @@ type TaskConfig struct { MemorySwappiness int64 `codec:"memory_swappiness"` PortMap hclutils.MapStrInt `codec:"port_map"` Sysctl hclutils.MapStrStr `codec:"sysctl"` + Ulimit hclutils.MapStrStr `codec:"ulimit"` CPUHardLimit bool `codec:"cpu_hard_limit"` Init bool `codec:"init"` Tty bool `codec:"tty"` diff --git a/driver.go b/driver.go index 2db8b35..027bc4b 100644 --- a/driver.go +++ b/driver.go @@ -450,6 +450,12 @@ func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *drive createOpts.ContainerResourceConfig.ResourceLimits.CPU.Shares = &cpuShares } + ulimits, err := sliceMergeUlimit(driverConfig.Ulimit) + if err != nil { + return nil, nil, fmt.Errorf("failed to parse ulimit configuration: %v", err) + } + createOpts.ContainerResourceConfig.Rlimits = ulimits + // Security config options createOpts.ContainerSecurityConfig.CapAdd = driverConfig.CapAdd createOpts.ContainerSecurityConfig.CapDrop = driverConfig.CapDrop @@ -703,6 +709,41 @@ func memoryInBytes(strmem string) (int64, error) { } } +func sliceMergeUlimit(ulimitsRaw map[string]string) ([]spec.POSIXRlimit, error) { + var ulimits []spec.POSIXRlimit + + for name, ulimitRaw := range ulimitsRaw { + if len(ulimitRaw) == 0 { + return []spec.POSIXRlimit{}, fmt.Errorf("Malformed ulimit specification %v: %q, cannot be empty", name, ulimitRaw) + } + // hard limit is optional + if !strings.Contains(ulimitRaw, ":") { + ulimitRaw = ulimitRaw + ":" + ulimitRaw + } + + splitted := strings.SplitN(ulimitRaw, ":", 2) + if len(splitted) < 2 { + return []spec.POSIXRlimit{}, fmt.Errorf("Malformed ulimit specification %v: %v", name, ulimitRaw) + } + soft, err := strconv.Atoi(splitted[0]) + if err != nil { + return []spec.POSIXRlimit{}, fmt.Errorf("Malformed soft ulimit %v: %v", name, ulimitRaw) + } + hard, err := strconv.Atoi(splitted[1]) + if err != nil { + return []spec.POSIXRlimit{}, fmt.Errorf("Malformed hard ulimit %v: %v", name, ulimitRaw) + } + + ulimit := spec.POSIXRlimit{ + Type: name, + Soft: uint64(soft), + Hard: uint64(hard), + } + ulimits = append(ulimits, ulimit) + } + return ulimits, nil +} + // Creates the requested image if missing from storage // returns the 64-byte image ID as an unique image identifier func (d *Driver) createImage(image string, auth *AuthConfig, forcePull bool, cfg *drivers.TaskConfig) (string, error) { diff --git a/driver_test.go b/driver_test.go index 57d371f..c9c03f5 100644 --- a/driver_test.go +++ b/driver_test.go @@ -1360,6 +1360,33 @@ func TestPodmanDriver_Privileged(t *testing.T) { require.True(t, inspectData.HostConfig.Privileged) } +// check ulimit option +func TestPodmanDriver_Ulimit(t *testing.T) { + taskCfg := newTaskConfig("", busyboxLongRunningCmd) + taskCfg.Ulimit = map[string]string{"nproc": "4096", "nofile": "2048:4096"} + inspectData := startDestroyInspect(t, taskCfg, "ulimits") + + nofileLimit := api.InspectUlimit{ + Name: "RLIMIT_NOFILE", + Soft: uint64(2048), + Hard: uint64(4096), + } + nprocLimit := api.InspectUlimit{ + Name: "RLIMIT_NPROC", + Soft: uint64(4096), + Hard: uint64(4096), + } + + require.Len(t, inspectData.HostConfig.Ulimits, 2) + if inspectData.HostConfig.Ulimits[0].Name == "RLIMIT_NOFILE" { + require.Exactly(t, nofileLimit, inspectData.HostConfig.Ulimits[0]) + require.Exactly(t, nprocLimit, inspectData.HostConfig.Ulimits[1]) + } else { + require.Exactly(t, nofileLimit, inspectData.HostConfig.Ulimits[1]) + require.Exactly(t, nprocLimit, inspectData.HostConfig.Ulimits[0]) + } +} + // check enabled readonly_rootfs option func TestPodmanDriver_ReadOnlyFilesystem(t *testing.T) { taskCfg := newTaskConfig("", busyboxLongRunningCmd) From 783054b5c5fd50cf4501350b01a88e9801ac4351 Mon Sep 17 00:00:00 2001 From: Luiz Aoqui Date: Mon, 30 May 2022 17:41:39 -0400 Subject: [PATCH 2/2] changelog: fix entry for #166 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a36bd9..d9a4d16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ FEATURES: * config: Privileged containers. * config: Add `cpu_hard_limit` and `cpu_cfs_period` options [[GH-149](https://github.com/hashicorp/nomad-driver-podman/pull/149)] * config: Allow mounting rootfs as read-only. [[GH-133](https://github.com/hashicorp/nomad-driver-podman/pull/133)] -* config: Allow setting ulimit configuration. +* config: Allow setting `ulimit` configuration. [[GH-166](https://github.com/hashicorp/nomad-driver-podman/pull/166)] BUG FIXES: * log: Use error key context to log errors rather than Go err style. [[GH-126](https://github.com/hashicorp/nomad-driver-podman/pull/126)]