diff --git a/libcontainer/nsinit/exec.go b/libcontainer/nsinit/exec.go index ef33d3a..d4ce1ca 100644 --- a/libcontainer/nsinit/exec.go +++ b/libcontainer/nsinit/exec.go @@ -19,17 +19,19 @@ var execCommand = cli.Command{ } func execAction(context *cli.Context) { - var ( - err error - nspid, exitCode int - ) + var nspid, exitCode int + + container, err := loadContainer() + if err != nil { + log.Fatal(err) + } if nspid, err = readPid(); err != nil && !os.IsNotExist(err) { log.Fatalf("unable to read pid: %s", err) } if nspid > 0 { - exitCode, err = namespaces.ExecIn(container, nspid, []string(context.Args())) + err = namespaces.ExecIn(container, nspid, []string(context.Args())) } else { term := namespaces.NewTerminal(os.Stdin, os.Stdout, os.Stderr, container.Tty) exitCode, err = startContainer(container, term, dataPath, []string(context.Args())) diff --git a/libcontainer/nsinit/init.go b/libcontainer/nsinit/init.go index 561b93b..20096f0 100644 --- a/libcontainer/nsinit/init.go +++ b/libcontainer/nsinit/init.go @@ -22,6 +22,11 @@ var ( ) func initAction(context *cli.Context) { + container, err := loadContainer() + if err != nil { + log.Fatal(err) + } + rootfs, err := os.Getwd() if err != nil { log.Fatal(err) diff --git a/libcontainer/nsinit/main.go b/libcontainer/nsinit/main.go index 29b80ba..20132de 100644 --- a/libcontainer/nsinit/main.go +++ b/libcontainer/nsinit/main.go @@ -5,21 +5,15 @@ import ( "os" "github.com/codegangsta/cli" - "github.com/dotcloud/docker/pkg/libcontainer" ) -var ( - container *libcontainer.Container - logPath = os.Getenv("log") -) - -func preload(context *cli.Context) (err error) { - container, err = loadContainer() - if err != nil { - return err - } +var logPath = os.Getenv("log") +func preload(context *cli.Context) error { if logPath != "" { + if err := openLog(logPath); err != nil { + return err + } } return nil @@ -37,6 +31,7 @@ func main() { initCommand, statsCommand, specCommand, + nsenterCommand, } if err := app.Run(os.Args); err != nil { diff --git a/libcontainer/nsinit/nsenter.go b/libcontainer/nsinit/nsenter.go new file mode 100644 index 0000000..5464428 --- /dev/null +++ b/libcontainer/nsinit/nsenter.go @@ -0,0 +1,40 @@ +package main + +import ( + "log" + "strconv" + + "github.com/codegangsta/cli" + "github.com/dotcloud/docker/pkg/libcontainer/namespaces" +) + +var nsenterCommand = cli.Command{ + Name: "nsenter", + Usage: "init process for entering an existing namespace", + Action: nsenterAction, +} + +func nsenterAction(context *cli.Context) { + args := context.Args() + if len(args) < 4 { + log.Fatalf("incorrect usage: ...") + } + + container, err := loadContainerFromJson(args.Get(2)) + 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)) + } + + 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 { + log.Fatalf("failed to nsenter: %s", err) + } +} diff --git a/libcontainer/nsinit/spec.go b/libcontainer/nsinit/spec.go index 92a2f64..2eb4da9 100644 --- a/libcontainer/nsinit/spec.go +++ b/libcontainer/nsinit/spec.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "log" - "os" "github.com/codegangsta/cli" "github.com/dotcloud/docker/pkg/libcontainer" @@ -17,15 +16,17 @@ var specCommand = cli.Command{ } func specAction(context *cli.Context) { - // returns the spec of the current container. + container, err := loadContainer() + if err != nil { + log.Fatal(err) + } + spec, err := getContainerSpec(container) if err != nil { - log.Printf("Failed to get spec - %v\n", err) - os.Exit(1) + log.Fatalf("Failed to get spec - %v\n", err) } - fmt.Printf("Spec:\n%v\n", spec) - os.Exit(0) + fmt.Printf("Spec:\n%v\n", spec) } // returns the container spec in json format. @@ -34,5 +35,6 @@ func getContainerSpec(container *libcontainer.Container) (string, error) { if err != nil { return "", err } + return string(spec), nil } diff --git a/libcontainer/nsinit/stats.go b/libcontainer/nsinit/stats.go index 0e93082..023b40a 100644 --- a/libcontainer/nsinit/stats.go +++ b/libcontainer/nsinit/stats.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "log" - "os" "github.com/codegangsta/cli" "github.com/dotcloud/docker/pkg/libcontainer" @@ -18,14 +17,17 @@ var statsCommand = cli.Command{ } func statsAction(context *cli.Context) { - // returns the stats of the current container. + container, err := loadContainer() + if err != nil { + log.Fatal(err) + } + stats, err := getContainerStats(container) if err != nil { - log.Printf("Failed to get stats - %v\n", err) - os.Exit(1) + log.Fatalf("Failed to get stats - %v\n", err) } + fmt.Printf("Stats:\n%v\n", stats) - os.Exit(0) } // returns the container stats in json format. @@ -34,9 +36,11 @@ func getContainerStats(container *libcontainer.Container) (string, error) { if err != nil { return "", err } + out, err := json.MarshalIndent(stats, "", "\t") if err != nil { return "", err } + return string(out), nil } diff --git a/libcontainer/nsinit/utils.go b/libcontainer/nsinit/utils.go index fc311a3..9926e27 100644 --- a/libcontainer/nsinit/utils.go +++ b/libcontainer/nsinit/utils.go @@ -50,3 +50,13 @@ func openLog(name string) error { return nil } + +func loadContainerFromJson(rawData string) (*libcontainer.Container, error) { + var container *libcontainer.Container + + if err := json.Unmarshal([]byte(rawData), &container); err != nil { + return nil, err + } + + return container, nil +}