Merge branch 'add_missing_attributes' of https://github.com/rogaha/docker into rogaha-add_missing_attributes

Conflicts:
	api.go

Docker-DCO-1.1-Signed-off-by: Victor Vieux <victor.vieux@docker.com> (github: vieux)
This commit is contained in:
Victor Vieux 2014-01-21 18:01:19 -08:00
commit 4c1879f919
4 changed files with 88 additions and 38 deletions

21
api.go
View File

@ -466,8 +466,29 @@ func getImagesSearch(srv *Server, version float64, w http.ResponseWriter, r *htt
if err := parseForm(r); err != nil { if err := parseForm(r); err != nil {
return err 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 job = srv.Eng.Job("search", r.Form.Get("term")) var job = srv.Eng.Job("search", r.Form.Get("term"))
job.SetenvJson("metaHeaders", metaHeaders)
job.SetenvJson("authConfig", authConfig)
job.Stdout.Add(w) job.Stdout.Add(w)
return job.Run() return job.Run()

View File

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

View File

@ -617,6 +617,10 @@ func (r *Registry) SearchRepositories(term string) (*SearchResults, error) {
if err != nil { if err != nil {
return nil, err 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) res, err := r.client.Do(req)
if err != nil { if err != nil {
return nil, err return nil, err

View File

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