From d0697f1a154816d6bd1065fee56b1f43f33c62d3 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Mon, 12 Dec 2016 22:12:56 +1100 Subject: [PATCH 1/4] cmd: generate: add --linux-namespace-* family of flags This allows users to modify what namespaces are used by a container. Signed-off-by: Aleksa Sarai --- cmd/oci-runtime-tool/generate.go | 45 ++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/cmd/oci-runtime-tool/generate.go b/cmd/oci-runtime-tool/generate.go index d0a18f6b1..8f219de70 100644 --- a/cmd/oci-runtime-tool/generate.go +++ b/cmd/oci-runtime-tool/generate.go @@ -47,6 +47,9 @@ var generateFlags = []cli.Flag{ cli.Uint64Flag{Name: "linux-mem-swap", Usage: "total memory limit (memory + swap) (in bytes)"}, cli.Uint64Flag{Name: "linux-mem-swappiness", Usage: "how aggressive the kernel will swap memory pages (Range from 0 to 100)"}, cli.StringFlag{Name: "linux-mems", Usage: "list of memory nodes in the cpuset (default is to use any available memory node)"}, + cli.StringSliceFlag{Name: "linux-namespace-add", Usage: "adds a namespace to the set of namespaces to create or join of the form 'ns[:path]'"}, + cli.StringSliceFlag{Name: "linux-namespace-remove", Usage: "removes a namespace from the set of namespaces to create or join of the form 'ns'"}, + cli.BoolFlag{Name: "linux-namespace-remove-all", Usage: "removes all namespaces from the set of namespaces created or joined"}, cli.IntFlag{Name: "linux-network-classid", Usage: "specifies class identifier tagged by container's network packets"}, cli.StringSliceFlag{Name: "linux-network-priorities", Usage: "specifies priorities of network traffic"}, cli.Int64Flag{Name: "linux-pids-limit", Usage: "maximum number of PIDs"}, @@ -461,6 +464,32 @@ func setupSpec(g *generate.Generator, context *cli.Context) error { } } + if context.IsSet("linux-namespace-add") { + namespaces := context.StringSlice("linux-namespace-add") + for _, ns := range namespaces { + name, path, err := parseNamespace(ns) + if err != nil { + return err + } + if err := g.AddOrReplaceLinuxNamespace(name, path); err != nil { + return err + } + } + } + + if context.IsSet("linux-namespace-remove") { + namespaces := context.StringSlice("linux-namespace-remove") + for _, name := range namespaces { + if err := g.RemoveLinuxNamespace(name); err != nil { + return err + } + } + } + + if context.Bool("linux-namespace-remove-all") { + g.ClearLinuxNamespaces() + } + if context.IsSet("rlimits-add") { rlimits := context.StringSlice("rlimits-add") for _, rlimit := range rlimits { @@ -608,6 +637,22 @@ func parseRlimit(rlimit string) (string, uint64, uint64, error) { return parts[0], uint64(hard), uint64(soft), nil } +func parseNamespace(ns string) (string, string, error) { + parts := strings.SplitN(ns, ":", 2) + if len(parts) == 0 || parts[0] == "" { + return "", "", fmt.Errorf("invalid namespace value: %s", ns) + } + + nsType := parts[0] + nsPath := "" + + if len(parts) == 2 { + nsPath = parts[1] + } + + return nsType, nsPath, nil +} + func addSeccomp(context *cli.Context, g *generate.Generator) error { // Set the DefaultAction of seccomp From fac26fa1a76283798bc42be5edce1604717a2966 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Wed, 21 Dec 2016 22:31:36 +1100 Subject: [PATCH 2/4] cmd: generate: remove old namespace flags --uts, --user and the other flags are not properly namespaced or extensible, so remove them in favour of the new --linux-namespace-* family of flags. Signed-off-by: Aleksa Sarai --- cmd/oci-runtime-tool/generate.go | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/cmd/oci-runtime-tool/generate.go b/cmd/oci-runtime-tool/generate.go index 8f219de70..6679330f9 100644 --- a/cmd/oci-runtime-tool/generate.go +++ b/cmd/oci-runtime-tool/generate.go @@ -24,7 +24,6 @@ var generateFlags = []cli.Flag{ cli.StringSliceFlag{Name: "bind", Usage: "bind mount directories src:dest[:options...]"}, cli.StringSliceFlag{Name: "cap-add", Usage: "add Linux capabilities"}, cli.StringSliceFlag{Name: "cap-drop", Usage: "drop Linux capabilities"}, - cli.StringFlag{Name: "cgroup", Usage: "cgroup namespace"}, cli.StringFlag{Name: "cgroups-path", Usage: "specify the path to the cgroups"}, cli.StringFlag{Name: "cwd", Value: "/", Usage: "current working directory for the process"}, cli.BoolFlag{Name: "disable-oom-kill", Usage: "disable OOM Killer"}, @@ -34,7 +33,6 @@ var generateFlags = []cli.Flag{ cli.StringSliceFlag{Name: "gidmappings", Usage: "add GIDMappings e.g HostID:ContainerID:Size"}, cli.StringSliceFlag{Name: "groups", Usage: "supplementary groups for the process"}, cli.StringFlag{Name: "hostname", Usage: "hostname value for the container"}, - cli.StringFlag{Name: "ipc", Usage: "ipc namespace"}, cli.StringSliceFlag{Name: "label", Usage: "add annotations to the configuration e.g. key=value"}, cli.Uint64Flag{Name: "linux-cpu-shares", Usage: "the relative share of CPU time available to the tasks in a cgroup"}, cli.Uint64Flag{Name: "linux-cpu-period", Usage: "the CPU period to be used for hardcapping (in usecs)"}, @@ -56,15 +54,12 @@ var generateFlags = []cli.Flag{ cli.Uint64Flag{Name: "linux-realtime-period", Usage: "CPU period to be used for realtime scheduling (in usecs)"}, cli.Uint64Flag{Name: "linux-realtime-runtime", Usage: "the time realtime scheduling may use (in usecs)"}, cli.StringSliceFlag{Name: "masked-paths", Usage: "specifies paths can not be read inside container"}, - cli.StringFlag{Name: "mount", Usage: "mount namespace"}, cli.StringFlag{Name: "mount-cgroups", Value: "no", Usage: "mount cgroups (rw,ro,no)"}, cli.StringFlag{Name: "mount-label", Usage: "selinux mount context label"}, - cli.StringFlag{Name: "network", Usage: "network namespace"}, cli.BoolFlag{Name: "no-new-privileges", Usage: "set no new privileges bit for the container process"}, cli.IntFlag{Name: "oom-score-adj", Usage: "oom_score_adj for the container"}, cli.StringFlag{Name: "os", Value: runtime.GOOS, Usage: "operating system the container is created for"}, cli.StringFlag{Name: "output", Usage: "output file (defaults to stdout)"}, - cli.StringFlag{Name: "pid", Usage: "pid namespace"}, cli.StringSliceFlag{Name: "poststart", Usage: "set command to run in poststart hooks"}, cli.StringSliceFlag{Name: "poststop", Usage: "set command to run in poststop hooks"}, cli.StringSliceFlag{Name: "prestart", Usage: "set command to run in prestart hooks"}, @@ -94,8 +89,6 @@ var generateFlags = []cli.Flag{ cli.BoolFlag{Name: "tty", Usage: "allocate a new tty for the container process"}, cli.IntFlag{Name: "uid", Usage: "uid for the process"}, cli.StringSliceFlag{Name: "uidmappings", Usage: "add UIDMappings e.g HostID:ContainerID:Size"}, - cli.StringFlag{Name: "user", Usage: "user namespace"}, - cli.StringFlag{Name: "uts", Usage: "uts namespace"}, } var generateCommand = cli.Command{ @@ -287,8 +280,6 @@ func setupSpec(g *generate.Generator, context *cli.Context) error { } } - needsNewUser := false - var uidMaps, gidMaps []string if context.IsSet("uidmappings") { @@ -299,12 +290,11 @@ func setupSpec(g *generate.Generator, context *cli.Context) error { gidMaps = context.StringSlice("gidmappings") } + // Add default user namespace. if len(uidMaps) > 0 || len(gidMaps) > 0 { - needsNewUser = true + g.AddOrReplaceLinuxNamespace("user", "") } - setupLinuxNamespaces(context, g, needsNewUser) - if context.IsSet("tmpfs") { tmpfsSlice := context.StringSlice("tmpfs") for _, s := range tmpfsSlice { @@ -519,20 +509,6 @@ func setupSpec(g *generate.Generator, context *cli.Context) error { return err } -func setupLinuxNamespaces(context *cli.Context, g *generate.Generator, needsNewUser bool) { - for _, nsName := range generate.Namespaces { - if !context.IsSet(nsName) && !(needsNewUser && nsName == "user") { - continue - } - nsPath := context.String(nsName) - if nsPath == "host" { - g.RemoveLinuxNamespace(nsName) - continue - } - g.AddOrReplaceLinuxNamespace(nsName, nsPath) - } -} - func parseIDMapping(idms string) (uint32, uint32, uint32, error) { idm := strings.Split(idms, ":") if len(idm) != 3 { From 3807b60000886ea7571d66ed115b21969a14c7ed Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Wed, 21 Dec 2016 22:36:27 +1100 Subject: [PATCH 3/4] man: update docs to use new --linux-namespace-* flags Signed-off-by: Aleksa Sarai --- man/oci-runtime-tool-generate.1.md | 58 ++++++++---------------------- 1 file changed, 15 insertions(+), 43 deletions(-) diff --git a/man/oci-runtime-tool-generate.1.md b/man/oci-runtime-tool-generate.1.md index f10a6d849..0253bffbb 100644 --- a/man/oci-runtime-tool-generate.1.md +++ b/man/oci-runtime-tool-generate.1.md @@ -45,12 +45,6 @@ read the configuration from `config.json`. **--cap-drop**=[] Drop Linux capabilities -**--cgroup**=*PATH* - Use a Cgroup namespace where *PATH* is an existing Cgroup namespace file - to join. The special *PATH* empty-string creates a new namespace. - The special *PATH* `host` removes any existing Cgroup namespace from - the configuration. - **--cgroups-path**="" Specifies the path to the cgroups relative to the cgroups mount point. @@ -65,7 +59,7 @@ read the configuration from `config.json`. This option allows you to specify arbitrary environment variables that are available for the process that will be launched inside of the container. - + **--env-file**=[] Set environment variables from a file. This option sets environment variables in the container from the @@ -88,12 +82,6 @@ read the configuration from `config.json`. **--hostname**="" Set the container host name that is available inside the container. -**--ipc**=*PATH* - Use an IPC namespace where *PATH* is an existing IPC namespace file - to join. The special *PATH* empty-string creates a new namespace. - The special *PATH* `host` removes any existing IPC namespace from the - configuration. - **--label**=[] Add annotations to the configuration e.g. key=value. @@ -130,6 +118,20 @@ read the configuration from `config.json`. **--linux-mems**=MEMS Sets the list of memory nodes in the cpuset (default is to use any available memory node). +**--linux-namespace-add**=NSNAME[:PATH] + Adds or replaces the given linux namespace NSNAME with a namespace entry that + has a path of PATH. Omitting PATH means that a new namespace will be created + by the container. + +**--linux-namespace-remove**=NSNAME + Removes a namespace from the set of namespaces configured in the container, + so that the host's namespace will be used by the container instead of + creating or joining another namespace. + +**--linux-namespace-remove-all** + Removes all namespaces from the set of namespaces configured for a container, + such that the container will effectively run on the host. + **--linux-network-classid**=CLASSID Specifies network class identifier which will be tagged by container's network packets. @@ -152,12 +154,6 @@ read the configuration from `config.json`. Specifies paths can not be read inside container. e.g. --masked-paths=/proc/kcore This option can be specified multiple times. -**--mount**=*PATH* - Use a mount namespace where *PATH* is an existing mount namespace file - to join. The special *PATH* empty-string creates a new namespace. - The special *PATH* `host` removes any existing mount namespace from the - configuration. - **--mount-cgroups**=[rw|ro|no] Mount cgroups. The default is `no`. @@ -173,12 +169,6 @@ read the configuration from `config.json`. "system_u:object_r:usr_t:s0" might be a good label for a readonly container, "system_u:system_r:svirt_sandbox_file_t:s0:c1,c2" for a read/write container. -**--network**=*PATH* - Use a network namespace where *PATH* is an existing network namespace file - to join. The special *PATH* empty-string creates a new namespace. - The special *PATH* `host` removes any existing network namespace from the - configuration. - **--no-new-privileges**=true|false Set no new privileges bit for the container process. Setting this flag will block the container processes from gaining any additional privileges @@ -196,12 +186,6 @@ read the configuration from `config.json`. file at *PATH* (overwriting the existing content if a file already exists at *PATH*). -**--pid**=*PATH* - Use a PID namespace where *PATH* is an existing PID namespace file - to join. The special *PATH* empty-string creates a new namespace. - The special *PATH* `host` removes any existing PID namespace from - the configuration. - **--poststart**=CMD[:ARGS...] Set command to run in poststart hooks. Can be specified multiple times. The multiple commands will be run in order before the container process @@ -329,18 +313,6 @@ read the configuration from `config.json`. **--uidmappings** Add UIDMappings e.g HostUID:ContainerID:Size. Implies **--user=**. -**--user**=*PATH* - Use a user namespace where *PATH* is an existing user namespace file - to join. The special *PATH* empty-string creates a new namespace. - The special *PATH* `host` removes any existing user namespace from - the configuration. - -**--uts**=*PATH* - Use a UTS namespace where *PATH* is an existing UTS namespace file - to join. The special *PATH* empty-string creates a new namespace. - The special *PATH* `host` removes any existing UTS namespace from - the configuration. - # EXAMPLES ## Generating container in read-only mode From eb189d57c18ebcec69ea3e929a85e51c967f2575 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Thu, 22 Dec 2016 01:15:09 +1100 Subject: [PATCH 4/4] completions: bash: update flags This is generated from "oci-runtime-tool generate -h". Signed-off-by: Aleksa Sarai --- completions/bash/oci-runtime-tool | 134 ++++++++++++++++-------------- 1 file changed, 71 insertions(+), 63 deletions(-) diff --git a/completions/bash/oci-runtime-tool b/completions/bash/oci-runtime-tool index 8966ee398..e4dd18551 100644 --- a/completions/bash/oci-runtime-tool +++ b/completions/bash/oci-runtime-tool @@ -292,72 +292,80 @@ _oci-runtime-tool_help() { _oci-runtime-tool_generate() { local options_with_args=" - --arch - --apparmor - --args - --bind - --cap-add - --cap-drop - --cgroup - --cgroup-path - --cwd - --disable-oom-kill - --env - --env-file - --gid - --gidmappings - --groups - --hostname - --help - --ipc - --label - --linux-network-classid - --linux-network-priorities - --linux-pids-limit - --masked-paths - --mount - --mount-cgroups - --mount-label - --network - --os - --output - --pid - --poststart - --poststop - --prestart - --readonly-paths - --rootfs-path - --rootfs-propagation - --rlimits-add - --rlimits-remove - --rlimits-remove-all - --seccomp-allow - --seccomp-arch - --seccomp-default - --seccomp-default-force - --seccomp-errno - --seccomp-kill - --seccomp-only - --seccomp-remove - --seccomp-remove-all - --seccomp-trace - --seccomp-trap - --seccomp-syscalls - --selinux-label - --sysctl - --tmplate - --tmpfs - --uid - --uidmappings - --user - --uts + --apparmor + --arch + --args + --bind + --cap-add + --cap-drop + --cgroups-path + --cwd + --env + --env-file + --gid + --gidmappings + --groups + --hostname + --label + --linux-cpu-shares + --linux-cpu-period + --linux-cpu-quota + --linux-cpus + --linux-mem-kernel-limit + --linux-mem-kernel-tcp + --linux-mem-limit + --linux-mem-reservation + --linux-mem-swap + --linux-mem-swappiness + --linux-mems + --linux-namespace-add + --linux-namespace-remove + --linux-network-classid + --linux-network-priorities + --linux-pids-limit + --linux-realtime-period + --linux-realtime-runtime + --masked-paths + --mount-cgroups + --mount-label + --oom-score-adj + --os + --output + --poststart + --poststop + --prestart + --readonly-paths + --rootfs-path + --rootfs-propagation + --rlimits-add + --rlimits-remove + --seccomp-allow + --seccomp-arch + --seccomp-default + --seccomp-default-force + --seccomp-errno + --seccomp-kill + --seccomp-remove + --seccomp-trace + --seccomp-trap + --selinux-label + --sysctl + --template + --tmpfs + --uid + --uidmappings " local boolean_options=" - --no-new-privileges - --privileged - --rootfs-readonly - --tty + --disable-oom-kill + --linux-namespace-remove-all + --no-new-privileges + --privileged + --rlimits-remove-all + --rootfs-readonly + --seccomp-only + --seccomp-remove-all + --tty " local all_options="$options_with_args $boolean_options"