Browse Source

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 11 years ago
parent
commit
2cfd696b9b
4 changed files with 89 additions and 39 deletions
  1. 21 0
      api.go
  2. 55 36
      commands.go
  3. 4 0
      registry/registry.go
  4. 9 3
      server.go

+ 21 - 0
api.go

@@ -500,12 +500,33 @@ func getImagesSearch(srv *Server, version float64, w http.ResponseWriter, r *htt
 	if err := parseForm(r); err != nil {
 		return err
 	}
+	var (
+		authEncoded = r.Header.Get("X-Registry-Auth")
+		authConfig  = &auth.AuthConfig{}
+		metaHeaders = map[string][]string{}
+	)
+
+	if authEncoded != "" {
+		authJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded))
+		if err := json.NewDecoder(authJson).Decode(authConfig); err != nil {
+			// for a search it is not an error if no auth was given
+			// to increase compatibility with the existing api it is defaulting to be empty
+			authConfig = &auth.AuthConfig{}
+		}
+	}
+	for k, v := range r.Header {
+		if strings.HasPrefix(k, "X-Meta-") {
+			metaHeaders[k] = v
+		}
+	}
 
 	var (
 		err  error
 		outs *engine.Table
 		job  = srv.Eng.Job("search", r.Form.Get("term"))
 	)
+	job.SetenvJson("metaHeaders", metaHeaders)
+	job.SetenvJson("authConfig", authConfig)
 	if version >= 1.9 {
 		job.Stdout.Add(w)
 	} else if outs, err = job.Stdout.AddTable(); err != nil {

+ 55 - 36
commands.go

@@ -335,7 +335,7 @@ func (cli *DockerCli) CmdLogin(args ...string) error {
 	authconfig.ServerAddress = serverAddress
 	cli.configFile.Configs[serverAddress] = authconfig
 
-	body, statusCode, err := readBody(cli.call("POST", "/auth", cli.configFile.Configs[serverAddress]))
+	body, statusCode, err := readBody(cli.call("POST", "/auth", cli.configFile.Configs[serverAddress], false))
 	if statusCode == 401 {
 		delete(cli.configFile.Configs, serverAddress)
 		auth.SaveConfig(cli.configFile)
@@ -400,7 +400,7 @@ func (cli *DockerCli) CmdVersion(args ...string) error {
 		fmt.Fprintf(cli.out, "Git commit (client): %s\n", GITCOMMIT)
 	}
 
-	body, _, err := readBody(cli.call("GET", "/version", nil))
+	body, _, err := readBody(cli.call("GET", "/version", nil, false))
 	if err != nil {
 		return err
 	}
@@ -441,7 +441,7 @@ func (cli *DockerCli) CmdInfo(args ...string) error {
 		return nil
 	}
 
-	body, _, err := readBody(cli.call("GET", "/info", nil))
+	body, _, err := readBody(cli.call("GET", "/info", nil, false))
 	if err != nil {
 		return err
 	}
@@ -521,7 +521,7 @@ func (cli *DockerCli) CmdStop(args ...string) error {
 
 	var encounteredError error
 	for _, name := range cmd.Args() {
-		_, _, err := readBody(cli.call("POST", "/containers/"+name+"/stop?"+v.Encode(), nil))
+		_, _, err := readBody(cli.call("POST", "/containers/"+name+"/stop?"+v.Encode(), nil, false))
 		if err != nil {
 			fmt.Fprintf(cli.err, "%s\n", err)
 			encounteredError = fmt.Errorf("Error: failed to stop one or more containers")
@@ -548,7 +548,7 @@ func (cli *DockerCli) CmdRestart(args ...string) error {
 
 	var encounteredError error
 	for _, name := range cmd.Args() {
-		_, _, err := readBody(cli.call("POST", "/containers/"+name+"/restart?"+v.Encode(), nil))
+		_, _, err := readBody(cli.call("POST", "/containers/"+name+"/restart?"+v.Encode(), nil, false))
 		if err != nil {
 			fmt.Fprintf(cli.err, "%s\n", err)
 			encounteredError = fmt.Errorf("Error: failed to  restart one or more containers")
@@ -567,7 +567,7 @@ func (cli *DockerCli) forwardAllSignals(cid string) chan os.Signal {
 			if s == syscall.SIGCHLD {
 				continue
 			}
-			if _, _, err := readBody(cli.call("POST", fmt.Sprintf("/containers/%s/kill?signal=%d", cid, s), nil)); err != nil {
+			if _, _, err := readBody(cli.call("POST", fmt.Sprintf("/containers/%s/kill?signal=%d", cid, s), nil, false)); err != nil {
 				utils.Debugf("Error sending signal: %s", err)
 			}
 		}
@@ -594,7 +594,7 @@ func (cli *DockerCli) CmdStart(args ...string) error {
 			return fmt.Errorf("Impossible to start and attach multiple containers at once.")
 		}
 
-		body, _, err := readBody(cli.call("GET", "/containers/"+cmd.Arg(0)+"/json", nil))
+		body, _, err := readBody(cli.call("GET", "/containers/"+cmd.Arg(0)+"/json", nil, false))
 		if err != nil {
 			return err
 		}
@@ -630,7 +630,7 @@ func (cli *DockerCli) CmdStart(args ...string) error {
 
 	var encounteredError error
 	for _, name := range cmd.Args() {
-		_, _, err := readBody(cli.call("POST", "/containers/"+name+"/start", nil))
+		_, _, err := readBody(cli.call("POST", "/containers/"+name+"/start", nil, false))
 		if err != nil {
 			if !*attach || !*openStdin {
 				fmt.Fprintf(cli.err, "%s\n", err)
@@ -687,9 +687,9 @@ func (cli *DockerCli) CmdInspect(args ...string) error {
 	status := 0
 
 	for _, name := range cmd.Args() {
-		obj, _, err := readBody(cli.call("GET", "/containers/"+name+"/json", nil))
+		obj, _, err := readBody(cli.call("GET", "/containers/"+name+"/json", nil, false))
 		if err != nil {
-			obj, _, err = readBody(cli.call("GET", "/images/"+name+"/json", nil))
+			obj, _, err = readBody(cli.call("GET", "/images/"+name+"/json", nil, false))
 			if err != nil {
 				if strings.Contains(err.Error(), "No such") {
 					fmt.Fprintf(cli.err, "Error: No such image or container: %s\n", name)
@@ -755,7 +755,7 @@ func (cli *DockerCli) CmdTop(args ...string) error {
 		val.Set("ps_args", strings.Join(cmd.Args()[1:], " "))
 	}
 
-	body, _, err := readBody(cli.call("GET", "/containers/"+cmd.Arg(0)+"/top?"+val.Encode(), nil))
+	body, _, err := readBody(cli.call("GET", "/containers/"+cmd.Arg(0)+"/top?"+val.Encode(), nil, false))
 	if err != nil {
 		return err
 	}
@@ -790,7 +790,7 @@ func (cli *DockerCli) CmdPort(args ...string) error {
 		port = parts[0]
 		proto = parts[1]
 	}
-	body, _, err := readBody(cli.call("GET", "/containers/"+cmd.Arg(0)+"/json", nil))
+	body, _, err := readBody(cli.call("GET", "/containers/"+cmd.Arg(0)+"/json", nil, false))
 	if err != nil {
 		return err
 	}
@@ -823,7 +823,7 @@ func (cli *DockerCli) CmdRmi(args ...string) error {
 
 	var encounteredError error
 	for _, name := range cmd.Args() {
-		body, _, err := readBody(cli.call("DELETE", "/images/"+name, nil))
+		body, _, err := readBody(cli.call("DELETE", "/images/"+name, nil, false))
 		if err != nil {
 			fmt.Fprintf(cli.err, "%s\n", err)
 			encounteredError = fmt.Errorf("Error: failed to remove one or more images")
@@ -860,7 +860,7 @@ func (cli *DockerCli) CmdHistory(args ...string) error {
 		return nil
 	}
 
-	stream, _, err := cli.call("GET", "/images/"+cmd.Arg(0)+"/history", nil)
+	stream, _, err := cli.call("GET", "/images/"+cmd.Arg(0)+"/history", nil, false)
 	if stream != nil {
 		defer stream.Close()
 	}
@@ -929,7 +929,7 @@ func (cli *DockerCli) CmdRm(args ...string) error {
 
 	var encounteredError error
 	for _, name := range cmd.Args() {
-		_, _, err := readBody(cli.call("DELETE", "/containers/"+name+"?"+val.Encode(), nil))
+		_, _, err := readBody(cli.call("DELETE", "/containers/"+name+"?"+val.Encode(), nil, false))
 		if err != nil {
 			fmt.Fprintf(cli.err, "%s\n", err)
 			encounteredError = fmt.Errorf("Error: failed to remove one or more containers")
@@ -953,7 +953,7 @@ func (cli *DockerCli) CmdKill(args ...string) error {
 
 	var encounteredError error
 	for _, name := range args {
-		if _, _, err := readBody(cli.call("POST", "/containers/"+name+"/kill", nil)); err != nil {
+		if _, _, err := readBody(cli.call("POST", "/containers/"+name+"/kill", nil, false)); err != nil {
 			fmt.Fprintf(cli.err, "%s\n", err)
 			encounteredError = fmt.Errorf("Error: failed to kill one or more containers")
 		} else {
@@ -1138,7 +1138,7 @@ func (cli *DockerCli) CmdImages(args ...string) error {
 	filter := cmd.Arg(0)
 
 	if *flViz || *flTree {
-		stream, _, err := cli.call("GET", "/images/json?all=1", nil)
+		stream, _, err := cli.call("GET", "/images/json?all=1", nil, false)
 		if stream != nil {
 			defer stream.Close()
 		}
@@ -1210,7 +1210,7 @@ func (cli *DockerCli) CmdImages(args ...string) error {
 			v.Set("all", "1")
 		}
 
-		stream, _, err := cli.call("GET", "/images/json?"+v.Encode(), nil)
+		stream, _, err := cli.call("GET", "/images/json?"+v.Encode(), nil, false)
 		if stream != nil {
 			defer stream.Close()
 		}
@@ -1364,7 +1364,7 @@ func (cli *DockerCli) CmdPs(args ...string) error {
 		v.Set("size", "1")
 	}
 
-	body, _, err := readBody(cli.call("GET", "/containers/json?"+v.Encode(), nil))
+	body, _, err := readBody(cli.call("GET", "/containers/json?"+v.Encode(), nil, false))
 	if err != nil {
 		return err
 	}
@@ -1456,7 +1456,7 @@ func (cli *DockerCli) CmdCommit(args ...string) error {
 			return err
 		}
 	}
-	body, _, err := readBody(cli.call("POST", "/commit?"+v.Encode(), config))
+	body, _, err := readBody(cli.call("POST", "/commit?"+v.Encode(), config, false))
 	if err != nil {
 		return err
 	}
@@ -1531,7 +1531,7 @@ func (cli *DockerCli) CmdDiff(args ...string) error {
 		return nil
 	}
 
-	stream, _, err := cli.call("GET", "/containers/"+cmd.Arg(0)+"/changes", nil)
+	stream, _, err := cli.call("GET", "/containers/"+cmd.Arg(0)+"/changes", nil, false)
 	if stream != nil {
 		defer stream.Close()
 	}
@@ -1569,7 +1569,7 @@ func (cli *DockerCli) CmdLogs(args ...string) error {
 		return nil
 	}
 	name := cmd.Arg(0)
-	body, _, err := readBody(cli.call("GET", "/containers/"+name+"/json", nil))
+	body, _, err := readBody(cli.call("GET", "/containers/"+name+"/json", nil, false))
 	if err != nil {
 		return err
 	}
@@ -1606,7 +1606,7 @@ func (cli *DockerCli) CmdAttach(args ...string) error {
 		return nil
 	}
 	name := cmd.Arg(0)
-	body, _, err := readBody(cli.call("GET", "/containers/"+name+"/json", nil))
+	body, _, err := readBody(cli.call("GET", "/containers/"+name+"/json", nil, false))
 	if err != nil {
 		return err
 	}
@@ -1673,7 +1673,7 @@ func (cli *DockerCli) CmdSearch(args ...string) error {
 
 	v := url.Values{}
 	v.Set("term", cmd.Arg(0))
-	stream, _, err := cli.call("GET", "/images/search?"+v.Encode(), nil)
+	stream, _, err := cli.call("GET", "/images/search?"+v.Encode(), nil, true)
 	if stream != nil {
 		defer stream.Close()
 	}
@@ -1741,7 +1741,7 @@ func (cli *DockerCli) CmdTag(args ...string) error {
 		v.Set("force", "1")
 	}
 
-	if _, _, err := readBody(cli.call("POST", "/images/"+cmd.Arg(0)+"/tag?"+v.Encode(), nil)); err != nil {
+	if _, _, err := readBody(cli.call("POST", "/images/"+cmd.Arg(0)+"/tag?"+v.Encode(), nil, false)); err != nil {
 		return err
 	}
 	return nil
@@ -1990,7 +1990,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
 	}
 
 	//create the container
-	body, statusCode, err := readBody(cli.call("POST", "/containers/create?"+containerValues.Encode(), config))
+	body, statusCode, err := readBody(cli.call("POST", "/containers/create?"+containerValues.Encode(), config, false))
 	//if image not found try to pull it
 	if statusCode == 404 {
 		_, tag := utils.ParseRepositoryTag(config.Image)
@@ -2027,7 +2027,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
 		if err = cli.stream("POST", "/images/create?"+v.Encode(), nil, cli.err, map[string][]string{"X-Registry-Auth": registryAuthHeader}); err != nil {
 			return err
 		}
-		if body, _, err = readBody(cli.call("POST", "/containers/create?"+containerValues.Encode(), config)); err != nil {
+		if body, _, err = readBody(cli.call("POST", "/containers/create?"+containerValues.Encode(), config, false)); err != nil {
 			return err
 		}
 	} else if err != nil {
@@ -2128,7 +2128,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
 	}
 
 	//start the container
-	if _, _, err = readBody(cli.call("POST", "/containers/"+runResult.ID+"/start", hostConfig)); err != nil {
+	if _, _, err = readBody(cli.call("POST", "/containers/"+runResult.ID+"/start", hostConfig, false)); err != nil {
 		return err
 	}
 
@@ -2158,13 +2158,13 @@ func (cli *DockerCli) CmdRun(args ...string) error {
 	if autoRemove {
 		// Autoremove: wait for the container to finish, retrieve
 		// the exit code and remove the container
-		if _, _, err := readBody(cli.call("POST", "/containers/"+runResult.ID+"/wait", nil)); err != nil {
+		if _, _, err := readBody(cli.call("POST", "/containers/"+runResult.ID+"/wait", nil, false)); err != nil {
 			return err
 		}
 		if _, status, err = getExitCode(cli, runResult.ID); err != nil {
 			return err
 		}
-		if _, _, err := readBody(cli.call("DELETE", "/containers/"+runResult.ID+"?v=1", nil)); err != nil {
+		if _, _, err := readBody(cli.call("DELETE", "/containers/"+runResult.ID+"?v=1", nil, false)); err != nil {
 			return err
 		}
 	} else {
@@ -2200,7 +2200,7 @@ func (cli *DockerCli) CmdCp(args ...string) error {
 	copyData.Resource = info[1]
 	copyData.HostPath = cmd.Arg(1)
 
-	stream, statusCode, err := cli.call("POST", "/containers/"+info[0]+"/copy", copyData)
+	stream, statusCode, err := cli.call("POST", "/containers/"+info[0]+"/copy", copyData, false)
 	if stream != nil {
 		defer stream.Close()
 	}
@@ -2251,7 +2251,7 @@ func (cli *DockerCli) CmdLoad(args ...string) error {
 	return nil
 }
 
-func (cli *DockerCli) call(method, path string, data interface{}) (io.ReadCloser, int, error) {
+func (cli *DockerCli) call(method, path string, data interface{}, passAuthInfo bool) (io.ReadCloser, int, error) {
 	var params io.Reader
 	if data != nil {
 		buf, err := json.Marshal(data)
@@ -2260,7 +2260,6 @@ func (cli *DockerCli) call(method, path string, data interface{}) (io.ReadCloser
 		}
 		params = bytes.NewBuffer(buf)
 	}
-
 	// fixme: refactor client to support redirect
 	re := regexp.MustCompile("/+")
 	path = re.ReplaceAllString(path, "/")
@@ -2269,6 +2268,26 @@ func (cli *DockerCli) call(method, path string, data interface{}) (io.ReadCloser
 	if err != nil {
 		return nil, -1, err
 	}
+	if passAuthInfo {
+		cli.LoadConfigFile()
+		// Resolve the Auth config relevant for this server
+		authConfig := cli.configFile.ResolveAuthConfig(auth.IndexServerAddress())
+		getHeaders := func(authConfig auth.AuthConfig) (map[string][]string, error) {
+			buf, err := json.Marshal(authConfig)
+			if err != nil {
+				return nil, err
+			}
+			registryAuthHeader := []string{
+				base64.URLEncoding.EncodeToString(buf),
+			}
+			return map[string][]string{"X-Registry-Auth": registryAuthHeader}, nil
+		}
+		if headers, err := getHeaders(authConfig); err == nil && headers != nil {
+			for k, v := range headers {
+				req.Header[k] = v
+			}
+		}
+	}
 	req.Header.Set("User-Agent", "Docker-Client/"+VERSION)
 	req.Host = cli.addr
 	if data != nil {
@@ -2493,7 +2512,7 @@ func (cli *DockerCli) resizeTty(id string) {
 	v := url.Values{}
 	v.Set("h", strconv.Itoa(height))
 	v.Set("w", strconv.Itoa(width))
-	if _, _, err := readBody(cli.call("POST", "/containers/"+id+"/resize?"+v.Encode(), nil)); err != nil {
+	if _, _, err := readBody(cli.call("POST", "/containers/"+id+"/resize?"+v.Encode(), nil, false)); err != nil {
 		utils.Errorf("Error resize: %s", err)
 	}
 }
@@ -2530,7 +2549,7 @@ func (cli *DockerCli) LoadConfigFile() (err error) {
 }
 
 func waitForExit(cli *DockerCli, containerId string) (int, error) {
-	body, _, err := readBody(cli.call("POST", "/containers/"+containerId+"/wait", nil))
+	body, _, err := readBody(cli.call("POST", "/containers/"+containerId+"/wait", nil, false))
 	if err != nil {
 		return -1, err
 	}
@@ -2545,7 +2564,7 @@ func waitForExit(cli *DockerCli, containerId string) (int, error) {
 // getExitCode perform an inspect on the container. It returns
 // the running state and the exit code.
 func getExitCode(cli *DockerCli, containerId string) (bool, int, error) {
-	body, _, err := readBody(cli.call("GET", "/containers/"+containerId+"/json", nil))
+	body, _, err := readBody(cli.call("GET", "/containers/"+containerId+"/json", nil, false))
 	if err != nil {
 		// If we can't connect, then the daemon probably died.
 		if err != ErrConnectionRefused {

+ 4 - 0
registry/registry.go

@@ -617,6 +617,10 @@ func (r *Registry) SearchRepositories(term string) (*SearchResults, error) {
 	if err != nil {
 		return nil, err
 	}
+	if r.authConfig != nil && len(r.authConfig.Username) > 0 {
+		req.SetBasicAuth(r.authConfig.Username, r.authConfig.Password)
+	}
+	req.Header.Set("X-Docker-Token", "true")
 	res, err := r.client.Do(req)
 	if err != nil {
 		return nil, err

+ 9 - 3
server.go

@@ -462,9 +462,15 @@ func (srv *Server) ImagesSearch(job *engine.Job) engine.Status {
 		job.Errorf("Usage: %s TERM", job.Name)
 		return engine.StatusErr
 	}
-	term := job.Args[0]
-
-	r, err := registry.NewRegistry(nil, srv.HTTPRequestFactory(nil), auth.IndexServerAddress())
+        var (
+                term        = job.Args[0]
+                metaHeaders = map[string][]string{}
+                authConfig  = &auth.AuthConfig{}
+        )
+        job.GetenvJson("authConfig", authConfig)
+        job.GetenvJson("metaHeaders", metaHeaders)
+
+	r, err := registry.NewRegistry(authConfig, srv.HTTPRequestFactory(metaHeaders), auth.IndexServerAddress())
 	if err != nil {
 		job.Error(err)
 		return engine.StatusErr