diff --git a/docker.spec b/docker.spec index 6924cfe..b305c57 100644 --- a/docker.spec +++ b/docker.spec @@ -217,11 +217,15 @@ Zsh command line completion support for %{name}. %package test %global __requires_exclude ^libgo.so.*$ Summary: Test package for docker +Group: System/Management +Requires: curl +Requires: go +Requires: iputils +Requires: jq # KUBIC-SPECIFIC: This was required when upgrading from the original kubic # packaging, when everything was renamed to -kubic. It also is # used to ensure that nothing complains too much when using # -kubic packages. Hopfully it can be removed one day. -Group: System/Management %if "%flavour" == "kubic" # Obsolete old packege without the -kubic suffix Obsoletes: %{realname}-test = 1.12.6 @@ -373,11 +377,6 @@ install -D -m0755 %{SOURCE9} %{buildroot}%{_prefix}/src/docker/tests.sh cp -a components/engine/{hack,contrib,integration{,-cli}} %{buildroot}%{_prefix}/src/docker/ echo "%{version}" > %{buildroot}%{_prefix}/src/docker/VERSION -find %{buildroot}%{_prefix}/src/docker/ \ - \( -type f -name '*_test.go' \) -delete -find %{buildroot}%{_prefix}/src/docker/ \ - \( -type d -empty \) -delete - # # systemd service # diff --git a/tests.sh b/tests.sh index 01279d5..858b9ad 100644 --- a/tests.sh +++ b/tests.sh @@ -4,132 +4,125 @@ # XXX: We currently only support running integration-cli. # -set -Eeuxo pipefail +set -Eeuo pipefail DOCKER_DIR=/usr/src/docker -SCRIPTS_DIR=$DOCKER_DIR/hack -TESTS_EXE=$DOCKER_DIR/integration-cli/tests.main -VERSION=$(cat $DOCKER_DIR/VERSION) +SCRIPTS_DIR="$DOCKER_DIR/hack" +TESTS_EXE="$DOCKER_DIR/integration-cli/tests.main" +VERSION="$(cat "$DOCKER_DIR/VERSION")" # working dirs TESTS_DIR=/tmp/docker-int-tests -BUNDLES_DIR=$TESTS_DIR/run/bundles -FAKE_GOPATH=$TESTS_DIR/go +FROZEN_IMAGES=/docker-frozen-images +BUNDLES_DIR="$TESTS_DIR/run/bundles" CHECK_TIMEOUT="${CHECK_TIMEOUT:-5m}" TEST_TIMEOUT="${TEST_TIMEOUT:-60m}" -TEST_ARGS="-check.vv -check.timeout=${CHECK_TIMEOUT} -test.timeout=${TEST_TIMEOUT}" +TEST_ARGS=("-check.v" "-check.timeout=${CHECK_TIMEOUT}" "-test.timeout=${TEST_TIMEOUT}") TEST_SELECT= TEST_LOG=/tmp/docker-tests.log -ENABLE_XUNIT="${ENABLE_XUNIT:=yes}" +ENABLE_XUNIT="${ENABLE_XUNIT-yes}" +KEEPBUNDLE="${KEEPBUNDLE:-}" # the config file for Docker CFG_DOCKER=/etc/docker/daemon.json ################################################################################ -log() { echo ">>> $@" ; } -warn() { log "WARNING: $@" ; } -error() { log "ERROR: $@" ; } -abort() { log "FATAL: $@" ; exit 1 ; } -usage() { echo "$USAGE" ; } -abort_usage() { usage ; abort $@ ; } +log() { echo ">>> $@" ; } +warn() { log "WARNING: $@" ; } +error() { log "ERROR: $@" ; } +abort() { log "FATAL: $@" ; exit 1 ; } +usage() { echo "$USAGE" ; } +abort_usage() { usage ; abort "$@" ; } bundle() { - local bundle="$1"; shift - log "Making bundle: $(basename "$bundle") (in $DEST)" - source "$SCRIPTS_DIR/make/$bundle" "$@" + local bundle="$1"; shift + log "Making bundle: $(basename "$bundle") (in $DEST)" + local oldFlags="$-" + set +Eeu + source "$SCRIPTS_DIR/make/$bundle" "$@" + set "-$oldFlags" } -set_opts() { - OPT="$1" - VALUE="$2" - FILE=$3 - - perl -pi -e "s/^$OPT=.*$//g" $FILE - echo "$OPT=\"$VALUE\"" >> $FILE -} - -set_docker_opts() { set_opts "DOCKER_OPTS" "$DOCKER_OPTS" /etc/sysconfig/docker ; } - fix_expected() { - EXPECTED=$1 - EXISTING=$2 + EXPECTED="$1" + EXISTING="$2" - exp_base=$(basename $EXPECTED) - exp_dir=$(dirname $EXPECTED) - [ -d $exp_dir ] || mkdir -p $exp_dir - rm -f $exp_dir/$exp_base - (cd $exp_dir && ln -sf $EXISTING $exp_base) + exp_base="$(basename "$EXPECTED")" + exp_dir="$(dirname "$EXPECTED")" + [ -d "$exp_dir" ] || mkdir -p "$exp_dir" + rm -f "$exp_dir/$exp_base" + ( cd "$exp_dir" && ln -sf "$EXISTING" "$exp_base" ) } -save_backup() { - for x in $@ ; do - if [ ! -f $x ] ; then - touch $x.nbak - elif [ -f $x.bak ] ; then - warn "$x.bak already exists: no backup will be done" - else - cp -f $x $x.bak - fi - done +save_backup() { + for x in $@ ; do + if [ ! -f "$x" ] ; then + touch "$x.nbak" + elif [ -f "$x.bak" ] ; then + warn "$x.bak already exists: no backup will be done" + else + cp -f "$x" "$x.bak" + fi + done } restore_backup() { - for x in $@ ; do - if [ -f $x.nbak ] ; then - rm -f $x.nbak - else - if [ -f $x.bak ] ; then - mv -f $x.bak $x - fi - fi - done + for x in $@ ; do + if [ -f "$x.nbak" ] ; then + rm -f "$x.nbak" + else + if [ -f "$x.bak" ] ; then + mv -f "$x.bak" "$x" + fi + fi + done } -require_go() { go version >/dev/null 2>&1 ; } -require_git() { git version >/dev/null 2>&1 ; } +require_go() { go version >/dev/null 2>&1 ; } +require_git() { git version >/dev/null 2>&1 ; } ################################################################################ -[ -x $TESTS_EXE ] || abort "integration tests executable not found at $TESTS_EXE" -[ $EUID -eq 0 ] || abort "this script must be run as root" -[ -n "$VERSION" ] || abort "could not obtain version" +[ -x "$TESTS_EXE" ] || abort "integration tests executable not found at $TESTS_EXE" +[ "$EUID" -eq 0 ] || abort "this script must be run as root" +[ -n "$VERSION" ] || abort "could not obtain version" -if [ $# -gt 0 ] ; then - # run only some specific tests - TEST_SELECT="-check.f=$(echo $@ | tr ' ' '|')" +if [ "$#" -gt 0 ] ; then + # run only some specific tests + TEST_SELECT="-check.f=$(echo $@ | tr ' ' '|')" fi # We want this to fail if the bundles already exist and cannot be removed. # This is to avoid mixing bundles from different versions of the code. -mkdir -p $BUNDLES_DIR +mkdir -p "$BUNDLES_DIR" if [ -e "$BUNDLES_DIR/$VERSION" ] && [ -z "$KEEPBUNDLE" ]; then - log "$BUNDLES_DIR/$VERSION already exists. Removing." - rm -fr "$BUNDLES_DIR/$VERSION" && mkdir "$BUNDLES_DIR/$VERSION" || exit 1 - echo + log "$BUNDLES_DIR/$VERSION already exists. Removing." + rm -fr "$BUNDLES_DIR/$VERSION" && mkdir "$BUNDLES_DIR/$VERSION" || exit 1 + echo fi DEST="$BUNDLES_DIR/$VERSION/" mkdir -p "$DEST" -export DEST=$(realpath $DEST) +export DEST="$(realpath "$DEST")" if [ -n "$ENABLE_XUNIT" ] ; then - if [ ! -x /usr/local/bin/go2xunit ] ; then - echo >&2 "Installing go2xunit." + if [ ! -x /usr/local/bin/go2xunit ] ; then + echo >&2 "Installing go2xunit." - require_go || abort "the Go compiler is not installed" + require_go || abort "the Go compiler is not installed" - export GOPATH="$(mktemp -d)" + export GOPATH="$(mktemp -d)" - go get -d github.com/tebeka/go2xunit - cd $GOPATH/src/github.com/tebeka/go2xunit && go build -o /usr/local/bin/go2xunit . - chmod 755 /usr/local/bin/go2xunit - [ -x /usr/local/bin/go2xunit ] || abort "go2xunit could not be built" + go get -d github.com/tebeka/go2xunit + cd "$GOPATH/src/github.com/tebeka/go2xunit" && go build -o /usr/local/bin/go2xunit . + chmod 755 /usr/local/bin/go2xunit + [ -x /usr/local/bin/go2xunit ] || abort "go2xunit could not be built" - rm -rf "$GOPATH" - export -n GOPATH - fi + rm -rf "$GOPATH" + export -n GOPATH + fi fi # tests require this user and group @@ -137,40 +130,39 @@ fi /usr/sbin/useradd --create-home --gid docker unprivilegeduser >/dev/null 2>&1 || /bin/true # prepare some expected dirs, files, etc... -fix_expected $TESTS_DIR/contrib $DOCKER_DIR/contrib -fix_expected $DEST/fixtures $DOCKER_DIR/integration-cli/fixtures +fix_expected "$TESTS_DIR/contrib" "$DOCKER_DIR/contrib" +fix_expected "$DEST/fixtures" "$DOCKER_DIR/integration-cli/fixtures" +fix_expected "$DEST/../Dockerfile" "$DOCKER_DIR/Dockerfile" export DOCKER_TEST_HOST="tcp://127.0.0.1:2375" -export PATH=/usr/local/bin:$PATH +export PATH="/usr/local/bin:$PATH" export TZ=utc -export GOPATH="$FAKE_GOPATH" export DOCKER_GRAPHDRIVER="${DOCKER_GRAPHDRIVER:-vfs}" export DOCKER_USERLANDPROXY="${DOCKER_USERLANDPROXY:-true}" -#export DOCKER_REMAP_ROOT=default +export DOCKER_STORAGE_OPTS="${DOCKER_STORAGE_OPTS:-}" +export DOCKER_REMAP_ROOT="${DOCKER_REMAP_ROOT:-}" # "default" uses dockremap -# example usage: DOCKER_STORAGE_OPTS="dm.basesize=20G,dm.loopdatasize=200G" -storage_params="" +# Example usage: DOCKER_STORAGE_OPTS="dm.basesize=20G,dm.loopdatasize=200G". +storage_opts=() if [ -n "$DOCKER_STORAGE_OPTS" ]; then - IFS=',' - for i in ${DOCKER_STORAGE_OPTS}; do - storage_params="--storage-opt $i $storage_params" - done - unset IFS + IFS=',' + for i in ${DOCKER_STORAGE_OPTS}; do + storage_opts+=("$i") + done + unset IFS fi -# example usage: DOCKER_STORAGE_OPTS="dm.basesize=20G,dm.loopdatasize=200G" -extra_params="" # deal with remapping save_backup /etc/subuid /etc/subgid -echo "dockremap:500000:65536" > /etc/subuid -echo "dockremap:500000:65536" > /etc/subgid -groupadd dockremap >/dev/null 2>&1 || /bin/true -useradd -g dockremap dockremap >/dev/null 2>&1 || /bin/true +echo "dockremap:500000:65536" >/etc/subuid +echo "dockremap:500000:65536" >/etc/subgid +groupadd dockremap >/dev/null 2>&1 || /bin/true +useradd -g dockremap dockremap >/dev/null 2>&1 || /bin/true # make sure Docker is stopped, set our config file and then start again -save_backup $CFG_DOCKER -cat < $CFG_DOCKER +save_backup "$CFG_DOCKER" +cat <"$CFG_DOCKER" { "log-level": "debug", "log-driver": "json-file", @@ -178,42 +170,56 @@ cat < $CFG_DOCKER "max-size": "50m", "max-file": "5" }, + "userns-remap": "$DOCKER_REMAP_ROOT", "pidfile": "$DEST/docker.pid", - "host": [ + "hosts": [ "tcp://127.0.0.1:2375" ], "storage-driver": "$DOCKER_GRAPHDRIVER", + "storage-opts": [ + $(printf '"%s",' "${storage_opts[@]}" | sed 's/"",//g;$s/,$//') + ], "userland-proxy": $DOCKER_USERLANDPROXY } CFG_DOCKER_EOF systemctl restart docker.service cleanup() { - log "Restoring the Docker service..." - restore_backup $CFG_DOCKER - systemctl restart docker.service + log "Restoring the Docker service..." + restore_backup "$CFG_DOCKER" + systemctl restart docker.service - log "Removing extra files and restoring backups..." - restore_backup /etc/subuid /etc/subgid - rm -f $TESTS_DIR/contrib \ - $DEST/fixtures + log "Removing extra files and restoring backups..." + restore_backup /etc/subuid /etc/subgid + rm -f "$TESTS_DIR/contrib" "$DEST/fixtures" + rm -rf "$FROZEN_IMAGES" } trap cleanup EXIT -cd $DOCKER_DIR +cd "$DOCKER_DIR" log "Preparing the environment..." -bundle .integration-daemon-start +export MAKEDIR="$SCRIPTS_DIR/make" +export DOCKER_HOST="$DOCKER_TEST_HOST" bundle .integration-daemon-setup +# XXX: Really this should be sourced from the Dockerfile but this is good +# enough for now. This comes from the Docker 18.09.1-ce Dockerfile. +log "Downlading frozen images..." +mkdir -p "$FROZEN_IMAGES" +"$DOCKER_DIR/contrib/download-frozen-image-v2.sh" "$FROZEN_IMAGES" \ + buildpack-deps:jessie@sha256:dd86dced7c9cd2a724e779730f0a53f93b7ef42228d4344b25ce9a42a1486251 \ + busybox:latest@sha256:bbc3a03235220b170ba48a157dd097dd1379299370e1ed99ce976df0355d24f0 \ + busybox:glibc@sha256:0b55a30394294ab23b9afd58fab94e61a923f5834fba7ddbae7f8e0c11ba85e6 \ + debian:jessie@sha256:287a20c5f73087ab406e6b364833e3fb7b3ae63ca0eb3486555dc27ed32c6e60 \ + hello-world:latest@sha256:be0cd392e45be79ffeffa6b05338b98ebb16c87b255f48e297ec7f98e123905c + log "Running integration tests..." -export DOCKER_HOST=$DOCKER_TEST_HOST -cd $DEST && $TESTS_EXE $TEST_ARGS $TEST_SELECT | tee $TEST_LOG || /bin/true +cd "$DEST" && \ + "$TESTS_EXE" "${TEST_ARGS[@]}" $TEST_SELECT 2>&1 | tee "$TEST_LOG" || /bin/true if [ -n "$ENABLE_XUNIT" ] ; then - log "Generating xunit logs..." - go2xunit -fail -gocheck -input $TEST_LOG -output $TEST_LOG.xml + log "Generating xunit logs..." + go2xunit -fail -gocheck -input "$TEST_LOG" -output "$TEST_LOG.xml" fi export -n DOCKER_HOST - -bundle .integration-daemon-stop