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