Skip to content

Commit

Permalink
Make buildah match podman for handling of ulimits
Browse files Browse the repository at this point in the history
Podman currently sets the ulimits of nofile and nproc
to max in rootless mode, if the user does not override.

Buildah on the other hand just passes in the current defaults.

Podman build should match podman run, and this will fix that problem.

Fixes: #5273

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
  • Loading branch information
rhatdan committed Jan 31, 2024
1 parent 0632df1 commit f9ac398
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 2 deletions.
3 changes: 3 additions & 0 deletions define/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ const (
SNP TeeType = "snp"
)

// DefaultRlimitValue is the value set by default for nofile and nproc
const RLimitDefaultValue = uint64(1048576)

// TeeType is a supported trusted execution environment type.
type TeeType string

Expand Down
34 changes: 34 additions & 0 deletions run_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,9 @@ func addRlimits(ulimit []string, g *generate.Generator, defaultUlimits []string)
var (
ul *units.Ulimit
err error
// setup rlimits
nofileSet bool
nprocSet bool
)

ulimit = append(defaultUlimits, ulimit...)
Expand All @@ -862,8 +865,39 @@ func addRlimits(ulimit []string, g *generate.Generator, defaultUlimits []string)
return fmt.Errorf("ulimit option %q requires name=SOFT:HARD, failed to be parsed: %w", u, err)
}

if strings.ToUpper(ul.Name) == "NOFILE" {
nofileSet = true
}
if strings.ToUpper(ul.Name) == "NPROC" {
nprocSet = true
}
g.AddProcessRlimits("RLIMIT_"+strings.ToUpper(ul.Name), uint64(ul.Hard), uint64(ul.Soft))
}
if !nofileSet {
max := define.RLimitDefaultValue
var rlimit unix.Rlimit
if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rlimit); err == nil {
if max < rlimit.Max || unshare.IsRootless() {
max = rlimit.Max
}
} else {
logrus.Warnf("Failed to return RLIMIT_NOFILE ulimit %q", err)
}
g.AddProcessRlimits("RLIMIT_NOFILE", max, max)
}
if !nprocSet {
max := define.RLimitDefaultValue
var rlimit unix.Rlimit
if err := unix.Getrlimit(unix.RLIMIT_NPROC, &rlimit); err == nil {
if max < rlimit.Max || unshare.IsRootless() {
max = rlimit.Max
}
} else {
logrus.Warnf("Failed to return RLIMIT_NPROC ulimit %q", err)
}
g.AddProcessRlimits("RLIMIT_NPROC", max, max)
}

return nil
}

Expand Down
15 changes: 15 additions & 0 deletions tests/bud.bats
Original file line number Diff line number Diff line change
Expand Up @@ -6602,3 +6602,18 @@ _EOF
expect_output --substring "localhost/foo/bar"
expect_output --substring "localhost/bar"
}

@test "build test default ulimits" {
skip_if_no_runtime
_prefetch alpine

run podman run --rm alpine sh -c "echo -n Files=; awk '/open files/{print \$4 \"/\" \$5}' /proc/self/limits"
podman_files=$output

run podman run --rm alpine sh -c "echo -n Processes=; awk '/processes/{print \$3 \"/\" \$4}' /proc/self/limits"
podman_processes=$output

CONTAINERS_CONF=/dev/null run_buildah build --no-cache --pull=false $WITH_POLICY_JSON -t foo/bar $BUDFILES/bud.limits
expect_output --substring "$podman_files"
expect_output --substring "$podman_processes"
}
4 changes: 4 additions & 0 deletions tests/bud/bud.limits/Containerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Containerfile
FROM alpine
RUN echo -n "Files="; awk '/open files/{print $4 "/" $5}' /proc/self/limits
RUN echo -n "Processes="; awk '/processes/{print $3 "/" $4}' /proc/self/limits
11 changes: 9 additions & 2 deletions tests/run.bats
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,6 @@ function configure_and_check_user() {
}

@test "Check if containers run with correct open files/processes limits" {
skip_if_rootless_environment
skip_if_no_runtime

# we need to not use the list of limits that are set in our default
Expand All @@ -521,11 +520,19 @@ function configure_and_check_user() {
export CONTAINERS_CONF=${TEST_SCRATCH_DIR}/containers.conf

_prefetch alpine
run awk '/open files/{print $5}' /proc/self/limits
olimit=$output

maxpids=$(cat /proc/sys/kernel/pid_max)
if is_rootless; then
run awk '/processes/{print $4}' /proc/self/limits
maxpids=$output
fi

run_buildah from --quiet --pull=false $WITH_POLICY_JSON alpine
cid=$output
run_buildah run $cid awk '/open files/{print $4}' /proc/self/limits
expect_output 1024 "limits: open files (unlimited)"
expect_output $olimit "limits: open files (unlimited)"
run_buildah run $cid awk '/processes/{print $3}' /proc/self/limits
expect_output ${maxpids} "limits: processes (unlimited)"
run_buildah rm $cid
Expand Down

0 comments on commit f9ac398

Please sign in to comment.