mirror of
https://github.com/containers/podman.git
synced 2025-05-29 22:46:25 +08:00
Merge pull request #3491 from giuseppe/rlimit-host
podman: add --ulimit host
This commit is contained in:
@ -723,6 +723,8 @@ The following example maps uids 0-2000 in the container to the uids 30000-31999
|
|||||||
|
|
||||||
Ulimit options
|
Ulimit options
|
||||||
|
|
||||||
|
You can pass `host` to copy the current configuration from the host.
|
||||||
|
|
||||||
**--user**, **-u**=*user*
|
**--user**, **-u**=*user*
|
||||||
|
|
||||||
Sets the username or UID used and optionally the groupname or GID for the specified command.
|
Sets the username or UID used and optionally the groupname or GID for the specified command.
|
||||||
|
@ -759,6 +759,8 @@ The example maps uids 0-2000 in the container to the uids 30000-31999 on the hos
|
|||||||
|
|
||||||
Ulimit options
|
Ulimit options
|
||||||
|
|
||||||
|
You can pass `host` to copy the current configuration from the host.
|
||||||
|
|
||||||
**--user**, **-u**=*user*
|
**--user**, **-u**=*user*
|
||||||
|
|
||||||
Sets the username or UID used and optionally the groupname or GID for the specified command.
|
Sets the username or UID used and optionally the groupname or GID for the specified command.
|
||||||
|
@ -20,6 +20,12 @@ import (
|
|||||||
|
|
||||||
const cpuPeriod = 100000
|
const cpuPeriod = 100000
|
||||||
|
|
||||||
|
type systemUlimit struct {
|
||||||
|
name string
|
||||||
|
max uint64
|
||||||
|
cur uint64
|
||||||
|
}
|
||||||
|
|
||||||
func getAvailableGids() (int64, error) {
|
func getAvailableGids() (int64, error) {
|
||||||
idMap, err := user.ParseIDMapFile("/proc/self/gid_map")
|
idMap, err := user.ParseIDMapFile("/proc/self/gid_map")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -557,6 +563,20 @@ func addRlimits(config *CreateConfig, g *generate.Generator) error {
|
|||||||
)
|
)
|
||||||
|
|
||||||
for _, u := range config.Resources.Ulimit {
|
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)
|
ul, err := units.ParseUlimit(u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "ulimit option %q requires name=SOFT:HARD, failed to be parsed", u)
|
return errors.Wrapf(err, "ulimit option %q requires name=SOFT:HARD, failed to be parsed", u)
|
||||||
|
42
pkg/spec/spec_linux.go
Normal file
42
pkg/spec/spec_linux.go
Normal 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
|
||||||
|
|
||||||
|
}
|
7
pkg/spec/spec_unsupported.go
Normal file
7
pkg/spec/spec_unsupported.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
//+build !linux
|
||||||
|
|
||||||
|
package createconfig
|
||||||
|
|
||||||
|
func getHostRlimits() ([]systemUlimit, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
@ -8,7 +8,9 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
. "github.com/containers/libpod/test/utils"
|
. "github.com/containers/libpod/test/utils"
|
||||||
@ -250,6 +252,25 @@ var _ = Describe("Podman run", func() {
|
|||||||
Expect(session.OutputToString()).To(ContainSubstring("100"))
|
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() {
|
It("podman run with cidfile", func() {
|
||||||
session := podmanTest.Podman([]string{"run", "--cidfile", tempdir + "cidfile", ALPINE, "ls"})
|
session := podmanTest.Podman([]string{"run", "--cidfile", tempdir + "cidfile", ALPINE, "ls"})
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
|
Reference in New Issue
Block a user