github.com/sams1990/dockerrepo@v17.12.1-ce-rc2+incompatible/client/image_pull.go (about) 1 package client 2 3 import ( 4 "io" 5 "net/http" 6 "net/url" 7 "strings" 8 9 "golang.org/x/net/context" 10 11 "github.com/docker/distribution/reference" 12 "github.com/docker/docker/api/types" 13 ) 14 15 // ImagePull requests the docker host to pull an image from a remote registry. 16 // It executes the privileged function if the operation is unauthorized 17 // and it tries one more time. 18 // It's up to the caller to handle the io.ReadCloser and close it properly. 19 // 20 // FIXME(vdemeester): there is currently used in a few way in docker/docker 21 // - if not in trusted content, ref is used to pass the whole reference, and tag is empty 22 // - if in trusted content, ref is used to pass the reference name, and tag for the digest 23 func (cli *Client) ImagePull(ctx context.Context, refStr string, options types.ImagePullOptions) (io.ReadCloser, error) { 24 ref, err := reference.ParseNormalizedNamed(refStr) 25 if err != nil { 26 return nil, err 27 } 28 29 query := url.Values{} 30 query.Set("fromImage", reference.FamiliarName(ref)) 31 if !options.All { 32 query.Set("tag", getAPITagFromNamedRef(ref)) 33 } 34 if options.Platform != "" { 35 query.Set("platform", strings.ToLower(options.Platform)) 36 } 37 38 resp, err := cli.tryImageCreate(ctx, query, options.RegistryAuth) 39 if resp.statusCode == http.StatusUnauthorized && options.PrivilegeFunc != nil { 40 newAuthHeader, privilegeErr := options.PrivilegeFunc() 41 if privilegeErr != nil { 42 return nil, privilegeErr 43 } 44 resp, err = cli.tryImageCreate(ctx, query, newAuthHeader) 45 } 46 if err != nil { 47 return nil, err 48 } 49 return resp.body, nil 50 } 51 52 // getAPITagFromNamedRef returns a tag from the specified reference. 53 // This function is necessary as long as the docker "server" api expects 54 // digests to be sent as tags and makes a distinction between the name 55 // and tag/digest part of a reference. 56 func getAPITagFromNamedRef(ref reference.Named) string { 57 if digested, ok := ref.(reference.Digested); ok { 58 return digested.Digest().String() 59 } 60 ref = reference.TagNameOnly(ref) 61 if tagged, ok := ref.(reference.Tagged); ok { 62 return tagged.Tag() 63 } 64 return "" 65 }