test_container: Add non-layered demo test image
Often our tests are based on kuryr/demo. That image used to be based on python and alpine and was taking a very long time to pull for already slow tests. This change makes this repository have the authoritative version of the kuryr/demo build. The way it is built is just by running mkrootfs.sh. But that only needs to be run if we change the version of curl or modify server.go. Otherwise, to run test it just needs: docker build -t kuryr/demo . -f Dockerfile This build will not need to go to Docker Hub for anything so we also eliminate one source of flakiness. Depends-On: https://review.openstack.org/#/c/547390/ Change-Id: Iab5799e22c3b353a4f2adbaa280ab4a9904ecd95 Signed-off-by: Antoni Segura Puimedon <antonisp@celebdor.com>
This commit is contained in:
parent
10a741ec62
commit
c7ebfeadc6
devstack
kuryr_tempest_plugin/tests/scenario
test_container
@ -1,9 +1,18 @@
|
||||
# install tempest plugin
|
||||
function build_test_container {
|
||||
pushd "${DEST}/kuryr-tempest-plugin/test_container"
|
||||
|
||||
docker build -t kuryr/demo . -f Dockerfile
|
||||
popd
|
||||
}
|
||||
|
||||
function install_kuryr_tempest_plugin {
|
||||
setup_dev_lib "kuryr-tempest-plugin"
|
||||
}
|
||||
|
||||
if [[ "$1" == "stack" && "$2" == "install" ]]; then
|
||||
echo_summary "Building kuryr/demo test container"
|
||||
build_test_container
|
||||
echo_summary "Installing Kuryr Tempest Plugin"
|
||||
install_kuryr_tempest_plugin
|
||||
fi
|
||||
|
@ -52,7 +52,7 @@ class BaseKuryrScenarioTest(manager.NetworkScenarioTest):
|
||||
cls.os_admin.floating_ips_client.delete_floatingip(
|
||||
fip['floatingip']['id'])
|
||||
|
||||
def create_pod(self, name=None, image='celebdor/kuryr-demo',
|
||||
def create_pod(self, name=None, image='kuryr/demo',
|
||||
namespace="default"):
|
||||
name = data_utils.rand_name(prefix='kuryr-pod')
|
||||
pod = self.k8s_client.V1Pod()
|
||||
|
9
test_container/Dockerfile
Normal file
9
test_container/Dockerfile
Normal file
@ -0,0 +1,9 @@
|
||||
FROM scratch
|
||||
ADD rootfs.tar.xz /
|
||||
RUN adduser -S kuryr
|
||||
|
||||
USER kuryr
|
||||
WORKDIR /home/kuryr
|
||||
|
||||
EXPOSE 8080
|
||||
CMD ["/usr/bin/helloserver"]
|
172
test_container/Dockerfile.builder
Normal file
172
test_container/Dockerfile.builder
Normal file
@ -0,0 +1,172 @@
|
||||
FROM alpine:3.7
|
||||
|
||||
RUN apk add --no-cache \
|
||||
bash \
|
||||
bzip2 \
|
||||
coreutils \
|
||||
curl \
|
||||
gcc \
|
||||
go \
|
||||
linux-headers \
|
||||
make \
|
||||
musl-dev \
|
||||
perl \
|
||||
tzdata \
|
||||
\
|
||||
# explicitly using gnupg1 instead of gnupg (which is 2.x) due to an arm32v6 bug (likely related to our arm64v8 hardware)
|
||||
# SIGILL {si_signo=SIGILL, si_code=ILL_ILLOPC, si_addr=0xf7b79394} ---
|
||||
# (in dirmngr)
|
||||
gnupg1
|
||||
|
||||
# pub 1024D/ACC9965B 2006-12-12
|
||||
# Key fingerprint = C9E9 416F 76E6 10DB D09D 040F 47B7 0C55 ACC9 965B
|
||||
# uid Denis Vlasenko <vda.linux@googlemail.com>
|
||||
# sub 1024g/2C766641 2006-12-12
|
||||
RUN gpg --keyserver ha.pool.sks-keyservers.net --recv-keys C9E9416F76E610DBD09D040F47B70C55ACC9965B
|
||||
|
||||
ENV BUSYBOX_VERSION 1.28.0
|
||||
|
||||
RUN set -ex; \
|
||||
tarball="busybox-${BUSYBOX_VERSION}.tar.bz2"; \
|
||||
curl -fL -o busybox.tar.bz2 "https://busybox.net/downloads/$tarball"; \
|
||||
curl -fL -o busybox.tar.bz2.sign "https://busybox.net/downloads/$tarball.sign"; \
|
||||
gpg --batch --decrypt --output busybox.tar.bz2.txt busybox.tar.bz2.sign; \
|
||||
awk '$1 == "SHA1:" && $2 ~ /^[0-9a-f]+$/ && $3 == "'"$tarball"'" { print $2, "*busybox.tar.bz2" }' busybox.tar.bz2.txt > busybox.tar.bz2.sha1; \
|
||||
test -s busybox.tar.bz2.sha1; \
|
||||
sha1sum -c busybox.tar.bz2.sha1; \
|
||||
mkdir -p /usr/src/busybox; \
|
||||
tar -xf busybox.tar.bz2 -C /usr/src/busybox --strip-components 1; \
|
||||
rm busybox.tar.bz2*
|
||||
|
||||
WORKDIR /usr/src/busybox
|
||||
|
||||
# https://www.mail-archive.com/toybox@lists.landley.net/msg02528.html
|
||||
# https://www.mail-archive.com/toybox@lists.landley.net/msg02526.html
|
||||
RUN sed -i 's/^struct kconf_id \*$/static &/g' scripts/kconfig/zconf.hash.c_shipped
|
||||
|
||||
# CONFIG_LAST_SUPPORTED_WCHAR: see https://github.com/docker-library/busybox/issues/13 (UTF-8 input)
|
||||
# see http://wiki.musl-libc.org/wiki/Building_Busybox
|
||||
RUN set -ex; \
|
||||
\
|
||||
setConfs=' \
|
||||
CONFIG_FEATURE_SUID=y \
|
||||
CONFIG_AR=y \
|
||||
CONFIG_FEATURE_AR_CREATE=y \
|
||||
CONFIG_FEATURE_AR_LONG_FILENAMES=y \
|
||||
CONFIG_LAST_SUPPORTED_WCHAR=0 \
|
||||
CONFIG_STATIC=y \
|
||||
'; \
|
||||
\
|
||||
unsetConfs=' \
|
||||
CONFIG_FEATURE_SYNC_FANCY \
|
||||
\
|
||||
CONFIG_FEATURE_HAVE_RPC \
|
||||
CONFIG_FEATURE_INETD_RPC \
|
||||
CONFIG_FEATURE_UTMP \
|
||||
CONFIG_FEATURE_WTMP \
|
||||
'; \
|
||||
\
|
||||
make defconfig; \
|
||||
\
|
||||
for conf in $unsetConfs; do \
|
||||
sed -i \
|
||||
-e "s!^$conf=.*\$!# $conf is not set!" \
|
||||
.config; \
|
||||
done; \
|
||||
\
|
||||
for confV in $setConfs; do \
|
||||
conf="${confV%=*}"; \
|
||||
sed -i \
|
||||
-e "s!^$conf=.*\$!$confV!" \
|
||||
-e "s!^# $conf is not set\$!$confV!" \
|
||||
.config; \
|
||||
if ! grep -q "^$confV\$" .config; then \
|
||||
echo "$confV" >> .config; \
|
||||
fi; \
|
||||
done; \
|
||||
\
|
||||
make oldconfig; \
|
||||
\
|
||||
# trust, but verify
|
||||
for conf in $unsetConfs; do \
|
||||
! grep -q "^$conf=" .config; \
|
||||
done; \
|
||||
for confV in $setConfs; do \
|
||||
grep -q "^$confV\$" .config; \
|
||||
done;
|
||||
|
||||
RUN set -ex \
|
||||
&& make -j "$(nproc)" \
|
||||
busybox \
|
||||
&& ./busybox --help \
|
||||
&& mkdir -p rootfs/bin \
|
||||
&& ln -vL busybox rootfs/bin/ \
|
||||
&& chroot rootfs /bin/busybox --install /bin
|
||||
|
||||
# grab a simplified getconf port from Alpine we can statically compile
|
||||
RUN set -x \
|
||||
&& aportsVersion="v$(cat /etc/alpine-release)" \
|
||||
&& curl -fsSL \
|
||||
"http://git.alpinelinux.org/cgit/aports/plain/main/musl/getconf.c?h=${aportsVersion}" \
|
||||
-o /usr/src/getconf.c \
|
||||
&& gcc -o rootfs/bin/getconf -static -Os /usr/src/getconf.c \
|
||||
&& chroot rootfs /bin/getconf _NPROCESSORS_ONLN
|
||||
|
||||
# download a few extra files from buildroot (/etc/passwd, etc)
|
||||
RUN set -ex; \
|
||||
buildrootVersion='2017.11.1'; \
|
||||
mkdir -p rootfs/etc; \
|
||||
for f in passwd shadow group; do \
|
||||
curl -fL -o "rootfs/etc/$f" "https://git.busybox.net/buildroot/plain/system/skeleton/etc/$f?id=$buildrootVersion"; \
|
||||
done; \
|
||||
# set expected permissions, etc too (https://git.busybox.net/buildroot/tree/system/device_table.txt)
|
||||
curl -fL -o buildroot-device-table.txt "https://git.busybox.net/buildroot/plain/system/device_table.txt?id=$buildrootVersion"; \
|
||||
awk ' \
|
||||
!/^#/ { \
|
||||
if ($2 != "d" && $2 != "f") { \
|
||||
printf "error: unknown type \"%s\" encountered in line %d: %s\n", $2, NR, $0 > "/dev/stderr"; \
|
||||
exit 1; \
|
||||
} \
|
||||
sub(/^\/?/, "rootfs/", $1); \
|
||||
if ($2 == "d") { \
|
||||
printf "mkdir -p %s\n", $1; \
|
||||
} \
|
||||
printf "chmod %s %s\n", $3, $1; \
|
||||
} \
|
||||
' buildroot-device-table.txt | sh -eux; \
|
||||
rm buildroot-device-table.txt
|
||||
|
||||
# create missing home directories
|
||||
RUN set -ex \
|
||||
&& cd rootfs \
|
||||
&& for userHome in $(awk -F ':' '{ print $3 ":" $4 "=" $6 }' etc/passwd); do \
|
||||
user="${userHome%%=*}"; \
|
||||
home="${userHome#*=}"; \
|
||||
home="./${home#/}"; \
|
||||
if [ ! -d "$home" ]; then \
|
||||
mkdir -p "$home"; \
|
||||
chown "$user" "$home"; \
|
||||
chmod 755 "$home"; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
# test and make sure it works
|
||||
RUN chroot rootfs /bin/sh -xec 'true'
|
||||
|
||||
# ensure correct timezone (UTC)
|
||||
RUN set -ex; \
|
||||
ln -vL /usr/share/zoneinfo/UTC rootfs/etc/localtime; \
|
||||
[ "$(chroot rootfs date +%Z)" = 'UTC' ]
|
||||
|
||||
# test and make sure DNS works too
|
||||
RUN cp -L /etc/resolv.conf rootfs/etc/ \
|
||||
&& chroot rootfs /bin/sh -xec 'nslookup google.com' \
|
||||
&& rm rootfs/etc/resolv.conf
|
||||
|
||||
ADD ./curl_builder.sh .
|
||||
RUN mkdir -p rootfs/usr/bin; \
|
||||
./curl_builder.sh; \
|
||||
cp /usr/local/bin/curl rootfs/usr/bin/curl
|
||||
|
||||
ADD ./server.go .
|
||||
RUN go build -ldflags "-linkmode external -extldflags -static" -o rootfs/usr/bin/helloserver server.go
|
66
test_container/README.rst
Normal file
66
test_container/README.rst
Normal file
@ -0,0 +1,66 @@
|
||||
======================================
|
||||
Kuryr Testing container infrastructure
|
||||
======================================
|
||||
|
||||
This directory is the official source for building Docker hub's kuryr/demo
|
||||
images.
|
||||
|
||||
The build consists on two parts:
|
||||
|
||||
Builder container
|
||||
-----------------
|
||||
|
||||
The builder container is based on the musl compiled Alpine distribution. In the
|
||||
process of building the image, it downloads and compiles:
|
||||
|
||||
* busybox
|
||||
* musl
|
||||
* curl and its dependencies
|
||||
|
||||
It also includes golang so that we can use it in our test web server:
|
||||
|
||||
* server.go
|
||||
|
||||
Everything that is to be included in the kuryr/demo image is put in::
|
||||
|
||||
/usr/src/busybox/rootfs
|
||||
|
||||
The reason for this is that this build is based on Docker's busybox build
|
||||
system and the rootfs won't have any library, so all you want to add must be
|
||||
statically compiled there.
|
||||
|
||||
kuryr/demo container
|
||||
--------------------
|
||||
|
||||
This is the actual container used in the tests. It includes:
|
||||
|
||||
* Busybox: It gives us a very lightweight userspace that provides things like
|
||||
the ip command, vi, etc.
|
||||
* curl: Useful for testing HTTP/HTTPS connectivity to the API and other
|
||||
services.
|
||||
* helloserver: An HTTP server that binds to 8080 and prints out a message
|
||||
that includes the hostname, so it can be used to see which pod replies to a
|
||||
service request.
|
||||
|
||||
When and how to build
|
||||
---------------------
|
||||
|
||||
builder container + kuryr/demo
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You should only need to build the whole set if you want to change the library
|
||||
app version of something in kuryr/demo or add another tool like bind9 dig.
|
||||
|
||||
The way to do this is::
|
||||
|
||||
sudo ./mkrootfs.sh
|
||||
|
||||
|
||||
kuryr/demo
|
||||
~~~~~~~~~~
|
||||
|
||||
Everytime you want to run the tests, you should build the kuryr/demo container
|
||||
locally to avoid pulls from dockerhub to make sure you run the latest
|
||||
authoritative version.
|
||||
|
||||
Note that the kuryr-tempest-plugin devstack will build it for you.
|
117
test_container/curl_builder.sh
Executable file
117
test_container/curl_builder.sh
Executable file
@ -0,0 +1,117 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Names of latest versions of each package
|
||||
export VERSION_MUSL=musl-1.1.18
|
||||
export VERSION_ZLIB=zlib-1.2.11
|
||||
export VERSION_LIBRESSL=libressl-2.6.3
|
||||
export VERSION_CURL=curl-7.58.0
|
||||
|
||||
# URLs to the source directories
|
||||
export SOURCE_MUSL=http://www.musl-libc.org/releases/
|
||||
export SOURCE_LIBRESSL=http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/
|
||||
export SOURCE_CURL=https://curl.haxx.se/download/
|
||||
export SOURCE_ZLIB=http://zlib.net/
|
||||
|
||||
# Path to local build
|
||||
export BUILD_DIR=/tmp/curl-static-libressl/build
|
||||
# Path for libressl
|
||||
export STATICLIBSSL="${BUILD_DIR}/${VERSION_LIBRESSL}"
|
||||
|
||||
function setup() {
|
||||
# create and clean build directory
|
||||
mkdir -p ${BUILD_DIR}
|
||||
rm -Rf ${BUILD_DIR}/*
|
||||
# install build environment tools
|
||||
apk add linux-headers perl
|
||||
}
|
||||
|
||||
function download_sources() {
|
||||
# todo: verify checksum / integrity of downloads!
|
||||
echo "Download sources"
|
||||
|
||||
pushd ${BUILD_DIR}
|
||||
|
||||
curl -sSLO "${SOURCE_MUSL}${VERSION_MUSL}.tar.gz"
|
||||
curl -sSLO "${SOURCE_ZLIB}${VERSION_ZLIB}.tar.gz"
|
||||
curl -sSLO "${SOURCE_LIBRESSL}${VERSION_LIBRESSL}.tar.gz"
|
||||
curl -sSLO "${SOURCE_CURL}${VERSION_CURL}.tar.gz"
|
||||
|
||||
popd
|
||||
}
|
||||
|
||||
function extract_sources() {
|
||||
echo "Extracting sources"
|
||||
|
||||
pushd ${BUILD_DIR}
|
||||
|
||||
tar -xf "${VERSION_MUSL}.tar.gz"
|
||||
tar -xf "${VERSION_LIBRESSL}.tar.gz"
|
||||
tar -xf "${VERSION_CURL}.tar.gz"
|
||||
tar -xf "${VERSION_ZLIB}.tar.gz"
|
||||
|
||||
popd
|
||||
}
|
||||
|
||||
function compile_musl() {
|
||||
echo "Configure & build static musl"
|
||||
|
||||
pushd "${BUILD_DIR}/${VERSION_MUSL}"
|
||||
|
||||
make clean
|
||||
./configure --prefix=/usr/local --disable-shared
|
||||
make -j4
|
||||
make install
|
||||
}
|
||||
|
||||
function compile_zlib() {
|
||||
echo "Configure & build static zlib"
|
||||
|
||||
pushd "${BUILD_DIR}/${VERSION_ZLIB}"
|
||||
|
||||
make clean
|
||||
./configure --static --prefix=/usr/local
|
||||
make -j4
|
||||
make install
|
||||
}
|
||||
|
||||
function compile_libressl() {
|
||||
echo "Configure & build static libressl"
|
||||
|
||||
pushd "${BUILD_DIR}/${VERSION_LIBRESSL}"
|
||||
|
||||
make clean
|
||||
./configure --prefix=/usr/local --enable-shared=no
|
||||
make -j4
|
||||
make install
|
||||
}
|
||||
|
||||
function compile_curl() {
|
||||
echo "Configure & Build curl"
|
||||
|
||||
pushd "${BUILD_DIR}/${VERSION_CURL}"
|
||||
|
||||
make clean
|
||||
|
||||
LIBS="-ldl -lpthread" LDFLAGS="-static" CFLAGS="-no-pie" PKG_CONFIG_FLAGS="--static" PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/ ./configure --disable-shared --enable-static
|
||||
|
||||
make -j4
|
||||
make install
|
||||
|
||||
popd
|
||||
}
|
||||
|
||||
echo "Building ${VERSION_CURL} with static ${VERSION_LIBRESSL}, and ${VERSION_ZLIB} ..."
|
||||
|
||||
setup && download_sources && extract_sources && compile_musl && compile_zlib && compile_libressl && compile_curl
|
||||
|
||||
retval=$?
|
||||
echo ""
|
||||
if [ $retval -eq 0 ]; then
|
||||
echo "Your curl binary is located at ${BUILD_DIR}/${VERSION_CURL}/src/curl."
|
||||
echo "Listing dynamically linked libraries ..."
|
||||
ldd ${BUILD_DIR}/${VERSION_CURL}/src/curl
|
||||
echo ""
|
||||
${BUILD_DIR}/${VERSION_CURL}/src/curl --version
|
||||
else
|
||||
echo "Ooops, build failed. Check output!"
|
||||
fi
|
13
test_container/mkrootfs.sh
Executable file
13
test_container/mkrootfs.sh
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
BUILDER_NAME=$(uuidgen)
|
||||
docker build -t kuryr/demo_builder . -f Dockerfile.builder
|
||||
docker run --name ${BUILDER_NAME} kuryr/demo_builder
|
||||
docker cp ${BUILDER_NAME}:/usr/src/busybox/rootfs rootfs
|
||||
docker rm ${BUILDER_NAME}
|
||||
|
||||
# In order for ping and traceroute to work, we need to give suid to busybox
|
||||
chmod +s rootfs/bin/busybox
|
||||
tar -J -f rootfs.tar.xz --numeric-owner --exclude='dev/*' -C rootfs -c .
|
||||
rm -fr rootfs
|
||||
docker build -t kuryr/demo . -f Dockerfile
|
BIN
test_container/rootfs.tar.xz
Normal file
BIN
test_container/rootfs.tar.xz
Normal file
Binary file not shown.
21
test_container/server.go
Normal file
21
test_container/server.go
Normal file
@ -0,0 +1,21 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
func handler(w http.ResponseWriter, r *http.Request) {
|
||||
hostname, err := os.Hostname()
|
||||
log.Println("Received request")
|
||||
if err == nil {
|
||||
fmt.Fprintf(w, "%s: HELLO! I AM ALIVE!!!\n", hostname)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/", handler)
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user