Merge pull request #3491 from giuseppe/rlimit-host

podman: add --ulimit host
This commit is contained in:
OpenShift Merge Robot
2019-07-11 21:35:37 +02:00
committed by GitHub
6 changed files with 94 additions and 0 deletions

View File

@ -723,6 +723,8 @@ The following example maps uids 0-2000 in the container to the uids 30000-31999
Ulimit options
You can pass `host` to copy the current configuration from the host.
**--user**, **-u**=*user*
Sets the username or UID used and optionally the groupname or GID for the specified command.

View File

@ -759,6 +759,8 @@ The example maps uids 0-2000 in the container to the uids 30000-31999 on the hos
Ulimit options
You can pass `host` to copy the current configuration from the host.
**--user**, **-u**=*user*
Sets the username or UID used and optionally the groupname or GID for the specified command.

View File

@ -20,6 +20,12 @@ import (
const cpuPeriod = 100000
type systemUlimit struct {
name string
max uint64
cur uint64
}
func getAvailableGids() (int64, error) {
idMap, err := user.ParseIDMapFile("/proc/self/gid_map")
if err != nil {
@ -557,6 +563,20 @@ func addRlimits(config *CreateConfig, g *generate.Generator) error {
)
for _, u := range config.Resources.Ulimit {
if u == "host" {
if len(config.Resources.Ulimit) != 1 {
return errors.New("ulimit can use host only once")
}
hostLimits, err := getHostRlimits()
if err != nil {
return err
}
for _, i := range hostLimits {
g.AddProcessRlimits(i.name, i.max, i.cur)
}
break
}
ul, err := units.ParseUlimit(u)
if err != nil {
return errors.Wrapf(err, "ulimit option %q requires name=SOFT:HARD, failed to be parsed", u)

42
pkg/spec/spec_linux.go Normal file
View File

@ -0,0 +1,42 @@
//+build linux
package createconfig
import (
"syscall"
"github.com/pkg/errors"
)
type systemRlimit struct {
name string
value int
}
var systemLimits = []systemRlimit{
{"RLIMIT_AS", syscall.RLIMIT_AS},
{"RLIMIT_CORE", syscall.RLIMIT_CORE},
{"RLIMIT_CPU", syscall.RLIMIT_CPU},
{"RLIMIT_DATA", syscall.RLIMIT_DATA},
{"RLIMIT_FSIZE", syscall.RLIMIT_FSIZE},
{"RLIMIT_NOFILE", syscall.RLIMIT_NOFILE},
{"RLIMIT_STACK", syscall.RLIMIT_STACK},
}
func getHostRlimits() ([]systemUlimit, error) {
ret := []systemUlimit{}
for _, i := range systemLimits {
var l syscall.Rlimit
if err := syscall.Getrlimit(i.value, &l); err != nil {
return nil, errors.Wrapf(err, "cannot read limits for %s", i.name)
}
s := systemUlimit{
name: i.name,
max: l.Max,
cur: l.Cur,
}
ret = append(ret, s)
}
return ret, nil
}

View File

@ -0,0 +1,7 @@
//+build !linux
package createconfig
func getHostRlimits() ([]systemUlimit, error) {
return nil, nil
}

View File

@ -8,7 +8,9 @@ import (
"net"
"os"
"path/filepath"
"strconv"
"strings"
"syscall"
"time"
. "github.com/containers/libpod/test/utils"
@ -250,6 +252,25 @@ var _ = Describe("Podman run", func() {
Expect(session.OutputToString()).To(ContainSubstring("100"))
})
It("podman run limits host test", func() {
SkipIfRemote()
var l syscall.Rlimit
err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &l)
Expect(err).To(BeNil())
session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "host", fedoraMinimal, "ulimit", "-Hn"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
ulimitCtrStr := strings.TrimSpace(session.OutputToString())
ulimitCtr, err := strconv.ParseUint(ulimitCtrStr, 10, 0)
Expect(err).To(BeNil())
Expect(ulimitCtr).Should(BeNumerically(">=", l.Max))
})
It("podman run with cidfile", func() {
session := podmanTest.Podman([]string{"run", "--cidfile", tempdir + "cidfile", ALPINE, "ls"})
session.WaitWithDefaultTimeout()