Browse code

Replace os.File with io.ReadCloser and io.Writer

Guillaume J. Charmes authored on 2013/05/08 10:06:49
Showing 2 changed files
... ...
@@ -1,35 +1,26 @@
1 1
 package docker
2 2
 
3 3
 import (
4
-	_ "bytes"
5 4
 	"encoding/json"
6 5
 	"fmt"
7 6
 	"github.com/dotcloud/docker/auth"
8 7
 	"github.com/gorilla/mux"
9 8
 	"github.com/shin-/cookiejar"
9
+	"io"
10 10
 	"log"
11
-	"net"
12 11
 	"net/http"
13
-	"os"
14 12
 	"strconv"
15 13
 	"strings"
16 14
 )
17 15
 
18
-func hijackServer(w http.ResponseWriter) (*os.File, net.Conn, error) {
19
-	rwc, _, err := w.(http.Hijacker).Hijack()
16
+func hijackServer(w http.ResponseWriter) (io.ReadCloser, io.Writer, error) {
17
+	conn, _, err := w.(http.Hijacker).Hijack()
20 18
 	if err != nil {
21 19
 		return nil, nil, err
22 20
 	}
23
-
24
-	file, err := rwc.(*net.TCPConn).File()
25
-	if err != nil {
26
-		return nil, rwc, err
27
-	}
28
-
29 21
 	// Flush the options to make sure the client sets the raw mode
30
-	rwc.Write([]byte{})
31
-
32
-	return file, rwc, nil
22
+	conn.Write([]byte{})
23
+	return conn, conn, nil
33 24
 }
34 25
 
35 26
 func httpError(w http.ResponseWriter, err error) {
... ...
@@ -106,19 +97,14 @@ func getContainersExport(srv *Server, w http.ResponseWriter, r *http.Request) ([
106 106
 	vars := mux.Vars(r)
107 107
 	name := vars["name"]
108 108
 
109
-	file, rwc, err := hijackServer(w)
110
-	if file != nil {
111
-		defer file.Close()
112
-	}
113
-	if rwc != nil {
114
-		defer rwc.Close()
115
-	}
109
+	in, out, err := hijackServer(w)
116 110
 	if err != nil {
111
+		defer in.Close()
117 112
 		return nil, err
118 113
 	}
119
-	fmt.Fprintf(file, "HTTP/1.1 200 OK\r\nContent-Type: raw-stream-hijack\r\n\r\n")
120
-	if err := srv.ContainerExport(name, file); err != nil {
121
-		fmt.Fprintf(file, "Error: %s\n", err)
114
+	fmt.Fprintf(out, "HTTP/1.1 200 OK\r\nContent-Type: raw-stream-hijack\r\n\r\n")
115
+	if err := srv.ContainerExport(name, out); err != nil {
116
+		fmt.Fprintf(out, "Error: %s\n", err)
122 117
 		return nil, err
123 118
 	}
124 119
 	return nil, nil
... ...
@@ -131,19 +117,14 @@ func getImages(srv *Server, w http.ResponseWriter, r *http.Request) ([]byte, err
131 131
 
132 132
 	viz := r.Form.Get("viz") == "1"
133 133
 	if viz {
134
-		file, rwc, err := hijackServer(w)
135
-		if file != nil {
136
-			defer file.Close()
137
-		}
138
-		if rwc != nil {
139
-			defer rwc.Close()
140
-		}
134
+		in, out, err := hijackServer(w)
141 135
 		if err != nil {
136
+			defer in.Close()
142 137
 			return nil, err
143 138
 		}
144
-		fmt.Fprintf(file, "HTTP/1.1 200 OK\r\nContent-Type: raw-stream-hijack\r\n\r\n")
145
-		if err := srv.ImagesViz(file); err != nil {
146
-			fmt.Fprintf(file, "Error: %s\n", err)
139
+		fmt.Fprintf(out, "HTTP/1.1 200 OK\r\nContent-Type: raw-stream-hijack\r\n\r\n")
140
+		if err := srv.ImagesViz(out); err != nil {
141
+			fmt.Fprintf(out, "Error: %s\n", err)
147 142
 		}
148 143
 		return nil, nil
149 144
 	}
... ...
@@ -288,26 +269,21 @@ func postImages(srv *Server, w http.ResponseWriter, r *http.Request) ([]byte, er
288 288
 	repo := r.Form.Get("repo")
289 289
 	tag := r.Form.Get("tag")
290 290
 
291
-	file, rwc, err := hijackServer(w)
292
-	if file != nil {
293
-		defer file.Close()
294
-	}
295
-	if rwc != nil {
296
-		defer rwc.Close()
297
-	}
291
+	in, out, err := hijackServer(w)
298 292
 	if err != nil {
293
+		defer in.Close()
299 294
 		return nil, err
300 295
 	}
301
-	fmt.Fprintf(file, "HTTP/1.1 200 OK\r\nContent-Type: raw-stream-hijack\r\n\r\n")
296
+	fmt.Fprintf(out, "HTTP/1.1 200 OK\r\nContent-Type: raw-stream-hijack\r\n\r\n")
302 297
 	if image != "" { //pull
303 298
 		registry := r.Form.Get("registry")
304
-		if err := srv.ImagePull(image, tag, registry, file); err != nil {
305
-			fmt.Fprintf(file, "Error: %s\n", err)
299
+		if err := srv.ImagePull(image, tag, registry, out); err != nil {
300
+			fmt.Fprintf(out, "Error: %s\n", err)
306 301
 			return nil, err
307 302
 		}
308 303
 	} else { //import
309
-		if err := srv.ImageImport(src, repo, tag, file); err != nil {
310
-			fmt.Fprintf(file, "Error: %s\n", err)
304
+		if err := srv.ImageImport(src, repo, tag, in, out); err != nil {
305
+			fmt.Fprintf(out, "Error: %s\n", err)
311 306
 			return nil, err
312 307
 		}
313 308
 	}
... ...
@@ -341,19 +317,14 @@ func postImagesInsert(srv *Server, w http.ResponseWriter, r *http.Request) ([]by
341 341
 	vars := mux.Vars(r)
342 342
 	name := vars["name"]
343 343
 
344
-	file, rwc, err := hijackServer(w)
345
-	if file != nil {
346
-		defer file.Close()
347
-	}
348
-	if rwc != nil {
349
-		defer rwc.Close()
350
-	}
344
+	in, out, err := hijackServer(w)
351 345
 	if err != nil {
346
+		defer in.Close()
352 347
 		return nil, err
353 348
 	}
354
-	fmt.Fprintf(file, "HTTP/1.1 200 OK\r\nContent-Type: raw-stream-hijack\r\n\r\n")
355
-	if err := srv.ImageInsert(name, url, path, file); err != nil {
356
-		fmt.Fprintf(file, "Error: %s\n", err)
349
+	fmt.Fprintf(out, "HTTP/1.1 200 OK\r\nContent-Type: raw-stream-hijack\r\n\r\n")
350
+	if err := srv.ImageInsert(name, url, path, out); err != nil {
351
+		fmt.Fprintf(out, "Error: %s\n", err)
357 352
 		return nil, err
358 353
 	}
359 354
 	return nil, nil
... ...
@@ -369,39 +340,28 @@ func postImagesPush(srv *Server, w http.ResponseWriter, r *http.Request) ([]byte
369 369
 	vars := mux.Vars(r)
370 370
 	name := vars["name"]
371 371
 
372
-	file, rwc, err := hijackServer(w)
373
-	if file != nil {
374
-		defer file.Close()
375
-	}
376
-	if rwc != nil {
377
-		defer rwc.Close()
378
-	}
372
+	in, out, err := hijackServer(w)
379 373
 	if err != nil {
374
+		defer in.Close()
380 375
 		return nil, err
381 376
 	}
382
-	fmt.Fprintf(file, "HTTP/1.1 200 OK\r\nContent-Type: raw-stream-hijack\r\n\r\n")
383
-	if err := srv.ImagePush(name, registry, file); err != nil {
384
-		fmt.Fprintln(file, "Error: $s\n", err)
377
+	fmt.Fprintf(out, "HTTP/1.1 200 OK\r\nContent-Type: raw-stream-hijack\r\n\r\n")
378
+	if err := srv.ImagePush(name, registry, out); err != nil {
379
+		fmt.Fprintln(out, "Error: %s\n", err)
385 380
 		return nil, err
386 381
 	}
387 382
 	return nil, nil
388 383
 }
389 384
 
390 385
 func postBuild(srv *Server, w http.ResponseWriter, r *http.Request) ([]byte, error) {
391
-
392
-	file, rwc, err := hijackServer(w)
393
-	if file != nil {
394
-		defer file.Close()
395
-	}
396
-	if rwc != nil {
397
-		defer rwc.Close()
398
-	}
386
+	in, out, err := hijackServer(w)
399 387
 	if err != nil {
388
+		defer in.Close()
400 389
 		return nil, err
401 390
 	}
402
-	fmt.Fprintf(file, "HTTP/1.1 200 OK\r\nContent-Type: raw-stream-hijack\r\n\r\n")
403
-	if err := srv.ImageCreateFormFile(file); err != nil {
404
-		fmt.Fprintln(file, "Error: %s\n", err)
391
+	fmt.Fprintf(out, "HTTP/1.1 200 OK\r\nContent-Type: raw-stream-hijack\r\n\r\n")
392
+	if err := srv.ImageCreateFromFile(in, out); err != nil {
393
+		fmt.Fprintln(out, "Error: %s\n", err)
405 394
 		return nil, err
406 395
 	}
407 396
 	return nil, nil
... ...
@@ -532,20 +492,15 @@ func postContainersAttach(srv *Server, w http.ResponseWriter, r *http.Request) (
532 532
 	vars := mux.Vars(r)
533 533
 	name := vars["name"]
534 534
 
535
-	file, rwc, err := hijackServer(w)
536
-	if file != nil {
537
-		defer file.Close()
538
-	}
539
-	if rwc != nil {
540
-		defer rwc.Close()
541
-	}
535
+	in, out, err := hijackServer(w)
542 536
 	if err != nil {
537
+		defer in.Close()
543 538
 		return nil, err
544 539
 	}
545 540
 
546
-	fmt.Fprintf(file, "HTTP/1.1 200 OK\r\nContent-Type: raw-stream-hijack\r\n\r\n")
547
-	if err := srv.ContainerAttach(name, logs, stream, stdin, stdout, stderr, file); err != nil {
548
-		fmt.Fprintf(file, "Error: %s\n", err)
541
+	fmt.Fprintf(out, "HTTP/1.1 200 OK\r\nContent-Type: raw-stream-hijack\r\n\r\n")
542
+	if err := srv.ContainerAttach(name, logs, stream, stdin, stdout, stderr, in, out); err != nil {
543
+		fmt.Fprintf(out, "Error: %s\n", err)
549 544
 		return nil, err
550 545
 	}
551 546
 	return nil, nil
... ...
@@ -26,7 +26,7 @@ func (srv *Server) ContainerKill(name string) error {
26 26
 	return nil
27 27
 }
28 28
 
29
-func (srv *Server) ContainerExport(name string, file *os.File) error {
29
+func (srv *Server) ContainerExport(name string, out io.Writer) error {
30 30
 	if container := srv.runtime.Get(name); container != nil {
31 31
 
32 32
 		data, err := container.Export()
... ...
@@ -35,7 +35,7 @@ func (srv *Server) ContainerExport(name string, file *os.File) error {
35 35
 		}
36 36
 
37 37
 		// Stream the entire contents of the container (basically a volatile snapshot)
38
-		if _, err := io.Copy(file, data); err != nil {
38
+		if _, err := io.Copy(out, data); err != nil {
39 39
 			return err
40 40
 		}
41 41
 		return nil
... ...
@@ -62,13 +62,13 @@ func (srv *Server) ImagesSearch(term string) ([]ApiSearch, error) {
62 62
 	return outs, nil
63 63
 }
64 64
 
65
-func (srv *Server) ImageInsert(name, url, path string, stdout *os.File) error {
65
+func (srv *Server) ImageInsert(name, url, path string, out io.Writer) error {
66 66
 	img, err := srv.runtime.repositories.LookupImage(name)
67 67
 	if err != nil {
68 68
 		return err
69 69
 	}
70 70
 
71
-	file, err := Download(url, stdout)
71
+	file, err := Download(url, out)
72 72
 	if err != nil {
73 73
 		return err
74 74
 	}
... ...
@@ -85,7 +85,7 @@ func (srv *Server) ImageInsert(name, url, path string, stdout *os.File) error {
85 85
 		return err
86 86
 	}
87 87
 
88
-	if err := c.Inject(ProgressReader(file.Body, int(file.ContentLength), stdout, "Downloading %v/%v (%v)"), path); err != nil {
88
+	if err := c.Inject(ProgressReader(file.Body, int(file.ContentLength), out, "Downloading %v/%v (%v)"), path); err != nil {
89 89
 		return err
90 90
 	}
91 91
 	// FIXME: Handle custom repo, tag comment, author
... ...
@@ -93,29 +93,31 @@ func (srv *Server) ImageInsert(name, url, path string, stdout *os.File) error {
93 93
 	if err != nil {
94 94
 		return err
95 95
 	}
96
-	fmt.Fprintf(stdout, "%s\n", img.Id)
96
+	fmt.Fprintf(out, "%s\n", img.Id)
97 97
 	return nil
98 98
 }
99 99
 
100
-func (srv *Server) ImagesViz(file *os.File) error {
100
+func (srv *Server) ImagesViz(out io.Writer) error {
101 101
 	images, _ := srv.runtime.graph.All()
102 102
 	if images == nil {
103 103
 		return nil
104 104
 	}
105 105
 
106
-	fmt.Fprintf(file, "digraph docker {\n")
106
+	fmt.Fprintf(out, "digraph docker {\n")
107 107
 
108
-	var parentImage *Image
109
-	var err error
108
+	var (
109
+		parentImage *Image
110
+		err         error
111
+	)
110 112
 	for _, image := range images {
111 113
 		parentImage, err = image.GetParent()
112 114
 		if err != nil {
113 115
 			return fmt.Errorf("Error while getting parent image: %v", err)
114 116
 		}
115 117
 		if parentImage != nil {
116
-			fmt.Fprintf(file, "  \"%s\" -> \"%s\"\n", parentImage.ShortId(), image.ShortId())
118
+			fmt.Fprintf(out, "  \"%s\" -> \"%s\"\n", parentImage.ShortId(), image.ShortId())
117 119
 		} else {
118
-			fmt.Fprintf(file, "  base -> \"%s\" [style=invis]\n", image.ShortId())
120
+			fmt.Fprintf(out, "  base -> \"%s\" [style=invis]\n", image.ShortId())
119 121
 		}
120 122
 	}
121 123
 
... ...
@@ -128,11 +130,9 @@ func (srv *Server) ImagesViz(file *os.File) error {
128 128
 	}
129 129
 
130 130
 	for id, repos := range reporefs {
131
-		fmt.Fprintf(file, "  \"%s\" [label=\"%s\\n%s\",shape=box,fillcolor=\"paleturquoise\",style=\"filled,rounded\"];\n", id, id, strings.Join(repos, "\\n"))
131
+		fmt.Fprintf(out, "  \"%s\" [label=\"%s\\n%s\",shape=box,fillcolor=\"paleturquoise\",style=\"filled,rounded\"];\n", id, id, strings.Join(repos, "\\n"))
132 132
 	}
133
-
134
-	fmt.Fprintf(file, "  base [style=invisible]\n")
135
-	fmt.Fprintf(file, "}\n")
133
+	fmt.Fprintf(out, "  base [style=invisible]\n}\n")
136 134
 	return nil
137 135
 }
138 136
 
... ...
@@ -299,26 +299,26 @@ func (srv *Server) ContainerTag(name, repo, tag string, force bool) error {
299 299
 	return nil
300 300
 }
301 301
 
302
-func (srv *Server) ImagePull(name, tag, registry string, file *os.File) error {
302
+func (srv *Server) ImagePull(name, tag, registry string, out io.Writer) error {
303 303
 	if registry != "" {
304
-		if err := srv.runtime.graph.PullImage(file, name, registry, nil); err != nil {
304
+		if err := srv.runtime.graph.PullImage(out, name, registry, nil); err != nil {
305 305
 			return err
306 306
 		}
307 307
 		return nil
308 308
 	}
309
-	if err := srv.runtime.graph.PullRepository(file, name, tag, srv.runtime.repositories, srv.runtime.authConfig); err != nil {
309
+	if err := srv.runtime.graph.PullRepository(out, name, tag, srv.runtime.repositories, srv.runtime.authConfig); err != nil {
310 310
 		return err
311 311
 	}
312 312
 	return nil
313 313
 }
314 314
 
315
-func (srv *Server) ImagePush(name, registry string, file *os.File) error {
315
+func (srv *Server) ImagePush(name, registry string, out io.Writer) error {
316 316
 	img, err := srv.runtime.graph.Get(name)
317 317
 	if err != nil {
318 318
 		Debugf("The push refers to a repository [%s] (len: %d)\n", name, len(srv.runtime.repositories.Repositories[name]))
319 319
 		// If it fails, try to get the repository
320 320
 		if localRepo, exists := srv.runtime.repositories.Repositories[name]; exists {
321
-			if err := srv.runtime.graph.PushRepository(file, name, localRepo, srv.runtime.authConfig); err != nil {
321
+			if err := srv.runtime.graph.PushRepository(out, name, localRepo, srv.runtime.authConfig); err != nil {
322 322
 				return err
323 323
 			}
324 324
 			return nil
... ...
@@ -326,37 +326,37 @@ func (srv *Server) ImagePush(name, registry string, file *os.File) error {
326 326
 
327 327
 		return err
328 328
 	}
329
-	err = srv.runtime.graph.PushImage(file, img, registry, nil)
329
+	err = srv.runtime.graph.PushImage(out, img, registry, nil)
330 330
 	if err != nil {
331 331
 		return err
332 332
 	}
333 333
 	return nil
334 334
 }
335 335
 
336
-func (srv *Server) ImageImport(src, repo, tag string, file *os.File) error {
336
+func (srv *Server) ImageImport(src, repo, tag string, in io.Reader, out io.Writer) error {
337 337
 	var archive io.Reader
338 338
 	var resp *http.Response
339 339
 
340 340
 	if src == "-" {
341
-		archive = file
341
+		archive = in
342 342
 	} else {
343 343
 		u, err := url.Parse(src)
344 344
 		if err != nil {
345
-			fmt.Fprintf(file, "Error: %s\n", err)
345
+			fmt.Fprintf(out, "Error: %s\n", err)
346 346
 		}
347 347
 		if u.Scheme == "" {
348 348
 			u.Scheme = "http"
349 349
 			u.Host = src
350 350
 			u.Path = ""
351 351
 		}
352
-		fmt.Fprintln(file, "Downloading from", u)
352
+		fmt.Fprintln(out, "Downloading from", u)
353 353
 		// Download with curl (pretty progress bar)
354 354
 		// If curl is not available, fallback to http.Get()
355
-		resp, err = Download(u.String(), file)
355
+		resp, err = Download(u.String(), out)
356 356
 		if err != nil {
357 357
 			return err
358 358
 		}
359
-		archive = ProgressReader(resp.Body, int(resp.ContentLength), file, "Importing %v/%v (%v)")
359
+		archive = ProgressReader(resp.Body, int(resp.ContentLength), out, "Importing %v/%v (%v)")
360 360
 	}
361 361
 	img, err := srv.runtime.graph.Create(archive, nil, "Imported from "+src, "", nil)
362 362
 	if err != nil {
... ...
@@ -368,7 +368,7 @@ func (srv *Server) ImageImport(src, repo, tag string, file *os.File) error {
368 368
 			return err
369 369
 		}
370 370
 	}
371
-	fmt.Fprintln(file, img.ShortId())
371
+	fmt.Fprintln(out, img.ShortId())
372 372
 	return nil
373 373
 }
374 374
 
... ...
@@ -397,12 +397,12 @@ func (srv *Server) ContainerCreate(config Config) (string, bool, bool, error) {
397 397
 	return container.ShortId(), memoryW, swapW, nil
398 398
 }
399 399
 
400
-func (srv *Server) ImageCreateFormFile(file *os.File) error {
401
-	img, err := NewBuilder(srv.runtime).Build(file, file)
400
+func (srv *Server) ImageCreateFromFile(dockerfile io.Reader, out io.Writer) error {
401
+	img, err := NewBuilder(srv.runtime).Build(dockerfile, out)
402 402
 	if err != nil {
403 403
 		return err
404 404
 	}
405
-	fmt.Fprintf(file, "%s\n", img.ShortId())
405
+	fmt.Fprintf(out, "%s\n", img.ShortId())
406 406
 	return nil
407 407
 }
408 408
 
... ...
@@ -496,7 +496,7 @@ func (srv *Server) ContainerWait(name string) (int, error) {
496 496
 	return 0, fmt.Errorf("No such container: %s", name)
497 497
 }
498 498
 
499
-func (srv *Server) ContainerAttach(name string, logs, stream, stdin, stdout, stderr bool, file *os.File) error {
499
+func (srv *Server) ContainerAttach(name string, logs, stream, stdin, stdout, stderr bool, in io.ReadCloser, out io.Writer) error {
500 500
 	if container := srv.runtime.Get(name); container != nil {
501 501
 		//logs
502 502
 		if logs {
... ...
@@ -504,7 +504,7 @@ func (srv *Server) ContainerAttach(name string, logs, stream, stdin, stdout, std
504 504
 				cLog, err := container.ReadLog("stdout")
505 505
 				if err != nil {
506 506
 					Debugf(err.Error())
507
-				} else if _, err := io.Copy(file, cLog); err != nil {
507
+				} else if _, err := io.Copy(out, cLog); err != nil {
508 508
 					Debugf(err.Error())
509 509
 				}
510 510
 			}
... ...
@@ -512,7 +512,7 @@ func (srv *Server) ContainerAttach(name string, logs, stream, stdin, stdout, std
512 512
 				cLog, err := container.ReadLog("stderr")
513 513
 				if err != nil {
514 514
 					Debugf(err.Error())
515
-				} else if _, err := io.Copy(file, cLog); err != nil {
515
+				} else if _, err := io.Copy(out, cLog); err != nil {
516 516
 					Debugf(err.Error())
517 517
 				}
518 518
 			}
... ...
@@ -535,16 +535,16 @@ func (srv *Server) ContainerAttach(name string, logs, stream, stdin, stdout, std
535 535
 				go func() {
536 536
 					defer w.Close()
537 537
 					defer Debugf("Closing buffered stdin pipe")
538
-					io.Copy(w, file)
538
+					io.Copy(w, in)
539 539
 				}()
540 540
 				cStdin = r
541
-				cStdinCloser = file
541
+				cStdinCloser = in
542 542
 			}
543 543
 			if stdout {
544
-				cStdout = file
544
+				cStdout = out
545 545
 			}
546 546
 			if stderr {
547
-				cStderr = file
547
+				cStderr = out
548 548
 			}
549 549
 
550 550
 			<-container.Attach(cStdin, cStdinCloser, cStdout, cStderr)