Skip to content

Commit

Permalink
Merge pull request #166 from pabloyoyoista/ulimits
Browse files Browse the repository at this point in the history
config: Add ulimit option like docker driver
  • Loading branch information
lgfa29 authored May 30, 2022
2 parents c158df4 + 4f5a5ff commit 95c69a2
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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. [[GH-166](https://github.com/hashicorp/nomad-driver-podman/pull/166)]
* runtime: Add support for host and CSI volumes and using podman tasks as CSI plugins [[GH-169](https://github.com/hashicorp/nomad-driver-podman/pull/169)]

BUG FIXES:
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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"`
Expand Down
41 changes: 41 additions & 0 deletions driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down
27 changes: 27 additions & 0 deletions driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 95c69a2

Please sign in to comment.