vitess.io/vitess@v0.16.2/docker/test/run.sh (about) 1 #!/bin/bash 2 3 # Copyright 2019 The Vitess Authors. 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 17 # Script to run arbitrary commands within our bootstrap Docker images. 18 # 19 # NOTE: If your goal is to run a test within an image, please use our test 20 # runner "test.go" in the root directory instead. test.go will 21 # internally use this script to launch the test for you. 22 23 # If you still think that you want to use this script, read on. 24 # 25 # The script has two modes it can run in: 26 # - run_test: Run the test cmd in the given Docker image ("flavor"). 27 # - create_cache: Create a new Docker image after copying the source and 28 # running "make build". Such an image can be reused in 29 # future test invocations via --use_docker_cache <image>. 30 # 31 # Examples: 32 # a) Start an interactive shell within the Docker image. 33 # $ docker/test/run.sh mysql57 bash 34 # 35 # b) Build the code and run a test. 36 # $ docker/test/run.sh mysql57 "make build && ./test/keyrange_test.py -v" 37 # 38 # c) Cache the output of the command e.g. cache "make build" as we do for Travis CI. 39 # $ docker/test/run.sh --create_docker_cache vitess/bootstrap:rm_mysql57_test_cache_do_NOT_push mysql57 "make build" 40 # 41 # d) Run the test using a cache image. 42 # $ docker/test/run.sh --use_docker_cache vitess/bootstrap:rm_mysql57_test_cache_do_NOT_push mysql57 "./test/keyrange_test.py -v" 43 44 45 # Functions. 46 # Helper to append additional commands via "&&". 47 function append_cmd() { 48 local cmd="$1" 49 local append="$2" 50 if [[ -n "$cmd" ]]; then 51 cmd+=" && " 52 fi 53 cmd+="$append" 54 echo "$cmd" 55 } 56 57 # Variables. 58 # Default to "run_test" mode unless the --create_docker_cache flag is found. 59 mode="run_test" 60 61 62 # Main. 63 # Parse non-positional flags. 64 while true ; do 65 case "$1" in 66 --create_docker_cache) 67 case "$2" in 68 "") 69 echo "ERROR: --create_docker_cache requires the name of the image as second parameter" 70 exit 1 71 ;; 72 *) 73 mode="create_cache" 74 cache_image=$2 75 shift 2 76 ;; 77 esac ;; 78 --use_docker_cache) 79 case "$2" in 80 "") 81 echo "ERROR: --use_docker_cache requires the name of the image as second parameter" 82 exit 1 83 ;; 84 *) 85 existing_cache_image=$2 86 shift 2 87 ;; 88 esac ;; 89 -*) 90 echo "ERROR: Unrecognized flag: $1" 91 exit 1 92 ;; 93 *) 94 # No more non-positional flags. 95 break 96 ;; 97 esac 98 done 99 # Positional flags. 100 flavor=$1 101 version=${2:-0} 102 cmd=$3 103 args= 104 105 if [[ -z "$flavor" ]]; then 106 echo "Flavor must be specified as first argument." 107 exit 1 108 fi 109 110 if [[ -z "$cmd" ]]; then 111 cmd=bash 112 fi 113 114 if [[ ! -f bootstrap.sh ]]; then 115 echo "This script should be run from the root of the Vitess source tree - e.g. ~/src/vitess.io/vitess" 116 exit 1 117 fi 118 119 image=vitess/bootstrap:$version-$flavor 120 if [[ -n "$existing_cache_image" ]]; then 121 image=$existing_cache_image 122 fi 123 124 # Fix permissions before copying files, to avoid AUFS bug other must have read/access permissions 125 chmod -R o=rx *; 126 127 # This is required by the vtctld_web_test.py test. 128 # Otherwise, /usr/bin/chromium will crash with the error: 129 # "Failed to move to new namespace: PID namespaces supported, Network namespace supported, but failed: errno = Operation not permitted" 130 args="$args --cap-add=SYS_ADMIN" 131 132 args="$args -v /dev/log:/dev/log" 133 args="$args -v $PWD:/tmp/src" 134 135 # Share maven dependency cache so they don't have to be redownloaded every time. 136 mkdir -p /tmp/mavencache 137 chmod 777 /tmp/mavencache 138 args="$args -v /tmp/mavencache:/home/vitess/.m2" 139 140 # Add in the vitess user 141 args="$args --user vitess" 142 args="$args -v $PWD/test/bin:/tmp/bin" 143 144 # Mount in host VTDATAROOT if one exists, since it might be a RAM disk or SSD. 145 if [[ -n "$VTDATAROOT" ]]; then 146 hostdir=`mktemp -d $VTDATAROOT/test-XXX` 147 testid=`basename $hostdir` 148 149 chmod 777 $hostdir 150 151 echo "Mounting host dir $hostdir as VTDATAROOT" 152 args="$args -v $hostdir:/vt/vtdataroot --name=$testid -h $testid" 153 else 154 testid=test-$$ 155 args="$args --name=$testid -h $testid" 156 fi 157 158 # Run tests 159 case "$mode" in 160 "run_test") echo "Running tests in $image image..." ;; 161 "create_cache") echo "Creating cache image $cache_image ..." ;; 162 esac 163 164 bashcmd="" 165 166 if [[ -z "$existing_cache_image" ]]; then 167 168 # Construct "cp" command to copy the source code. 169 bashcmd=$(append_cmd "$bashcmd" "cp -R /tmp/src/!(vtdataroot|dist|bin|lib|vthook) . && cp -R /tmp/src/.git .") 170 171 fi 172 173 # Reset the environment if this was an old bootstrap. We can detect this from VTTOP presence. 174 bashcmd=$(append_cmd "$bashcmd" "export VTROOT=/vt/src/vitess.io/vitess") 175 bashcmd=$(append_cmd "$bashcmd" "export VTDATAROOT=/vt/vtdataroot") 176 bashcmd=$(append_cmd "$bashcmd" "export EXTRA_BIN=/tmp/bin") 177 178 bashcmd=$(append_cmd "$bashcmd" "mkdir -p dist; mkdir -p bin; mkdir -p lib; mkdir -p vthook") 179 bashcmd=$(append_cmd "$bashcmd" "rm -rf /vt/dist; ln -s /vt/src/vitess.io/vitess/dist /vt/dist") 180 bashcmd=$(append_cmd "$bashcmd" "rm -rf /vt/bin; ln -s /vt/src/vitess.io/vitess/bin /vt/bin") 181 bashcmd=$(append_cmd "$bashcmd" "rm -rf /vt/lib; ln -s /vt/src/vitess.io/vitess/lib /vt/lib") 182 bashcmd=$(append_cmd "$bashcmd" "rm -rf /vt/vthook; ln -s /vt/src/vitess.io/vitess/vthook /vt/vthook") 183 184 # Maven was setup in /vt/dist, may need to reinstall it. 185 bashcmd=$(append_cmd "$bashcmd" "echo 'Checking if mvn needs installing...'; if [[ ! \$(command -v mvn) ]]; then echo 'install maven'; curl -sL --connect-timeout 10 --retry 3 http://www-us.apache.org/dist/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz | tar -xz && mv apache-maven-3.3.9 /vt/dist/maven; fi; echo 'mvn check done'") 186 187 # Run bootstrap every time now 188 bashcmd=$(append_cmd "$bashcmd" "./bootstrap.sh") 189 190 # At last, append the user's command. 191 bashcmd=$(append_cmd "$bashcmd" "$cmd") 192 193 if tty -s; then 194 # interactive shell 195 # See above why we turn on "extglob" (extended Glob). 196 docker run -ti $args $image bash -O extglob -c "$bashcmd" 197 exitcode=$? 198 else 199 # non-interactive shell (kill child on signal) 200 trap 'docker kill $testid &>/dev/null' SIGTERM SIGINT 201 docker run $args $image bash -O extglob -c "$bashcmd" & 202 wait $! 203 exitcode=$? 204 trap - SIGTERM SIGINT 205 fi 206 207 # Clean up host dir mounted VTDATAROOT 208 if [[ -n "$hostdir" ]]; then 209 # Use Docker user to clean up first, to avoid permission errors. 210 docker run --name=rm_$testid -v $hostdir:/vt/vtdataroot $image bash -c 'rm -rf /vt/vtdataroot/*' 211 docker rm -f rm_$testid &>/dev/null 212 rm -rf $hostdir 213 fi 214 215 # If requested, create the cache image. 216 if [[ "$mode" == "create_cache" && $exitcode == 0 ]]; then 217 msg="DO NOT PUSH: This is a temporary layer meant to persist e.g. the result of 'make build'. Never push this layer back to our official Docker Hub repository." 218 docker commit -m "$msg" $testid $cache_image 219 220 if [[ $? != 0 ]]; then 221 exitcode=$? 222 echo "ERROR: Failed to create Docker cache. Used command: docker commit -m '$msg' $testid $image" 223 fi 224 fi 225 226 # Delete the container 227 docker rm -f $testid &>/dev/null 228 229 exit $exitcode