Browse code

Implement docker run with standalone client lib.

Signed-off-by: David Calavera <david.calavera@gmail.com>

David Calavera authored on 2015/12/06 13:18:06
Showing 2 changed files
... ...
@@ -3,12 +3,12 @@ package client
3 3
 import (
4 4
 	"fmt"
5 5
 	"io"
6
-	"net/url"
7 6
 	"os"
8 7
 	"runtime"
9 8
 	"strings"
10 9
 
11 10
 	"github.com/Sirupsen/logrus"
11
+	"github.com/docker/docker/api/types"
12 12
 	Cli "github.com/docker/docker/cli"
13 13
 	derr "github.com/docker/docker/errors"
14 14
 	"github.com/docker/docker/opts"
... ...
@@ -168,70 +168,57 @@ func (cli *DockerCli) CmdRun(args ...string) error {
168 168
 	if *flAutoRemove && (hostConfig.RestartPolicy.IsAlways() || hostConfig.RestartPolicy.IsOnFailure()) {
169 169
 		return ErrConflictRestartPolicyAndAutoRemove
170 170
 	}
171
-	// We need to instantiate the chan because the select needs it. It can
172
-	// be closed but can't be uninitialized.
173
-	hijacked := make(chan io.Closer)
174
-	// Block the return until the chan gets closed
175
-	defer func() {
176
-		logrus.Debugf("End of CmdRun(), Waiting for hijack to finish.")
177
-		if _, ok := <-hijacked; ok {
178
-			fmt.Fprintln(cli.err, "Hijack did not finish (chan still open)")
179
-		}
180
-	}()
171
+
181 172
 	if config.AttachStdin || config.AttachStdout || config.AttachStderr {
182 173
 		var (
183 174
 			out, stderr io.Writer
184 175
 			in          io.ReadCloser
185
-			v           = url.Values{}
186 176
 		)
187
-		v.Set("stream", "1")
188 177
 		if config.AttachStdin {
189
-			v.Set("stdin", "1")
190 178
 			in = cli.in
191 179
 		}
192 180
 		if config.AttachStdout {
193
-			v.Set("stdout", "1")
194 181
 			out = cli.out
195 182
 		}
196 183
 		if config.AttachStderr {
197
-			v.Set("stderr", "1")
198 184
 			if config.Tty {
199 185
 				stderr = cli.out
200 186
 			} else {
201 187
 				stderr = cli.err
202 188
 			}
203 189
 		}
204
-		errCh = promise.Go(func() error {
205
-			return cli.hijack("POST", "/containers/"+createResponse.ID+"/attach?"+v.Encode(), config.Tty, in, out, stderr, hijacked, nil)
206
-		})
207
-	} else {
208
-		close(hijacked)
209
-	}
210
-	// Acknowledge the hijack before starting
211
-	select {
212
-	case closer := <-hijacked:
213
-		// Make sure that the hijack gets closed when returning (results
214
-		// in closing the hijack chan and freeing server's goroutines)
215
-		if closer != nil {
216
-			defer closer.Close()
190
+
191
+		options := types.ContainerAttachOptions{
192
+			ContainerID: createResponse.ID,
193
+			Stream:      true,
194
+			Stdin:       config.AttachStdin,
195
+			Stdout:      config.AttachStdout,
196
+			Stderr:      config.AttachStderr,
217 197
 		}
218
-	case err := <-errCh:
198
+
199
+		resp, err := cli.client.ContainerAttach(options)
219 200
 		if err != nil {
220
-			logrus.Debugf("Error hijack: %s", err)
221 201
 			return err
222 202
 		}
203
+		errCh = promise.Go(func() error {
204
+			return cli.holdHijackedConnection(config.Tty, in, out, stderr, resp)
205
+		})
223 206
 	}
224 207
 
225 208
 	defer func() {
226 209
 		if *flAutoRemove {
227
-			if _, _, err = readBody(cli.call("DELETE", "/containers/"+createResponse.ID+"?v=1", nil, nil)); err != nil {
210
+			options := types.ContainerRemoveOptions{
211
+				ContainerID:   createResponse.ID,
212
+				RemoveVolumes: true,
213
+			}
214
+			if err := cli.client.ContainerRemove(options); err != nil {
228 215
 				fmt.Fprintf(cli.err, "Error deleting container: %s\n", err)
229 216
 			}
230 217
 		}
231 218
 	}()
232 219
 
233 220
 	//start the container
234
-	if _, _, err := readBody(cli.call("POST", "/containers/"+createResponse.ID+"/start", nil, nil)); err != nil {
221
+	if err := cli.client.ContainerStart(createResponse.ID); err != nil {
235 222
 		cmd.ReportError(err.Error(), false)
236 223
 		return runStartContainerErr(err)
237 224
 	}
... ...
@@ -262,7 +249,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
262 262
 	if *flAutoRemove {
263 263
 		// Autoremove: wait for the container to finish, retrieve
264 264
 		// the exit code and remove the container
265
-		if _, _, err := readBody(cli.call("POST", "/containers/"+createResponse.ID+"/wait", nil, nil)); err != nil {
265
+		if status, err = cli.client.ContainerWait(createResponse.ID); err != nil {
266 266
 			return runStartContainerErr(err)
267 267
 		}
268 268
 		if _, status, err = getExitCode(cli, createResponse.ID); err != nil {
... ...
@@ -95,13 +95,6 @@ func (cli *DockerCli) CmdStart(args ...string) error {
95 95
 			return cli.holdHijackedConnection(c.Config.Tty, in, cli.out, cli.err, resp)
96 96
 		})
97 97
 
98
-		select {
99
-		case err := <-cErr:
100
-			if err != nil {
101
-				return err
102
-			}
103
-		}
104
-
105 98
 		// 3. Start the container.
106 99
 		if err := cli.client.ContainerStart(containerID); err != nil {
107 100
 			return err