changeset 90:63cb9be89a26 production v1.0.0

flow: Merged <release> 'v1.0.0' to <master> ('production').
author smith@nwoca.org
date Thu, 22 Sep 2016 01:49:20 +0100
parents 44f401c902ba (current diff) 457283fe76b5 (diff)
children fe7b8e3b4100
files
diffstat 48 files changed, 915 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,30 @@
+syntax: regexp
+^\.DS_Store
+.*~$
+\.orig$
+\.orig\..*$
+\.chg\..*$
+\.rej$
+\.conflict\~$
+.*~$
+syntax: glob
+**/*.class
+*\#*
+classes/*
+out/*
+lib/*
+build/*
+dist/*
+nbproject/*
+.idea/workspace.*
+*.log
+.gradle/*
+.idea/*
+*.iml
+*.iws
+*.ipr
+gradle-app.*
+build.xml
+private*.*
+*.pdf
+*.pid
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compose/preview/debug.yml	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,20 @@
+uspsdebug:
+  image: docker.ssdt.io/ssdt-postgres:3
+  command: /bin/bash
+  links:
+    - uspsdb:database
+  environment:
+    - DB_HOST=database
+    - DB_NAME=$${DATABASE_ENV_DB_NAME}
+    - DB_USER=$${DATABASE_ENV_DB_USER}
+    - DB_PASS=$${DATABASE_ENV_DB_PASS}
+usasdebug:
+  image: docker.ssdt.io/ssdt-postgres:3
+  command: -i ${IMP_IRN} -u ${IMP_URL} -r ${IMP_PATH} ${IMP_ANON} ${IMP_EM}
+  links:
+    - usasdb:database
+  environment:
+    - DB_HOST=database
+    - DB_NAME=$${DATABASE_ENV_DB_NAME}
+    - DB_USER=$${DATABASE_ENV_DB_USER}
+    - DB_PASS=$${DATABASE_ENV_DB_PASS}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compose/preview/import.yml	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,20 @@
+uspsimport:
+  image: docker.ssdt.io/usps-import:preview
+  command: -i ${IMP_IRN} -u ${IMP_URL} -r ${IMP_PATH} ${IMP_ANON} ${IMP_EM}
+  links:
+    - uspsdb:database
+  environment:
+    - DB_HOST=database
+    - DB_NAME=$${DATABASE_ENV_DB_NAME}
+    - DB_USER=$${DATABASE_ENV_DB_USER}
+    - DB_PASS=$${DATABASE_ENV_DB_PASS}
+usasimport:
+  image: docker.ssdt.io/usas-import:preview
+  command: -i ${IMP_IRN} -u ${IMP_URL} -r ${IMP_PATH} ${IMP_ANON} ${IMP_EM}
+  links:
+    - usasdb:database
+  environment:
+    - DB_HOST=database
+    - DB_NAME=$${DATABASE_ENV_DB_NAME}
+    - DB_USER=$${DATABASE_ENV_DB_USER}
+    - DB_PASS=$${DATABASE_ENV_DB_PASS}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compose/preview/training.yml	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,41 @@
+usasdb:
+  restart: unless-stopped
+  image: docker.ssdt.io/trainingdb-usas
+  environment:
+    - DB_NAME=usasdb
+    - DB_USER=usas
+    - DB_PASS=usasdefault
+usasapp:
+  restart: unless-stopped
+  image: docker.ssdt.io/usas-app:preview
+  volumes:
+    - ${PWD}/config:/config
+  environment:
+    - DB_HOST=usas-database
+    - DB_NAME=usasdb
+    - DB_USER=usas
+    - DB_PASS=usasdefault
+    - JAVA_OPTS=-Xmx640m
+  links:
+    - usasdb:usas-database
+uspsdb:
+  restart: unless-stopped
+  image: docker.ssdt.io/trainingdb-usps
+  environment:
+    - DB_NAME=uspsdb
+    - DB_USER=usps
+    - DB_PASS=uspsdefault
+uspsapp:
+  restart: unless-stopped
+  image: docker.ssdt.io/usps-app:preview
+  volumes:
+    - ${PWD}/config:/config
+  environment:
+    - DB_HOST=usps-database
+    - DB_NAME=uspsdb
+    - DB_USER=usps
+    - DB_PASS=uspsdefault
+    - JAVA_OPTS=-Xmx640m
+  links:
+    - uspsdb:usps-database
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compose/preview/usas.template.yml	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,12 @@
+usasdb:
+  extends:
+    file: /ssdt/compose/preview/usas.yml
+    service: usasdb
+  volumes:
+    - |volumeName|:/var/lib/postgresql/data
+usasapp:
+  extends:
+     file: /ssdt/compose/preview/usas.yml
+     service: usasapp
+  links:
+    - usasdb:database
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compose/preview/usas.yml	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,20 @@
+# base compose file for USAS preview release
+usasdb:
+  restart: unless-stopped
+  image: docker.ssdt.io/ssdt-postgres:3
+  volumes:
+    - ${PWD}/backup:/backup
+  environment:
+    - DB_NAME=usasdb
+    - DB_USER=usas
+    - DB_PASS=usasdefault
+usasapp:
+  restart: unless-stopped
+  image: docker.ssdt.io/usas-app:preview
+  volumes:
+    - ${PWD}/config:/config
+  environment:
+    - DB_HOST=database
+    - DB_NAME=usasdb
+    - DB_USER=usas
+    - DB_PASS=usasdefault
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compose/preview/usps.template.yml	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,12 @@
+uspsdb:
+  extends:
+    file: /ssdt/compose/preview/usps.yml
+    service: uspsdb
+  volumes:
+    - |volumeName|:/var/lib/postgresql/data
+uspsapp:
+  extends:
+     file: /ssdt/compose/preview/usps.yml
+     service: uspsapp
+  links:
+    - uspsdb:database
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compose/preview/usps.yml	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,20 @@
+# base compose file for usps preview release
+uspsdb:
+  restart: unless-stopped
+  image: docker.ssdt.io/ssdt-postgres:3
+  volumes:
+    - ${PWD}/backup:/backup
+  environment:
+    - DB_NAME=uspsdb
+    - DB_USER=usps
+    - DB_PASS=uspsdefault
+uspsapp:
+  restart: unless-stopped
+  image: docker.ssdt.io/usps-app:preview
+  volumes:
+    - ${PWD}/config:/config
+  environment:
+    - DB_HOST=database
+    - DB_NAME=uspsdb
+    - DB_USER=usps
+    - DB_PASS=uspsdefault
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compose/sample/docker-compose.yml	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,30 @@
+data:
+  image: busybox
+  volumes:
+    - ${PWD}/dbdata:/var/lib/postgresql/data
+    - ${PWD}/config:/config
+    - ${PWD}/backup:/backup
+db:
+  restart: always
+  image: djsmith/ssdt-postgres:1
+  volumes_from:
+    - data
+  environment:
+    - DB_NAME=usasdb
+    - DB_USER=usas
+    - DB_PASS=PleaseDontUseExamplePasswords
+app:
+  restart: always
+  image: djsmith/usas-app:snapshot
+  volumes_from:
+    - data
+  ports:
+    - "18004:8080"
+  links:
+    - db:database
+  environment:
+    - DB_HOST=database
+    - DB_NAME=$${DATABASE_ENV_DB_NAME}
+    - DB_USER=$${DATABASE_ENV_DB_USER}
+    - DB_PASS=$${DATABASE_ENV_DB_PASS}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/init.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,3 @@
+#!/bin/bash
+alias utils='docker run -it -v ${PWD}:/tmp -v /ssdt:/ssdt --rm docker.ssdt.io/ssdt-utils'
+alias send2ssdt='/ssdt/scripts/send.sh'
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/Dockerfile	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,13 @@
+FROM docker.ssdt.io/java:8-jre
+
+MAINTAINER Dave Smith <smith@nwoca.org>
+
+RUN echo "ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true" | debconf-set-selections \
+	&& echo 'deb http://httpredir.debian.org/debian jessie contrib' > /etc/apt/sources.list.d/jessie-contrib.list \
+    && apt-get update 									\
+    && apt-get install -y ttf-mscorefonts-installer
+
+ENV TZ=America/New_York
+
+RUN echo $TZ > /etc/timezone \
+    && dpkg-reconfigure --frontend noninteractive tzdata
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/postgres/Dockerfile	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,23 @@
+#
+# Docker file to create postgres image for ssdt applications
+
+FROM postgres:9.4.5
+
+MAINTAINER Dave Smith smith@nwoca.org
+
+ENV DB_NAME=database \
+    DB_USER=dbuser \
+    DB_PASS=dbpassword \
+    PGDATA=/var/lib/postgresql/data/pgdata
+
+COPY setupDatabase.sh /docker-entrypoint-initdb.d/setupDatabase.sh
+
+COPY setupExtensions.sh /docker-entrypoint-initdb.d/setupExtensions.sh
+
+RUN chmod 755 /docker-entrypoint-initdb.d/setupDatabase.sh \
+    & chmod 755 /docker-entrypoint-initdb.d/setupExtensions.sh
+
+ENV TZ=America/New_York
+
+RUN     echo $TZ > /etc/timezone \
+    &&  dpkg-reconfigure --frontend noninteractive tzdata
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/postgres/setupDatabase.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+export PGUSER=postgres
+result=`psql -t -A <<- EOSQL
+   SELECT 1 FROM pg_database WHERE datname='$DB_NAME';
+EOSQL`
+
+echo "checking for existing $DB_NAME ( $result ) "
+
+if [[ $result == "1" ]]; then
+    echo "$DB_NAME exists. continuing startup."
+    # database exists
+    # $? is 0
+    exit 0
+else
+echo "Creating $DB_NAME for $DB_USER"
+psql <<- EOSQL
+   CREATE ROLE $DB_USER WITH LOGIN ENCRYPTED PASSWORD '${DB_PASS}' CREATEDB;
+   CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0 ENCODING 'UTF8';
+   GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;
+EOSQL
+fi
+
+echo ""
+echo "$DB_NAME database created"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/postgres/setupExtensions.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+export PGUSER=postgres
+result=`psql -t -A <<- EOSQL
+   SELECT 1 FROM pg_database WHERE datname='$DB_NAME';
+EOSQL`
+
+echo "Checking extensions on $DB_NAME ( $result )"
+if [[ $result == "1" ]]; then
+    psql $DB_NAME <<- EOSQL
+    CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
+EOSQL
+  echo "Set extensions on $DB_NAME"
+fi
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/.functions.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+# deletes psql data from specified service
+resetDbVolume() {
+#   Works for named and unnamed volumes and custom $PGDATA.
+#   Container must be stopped
+   service=${1?Must supply db service to reset}
+   container=$(composeGetContainer $service)
+   if [ "$container" != "" ]
+   then
+      echo "deleting db data from $container"
+      docker-compose run --no-deps --rm $service bash -c "rm -rf \${PGDATA?Missing PGDATA env}"
+   fi
+}
+
+# finds docker container for specified compose service 
+composeGetContainer() {
+  service=${1?"Must supply service from current project"}
+
+  container=$( docker-compose ps | cut -d " " -f 1 -s | grep _${service}_ )
+  echo $container
+}
+
+executeSQL() {
+   service=${1?Must supply db service to execute against}
+   container=$(composeGetContainer $service)
+
+   echo "$2" | docker exec -i $container  sh -c "gosu postgres psql \$DB_NAME"
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/backup-usas.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,6 @@
+#!/bin/bash
+ docker-compose run --rm usasdb sh -c \
+   "pg_dump -Cc --if-exists --host=usasdb \
+      --dbname=\$USASDB_ENV_DB_NAME \
+	  --username=\$USASDB_ENV_DB_USER | gzip \
+	  > /backup/\$USASDB_ENV_DB_NAME.$(date +%Y-%m-%d-%H-%M-%S).backup.gz"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/backup-usps.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,6 @@
+#!/bin/bash
+ docker-compose run --rm uspsdb sh -c \
+   "pg_dump -Cc --if-exists --host=uspsdb \
+      --dbname=\$USPSDB_ENV_DB_NAME \
+	  --username=\$USPSDB_ENV_DB_USER | gzip \
+	  > /backup/\$USPSDB_ENV_DB_NAME.$(date +%Y-%m-%d-%H-%M-%S).backup.gz"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/capture.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,3 @@
+#!/bin/bash
+# writes tail of current logs to standard out from running containers in compose project.
+docker-compose ps -q | xargs -I ID docker inspect --format='{{.LogPath}}' ID | xargs tail -n${1-8000}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/clearlocks.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,9 @@
+#!/bin/bash
+source "$( dirname "${BASH_SOURCE[0]}")/.functions.sh"
+if [ -z "$1" ]
+then
+  echo "Usage: `basename $0` {db service}"
+  echo  "  eg: clearlocks.sh usasdb"
+  exit $E_NOARGS
+fi
+executeSQL "$1" "update databasechangeloglock set locked = false, lockgranted = null, lockedby = null where locked = true;"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/console.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+# connects to the telnet console of the application for the specified service of the current project
+source "$( dirname "${BASH_SOURCE[0]}")/.functions.sh"
+
+container=$(composeGetContainer ${1?"Must specify the app service of the console to connect to"} )
+
+ip=$(docker inspect -f '{{.NetworkSettings.IPAddress}}' $container)
+
+docker run -it -v ${PWD}:/tmp -v /ssdt:/ssdt --rm docker.ssdt.io/ssdt-utils telnet $ip 2000 | tee console.log
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/d-images.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,4 @@
+#!/bin/bash
+docker images --filter "label=io.ssdt.id" -q | xargs docker inspect --format "{{.RepoTags}} {{index .Config.Labels \"io.ssdt.id\"}}" --type image
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/d-ps.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,4 @@
+#!/bin/bash
+docker ps -a --format="table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Label \"io.ssdt.id\"}}\t{{.Label \"io.ssdt.app\"}}\t{{.Label \"io.ssdt.type\"}}" $@
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/import-usas.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+source "$( dirname "${BASH_SOURCE[0]}")/.functions.sh"
+
+docker-compose stop usasapp usasdb
+resetDbVolume usasdb
+docker-compose rm -vf usasapp usasdb
+
+export IMP_IRN=${IMP_IRN}
+export IMP_URL=${IMP_URL-ftp://username:password@nwoca.org}
+export IMP_PATH=${IMP_PATH}
+export IMP_ANON=${IMP_ANON-}
+export IMP_EM=${IMP_EM-}
+#
+docker-compose -f docker-compose.yml -f /ssdt/compose/preview/import.yml rm -f usasimport
+# start import and wait for completion
+docker-compose -f docker-compose.yml -f /ssdt/compose/preview/import.yml up usasimport | tee usasimport.log
+# remove temporary container
+docker-compose -f docker-compose.yml -f /ssdt/compose/preview/import.yml rm -f usasimport
+# start application
+docker-compose up -d usasapp
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/import-usps.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+source "$( dirname "${BASH_SOURCE[0]}")/.functions.sh"
+
+docker-compose stop uspsapp uspsdb
+resetDbVolume uspsdb
+docker-compose rm -vf uspsapp uspsdb
+
+export IMP_IRN=${IMP_IRN}
+export IMP_URL=${IMP_URL-ftp://username:password@nwoca.org}
+export IMP_PATH=${IMP_PATH}
+export IMP_ANON=${IMP_ANON:--a false}
+export IMP_EM=${IMP_EM-}
+
+docker-compose -f docker-compose.yml -f /ssdt/compose/preview/import.yml rm -f uspsimport
+# start import and wait for completion
+docker-compose -f docker-compose.yml -f /ssdt/compose/preview/import.yml up uspsimport | tee uspsimport.log
+# remove temporary container
+docker-compose -f docker-compose.yml -f /ssdt/compose/preview/import.yml rm -f uspsimport
+# start application
+docker-compose up -d uspsapp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/info.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,13 @@
+#!/bin/bash
+echo $BASH_VERSION
+docker version
+docker-compose version
+echo "------- Docker info-------------"
+docker info
+echo "------- Images -----------------"
+/ssdt/scripts/d-images.sh
+echo "------- Containers------"
+/ssdt/scripts/d-ps.sh
+echo "------- OS Processes------------"
+top -b -n 1
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/pid2name.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,5 @@
+#!/bin/bash
+# determines the docker container name of a PID on docker host.
+docker ps -q | xargs docker inspect --format '{{.State.Pid}} {{.Name}}' \
+     | grep "^${1?specify pid of process on host}" |  sed 's/^.*\///g'
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/restore-usas.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,13 @@
+#!/bin/bash
+if [ -z "$1" ]
+then
+  echo "Usage: `basename $0` {backup file to restore}"
+  echo  " filename must relative to the container's file system. (e.g. /backup/filename)"
+  exit $E_NOARGS
+fi
+
+docker-compose stop usasapp
+docker-compose restart usasdb
+docker-compose run --rm usasdb sh -c \
+   "gunzip -f $1 -c | psql --host=usasdb --username=postgres"
+docker-compose start usasapp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/restore-usps.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,14 @@
+#!/bin/bash
+if [ -z "$1" ]
+then
+  echo "Usage: `basename $0` {backup file to restore}"
+  echo  " filename must relative to the container's file system. (e.g. /backup/filename)"
+  exit $E_NOARGS
+fi
+
+docker-compose stop uspsapp
+docker-compose restart uspsdb
+docker-compose run --rm uspsdb sh -c \
+   "gunzip -f $1 -c | psql --host=uspsdb --username=postgres"
+docker-compose start uspsapp
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/send.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,10 @@
+#!/bin/bash
+file=${1?"Usage: $0 filename [name]\n specify the filename relative to the current directory or - for stdin.\noptionally specify a short name (default to base directory)"}
+if [ "$file" != "-" ]
+then
+   file="/tmp/${file}"
+fi
+name=${2:-$(basename $PWD)}
+source=$(hostname)
+docker run -i -v /ssdt:/ssdt -v ${PWD}:/tmp --rm docker.ssdt.io/ssdt-utils \
+   curl -F source=$source -F name=$name -F file=@$file https://upload.ssdt.io/upload
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/training.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,72 @@
+#!/bin/bash
+
+BASEDIR=$PWD
+
+case "$1" in
+
+  create) 
+
+	prefix=${3:+$3-}
+
+	mkdir -p $BASEDIR/${prefix}training-00/config
+	
+	if [ ! -f $BASEDIR/${prefix}training-00/config/application.properties ]; then	    
+		echo "application.admin.password=training" > ${prefix}training-00/config/application.properties
+		echo "application.admin.reset=true" >> ${prefix}training-00/config/application.properties
+		echo "cache.config.file=ehcache-compact.xml" >> ${prefix}training-00/config/application.properties	
+	fi
+	
+    for i in $(eval echo {01..${2:-10}}); do
+    	mkdir -p $BASEDIR/${prefix}training-$i
+    done
+
+    for t in $( ls -d *training-* ); do
+        if [ ! $t == "${prefix}training-00" ]; then
+
+			echo $t
+			
+			mkdir -p ${BASEDIR}/$t/config
+			cp ${BASEDIR}/${prefix}training-00/config/application.properties ${BASEDIR}/$t/config/application.properties
+		   
+		   	sed "s/${prefix}training-00/$t/g" ${prefix}training-00/docker-compose.yml > $t/docker-compose.yml		   
+			if [ -f $BASEDIR/${prefix}training-00/docker-compose.override.yml ]; then
+				sed "s/${prefix}training-00/$t/g" ${prefix}training-00/docker-compose.override.yml > $t/docker-compose.override.yml
+			fi
+		   
+        fi 
+    done
+    ;;
+
+  compose)
+
+     for t in $( ls -d *training-* ); do
+         cd $BASEDIR/$t
+         docker-compose ${*:2}  
+     done
+     ;;
+ 
+  reset)
+
+     for t in $( ls -d *training-* ); do
+         cd $BASEDIR/$t
+
+         docker-compose stop
+         docker-compose rm -f usasdb uspsdb usasapp uspsapp
+         docker-compose up -d usasdb uspsdb
+         sleep 30 # delay to allow database startup and restore
+         docker-compose up -d
+         sleep 60 # delay to prevent overwhelming host
+
+     done
+     ;;
+
+
+  *)
+      echo "usage:"
+      echo "  create  [n:-10] [prefix] creates training-nn configs based on training-00 directory"
+      echo "  compose {cmd} [args...]  executes docker compose command on each training instance"
+      echo "  reset                    resets training database on each training instance"
+   ;;  
+esac
+echo "done"
+cd $BASEDIR
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/updates-apply.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,46 @@
+#!/bin/bash
+# Scans for docker projects in specified parent path and
+# updates images, if applicable.
+#
+# The parent directory to search for docker-compose.yml
+# files must be specified.  An optional service to update
+# may be specified in the second argument. The default is
+# to update services matching "*app".
+#
+# Only services which are currently running will be updated.
+# The script will not automatically start stopped services.
+#
+# examples:
+#   /ssdt/apply-updates.sh /data/preview
+#   /ssdt/apply-updates.sh /data/preview usps
+#
+: ${1?"Usage: {parent path} [service]"}
+SERVICE=${2:-*app}
+
+ORIGINALDIR=$PWD
+PARENTDIR=$1
+
+for f in $(find $PARENTDIR -name docker-compose.yml)
+do
+   projectdir=`dirname $f`
+   project=`basename $projectdir`
+   cd $projectdir
+   echo -e "----\n$project: checking services"
+   while read line
+   do
+      read  container eol <<< $line
+      if [[ $container == *_1 ]]
+      then
+        t=(${container//_/ })
+        service=${t[1]}
+        if [[ $service == $SERVICE ]]
+        then
+           echo -e "\n$project: Updating $service"
+           docker-compose up -d $service
+        fi
+      fi
+   done < <(docker-compose ps)
+
+done
+
+cd $ORIGINALDIR
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/updates-cleanup.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,7 @@
+#!/bin/bash
+#
+# Safely removes obsolete images from previous SSDT versions.
+#
+
+docker images --filter "label=io.ssdt.app" --filter "dangling=true" -q | xargs docker rmi
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/updates-pull.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,26 @@
+#!/bin/bash
+# 
+# Pulls updates from upstream repository for images matching filter. The
+# default filter pulls all ssdt application images.
+#
+# Usage:
+#    pull-updates.sh [application] [filter]
+#
+#    defaults:
+#      application=all applications
+#      filter=label=io.ssdt.app[=application]
+#
+# Note: if filter is provided, the first argument is ignored. A complete filter must be supplied.
+#
+APP=${1:+=$1}
+FILTER=${2:-label=io.ssdt.app$APP}
+while read -a line
+do
+   repo=${line[0]}
+   tag=${line[1]}
+   if [[ $repo == docker.ssdt.io* ]]
+   then
+      echo "docker pull ${repo}:${tag}"
+      docker pull ${repo}:${tag}
+   fi
+done <  <(docker images  --filter "$FILTER")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testbench-grid/Dockerfile	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,13 @@
+FROM java:8-jre
+
+MAINTAINER Dave Smith <smith@nwoca.org>
+
+ENV TESTBENCHJAR=/testbench-standalone.jar
+
+ADD http://files.ssdt.io/vaadin-testbench-standalone-4.0.3.jar $TESTBENCHJAR
+
+EXPOSE 4444
+
+WORKDIR /
+
+CMD ["java", "-jar", "testbench-standalone.jar", "-role", "hub" ]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testbench-node/Dockerfile	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,27 @@
+FROM java:8-jre
+
+MAINTAINER Dave Smith <smith@nwoca.org>
+
+ENV TESTBENCHJAR=/testbench-standalone.jar
+
+RUN mkdir /phantom
+
+WORKDIR /phantom
+
+ADD http://files.ssdt.io/phantomjs-2.1.1-linux-x86_64.tar /phantom/phantomjs.tar
+
+RUN 	tar -xf phantomjs.tar \
+		&& 	mv $(find /phantom -name phantomjs) /bin \
+		&& rm -rf /phantom
+
+ADD http://files.ssdt.io/vaadin-testbench-standalone-4.0.3.jar $TESTBENCHJAR
+
+WORKDIR / 
+
+COPY ./docker-entrypoint.sh /
+
+RUN chmod a+x /docker-entrypoint.sh
+
+ENTRYPOINT [ "./docker-entrypoint.sh" ]
+
+CMD [ "node" ]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testbench-node/docker-entrypoint.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,15 @@
+#!/bin/bash
+set -e
+
+case "$1" in
+
+   node)
+     java -jar testbench-standalone.jar -role node -hub http://$HUB_HOST:4444/grid/register -browser "browserName=phantomjs"
+   ;;
+
+  *)
+  exec "$@"
+  ;;
+
+esac
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tomcat/Dockerfile	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,22 @@
+FROM tomcat:8.0.33-jre8
+
+MAINTAINER Dave Smith <smith@nwoca.org>
+
+RUN echo "ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true" | debconf-set-selections \
+	&& echo 'deb http://httpredir.debian.org/debian jessie contrib' > /etc/apt/sources.list.d/jessie-contrib.list \
+    && apt-get update 									\
+    && apt-get install -y ttf-mscorefonts-installer
+
+WORKDIR /usr/local/tomcat
+
+COPY setenv.sh bin/
+COPY tomcat-users.xml server.xml context.xml conf/
+
+RUN rm -rf webapps/docs webapps/ROOT webapps/examples webapps/docs webapps/host-manager \
+	&& chmod +x bin/setenv.sh
+	
+ENV TZ=America/New_York
+
+ENV LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:/usr/lib/x86_64-linux-gnu/
+
+RUN apt-get install -y libtcnative-1
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tomcat/context.xml	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,28 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<Context>
+
+    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
+    <Manager pathname="" />
+
+    <!-- Uncomment this to enable Comet connection tacking (provides events
+         on session expiration as well as webapp lifecycle) -->
+    <!--
+    <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
+    -->
+</Context>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tomcat/server.xml	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,75 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<Server port="8005" shutdown="SHUTDOWN">
+  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
+  <!-- Security listener. Documentation at /docs/config/listeners.html
+  <Listener className="org.apache.catalina.security.SecurityListener" />
+  -->
+  <!--APR library loader. Documentation at /docs/apr.html -->
+  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
+  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
+  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
+  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
+  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
+
+
+  <GlobalNamingResources>
+    <Resource name="UserDatabase" auth="Container"
+              type="org.apache.catalina.UserDatabase"
+              description="User database for tomcat manager app"
+              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
+              pathname="conf/tomcat-users.xml" />
+  </GlobalNamingResources>
+
+  <Service name="Catalina">
+
+    <Executor name="tomcatThreads" 
+		namePrefix="tomcat-exec-"
+        maxThreads="200" 
+		minSpareThreads="1"
+		maxIdleTime="300000"
+		/>
+		
+    <Connector port="8080" protocol="HTTP/1.1"
+               connectionTimeout="20000"
+               redirectPort="8443" 
+			   executor="tomcatThreads"/>
+
+    <Engine name="Catalina" defaultHost="localhost">
+
+      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
+           via a brute-force attack -->
+      <Realm className="org.apache.catalina.realm.LockOutRealm">
+        <!-- This Realm uses the UserDatabase configured in the global JNDI
+             resources under the key "UserDatabase".  Any edits
+             that are performed against this UserDatabase are immediately
+             available for use by the Realm.  -->
+        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+               resourceName="UserDatabase"/>
+      </Realm>
+
+      <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true">
+        <Valve className="org.apache.catalina.valves.AccessLogValve" 
+				directory="logs"
+                prefix="localhost_access_log" suffix=".txt"
+                pattern="%h %l %u %t &quot;%r&quot; %s %b" />
+
+      </Host>
+    </Engine>
+  </Service>
+</Server>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tomcat/setenv.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,14 @@
+#! /bin/sh
+#
+echo "__________________________________________"
+
+export CATALINA_OPTS="$CATALINA_OPTS -XX:+UseG1GC"
+export CATALINA_OPTS="$CATALINA_OPTS -XX:+UseStringDeduplication "
+export CATALINA_OPTS="$CATALINA_OPTS -Djava.security.egd=file:/dev/./urandom"
+export CATALINA_OPTS="$CATALINA_OPTS -Duser.language=en"
+export CATALINA_OPTS="$CATALINA_OPTS -Duser.region=US"
+
+echo "Using CATALINA_OPTS $CATALINA_OPTS"
+echo "Using     JAVA_OPTS $JAVA_OPTS"
+echo "_________________________________________"
+echo ""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tomcat/tomcat-users.xml	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,9 @@
+<?xml version='1.0' encoding='utf-8'?>
+<tomcat-users xmlns="http://tomcat.apache.org/xml"
+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
+              version="1.0">
+  <role rolename="manager-gui"/>
+  <role rolename="manager-jmx"/>
+  <user username="admin" password="99admin00" roles="manager-gui,manager-jmx"/>
+</tomcat-users>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trainingdb-usas/Dockerfile	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,11 @@
+
+FROM docker.ssdt.io/trainingdb
+
+ADD http://files.ssdt.io/usas-training.backup.gz $BACKUP_FILE
+
+RUN chmod a+r $BACKUP_FILE
+
+ENV DB_NAME=usasdb \
+    DB_USER=usas \
+    DB_PASS=usasdefault
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trainingdb-usps/Dockerfile	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,11 @@
+
+FROM docker.ssdt.io/trainingdb
+
+ADD http://files.ssdt.io/usps-training.backup.gz $BACKUP_FILE
+
+RUN chmod a+r $BACKUP_FILE
+
+env DB_NAME=uspsdb \
+    DB_USER=usps \
+    DB_PASS=uspsdefault
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trainingdb/Dockerfile	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,11 @@
+
+FROM docker.ssdt.io/ssdt-postgres:3
+
+MAINTAINER Dave Smith smith@nwoca.org
+
+ENV PGDATA=/var/pgdata/trainingdata \
+    BACKUP_FILE=/training.backup.gz
+
+COPY setupDatabase.sh /docker-entrypoint-initdb.d/setupDatabase.sh
+
+RUN chmod 755 /docker-entrypoint-initdb.d/setupDatabase.sh	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trainingdb/setupDatabase.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+export PGUSER=postgres
+TEST=`psql <<- EOSQL
+   SELECT 1 FROM pg_database WHERE datname='$DB_NAME';
+EOSQL`
+
+if [[ $TEST == "1" ]]; then
+    echo "$DB_NAME exists. continuing startup."
+    # database exists
+    # $? is 0
+    exit 0
+else
+echo "Creating $DB_NAME for $DB_USER"
+psql <<- EOSQL
+   CREATE ROLE $DB_USER WITH LOGIN ENCRYPTED PASSWORD '${DB_PASS}' CREATEDB;
+   CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0 ENCODING 'UTF8';
+   GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;
+EOSQL
+
+echo "Restoring backup file"
+
+gunzip -f $BACKUP_FILE -c | psql
+
+fi
+
+echo ""
+echo "$DB_NAME database created"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/update.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,4 @@
+#!/bin/bash
+SSDT_HOME="$( dirname "${BASH_SOURCE[0]}")"
+docker pull docker.ssdt.io/ssdt-utils
+docker run -it -v $SSDT_HOME:/ssdt --rm docker.ssdt.io/ssdt-utils update
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utils/Dockerfile	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,21 @@
+FROM ubuntu:latest
+
+MAINTAINER Dave Smith smith@nwoca.org
+
+ENV SSDT_HOME=/ssdt \
+    SSDT_DOCKER=http://hg.ssdt-ohio.org/public/ssdt-docker/
+
+RUN apt-get update -y
+
+RUN apt-get install -y mercurial \
+    && apt-get install -y curl \
+    && apt-get install -y vim \
+    && apt-get install -y nano \
+    && apt-get install -y telnet
+
+COPY ./docker-entrypoint.sh /
+
+RUN chmod a+x ./docker-entrypoint.sh
+
+ENTRYPOINT ["/docker-entrypoint.sh"]
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utils/docker-entrypoint.sh	Thu Sep 22 01:49:20 2016 +0100
@@ -0,0 +1,21 @@
+#!/bin/bash
+set -e
+
+if [ "$1" = 'update' ]; then
+  mkdir -p $SSDT_HOME
+  cd $SSDT_HOME
+  if [ ! -d ".hg" ]; then
+      echo "cloning repository $SSDT_DOCKER  to $SSDT_HOME"
+      hg init
+  fi
+  branch=${2:-production}
+  echo "pulling updates from $SSDT_DOCKER ($branch)"
+  hg pull -y $SSDT_DOCKER
+  hg revert -a
+  hg update $branch
+
+else
+
+  exec "$@"
+
+fi