Add docker/run modifications to support Cygwin.
- Legacy-Id: 17506
Note: SVN reference [17486] has been migrated to Git commit f89dd2da7b
255 lines
8.3 KiB
Bash
Executable file
255 lines
8.3 KiB
Bash
Executable file
#!/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 <<EOF
|
|
NAME
|
|
$program - Run a docker datatracker container with suitable settings
|
|
|
|
SYNOPSIS
|
|
$program [OPTIONS] ARGS
|
|
|
|
DESCRIPTION
|
|
|
|
This is a wrapper which runs docker with suitable arguments on a
|
|
debian-based docker image which has been set up with the dependencies
|
|
needed to easily run the IETF datatracker in development mode. By
|
|
default, it expects to find the MySQL database files at
|
|
$parent/data/mysql, which is mapped inside the
|
|
container to /var/lib/mysql, and it will set up a home directory for
|
|
the current user ($USER) and map it to $HOME.
|
|
|
|
EOF
|
|
echo -e "OPTIONS"
|
|
if [ "$(uname)" = "Linux" ]; then
|
|
egrep "^[ ]+[-][A-Za-z| -]+\*?\)[ ]+[A-Za-z].+#" $0 | tr -s "\t|" "\t," | sed -r -e 's/\)[ \t]+([A-Z]+)=\$2[^#]*#/=\1\t/' -e 's/\)[^#]*#/\t/'
|
|
else
|
|
egrep "^[ ]+[-][A-Za-z| -]+\*?\)[ ]+[A-Za-z].+#" $0 | sed 's/\|.*\$2[^#]*#/ /'| sed -E 's/\|.*\)[^#]*#/ /'
|
|
fi
|
|
cat <<EOF
|
|
|
|
FILES
|
|
|
|
AUTHOR
|
|
Written by Henrik Levkowetz, <henrik@levkowetz.com>
|
|
|
|
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"
|
|
DBURL=https://www.ietf.org/lib/dt/sprint/ietf_utf8.bin.tar.bz2
|
|
WHO=$(whoami)
|
|
WHOUID=$(id -u $WHO)
|
|
WHOGID=$(id -g $WHO)
|
|
|
|
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
|
|
|
|
if [ -z "$TAG" ]; then
|
|
TAG=$(basename $(svn info $parent | grep ^URL | awk '{print $2}'))
|
|
fi
|
|
|
|
# ----------------------------------------------------------------------
|
|
# 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."
|
|
elif [[ $(uname) =~ CYGWIN.* ]]; then
|
|
echo "Running under Cygwin."
|
|
APP="Don't know how to start Docker when running under Cygwin"
|
|
CMD="echo"
|
|
MYSQLDIR=$(echo $MYSQLDIR | sed -e 's/^\/cygdrive\/\(.\)/\1:/')
|
|
WHO=$(echo $WHO | sed -e 's/^.*\\//' | tr -d \\r)
|
|
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"
|
|
echo -e "User $WHO ($WHOUID:$WHOGID)"
|
|
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} -e UID="$WHOUID" -e GID="$WHOGID" \
|
|
"$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} -e UID="$WHOUID" -e GID="$WHOGID" \
|
|
"$REPO:$TAG" "$@"
|
|
fi
|
|
|
|
echo ""
|
|
echo "Committing changes in the container to an image:"
|
|
image=$( docker images -q $REPO:$TAG)
|
|
latest=$(docker ps -lq -f "ancestor=$image")
|
|
docker commit $latest $REPO:$TAG
|
|
|
|
echo ""
|
|
echo "Cleaning up containers and images"
|
|
docker rm $latest
|
|
DANGLING=$( docker images -f dangling=true -q )
|
|
if [ -n "$DANGLING" ]; then
|
|
echo "Dangling images: $DANGLING"
|
|
docker rmi -f $DANGLING
|
|
fi
|
|
|
|
fi
|