Skip to content

Commit

Permalink
Merge pull request #18078 from xpahos/main
Browse files Browse the repository at this point in the history
The `--ulimit` option now also accepts the name with an `RLIMIT_` prefix both upper and lower case.
  • Loading branch information
openshift-merge-robot authored Apr 7, 2023
2 parents 9827f35 + db9785b commit 6ea703b
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 2 deletions.
12 changes: 10 additions & 2 deletions pkg/specgenutil/specgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ import (
"github.com/opencontainers/runtime-spec/specs-go"
)

const (
rlimitPrefix = "rlimit_"
)

func getCPULimits(c *entities.ContainerCreateOptions) *specs.LinuxCPU {
cpu := &specs.LinuxCPU{}
hasLimits := false
Expand Down Expand Up @@ -236,11 +240,15 @@ func setNamespaces(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions)
func GenRlimits(ulimits []string) ([]specs.POSIXRlimit, error) {
rlimits := make([]specs.POSIXRlimit, 0, len(ulimits))
// Rlimits/Ulimits
for _, u := range ulimits {
if u == "host" {
for _, ulimit := range ulimits {
if ulimit == "host" {
rlimits = nil
break
}
// `ulimitNameMapping` from go-units uses lowercase and names
// without prefixes, e.g. `RLIMIT_NOFILE` should be converted to `nofile`.
// https://github.com/containers/podman/issues/9803
u := strings.TrimPrefix(strings.ToLower(ulimit), rlimitPrefix)
ul, err := units.ParseUlimit(u)
if err != nil {
return nil, fmt.Errorf("ulimit option %q requires name=SOFT:HARD, failed to be parsed: %w", u, err)
Expand Down
63 changes: 63 additions & 0 deletions pkg/specgenutil/specgenutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
package specgenutil

import (
"fmt"
"strings"
"testing"

"github.com/containers/common/pkg/machine"
Expand Down Expand Up @@ -154,3 +156,64 @@ func TestParseLinuxResourcesDeviceAccess(t *testing.T) {
_, err = parseLinuxResourcesDeviceAccess("a *:-3 r")
assert.NotNil(t, err, "err is not nil")
}

func TestGenRlimits(t *testing.T) {
testLimits := map[string]string{
"core": "1:2",
"cpu": "1:2",
"data": "1:2",
"fsize": "1:2",
"locks": "1:2",
"memlock": "1:2",
"msgqueue": "1:2",
"nice": "1:2",
"nofile": "1:2",
"nproc": "1:2",
"rss": "1:2",
"rtprio": "1:2",
"rttime": "1:2",
"sigpending": "1:2",
"stack": "1:2",
}

lowerCaseLimits := make([]string, 0, len(testLimits))
upperCaseLimitsWithPrefix := make([]string, 0, len(testLimits))
for name, limit := range testLimits {
lowerCaseLimits = append(lowerCaseLimits, fmt.Sprintf("%s=%s", name, limit))
upperCaseLimitsWithPrefix = append(upperCaseLimitsWithPrefix, strings.ToUpper(fmt.Sprintf("%s%s=%s", rlimitPrefix, name, limit)))
}

parsedLimits, err := GenRlimits(lowerCaseLimits)
assert.NoError(t, err, "err is nil")

for _, limit := range parsedLimits {
val, ok := testLimits[limit.Type]
assert.True(t, ok, "%s matched", limit.Type)
assert.Equal(t, val, fmt.Sprintf("%d:%d", limit.Soft, limit.Hard), "soft and hard limits are equal")
}

parsedLimits, err = GenRlimits(upperCaseLimitsWithPrefix)
assert.NoError(t, err, "err is nil")

for _, limit := range parsedLimits {
val, ok := testLimits[limit.Type]
assert.True(t, ok, "%s matched", limit.Type)
assert.Equal(t, val, fmt.Sprintf("%d:%d", limit.Soft, limit.Hard), "soft and hard limits are equal")
}

// go-utils module has no tests for the parser.
_, err = GenRlimits([]string{"foo=1:1"})
assert.Error(t, err, "err is not nil")

_, err = GenRlimits([]string{"RLIMIT_FOO=1:1"})
assert.Error(t, err, "err is not nil")

_, err = GenRlimits([]string{"nofile"})
assert.Error(t, err, "err is not nil")

_, err = GenRlimits([]string{"nofile=bar"})
assert.Error(t, err, "err is not nil")

_, err = GenRlimits([]string{"nofile=bar:buzz"})
assert.Error(t, err, "err is not nil")
}

0 comments on commit 6ea703b

Please sign in to comment.