diff --git a/api/server/router/build/build_routes.go b/api/server/router/build/build_routes.go index 9744033f76..4222004c07 100644 --- a/api/server/router/build/build_routes.go +++ b/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/api/types/client.go b/api/types/client.go index c588508e79..6501ec3120 100644 --- a/api/types/client.go +++ b/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/api/types/container/host_config.go b/api/types/container/host_config.go index e1d4ea4095..1e849bfa9f 100644 --- a/api/types/container/host_config.go +++ b/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/builder/dockerfile/builder.go b/builder/dockerfile/builder.go index 0db8c41880..102918da9a 100644 --- a/builder/dockerfile/builder.go +++ b/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/daemon/container_operations_unix.go b/daemon/container_operations_unix.go index 6c4f17704a..bdc80357ef 100644 --- a/daemon/container_operations_unix.go +++ b/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/daemon/execdriver/driver_unix.go b/daemon/execdriver/driver_unix.go index dae5d916c1..168b818cc8 100644 --- a/daemon/execdriver/driver_unix.go +++ b/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/integration-cli/docker_cli_build_unix_test.go b/integration-cli/docker_cli_build_unix_test.go index 599845a2ce..644d91bca5 100644 --- a/integration-cli/docker_cli_build_unix_test.go +++ b/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/pkg/ulimit/ulimit.go b/pkg/ulimit/ulimit.go deleted file mode 100644 index 8fb0d804de..0000000000 --- a/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/pkg/ulimit/ulimit_test.go b/pkg/ulimit/ulimit_test.go deleted file mode 100644 index 1e8c881f51..0000000000 --- a/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) - } -}