Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 47 additions & 26 deletions cmd/oci-runtime-tool/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
Expand All @@ -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)"},
Expand All @@ -47,21 +45,21 @@ 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"},
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"},
Expand Down Expand Up @@ -91,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{
Expand Down Expand Up @@ -284,8 +280,6 @@ func setupSpec(g *generate.Generator, context *cli.Context) error {
}
}

needsNewUser := false

var uidMaps, gidMaps []string

if context.IsSet("uidmappings") {
Expand All @@ -296,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", "")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will silently create an invalid config with --uidmappings=… --linux-namespace-add=user:foo, because the resulting config with call for tweaking a joined namespace. I'm pro-tweaking though, and we're already doing something silent about this case, so I'm ok with that ;). Folks who want to ensure validity can pass their final config through to validate as a separate step.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it'll generate an invalid config, because the --linux-namespace-add handling is done afterwards and so the user entry will be replaced.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, sorry, it will generate an invalid config, but the user asked us to generate it...

}

setupLinuxNamespaces(context, g, needsNewUser)

if context.IsSet("tmpfs") {
tmpfsSlice := context.StringSlice("tmpfs")
for _, s := range tmpfsSlice {
Expand Down Expand Up @@ -461,6 +454,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 {
Expand Down Expand Up @@ -490,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 {
Expand Down Expand Up @@ -608,6 +613,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)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't check parts[0], then :testpat will also be a valid value. Though user set it, I think we should warn user it's invalid, as I did in #292

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can validate it against the spec's whitelist. But I'm fine punting validation to a post-generate call (for callers who care). Maybe they intend to fix the values in post-processing.

Copy link
Member Author

@cyphar cyphar Dec 23, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've fixed it to check parts[0]. The whitelist checking should be done in the generate library (IMO), and I'll punt it for now. I mean, we don't actually have tests for generate at all -- so maybe we should do that first? 😉

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what kind of tests?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There aren't any unit tests or integration tests for oci-runtime-tool. We should probably add some. Also, this tool isn't versioned which makes packaging annoying.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More importantly, as far as I can tell there's no tests of the validation -- which is quite worrying.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we should add unit tests. unit tests for validation already in #273

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd floated some sharness stubs for testing in #180. Happy to rebase if there is renewed interest.

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
Expand Down
134 changes: 71 additions & 63 deletions completions/bash/oci-runtime-tool
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Loading