2016-12-09 17:17:34 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2017-02-02 23:36:10 +00:00
|
|
|
"time"
|
2016-12-09 17:17:34 +00:00
|
|
|
|
|
|
|
gocontext "context"
|
|
|
|
|
2017-02-09 07:31:26 +00:00
|
|
|
"github.com/docker/containerd/api/services/execution"
|
|
|
|
"github.com/docker/containerd/api/types/process"
|
2016-12-09 17:17:34 +00:00
|
|
|
"github.com/urfave/cli"
|
|
|
|
)
|
|
|
|
|
|
|
|
var execCommand = cli.Command{
|
|
|
|
Name: "exec",
|
|
|
|
Usage: "exec a new process in a running container",
|
|
|
|
Flags: []cli.Flag{
|
|
|
|
cli.StringFlag{
|
|
|
|
Name: "id, i",
|
|
|
|
Usage: "target container id",
|
|
|
|
},
|
|
|
|
cli.StringFlag{
|
|
|
|
Name: "cwd, c",
|
|
|
|
Usage: "current working directory for the process",
|
|
|
|
},
|
|
|
|
cli.BoolFlag{
|
|
|
|
Name: "tty, t",
|
|
|
|
Usage: "create a terminal for the process",
|
|
|
|
},
|
|
|
|
cli.StringSliceFlag{
|
|
|
|
Name: "env, e",
|
|
|
|
Value: &cli.StringSlice{},
|
|
|
|
Usage: "environment variables for the process",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Action: func(context *cli.Context) error {
|
|
|
|
executionService, err := getExecutionService(context)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2017-02-07 17:25:55 +00:00
|
|
|
tmpDir, err := getTempDir(time.Now().Format("2006-02-01_15:04:05"))
|
2016-12-09 17:17:34 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
|
2017-02-07 17:25:55 +00:00
|
|
|
id := context.String("id")
|
2016-12-09 17:17:34 +00:00
|
|
|
sOpts := &execution.StartProcessRequest{
|
2016-12-09 19:32:45 +00:00
|
|
|
ContainerID: id,
|
2017-02-09 07:31:26 +00:00
|
|
|
Process: &process.Process{
|
2016-12-09 17:17:34 +00:00
|
|
|
Cwd: context.String("cwd"),
|
|
|
|
Terminal: context.Bool("tty"),
|
|
|
|
Args: context.Args(),
|
|
|
|
Env: context.StringSlice("env"),
|
|
|
|
},
|
|
|
|
Stdin: filepath.Join(tmpDir, "stdin"),
|
|
|
|
Stdout: filepath.Join(tmpDir, "stdout"),
|
|
|
|
Stderr: filepath.Join(tmpDir, "stderr"),
|
|
|
|
Console: context.Bool("tty"),
|
|
|
|
}
|
|
|
|
|
2017-01-12 18:24:22 +00:00
|
|
|
fwg, err := prepareStdio(sOpts.Stdin, sOpts.Stdout, sOpts.Stderr, sOpts.Console)
|
2016-12-09 17:17:34 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
sr, err := executionService.StartProcess(gocontext.Background(), sOpts)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = executionService.DeleteProcess(gocontext.Background(), &execution.DeleteProcessRequest{
|
2016-12-09 19:32:45 +00:00
|
|
|
ContainerID: id,
|
2017-02-02 23:36:10 +00:00
|
|
|
Pid: sr.Process.Pid,
|
2016-12-09 17:17:34 +00:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure we read all io
|
|
|
|
fwg.Wait()
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
}
|