#!/bin/bash version=0.10 program=${0##*/} progdir=${0%/*} if [ "$progdir" = "$program" ]; then progdir="."; fi if [ "$progdir" = "." ]; then progdir="$PWD"; fi parent=$(dirname $progdir) if [ "$parent" = "." ]; then parent="$PWD"; fi # ---------------------------------------------------------------------- function usage() { cat < COPYRIGHT Copyright (c) 2015 IETF Trust and the persons identified as authors of the code. All rights reserved. License 'Simplified BSD', as specified in http://opensource.org/licenses/BSD-3-Clause. EOF } # ---------------------------------------------------------------------- function die() { echo -e "\n$program: error: $*" >&2 exit 1 } function note() { if [ -n "$VERBOSE" ]; then echo -e "$*"; fi } # ---------------------------------------------------------------------- function version() { echo -e "$program $version" } # ---------------------------------------------------------------------- trap 'echo "$program($LINENO): Command failed with error code $? ([$$] $0 $*)"; exit 1' ERR # ---------------------------------------------------------------------- # Option parsing # Options shortopts=dhi:m:Mp:r:t:vVu: longopts=download-data,help,ietfdb-url=,mysqldata=,no-mysqldir,port=,docker-repo=,tag=,verbose,version,user=, # Default values MYSQLDIR=$parent/data/mysql FILEDIR=$parent/../data/ PORT=8000 REPO="ietf/datatracker-environment" TAG=$(basename $(svn info $parent | grep ^URL | awk '{print $2}')) DBURL=https://www.ietf.org/lib/dt/sprint/ietf_utf8.bin.tar.bz2 WHO=$(whoami) if [ "$(uname)" = "Linux" ]; then args=$(getopt -o "$shortopts" --long "$longopts" -n '$program' -- $SV "$@") if [ $? != 0 ] ; then die "Terminating..." >&2 ; exit 1 ; fi eval set -- "$args" sed="sed -r" else # Darwin, BSDs args=$(getopt -o$shortopts $SV $*) if [ $? != 0 ] ; then die "Terminating..." >&2 ; exit 1 ; fi set -- $args sed="sed -E" fi while true ; do case "$1" in -d| --download-data) DOWNLOAD=1;; # Download and set up the database files -h| --help) usage; exit;; # Show this help, then exit -f| --filedir) FILEDIR=$2; shift;; # Set the desired location of drafts, charters etc. -i| --ietfdb-url) DBURL=$2; shift;; # Use an alternative database tarball URL -m| --mysqldir) MYSQLDIR=$2; shift;; # Set the desired location of MySQL's database files -p| --port) PORT=$2; shift;; # Bind the container's port 8000 to external port PORT -r| --docker-repo) REPO=$2; shift;; # Use the given docker repository, instead of the default -t| --tag) TAG=$2; shift;; # Use this docker image tag, instead of the svn branch name -u| --user) WHO=$2; shift;; # Run the container as the specified user -v| --verbose) VERBOSE=1;; # Be more talkative -V| --version) version; exit;; # Show program version, then exit --) shift; break;; *) die "Internal error, inconsistent option specification: '$1'";; esac shift done # ---------------------------------------------------------------------- # The program itself [ -f /proc/1/cgroups ] && grep 'docker' /proc/1/cgroups && die "It looks like you're inside docker already ..." if [ "$(uname)" = "Darwin" ]; then APP="/Applications/Docker.app" CMD="open -a" elif [ "$(uname)" = "Linux" ]; then echo "Running on Linux." else die "This script does not have support for your architecture ($(uname)); sorry :-(" fi if [ "$(uname)" = "Linux" ]; then echo "Not trying to start a virtual docker machine on Linux" elif [ -e "$APP" ]; then info=$(docker info 2>&1 || true) if ! docker info 1> /dev/null 2>&1; then echo -e "The docker VM doesn't seem to be running; docker info gave:\n $info" echo "Will attempt to start docker by doing '\$ $CMD $APP':" $CMD $APP declare -i count printf "Waiting for docker engine .." while true; do printf "." sleep 2 if docker info >/dev/null 2>&1; then break; fi count=$(( $count + 1)) if [ $count -gt 10 ]; then die "No contact with docker engine; bailing out." fi done fi URL="http://localhost:$PORT/" else if [ $($machine status default | tr "A-Z" "a-z" ) != "running" ]; then echo "The docker VM doesn't seem to be running; will attempt to start it by doing '\$ $machine start':" $machine start || die "Failed taking up the Docker VM" fi if [ -f "$machine" ]; then if [ $($machine status default | tr "A-Z" "a-z") = "running" ]; then tmpfile=$(mktemp docker.run.XXXXXXXX) if $machine env 2>/dev/null | grep DOCKER_ > $tmpfile; then mv $tmpfile ~/.docker-info elif printenv | grep DOCKER_ > $tmpfile; then mv $tmpfile ~/.docker-info else rm $tmpfile die "Failed setting the appropriate DOCKER_* environment variables." fi . ~/.docker-info else rm -f ~/.docker-info fi ip=$($machine ip) URL="http://$ip:$PORT/" fi fi image=$(docker ps | grep "$REPO:$TAG" | awk '{ print $1 }') if [ "$image" ]; then if [ "$*" ]; then echo "Running 'cd ~/${parent#$HOME/}; $*'" docker exec -u "$WHO" -t $image bash -i -c "cd; cd \"${parent#$HOME/}\"; $*" else docker exec -u "$WHO" -ti $image bash -i fi else echo "" echo "Starting a docker container for '$TAG'." if [ -n "$DOWNLOAD" ]; then ( cd "$(dirname $MYSQLDIR)" wget -N "$DBURL" && tar xjf ietf_utf8.bin.tar.bz2 && chmod -R go+rwX mysql ) [ -d "$MYSQLDIR" ] || die "The download seems to have failed; still no $MYSQLDIR. Giving up." else [ -d "$MYSQLDIR" ] || die "Expected $MYSQLDIR to exist, but it\ndidn't. Use '$program -d' to download and unpack the database." fi if ! docker images "$REPO" | grep -q "$TAG"; then echo "Fetching docker image '$REPO:$TAG'" if ! docker pull "$REPO:$TAG"; then docker pull "$REPO:latest" || die "Failed to pull down the '$REPO:latest' docker image" id=$(docker images "$REPO" | grep latest | awk '{print $3}') echo "Tagging $REPO:latest as $REPO:$TAG for use as environment for this branch." docker tag $id "$REPO:$TAG" fi fi echo -e "\nThe web interface for 'runserver' should appear on $URL\n" if [ -z "$MYSQLDIR" ]; then docker run -ti -p $PORT:8000 -v "$HOME:/home/$WHO" \ -e USER="$WHO" -e DATADIR="${parent#$HOME/}/data" -e CWD="${PWD#$HOME/}" \ -e TAG="$TAG" -e FILEDIR=${FILEDIR#$HOME} \ "$REPO:$TAG" "$@" else docker run -ti -p $PORT:8000 -v "$HOME:/home/$WHO" -v "$MYSQLDIR:/var/lib/mysql"\ -e USER="$WHO" -e DATADIR="${parent#$HOME/}/data" -e CWD="${PWD#$HOME/}" \ -e TAG="$TAG" -e FILEDIR=${FILEDIR#$HOME} \ "$REPO:$TAG" "$@" fi echo "" echo "Committing changes in the container to an image:" latest=$(docker ps -lq) docker commit $latest $REPO:$TAG echo "" echo "Cleaning up containers and images" docker rm $latest docker images -f dangling=true -q | xargs docker rmi -f fi