mirror of
				https://github.com/containers/podman.git
				synced 2025-11-04 17:07:20 +08:00 
			
		
		
		
	Merge pull request #14484 from marshall-lee/test/manifest-push
Add missing tests for manifests API
This commit is contained in:
		@ -163,7 +163,6 @@ func ManifestAddV3(w http.ResponseWriter, r *http.Request) {
 | 
				
			|||||||
	// Wrapper to support 3.x with 4.x libpod
 | 
						// Wrapper to support 3.x with 4.x libpod
 | 
				
			||||||
	query := struct {
 | 
						query := struct {
 | 
				
			||||||
		entities.ManifestAddOptions
 | 
							entities.ManifestAddOptions
 | 
				
			||||||
		Images    []string
 | 
					 | 
				
			||||||
		TLSVerify bool `schema:"tlsVerify"`
 | 
							TLSVerify bool `schema:"tlsVerify"`
 | 
				
			||||||
	}{}
 | 
						}{}
 | 
				
			||||||
	if err := json.NewDecoder(r.Body).Decode(&query); err != nil {
 | 
						if err := json.NewDecoder(r.Body).Decode(&query); err != nil {
 | 
				
			||||||
 | 
				
			|||||||
@ -6,6 +6,8 @@
 | 
				
			|||||||
red='\e[31m'
 | 
					red='\e[31m'
 | 
				
			||||||
nc='\e[0m'
 | 
					nc='\e[0m'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					start_registry
 | 
				
			||||||
 | 
					
 | 
				
			||||||
podman pull -q $IMAGE
 | 
					podman pull -q $IMAGE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
t GET libpod/images/json 200 \
 | 
					t GET libpod/images/json 200 \
 | 
				
			||||||
@ -20,15 +22,10 @@ t GET libpod/images/$IMAGE/tree 200 \
 | 
				
			|||||||
t POST "libpod/images/nonesuch/tag?repo=myrepo&tag=mytag" 404
 | 
					t POST "libpod/images/nonesuch/tag?repo=myrepo&tag=mytag" 404
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Tag the image
 | 
					# Tag the image
 | 
				
			||||||
t POST "libpod/images/$IMAGE/tag?repo=localhost:5000/myrepo&tag=mytag" 201
 | 
					t POST "libpod/images/$IMAGE/tag?repo=localhost:$REGISTRY_PORT/myrepo&tag=mytag" 201
 | 
				
			||||||
 | 
					
 | 
				
			||||||
t GET libpod/images/$IMAGE/json 200 \
 | 
					t GET libpod/images/$IMAGE/json 200 \
 | 
				
			||||||
  .RepoTags[1]=localhost:5000/myrepo:mytag
 | 
					  .RepoTags[1]=localhost:$REGISTRY_PORT/myrepo:mytag
 | 
				
			||||||
 | 
					 | 
				
			||||||
# Run registry container
 | 
					 | 
				
			||||||
# FIXME this fails if python tests have been run first...
 | 
					 | 
				
			||||||
podman run -d --name registry -p 5000:5000 quay.io/libpod/registry:2.7 /entrypoint.sh /etc/docker/registry/config.yml
 | 
					 | 
				
			||||||
wait_for_port localhost 5000
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Push to local registry and check output
 | 
					# Push to local registry and check output
 | 
				
			||||||
while read -r LINE
 | 
					while read -r LINE
 | 
				
			||||||
@ -36,32 +33,23 @@ do
 | 
				
			|||||||
  if echo "${LINE}" | jq --exit-status 'select( .status != null) | select ( .status | contains("digest: sha256:"))' &>/dev/null; then
 | 
					  if echo "${LINE}" | jq --exit-status 'select( .status != null) | select ( .status | contains("digest: sha256:"))' &>/dev/null; then
 | 
				
			||||||
    GOT_DIGEST="1"
 | 
					    GOT_DIGEST="1"
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
done < <(curl -sL "http://$HOST:$PORT/images/localhost:5000/myrepo/push?tlsVerify=false&tag=mytag" -XPOST)
 | 
					done < <(curl -sL "http://$HOST:$PORT/images/localhost:$REGISTRY_PORT/myrepo/push?tlsVerify=false&tag=mytag" -XPOST -H "X-Registry-Config: $REGISTRY_CONFIG_HEADER")
 | 
				
			||||||
if [ -z "${GOT_DIGEST}" ] ; then
 | 
					if [ -z "${GOT_DIGEST}" ] ; then
 | 
				
			||||||
  echo -e "${red}not ok: did not found digest in output${nc}"  1>&2;
 | 
					  echo -e "${red}not ok: did not found digest in output${nc}"  1>&2;
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Push to local registry
 | 
					# Push to local registry
 | 
				
			||||||
t POST "images/localhost:5000/myrepo/push?tlsVerify=false&tag=mytag" 200
 | 
					t POST "images/localhost:$REGISTRY_PORT/myrepo/push?tlsVerify=false&tag=mytag" 200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Untag the image
 | 
					# Untag the image
 | 
				
			||||||
t POST "libpod/images/$iid/untag?repo=localhost:5000/myrepo&tag=mytag" 201
 | 
					t POST "libpod/images/$iid/untag?repo=localhost:$REGISTRY_PORT/myrepo&tag=mytag" 201
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Try to push non-existing image
 | 
					# Try to push non-existing image
 | 
				
			||||||
t POST "images/localhost:5000/idonotexist/push?tlsVerify=false" 404
 | 
					t POST "images/localhost:$REGISTRY_PORT/idonotexist/push?tlsVerify=false" 404
 | 
				
			||||||
 | 
					
 | 
				
			||||||
t GET libpod/images/$IMAGE/json 200 \
 | 
					t GET libpod/images/$IMAGE/json 200 \
 | 
				
			||||||
  .RepoTags[-1]=$IMAGE
 | 
					  .RepoTags[-1]=$IMAGE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Remove the registry container
 | 
					# Remove image
 | 
				
			||||||
t DELETE libpod/containers/registry?force=true 200
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Remove images
 | 
					 | 
				
			||||||
t DELETE libpod/images/$IMAGE 200 \
 | 
					t DELETE libpod/images/$IMAGE 200 \
 | 
				
			||||||
  .ExitCode=0
 | 
					  .ExitCode=0
 | 
				
			||||||
t DELETE libpod/images/quay.io/libpod/registry:2.7 200 \
 | 
					 | 
				
			||||||
  .ExitCode=0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if [ -z "${GOT_DIGEST}" ] ; then
 | 
					 | 
				
			||||||
  exit 1;
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -2,18 +2,43 @@
 | 
				
			|||||||
#
 | 
					#
 | 
				
			||||||
# Tests for manifest list endpoints
 | 
					# Tests for manifest list endpoints
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					start_registry
 | 
				
			||||||
 | 
					
 | 
				
			||||||
t POST /v3.4.0/libpod/manifests/create?name=abc 200 \
 | 
					t POST /v3.4.0/libpod/manifests/create?name=abc 200 \
 | 
				
			||||||
    .Id~[0-9a-f]\\{64\\}
 | 
					    .Id~[0-9a-f]\\{64\\}
 | 
				
			||||||
id_abc=$(jq -r '.Id' <<<"$output")
 | 
					id_abc=$(jq -r '.Id' <<<"$output")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
t POST /v4.0.0/libpod/manifests/xyz 201 \
 | 
					t POST /v4.0.0/libpod/manifests/xyz 201 \
 | 
				
			||||||
    .Id~[0-9a-f]\\{64\\}
 | 
					    .Id~[0-9a-f]\\{64\\}
 | 
				
			||||||
echo xyz $output
 | 
					 | 
				
			||||||
id_xyz=$(jq -r '.Id' <<<"$output")
 | 
					id_xyz=$(jq -r '.Id' <<<"$output")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
t GET /v3.4.0/libpod/manifests/$id_abc/exists 204
 | 
					t GET /v3.4.0/libpod/manifests/$id_abc/exists 204
 | 
				
			||||||
t GET /v4.0.0/libpod/manifests/$id_xyz/exists 204
 | 
					t GET /v4.0.0/libpod/manifests/$id_xyz/exists 204
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					id_abc_image=$($PODMAN_BIN --root $WORKDIR/server_root image build -q --format=docker -<<EOF
 | 
				
			||||||
 | 
					FROM alpine
 | 
				
			||||||
 | 
					RUN >file1
 | 
				
			||||||
 | 
					EOF
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					id_xyz_image=$($PODMAN_BIN --root $WORKDIR/server_root image build -q --format=docker -<<EOF
 | 
				
			||||||
 | 
					FROM alpine
 | 
				
			||||||
 | 
					RUN >file2
 | 
				
			||||||
 | 
					EOF
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function cleanUpManifestTest() {
 | 
				
			||||||
 | 
					    podman rmi -a
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					t POST /v3.4.0/libpod/manifests/$id_abc/add images="[\"containers-storage:$id_abc_image\"]" 200
 | 
				
			||||||
 | 
					t PUT /v4.0.0/libpod/manifests/$id_xyz operation='update' images="[\"containers-storage:$id_xyz_image\"]" 200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					t POST "/v3.4.0/libpod/manifests/abc:latest/push?destination=localhost:$REGISTRY_PORT%2Fabc:latest&tlsVerify=false&all=true" 200
 | 
				
			||||||
 | 
					t POST "/v4.0.0/libpod/manifests/xyz:latest/registry/localhost:$REGISTRY_PORT%2Fxyz:latest?tlsVerify=false&all=true" 200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# /v3.x cannot delete a manifest list
 | 
					# /v3.x cannot delete a manifest list
 | 
				
			||||||
t DELETE /v4.0.0/libpod/manifests/$id_abc 200
 | 
					t DELETE /v4.0.0/libpod/manifests/$id_abc 200
 | 
				
			||||||
t DELETE /v4.0.0/libpod/manifests/$id_xyz 200
 | 
					t DELETE /v4.0.0/libpod/manifests/$id_xyz 200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cleanUpManifestTest
 | 
				
			||||||
 | 
				
			|||||||
@ -128,7 +128,7 @@ t DELETE "containers/$cid"
 | 
				
			|||||||
# disable the docker.io enforcement.
 | 
					# disable the docker.io enforcement.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
stop_service
 | 
					stop_service
 | 
				
			||||||
CONTAINERS_CONF=$(pwd)/test/apiv2/containers.conf start_service
 | 
					CONTAINERS_CONF=$TESTS_DIR/containers.conf start_service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
t POST   "images/create?fromImage=quay.io/libpod/alpine:latest"       200 .error~null .status~".*Download complete.*"
 | 
					t POST   "images/create?fromImage=quay.io/libpod/alpine:latest"       200 .error~null .status~".*Download complete.*"
 | 
				
			||||||
t POST   "images/alpine/tag?repo=foo"                                 201
 | 
					t POST   "images/alpine/tag?repo=foo"                                 201
 | 
				
			||||||
 | 
				
			|||||||
@ -87,6 +87,7 @@ trap err_handler ERR
 | 
				
			|||||||
#########
 | 
					#########
 | 
				
			||||||
function die() {
 | 
					function die() {
 | 
				
			||||||
    echo "$ME: $*" >&2
 | 
					    echo "$ME: $*" >&2
 | 
				
			||||||
 | 
					    clean_up_server
 | 
				
			||||||
    exit 1
 | 
					    exit 1
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -219,19 +220,19 @@ function jsonify() {
 | 
				
			|||||||
function t() {
 | 
					function t() {
 | 
				
			||||||
    local method=$1; shift
 | 
					    local method=$1; shift
 | 
				
			||||||
    local path=$1; shift
 | 
					    local path=$1; shift
 | 
				
			||||||
    local curl_args
 | 
					    local -a curl_args
 | 
				
			||||||
    local content_type="application/json"
 | 
					    local content_type="application/json"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    local testname="$method $path"
 | 
					    local testname="$method $path"
 | 
				
			||||||
    # POST requests may be followed by one or more key=value pairs.
 | 
					    # POST and PUT requests may be followed by one or more key=value pairs.
 | 
				
			||||||
    # Slurp the command line until we see a 3-digit status code.
 | 
					    # Slurp the command line until we see a 3-digit status code.
 | 
				
			||||||
    if [[ $method = "POST" ]]; then
 | 
					    if [[ $method = "POST" || $method == "PUT" ]]; then
 | 
				
			||||||
        local -a post_args
 | 
					        local -a post_args
 | 
				
			||||||
        for arg; do
 | 
					        for arg; do
 | 
				
			||||||
            case "$arg" in
 | 
					            case "$arg" in
 | 
				
			||||||
                *=*)              post_args+=("$arg");
 | 
					                *=*)              post_args+=("$arg");
 | 
				
			||||||
                                  shift;;
 | 
					                                  shift;;
 | 
				
			||||||
                *.tar)            curl_args="--data-binary @$arg" ;
 | 
					                *.tar)            curl_args+=(--data-binary @$arg);
 | 
				
			||||||
                                  content_type="application/x-tar";
 | 
					                                  content_type="application/x-tar";
 | 
				
			||||||
                                  shift;;
 | 
					                                  shift;;
 | 
				
			||||||
                application/*)    content_type="$arg";
 | 
					                application/*)    content_type="$arg";
 | 
				
			||||||
@ -241,8 +242,8 @@ function t() {
 | 
				
			|||||||
            esac
 | 
					            esac
 | 
				
			||||||
        done
 | 
					        done
 | 
				
			||||||
        if [[ -z "$curl_args" ]]; then
 | 
					        if [[ -z "$curl_args" ]]; then
 | 
				
			||||||
            curl_args="-d $(jsonify ${post_args[@]})"
 | 
					            curl_args+=(-d $(jsonify ${post_args[@]}))
 | 
				
			||||||
            testname="$testname [$curl_args]"
 | 
					            testname="$testname [${curl_args[@]}]"
 | 
				
			||||||
        fi
 | 
					        fi
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -269,7 +270,11 @@ function t() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    # curl -X HEAD but without --head seems to wait for output anyway
 | 
					    # curl -X HEAD but without --head seems to wait for output anyway
 | 
				
			||||||
    if [[ $method == "HEAD" ]]; then
 | 
					    if [[ $method == "HEAD" ]]; then
 | 
				
			||||||
        curl_args="--head"
 | 
					        curl_args+=("--head")
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if [ -n "$REGISTRY_CONFIG_HEADER" ]; then
 | 
				
			||||||
 | 
					        curl_args+=(-H "X-Registry-Config: $REGISTRY_CONFIG_HEADER")
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    local expected_code=$1; shift
 | 
					    local expected_code=$1; shift
 | 
				
			||||||
@ -281,7 +286,7 @@ function t() {
 | 
				
			|||||||
    # -s = silent, but --write-out 'format' gives us important response data
 | 
					    # -s = silent, but --write-out 'format' gives us important response data
 | 
				
			||||||
    # The hairy "{ ...;rc=$?; } || :" lets us capture curl's exit code and
 | 
					    # The hairy "{ ...;rc=$?; } || :" lets us capture curl's exit code and
 | 
				
			||||||
    # give a helpful diagnostic if it fails.
 | 
					    # give a helpful diagnostic if it fails.
 | 
				
			||||||
    { response=$(curl -s -X $method ${curl_args}                 \
 | 
					    { response=$(curl -s -X $method "${curl_args[@]}"            \
 | 
				
			||||||
                    -H "Content-type: $content_type"             \
 | 
					                    -H "Content-type: $content_type"             \
 | 
				
			||||||
                    --dump-header $WORKDIR/curl.headers.out      \
 | 
					                    --dump-header $WORKDIR/curl.headers.out      \
 | 
				
			||||||
                    --write-out '%{http_code}^%{content_type}^%{time_total}' \
 | 
					                    --write-out '%{http_code}^%{content_type}^%{time_total}' \
 | 
				
			||||||
@ -289,8 +294,7 @@ function t() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    # Any error from curl is instant bad news, from which we can't recover
 | 
					    # Any error from curl is instant bad news, from which we can't recover
 | 
				
			||||||
    if [[ $rc -ne 0 ]]; then
 | 
					    if [[ $rc -ne 0 ]]; then
 | 
				
			||||||
        echo "FATAL: curl failure ($rc) on $url - cannot continue" >&2
 | 
					        die "curl failure ($rc) on $url - cannot continue"
 | 
				
			||||||
        exit 1
 | 
					 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Show returned headers (without trailing ^M or empty lines) in log file.
 | 
					    # Show returned headers (without trailing ^M or empty lines) in log file.
 | 
				
			||||||
@ -410,6 +414,7 @@ function stop_service() {
 | 
				
			|||||||
REGISTRY_PORT=
 | 
					REGISTRY_PORT=
 | 
				
			||||||
REGISTRY_USERNAME=
 | 
					REGISTRY_USERNAME=
 | 
				
			||||||
REGISTRY_PASSWORD=
 | 
					REGISTRY_PASSWORD=
 | 
				
			||||||
 | 
					REGISTRY_CONFIG_HEADER=
 | 
				
			||||||
function start_registry() {
 | 
					function start_registry() {
 | 
				
			||||||
    # We can be invoked multiple times, e.g. from different subtests, but
 | 
					    # We can be invoked multiple times, e.g. from different subtests, but
 | 
				
			||||||
    # let's assume that once started we only kill it at the end of tests.
 | 
					    # let's assume that once started we only kill it at the end of tests.
 | 
				
			||||||
@ -420,6 +425,7 @@ function start_registry() {
 | 
				
			|||||||
    REGISTRY_PORT=$(random_port)
 | 
					    REGISTRY_PORT=$(random_port)
 | 
				
			||||||
    REGISTRY_USERNAME=u$(random_string 7)
 | 
					    REGISTRY_USERNAME=u$(random_string 7)
 | 
				
			||||||
    REGISTRY_PASSWORD=p$(random_string 7)
 | 
					    REGISTRY_PASSWORD=p$(random_string 7)
 | 
				
			||||||
 | 
					    REGISTRY_CONFIG_HEADER=$(echo "{\"localhost:${REGISTRY_PORT}\":{\"username\":\"${REGISTRY_USERNAME}\",\"password\":\"${REGISTRY_PASSWORD}\"}}" | base64 --wrap=0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    local REGDIR=$WORKDIR/registry
 | 
					    local REGDIR=$WORKDIR/registry
 | 
				
			||||||
    local AUTHDIR=$REGDIR/auth
 | 
					    local AUTHDIR=$REGDIR/auth
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user