github.com/rish1988/moby@v25.0.2+incompatible/client/image_push.go (about) 1 package client // import "github.com/docker/docker/client" 2 3 import ( 4 "context" 5 "errors" 6 "io" 7 "net/http" 8 "net/url" 9 10 "github.com/distribution/reference" 11 "github.com/docker/docker/api/types/image" 12 "github.com/docker/docker/api/types/registry" 13 "github.com/docker/docker/errdefs" 14 ) 15 16 // ImagePush requests the docker host to push an image to a remote registry. 17 // It executes the privileged function if the operation is unauthorized 18 // and it tries one more time. 19 // It's up to the caller to handle the io.ReadCloser and close it properly. 20 func (cli *Client) ImagePush(ctx context.Context, image string, options image.PushOptions) (io.ReadCloser, error) { 21 ref, err := reference.ParseNormalizedNamed(image) 22 if err != nil { 23 return nil, err 24 } 25 26 if _, isCanonical := ref.(reference.Canonical); isCanonical { 27 return nil, errors.New("cannot push a digest reference") 28 } 29 30 name := reference.FamiliarName(ref) 31 query := url.Values{} 32 if !options.All { 33 ref = reference.TagNameOnly(ref) 34 if tagged, ok := ref.(reference.Tagged); ok { 35 query.Set("tag", tagged.Tag()) 36 } 37 } 38 39 resp, err := cli.tryImagePush(ctx, name, query, options.RegistryAuth) 40 if errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil { 41 newAuthHeader, privilegeErr := options.PrivilegeFunc() 42 if privilegeErr != nil { 43 return nil, privilegeErr 44 } 45 resp, err = cli.tryImagePush(ctx, name, query, newAuthHeader) 46 } 47 if err != nil { 48 return nil, err 49 } 50 return resp.body, nil 51 } 52 53 func (cli *Client) tryImagePush(ctx context.Context, imageID string, query url.Values, registryAuth string) (serverResponse, error) { 54 return cli.post(ctx, "/images/"+imageID+"/push", query, nil, http.Header{ 55 registry.AuthHeader: {registryAuth}, 56 }) 57 }