#!/usr/bin/env bash # Helper script that builds and launches the Docker container. # --------------------------------------------------------------------- function main { # initialize cd "$( dirname "$0" )" PORT=5020 DATA_DIR= QA_DIR= ERRATA_DIR= USER_ANNO_FILE= ASOP_DIR= CACHED_SEARCHDB= IMAGE_TAG=latest CONTAINER_NAME=asl-rulebook2 DETACH= NO_BUILD= BUILD_NETWORK= CONTROL_TESTS_PORT= # parse the command-line arguments if [ $# -eq 0 ]; then print_help exit 0 fi params="$(getopt -o p:d:t: -l port:,data:,qa:,errata:,annotations:,asop:,cached-searchdb:,tag:,name:,detach,no-build,build-network:,control-tests-port:,help --name "$0" -- "$@")" if [ $? -ne 0 ]; then exit 1; fi eval set -- "$params" while true; do case "$1" in -p | --port ) PORT=$2 shift 2 ;; -d | --data ) DATA_DIR=$2 shift 2 ;; --qa ) QA_DIR=$2 shift 2 ;; --errata ) ERRATA_DIR=$2 shift 2 ;; --annotations ) USER_ANNO_FILE=$2 shift 2 ;; --asop ) ASOP_DIR=$2 shift 2 ;; --cached-searchdb ) CACHED_SEARCHDB=$2 shift 2 ;; -t | --tag ) IMAGE_TAG=$2 shift 2 ;; --name ) CONTAINER_NAME=$2 shift 2 ;; --detach ) DETACH=--detach shift 1 ;; --no-build ) NO_BUILD=1 shift 1 ;; --build-network ) # FUDGE! We sometimes can't get out to the internet from the container (DNS problems) using the default # "bridge" network, so we offer the option of using an alternate network (e.g. "host"). BUILD_NETWORK="--network $2" shift 2 ;; --control-tests-port ) CONTROL_TESTS_PORT=$2 shift 2 ;; --help ) print_help exit 0 ;; -- ) shift ; break ;; * ) echo "Unknown option: $1" >&2 exit 1 ;; esac done # check the data directory if [ -n "$DATA_DIR" ]; then target=$( get_target DIR "$DATA_DIR" ) if [ -z "$target" ]; then echo "Can't find the data directory: $DATA_DIR" exit 2 fi mpoint=/data/ DATA_DIR_VOLUME="--volume $target:$mpoint" DATA_DIR_ENV="--env DOCKER_DATA_DIR=$mpoint" fi # check the Q+A directory if [ -n "$QA_DIR" ]; then target=$( get_target DIR "$QA_DIR" ) if [ -z "$target" ]; then echo "Can't find the Q+A directory: $QA_DIR" exit 2 fi mpoint=/data/q+a/ QA_DIR_VOLUME="--volume $target:$mpoint" fi # check the errata directory if [ -n "$ERRATA_DIR" ]; then target=$( get_target DIR "$ERRATA_DIR" ) if [ -z "$target" ]; then echo "Can't find the errata directory: $ERRATA_DIR" exit 2 fi mpoint=/data/errata/ ERRATA_DIR_VOLUME="--volume $target:$mpoint" fi # check the user annotations file if [ -n "$USER_ANNO_FILE" ]; then target=$( get_target FILE "$USER_ANNO_FILE" ) if [ -z "$target" ]; then echo "Can't find the user annotations: $USER_ANNO_FILE" exit 2 fi mpoint=/data/annotations.json USER_ANNO_VOLUME="--volume $target:$mpoint" fi # check the ASOP directory if [ -n "$ASOP_DIR" ]; then target=$( get_target DIR "$ASOP_DIR" ) if [ -z "$target" ]; then echo "Can't find the ASOP directory: $ASOP_DIR" exit 2 fi mpoint=/data/asop/ ASOP_DIR_VOLUME="--volume $target:$mpoint" fi # check the cached search database file if [ -n "$CACHED_SEARCHDB" ]; then target=$( get_target FILE "$CACHED_SEARCHDB" ) if [ -z "$target" ]; then # NOTE: It's acceptable for the file to not exist (if we are generating the cached database for # the first time), but it has to be present for Docker to mount it :-/ target=$( realpath --no-symlinks "$CACHED_SEARCHDB" ) touch "$target" fi mpoint=/tmp/searchdb-cached.db CACHED_SEARCHDB_VOLUME="--volume $target:$mpoint" CACHED_SEARCHDB_ENV="--env DOCKER_CACHED_SEARCHDB=$mpoint" fi # check if testing has been enabled if [ -n "$CONTROL_TESTS_PORT" ]; then CONTROL_TESTS_PORT_BUILD="--build-arg CONTROL_TESTS_PORT=$CONTROL_TESTS_PORT" CONTROL_TESTS_PORT_RUN="--env CONTROL_TESTS_PORT=$CONTROL_TESTS_PORT --publish $CONTROL_TESTS_PORT:$CONTROL_TESTS_PORT" fi # build the image if [ -z "$NO_BUILD" ]; then echo Building the \"$IMAGE_TAG\" image... docker build \ --tag asl-rulebook2:$IMAGE_TAG \ $CONTROL_TESTS_PORT_BUILD \ $BUILD_NETWORK \ . 2>&1 \ | sed -e 's/^/ /' if [ ${PIPESTATUS[0]} -ne 0 ]; then exit 10 ; fi echo fi # launch the container echo Launching the \"$IMAGE_TAG\" image as \"$CONTAINER_NAME\"... docker run \ --name $CONTAINER_NAME \ --publish $PORT:5020 \ -it --rm \ $CONTROL_TESTS_PORT_RUN \ $DATA_DIR_VOLUME $DATA_DIR_ENV \ $QA_DIR_VOLUME \ $ERRATA_DIR_VOLUME \ $ASOP_DIR_VOLUME \ $USER_ANNO_VOLUME \ $CACHED_SEARCHDB_VOLUME $CACHED_SEARCHDB_ENV \ $DETACH \ asl-rulebook2:$IMAGE_TAG \ 2>&1 \ | sed -e 's/^/ /' exit ${PIPESTATUS[0]} } # --------------------------------------------------------------------- function get_target { local type=$1 local target=$2 # check that the target exists if [ "$type" == "FILE" ]; then test -f "$target" || return elif [ "$type" == "DIR" ]; then test -d "$target" || return elif [ "$type" == "FILE-OR-DIR" ]; then ls "$target" >/dev/null 2>&1 || return fi # convert the target to a full path # FUDGE! I couldn't get the "docker run" command to work with spaces in the volume targets (although # copying the generated command into the terminal worked fine) (and no, using ${var@Q} didn't help). # So, the next best thing is to allow users to create symlinks to the targets :-/ echo $( realpath --no-symlinks "$target" ) } # --------------------------------------------------------------------- function print_help { echo "`basename "$0"` {options}" cat <