Browse code

Merge pull request #12650 from LK4D4/carry_12472

remove execCreate & execStart from job

Jessie Frazelle authored on 2015/04/23 07:32:14
Showing 6 changed files
... ...
@@ -32,9 +32,6 @@ func (cli *DockerCli) CmdExec(args ...string) error {
32 32
 	if err := json.NewDecoder(stream).Decode(&response); err != nil {
33 33
 		return err
34 34
 	}
35
-	for _, warning := range response.Warnings {
36
-		fmt.Fprintf(cli.err, "WARNING: %s\n", warning)
37
-	}
38 35
 
39 36
 	execID := response.ID
40 37
 
... ...
@@ -43,12 +40,18 @@ func (cli *DockerCli) CmdExec(args ...string) error {
43 43
 		return nil
44 44
 	}
45 45
 
46
+	//Temp struct for execStart so that we don't need to transfer all the execConfig
47
+	execStartCheck := &types.ExecStartCheck{
48
+		Detach: execConfig.Detach,
49
+		Tty:    execConfig.Tty,
50
+	}
51
+
46 52
 	if !execConfig.Detach {
47 53
 		if err := cli.CheckTtyInput(execConfig.AttachStdin, execConfig.Tty); err != nil {
48 54
 			return err
49 55
 		}
50 56
 	} else {
51
-		if _, _, err := readBody(cli.call("POST", "/exec/"+execID+"/start", execConfig, nil)); err != nil {
57
+		if _, _, err := readBody(cli.call("POST", "/exec/"+execID+"/start", execStartCheck, nil)); err != nil {
52 58
 			return err
53 59
 		}
54 60
 		// For now don't print this - wait for when we support exec wait()
... ...
@@ -1,8 +1,6 @@
1 1
 package server
2 2
 
3 3
 import (
4
-	"bufio"
5
-	"bytes"
6 4
 	"runtime"
7 5
 	"time"
8 6
 
... ...
@@ -1393,35 +1391,27 @@ func (s *Server) postContainerExecCreate(eng *engine.Engine, version version.Ver
1393 1393
 	if err := parseForm(r); err != nil {
1394 1394
 		return nil
1395 1395
 	}
1396
-	var (
1397
-		name         = vars["name"]
1398
-		job          = eng.Job("execCreate", name)
1399
-		stdoutBuffer = bytes.NewBuffer(nil)
1400
-		outWarnings  []string
1401
-		warnings     = bytes.NewBuffer(nil)
1402
-	)
1396
+	name := vars["name"]
1403 1397
 
1404
-	if err := job.DecodeEnv(r.Body); err != nil {
1398
+	execConfig := &runconfig.ExecConfig{}
1399
+	if err := json.NewDecoder(r.Body).Decode(execConfig); err != nil {
1405 1400
 		return err
1406 1401
 	}
1402
+	execConfig.Container = name
1403
+
1404
+	if len(execConfig.Cmd) == 0 {
1405
+		return fmt.Errorf("No exec command specified")
1406
+	}
1407 1407
 
1408
-	job.Stdout.Add(stdoutBuffer)
1409
-	// Read warnings from stderr
1410
-	job.Stderr.Add(warnings)
1411 1408
 	// Register an instance of Exec in container.
1412
-	if err := job.Run(); err != nil {
1413
-		fmt.Fprintf(os.Stderr, "Error setting up exec command in container %s: %s\n", name, err)
1409
+	id, err := s.daemon.ContainerExecCreate(execConfig)
1410
+	if err != nil {
1411
+		logrus.Errorf("Error setting up exec command in container %s: %s", name, err)
1414 1412
 		return err
1415 1413
 	}
1416
-	// Parse warnings from stderr
1417
-	scanner := bufio.NewScanner(warnings)
1418
-	for scanner.Scan() {
1419
-		outWarnings = append(outWarnings, scanner.Text())
1420
-	}
1421 1414
 
1422 1415
 	return writeJSON(w, http.StatusCreated, &types.ContainerExecCreateResponse{
1423
-		ID:       engine.Tail(stdoutBuffer, 1),
1424
-		Warnings: outWarnings,
1416
+		ID: id,
1425 1417
 	})
1426 1418
 }
1427 1419
 
... ...
@@ -1431,15 +1421,18 @@ func (s *Server) postContainerExecStart(eng *engine.Engine, version version.Vers
1431 1431
 		return nil
1432 1432
 	}
1433 1433
 	var (
1434
-		name             = vars["name"]
1435
-		job              = eng.Job("execStart", name)
1436
-		errOut io.Writer = os.Stderr
1434
+		execName = vars["name"]
1435
+		stdin    io.ReadCloser
1436
+		stdout   io.Writer
1437
+		stderr   io.Writer
1437 1438
 	)
1438 1439
 
1439
-	if err := job.DecodeEnv(r.Body); err != nil {
1440
+	execStartCheck := &types.ExecStartCheck{}
1441
+	if err := json.NewDecoder(r.Body).Decode(execStartCheck); err != nil {
1440 1442
 		return err
1441 1443
 	}
1442
-	if !job.GetenvBool("Detach") {
1444
+
1445
+	if !execStartCheck.Detach {
1443 1446
 		// Setting up the streaming http interface.
1444 1447
 		inStream, outStream, err := hijackServer(w)
1445 1448
 		if err != nil {
... ...
@@ -1455,21 +1448,20 @@ func (s *Server) postContainerExecStart(eng *engine.Engine, version version.Vers
1455 1455
 			fmt.Fprintf(outStream, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n")
1456 1456
 		}
1457 1457
 
1458
-		if !job.GetenvBool("Tty") && version.GreaterThanOrEqualTo("1.6") {
1458
+		if !execStartCheck.Tty && version.GreaterThanOrEqualTo("1.6") {
1459 1459
 			errStream = stdcopy.NewStdWriter(outStream, stdcopy.Stderr)
1460 1460
 			outStream = stdcopy.NewStdWriter(outStream, stdcopy.Stdout)
1461 1461
 		} else {
1462 1462
 			errStream = outStream
1463 1463
 		}
1464
-		job.Stdin.Add(inStream)
1465
-		job.Stdout.Add(outStream)
1466
-		job.Stderr.Set(errStream)
1467
-		errOut = outStream
1464
+		stdin = inStream
1465
+		stdout = outStream
1466
+		stderr = errStream
1468 1467
 	}
1469 1468
 	// Now run the user process in container.
1470
-	job.SetCloseIO(false)
1471
-	if err := job.Run(); err != nil {
1472
-		fmt.Fprintf(errOut, "Error starting exec command in container %s: %s\n", name, err)
1469
+
1470
+	if err := s.daemon.ContainerExecStart(execName, stdin, stdout, stderr); err != nil {
1471
+		logrus.Errorf("Error starting exec command in container %s: %s", execName, err)
1473 1472
 		return err
1474 1473
 	}
1475 1474
 	w.WriteHeader(http.StatusNoContent)
... ...
@@ -16,9 +16,6 @@ type ContainerCreateResponse struct {
16 16
 type ContainerExecCreateResponse struct {
17 17
 	// ID is the exec ID.
18 18
 	ID string `json:"Id"`
19
-
20
-	// Warnings are any warnings encountered during the execution of the command.
21
-	Warnings []string `json:"Warnings"`
22 19
 }
23 20
 
24 21
 // POST /auth
... ...
@@ -156,3 +153,12 @@ type Info struct {
156 156
 	Name               string
157 157
 	Labels             []string
158 158
 }
159
+
160
+// This struct is a temp struct used by execStart
161
+// Config fields is part of ExecConfig in runconfig package
162
+type ExecStartCheck struct {
163
+	// ExecStart will first check if it's detached
164
+	Detach bool
165
+	// Check if there's a tty
166
+	Tty bool
167
+}
... ...
@@ -118,8 +118,6 @@ type Daemon struct {
118 118
 func (daemon *Daemon) Install(eng *engine.Engine) error {
119 119
 	for name, method := range map[string]engine.Handler{
120 120
 		"container_inspect": daemon.ContainerInspect,
121
-		"execCreate":        daemon.ContainerExecCreate,
122
-		"execStart":         daemon.ContainerExecStart,
123 121
 	} {
124 122
 		if err := eng.Register(name, method); err != nil {
125 123
 			return err
... ...
@@ -10,7 +10,6 @@ import (
10 10
 	"github.com/Sirupsen/logrus"
11 11
 	"github.com/docker/docker/daemon/execdriver"
12 12
 	"github.com/docker/docker/daemon/execdriver/lxc"
13
-	"github.com/docker/docker/engine"
14 13
 	"github.com/docker/docker/pkg/broadcastwriter"
15 14
 	"github.com/docker/docker/pkg/ioutils"
16 15
 	"github.com/docker/docker/pkg/promise"
... ...
@@ -111,25 +110,15 @@ func (d *Daemon) getActiveContainer(name string) (*Container, error) {
111 111
 	return container, nil
112 112
 }
113 113
 
114
-func (d *Daemon) ContainerExecCreate(job *engine.Job) error {
115
-	if len(job.Args) != 1 {
116
-		return fmt.Errorf("Usage: %s [options] container command [args]", job.Name)
117
-	}
114
+func (d *Daemon) ContainerExecCreate(config *runconfig.ExecConfig) (string, error) {
118 115
 
119 116
 	if strings.HasPrefix(d.execDriver.Name(), lxc.DriverName) {
120
-		return lxc.ErrExec
117
+		return "", lxc.ErrExec
121 118
 	}
122 119
 
123
-	var name = job.Args[0]
124
-
125
-	container, err := d.getActiveContainer(name)
120
+	container, err := d.getActiveContainer(config.Container)
126 121
 	if err != nil {
127
-		return err
128
-	}
129
-
130
-	config, err := runconfig.ExecConfigFromJob(job)
131
-	if err != nil {
132
-		return err
122
+		return "", err
133 123
 	}
134 124
 
135 125
 	cmd := runconfig.NewCommand(config.Cmd...)
... ...
@@ -158,20 +147,15 @@ func (d *Daemon) ContainerExecCreate(job *engine.Job) error {
158 158
 
159 159
 	d.registerExecCommand(execConfig)
160 160
 
161
-	job.Printf("%s\n", execConfig.ID)
161
+	return execConfig.ID, nil
162 162
 
163
-	return nil
164 163
 }
165 164
 
166
-func (d *Daemon) ContainerExecStart(job *engine.Job) error {
167
-	if len(job.Args) != 1 {
168
-		return fmt.Errorf("Usage: %s [options] exec", job.Name)
169
-	}
165
+func (d *Daemon) ContainerExecStart(execName string, stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) error {
170 166
 
171 167
 	var (
172 168
 		cStdin           io.ReadCloser
173 169
 		cStdout, cStderr io.Writer
174
-		execName         = job.Args[0]
175 170
 	)
176 171
 
177 172
 	execConfig, err := d.getExecConfig(execName)
... ...
@@ -201,15 +185,15 @@ func (d *Daemon) ContainerExecStart(job *engine.Job) error {
201 201
 		go func() {
202 202
 			defer w.Close()
203 203
 			defer logrus.Debugf("Closing buffered stdin pipe")
204
-			io.Copy(w, job.Stdin)
204
+			io.Copy(w, stdin)
205 205
 		}()
206 206
 		cStdin = r
207 207
 	}
208 208
 	if execConfig.OpenStdout {
209
-		cStdout = job.Stdout
209
+		cStdout = stdout
210 210
 	}
211 211
 	if execConfig.OpenStderr {
212
-		cStderr = job.Stderr
212
+		cStderr = stderr
213 213
 	}
214 214
 
215 215
 	execConfig.StreamConfig.stderr = broadcastwriter.New()
... ...
@@ -1,9 +1,6 @@
1 1
 package runconfig
2 2
 
3 3
 import (
4
-	"fmt"
5
-
6
-	"github.com/docker/docker/engine"
7 4
 	flag "github.com/docker/docker/pkg/mflag"
8 5
 )
9 6
 
... ...
@@ -19,25 +16,6 @@ type ExecConfig struct {
19 19
 	Cmd          []string
20 20
 }
21 21
 
22
-func ExecConfigFromJob(job *engine.Job) (*ExecConfig, error) {
23
-	execConfig := &ExecConfig{
24
-		User:         job.Getenv("User"),
25
-		Privileged:   job.GetenvBool("Privileged"),
26
-		Tty:          job.GetenvBool("Tty"),
27
-		AttachStdin:  job.GetenvBool("AttachStdin"),
28
-		AttachStderr: job.GetenvBool("AttachStderr"),
29
-		AttachStdout: job.GetenvBool("AttachStdout"),
30
-	}
31
-	cmd := job.GetenvList("Cmd")
32
-	if len(cmd) == 0 {
33
-		return nil, fmt.Errorf("No exec command specified")
34
-	}
35
-
36
-	execConfig.Cmd = cmd
37
-
38
-	return execConfig, nil
39
-}
40
-
41 22
 func ParseExec(cmd *flag.FlagSet, args []string) (*ExecConfig, error) {
42 23
 	var (
43 24
 		flStdin      = cmd.Bool([]string{"i", "-interactive"}, false, "Keep STDIN open even if not attached")