Migrate away from docker.io

CI and system tests currently pull some images from docker.io.
Eliminate that, by:

  - building a custom image containing much of what we need
    for testing; and
  - copying other needed images to quay.io

(Reason: effective 2020-11-01 docker.io will limit the
number of image pulls).

The principal change is to create a new quay.io/libpod/testimage,
using the new test/system/build-testimage script, instead of
relying on quay.io/libpod/alpine_labels. We also switch to
using a hardcoded :YYYYMMDD tag, instead of :latest, in an
attempt to futureproof our CI. This image includes 'httpd'
from busybox-extras, which we use in our networking test
(previously we had to pull and run busybox from docker.io).

The testimage can and should be extended as needed for future
tests, e.g. adding test file content or other useful tools.

For the '--pull' tests which require actually pulling from
the registry, I've created an image with the same name but
tagged :00000000 so it will never be pulled by default.
Since this image is only used minimally, it's just busybox.

Unfortunately there remain two cases we cannot solve in
this tiny alpine-based image:

  1) docker registry
  2) systemd

For those, I've (manually) run:

    podman pull [ docker.io/library/registry:2.7 | registry.fedoraproject.org/fedora:31 ]
    podman tag !$ quay.io/...
    podman push !$

...and amended the calling tests accordingly.

I've tried to make the the smallest reasonable diff, not the
smallest possible one. I hope it's a reasonable tradeoff.

Signed-off-by: Ed Santiago <santiago@redhat.com>
This commit is contained in:
Ed Santiago
2020-09-02 07:03:49 -06:00
parent be7778df6c
commit a9dbd2b3de
8 changed files with 111 additions and 53 deletions

View File

@ -14,6 +14,8 @@ load helpers
--format {{.ID}} | [0-9a-f]\\\{12\\\} --format {{.ID}} | [0-9a-f]\\\{12\\\}
--format {{.ID}} --no-trunc | sha256:[0-9a-f]\\\{64\\\} --format {{.ID}} --no-trunc | sha256:[0-9a-f]\\\{64\\\}
--format {{.Repository}}:{{.Tag}} | $PODMAN_TEST_IMAGE_FQN --format {{.Repository}}:{{.Tag}} | $PODMAN_TEST_IMAGE_FQN
--format {{.Labels.created_by}} | test/system/build-testimage
--format {{.Labels.created_at}} | 20[0-9-]\\\+T[0-9:]\\\+Z
" "
parse_table "$tests" | while read fmt expect; do parse_table "$tests" | while read fmt expect; do
@ -32,6 +34,8 @@ Id | [0-9a-f]\\\{64\\\}
Digest | sha256:[0-9a-f]\\\{64\\\} Digest | sha256:[0-9a-f]\\\{64\\\}
CreatedAt | [0-9-]\\\+T[0-9:.]\\\+Z CreatedAt | [0-9-]\\\+T[0-9:.]\\\+Z
Size | [0-9]\\\+ Size | [0-9]\\\+
Labels.created_by | test/system/build-testimage
Labels.created_at | 20[0-9-]\\\+T[0-9:]\\\+Z
" "
run_podman images -a --format json run_podman images -a --format json

View File

@ -134,24 +134,29 @@ echo $rand | 0 | $rand
run_podman run --pull=never $IMAGE true run_podman run --pull=never $IMAGE true
is "$output" "" "--pull=never [present]: no output" is "$output" "" "--pull=never [present]: no output"
# Now test with busybox, which we don't have present # Now test with a remote image which we don't have present (the 00 tag)
run_podman 125 run --pull=never busybox true NONLOCAL_IMAGE="$PODMAN_TEST_IMAGE_REGISTRY/$PODMAN_TEST_IMAGE_USER/$PODMAN_TEST_IMAGE_NAME:00000000"
is "$output" "Error: unable to find a name and tag match for busybox in repotags: no such image" "--pull=never [busybox/missing]: error"
run_podman run --pull=missing busybox true run_podman 125 run --pull=never $NONLOCAL_IMAGE true
is "$output" "Trying to pull .*" "--pull=missing [busybox/missing]: fetches" is "$output" "Error: unable to find a name and tag match for $NONLOCAL_IMAGE in repotags: no such image" "--pull=never [with image not present]: error"
run_podman run --pull=always busybox true run_podman run --pull=missing $NONLOCAL_IMAGE true
is "$output" "Trying to pull .*" "--pull=always [busybox/present]: fetches" is "$output" "Trying to pull .*" "--pull=missing [with image NOT PRESENT]: fetches"
run_podman run --pull=missing $NONLOCAL_IMAGE true
is "$output" "" "--pull=missing [with image PRESENT]: does not re-fetch"
run_podman run --pull=always $NONLOCAL_IMAGE true
is "$output" "Trying to pull .*" "--pull=always [with image PRESENT]: re-fetches"
run_podman rm -a run_podman rm -a
run_podman rmi busybox run_podman rmi $NONLOCAL_IMAGE
} }
# 'run --rmi' deletes the image in the end unless it's used by another container # 'run --rmi' deletes the image in the end unless it's used by another container
@test "podman run --rmi" { @test "podman run --rmi" {
# Name of a nonlocal image. It should be pulled in by the first 'run' # Name of a nonlocal image. It should be pulled in by the first 'run'
NONLOCAL_IMAGE=busybox NONLOCAL_IMAGE="$PODMAN_TEST_IMAGE_REGISTRY/$PODMAN_TEST_IMAGE_USER/$PODMAN_TEST_IMAGE_NAME:00000000"
run_podman 1 image exists $NONLOCAL_IMAGE run_podman 1 image exists $NONLOCAL_IMAGE
# Run a container, without --rm; this should block subsequent --rmi # Run a container, without --rm; this should block subsequent --rmi

View File

@ -22,9 +22,10 @@ load helpers
} }
@test "podman history - json" { @test "podman history - json" {
# Sigh. Timestamp in .created can be '...Z' or '...-06:00'
tests=" tests="
id | [0-9a-f]\\\{64\\\} id | [0-9a-f]\\\{64\\\}
created | [0-9-]\\\+T[0-9:.]\\\+Z created | [0-9-]\\\+T[0-9:.]\\\+[Z0-9:+-]\\\+
size | -\\\?[0-9]\\\+ size | -\\\?[0-9]\\\+
" "

View File

@ -56,14 +56,17 @@ function setup() {
AUTHDIR=${PODMAN_LOGIN_WORKDIR}/auth AUTHDIR=${PODMAN_LOGIN_WORKDIR}/auth
mkdir -p $AUTHDIR mkdir -p $AUTHDIR
# Registry image; copy of docker.io, but on our own registry
local REGISTRY_IMAGE="$PODMAN_TEST_IMAGE_REGISTRY/$PODMAN_TEST_IMAGE_USER/registry:2.7"
# Pull registry image, but into a separate container storage # Pull registry image, but into a separate container storage
mkdir -p ${PODMAN_LOGIN_WORKDIR}/root mkdir -p ${PODMAN_LOGIN_WORKDIR}/root
mkdir -p ${PODMAN_LOGIN_WORKDIR}/runroot mkdir -p ${PODMAN_LOGIN_WORKDIR}/runroot
PODMAN_LOGIN_ARGS="--root ${PODMAN_LOGIN_WORKDIR}/root --runroot ${PODMAN_LOGIN_WORKDIR}/runroot" PODMAN_LOGIN_ARGS="--root ${PODMAN_LOGIN_WORKDIR}/root --runroot ${PODMAN_LOGIN_WORKDIR}/runroot"
# Give it three tries, to compensate for flakes # Give it three tries, to compensate for flakes
run_podman ${PODMAN_LOGIN_ARGS} pull registry:2.6 || run_podman ${PODMAN_LOGIN_ARGS} pull $REGISTRY_IMAGE ||
run_podman ${PODMAN_LOGIN_ARGS} pull registry:2.6 || run_podman ${PODMAN_LOGIN_ARGS} pull $REGISTRY_IMAGE ||
run_podman ${PODMAN_LOGIN_ARGS} pull registry:2.6 run_podman ${PODMAN_LOGIN_ARGS} pull $REGISTRY_IMAGE
# Registry image needs a cert. Self-signed is good enough. # Registry image needs a cert. Self-signed is good enough.
CERT=$AUTHDIR/domain.crt CERT=$AUTHDIR/domain.crt
@ -76,9 +79,7 @@ function setup() {
# Store credentials where container will see them # Store credentials where container will see them
if [ ! -e $AUTHDIR/htpasswd ]; then if [ ! -e $AUTHDIR/htpasswd ]; then
run_podman ${PODMAN_LOGIN_ARGS} run --rm \ htpasswd -Bbn ${PODMAN_LOGIN_USER} ${PODMAN_LOGIN_PASS} \
--entrypoint htpasswd registry:2.6 \
-Bbn ${PODMAN_LOGIN_USER} ${PODMAN_LOGIN_PASS} \
> $AUTHDIR/htpasswd > $AUTHDIR/htpasswd
# In case $PODMAN_TEST_KEEP_LOGIN_REGISTRY is set, for testing later # In case $PODMAN_TEST_KEEP_LOGIN_REGISTRY is set, for testing later
@ -97,7 +98,7 @@ function setup() {
-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 \
-e REGISTRY_HTTP_TLS_KEY=/auth/domain.key \ -e REGISTRY_HTTP_TLS_KEY=/auth/domain.key \
registry:2.6 $REGISTRY_IMAGE
} }
# END first "test" - start a registry for use by other tests # END first "test" - start a registry for use by other tests
@ -189,38 +190,26 @@ EOF
} }
@test "podman push ok" { @test "podman push ok" {
# ARGH! We can't push $IMAGE (alpine_labels) to this registry; error is: # Preserve image ID for later comparison against push/pulled image
# run_podman inspect --format '{{.Id}}' $IMAGE
# Writing manifest to image destination iid=$output
# Error: Error copying image to the remote destination: Error writing manifest: Error uploading manifest latest to localhost:${PODMAN_LOGIN_REGISTRY_PORT}/okpush: received unexpected HTTP status: 500 Internal Server Error
#
# Root cause: something to do with v1/v2 s1/s2:
#
# https://github.com/containers/skopeo/issues/651
#
run_podman pull busybox
# Preserve its ID for later comparison against push/pulled image
run_podman inspect --format '{{.Id}}' busybox
id_busybox=$output
destname=ok-$(random_string 10 | tr A-Z a-z)-ok destname=ok-$(random_string 10 | tr A-Z a-z)-ok
# Use command-line credentials # Use command-line credentials
run_podman push --tls-verify=false \ run_podman push --tls-verify=false \
--creds ${PODMAN_LOGIN_USER}:${PODMAN_LOGIN_PASS} \ --creds ${PODMAN_LOGIN_USER}:${PODMAN_LOGIN_PASS} \
busybox localhost:${PODMAN_LOGIN_REGISTRY_PORT}/$destname $IMAGE localhost:${PODMAN_LOGIN_REGISTRY_PORT}/$destname
# Yay! Pull it back # Yay! Pull it back
run_podman pull --tls-verify=false \ run_podman pull --tls-verify=false \
--creds ${PODMAN_LOGIN_USER}:${PODMAN_LOGIN_PASS} \ --creds ${PODMAN_LOGIN_USER}:${PODMAN_LOGIN_PASS} \
localhost:${PODMAN_LOGIN_REGISTRY_PORT}/$destname localhost:${PODMAN_LOGIN_REGISTRY_PORT}/$destname
# Compare to original busybox # Compare to original image
run_podman inspect --format '{{.Id}}' $destname run_podman inspect --format '{{.Id}}' $destname
is "$output" "$id_busybox" "Image ID of pulled image == busybox" is "$output" "$iid" "Image ID of pulled image == original IID"
run_podman rmi busybox $destname run_podman rmi $destname
} }
# END primary podman login/push/pull tests # END primary podman login/push/pull tests

View File

@ -115,9 +115,10 @@ function _assert_mainpid_is_conmon() {
@test "sdnotify : container" { @test "sdnotify : container" {
# Sigh... we need to pull a humongous image because it has systemd-notify. # Sigh... we need to pull a humongous image because it has systemd-notify.
# (IMPORTANT: fedora:32 and above silently removed systemd-notify; this
# caused CI to hang. That's why we explicitly require fedora:31)
# FIXME: is there a smaller image we could use? # FIXME: is there a smaller image we could use?
_FEDORA=registry.fedoraproject.org/fedora:31 local _FEDORA="$PODMAN_TEST_IMAGE_REGISTRY/$PODMAN_TEST_IMAGE_USER/fedora:31"
# Pull that image. Retry in case of flakes. # Pull that image. Retry in case of flakes.
run_podman pull $_FEDORA || \ run_podman pull $_FEDORA || \
run_podman pull $_FEDORA || \ run_podman pull $_FEDORA || \

View File

@ -12,7 +12,7 @@ load helpers
random_2=$(random_string 30) random_2=$(random_string 30)
HOST_PORT=8080 HOST_PORT=8080
SERVER=http://localhost:$HOST_PORT SERVER=http://127.0.0.1:$HOST_PORT
# Create a test file with random content # Create a test file with random content
INDEX1=$PODMAN_TMPDIR/hello.txt INDEX1=$PODMAN_TMPDIR/hello.txt
@ -22,7 +22,7 @@ load helpers
run_podman run -d --name myweb -p "$HOST_PORT:80" \ run_podman run -d --name myweb -p "$HOST_PORT:80" \
-v $INDEX1:/var/www/index.txt \ -v $INDEX1:/var/www/index.txt \
-w /var/www \ -w /var/www \
busybox httpd -f -p 80 $IMAGE /bin/busybox-extras httpd -f -p 80
cid=$output cid=$output
# In that container, create a second file, using exec and redirection # In that container, create a second file, using exec and redirection
@ -33,14 +33,14 @@ load helpers
# Verify http contents: curl from localhost # Verify http contents: curl from localhost
run curl -s $SERVER/index.txt run curl -s $SERVER/index.txt
is "$output" "$random_1" "curl localhost:/index.txt" is "$output" "$random_1" "curl 127.0.0.1:/index.txt"
run curl -s $SERVER/index2.txt run curl -s $SERVER/index2.txt
is "$output" "$random_2" "curl localhost:/index2.txt" is "$output" "$random_2" "curl 127.0.0.1:/index2.txt"
# Verify http contents: wget from a second container # Verify http contents: wget from a second container
run_podman run --rm --net=host busybox wget -qO - $SERVER/index.txt run_podman run --rm --net=host $IMAGE wget -qO - $SERVER/index.txt
is "$output" "$random_1" "podman wget /index.txt" is "$output" "$random_1" "podman wget /index.txt"
run_podman run --rm --net=host busybox wget -qO - $SERVER/index2.txt run_podman run --rm --net=host $IMAGE wget -qO - $SERVER/index2.txt
is "$output" "$random_2" "podman wget /index2.txt" is "$output" "$random_2" "podman wget /index2.txt"
# Tests #4889 - two-argument form of "podman ports" was broken # Tests #4889 - two-argument form of "podman ports" was broken
@ -57,7 +57,6 @@ load helpers
# Clean up # Clean up
run_podman stop -t 1 myweb run_podman stop -t 1 myweb
run_podman rm myweb run_podman rm myweb
run_podman rmi busybox
} }
# Issue #5466 - port-forwarding doesn't work with this option and -d # Issue #5466 - port-forwarding doesn't work with this option and -d

59
test/system/build-testimage Executable file
View File

@ -0,0 +1,59 @@
#!/bin/bash
#
# build-testimage - script for producing a test image for podman CI
#
# The idea is to have a small multi-purpose image that can be pulled once
# by system tests and used for as many tests as possible. This image
# should live on quay.io, should be small in size, and should include
# as many components as needed by system tests so they don't have to
# pull other images.
#
# Unfortunately, "small" is incompatible with "systemd" so tests
# still need a fedora image for that.
#
# Tag for this new image
YMD=$(date +%Y%m%d)
# git-relative path to this script
create_script=$(cd $(dirname $0) && git ls-files --full-name $(basename $0))
if [ -z "$create_script" ]; then
create_script=$0
fi
# Creation timestamp, Zulu time
create_time_z=$(env TZ=UTC date +'%Y-%m-%dT%H:%M:%SZ')
set -ex
# Please document the reason for all flags, apk's, and anything non-obvious
#
# --squash-all : needed by 'tree' test in 070-build.bats
# busybox-extras : provides httpd needed in 500-networking.bats
#
podman rmi -f testimage &> /dev/null || true
podman build --squash-all -t testimage - <<EOF
FROM docker.io/library/alpine:3.12.0
RUN apk add busybox-extras
LABEL created_by=$create_script
LABEL created_at=$create_time_z
CMD ["/bin/echo", "This container is intended for podman CI testing"]
EOF
# Tag and push to quay.
podman tag testimage quay.io/edsantiago/testimage:$YMD
podman push quay.io/edsantiago/testimage:$YMD
# Side note: there should always be a testimage tagged ':00000000'
# (eight zeroes) in the same location; this is used by tests which
# need to pull a non-locally-cached image. This image will rarely
# if ever need to change, nor in fact does it even have to be a
# copy of this testimage since all we use it for is 'true'.
#
# As of 2020-09-02 it is simply busybox, because it is super small:
#
# podman pull docker.io/library/busybox:1.32.0
# podman tag docker.io/library/busybox:1.32.0 \
# quay.io/edsantiago/testimage:00000000
# podman push quay.io/edsantiago/testimage:00000000
#

View File

@ -6,8 +6,8 @@ PODMAN=${PODMAN:-podman}
# Standard image to use for most tests # Standard image to use for most tests
PODMAN_TEST_IMAGE_REGISTRY=${PODMAN_TEST_IMAGE_REGISTRY:-"quay.io"} PODMAN_TEST_IMAGE_REGISTRY=${PODMAN_TEST_IMAGE_REGISTRY:-"quay.io"}
PODMAN_TEST_IMAGE_USER=${PODMAN_TEST_IMAGE_USER:-"libpod"} PODMAN_TEST_IMAGE_USER=${PODMAN_TEST_IMAGE_USER:-"libpod"}
PODMAN_TEST_IMAGE_NAME=${PODMAN_TEST_IMAGE_NAME:-"alpine_labels"} PODMAN_TEST_IMAGE_NAME=${PODMAN_TEST_IMAGE_NAME:-"testimage"}
PODMAN_TEST_IMAGE_TAG=${PODMAN_TEST_IMAGE_TAG:-"latest"} PODMAN_TEST_IMAGE_TAG=${PODMAN_TEST_IMAGE_TAG:-"20200902"}
PODMAN_TEST_IMAGE_FQN="$PODMAN_TEST_IMAGE_REGISTRY/$PODMAN_TEST_IMAGE_USER/$PODMAN_TEST_IMAGE_NAME:$PODMAN_TEST_IMAGE_TAG" PODMAN_TEST_IMAGE_FQN="$PODMAN_TEST_IMAGE_REGISTRY/$PODMAN_TEST_IMAGE_USER/$PODMAN_TEST_IMAGE_NAME:$PODMAN_TEST_IMAGE_TAG"
# Because who wants to spell that out each time? # Because who wants to spell that out each time?