Merge pull request #11528 from jlhawn/separate_init_blob_upload

Separate init blob upload
This commit is contained in:
Michael Crosby 2015-03-20 16:39:31 -07:00
commit 50b10850bb

View file

@ -6,6 +6,7 @@ import (
"fmt"
"io"
"io/ioutil"
"net/http"
"strconv"
log "github.com/Sirupsen/logrus"
@ -212,29 +213,14 @@ func (r *Session) GetV2ImageBlobReader(ep *Endpoint, imageName, sumType, sum str
// 'layer' is an uncompressed reader of the blob to be pushed.
// The server will generate it's own checksum calculation.
func (r *Session) PutV2ImageBlob(ep *Endpoint, imageName, sumType, sumStr string, blobRdr io.Reader, auth *RequestAuthorization) error {
routeURL, err := getV2Builder(ep).BuildBlobUploadURL(imageName)
location, err := r.initiateBlobUpload(ep, imageName, auth)
if err != nil {
return err
}
log.Debugf("[registry] Calling %q %s", "POST", routeURL)
req, err := r.reqFactory.NewRequest("POST", routeURL, nil)
if err != nil {
return err
}
if err := auth.Authorize(req); err != nil {
return err
}
res, _, err := r.doRequest(req)
if err != nil {
return err
}
location := res.Header.Get("Location")
method := "PUT"
log.Debugf("[registry] Calling %q %s", method, location)
req, err = r.reqFactory.NewRequest(method, location, ioutil.NopCloser(blobRdr))
req, err := r.reqFactory.NewRequest(method, location, ioutil.NopCloser(blobRdr))
if err != nil {
return err
}
@ -244,7 +230,7 @@ func (r *Session) PutV2ImageBlob(ep *Endpoint, imageName, sumType, sumStr string
if err := auth.Authorize(req); err != nil {
return err
}
res, _, err = r.doRequest(req)
res, _, err := r.doRequest(req)
if err != nil {
return err
}
@ -265,6 +251,51 @@ func (r *Session) PutV2ImageBlob(ep *Endpoint, imageName, sumType, sumStr string
return nil
}
// initiateBlobUpload gets the blob upload location for the given image name.
func (r *Session) initiateBlobUpload(ep *Endpoint, imageName string, auth *RequestAuthorization) (location string, err error) {
routeURL, err := getV2Builder(ep).BuildBlobUploadURL(imageName)
if err != nil {
return "", err
}
log.Debugf("[registry] Calling %q %s", "POST", routeURL)
req, err := r.reqFactory.NewRequest("POST", routeURL, nil)
if err != nil {
return "", err
}
if err := auth.Authorize(req); err != nil {
return "", err
}
res, _, err := r.doRequest(req)
if err != nil {
return "", err
}
if res.StatusCode != http.StatusAccepted {
if res.StatusCode == http.StatusUnauthorized {
return "", errLoginRequired
}
if res.StatusCode == http.StatusNotFound {
return "", ErrDoesNotExist
}
errBody, err := ioutil.ReadAll(res.Body)
if err != nil {
return "", err
}
log.Debugf("Unexpected response from server: %q %#v", errBody, res.Header)
return "", utils.NewHTTPRequestError(fmt.Sprintf("Server error: unexpected %d response status trying to initiate upload of %s", res.StatusCode, imageName), res)
}
if location = res.Header.Get("Location"); location == "" {
return "", fmt.Errorf("registry did not return a Location header for resumable blob upload for image %s", imageName)
}
return
}
// Finally Push the (signed) manifest of the blobs we've just pushed
func (r *Session) PutV2ImageManifest(ep *Endpoint, imageName, tagName string, signedManifest, rawManifest []byte, auth *RequestAuthorization) (digest.Digest, error) {
routeURL, err := getV2Builder(ep).BuildManifestURL(imageName, tagName)