Browse code

Added missing attributes to api search calls: - Added an argument to the call() method in order to control the auth sharing - Enabled it only for search. Pulls and pushes were enabled already. - Grouped a few variable declarations

Docker-DCO-1.1-Signed-off-by: Roberto Hashioka <roberto.hashioka@docker.com> (github: rogaha)

Roberto G. Hashioka authored on 2014/01/21 13:06:19
Showing 4 changed files
... ...
@@ -500,12 +500,33 @@ func getImagesSearch(srv *Server, version float64, w http.ResponseWriter, r *htt
500 500
 	if err := parseForm(r); err != nil {
501 501
 		return err
502 502
 	}
503
+	var (
504
+		authEncoded = r.Header.Get("X-Registry-Auth")
505
+		authConfig  = &auth.AuthConfig{}
506
+		metaHeaders = map[string][]string{}
507
+	)
508
+
509
+	if authEncoded != "" {
510
+		authJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded))
511
+		if err := json.NewDecoder(authJson).Decode(authConfig); err != nil {
512
+			// for a search it is not an error if no auth was given
513
+			// to increase compatibility with the existing api it is defaulting to be empty
514
+			authConfig = &auth.AuthConfig{}
515
+		}
516
+	}
517
+	for k, v := range r.Header {
518
+		if strings.HasPrefix(k, "X-Meta-") {
519
+			metaHeaders[k] = v
520
+		}
521
+	}
503 522
 
504 523
 	var (
505 524
 		err  error
506 525
 		outs *engine.Table
507 526
 		job  = srv.Eng.Job("search", r.Form.Get("term"))
508 527
 	)
528
+	job.SetenvJson("metaHeaders", metaHeaders)
529
+	job.SetenvJson("authConfig", authConfig)
509 530
 	if version >= 1.9 {
510 531
 		job.Stdout.Add(w)
511 532
 	} else if outs, err = job.Stdout.AddTable(); err != nil {
... ...
@@ -335,7 +335,7 @@ func (cli *DockerCli) CmdLogin(args ...string) error {
335 335
 	authconfig.ServerAddress = serverAddress
336 336
 	cli.configFile.Configs[serverAddress] = authconfig
337 337
 
338
-	body, statusCode, err := readBody(cli.call("POST", "/auth", cli.configFile.Configs[serverAddress]))
338
+	body, statusCode, err := readBody(cli.call("POST", "/auth", cli.configFile.Configs[serverAddress], false))
339 339
 	if statusCode == 401 {
340 340
 		delete(cli.configFile.Configs, serverAddress)
341 341
 		auth.SaveConfig(cli.configFile)
... ...
@@ -400,7 +400,7 @@ func (cli *DockerCli) CmdVersion(args ...string) error {
400 400
 		fmt.Fprintf(cli.out, "Git commit (client): %s\n", GITCOMMIT)
401 401
 	}
402 402
 
403
-	body, _, err := readBody(cli.call("GET", "/version", nil))
403
+	body, _, err := readBody(cli.call("GET", "/version", nil, false))
404 404
 	if err != nil {
405 405
 		return err
406 406
 	}
... ...
@@ -441,7 +441,7 @@ func (cli *DockerCli) CmdInfo(args ...string) error {
441 441
 		return nil
442 442
 	}
443 443
 
444
-	body, _, err := readBody(cli.call("GET", "/info", nil))
444
+	body, _, err := readBody(cli.call("GET", "/info", nil, false))
445 445
 	if err != nil {
446 446
 		return err
447 447
 	}
... ...
@@ -521,7 +521,7 @@ func (cli *DockerCli) CmdStop(args ...string) error {
521 521
 
522 522
 	var encounteredError error
523 523
 	for _, name := range cmd.Args() {
524
-		_, _, err := readBody(cli.call("POST", "/containers/"+name+"/stop?"+v.Encode(), nil))
524
+		_, _, err := readBody(cli.call("POST", "/containers/"+name+"/stop?"+v.Encode(), nil, false))
525 525
 		if err != nil {
526 526
 			fmt.Fprintf(cli.err, "%s\n", err)
527 527
 			encounteredError = fmt.Errorf("Error: failed to stop one or more containers")
... ...
@@ -548,7 +548,7 @@ func (cli *DockerCli) CmdRestart(args ...string) error {
548 548
 
549 549
 	var encounteredError error
550 550
 	for _, name := range cmd.Args() {
551
-		_, _, err := readBody(cli.call("POST", "/containers/"+name+"/restart?"+v.Encode(), nil))
551
+		_, _, err := readBody(cli.call("POST", "/containers/"+name+"/restart?"+v.Encode(), nil, false))
552 552
 		if err != nil {
553 553
 			fmt.Fprintf(cli.err, "%s\n", err)
554 554
 			encounteredError = fmt.Errorf("Error: failed to  restart one or more containers")
... ...
@@ -567,7 +567,7 @@ func (cli *DockerCli) forwardAllSignals(cid string) chan os.Signal {
567 567
 			if s == syscall.SIGCHLD {
568 568
 				continue
569 569
 			}
570
-			if _, _, err := readBody(cli.call("POST", fmt.Sprintf("/containers/%s/kill?signal=%d", cid, s), nil)); err != nil {
570
+			if _, _, err := readBody(cli.call("POST", fmt.Sprintf("/containers/%s/kill?signal=%d", cid, s), nil, false)); err != nil {
571 571
 				utils.Debugf("Error sending signal: %s", err)
572 572
 			}
573 573
 		}
... ...
@@ -594,7 +594,7 @@ func (cli *DockerCli) CmdStart(args ...string) error {
594 594
 			return fmt.Errorf("Impossible to start and attach multiple containers at once.")
595 595
 		}
596 596
 
597
-		body, _, err := readBody(cli.call("GET", "/containers/"+cmd.Arg(0)+"/json", nil))
597
+		body, _, err := readBody(cli.call("GET", "/containers/"+cmd.Arg(0)+"/json", nil, false))
598 598
 		if err != nil {
599 599
 			return err
600 600
 		}
... ...
@@ -630,7 +630,7 @@ func (cli *DockerCli) CmdStart(args ...string) error {
630 630
 
631 631
 	var encounteredError error
632 632
 	for _, name := range cmd.Args() {
633
-		_, _, err := readBody(cli.call("POST", "/containers/"+name+"/start", nil))
633
+		_, _, err := readBody(cli.call("POST", "/containers/"+name+"/start", nil, false))
634 634
 		if err != nil {
635 635
 			if !*attach || !*openStdin {
636 636
 				fmt.Fprintf(cli.err, "%s\n", err)
... ...
@@ -687,9 +687,9 @@ func (cli *DockerCli) CmdInspect(args ...string) error {
687 687
 	status := 0
688 688
 
689 689
 	for _, name := range cmd.Args() {
690
-		obj, _, err := readBody(cli.call("GET", "/containers/"+name+"/json", nil))
690
+		obj, _, err := readBody(cli.call("GET", "/containers/"+name+"/json", nil, false))
691 691
 		if err != nil {
692
-			obj, _, err = readBody(cli.call("GET", "/images/"+name+"/json", nil))
692
+			obj, _, err = readBody(cli.call("GET", "/images/"+name+"/json", nil, false))
693 693
 			if err != nil {
694 694
 				if strings.Contains(err.Error(), "No such") {
695 695
 					fmt.Fprintf(cli.err, "Error: No such image or container: %s\n", name)
... ...
@@ -755,7 +755,7 @@ func (cli *DockerCli) CmdTop(args ...string) error {
755 755
 		val.Set("ps_args", strings.Join(cmd.Args()[1:], " "))
756 756
 	}
757 757
 
758
-	body, _, err := readBody(cli.call("GET", "/containers/"+cmd.Arg(0)+"/top?"+val.Encode(), nil))
758
+	body, _, err := readBody(cli.call("GET", "/containers/"+cmd.Arg(0)+"/top?"+val.Encode(), nil, false))
759 759
 	if err != nil {
760 760
 		return err
761 761
 	}
... ...
@@ -790,7 +790,7 @@ func (cli *DockerCli) CmdPort(args ...string) error {
790 790
 		port = parts[0]
791 791
 		proto = parts[1]
792 792
 	}
793
-	body, _, err := readBody(cli.call("GET", "/containers/"+cmd.Arg(0)+"/json", nil))
793
+	body, _, err := readBody(cli.call("GET", "/containers/"+cmd.Arg(0)+"/json", nil, false))
794 794
 	if err != nil {
795 795
 		return err
796 796
 	}
... ...
@@ -823,7 +823,7 @@ func (cli *DockerCli) CmdRmi(args ...string) error {
823 823
 
824 824
 	var encounteredError error
825 825
 	for _, name := range cmd.Args() {
826
-		body, _, err := readBody(cli.call("DELETE", "/images/"+name, nil))
826
+		body, _, err := readBody(cli.call("DELETE", "/images/"+name, nil, false))
827 827
 		if err != nil {
828 828
 			fmt.Fprintf(cli.err, "%s\n", err)
829 829
 			encounteredError = fmt.Errorf("Error: failed to remove one or more images")
... ...
@@ -860,7 +860,7 @@ func (cli *DockerCli) CmdHistory(args ...string) error {
860 860
 		return nil
861 861
 	}
862 862
 
863
-	stream, _, err := cli.call("GET", "/images/"+cmd.Arg(0)+"/history", nil)
863
+	stream, _, err := cli.call("GET", "/images/"+cmd.Arg(0)+"/history", nil, false)
864 864
 	if stream != nil {
865 865
 		defer stream.Close()
866 866
 	}
... ...
@@ -929,7 +929,7 @@ func (cli *DockerCli) CmdRm(args ...string) error {
929 929
 
930 930
 	var encounteredError error
931 931
 	for _, name := range cmd.Args() {
932
-		_, _, err := readBody(cli.call("DELETE", "/containers/"+name+"?"+val.Encode(), nil))
932
+		_, _, err := readBody(cli.call("DELETE", "/containers/"+name+"?"+val.Encode(), nil, false))
933 933
 		if err != nil {
934 934
 			fmt.Fprintf(cli.err, "%s\n", err)
935 935
 			encounteredError = fmt.Errorf("Error: failed to remove one or more containers")
... ...
@@ -953,7 +953,7 @@ func (cli *DockerCli) CmdKill(args ...string) error {
953 953
 
954 954
 	var encounteredError error
955 955
 	for _, name := range args {
956
-		if _, _, err := readBody(cli.call("POST", "/containers/"+name+"/kill", nil)); err != nil {
956
+		if _, _, err := readBody(cli.call("POST", "/containers/"+name+"/kill", nil, false)); err != nil {
957 957
 			fmt.Fprintf(cli.err, "%s\n", err)
958 958
 			encounteredError = fmt.Errorf("Error: failed to kill one or more containers")
959 959
 		} else {
... ...
@@ -1138,7 +1138,7 @@ func (cli *DockerCli) CmdImages(args ...string) error {
1138 1138
 	filter := cmd.Arg(0)
1139 1139
 
1140 1140
 	if *flViz || *flTree {
1141
-		stream, _, err := cli.call("GET", "/images/json?all=1", nil)
1141
+		stream, _, err := cli.call("GET", "/images/json?all=1", nil, false)
1142 1142
 		if stream != nil {
1143 1143
 			defer stream.Close()
1144 1144
 		}
... ...
@@ -1210,7 +1210,7 @@ func (cli *DockerCli) CmdImages(args ...string) error {
1210 1210
 			v.Set("all", "1")
1211 1211
 		}
1212 1212
 
1213
-		stream, _, err := cli.call("GET", "/images/json?"+v.Encode(), nil)
1213
+		stream, _, err := cli.call("GET", "/images/json?"+v.Encode(), nil, false)
1214 1214
 		if stream != nil {
1215 1215
 			defer stream.Close()
1216 1216
 		}
... ...
@@ -1364,7 +1364,7 @@ func (cli *DockerCli) CmdPs(args ...string) error {
1364 1364
 		v.Set("size", "1")
1365 1365
 	}
1366 1366
 
1367
-	body, _, err := readBody(cli.call("GET", "/containers/json?"+v.Encode(), nil))
1367
+	body, _, err := readBody(cli.call("GET", "/containers/json?"+v.Encode(), nil, false))
1368 1368
 	if err != nil {
1369 1369
 		return err
1370 1370
 	}
... ...
@@ -1456,7 +1456,7 @@ func (cli *DockerCli) CmdCommit(args ...string) error {
1456 1456
 			return err
1457 1457
 		}
1458 1458
 	}
1459
-	body, _, err := readBody(cli.call("POST", "/commit?"+v.Encode(), config))
1459
+	body, _, err := readBody(cli.call("POST", "/commit?"+v.Encode(), config, false))
1460 1460
 	if err != nil {
1461 1461
 		return err
1462 1462
 	}
... ...
@@ -1531,7 +1531,7 @@ func (cli *DockerCli) CmdDiff(args ...string) error {
1531 1531
 		return nil
1532 1532
 	}
1533 1533
 
1534
-	stream, _, err := cli.call("GET", "/containers/"+cmd.Arg(0)+"/changes", nil)
1534
+	stream, _, err := cli.call("GET", "/containers/"+cmd.Arg(0)+"/changes", nil, false)
1535 1535
 	if stream != nil {
1536 1536
 		defer stream.Close()
1537 1537
 	}
... ...
@@ -1569,7 +1569,7 @@ func (cli *DockerCli) CmdLogs(args ...string) error {
1569 1569
 		return nil
1570 1570
 	}
1571 1571
 	name := cmd.Arg(0)
1572
-	body, _, err := readBody(cli.call("GET", "/containers/"+name+"/json", nil))
1572
+	body, _, err := readBody(cli.call("GET", "/containers/"+name+"/json", nil, false))
1573 1573
 	if err != nil {
1574 1574
 		return err
1575 1575
 	}
... ...
@@ -1606,7 +1606,7 @@ func (cli *DockerCli) CmdAttach(args ...string) error {
1606 1606
 		return nil
1607 1607
 	}
1608 1608
 	name := cmd.Arg(0)
1609
-	body, _, err := readBody(cli.call("GET", "/containers/"+name+"/json", nil))
1609
+	body, _, err := readBody(cli.call("GET", "/containers/"+name+"/json", nil, false))
1610 1610
 	if err != nil {
1611 1611
 		return err
1612 1612
 	}
... ...
@@ -1673,7 +1673,7 @@ func (cli *DockerCli) CmdSearch(args ...string) error {
1673 1673
 
1674 1674
 	v := url.Values{}
1675 1675
 	v.Set("term", cmd.Arg(0))
1676
-	stream, _, err := cli.call("GET", "/images/search?"+v.Encode(), nil)
1676
+	stream, _, err := cli.call("GET", "/images/search?"+v.Encode(), nil, true)
1677 1677
 	if stream != nil {
1678 1678
 		defer stream.Close()
1679 1679
 	}
... ...
@@ -1741,7 +1741,7 @@ func (cli *DockerCli) CmdTag(args ...string) error {
1741 1741
 		v.Set("force", "1")
1742 1742
 	}
1743 1743
 
1744
-	if _, _, err := readBody(cli.call("POST", "/images/"+cmd.Arg(0)+"/tag?"+v.Encode(), nil)); err != nil {
1744
+	if _, _, err := readBody(cli.call("POST", "/images/"+cmd.Arg(0)+"/tag?"+v.Encode(), nil, false)); err != nil {
1745 1745
 		return err
1746 1746
 	}
1747 1747
 	return nil
... ...
@@ -1990,7 +1990,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
1990 1990
 	}
1991 1991
 
1992 1992
 	//create the container
1993
-	body, statusCode, err := readBody(cli.call("POST", "/containers/create?"+containerValues.Encode(), config))
1993
+	body, statusCode, err := readBody(cli.call("POST", "/containers/create?"+containerValues.Encode(), config, false))
1994 1994
 	//if image not found try to pull it
1995 1995
 	if statusCode == 404 {
1996 1996
 		_, tag := utils.ParseRepositoryTag(config.Image)
... ...
@@ -2027,7 +2027,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
2027 2027
 		if err = cli.stream("POST", "/images/create?"+v.Encode(), nil, cli.err, map[string][]string{"X-Registry-Auth": registryAuthHeader}); err != nil {
2028 2028
 			return err
2029 2029
 		}
2030
-		if body, _, err = readBody(cli.call("POST", "/containers/create?"+containerValues.Encode(), config)); err != nil {
2030
+		if body, _, err = readBody(cli.call("POST", "/containers/create?"+containerValues.Encode(), config, false)); err != nil {
2031 2031
 			return err
2032 2032
 		}
2033 2033
 	} else if err != nil {
... ...
@@ -2128,7 +2128,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
2128 2128
 	}
2129 2129
 
2130 2130
 	//start the container
2131
-	if _, _, err = readBody(cli.call("POST", "/containers/"+runResult.ID+"/start", hostConfig)); err != nil {
2131
+	if _, _, err = readBody(cli.call("POST", "/containers/"+runResult.ID+"/start", hostConfig, false)); err != nil {
2132 2132
 		return err
2133 2133
 	}
2134 2134
 
... ...
@@ -2158,13 +2158,13 @@ func (cli *DockerCli) CmdRun(args ...string) error {
2158 2158
 	if autoRemove {
2159 2159
 		// Autoremove: wait for the container to finish, retrieve
2160 2160
 		// the exit code and remove the container
2161
-		if _, _, err := readBody(cli.call("POST", "/containers/"+runResult.ID+"/wait", nil)); err != nil {
2161
+		if _, _, err := readBody(cli.call("POST", "/containers/"+runResult.ID+"/wait", nil, false)); err != nil {
2162 2162
 			return err
2163 2163
 		}
2164 2164
 		if _, status, err = getExitCode(cli, runResult.ID); err != nil {
2165 2165
 			return err
2166 2166
 		}
2167
-		if _, _, err := readBody(cli.call("DELETE", "/containers/"+runResult.ID+"?v=1", nil)); err != nil {
2167
+		if _, _, err := readBody(cli.call("DELETE", "/containers/"+runResult.ID+"?v=1", nil, false)); err != nil {
2168 2168
 			return err
2169 2169
 		}
2170 2170
 	} else {
... ...
@@ -2200,7 +2200,7 @@ func (cli *DockerCli) CmdCp(args ...string) error {
2200 2200
 	copyData.Resource = info[1]
2201 2201
 	copyData.HostPath = cmd.Arg(1)
2202 2202
 
2203
-	stream, statusCode, err := cli.call("POST", "/containers/"+info[0]+"/copy", copyData)
2203
+	stream, statusCode, err := cli.call("POST", "/containers/"+info[0]+"/copy", copyData, false)
2204 2204
 	if stream != nil {
2205 2205
 		defer stream.Close()
2206 2206
 	}
... ...
@@ -2251,7 +2251,7 @@ func (cli *DockerCli) CmdLoad(args ...string) error {
2251 2251
 	return nil
2252 2252
 }
2253 2253
 
2254
-func (cli *DockerCli) call(method, path string, data interface{}) (io.ReadCloser, int, error) {
2254
+func (cli *DockerCli) call(method, path string, data interface{}, passAuthInfo bool) (io.ReadCloser, int, error) {
2255 2255
 	var params io.Reader
2256 2256
 	if data != nil {
2257 2257
 		buf, err := json.Marshal(data)
... ...
@@ -2260,7 +2260,6 @@ func (cli *DockerCli) call(method, path string, data interface{}) (io.ReadCloser
2260 2260
 		}
2261 2261
 		params = bytes.NewBuffer(buf)
2262 2262
 	}
2263
-
2264 2263
 	// fixme: refactor client to support redirect
2265 2264
 	re := regexp.MustCompile("/+")
2266 2265
 	path = re.ReplaceAllString(path, "/")
... ...
@@ -2269,6 +2268,26 @@ func (cli *DockerCli) call(method, path string, data interface{}) (io.ReadCloser
2269 2269
 	if err != nil {
2270 2270
 		return nil, -1, err
2271 2271
 	}
2272
+	if passAuthInfo {
2273
+		cli.LoadConfigFile()
2274
+		// Resolve the Auth config relevant for this server
2275
+		authConfig := cli.configFile.ResolveAuthConfig(auth.IndexServerAddress())
2276
+		getHeaders := func(authConfig auth.AuthConfig) (map[string][]string, error) {
2277
+			buf, err := json.Marshal(authConfig)
2278
+			if err != nil {
2279
+				return nil, err
2280
+			}
2281
+			registryAuthHeader := []string{
2282
+				base64.URLEncoding.EncodeToString(buf),
2283
+			}
2284
+			return map[string][]string{"X-Registry-Auth": registryAuthHeader}, nil
2285
+		}
2286
+		if headers, err := getHeaders(authConfig); err == nil && headers != nil {
2287
+			for k, v := range headers {
2288
+				req.Header[k] = v
2289
+			}
2290
+		}
2291
+	}
2272 2292
 	req.Header.Set("User-Agent", "Docker-Client/"+VERSION)
2273 2293
 	req.Host = cli.addr
2274 2294
 	if data != nil {
... ...
@@ -2493,7 +2512,7 @@ func (cli *DockerCli) resizeTty(id string) {
2493 2493
 	v := url.Values{}
2494 2494
 	v.Set("h", strconv.Itoa(height))
2495 2495
 	v.Set("w", strconv.Itoa(width))
2496
-	if _, _, err := readBody(cli.call("POST", "/containers/"+id+"/resize?"+v.Encode(), nil)); err != nil {
2496
+	if _, _, err := readBody(cli.call("POST", "/containers/"+id+"/resize?"+v.Encode(), nil, false)); err != nil {
2497 2497
 		utils.Errorf("Error resize: %s", err)
2498 2498
 	}
2499 2499
 }
... ...
@@ -2530,7 +2549,7 @@ func (cli *DockerCli) LoadConfigFile() (err error) {
2530 2530
 }
2531 2531
 
2532 2532
 func waitForExit(cli *DockerCli, containerId string) (int, error) {
2533
-	body, _, err := readBody(cli.call("POST", "/containers/"+containerId+"/wait", nil))
2533
+	body, _, err := readBody(cli.call("POST", "/containers/"+containerId+"/wait", nil, false))
2534 2534
 	if err != nil {
2535 2535
 		return -1, err
2536 2536
 	}
... ...
@@ -2545,7 +2564,7 @@ func waitForExit(cli *DockerCli, containerId string) (int, error) {
2545 2545
 // getExitCode perform an inspect on the container. It returns
2546 2546
 // the running state and the exit code.
2547 2547
 func getExitCode(cli *DockerCli, containerId string) (bool, int, error) {
2548
-	body, _, err := readBody(cli.call("GET", "/containers/"+containerId+"/json", nil))
2548
+	body, _, err := readBody(cli.call("GET", "/containers/"+containerId+"/json", nil, false))
2549 2549
 	if err != nil {
2550 2550
 		// If we can't connect, then the daemon probably died.
2551 2551
 		if err != ErrConnectionRefused {
... ...
@@ -617,6 +617,10 @@ func (r *Registry) SearchRepositories(term string) (*SearchResults, error) {
617 617
 	if err != nil {
618 618
 		return nil, err
619 619
 	}
620
+	if r.authConfig != nil && len(r.authConfig.Username) > 0 {
621
+		req.SetBasicAuth(r.authConfig.Username, r.authConfig.Password)
622
+	}
623
+	req.Header.Set("X-Docker-Token", "true")
620 624
 	res, err := r.client.Do(req)
621 625
 	if err != nil {
622 626
 		return nil, err
... ...
@@ -462,9 +462,15 @@ func (srv *Server) ImagesSearch(job *engine.Job) engine.Status {
462 462
 		job.Errorf("Usage: %s TERM", job.Name)
463 463
 		return engine.StatusErr
464 464
 	}
465
-	term := job.Args[0]
466
-
467
-	r, err := registry.NewRegistry(nil, srv.HTTPRequestFactory(nil), auth.IndexServerAddress())
465
+        var (
466
+                term        = job.Args[0]
467
+                metaHeaders = map[string][]string{}
468
+                authConfig  = &auth.AuthConfig{}
469
+        )
470
+        job.GetenvJson("authConfig", authConfig)
471
+        job.GetenvJson("metaHeaders", metaHeaders)
472
+
473
+	r, err := registry.NewRegistry(authConfig, srv.HTTPRequestFactory(metaHeaders), auth.IndexServerAddress())
468 474
 	if err != nil {
469 475
 		job.Error(err)
470 476
 		return engine.StatusErr