mirror of
https://github.com/containers/podman.git
synced 2025-06-19 00:06:43 +08:00
Docker APIv2 push sends digest in response body
Signed-off-by: Matej Vasek <mvasek@redhat.com>
This commit is contained in:
@ -1,6 +1,8 @@
|
||||
package compat
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@ -19,6 +21,14 @@ import (
|
||||
func PushImage(w http.ResponseWriter, r *http.Request) {
|
||||
decoder := r.Context().Value("decoder").(*schema.Decoder)
|
||||
runtime := r.Context().Value("runtime").(*libpod.Runtime)
|
||||
|
||||
digestFile, err := ioutil.TempFile("", "digest.txt")
|
||||
if err != nil {
|
||||
utils.Error(w, "unable to create digest tempfile", http.StatusInternalServerError, errors.Wrap(err, "unable to create tempfile"))
|
||||
return
|
||||
}
|
||||
defer digestFile.Close()
|
||||
|
||||
// Now use the ABI implementation to prevent us from having duplicate
|
||||
// code.
|
||||
imageEngine := abi.ImageEngine{Libpod: runtime}
|
||||
@ -65,12 +75,13 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
|
||||
password = authconf.Password
|
||||
}
|
||||
options := entities.ImagePushOptions{
|
||||
All: query.All,
|
||||
Authfile: authfile,
|
||||
Compress: query.Compress,
|
||||
Format: query.Format,
|
||||
Password: password,
|
||||
Username: username,
|
||||
All: query.All,
|
||||
Authfile: authfile,
|
||||
Compress: query.Compress,
|
||||
Format: query.Format,
|
||||
Password: password,
|
||||
Username: username,
|
||||
DigestFile: digestFile.Name(),
|
||||
}
|
||||
if _, found := r.URL.Query()["tlsVerify"]; found {
|
||||
options.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
|
||||
@ -93,5 +104,21 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
utils.WriteResponse(w, http.StatusOK, "")
|
||||
digestBytes, err := ioutil.ReadAll(digestFile)
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to read digest tmp file"))
|
||||
return
|
||||
}
|
||||
|
||||
tag := query.Tag
|
||||
if tag == "" {
|
||||
tag = "latest"
|
||||
}
|
||||
respData := struct {
|
||||
Status string `json:"status"`
|
||||
}{
|
||||
Status: fmt.Sprintf("%s: digest: %s size: null", tag, string(digestBytes)),
|
||||
}
|
||||
|
||||
utils.WriteJSON(w, http.StatusOK, &respData)
|
||||
}
|
||||
|
@ -3,6 +3,9 @@
|
||||
# Tests for more image-related endpoints
|
||||
#
|
||||
|
||||
red='\e[31m'
|
||||
nc='\e[0m'
|
||||
|
||||
podman pull -q $IMAGE
|
||||
|
||||
t GET libpod/images/json 200 \
|
||||
@ -26,6 +29,17 @@ t GET libpod/images/$IMAGE/json 200 \
|
||||
podman run -d --name registry -p 5000:5000 quay.io/libpod/registry:2.6 /entrypoint.sh /etc/docker/registry/config.yml
|
||||
wait_for_port localhost 5000
|
||||
|
||||
# Push to local registry and check output
|
||||
while read -r LINE
|
||||
do
|
||||
if echo "${LINE}" | jq --exit-status 'select( .status != null) | select ( .status | contains("digest: sha256:"))' &>/dev/null; then
|
||||
GOT_DIGEST="1"
|
||||
fi
|
||||
done < <(curl -sL "http://$HOST:$PORT/images/localhost:5000/myrepo/push?tlsVerify=false&tag=mytag" -XPOST)
|
||||
if [ -z "${GOT_DIGEST}" ] ; then
|
||||
echo -e "${red}not ok: did not found digest in output${nc}" 1>&2;
|
||||
fi
|
||||
|
||||
# Push to local registry
|
||||
t POST "images/localhost:5000/myrepo/push?tlsVerify=false&tag=mytag" '' 200
|
||||
|
||||
@ -43,3 +57,7 @@ t DELETE libpod/images/$IMAGE 200 \
|
||||
.ExitCode=0
|
||||
t DELETE libpod/images/quay.io/libpod/registry:2.6 200 \
|
||||
.ExitCode=0
|
||||
|
||||
if [ -z "${GOT_DIGEST}" ] ; then
|
||||
exit 1;
|
||||
fi
|
||||
|
Reference in New Issue
Block a user