image_push.go 1.7 KB

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