From f6aad9da226026e840735ba3f3f712c9d2e2e129 Mon Sep 17 00:00:00 2001 From: Ma Shimiao Date: Tue, 15 Nov 2016 14:03:23 +0800 Subject: [PATCH 1/2] generate: add rlimit related options Signed-off-by: Ma Shimiao --- cmd/oci-runtime-tool/generate.go | 47 ++++++++++++++++++++++++++++++++ generate/generate.go | 41 ++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/cmd/oci-runtime-tool/generate.go b/cmd/oci-runtime-tool/generate.go index a71ef2090..1ddef0c0e 100644 --- a/cmd/oci-runtime-tool/generate.go +++ b/cmd/oci-runtime-tool/generate.go @@ -65,6 +65,9 @@ var generateFlags = []cli.Flag{ cli.StringFlag{Name: "rootfs-path", Value: "rootfs", Usage: "path to the root filesystem"}, cli.StringFlag{Name: "rootfs-propagation", Usage: "mount propagation for rootfs"}, cli.BoolFlag{Name: "rootfs-readonly", Usage: "make the container's rootfs readonly"}, + cli.StringSliceFlag{Name: "rlimits-add", Usage: "specifies resource limits for processes inside the container. "}, + cli.StringSliceFlag{Name: "rlimits-remove", Usage: "remove specified resource limits for processes inside the container. "}, + cli.BoolFlag{Name: "rlimits-remove-all", Usage: "remove all resource limits for processes inside the container. "}, cli.StringFlag{Name: "seccomp-allow", Usage: "specifies syscalls to respond with allow"}, cli.StringFlag{Name: "seccomp-arch", Usage: "specifies additional architectures permitted to be used for system calls"}, cli.StringFlag{Name: "seccomp-default", Usage: "specifies default action to be used for system calls and removes existing rules with specified action"}, @@ -445,6 +448,31 @@ func setupSpec(g *generate.Generator, context *cli.Context) error { } } + if context.IsSet("rlimits-add") { + rlimits := context.StringSlice("rlimits-add") + for _, rlimit := range rlimits { + rType, rHard, rSoft, err := parseRlimit(rlimit) + if err != nil { + return err + } + g.AddProcessRlimits(rType, rHard, rSoft) + } + } + + if context.IsSet("rlimits-remove") { + rlimits := context.StringSlice("rlimits-remove") + for _, rlimit := range rlimits { + err := g.RemoveProcessRlimits(rlimit) + if err != nil { + return err + } + } + } + + if context.IsSet("rlimits-remove-all") { + g.ClearProcessRlimits() + } + err := addSeccomp(context, g) return err } @@ -548,6 +576,25 @@ func parseBindMount(s string) (string, string, []string, error) { return source, dest, options, nil } +func parseRlimit(rlimit string) (string, uint64, uint64, error) { + parts := strings.Split(rlimit, ":") + if len(parts) != 3 { + return "", 0, 0, fmt.Errorf("invalid rlimits value: %s", rlimit) + } + + hard, err := strconv.Atoi(parts[1]) + if err != nil { + return "", 0, 0, err + } + + soft, err := strconv.Atoi(parts[2]) + if err != nil { + return "", 0, 0, err + } + + return parts[0], uint64(hard), uint64(soft), nil +} + func addSeccomp(context *cli.Context, g *generate.Generator) error { // Set the DefaultAction of seccomp diff --git a/generate/generate.go b/generate/generate.go index dc6d2efd3..e8c364162 100644 --- a/generate/generate.go +++ b/generate/generate.go @@ -337,6 +337,47 @@ func (g *Generator) AddProcessEnv(env string) { g.spec.Process.Env = append(g.spec.Process.Env, env) } +// AddProcessRlimits adds rlimit into g.spec.Process.Rlimits. +func (g *Generator) AddProcessRlimits(rType string, rHard uint64, rSoft uint64) { + g.initSpec() + for i, rlimit := range g.spec.Process.Rlimits { + if rlimit.Type == rType { + g.spec.Process.Rlimits[i].Hard = rHard + g.spec.Process.Rlimits[i].Soft = rSoft + return + } + } + + newRlimit := rspec.Rlimit{ + Type: rType, + Hard: rHard, + Soft: rSoft, + } + g.spec.Process.Rlimits = append(g.spec.Process.Rlimits, newRlimit) +} + +// RemoveProcessRlimits removes a rlimit from g.spec.Process.Rlimits. +func (g *Generator) RemoveProcessRlimits(rType string) error { + if g.spec == nil { + return nil + } + for i, rlimit := range g.spec.Process.Rlimits { + if rlimit.Type == rType { + g.spec.Process.Rlimits = append(g.spec.Process.Rlimits[:i], g.spec.Process.Rlimits[i+1:]...) + return nil + } + } + return nil +} + +// ClearProcessRlimits clear g.spec.Process.Rlimits. +func (g *Generator) ClearProcessRlimits() { + if g.spec == nil { + return + } + g.spec.Process.Rlimits = []rspec.Rlimit{} +} + // ClearProcessAdditionalGids clear g.spec.Process.AdditionalGids. func (g *Generator) ClearProcessAdditionalGids() { if g.spec == nil { From aa80849b4e5d03f5256d0ba19dc3e55c2dbb0ba6 Mon Sep 17 00:00:00 2001 From: Ma Shimiao Date: Tue, 15 Nov 2016 14:27:40 +0800 Subject: [PATCH 2/2] man: add rlimits related manpages Signed-off-by: Ma Shimiao --- completions/bash/oci-runtime-tool | 3 +++ man/oci-runtime-tool-generate.1.md | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/completions/bash/oci-runtime-tool b/completions/bash/oci-runtime-tool index 1fb9c8b95..6737c740c 100644 --- a/completions/bash/oci-runtime-tool +++ b/completions/bash/oci-runtime-tool @@ -303,6 +303,9 @@ _oci-runtime-tool_generate() { --readonly-paths --rootfs-path --rootfs-propagation + --rlimits-add + --rlimits-remove + --rlimits-remove-all --seccomp-allow --seccomp-arch --seccomp-default diff --git a/man/oci-runtime-tool-generate.1.md b/man/oci-runtime-tool-generate.1.md index ebf65d78a..b4f118bce 100644 --- a/man/oci-runtime-tool-generate.1.md +++ b/man/oci-runtime-tool-generate.1.md @@ -237,6 +237,17 @@ read the configuration from `config.json`. By default a container will have its root filesystem writable allowing processes to write files anywhere. By specifying the `--rootfs-readonly` flag the container will have its root filesystem mounted as read only prohibiting any writes. +**--rlimits-add**=[] + Specifies resource limits, format is RLIMIT:HARD:SOFT. e.g. --rlimits-add=RLIMIT_NOFILE:1024:1024 + This option can be specified multiple times. When same RLIMIT specified over once, the last one make sense. + +**--rlimits-remove**=[] + Remove the specified resource limits for process inside the container. + This option can be specified multiple times. + +**--rlimits-remove-all**=true|false + Remove all resource limits for process inside the container. The default is *false*. + **--seccomp-allow**=SYSCALL Specifies syscalls to be added to the ALLOW list. See --seccomp-syscalls for setting limits on arguments.