From 889a0e3758478204d71542866bbffbb8150b1b91 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Mon, 21 Dec 2015 15:18:24 -0500 Subject: [PATCH 1/3] Upgrade go-units vendor to latest version with ulimits. Signed-off-by: Daniel Nephin Upstream-commit: 3b8301b6600855e348bf4eeacabe5059f52e9d99 Component: engine --- components/engine/hack/vendor.sh | 2 +- .../src/github.com/docker/go-units/circle.yml | 11 ++ .../src/github.com/docker/go-units/ulimit.go | 109 ++++++++++++++++++ 3 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 components/engine/vendor/src/github.com/docker/go-units/circle.yml create mode 100644 components/engine/vendor/src/github.com/docker/go-units/ulimit.go diff --git a/components/engine/hack/vendor.sh b/components/engine/hack/vendor.sh index 4b7a171111..f57884eaa2 100755 --- a/components/engine/hack/vendor.sh +++ b/components/engine/hack/vendor.sh @@ -20,7 +20,7 @@ clone git github.com/mistifyio/go-zfs v2.1.1 clone git github.com/tchap/go-patricia v2.1.0 clone git github.com/vdemeester/shakers 3c10293ce22b900c27acad7b28656196fcc2f73b clone git golang.org/x/net 47990a1ba55743e6ef1affd3a14e5bac8553615d https://github.com/golang/net.git -clone git github.com/docker/go-units v0.2.0 +clone git github.com/docker/go-units 651fc226e7441360384da338d0fd37f2440ffbe3 clone git github.com/docker/go-connections 4e42727957c146776e5de9cec8c39e4059ed9f20 #get libnetwork packages diff --git a/components/engine/vendor/src/github.com/docker/go-units/circle.yml b/components/engine/vendor/src/github.com/docker/go-units/circle.yml new file mode 100644 index 0000000000..9043b35478 --- /dev/null +++ b/components/engine/vendor/src/github.com/docker/go-units/circle.yml @@ -0,0 +1,11 @@ +dependencies: + post: + # install golint + - go get github.com/golang/lint/golint + +test: + pre: + # run analysis before tests + - go vet ./... + - test -z "$(golint ./... | tee /dev/stderr)" + - test -z "$(gofmt -s -l . | tee /dev/stderr)" diff --git a/components/engine/vendor/src/github.com/docker/go-units/ulimit.go b/components/engine/vendor/src/github.com/docker/go-units/ulimit.go new file mode 100644 index 0000000000..f0a7be2921 --- /dev/null +++ b/components/engine/vendor/src/github.com/docker/go-units/ulimit.go @@ -0,0 +1,109 @@ +package units + +import ( + "fmt" + "strconv" + "strings" +) + +// Ulimit is a human friendly version of Rlimit. +type Ulimit struct { + Name string + Hard int64 + Soft int64 +} + +// Rlimit specifies the resource limits, such as max open files. +type Rlimit struct { + Type int `json:"type,omitempty"` + Hard uint64 `json:"hard,omitempty"` + Soft uint64 `json:"soft,omitempty"` +} + +const ( + // magic numbers for making the syscall + // some of these are defined in the syscall package, but not all. + // Also since Windows client doesn't get access to the syscall package, need to + // define these here + rlimitAs = 9 + rlimitCore = 4 + rlimitCPU = 0 + rlimitData = 2 + rlimitFsize = 1 + rlimitLocks = 10 + rlimitMemlock = 8 + rlimitMsgqueue = 12 + rlimitNice = 13 + rlimitNofile = 7 + rlimitNproc = 6 + rlimitRss = 5 + rlimitRtprio = 14 + rlimitRttime = 15 + rlimitSigpending = 11 + rlimitStack = 3 +) + +var ulimitNameMapping = map[string]int{ + //"as": rlimitAs, // Disabled since this doesn't seem usable with the way Docker inits a container. + "core": rlimitCore, + "cpu": rlimitCPU, + "data": rlimitData, + "fsize": rlimitFsize, + "locks": rlimitLocks, + "memlock": rlimitMemlock, + "msgqueue": rlimitMsgqueue, + "nice": rlimitNice, + "nofile": rlimitNofile, + "nproc": rlimitNproc, + "rss": rlimitRss, + "rtprio": rlimitRtprio, + "rttime": rlimitRttime, + "sigpending": rlimitSigpending, + "stack": rlimitStack, +} + +// ParseUlimit parses and returns a Ulimit from the specified string. +func ParseUlimit(val string) (*Ulimit, error) { + parts := strings.SplitN(val, "=", 2) + if len(parts) != 2 { + return nil, fmt.Errorf("invalid ulimit argument: %s", val) + } + + if _, exists := ulimitNameMapping[parts[0]]; !exists { + return nil, fmt.Errorf("invalid ulimit type: %s", parts[0]) + } + + limitVals := strings.SplitN(parts[1], ":", 2) + if len(limitVals) > 2 { + return nil, fmt.Errorf("too many limit value arguments - %s, can only have up to two, `soft[:hard]`", parts[1]) + } + + soft, err := strconv.ParseInt(limitVals[0], 10, 64) + if err != nil { + return nil, err + } + + hard := soft // in case no hard was set + if len(limitVals) == 2 { + hard, err = strconv.ParseInt(limitVals[1], 10, 64) + } + if soft > hard { + return nil, fmt.Errorf("ulimit soft limit must be less than or equal to hard limit: %d > %d", soft, hard) + } + + return &Ulimit{Name: parts[0], Soft: soft, Hard: hard}, nil +} + +// GetRlimit returns the RLimit corresponding to Ulimit. +func (u *Ulimit) GetRlimit() (*Rlimit, error) { + t, exists := ulimitNameMapping[u.Name] + if !exists { + return nil, fmt.Errorf("invalid ulimit name %s", u.Name) + } + + return &Rlimit{Type: t, Soft: uint64(u.Soft), Hard: uint64(u.Hard)}, nil +} + +func (u *Ulimit) String() string { + return fmt.Sprintf("%s=%d:%d", u.Name, u.Soft, u.Hard) +} From b109cc7bb5d6cc509a6c570e5de27f11d512a9f9 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Mon, 21 Dec 2015 15:06:46 -0500 Subject: [PATCH 2/3] Move ulimit options to runconfig opts Signed-off-by: Daniel Nephin Upstream-commit: 5adbea7075b2fda6ea9947d131aaa2a5db0c1295 Component: engine --- components/engine/api/client/build.go | 6 +++--- components/engine/daemon/config_unix.go | 9 +++++---- components/engine/{ => runconfig}/opts/ulimit.go | 14 +++++++------- .../engine/{ => runconfig}/opts/ulimit_test.go | 4 ++-- components/engine/runconfig/parse.go | 3 ++- 5 files changed, 19 insertions(+), 17 deletions(-) rename components/engine/{ => runconfig}/opts/ulimit.go (71%) rename components/engine/{ => runconfig}/opts/ulimit_test.go (92%) diff --git a/components/engine/api/client/build.go b/components/engine/api/client/build.go index b700884835..7d226ee803 100644 --- a/components/engine/api/client/build.go +++ b/components/engine/api/client/build.go @@ -27,9 +27,9 @@ import ( flag "github.com/docker/docker/pkg/mflag" "github.com/docker/docker/pkg/progress" "github.com/docker/docker/pkg/streamformatter" - "github.com/docker/docker/pkg/ulimit" "github.com/docker/docker/pkg/urlutil" "github.com/docker/docker/reference" + runconfigopts "github.com/docker/docker/runconfig/opts" "github.com/docker/docker/utils" "github.com/docker/go-units" ) @@ -62,8 +62,8 @@ func (cli *DockerCli) CmdBuild(args ...string) error { cmd.Var(&flBuildArg, []string{"-build-arg"}, "Set build-time variables") isolation := cmd.String([]string{"-isolation"}, "", "Container isolation level") - ulimits := make(map[string]*ulimit.Ulimit) - flUlimits := opts.NewUlimitOpt(&ulimits) + ulimits := make(map[string]*units.Ulimit) + flUlimits := runconfigopts.NewUlimitOpt(&ulimits) cmd.Var(flUlimits, []string{"-ulimit"}, "Ulimit options") cmd.Require(flag.Exact, 1) diff --git a/components/engine/daemon/config_unix.go b/components/engine/daemon/config_unix.go index 8772aad977..06439ef50b 100644 --- a/components/engine/daemon/config_unix.go +++ b/components/engine/daemon/config_unix.go @@ -7,7 +7,8 @@ import ( "github.com/docker/docker/opts" flag "github.com/docker/docker/pkg/mflag" - "github.com/docker/docker/pkg/ulimit" + runconfigopts "github.com/docker/docker/runconfig/opts" + "github.com/docker/go-units" ) var ( @@ -27,7 +28,7 @@ type Config struct { EnableSelinuxSupport bool RemappedRoot string SocketGroup string - Ulimits map[string]*ulimit.Ulimit + Ulimits map[string]*units.Ulimit } // bridgeConfig stores all the bridge driver specific @@ -59,8 +60,8 @@ func (config *Config) InstallFlags(cmd *flag.FlagSet, usageFn func(string) strin // Then platform-specific install flags cmd.BoolVar(&config.EnableSelinuxSupport, []string{"-selinux-enabled"}, false, usageFn("Enable selinux support")) cmd.StringVar(&config.SocketGroup, []string{"G", "-group"}, "docker", usageFn("Group for the unix socket")) - config.Ulimits = make(map[string]*ulimit.Ulimit) - cmd.Var(opts.NewUlimitOpt(&config.Ulimits), []string{"-default-ulimit"}, usageFn("Set default ulimits for containers")) + config.Ulimits = make(map[string]*units.Ulimit) + cmd.Var(runconfigopts.NewUlimitOpt(&config.Ulimits), []string{"-default-ulimit"}, usageFn("Set default ulimits for containers")) cmd.BoolVar(&config.Bridge.EnableIPTables, []string{"#iptables", "-iptables"}, true, usageFn("Enable addition of iptables rules")) cmd.BoolVar(&config.Bridge.EnableIPForward, []string{"#ip-forward", "-ip-forward"}, true, usageFn("Enable net.ipv4.ip_forward")) cmd.BoolVar(&config.Bridge.EnableIPMasq, []string{"-ip-masq"}, true, usageFn("Enable IP masquerading")) diff --git a/components/engine/opts/ulimit.go b/components/engine/runconfig/opts/ulimit.go similarity index 71% rename from components/engine/opts/ulimit.go rename to components/engine/runconfig/opts/ulimit.go index b41f475bd5..0aec91f170 100644 --- a/components/engine/opts/ulimit.go +++ b/components/engine/runconfig/opts/ulimit.go @@ -3,25 +3,25 @@ package opts import ( "fmt" - "github.com/docker/docker/pkg/ulimit" + "github.com/docker/go-units" ) // UlimitOpt defines a map of Ulimits type UlimitOpt struct { - values *map[string]*ulimit.Ulimit + values *map[string]*units.Ulimit } // NewUlimitOpt creates a new UlimitOpt -func NewUlimitOpt(ref *map[string]*ulimit.Ulimit) *UlimitOpt { +func NewUlimitOpt(ref *map[string]*units.Ulimit) *UlimitOpt { if ref == nil { - ref = &map[string]*ulimit.Ulimit{} + ref = &map[string]*units.Ulimit{} } return &UlimitOpt{ref} } // Set validates a Ulimit and sets its name as a key in UlimitOpt func (o *UlimitOpt) Set(val string) error { - l, err := ulimit.Parse(val) + l, err := units.ParseUlimit(val) if err != nil { return err } @@ -42,8 +42,8 @@ func (o *UlimitOpt) String() string { } // GetList returns a slice of pointers to Ulimits. -func (o *UlimitOpt) GetList() []*ulimit.Ulimit { - var ulimits []*ulimit.Ulimit +func (o *UlimitOpt) GetList() []*units.Ulimit { + var ulimits []*units.Ulimit for _, v := range *o.values { ulimits = append(ulimits, v) } diff --git a/components/engine/opts/ulimit_test.go b/components/engine/runconfig/opts/ulimit_test.go similarity index 92% rename from components/engine/opts/ulimit_test.go rename to components/engine/runconfig/opts/ulimit_test.go index 3845d1ec18..0aa3facdfb 100644 --- a/components/engine/opts/ulimit_test.go +++ b/components/engine/runconfig/opts/ulimit_test.go @@ -3,11 +3,11 @@ package opts import ( "testing" - "github.com/docker/docker/pkg/ulimit" + "github.com/docker/go-units" ) func TestUlimitOpt(t *testing.T) { - ulimitMap := map[string]*ulimit.Ulimit{ + ulimitMap := map[string]*units.Ulimit{ "nofile": {"nofile", 1024, 512}, } diff --git a/components/engine/runconfig/parse.go b/components/engine/runconfig/parse.go index 488af26127..3556202f4d 100644 --- a/components/engine/runconfig/parse.go +++ b/components/engine/runconfig/parse.go @@ -12,6 +12,7 @@ import ( flag "github.com/docker/docker/pkg/mflag" "github.com/docker/docker/pkg/mount" "github.com/docker/docker/pkg/signal" + runconfigopts "github.com/docker/docker/runconfig/opts" "github.com/docker/docker/volume" "github.com/docker/go-connections/nat" "github.com/docker/go-units" @@ -63,7 +64,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*container.Config, *container.Host flLabels = opts.NewListOpts(opts.ValidateEnv) flDevices = opts.NewListOpts(ValidateDevice) - flUlimits = opts.NewUlimitOpt(nil) + flUlimits = runconfigopts.NewUlimitOpt(nil) flPublish = opts.NewListOpts(nil) flExpose = opts.NewListOpts(nil) From 1cfbdcfe91962dbdad9e4e6405b43ee9fc4ef61a Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Mon, 21 Dec 2015 15:10:53 -0500 Subject: [PATCH 3/3] Remove package pkg/ulimit, use go-units instead. Signed-off-by: Daniel Nephin Upstream-commit: 83237aab2b9430a88790467867505cc9a5147f3e Component: engine --- .../api/server/router/build/build_routes.go | 4 +- components/engine/api/types/client.go | 4 +- .../engine/api/types/container/host_config.go | 26 ++-- .../engine/builder/dockerfile/builder.go | 4 +- .../daemon/container_operations_unix.go | 6 +- .../engine/daemon/execdriver/driver_unix.go | 4 +- .../docker_cli_build_unix_test.go | 4 +- components/engine/pkg/ulimit/ulimit.go | 111 ------------------ components/engine/pkg/ulimit/ulimit_test.go | 55 --------- 9 files changed, 26 insertions(+), 192 deletions(-) delete mode 100644 components/engine/pkg/ulimit/ulimit.go delete mode 100644 components/engine/pkg/ulimit/ulimit_test.go diff --git a/components/engine/api/server/router/build/build_routes.go b/components/engine/api/server/router/build/build_routes.go index 9744033f76..4222004c07 100644 --- a/components/engine/api/server/router/build/build_routes.go +++ b/components/engine/api/server/router/build/build_routes.go @@ -23,9 +23,9 @@ import ( "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/progress" "github.com/docker/docker/pkg/streamformatter" - "github.com/docker/docker/pkg/ulimit" "github.com/docker/docker/reference" "github.com/docker/docker/utils" + "github.com/docker/go-units" "golang.org/x/net/context" ) @@ -151,7 +151,7 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r * buildConfig.Isolation = i } - var buildUlimits = []*ulimit.Ulimit{} + var buildUlimits = []*units.Ulimit{} ulimitsJSON := r.FormValue("ulimits") if ulimitsJSON != "" { if err := json.NewDecoder(strings.NewReader(ulimitsJSON)).Decode(&buildUlimits); err != nil { diff --git a/components/engine/api/types/client.go b/components/engine/api/types/client.go index c588508e79..6501ec3120 100644 --- a/components/engine/api/types/client.go +++ b/components/engine/api/types/client.go @@ -7,7 +7,7 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" - "github.com/docker/docker/pkg/ulimit" + "github.com/docker/go-units" ) // ContainerAttachOptions holds parameters to attach to a container. @@ -137,7 +137,7 @@ type ImageBuildOptions struct { CgroupParent string ShmSize string Dockerfile string - Ulimits []*ulimit.Ulimit + Ulimits []*units.Ulimit BuildArgs []string AuthConfigs map[string]AuthConfig Context io.Reader diff --git a/components/engine/api/types/container/host_config.go b/components/engine/api/types/container/host_config.go index e1d4ea4095..1e849bfa9f 100644 --- a/components/engine/api/types/container/host_config.go +++ b/components/engine/api/types/container/host_config.go @@ -5,8 +5,8 @@ import ( "github.com/docker/docker/api/types/blkiodev" "github.com/docker/docker/api/types/strslice" - "github.com/docker/docker/pkg/ulimit" "github.com/docker/go-connections/nat" + "github.com/docker/go-units" ) // NetworkMode represents the container network stack. @@ -170,18 +170,18 @@ type Resources struct { BlkioDeviceWriteBps []*blkiodev.ThrottleDevice BlkioDeviceReadIOps []*blkiodev.ThrottleDevice BlkioDeviceWriteIOps []*blkiodev.ThrottleDevice - CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period - CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota - CpusetCpus string // CpusetCpus 0-2, 0,1 - CpusetMems string // CpusetMems 0-2, 0,1 - Devices []DeviceMapping // List of devices to map inside the container - KernelMemory int64 // Kernel memory limit (in bytes) - Memory int64 // Memory limit (in bytes) - MemoryReservation int64 // Memory soft limit (in bytes) - MemorySwap int64 // Total memory usage (memory + swap); set `-1` to disable swap - MemorySwappiness *int64 // Tuning container memory swappiness behaviour - OomKillDisable bool // Whether to disable OOM Killer or not - Ulimits []*ulimit.Ulimit // List of ulimits to be set in the container + CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period + CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota + CpusetCpus string // CpusetCpus 0-2, 0,1 + CpusetMems string // CpusetMems 0-2, 0,1 + Devices []DeviceMapping // List of devices to map inside the container + KernelMemory int64 // Kernel memory limit (in bytes) + Memory int64 // Memory limit (in bytes) + MemoryReservation int64 // Memory soft limit (in bytes) + MemorySwap int64 // Total memory usage (memory + swap); set `-1` to disable swap + MemorySwappiness *int64 // Tuning container memory swappiness behaviour + OomKillDisable bool // Whether to disable OOM Killer or not + Ulimits []*units.Ulimit // List of ulimits to be set in the container } // HostConfig the non-portable Config structure of a container. diff --git a/components/engine/builder/dockerfile/builder.go b/components/engine/builder/dockerfile/builder.go index 0db8c41880..102918da9a 100644 --- a/components/engine/builder/dockerfile/builder.go +++ b/components/engine/builder/dockerfile/builder.go @@ -14,7 +14,7 @@ import ( "github.com/docker/docker/builder" "github.com/docker/docker/builder/dockerfile/parser" "github.com/docker/docker/pkg/stringid" - "github.com/docker/docker/pkg/ulimit" + "github.com/docker/go-units" ) var validCommitCommands = map[string]bool{ @@ -66,7 +66,7 @@ type Config struct { CPUSetCpus string CPUSetMems string CgroupParent string - Ulimits []*ulimit.Ulimit + Ulimits []*units.Ulimit } // Builder is a Dockerfile builder diff --git a/components/engine/daemon/container_operations_unix.go b/components/engine/daemon/container_operations_unix.go index 6c4f17704a..bdc80357ef 100644 --- a/components/engine/daemon/container_operations_unix.go +++ b/components/engine/daemon/container_operations_unix.go @@ -24,8 +24,8 @@ import ( "github.com/docker/docker/pkg/idtools" "github.com/docker/docker/pkg/mount" "github.com/docker/docker/pkg/stringid" - "github.com/docker/docker/pkg/ulimit" "github.com/docker/docker/runconfig" + "github.com/docker/go-units" "github.com/docker/libnetwork" "github.com/docker/libnetwork/netlabel" "github.com/docker/libnetwork/options" @@ -146,11 +146,11 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro autoCreatedDevices := mergeDevices(configs.DefaultAutoCreatedDevices, userSpecifiedDevices) - var rlimits []*ulimit.Rlimit + var rlimits []*units.Rlimit ulimits := c.HostConfig.Ulimits // Merge ulimits with daemon defaults - ulIdx := make(map[string]*ulimit.Ulimit) + ulIdx := make(map[string]*units.Ulimit) for _, ul := range ulimits { ulIdx[ul.Name] = ul } diff --git a/components/engine/daemon/execdriver/driver_unix.go b/components/engine/daemon/execdriver/driver_unix.go index dae5d916c1..168b818cc8 100644 --- a/components/engine/daemon/execdriver/driver_unix.go +++ b/components/engine/daemon/execdriver/driver_unix.go @@ -14,7 +14,7 @@ import ( "github.com/docker/docker/daemon/execdriver/native/template" "github.com/docker/docker/pkg/idtools" "github.com/docker/docker/pkg/mount" - "github.com/docker/docker/pkg/ulimit" + "github.com/docker/go-units" "github.com/opencontainers/runc/libcontainer" "github.com/opencontainers/runc/libcontainer/cgroups/fs" "github.com/opencontainers/runc/libcontainer/configs" @@ -48,7 +48,7 @@ type Resources struct { CpusetCpus string `json:"cpuset_cpus"` CpusetMems string `json:"cpuset_mems"` CPUPeriod int64 `json:"cpu_period"` - Rlimits []*ulimit.Rlimit `json:"rlimits"` + Rlimits []*units.Rlimit `json:"rlimits"` OomKillDisable bool `json:"oom_kill_disable"` MemorySwappiness int64 `json:"memory_swappiness"` } diff --git a/components/engine/integration-cli/docker_cli_build_unix_test.go b/components/engine/integration-cli/docker_cli_build_unix_test.go index 599845a2ce..644d91bca5 100644 --- a/components/engine/integration-cli/docker_cli_build_unix_test.go +++ b/components/engine/integration-cli/docker_cli_build_unix_test.go @@ -7,7 +7,7 @@ import ( "strings" "github.com/docker/docker/pkg/integration/checker" - "github.com/docker/docker/pkg/ulimit" + "github.com/docker/go-units" "github.com/go-check/check" ) @@ -33,7 +33,7 @@ func (s *DockerSuite) TestBuildResourceConstraintsAreUsed(c *check.C) { CpusetMems string CPUShares int64 CPUQuota int64 - Ulimits []*ulimit.Ulimit + Ulimits []*units.Ulimit } cfg, err := inspectFieldJSON(cID, "HostConfig") diff --git a/components/engine/pkg/ulimit/ulimit.go b/components/engine/pkg/ulimit/ulimit.go deleted file mode 100644 index 8fb0d804de..0000000000 --- a/components/engine/pkg/ulimit/ulimit.go +++ /dev/null @@ -1,111 +0,0 @@ -// Package ulimit provides structure and helper function to parse and represent -// resource limits (Rlimit and Ulimit, its human friendly version). -package ulimit - -import ( - "fmt" - "strconv" - "strings" -) - -// Ulimit is a human friendly version of Rlimit. -type Ulimit struct { - Name string - Hard int64 - Soft int64 -} - -// Rlimit specifies the resource limits, such as max open files. -type Rlimit struct { - Type int `json:"type,omitempty"` - Hard uint64 `json:"hard,omitempty"` - Soft uint64 `json:"soft,omitempty"` -} - -const ( - // magic numbers for making the syscall - // some of these are defined in the syscall package, but not all. - // Also since Windows client doesn't get access to the syscall package, need to - // define these here - rlimitAs = 9 - rlimitCore = 4 - rlimitCPU = 0 - rlimitData = 2 - rlimitFsize = 1 - rlimitLocks = 10 - rlimitMemlock = 8 - rlimitMsgqueue = 12 - rlimitNice = 13 - rlimitNofile = 7 - rlimitNproc = 6 - rlimitRss = 5 - rlimitRtprio = 14 - rlimitRttime = 15 - rlimitSigpending = 11 - rlimitStack = 3 -) - -var ulimitNameMapping = map[string]int{ - //"as": rlimitAs, // Disabled since this doesn't seem usable with the way Docker inits a container. - "core": rlimitCore, - "cpu": rlimitCPU, - "data": rlimitData, - "fsize": rlimitFsize, - "locks": rlimitLocks, - "memlock": rlimitMemlock, - "msgqueue": rlimitMsgqueue, - "nice": rlimitNice, - "nofile": rlimitNofile, - "nproc": rlimitNproc, - "rss": rlimitRss, - "rtprio": rlimitRtprio, - "rttime": rlimitRttime, - "sigpending": rlimitSigpending, - "stack": rlimitStack, -} - -// Parse parses and returns a Ulimit from the specified string. -func Parse(val string) (*Ulimit, error) { - parts := strings.SplitN(val, "=", 2) - if len(parts) != 2 { - return nil, fmt.Errorf("invalid ulimit argument: %s", val) - } - - if _, exists := ulimitNameMapping[parts[0]]; !exists { - return nil, fmt.Errorf("invalid ulimit type: %s", parts[0]) - } - - limitVals := strings.SplitN(parts[1], ":", 2) - if len(limitVals) > 2 { - return nil, fmt.Errorf("too many limit value arguments - %s, can only have up to two, `soft[:hard]`", parts[1]) - } - - soft, err := strconv.ParseInt(limitVals[0], 10, 64) - if err != nil { - return nil, err - } - - hard := soft // in case no hard was set - if len(limitVals) == 2 { - hard, err = strconv.ParseInt(limitVals[1], 10, 64) - } - if soft > hard { - return nil, fmt.Errorf("ulimit soft limit must be less than or equal to hard limit: %d > %d", soft, hard) - } - - return &Ulimit{Name: parts[0], Soft: soft, Hard: hard}, nil -} - -// GetRlimit returns the RLimit corresponding to Ulimit. -func (u *Ulimit) GetRlimit() (*Rlimit, error) { - t, exists := ulimitNameMapping[u.Name] - if !exists { - return nil, fmt.Errorf("invalid ulimit name %s", u.Name) - } - - return &Rlimit{Type: t, Soft: uint64(u.Soft), Hard: uint64(u.Hard)}, nil -} - -func (u *Ulimit) String() string { - return fmt.Sprintf("%s=%d:%d", u.Name, u.Soft, u.Hard) -} diff --git a/components/engine/pkg/ulimit/ulimit_test.go b/components/engine/pkg/ulimit/ulimit_test.go deleted file mode 100644 index 1e8c881f51..0000000000 --- a/components/engine/pkg/ulimit/ulimit_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package ulimit - -import "testing" - -func TestParseValid(t *testing.T) { - u1 := &Ulimit{"nofile", 1024, 512} - if u2, _ := Parse("nofile=512:1024"); *u1 != *u2 { - t.Fatalf("expected %q, but got %q", u1, u2) - } -} - -func TestParseInvalidLimitType(t *testing.T) { - if _, err := Parse("notarealtype=1024:1024"); err == nil { - t.Fatalf("expected error on invalid ulimit type") - } -} - -func TestParseBadFormat(t *testing.T) { - if _, err := Parse("nofile:1024:1024"); err == nil { - t.Fatal("expected error on bad syntax") - } - - if _, err := Parse("nofile"); err == nil { - t.Fatal("expected error on bad syntax") - } - - if _, err := Parse("nofile="); err == nil { - t.Fatal("expected error on bad syntax") - } - if _, err := Parse("nofile=:"); err == nil { - t.Fatal("expected error on bad syntax") - } - if _, err := Parse("nofile=:1024"); err == nil { - t.Fatal("expected error on bad syntax") - } -} - -func TestParseHardLessThanSoft(t *testing.T) { - if _, err := Parse("nofile:1024:1"); err == nil { - t.Fatal("expected error on hard limit less than soft limit") - } -} - -func TestParseInvalidValueType(t *testing.T) { - if _, err := Parse("nofile:asdf"); err == nil { - t.Fatal("expected error on bad value type") - } -} - -func TestStringOutput(t *testing.T) { - u := &Ulimit{"nofile", 1024, 512} - if s := u.String(); s != "nofile=512:1024" { - t.Fatal("expected String to return nofile=512:1024, but got", s) - } -}