in lib/containerruntime/dockerdaemon/cli.go [106:154]
func (cli *dockerClient) PullImage(ctx context.Context, repo, tag string) error {
query := url.Values{}
fromImage := fmt.Sprintf("%s/%s", cli.registry, repo)
query.Set("fromImage", fromImage)
query.Set("tag", tag)
headers := map[string][]string{"X-Registry-Auth": {""}}
urlPath := "/images/create"
// Construct request. It veries depending on client version.
var apiPath string
if cli.version != "" {
v := strings.TrimPrefix(cli.version, "v")
apiPath = fmt.Sprintf("%s/v%s%s", cli.basePath, v, urlPath)
} else {
apiPath = fmt.Sprintf("%s%s", cli.basePath, urlPath)
}
u := &url.URL{Path: apiPath}
if len(query) > 0 {
u.RawQuery = query.Encode()
}
req, err := http.NewRequest("POST", u.String(), bytes.NewReader([]byte{}))
if err != nil {
return fmt.Errorf("create request: %s", err)
}
req.Header = headers
req.Host = "docker"
req.URL.Host = cli.addr
req.URL.Scheme = cli.scheme
resp, err := ctxhttp.Do(ctx, cli.client, req)
if err != nil {
return fmt.Errorf("send post request: %s", err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
errMsg, err := ioutil.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("read error resp: %s", err)
}
return fmt.Errorf("Error posting to %s: code %d, err: %s", urlPath, resp.StatusCode, errMsg)
}
// Docker daemon returns 200 early. Close resp.Body after reading all.
if _, err := ioutil.ReadAll(resp.Body); err != nil {
return fmt.Errorf("read resp body: %s", err)
}
return nil
}