diff options
Diffstat (limited to 'test/apiv2')
-rw-r--r-- | test/apiv2/10-images.at | 2 | ||||
-rw-r--r-- | test/apiv2/12-imagesMore.at | 56 | ||||
-rw-r--r-- | test/apiv2/15-manifest.at | 24 | ||||
-rw-r--r-- | test/apiv2/20-containers.at | 10 | ||||
-rw-r--r-- | test/apiv2/60-auth.at | 4 | ||||
-rw-r--r-- | test/apiv2/70-short-names.at | 2 | ||||
-rwxr-xr-x | test/apiv2/test-apiv2 | 90 |
7 files changed, 112 insertions, 76 deletions
diff --git a/test/apiv2/10-images.at b/test/apiv2/10-images.at index 13aaea317..f03b95786 100644 --- a/test/apiv2/10-images.at +++ b/test/apiv2/10-images.at @@ -53,7 +53,7 @@ t POST "images/create?fromImage=alpine" 200 .error~null .status~".*Download comp t POST "images/create?fromImage=alpine&tag=latest" 200 # 10977 - handle platform parameter correctly -t POST "images/create?fromImage=testimage:20210610&platform=linux/arm64" 200 +t POST "images/create?fromImage=quay.io/libpod/testimage:20210610&platform=linux/arm64" 200 t GET "images/testimage:20210610/json" 200 \ .Architecture=arm64 diff --git a/test/apiv2/12-imagesMore.at b/test/apiv2/12-imagesMore.at index 67b4f1c79..57d5e114d 100644 --- a/test/apiv2/12-imagesMore.at +++ b/test/apiv2/12-imagesMore.at @@ -6,6 +6,8 @@ red='\e[31m' nc='\e[0m' +start_registry + podman pull -q $IMAGE t GET libpod/images/json 200 \ @@ -20,48 +22,38 @@ t GET libpod/images/$IMAGE/tree 200 \ t POST "libpod/images/nonesuch/tag?repo=myrepo&tag=mytag" 404 # 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 \ - .RepoTags[1]=localhost:5000/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 -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 + .RepoTags[1]=localhost:$REGISTRY_PORT/myrepo:mytag + +# Push to local registry... +t POST "images/localhost:$REGISTRY_PORT/myrepo/push?tlsVerify=false&tag=mytag" 200 + +# ...and check output. We can't use our built-in checks because this output +# is a sequence of JSON objects, i.e., individual ones, not in a JSON array. +# The lines themselves are valid JSON, but taken together they are not. +readarray lines <<<"$output" +s0=$(jq -r .status <<<"${lines[0]}") +is "$s0" "The push refers to repository [localhost:$REGISTRY_PORT/myrepo:mytag]" \ + "Push to local registry: first status line" + +# FIXME: is there a way to test the actual digest? +s1=$(jq -r .status <<<"${lines[1]}") +like "$s1" "mytag: digest: sha256:[0-9a-f]\{64\} size: [0-9]\+" \ + "Push to local registry: second status line" # 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 -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 \ .RepoTags[-1]=$IMAGE -# Remove the registry container -t DELETE libpod/containers/registry?force=true 200 - -# Remove images +# Remove image t DELETE libpod/images/$IMAGE 200 \ .ExitCode=0 -t DELETE libpod/images/quay.io/libpod/registry:2.7 200 \ - .ExitCode=0 -if [ -z "${GOT_DIGEST}" ] ; then - exit 1; -fi +stop_registry diff --git a/test/apiv2/15-manifest.at b/test/apiv2/15-manifest.at index 0dd7026fa..970bed5a8 100644 --- a/test/apiv2/15-manifest.at +++ b/test/apiv2/15-manifest.at @@ -2,18 +2,40 @@ # # Tests for manifest list endpoints +start_registry + t POST /v3.4.0/libpod/manifests/create?name=abc 200 \ .Id~[0-9a-f]\\{64\\} id_abc=$(jq -r '.Id' <<<"$output") t POST /v4.0.0/libpod/manifests/xyz 201 \ .Id~[0-9a-f]\\{64\\} -echo xyz $output id_xyz=$(jq -r '.Id' <<<"$output") t GET /v3.4.0/libpod/manifests/$id_abc/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 +) + +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 t DELETE /v4.0.0/libpod/manifests/$id_abc 200 t DELETE /v4.0.0/libpod/manifests/$id_xyz 200 + +podman rmi -a +stop_registry diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at index 4d32a1031..383c527b4 100644 --- a/test/apiv2/20-containers.at +++ b/test/apiv2/20-containers.at @@ -45,16 +45,16 @@ t GET libpod/containers/json?all=true 200 \ .[0].IsInfra=false # Test compat API for Network Settings (.Network is N/A when rootless) -network_expect= +network_expect="Networks=null" if root; then - network_expect='.[0].NetworkSettings.Networks.podman.NetworkID=podman' + network_expect="Networks.podman.NetworkID=podman" fi t GET /containers/json?all=true 200 \ length=1 \ .[0].Id~[0-9a-f]\\{64\\} \ .[0].Image=$IMAGE \ .[0].Mounts~.*/tmp \ - $network_expect + .[0].NetworkSettings.$network_expect # compat API imageid with sha256: prefix t GET containers/json?limit=1 200 \ @@ -239,6 +239,7 @@ t GET containers/$cid/json 200 \ t POST containers/create Image=$IMAGE Entrypoint='["top"]' 201 \ .Id~[0-9a-f]\\{64\\} cid_top=$(jq -r '.Id' <<<"$output") + t GET containers/${cid_top}/json 200 \ .Config.Entrypoint[0]="top" \ .Config.Cmd='[]' \ @@ -477,7 +478,8 @@ for endpoint in containers/create libpod/containers/create; do t POST libpod/containers/$cid/init 204 - t GET libpod/containers/$cid/json 200 + t GET libpod/containers/$cid/json 200 \ + .HostsPath="" t DELETE containers/$cid 204 done diff --git a/test/apiv2/60-auth.at b/test/apiv2/60-auth.at index 1e087d12b..465b0a96d 100644 --- a/test/apiv2/60-auth.at +++ b/test/apiv2/60-auth.at @@ -3,7 +3,7 @@ # registry-related tests # -start_registry +start_registry htpasswd # Test unreachable t POST /v1.40/auth username=$REGISTRY_USERNAME password=WrOnGPassWord serveraddress=does.not.exist.io:1234/ \ @@ -26,3 +26,5 @@ t POST /v1.40/auth username=$REGISTRY_USERNAME password=$REGISTRY_PASSWORD serve 200 \ .Status="Login Succeeded" \ .IdentityToken="" + +stop_registry diff --git a/test/apiv2/70-short-names.at b/test/apiv2/70-short-names.at index dbf816f55..bd7f8e7bd 100644 --- a/test/apiv2/70-short-names.at +++ b/test/apiv2/70-short-names.at @@ -128,7 +128,7 @@ t DELETE "containers/$cid" # disable the docker.io enforcement. 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/alpine/tag?repo=foo" 201 diff --git a/test/apiv2/test-apiv2 b/test/apiv2/test-apiv2 index c3545522e..8ecc2aa2d 100755 --- a/test/apiv2/test-apiv2 +++ b/test/apiv2/test-apiv2 @@ -62,7 +62,7 @@ clean_up_server() { podman rm -a podman rmi -af - stop_registry + stop_registry --cleanup stop_service fi } @@ -87,6 +87,7 @@ trap err_handler ERR ######### function die() { echo "$ME: $*" >&2 + clean_up_server exit 1 } @@ -219,19 +220,19 @@ function jsonify() { function t() { local method=$1; shift local path=$1; shift - local curl_args + local -a curl_args local content_type="application/json" 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. - if [[ $method = "POST" ]]; then + if [[ $method = "POST" || $method == "PUT" ]]; then local -a post_args for arg; do case "$arg" in *=*) post_args+=("$arg"); shift;; - *.tar) curl_args="--data-binary @$arg" ; + *.tar) curl_args+=(--data-binary @$arg); content_type="application/x-tar"; shift;; application/*) content_type="$arg"; @@ -241,8 +242,8 @@ function t() { esac done if [[ -z "$curl_args" ]]; then - curl_args="-d $(jsonify ${post_args[@]})" - testname="$testname [$curl_args]" + curl_args=(-d $(jsonify ${post_args[@]})) + testname="$testname [${curl_args[@]}]" fi fi @@ -269,7 +270,7 @@ function t() { # curl -X HEAD but without --head seems to wait for output anyway if [[ $method == "HEAD" ]]; then - curl_args="--head" + curl_args+=("--head") fi local expected_code=$1; shift @@ -281,7 +282,7 @@ function t() { # -s = silent, but --write-out 'format' gives us important response data # The hairy "{ ...;rc=$?; } || :" lets us capture curl's exit code and # 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" \ --dump-header $WORKDIR/curl.headers.out \ --write-out '%{http_code}^%{content_type}^%{time_total}' \ @@ -289,8 +290,7 @@ function t() { # Any error from curl is instant bad news, from which we can't recover if [[ $rc -ne 0 ]]; then - echo "FATAL: curl failure ($rc) on $url - cannot continue" >&2 - exit 1 + die "curl failure ($rc) on $url - cannot continue" fi # Show returned headers (without trailing ^M or empty lines) in log file. @@ -380,11 +380,6 @@ function start_service() { die "Cannot start service on non-localhost ($HOST)" fi - echo "rootdir: "$WORKDIR - # Some tests use shortnames; force registry override to work around - # docker.io throttling. -# FIXME esm revisit pulling expected images re: shortnames caused tests to fail -# env CONTAINERS_REGISTRIES_CONF=$TESTS_DIR/../registries.conf $PODMAN_BIN \ --root $WORKDIR/server_root --syslog=true \ system service \ @@ -411,15 +406,17 @@ REGISTRY_PORT= REGISTRY_USERNAME= REGISTRY_PASSWORD= function start_registry() { - # 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. + # We can be called multiple times, but each time should start a new + # registry container with (possibly) different configuration. That + # means that all callers must be responsible for invoking stop_registry. if [[ -n "$REGISTRY_PORT" ]]; then - return + die "start_registry invoked twice in succession, without stop_registry" fi + # First arg is auth type (default: "none", but can also be "htpasswd") + local auth="${1:-none}" + REGISTRY_PORT=$(random_port) - REGISTRY_USERNAME=u$(random_string 7) - REGISTRY_PASSWORD=p$(random_string 7) local REGDIR=$WORKDIR/registry local AUTHDIR=$REGDIR/auth @@ -433,24 +430,39 @@ function start_registry() { podman ${PODMAN_REGISTRY_ARGS} pull $REGISTRY_IMAGE || podman ${PODMAN_REGISTRY_ARGS} pull $REGISTRY_IMAGE - # Create a local cert and credentials - # FIXME: is there a hidden "--quiet" flag? This is too noisy. - openssl req -newkey rsa:4096 -nodes -sha256 \ - -keyout $AUTHDIR/domain.key -x509 -days 2 \ - -out $AUTHDIR/domain.crt \ - -subj "/C=US/ST=Foo/L=Bar/O=Red Hat, Inc./CN=registry host certificate" \ - -addext subjectAltName=DNS:localhost - htpasswd -Bbn ${REGISTRY_USERNAME} ${REGISTRY_PASSWORD} \ - > $AUTHDIR/htpasswd + # Create a local cert (no need to do this more than once) + if [[ ! -e $AUTHDIR/domain.key ]]; then + # FIXME: is there a hidden "--quiet" flag? This is too noisy. + openssl req -newkey rsa:4096 -nodes -sha256 \ + -keyout $AUTHDIR/domain.key -x509 -days 2 \ + -out $AUTHDIR/domain.crt \ + -subj "/C=US/ST=Foo/L=Bar/O=Red Hat, Inc./CN=registry host certificate" \ + -addext subjectAltName=DNS:localhost + fi + + # If invoked with auth=htpasswd, create credentials + REGISTRY_USERNAME= + REGISTRY_PASSWORD= + declare -a registry_auth_params=(-e "REGISTRY_AUTH=$auth") + if [[ "$auth" = "htpasswd" ]]; then + REGISTRY_USERNAME=u$(random_string 7) + REGISTRY_PASSWORD=p$(random_string 7) + + htpasswd -Bbn ${REGISTRY_USERNAME} ${REGISTRY_PASSWORD} \ + > $AUTHDIR/htpasswd + + registry_auth_params+=( + -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" + -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" + ) + fi # Run the registry, and wait for it to come up podman ${PODMAN_REGISTRY_ARGS} run -d \ -p ${REGISTRY_PORT}:5000 \ --name registry \ -v $AUTHDIR:/auth:Z \ - -e "REGISTRY_AUTH=htpasswd" \ - -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ - -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ + "${registry_auth_params[@]}" \ -e REGISTRY_HTTP_TLS_CERTIFICATE=/auth/domain.crt \ -e REGISTRY_HTTP_TLS_KEY=/auth/domain.key \ ${REGISTRY_IMAGE} @@ -462,13 +474,19 @@ function stop_registry() { local REGDIR=${WORKDIR}/registry if [[ -d $REGDIR ]]; then local OPTS="--root ${REGDIR}/root --runroot ${REGDIR}/runroot" - podman $OPTS stop -f -t 0 -a + podman $OPTS stop -i -t 0 registry # rm/rmi are important when running rootless: without them we # get EPERMS in tmpdir cleanup because files are owned by subuids. - podman $OPTS rm -f -a - podman $OPTS rmi -f -a + podman $OPTS rm -f -i registry + if [[ "$1" = "--cleanup" ]]; then + podman $OPTS rmi -f -a + fi fi + + REGISTRY_PORT= + REGISTRY_USERNAME= + REGISTRY_PASSWORD= } ################# |