Skip to content

Commit

Permalink
Merge pull request #1179 from Ace-Tang/run_flag_ulimit
Browse files Browse the repository at this point in the history
feature: add run flag ulimit
  • Loading branch information
allencloud authored Apr 26, 2018
2 parents 00f4f6e + c0ea209 commit 6d7aa83
Show file tree
Hide file tree
Showing 12 changed files with 225 additions and 65 deletions.
26 changes: 15 additions & 11 deletions apis/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2258,17 +2258,7 @@ definitions:
A list of resource limits to set in the container. For example: `{"Name": "nofile", "Soft": 1024, "Hard": 2048}`"
type: "array"
items:
type: "object"
properties:
Name:
description: "Name of ulimit"
type: "string"
Soft:
description: "Soft limit"
type: "integer"
Hard:
description: "Hard limit"
type: "integer"
$ref: "#/definitions/Ulimit"
# Applicable to Windows
CpuCount:
description: |
Expand Down Expand Up @@ -2372,6 +2362,20 @@ definitions:
PathInContainer: "/dev/deviceName"
CgroupPermissions: "mrw"

Ulimit:
type: "object"
description: "A list of resource limits"
properties:
Name:
description: "Name of ulimit"
type: "string"
Soft:
description: "Soft limit"
type: "integer"
Hard:
description: "Hard limit"
type: "integer"

Container:
description: |
an array of Container contains response of Engine API:
Expand Down
51 changes: 1 addition & 50 deletions apis/types/resources.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 62 additions & 0 deletions apis/types/ulimit.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions cli/common_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ func addCommonFlags(flagSet *pflag.FlagSet) *container {
// blkio
flagSet.Uint16Var(&c.blkioWeight, "blkio-weight", 0, "Block IO (relative weight), between 10 and 1000, or 0 to disable")
flagSet.Var(&c.blkioWeightDevice, "blkio-weight-device", "Block IO weight (relative device weight)")
flagSet.Var(&c.blkioDeviceReadBps, "device-read-bps", "Limit read rate (bytes per second) from a device")
flagSet.Var(&c.blkioDeviceReadIOps, "device-read-iops", "Limit read rate (IO per second) from a device")
flagSet.Var(&c.blkioDeviceWriteBps, "device-write-bps", "Limit write rate (bytes per second) from a device")
flagSet.Var(&c.blkioDeviceWriteIOps, "device-write-iops", "Limit write rate (IO per second) from a device")

// capbilities
flagSet.StringSliceVar(&c.capAdd, "cap-add", nil, "Add Linux capabilities")
Expand All @@ -25,10 +29,6 @@ func addCommonFlags(flagSet *pflag.FlagSet) *container {

// device related options
flagSet.StringSliceVarP(&c.devices, "device", "", nil, "Add a host device to the container")
flagSet.Var(&c.blkioDeviceReadBps, "device-read-bps", "Limit read rate (bytes per second) from a device")
flagSet.Var(&c.blkioDeviceReadIOps, "device-read-iops", "Limit read rate (IO per second) from a device")
flagSet.Var(&c.blkioDeviceWriteBps, "device-write-bps", "Limit write rate (bytes per second) from a device")
flagSet.Var(&c.blkioDeviceWriteIOps, "device-write-iops", "Limit write rate (IO per second) from a device")

flagSet.BoolVar(&c.enableLxcfs, "enableLxcfs", false, "Enable lxcfs for the container, only effective when enable-lxcfs switched on in Pouchd")
flagSet.StringVar(&c.entrypoint, "entrypoint", "", "Overwrite the default ENTRYPOINT of the image")
Expand Down Expand Up @@ -83,6 +83,7 @@ func addCommonFlags(flagSet *pflag.FlagSet) *container {
flagSet.StringSliceVar(&c.volumesFrom, "volumes-from", nil, "set volumes from other containers, format is <container>[:mode]")

flagSet.StringVarP(&c.workdir, "workdir", "w", "", "Set the working directory in a container")
flagSet.Var(&c.ulimit, "ulimit", "Set container ulimit")

flagSet.BoolVar(&c.rich, "rich", false, "Start container in rich container mode. (default false)")
flagSet.StringVar(&c.richMode, "rich-mode", "", "Choose one rich container mode. dumb-init(default), systemd, sbin-init")
Expand Down
2 changes: 2 additions & 0 deletions cli/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ type container struct {
oomScoreAdj int64
specAnnotation []string
cgroupParent string
ulimit Ulimit

//add for rich container mode
rich bool
Expand Down Expand Up @@ -221,6 +222,7 @@ func (c *container) config() (*types.ContainerCreateConfig, error) {
Devices: deviceMappings,
IntelRdtL3Cbm: intelRdtL3Cbm,
CgroupParent: c.cgroupParent,
Ulimits: c.ulimit.value(),
},
EnableLxcfs: c.enableLxcfs,
Privileged: c.privileged,
Expand Down
58 changes: 58 additions & 0 deletions cli/ulimit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package main

import (
"fmt"

"github.com/alibaba/pouch/apis/types"

units "github.com/docker/go-units"
)

// Ulimit defines ulimit options.
type Ulimit struct {
values map[string]*units.Ulimit
}

// Set implement Ulimit as pflag.Value interface.
func (u *Ulimit) Set(val string) error {
ul, err := units.ParseUlimit(val)
if err != nil {
return err
}

if u.values == nil {
u.values = make(map[string]*units.Ulimit)
}

u.values[ul.Name] = ul
return nil
}

// String implement Ulimit as pflag.Value interface.
func (u *Ulimit) String() string {
var str []string
for _, ul := range u.values {
str = append(str, ul.String())
}

return fmt.Sprintf("%v", str)
}

// Type implement Ulimit as pflag.Value interface.
func (u *Ulimit) Type() string {
return "value"
}

// value return ulimit values as type ResourcesUlimitsItems0
func (u *Ulimit) value() []*types.Ulimit {
var ulimit []*types.Ulimit
for _, ul := range u.values {
ulimit = append(ulimit, &types.Ulimit{
Name: ul.Name,
Hard: ul.Hard,
Soft: ul.Soft,
})
}

return ulimit
}
5 changes: 5 additions & 0 deletions daemon/mgr/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,11 @@ func (mgr *ContainerManager) StartExec(ctx context.Context, execid string, confi
return err
}

// set exec process ulimit
if err := setupRlimits(ctx, c.meta.HostConfig, &specs.Spec{Process: process}); err != nil {
return err
}

execConfig.Running = true
defer func() {
if err != nil {
Expand Down
19 changes: 19 additions & 0 deletions daemon/mgr/spec_process.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"io/ioutil"
"os"
"strings"

"github.com/alibaba/pouch/apis/types"
"github.com/alibaba/pouch/pkg/user"
Expand Down Expand Up @@ -53,6 +54,10 @@ func setupProcess(ctx context.Context, c *ContainerMeta, s *specs.Spec) error {
return err
}

if err := setupRlimits(ctx, c.HostConfig, s); err != nil {
return err
}

if err := setupAppArmor(ctx, c, s); err != nil {
return err
}
Expand Down Expand Up @@ -158,3 +163,17 @@ func setupAppArmor(ctx context.Context, c *ContainerMeta, s *specs.Spec) error {

return nil
}

func setupRlimits(ctx context.Context, hostConfig *types.HostConfig, s *specs.Spec) error {
var rlimits []specs.POSIXRlimit
for _, ul := range hostConfig.Ulimits {
rlimits = append(rlimits, specs.POSIXRlimit{
Type: "RLIMIT_" + strings.ToUpper(ul.Name),
Hard: uint64(ul.Hard),
Soft: uint64(ul.Soft),
})
}

s.Process.Rlimits = rlimits
return nil
}
16 changes: 16 additions & 0 deletions test/cli_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,3 +434,19 @@ func (suite *PouchCreateSuite) TestCreateWithAnnotation(c *check.C) {
c.Assert(util.PartialEqual(annotationStr, "a=b"), check.IsNil)
c.Assert(util.PartialEqual(annotationStr, "foo=bar"), check.IsNil)
}

// TestCreateWithUlimit tests creating container with annotation.
func (suite *PouchCreateSuite) TestCreateWithUlimit(c *check.C) {
cname := "TestCreateWithUlimit"
command.PouchRun("create", "--ulimit", "nproc=21", "--name", cname, busyboxImage).Assert(c, icmd.Success)

output := command.PouchRun("inspect", cname).Stdout()
result := []types.ContainerJSON{}
if err := json.Unmarshal([]byte(output), &result); err != nil {
c.Errorf("failed to decode inspect output: %v", err)
}
ul := result[0].HostConfig.Ulimits[0]
c.Assert(ul.Name, check.Equals, "nproc")
c.Assert(int(ul.Hard), check.Equals, 21)
c.Assert(int(ul.Soft), check.Equals, 21)
}
10 changes: 10 additions & 0 deletions test/cli_exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,13 @@ func (suite *PouchExecSuite) TestExecAfterContainerRestart(c *check.C) {
c.Errorf("failed to exec in container: %s", out)
}
}

// TestExecUlimit test ulimit set container.
func (suite *PouchExecSuite) TestExecUlimit(c *check.C) {
name := "TestExecUlimit"
command.PouchRun("run", "-d", "--name", name, "--ulimit", "nproc=256", busyboxImage, "top").Assert(c, icmd.Success)
defer DelContainerForceMultyTime(c, name)

out := command.PouchRun("exec", name, "sh", "-c", "ulimit -p").Stdout()
c.Assert(out, check.Equals, "256\n")
}
21 changes: 21 additions & 0 deletions test/cli_run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1027,3 +1027,24 @@ func (suite *PouchRunSuite) TestRunWithVolumesFromWithDupclicate(c *check.C) {

c.Assert(volumeFound, check.Equals, true)
}

// TestRunWithUlimit tests running container with --ulimit flag.
func (suite *PouchRunSuite) TestRunWithUlimit(c *check.C) {
cname := "TestRunWithUlimit"
res := command.PouchRun("run", "--ulimit", "nproc=256", "--name", cname, busyboxImage, "sh", "-c", "ulimit -p")
res.Assert(c, icmd.Success)

out := res.Stdout()
c.Assert(out, check.Equals, "256\n")

output := command.PouchRun("inspect", cname).Stdout()
result := []types.ContainerJSON{}
if err := json.Unmarshal([]byte(output), &result); err != nil {
c.Errorf("failed to decode inspect output: %v", err)
}
ul := result[0].HostConfig.Ulimits[0]
c.Assert(ul.Name, check.Equals, "nproc")
c.Assert(int(ul.Hard), check.Equals, 256)
c.Assert(int(ul.Soft), check.Equals, 256)

}
11 changes: 11 additions & 0 deletions test/cli_start_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,3 +267,14 @@ func (suite *PouchStartSuite) TestStartWithExitCode(c *check.C) {
}
c.Assert(result[0].State.ExitCode, check.Equals, int64(101))
}

// TestStartWithUlimit starts a container with --ulimit.
func (suite *PouchStartSuite) TestStartWithUlimit(c *check.C) {
name := "start-ulimit"

res := command.PouchRun("create", "--name", name, "--ulimit", "nproc=256", busyboxImage)
res.Assert(c, icmd.Success)
defer DelContainerForceMultyTime(c, name)

command.PouchRun("start", name).Assert(c, icmd.Success)
}

0 comments on commit 6d7aa83

Please sign in to comment.