code: func (r *Session) PushImageJSONRegistry(imgData *ImgData, jsonRaw []byte, registry string) error {
  
  	u := registry + "images/" + imgData.ID + "/json"
  
  	logrus.Debugf("[registry] Calling PUT %s", u)
  
  	req, err := http.NewRequest("PUT", u, bytes.NewReader(jsonRaw))
  	if err != nil {
  		return err
  	}
  	req.Header.Add("Content-type", "application/json")
  
  	res, err := r.client.Do(req)
  	if err != nil {
  		return fmt.Errorf("Failed to upload metadata: %s", err)
  	}
  	defer res.Body.Close()
  	if res.StatusCode == 401 && strings.HasPrefix(registry, "http://") {
  		return newJSONError("HTTP code 401, Docker will not send auth headers over HTTP.", res)
  	}
  	if res.StatusCode != 200 {
  		errBody, err := ioutil.ReadAll(res.Body)
  		if err != nil {
  			return newJSONError(fmt.Sprintf("HTTP code %d while uploading metadata and error when trying to parse response body: %s", res.StatusCode, err), res)
  		}
  		var jsonBody map[string]string
  		if err := json.Unmarshal(errBody, &jsonBody); err != nil {
  			errBody = []byte(err.Error())
  		} else if jsonBody["error"] == "Image already exists" {
  			return ErrAlreadyExists
  		}
  		return newJSONError(fmt.Sprintf("HTTP code %d while uploading metadata: %q", res.StatusCode, errBody), res)
  	}
  	return nil
  }
docs: // PushImageJSONRegistry pushes JSON metadata for a local image to the registry