From e838be38d2231a546f6c14099cbfd8c769200023 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Fri, 29 Jan 2016 17:22:50 -0800 Subject: [PATCH] Add load process.json for exec command Signed-off-by: Michael Crosby --- exec.go | 86 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 50 insertions(+), 36 deletions(-) diff --git a/exec.go b/exec.go index 73753d43..39dfd477 100644 --- a/exec.go +++ b/exec.go @@ -3,6 +3,7 @@ package main import ( + "encoding/json" "fmt" "os" "path" @@ -11,6 +12,7 @@ import ( "github.com/Sirupsen/logrus" "github.com/codegangsta/cli" + "github.com/opencontainers/specs" ) var execCommand = cli.Command{ @@ -37,15 +39,16 @@ var execCommand = cli.Command{ Name: "user, u", Usage: "UID (format: [:])", }, + cli.StringFlag{ + Name: "process,p", + Usage: "path to the process.json", + }, }, Action: func(context *cli.Context) { - if len(context.Args()) == 0 { - logrus.Fatal("pass the command") - } if os.Geteuid() != 0 { logrus.Fatal("runc should be run as root") } - status, err := execProcess(context, context.Args()) + status, err := execProcess(context) if err != nil { logrus.Fatalf("exec failed: %v", err) } @@ -53,72 +56,83 @@ var execCommand = cli.Command{ }, } -func execProcess(context *cli.Context, args []string) (int, error) { +func execProcess(context *cli.Context) (int, error) { container, err := getContainer(context) if err != nil { return -1, err } - bundle := container.Config().Rootfs - if err := os.Chdir(path.Dir(bundle)); err != nil { - return -1, err - } - spec, _, err := loadSpec(specConfig, runtimeConfig) + rootuid, err := container.Config().HostUID() if err != nil { return -1, err } + p, err := getProcess(context, path.Dir(bundle)) + if err != nil { + return -1, err + } + process := newProcess(*p) + tty, err := newTty(p.Terminal, process, rootuid, context.String("console")) + if err != nil { + return -1, err + } + handler := newSignalHandler(tty) + defer handler.Close() + if err := container.Start(process); err != nil { + return -1, err + } + return handler.forward(process) +} +func getProcess(context *cli.Context, bundle string) (*specs.Process, error) { + if path := context.String("process"); path != "" { + f, err := os.Open(path) + if err != nil { + return nil, err + } + defer f.Close() + var p specs.Process + if err := json.NewDecoder(f).Decode(&p); err != nil { + return nil, err + } + return &p, nil + } + // process via cli flags + if err := os.Chdir(bundle); err != nil { + return nil, err + } + spec, _, err := loadSpec(specConfig, runtimeConfig) + if err != nil { + return nil, err + } p := spec.Process - + p.Args = context.Args() // override the cwd, if passed if context.String("cwd") != "" { p.Cwd = context.String("cwd") } - // append the passed env variables for _, e := range context.StringSlice("env") { p.Env = append(p.Env, e) } - // set the tty if context.IsSet("tty") { p.Terminal = context.Bool("tty") } - // override the user, if passed if context.String("user") != "" { u := strings.SplitN(context.String("user"), ":", 2) if len(u) > 1 { gid, err := strconv.Atoi(u[1]) if err != nil { - return -1, fmt.Errorf("parsing %s as int for gid failed: %v", u[1], err) + return nil, fmt.Errorf("parsing %s as int for gid failed: %v", u[1], err) } p.User.GID = uint32(gid) } uid, err := strconv.Atoi(u[0]) if err != nil { - return -1, fmt.Errorf("parsing %s as int for uid failed: %v", u[0], err) + return nil, fmt.Errorf("parsing %s as int for uid failed: %v", u[0], err) } p.User.UID = uint32(uid) } - - process := newProcess(p) - process.Args = args - rootuid, err := container.Config().HostUID() - if err != nil { - return -1, err - } - - tty, err := newTty(p.Terminal, process, rootuid, context.String("console")) - if err != nil { - return -1, err - } - - handler := newSignalHandler(tty) - defer handler.Close() - if err := container.Start(process); err != nil { - return -1, err - } - - return handler.forward(process) + return &p, nil }