| ... | ... |
@@ -19,17 +19,19 @@ var execCommand = cli.Command{
|
| 19 | 19 |
} |
| 20 | 20 |
|
| 21 | 21 |
func execAction(context *cli.Context) {
|
| 22 |
- var ( |
|
| 23 |
- err error |
|
| 24 |
- nspid, exitCode int |
|
| 25 |
- ) |
|
| 22 |
+ var nspid, exitCode int |
|
| 23 |
+ |
|
| 24 |
+ container, err := loadContainer() |
|
| 25 |
+ if err != nil {
|
|
| 26 |
+ log.Fatal(err) |
|
| 27 |
+ } |
|
| 26 | 28 |
|
| 27 | 29 |
if nspid, err = readPid(); err != nil && !os.IsNotExist(err) {
|
| 28 | 30 |
log.Fatalf("unable to read pid: %s", err)
|
| 29 | 31 |
} |
| 30 | 32 |
|
| 31 | 33 |
if nspid > 0 {
|
| 32 |
- exitCode, err = namespaces.ExecIn(container, nspid, []string(context.Args())) |
|
| 34 |
+ err = namespaces.ExecIn(container, nspid, []string(context.Args())) |
|
| 33 | 35 |
} else {
|
| 34 | 36 |
term := namespaces.NewTerminal(os.Stdin, os.Stdout, os.Stderr, container.Tty) |
| 35 | 37 |
exitCode, err = startContainer(container, term, dataPath, []string(context.Args())) |
| ... | ... |
@@ -5,21 +5,15 @@ import ( |
| 5 | 5 |
"os" |
| 6 | 6 |
|
| 7 | 7 |
"github.com/codegangsta/cli" |
| 8 |
- "github.com/dotcloud/docker/pkg/libcontainer" |
|
| 9 | 8 |
) |
| 10 | 9 |
|
| 11 |
-var ( |
|
| 12 |
- container *libcontainer.Container |
|
| 13 |
- logPath = os.Getenv("log")
|
|
| 14 |
-) |
|
| 15 |
- |
|
| 16 |
-func preload(context *cli.Context) (err error) {
|
|
| 17 |
- container, err = loadContainer() |
|
| 18 |
- if err != nil {
|
|
| 19 |
- return err |
|
| 20 |
- } |
|
| 10 |
+var logPath = os.Getenv("log")
|
|
| 21 | 11 |
|
| 12 |
+func preload(context *cli.Context) error {
|
|
| 22 | 13 |
if logPath != "" {
|
| 14 |
+ if err := openLog(logPath); err != nil {
|
|
| 15 |
+ return err |
|
| 16 |
+ } |
|
| 23 | 17 |
} |
| 24 | 18 |
|
| 25 | 19 |
return nil |
| ... | ... |
@@ -37,6 +31,7 @@ func main() {
|
| 37 | 37 |
initCommand, |
| 38 | 38 |
statsCommand, |
| 39 | 39 |
specCommand, |
| 40 |
+ nsenterCommand, |
|
| 40 | 41 |
} |
| 41 | 42 |
|
| 42 | 43 |
if err := app.Run(os.Args); err != nil {
|
| 43 | 44 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,40 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "log" |
|
| 4 |
+ "strconv" |
|
| 5 |
+ |
|
| 6 |
+ "github.com/codegangsta/cli" |
|
| 7 |
+ "github.com/dotcloud/docker/pkg/libcontainer/namespaces" |
|
| 8 |
+) |
|
| 9 |
+ |
|
| 10 |
+var nsenterCommand = cli.Command{
|
|
| 11 |
+ Name: "nsenter", |
|
| 12 |
+ Usage: "init process for entering an existing namespace", |
|
| 13 |
+ Action: nsenterAction, |
|
| 14 |
+} |
|
| 15 |
+ |
|
| 16 |
+func nsenterAction(context *cli.Context) {
|
|
| 17 |
+ args := context.Args() |
|
| 18 |
+ if len(args) < 4 {
|
|
| 19 |
+ log.Fatalf("incorrect usage: <pid> <process label> <container JSON> <cmd>...")
|
|
| 20 |
+ } |
|
| 21 |
+ |
|
| 22 |
+ container, err := loadContainerFromJson(args.Get(2)) |
|
| 23 |
+ if err != nil {
|
|
| 24 |
+ log.Fatalf("unable to load container: %s", err)
|
|
| 25 |
+ } |
|
| 26 |
+ |
|
| 27 |
+ nspid, err := strconv.Atoi(args.Get(0)) |
|
| 28 |
+ if err != nil {
|
|
| 29 |
+ log.Fatalf("unable to read pid: %s from %q", err, args.Get(0))
|
|
| 30 |
+ } |
|
| 31 |
+ |
|
| 32 |
+ if nspid <= 0 {
|
|
| 33 |
+ log.Fatalf("cannot enter into namespaces without valid pid: %q", nspid)
|
|
| 34 |
+ } |
|
| 35 |
+ |
|
| 36 |
+ if err := namespaces.NsEnter(container, args.Get(1), nspid, args[3:]); err != nil {
|
|
| 37 |
+ log.Fatalf("failed to nsenter: %s", err)
|
|
| 38 |
+ } |
|
| 39 |
+} |
| ... | ... |
@@ -4,7 +4,6 @@ import ( |
| 4 | 4 |
"encoding/json" |
| 5 | 5 |
"fmt" |
| 6 | 6 |
"log" |
| 7 |
- "os" |
|
| 8 | 7 |
|
| 9 | 8 |
"github.com/codegangsta/cli" |
| 10 | 9 |
"github.com/dotcloud/docker/pkg/libcontainer" |
| ... | ... |
@@ -17,15 +16,17 @@ var specCommand = cli.Command{
|
| 17 | 17 |
} |
| 18 | 18 |
|
| 19 | 19 |
func specAction(context *cli.Context) {
|
| 20 |
- // returns the spec of the current container. |
|
| 20 |
+ container, err := loadContainer() |
|
| 21 |
+ if err != nil {
|
|
| 22 |
+ log.Fatal(err) |
|
| 23 |
+ } |
|
| 24 |
+ |
|
| 21 | 25 |
spec, err := getContainerSpec(container) |
| 22 | 26 |
if err != nil {
|
| 23 |
- log.Printf("Failed to get spec - %v\n", err)
|
|
| 24 |
- os.Exit(1) |
|
| 27 |
+ log.Fatalf("Failed to get spec - %v\n", err)
|
|
| 25 | 28 |
} |
| 26 |
- fmt.Printf("Spec:\n%v\n", spec)
|
|
| 27 |
- os.Exit(0) |
|
| 28 | 29 |
|
| 30 |
+ fmt.Printf("Spec:\n%v\n", spec)
|
|
| 29 | 31 |
} |
| 30 | 32 |
|
| 31 | 33 |
// returns the container spec in json format. |
| ... | ... |
@@ -34,5 +35,6 @@ func getContainerSpec(container *libcontainer.Container) (string, error) {
|
| 34 | 34 |
if err != nil {
|
| 35 | 35 |
return "", err |
| 36 | 36 |
} |
| 37 |
+ |
|
| 37 | 38 |
return string(spec), nil |
| 38 | 39 |
} |
| ... | ... |
@@ -4,7 +4,6 @@ import ( |
| 4 | 4 |
"encoding/json" |
| 5 | 5 |
"fmt" |
| 6 | 6 |
"log" |
| 7 |
- "os" |
|
| 8 | 7 |
|
| 9 | 8 |
"github.com/codegangsta/cli" |
| 10 | 9 |
"github.com/dotcloud/docker/pkg/libcontainer" |
| ... | ... |
@@ -18,14 +17,17 @@ var statsCommand = cli.Command{
|
| 18 | 18 |
} |
| 19 | 19 |
|
| 20 | 20 |
func statsAction(context *cli.Context) {
|
| 21 |
- // returns the stats of the current container. |
|
| 21 |
+ container, err := loadContainer() |
|
| 22 |
+ if err != nil {
|
|
| 23 |
+ log.Fatal(err) |
|
| 24 |
+ } |
|
| 25 |
+ |
|
| 22 | 26 |
stats, err := getContainerStats(container) |
| 23 | 27 |
if err != nil {
|
| 24 |
- log.Printf("Failed to get stats - %v\n", err)
|
|
| 25 |
- os.Exit(1) |
|
| 28 |
+ log.Fatalf("Failed to get stats - %v\n", err)
|
|
| 26 | 29 |
} |
| 30 |
+ |
|
| 27 | 31 |
fmt.Printf("Stats:\n%v\n", stats)
|
| 28 |
- os.Exit(0) |
|
| 29 | 32 |
} |
| 30 | 33 |
|
| 31 | 34 |
// returns the container stats in json format. |
| ... | ... |
@@ -34,9 +36,11 @@ func getContainerStats(container *libcontainer.Container) (string, error) {
|
| 34 | 34 |
if err != nil {
|
| 35 | 35 |
return "", err |
| 36 | 36 |
} |
| 37 |
+ |
|
| 37 | 38 |
out, err := json.MarshalIndent(stats, "", "\t") |
| 38 | 39 |
if err != nil {
|
| 39 | 40 |
return "", err |
| 40 | 41 |
} |
| 42 |
+ |
|
| 41 | 43 |
return string(out), nil |
| 42 | 44 |
} |
| ... | ... |
@@ -50,3 +50,13 @@ func openLog(name string) error {
|
| 50 | 50 |
|
| 51 | 51 |
return nil |
| 52 | 52 |
} |
| 53 |
+ |
|
| 54 |
+func loadContainerFromJson(rawData string) (*libcontainer.Container, error) {
|
|
| 55 |
+ var container *libcontainer.Container |
|
| 56 |
+ |
|
| 57 |
+ if err := json.Unmarshal([]byte(rawData), &container); err != nil {
|
|
| 58 |
+ return nil, err |
|
| 59 |
+ } |
|
| 60 |
+ |
|
| 61 |
+ return container, nil |
|
| 62 |
+} |