From 17dc15185dc4e32fe0b1371f6c136f45093dad80 Mon Sep 17 00:00:00 2001 From: Jim Van Fleet Date: Fri, 2 Sep 2016 14:10:28 -0400 Subject: [PATCH] Taking cues from COmanage script --- Dockerfile | 6 +- container_files/bin/check.sh | 5 + container_files/{ => bin}/configure.sh | 0 .../{container_start.sh => bin/main.sh} | 6 +- container_files/bin/start.sh | 30 ++++ container_files/wait-for-it/LICENSE | 20 +++ container_files/wait-for-it/README.md | 59 +++++++ container_files/wait-for-it/wait-for-it.sh | 161 ++++++++++++++++++ 8 files changed, 281 insertions(+), 6 deletions(-) create mode 100755 container_files/bin/check.sh rename container_files/{ => bin}/configure.sh (100%) rename container_files/{container_start.sh => bin/main.sh} (62%) create mode 100755 container_files/bin/start.sh create mode 100644 container_files/wait-for-it/LICENSE create mode 100644 container_files/wait-for-it/README.md create mode 100755 container_files/wait-for-it/wait-for-it.sh diff --git a/Dockerfile b/Dockerfile index 79dcf569..914ba0c0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM bigfleet/shibboleth_sp # Define args and set a default value ARG maintainer=tier -ARG imagename=shibboleth_sp +ARG imagename=grouper ARG version=2.3.0 MAINTAINER $maintainer @@ -30,7 +30,7 @@ RUN mkdir -p /opt/grouper/$VERSION \ && yum clean all # Add starters and installers -ADD ./container_files /root +ADD ./container_files /opt COPY grouper.installer.properties /opt/grouper/$version # The installer creates a HSQL DB which we ignore later @@ -41,4 +41,4 @@ VOLUME /opt/grouper/2.3.0/apache-tomcat-$TOMCAT_VERSION/logs EXPOSE 8080 8009 8005 -CMD ["/root/container_start.sh"] \ No newline at end of file +CMD ["/opt/bin/container_start.sh"] \ No newline at end of file diff --git a/container_files/bin/check.sh b/container_files/bin/check.sh new file mode 100755 index 00000000..bf27d499 --- /dev/null +++ b/container_files/bin/check.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +log="/tmp/shib.log" + +cd /opt/grouper/2.3.0/grouper.apiBinary-2.3.0 && GROUPER_HOME=/opt/grouper/2.3.0/grouper.apiBinary-2.3.0 bin/gsh.sh -check \ No newline at end of file diff --git a/container_files/configure.sh b/container_files/bin/configure.sh similarity index 100% rename from container_files/configure.sh rename to container_files/bin/configure.sh diff --git a/container_files/container_start.sh b/container_files/bin/main.sh similarity index 62% rename from container_files/container_start.sh rename to container_files/bin/main.sh index 0910a480..01dfa7dd 100755 --- a/container_files/container_start.sh +++ b/container_files/bin/main.sh @@ -10,9 +10,9 @@ if [ -e "/tmp/firsttimerunning" ]; then set -e - /root/configure.sh - - cd /opt/grouper/2.3.0/grouper.apiBinary-2.3.0 && GROUPER_HOME=/opt/grouper/2.3.0/grouper.apiBinary-2.3.0 bin/gsh.sh -check + /opt/bin/configure.sh + + /opt/bin/check.sh rm -f /tmp/firsttimerunning else diff --git a/container_files/bin/start.sh b/container_files/bin/start.sh new file mode 100755 index 00000000..13aa9cde --- /dev/null +++ b/container_files/bin/start.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +log="/tmp/start.log" + +if [ -z ${COMPOSE+x} ] +then + echo "Not composed so not waiting for MariaDB: " > $log + /opt/bin/main.sh + laststatus="$?" + echo "Not composed status: $laststatus" + if [ "$laststatus" != "0" ]; then + echo "Not composed non-zero exit status: $laststatus" >> $log + echo "Not composed non-zero exit status: $laststatus" + exit 1 + else + exit 0 + fi +else + echo "Composed so waiting for MariaDB: " > $log + /opt/wait-for-it/wait-for-it.sh $MYSQL_HOST:3306 -t 60 --strict -- /opt/bin/main.sh + laststatus="$?" + echo "Composed status: $laststatus" + if [ "$laststatus" != "0" ]; then + echo "Composed non-zero exit status: $laststatus" >> $log + echo "Composed non-zero exit status: $laststatus" + exit 1 + else + exit 0 + fi +fi diff --git a/container_files/wait-for-it/LICENSE b/container_files/wait-for-it/LICENSE new file mode 100644 index 00000000..bd18d0c4 --- /dev/null +++ b/container_files/wait-for-it/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) +Copyright (c) 2016 Giles Hall + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/container_files/wait-for-it/README.md b/container_files/wait-for-it/README.md new file mode 100644 index 00000000..3a65c3d7 --- /dev/null +++ b/container_files/wait-for-it/README.md @@ -0,0 +1,59 @@ +`wait-for-it.sh` is a pure bash script that will wait on the availability of a host and TCP port. It is useful for synchronizing the spin-up of interdependent services, such as linked docker containers. Since it is a pure bash script, it does not have any external dependencies. + +## Usage + +``` +wait-for-it.sh host:port [-s] [-t timeout] [-- command args] +-h HOST | --host=HOST Host or IP under test +-p PORT | --port=PORT TCP port under test + Alternatively, you specify the host and port as host:port +-s | --strict Only execute subcommand if the test succeeds +-q | --quiet Don't output any status messages +-t TIMEOUT | --timeout=TIMEOUT + Timeout in seconds, zero for no timeout +-- COMMAND ARGS Execute command with args after the test finishes +``` + +## Examples + +For example, let's test to see if we can access port 80 on www.google.com, and if it is available, echo the message `google is up`. + +``` +$ ./wait-for-it.sh www.google.com:80 -- echo "google is up" +wait-for-it.sh: waiting 15 seconds for www.google.com:80 +wait-for-it.sh: www.google.com:80 is available after 0 seconds +google is up +``` + +You can set your own timeout with the `-t` or `--timeout=` option. Setting the timeout value to 0 will disable the timeout: + +``` +$ ./wait-for-it.sh -t 0 www.google.com:80 -- echo "google is up" +wait-for-it.sh: waiting for www.google.com:80 without a timeout +wait-for-it.sh: www.google.com:80 is available after 0 seconds +google is up +``` + +The subcommand will be executed regardless if the service is up or not. If you wish to execute the subcommand only if the service is up, add the `--strict` argument. In this example, we will test port 81 on www.google.com which will fail: + +``` +$ ./wait-for-it.sh www.google.com:81 --timeout=1 --strict -- echo "google is up" +wait-for-it.sh: waiting 1 seconds for www.google.com:81 +wait-for-it.sh: timeout occurred after waiting 1 seconds for www.google.com:81 +wait-for-it.sh: strict mode, refusing to execute subprocess +``` + +If you don't want to execute a subcommand, leave off the `--` argument. This way, you can test the exit condition of `wait-for-it.sh` in your own scripts, and determine how to proceed: + +``` +$ ./wait-for-it.sh www.google.com:80 +wait-for-it.sh: waiting 15 seconds for www.google.com:80 +wait-for-it.sh: www.google.com:80 is available after 0 seconds +$ echo $? +0 +$ ./wait-for-it.sh www.google.com:81 +wait-for-it.sh: waiting 15 seconds for www.google.com:81 +wait-for-it.sh: timeout occurred after waiting 15 seconds for www.google.com:81 +$ echo $? +124 +``` diff --git a/container_files/wait-for-it/wait-for-it.sh b/container_files/wait-for-it/wait-for-it.sh new file mode 100755 index 00000000..eca6c3b9 --- /dev/null +++ b/container_files/wait-for-it/wait-for-it.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env bash +# Use this script to test if a given TCP host/port are available + +cmdname=$(basename $0) + +echoerr() { if [[ $QUIET -ne 1 ]]; then echo "$@" 1>&2; fi } + +usage() +{ + cat << USAGE >&2 +Usage: + $cmdname host:port [-s] [-t timeout] [-- command args] + -h HOST | --host=HOST Host or IP under test + -p PORT | --port=PORT TCP port under test + Alternatively, you specify the host and port as host:port + -s | --strict Only execute subcommand if the test succeeds + -q | --quiet Don't output any status messages + -t TIMEOUT | --timeout=TIMEOUT + Timeout in seconds, zero for no timeout + -- COMMAND ARGS Execute command with args after the test finishes +USAGE + exit 1 +} + +wait_for() +{ + if [[ $TIMEOUT -gt 0 ]]; then + echoerr "$cmdname: waiting $TIMEOUT seconds for $HOST:$PORT" + else + echoerr "$cmdname: waiting for $HOST:$PORT without a timeout" + fi + start_ts=$(date +%s) + while : + do + (echo > /dev/tcp/$HOST/$PORT) >/dev/null 2>&1 + result=$? + if [[ $result -eq 0 ]]; then + end_ts=$(date +%s) + echoerr "$cmdname: $HOST:$PORT is available after $((end_ts - start_ts)) seconds" + break + fi + sleep 1 + done + return $result +} + +wait_for_wrapper() +{ + # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 + if [[ $QUIET -eq 1 ]]; then + timeout $TIMEOUT $0 --quiet --child --host=$HOST --port=$PORT --timeout=$TIMEOUT & + else + timeout $TIMEOUT $0 --child --host=$HOST --port=$PORT --timeout=$TIMEOUT & + fi + PID=$! + trap "kill -INT -$PID" INT + wait $PID + RESULT=$? + if [[ $RESULT -ne 0 ]]; then + echoerr "$cmdname: timeout occurred after waiting $TIMEOUT seconds for $HOST:$PORT" + fi + return $RESULT +} + +# process arguments +while [[ $# -gt 0 ]] +do + case "$1" in + *:* ) + hostport=(${1//:/ }) + HOST=${hostport[0]} + PORT=${hostport[1]} + shift 1 + ;; + --child) + CHILD=1 + shift 1 + ;; + -q | --quiet) + QUIET=1 + shift 1 + ;; + -s | --strict) + STRICT=1 + shift 1 + ;; + -h) + HOST="$2" + if [[ $HOST == "" ]]; then break; fi + shift 2 + ;; + --host=*) + HOST="${1#*=}" + shift 1 + ;; + -p) + PORT="$2" + if [[ $PORT == "" ]]; then break; fi + shift 2 + ;; + --port=*) + PORT="${1#*=}" + shift 1 + ;; + -t) + TIMEOUT="$2" + if [[ $TIMEOUT == "" ]]; then break; fi + shift 2 + ;; + --timeout=*) + TIMEOUT="${1#*=}" + shift 1 + ;; + --) + shift + CLI="$@" + break + ;; + --help) + usage + ;; + *) + echoerr "Unknown argument: $1" + usage + ;; + esac +done + +if [[ "$HOST" == "" || "$PORT" == "" ]]; then + echoerr "Error: you need to provide a host and port to test." + usage +fi + +TIMEOUT=${TIMEOUT:-15} +STRICT=${STRICT:-0} +CHILD=${CHILD:-0} +QUIET=${QUIET:-0} + +if [[ $CHILD -gt 0 ]]; then + wait_for + RESULT=$? + exit $RESULT +else + if [[ $TIMEOUT -gt 0 ]]; then + wait_for_wrapper + RESULT=$? + else + wait_for + RESULT=$? + fi +fi + +if [[ $CLI != "" ]]; then + if [[ $RESULT -ne 0 && $STRICT -eq 1 ]]; then + echoerr "$cmdname: strict mode, refusing to execute subprocess" + exit $RESULT + fi + exec $CLI +else + exit $RESULT +fi