diff --git a/namespaces/execin.go b/namespaces/execin.go index 97bbb5f7..f44e92ab 100644 --- a/namespaces/execin.go +++ b/namespaces/execin.go @@ -21,14 +21,8 @@ func ExecIn(container *libcontainer.Container, nspid int, args []string) error { return err } - // TODO(vmarmol): Move this to the container JSON. - processLabel, err := label.GetPidCon(nspid) - if err != nil { - return err - } - // Enter the namespace and then finish setup - finalArgs := []string{os.Args[0], "nsenter", strconv.Itoa(nspid), processLabel, string(containerJson)} + finalArgs := []string{os.Args[0], "nsenter", "--nspid", strconv.Itoa(nspid), "--containerjson", string(containerJson), "--"} finalArgs = append(finalArgs, args...) if err := system.Execv(finalArgs[0], finalArgs[0:], os.Environ()); err != nil { return err @@ -37,7 +31,7 @@ func ExecIn(container *libcontainer.Container, nspid int, args []string) error { } // NsEnter is run after entering the namespace. -func NsEnter(container *libcontainer.Container, processLabel string, nspid int, args []string) error { +func NsEnter(container *libcontainer.Container, nspid int, args []string) error { // clear the current processes env and replace it with the environment // defined on the container if err := LoadContainerEnvironment(container); err != nil { @@ -46,9 +40,13 @@ func NsEnter(container *libcontainer.Container, processLabel string, nspid int, if err := FinalizeNamespace(container); err != nil { return err } - if err := label.SetProcessLabel(processLabel); err != nil { - return err + + if process_label, ok := container.Context["process_label"]; ok { + if err := label.SetProcessLabel(process_label); err != nil { + return err + } } + if err := system.Execv(args[0], args[0:], container.Env); err != nil { return err } diff --git a/namespaces/nsenter.go b/namespaces/nsenter.go index acf3d435..d5eaa271 100644 --- a/namespaces/nsenter.go +++ b/namespaces/nsenter.go @@ -15,6 +15,7 @@ package namespaces #include #include #include +#include static const kBufSize = 256; @@ -64,6 +65,10 @@ int setns(int fd, int nstype) { #endif #endif +void print_usage() { + fprintf(stderr, " nsenter --nspid --containerjson -- cmd1 arg1 arg2...\n"); +} + void nsenter() { int argc; char **argv; @@ -79,11 +84,40 @@ void nsenter() { fprintf(stderr, "nsenter: Incorrect usage, not enough arguments\n"); exit(1); } - pid_t init_pid = strtol(argv[2], NULL, 10); - if (errno != 0 || init_pid <= 0) { - fprintf(stderr, "nsenter: Failed to parse PID from \"%s\" with error: \"%s\"\n", argv[2], strerror(errno)); + + static const struct option longopts[] = { + { "nspid", required_argument, NULL, 'n' }, + { "containerjson", required_argument, NULL, 'c' }, + { NULL, 0, NULL, 0 } + }; + + int c; + pid_t init_pid = -1; + char *init_pid_str = NULL; + char *container_json = NULL; + while ((c = getopt_long_only(argc, argv, "n:s:c:", longopts, NULL)) != -1) { + switch (c) { + case 'n': + init_pid_str = optarg; + break; + case 'c': + container_json = optarg; + break; + } + } + + if (container_json == NULL || init_pid_str == NULL) { + print_usage(); exit(1); } + + init_pid = strtol(init_pid_str, NULL, 10); + if (errno != 0 || init_pid <= 0) { + fprintf(stderr, "nsenter: Failed to parse PID from \"%s\" with error: \"%s\"\n", init_pid_str, strerror(errno)); + print_usage(); + exit(1); + } + argc -= 3; argv += 3; diff --git a/nsinit/nsenter.go b/nsinit/nsenter.go index 8a9caa75..faa61315 100644 --- a/nsinit/nsenter.go +++ b/nsinit/nsenter.go @@ -2,7 +2,6 @@ package main import ( "log" - "strconv" "github.com/codegangsta/cli" "github.com/docker/libcontainer/namespaces" @@ -12,29 +11,30 @@ var nsenterCommand = cli.Command{ Name: "nsenter", Usage: "init process for entering an existing namespace", Action: nsenterAction, + Flags: []cli.Flag{ + cli.IntFlag{Name: "nspid"}, + cli.StringFlag{Name: "containerjson"}, + }, } func nsenterAction(context *cli.Context) { args := context.Args() - if len(args) < 4 { - log.Fatalf("incorrect usage: ...") + + if len(args) == 0 { + args = []string{"/bin/bash"} } - container, err := loadContainerFromJson(args.Get(2)) + container, err := loadContainerFromJson(context.String("containerjson")) if err != nil { log.Fatalf("unable to load container: %s", err) } - nspid, err := strconv.Atoi(args.Get(0)) - if err != nil { - log.Fatalf("unable to read pid: %s from %q", err, args.Get(0)) - } - + nspid := context.Int("nspid") if nspid <= 0 { log.Fatalf("cannot enter into namespaces without valid pid: %q", nspid) } - if err := namespaces.NsEnter(container, args.Get(1), nspid, args[3:]); err != nil { + if err := namespaces.NsEnter(container, nspid, args); err != nil { log.Fatalf("failed to nsenter: %s", err) } }