From e4e53bf486573739b50d9da5b7ccc998081f5aa7 Mon Sep 17 00:00:00 2001 From: Phil Estes Date: Fri, 16 Feb 2018 13:45:25 -0500 Subject: [PATCH] Add --with-ns flag to ctr run/create Adds a useful flag to `ctr` to enable joining any existing Linux namespaces for any namespace types (network, pid, ipc, etc.) using the existing With helper in the oci package. Signed-off-by: Phil Estes --- cmd/ctr/commands/run/run.go | 4 ++++ cmd/ctr/commands/run/run_unix.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/cmd/ctr/commands/run/run.go b/cmd/ctr/commands/run/run.go index 425845594..ce6bee015 100644 --- a/cmd/ctr/commands/run/run.go +++ b/cmd/ctr/commands/run/run.go @@ -65,6 +65,10 @@ var ContainerFlags = []cli.Flag{ Name: "tty,t", Usage: "allocate a TTY for the container", }, + cli.StringSliceFlag{ + Name: "with-ns", + Usage: "specify existing Linux namespaces to join at container runtime (format ':')", + }, } func loadSpec(path string, s *specs.Spec) error { diff --git a/cmd/ctr/commands/run/run_unix.go b/cmd/ctr/commands/run/run_unix.go index ef255ea1d..79ef5e576 100644 --- a/cmd/ctr/commands/run/run_unix.go +++ b/cmd/ctr/commands/run/run_unix.go @@ -4,11 +4,13 @@ package run import ( gocontext "context" + "strings" "github.com/containerd/containerd" "github.com/containerd/containerd/cmd/ctr/commands" "github.com/containerd/containerd/oci" specs "github.com/opencontainers/runtime-spec/specs-go" + "github.com/pkg/errors" "github.com/urfave/cli" ) @@ -78,6 +80,20 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli if context.Bool("net-host") { opts = append(opts, oci.WithHostNamespace(specs.NetworkNamespace), oci.WithHostHostsFile, oci.WithHostResolvconf) } + joinNs := context.StringSlice("with-ns") + for _, ns := range joinNs { + parts := strings.Split(ns, ":") + if len(parts) != 2 { + return nil, errors.New("joining a Linux namespace using --with-ns requires the format 'nstype:path'") + } + if !validNamespace(parts[0]) { + return nil, errors.New("the Linux namespace type specified in --with-ns is not valid: " + parts[0]) + } + opts = append(opts, oci.WithLinuxNamespace(specs.LinuxNamespace{ + Type: specs.LinuxNamespaceType(parts[0]), + Path: parts[1], + })) + } if context.IsSet("config") { var s specs.Spec if err := loadSpec(context.String("config"), &s); err != nil { @@ -101,3 +117,19 @@ func getNewTaskOpts(context *cli.Context) []containerd.NewTaskOpts { } return nil } + +func validNamespace(ns string) bool { + linuxNs := specs.LinuxNamespaceType(ns) + switch linuxNs { + case specs.PIDNamespace, + specs.NetworkNamespace, + specs.UTSNamespace, + specs.MountNamespace, + specs.UserNamespace, + specs.IPCNamespace, + specs.CgroupNamespace: + return true + default: + return false + } +}