mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
remove execCreate & execStart from job
Also removed the function ExecConfigFromJob Signed-off-by: Sun Jianbo <wonderflow@zju.edu.cn> Signed-off-by: Alexander Morozov <lk4d4@docker.com>
This commit is contained in:
parent
ccbb93e1cd
commit
24425021d2
6 changed files with 52 additions and 91 deletions
|
@ -32,9 +32,6 @@ func (cli *DockerCli) CmdExec(args ...string) error {
|
||||||
if err := json.NewDecoder(stream).Decode(&response); err != nil {
|
if err := json.NewDecoder(stream).Decode(&response); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, warning := range response.Warnings {
|
|
||||||
fmt.Fprintf(cli.err, "WARNING: %s\n", warning)
|
|
||||||
}
|
|
||||||
|
|
||||||
execID := response.ID
|
execID := response.ID
|
||||||
|
|
||||||
|
@ -43,12 +40,18 @@ func (cli *DockerCli) CmdExec(args ...string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Temp struct for execStart so that we don't need to transfer all the execConfig
|
||||||
|
execStartCheck := &types.ExecStartCheck{
|
||||||
|
Detach: execConfig.Detach,
|
||||||
|
Tty: execConfig.Tty,
|
||||||
|
}
|
||||||
|
|
||||||
if !execConfig.Detach {
|
if !execConfig.Detach {
|
||||||
if err := cli.CheckTtyInput(execConfig.AttachStdin, execConfig.Tty); err != nil {
|
if err := cli.CheckTtyInput(execConfig.AttachStdin, execConfig.Tty); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if _, _, err := readBody(cli.call("POST", "/exec/"+execID+"/start", execConfig, nil)); err != nil {
|
if _, _, err := readBody(cli.call("POST", "/exec/"+execID+"/start", execStartCheck, nil)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// For now don't print this - wait for when we support exec wait()
|
// For now don't print this - wait for when we support exec wait()
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"bytes"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -1393,35 +1391,27 @@ func (s *Server) postContainerExecCreate(eng *engine.Engine, version version.Ver
|
||||||
if err := parseForm(r); err != nil {
|
if err := parseForm(r); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var (
|
name := vars["name"]
|
||||||
name = vars["name"]
|
|
||||||
job = eng.Job("execCreate", name)
|
|
||||||
stdoutBuffer = bytes.NewBuffer(nil)
|
|
||||||
outWarnings []string
|
|
||||||
warnings = bytes.NewBuffer(nil)
|
|
||||||
)
|
|
||||||
|
|
||||||
if err := job.DecodeEnv(r.Body); err != nil {
|
execConfig := &runconfig.ExecConfig{}
|
||||||
|
if err := json.NewDecoder(r.Body).Decode(execConfig); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
execConfig.Container = name
|
||||||
|
|
||||||
|
if len(execConfig.Cmd) == 0 {
|
||||||
|
return fmt.Errorf("No exec command specified")
|
||||||
|
}
|
||||||
|
|
||||||
job.Stdout.Add(stdoutBuffer)
|
|
||||||
// Read warnings from stderr
|
|
||||||
job.Stderr.Add(warnings)
|
|
||||||
// Register an instance of Exec in container.
|
// Register an instance of Exec in container.
|
||||||
if err := job.Run(); err != nil {
|
id, err := s.daemon.ContainerExecCreate(execConfig)
|
||||||
fmt.Fprintf(os.Stderr, "Error setting up exec command in container %s: %s\n", name, err)
|
if err != nil {
|
||||||
|
logrus.Errorf("Error setting up exec command in container %s: %s", name, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Parse warnings from stderr
|
|
||||||
scanner := bufio.NewScanner(warnings)
|
|
||||||
for scanner.Scan() {
|
|
||||||
outWarnings = append(outWarnings, scanner.Text())
|
|
||||||
}
|
|
||||||
|
|
||||||
return writeJSON(w, http.StatusCreated, &types.ContainerExecCreateResponse{
|
return writeJSON(w, http.StatusCreated, &types.ContainerExecCreateResponse{
|
||||||
ID: engine.Tail(stdoutBuffer, 1),
|
ID: id,
|
||||||
Warnings: outWarnings,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1431,15 +1421,18 @@ func (s *Server) postContainerExecStart(eng *engine.Engine, version version.Vers
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
name = vars["name"]
|
execName = vars["name"]
|
||||||
job = eng.Job("execStart", name)
|
stdin io.ReadCloser
|
||||||
errOut io.Writer = os.Stderr
|
stdout io.Writer
|
||||||
|
stderr io.Writer
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := job.DecodeEnv(r.Body); err != nil {
|
execStartCheck := &types.ExecStartCheck{}
|
||||||
|
if err := json.NewDecoder(r.Body).Decode(execStartCheck); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !job.GetenvBool("Detach") {
|
|
||||||
|
if !execStartCheck.Detach {
|
||||||
// Setting up the streaming http interface.
|
// Setting up the streaming http interface.
|
||||||
inStream, outStream, err := hijackServer(w)
|
inStream, outStream, err := hijackServer(w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1455,21 +1448,20 @@ func (s *Server) postContainerExecStart(eng *engine.Engine, version version.Vers
|
||||||
fmt.Fprintf(outStream, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n")
|
fmt.Fprintf(outStream, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !job.GetenvBool("Tty") && version.GreaterThanOrEqualTo("1.6") {
|
if !execStartCheck.Tty && version.GreaterThanOrEqualTo("1.6") {
|
||||||
errStream = stdcopy.NewStdWriter(outStream, stdcopy.Stderr)
|
errStream = stdcopy.NewStdWriter(outStream, stdcopy.Stderr)
|
||||||
outStream = stdcopy.NewStdWriter(outStream, stdcopy.Stdout)
|
outStream = stdcopy.NewStdWriter(outStream, stdcopy.Stdout)
|
||||||
} else {
|
} else {
|
||||||
errStream = outStream
|
errStream = outStream
|
||||||
}
|
}
|
||||||
job.Stdin.Add(inStream)
|
stdin = inStream
|
||||||
job.Stdout.Add(outStream)
|
stdout = outStream
|
||||||
job.Stderr.Set(errStream)
|
stderr = errStream
|
||||||
errOut = outStream
|
|
||||||
}
|
}
|
||||||
// Now run the user process in container.
|
// Now run the user process in container.
|
||||||
job.SetCloseIO(false)
|
|
||||||
if err := job.Run(); err != nil {
|
if err := s.daemon.ContainerExecStart(execName, stdin, stdout, stderr); err != nil {
|
||||||
fmt.Fprintf(errOut, "Error starting exec command in container %s: %s\n", name, err)
|
logrus.Errorf("Error starting exec command in container %s: %s", execName, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
w.WriteHeader(http.StatusNoContent)
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
|
|
@ -16,9 +16,6 @@ type ContainerCreateResponse struct {
|
||||||
type ContainerExecCreateResponse struct {
|
type ContainerExecCreateResponse struct {
|
||||||
// ID is the exec ID.
|
// ID is the exec ID.
|
||||||
ID string `json:"Id"`
|
ID string `json:"Id"`
|
||||||
|
|
||||||
// Warnings are any warnings encountered during the execution of the command.
|
|
||||||
Warnings []string `json:"Warnings"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// POST /auth
|
// POST /auth
|
||||||
|
@ -156,3 +153,12 @@ type Info struct {
|
||||||
Name string
|
Name string
|
||||||
Labels []string
|
Labels []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This struct is a temp struct used by execStart
|
||||||
|
// Config fields is part of ExecConfig in runconfig package
|
||||||
|
type ExecStartCheck struct {
|
||||||
|
// ExecStart will first check if it's detached
|
||||||
|
Detach bool
|
||||||
|
// Check if there's a tty
|
||||||
|
Tty bool
|
||||||
|
}
|
||||||
|
|
|
@ -118,8 +118,6 @@ type Daemon struct {
|
||||||
func (daemon *Daemon) Install(eng *engine.Engine) error {
|
func (daemon *Daemon) Install(eng *engine.Engine) error {
|
||||||
for name, method := range map[string]engine.Handler{
|
for name, method := range map[string]engine.Handler{
|
||||||
"container_inspect": daemon.ContainerInspect,
|
"container_inspect": daemon.ContainerInspect,
|
||||||
"execCreate": daemon.ContainerExecCreate,
|
|
||||||
"execStart": daemon.ContainerExecStart,
|
|
||||||
} {
|
} {
|
||||||
if err := eng.Register(name, method); err != nil {
|
if err := eng.Register(name, method); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/docker/daemon/execdriver"
|
"github.com/docker/docker/daemon/execdriver"
|
||||||
"github.com/docker/docker/daemon/execdriver/lxc"
|
"github.com/docker/docker/daemon/execdriver/lxc"
|
||||||
"github.com/docker/docker/engine"
|
|
||||||
"github.com/docker/docker/pkg/broadcastwriter"
|
"github.com/docker/docker/pkg/broadcastwriter"
|
||||||
"github.com/docker/docker/pkg/ioutils"
|
"github.com/docker/docker/pkg/ioutils"
|
||||||
"github.com/docker/docker/pkg/promise"
|
"github.com/docker/docker/pkg/promise"
|
||||||
|
@ -111,25 +110,15 @@ func (d *Daemon) getActiveContainer(name string) (*Container, error) {
|
||||||
return container, nil
|
return container, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Daemon) ContainerExecCreate(job *engine.Job) error {
|
func (d *Daemon) ContainerExecCreate(config *runconfig.ExecConfig) (string, error) {
|
||||||
if len(job.Args) != 1 {
|
|
||||||
return fmt.Errorf("Usage: %s [options] container command [args]", job.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.HasPrefix(d.execDriver.Name(), lxc.DriverName) {
|
if strings.HasPrefix(d.execDriver.Name(), lxc.DriverName) {
|
||||||
return lxc.ErrExec
|
return "", lxc.ErrExec
|
||||||
}
|
}
|
||||||
|
|
||||||
var name = job.Args[0]
|
container, err := d.getActiveContainer(config.Container)
|
||||||
|
|
||||||
container, err := d.getActiveContainer(name)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
|
||||||
|
|
||||||
config, err := runconfig.ExecConfigFromJob(job)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := runconfig.NewCommand(config.Cmd...)
|
cmd := runconfig.NewCommand(config.Cmd...)
|
||||||
|
@ -158,20 +147,15 @@ func (d *Daemon) ContainerExecCreate(job *engine.Job) error {
|
||||||
|
|
||||||
d.registerExecCommand(execConfig)
|
d.registerExecCommand(execConfig)
|
||||||
|
|
||||||
job.Printf("%s\n", execConfig.ID)
|
return execConfig.ID, nil
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Daemon) ContainerExecStart(job *engine.Job) error {
|
func (d *Daemon) ContainerExecStart(execName string, stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) error {
|
||||||
if len(job.Args) != 1 {
|
|
||||||
return fmt.Errorf("Usage: %s [options] exec", job.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
cStdin io.ReadCloser
|
cStdin io.ReadCloser
|
||||||
cStdout, cStderr io.Writer
|
cStdout, cStderr io.Writer
|
||||||
execName = job.Args[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
execConfig, err := d.getExecConfig(execName)
|
execConfig, err := d.getExecConfig(execName)
|
||||||
|
@ -201,15 +185,15 @@ func (d *Daemon) ContainerExecStart(job *engine.Job) error {
|
||||||
go func() {
|
go func() {
|
||||||
defer w.Close()
|
defer w.Close()
|
||||||
defer logrus.Debugf("Closing buffered stdin pipe")
|
defer logrus.Debugf("Closing buffered stdin pipe")
|
||||||
io.Copy(w, job.Stdin)
|
io.Copy(w, stdin)
|
||||||
}()
|
}()
|
||||||
cStdin = r
|
cStdin = r
|
||||||
}
|
}
|
||||||
if execConfig.OpenStdout {
|
if execConfig.OpenStdout {
|
||||||
cStdout = job.Stdout
|
cStdout = stdout
|
||||||
}
|
}
|
||||||
if execConfig.OpenStderr {
|
if execConfig.OpenStderr {
|
||||||
cStderr = job.Stderr
|
cStderr = stderr
|
||||||
}
|
}
|
||||||
|
|
||||||
execConfig.StreamConfig.stderr = broadcastwriter.New()
|
execConfig.StreamConfig.stderr = broadcastwriter.New()
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
package runconfig
|
package runconfig
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/docker/docker/engine"
|
|
||||||
flag "github.com/docker/docker/pkg/mflag"
|
flag "github.com/docker/docker/pkg/mflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,25 +16,6 @@ type ExecConfig struct {
|
||||||
Cmd []string
|
Cmd []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExecConfigFromJob(job *engine.Job) (*ExecConfig, error) {
|
|
||||||
execConfig := &ExecConfig{
|
|
||||||
User: job.Getenv("User"),
|
|
||||||
Privileged: job.GetenvBool("Privileged"),
|
|
||||||
Tty: job.GetenvBool("Tty"),
|
|
||||||
AttachStdin: job.GetenvBool("AttachStdin"),
|
|
||||||
AttachStderr: job.GetenvBool("AttachStderr"),
|
|
||||||
AttachStdout: job.GetenvBool("AttachStdout"),
|
|
||||||
}
|
|
||||||
cmd := job.GetenvList("Cmd")
|
|
||||||
if len(cmd) == 0 {
|
|
||||||
return nil, fmt.Errorf("No exec command specified")
|
|
||||||
}
|
|
||||||
|
|
||||||
execConfig.Cmd = cmd
|
|
||||||
|
|
||||||
return execConfig, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseExec(cmd *flag.FlagSet, args []string) (*ExecConfig, error) {
|
func ParseExec(cmd *flag.FlagSet, args []string) (*ExecConfig, error) {
|
||||||
var (
|
var (
|
||||||
flStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Keep STDIN open even if not attached")
|
flStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Keep STDIN open even if not attached")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue