apiv2 tests: clean up

Mostly fix a bad design decision I made early on, re: registry.
 old: registry starts once, runs to the end
 new: registry is brought up on demand, then stopped
Reason: there are times when we need a password-controlled
registry, and times when we need it open.

As long as I'm in here, I've also cleaned up some confusing code
and fixed things so tests can run rootless again.

Signed-off-by: Ed Santiago <santiago@redhat.com>
This commit is contained in:
Ed Santiago
2022-06-08 13:41:43 -06:00
parent 576c739e5f
commit bce97a3b5d
6 changed files with 75 additions and 55 deletions

View File

@ -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 t POST "images/create?fromImage=alpine&tag=latest" 200
# 10977 - handle platform parameter correctly # 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 \ t GET "images/testimage:20210610/json" 200 \
.Architecture=arm64 .Architecture=arm64

View File

@ -27,20 +27,22 @@ t POST "libpod/images/$IMAGE/tag?repo=localhost:$REGISTRY_PORT/myrepo&tag=mytag"
t GET libpod/images/$IMAGE/json 200 \ t GET libpod/images/$IMAGE/json 200 \
.RepoTags[1]=localhost:$REGISTRY_PORT/myrepo:mytag .RepoTags[1]=localhost:$REGISTRY_PORT/myrepo:mytag
# Push to local registry and check output # Push to local registry...
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:$REGISTRY_PORT/myrepo/push?tlsVerify=false&tag=mytag" -XPOST -H "X-Registry-Config: $REGISTRY_CONFIG_HEADER")
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:$REGISTRY_PORT/myrepo/push?tlsVerify=false&tag=mytag" 200 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 # Untag the image
t POST "libpod/images/$iid/untag?repo=localhost:$REGISTRY_PORT/myrepo&tag=mytag" 201 t POST "libpod/images/$iid/untag?repo=localhost:$REGISTRY_PORT/myrepo&tag=mytag" 201
@ -53,3 +55,5 @@ t GET libpod/images/$IMAGE/json 200 \
# Remove image # Remove image
t DELETE libpod/images/$IMAGE 200 \ t DELETE libpod/images/$IMAGE 200 \
.ExitCode=0 .ExitCode=0
stop_registry

View File

@ -27,10 +27,6 @@ RUN >file2
EOF EOF
) )
function cleanUpManifestTest() {
podman rmi -a
}
t POST /v3.4.0/libpod/manifests/$id_abc/add images="[\"containers-storage:$id_abc_image\"]" 200 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 PUT /v4.0.0/libpod/manifests/$id_xyz operation='update' images="[\"containers-storage:$id_xyz_image\"]" 200
@ -41,4 +37,5 @@ t POST "/v4.0.0/libpod/manifests/xyz:latest/registry/localhost:$REGISTRY_PORT%2F
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 podman rmi -a
stop_registry

View File

@ -45,16 +45,16 @@ t GET libpod/containers/json?all=true 200 \
.[0].IsInfra=false .[0].IsInfra=false
# Test compat API for Network Settings (.Network is N/A when rootless) # Test compat API for Network Settings (.Network is N/A when rootless)
network_expect= network_expect="Networks=null"
if root; then if root; then
network_expect='.[0].NetworkSettings.Networks.podman.NetworkID=podman' network_expect="Networks.podman.NetworkID=podman"
fi fi
t GET /containers/json?all=true 200 \ t GET /containers/json?all=true 200 \
length=1 \ length=1 \
.[0].Id~[0-9a-f]\\{64\\} \ .[0].Id~[0-9a-f]\\{64\\} \
.[0].Image=$IMAGE \ .[0].Image=$IMAGE \
.[0].Mounts~.*/tmp \ .[0].Mounts~.*/tmp \
$network_expect .[0].NetworkSettings.$network_expect
# compat API imageid with sha256: prefix # compat API imageid with sha256: prefix
t GET containers/json?limit=1 200 \ t GET containers/json?limit=1 200 \
@ -239,11 +239,15 @@ t GET containers/$cid/json 200 \
t POST containers/create Image=$IMAGE Entrypoint='["top"]' 201 \ t POST containers/create Image=$IMAGE Entrypoint='["top"]' 201 \
.Id~[0-9a-f]\\{64\\} .Id~[0-9a-f]\\{64\\}
cid_top=$(jq -r '.Id' <<<"$output") cid_top=$(jq -r '.Id' <<<"$output")
# Unexpected difference between /containers/json and /containers/CID/json:
# in rootless, the former returns .Networks=none, the latter .Networks={}
network_expect=${network_expect/=null/='{}'}
t GET containers/${cid_top}/json 200 \ t GET containers/${cid_top}/json 200 \
.Config.Entrypoint[0]="top" \ .Config.Entrypoint[0]="top" \
.Config.Cmd='[]' \ .Config.Cmd='[]' \
.Path="top" \ .Path="top" \
.NetworkSettings.Networks.podman.NetworkID=podman .NetworkSettings.$network_expect
t POST containers/${cid_top}/start 204 t POST containers/${cid_top}/start 204
# make sure the container is running # make sure the container is running
t GET containers/${cid_top}/json 200 \ t GET containers/${cid_top}/json 200 \
@ -374,8 +378,13 @@ t DELETE containers/$cid?v=true 204
t POST containers/create Image=$IMAGE HostConfig='{"NetworkMode":"default"}' 201 \ t POST containers/create Image=$IMAGE HostConfig='{"NetworkMode":"default"}' 201 \
.Id~[0-9a-f]\\{64\\} .Id~[0-9a-f]\\{64\\}
cid=$(jq -r '.Id' <<<"$output") cid=$(jq -r '.Id' <<<"$output")
if root; then
network_type=bridge
else
network_type=slirp4netns
fi
t GET containers/$cid/json 200 \ t GET containers/$cid/json 200 \
.HostConfig.NetworkMode="bridge" .HostConfig.NetworkMode="$network_type"
t DELETE containers/$cid?v=true 204 t DELETE containers/$cid?v=true 204

View File

@ -3,7 +3,7 @@
# registry-related tests # registry-related tests
# #
start_registry start_registry htpasswd
# Test unreachable # Test unreachable
t POST /v1.40/auth username=$REGISTRY_USERNAME password=WrOnGPassWord serveraddress=does.not.exist.io:1234/ \ 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 \ 200 \
.Status="Login Succeeded" \ .Status="Login Succeeded" \
.IdentityToken="" .IdentityToken=""
stop_registry

View File

@ -62,7 +62,7 @@ clean_up_server() {
podman rm -a podman rm -a
podman rmi -af podman rmi -af
stop_registry stop_registry --cleanup
stop_service stop_service
fi fi
} }
@ -242,7 +242,7 @@ 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
@ -273,10 +273,6 @@ function t() {
curl_args+=("--head") curl_args+=("--head")
fi fi
if [ -n "$REGISTRY_CONFIG_HEADER" ]; then
curl_args+=(-H "X-Registry-Config: $REGISTRY_CONFIG_HEADER")
fi
local expected_code=$1; shift local expected_code=$1; shift
# Log every action we do # Log every action we do
@ -384,11 +380,6 @@ function start_service() {
die "Cannot start service on non-localhost ($HOST)" die "Cannot start service on non-localhost ($HOST)"
fi 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 \ $PODMAN_BIN \
--root $WORKDIR/server_root --syslog=true \ --root $WORKDIR/server_root --syslog=true \
system service \ system service \
@ -414,18 +405,18 @@ 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 called multiple times, but each time should start a new
# let's assume that once started we only kill it at the end of tests. # registry container with (possibly) different configuration. That
# means that all callers must be responsible for invoking stop_registry.
if [[ -n "$REGISTRY_PORT" ]]; then if [[ -n "$REGISTRY_PORT" ]]; then
return die "start_registry invoked twice in succession, without stop_registry"
fi fi
# First arg is auth type (default: "none", but can also be "htpasswd")
local auth="${1:-none}"
REGISTRY_PORT=$(random_port) REGISTRY_PORT=$(random_port)
REGISTRY_USERNAME=u$(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
@ -439,22 +430,33 @@ function start_registry() {
podman ${PODMAN_REGISTRY_ARGS} pull $REGISTRY_IMAGE || podman ${PODMAN_REGISTRY_ARGS} pull $REGISTRY_IMAGE ||
podman ${PODMAN_REGISTRY_ARGS} pull $REGISTRY_IMAGE podman ${PODMAN_REGISTRY_ARGS} pull $REGISTRY_IMAGE
# Create a local cert and credentials # Create a local cert (no need to do this more than once)
# FIXME: is there a hidden "--quiet" flag? This is too noisy. if [[ ! -e $AUTHDIR/domain.key ]]; then
openssl req -newkey rsa:4096 -nodes -sha256 \ # FIXME: is there a hidden "--quiet" flag? This is too noisy.
-keyout $AUTHDIR/domain.key -x509 -days 2 \ openssl req -newkey rsa:4096 -nodes -sha256 \
-out $AUTHDIR/domain.crt \ -keyout $AUTHDIR/domain.key -x509 -days 2 \
-subj "/C=US/ST=Foo/L=Bar/O=Red Hat, Inc./CN=registry host certificate" \ -out $AUTHDIR/domain.crt \
-addext subjectAltName=DNS:localhost -subj "/C=US/ST=Foo/L=Bar/O=Red Hat, Inc./CN=registry host certificate" \
htpasswd -Bbn ${REGISTRY_USERNAME} ${REGISTRY_PASSWORD} \ -addext subjectAltName=DNS:localhost
> $AUTHDIR/htpasswd fi
# If invoked with auth=htpasswd, create credentials
REGISTRY_USERNAME=
REGISTRY_PASSWORD=
if [[ "$auth" = "htpasswd" ]]; then
REGISTRY_USERNAME=u$(random_string 7)
REGISTRY_PASSWORD=p$(random_string 7)
htpasswd -Bbn ${REGISTRY_USERNAME} ${REGISTRY_PASSWORD} \
> $AUTHDIR/htpasswd
fi
# Run the registry, and wait for it to come up # Run the registry, and wait for it to come up
podman ${PODMAN_REGISTRY_ARGS} run -d \ podman ${PODMAN_REGISTRY_ARGS} run -d \
-p ${REGISTRY_PORT}:5000 \ -p ${REGISTRY_PORT}:5000 \
--name registry \ --name registry \
-v $AUTHDIR:/auth:Z \ -v $AUTHDIR:/auth:Z \
-e "REGISTRY_AUTH=htpasswd" \ -e "REGISTRY_AUTH=$auth" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/auth/domain.crt \ -e REGISTRY_HTTP_TLS_CERTIFICATE=/auth/domain.crt \
@ -468,13 +470,19 @@ function stop_registry() {
local REGDIR=${WORKDIR}/registry local REGDIR=${WORKDIR}/registry
if [[ -d $REGDIR ]]; then if [[ -d $REGDIR ]]; then
local OPTS="--root ${REGDIR}/root --runroot ${REGDIR}/runroot" 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 # rm/rmi are important when running rootless: without them we
# get EPERMS in tmpdir cleanup because files are owned by subuids. # get EPERMS in tmpdir cleanup because files are owned by subuids.
podman $OPTS rm -f -a podman $OPTS rm -f -i registry
podman $OPTS rmi -f -a if [[ "$1" = "--cleanup" ]]; then
podman $OPTS rmi -f -a
fi
fi fi
REGISTRY_PORT=
REGISTRY_USERNAME=
REGISTRY_PASSWORD=
} }
################# #################