diff --git a/commands b/commands index 593186c..17b365b 100755 --- a/commands +++ b/commands @@ -35,7 +35,8 @@ case "$1" in touch "$LINKS_FILE" dokku_log_info1 "Starting container" - ID=$(docker run --name "dokku.redis.$SERVICE" -v "$SERVICE_ROOT/data:/data" -v "$SERVICE_ROOT/config:/usr/local/etc/redis" -d "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION") + SERVICE_NAME=$(get_service_name "$SERVICE") + ID=$(docker run --name "$SERVICE_NAME" -v "$SERVICE_ROOT/data:/data" -v "$SERVICE_ROOT/config:/usr/local/etc/redis" -d --restart always "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION") echo "$ID" > "$SERVICE_ROOT/ID" dokku_log_verbose_quiet "Waiting for container to be ready" @@ -73,10 +74,7 @@ case "$1" in dokku_log_verbose_quiet "Deleting container data" docker exec -it "$ID" chmod -R 777 /data - dokku_log_verbose_quiet "Stopping container" - docker stop "$ID" > /dev/null - docker kill "$ID" > /dev/null - sleep 1 + service_stop "$SERVICE" dokku_log_verbose_quiet "Removing container" docker rm -v "$ID" > /dev/null @@ -144,11 +142,8 @@ case "$1" in $PLUGIN_COMMAND_PREFIX:restart) [[ -z $2 ]] && dokku_log_fail "Please specify a name for the service" verify_service_name "$2" - SERVICE="$2"; SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" - - ID=$(cat "$SERVICE_ROOT/ID") - - docker restart --time=10 "$ID" + service_stop "$2" + service_start "$2" dokku_log_info1 "Please call dokku ps:restart on all linked apps" ;; @@ -183,7 +178,7 @@ case "$1" in $PLUGIN_COMMAND_PREFIX:expose) [[ -z $2 ]] && dokku_log_fail "Please specify a name for the service" verify_service_name "$2" - service_port_expose "$2" + service_port_expose "$2" "${@:3}" ;; $PLUGIN_COMMAND_PREFIX:unexpose) @@ -207,8 +202,8 @@ case "$1" in $PLUGIN_COMMAND_PREFIX:info , Print the connection information $PLUGIN_COMMAND_PREFIX:list, List all $PLUGIN_SERVICE services $PLUGIN_COMMAND_PREFIX:clone , NOT IMPLEMENTED - $PLUGIN_COMMAND_PREFIX:expose , NOT IMPLEMENTED - $PLUGIN_COMMAND_PREFIX:unexpose , NOT IMPLEMENTED + $PLUGIN_COMMAND_PREFIX:expose [port], Expose a $PLUGIN_SERVICE service on custom port if provided (random port otherwise) + $PLUGIN_COMMAND_PREFIX:unexpose , Unexpose a previously exposed $PLUGIN_SERVICE service EOF ;; diff --git a/config b/config old mode 100644 new mode 100755 index 705380c..ec5ab13 --- a/config +++ b/config @@ -5,7 +5,7 @@ export REDIS_ROOT=/var/lib/dokku/services/redis export PLUGIN_COMMAND_PREFIX="redis" export PLUGIN_DATA_ROOT=$REDIS_ROOT -export PLUGIN_DATASTORE_PORT=6379 +export PLUGIN_DATASTORE_PORTS=(6379) export PLUGIN_DEFAULT_ALIAS="REDIS" export PLUGIN_IMAGE=$REDIS_IMAGE export PLUGIN_IMAGE_VERSION=$REDIS_IMAGE_VERSION diff --git a/functions b/functions index 653a0ba..d33c47a 100755 --- a/functions +++ b/functions @@ -2,19 +2,21 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x source "$(dirname "$0")/config" -get_random_port() { - local port=$RANDOM - local quit=0 - - while [ "$quit" -ne 1 ]; do - netstat -a | grep $port >> /dev/null - if [ $? -gt 0 ]; then - quit=1 - else - port=$((port + 1)) - fi +get_random_ports() { + local iterations="${1:-1}" + for (( i=0; i < iterations; i++ )); do + local port=$RANDOM + local quit=0 + while [ "$quit" -ne 1 ]; do + netstat -an | grep $port > /dev/null + if [ $? -gt 0 ]; then + quit=1 + else + port=$((port + 1)) + fi + done + echo $port done - echo $port } get_container_ip() { @@ -54,11 +56,19 @@ service_list() { else dokku_log_info1_quiet "$PLUGIN_SERVICE services:" for SERVICE in $SERVICES; do - dokku_log_verbose "$SERVICE $(service_status $SERVICE)" + dokku_log_verbose "$SERVICE $(service_status "$SERVICE")$(service_exposed_ports "$SERVICE")" done fi } +service_exposed_ports() { + local SERVICE="$1" + local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" + local PORT_FILE="$SERVICE_ROOT/PORT" + [[ ! -f $PORT_FILE ]] && return 0 + printf ", exposed port(s): %s" "$(cat "$PORT_FILE")" +} + service_link() { local APP="$2" local SERVICE="$1" @@ -112,14 +122,14 @@ service_status() { } service_port_expose() { - service_port_unpause "$1" "true" + service_port_unpause "$1" "true" "${@:2}" } service_port_pause() { local SERVICE="$1" local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" + local EXPOSED_NAME="$(get_service_name "$SERVICE").ambassador" local PORT_FILE="$SERVICE_ROOT/PORT" - local DESTINATION_FILE="$SERVICE_ROOT/IPTABLES_DESTINATION" local LOG_FAIL="$2" if [[ "$LOG_FAIL" == "true" ]]; then @@ -128,56 +138,67 @@ service_port_pause() { [[ ! -f "$PORT_FILE" ]] && return 0 fi - local ID=$(cat "$SERVICE_ROOT/ID") - local IP=$(get_container_ip "$ID") - local PORT=$(cat "$PORT_FILE") - local DESTINATION=$(cat "$DESTINATION_FILE") - - sudo /sbin/iptables -t nat -D DOCKER -p tcp --dport "$PORT" -j DNAT --to-destination "$DESTINATION" + docker stop "$EXPOSED_NAME" > /dev/null + docker rm "$EXPOSED_NAME" > /dev/null + if [[ "$LOG_FAIL" == "true" ]]; then + dokku_log_info1 "Service $SERVICE unexposed" + fi } service_port_unexpose() { - service_port_pause "$1" "true" + local SERVICE="$1" + local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" + local PORT_FILE="$SERVICE_ROOT/PORT" + service_port_pause "$SERVICE" "true" rm -rf "$PORT_FILE" } service_port_unpause() { local SERVICE="$1" local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" + local SERVICE_NAME=$(get_service_name "$SERVICE") + local EXPOSED_NAME="${SERVICE_NAME}.ambassador" local PORT_FILE="$SERVICE_ROOT/PORT" - local DESTINATION_FILE="$SERVICE_ROOT/IPTABLES_DESTINATION" local LOG_FAIL="$2" - local PORT=$(get_random_port) + local PORTS=(${@:3}) + PORTS=(${PORTS[@]:-$(get_random_ports ${#PLUGIN_DATASTORE_PORTS[@]})}) local ID=$(cat "$SERVICE_ROOT/ID") - local IP=$(get_container_ip "$ID") - local DESTINATION="$IP:$PLUGIN_DATASTORE_PORT" + + [[ "${#PORTS[@]}" != "${#PLUGIN_DATASTORE_PORTS[@]}" ]] && dokku_log_fail "${#PLUGIN_DATASTORE_PORTS[@]} ports to be exposed need to be provided" if [[ "$LOG_FAIL" == "true" ]]; then - [[ -f "$PORT_FILE" ]] && PORT=$(cat "$PORT_FILE") && dokku_log_fail "Service $SERVICE already exposed on port $PORT" + [[ -f "$PORT_FILE" ]] && PORTS=($(cat "$PORT_FILE")) && dokku_log_fail "Service $SERVICE already exposed on port(s) ${PORTS[*]}" else [[ ! -f "$PORT_FILE" ]] && return 0 - PORT=$(cat "$PORT_FILE") && sudo /sbin/iptables -t nat -D DOCKER -p tcp --dport "$PORT" -j DNAT --to-destination "$DESTINATION" + PORTS=($(cat "$PORT_FILE")) fi - echo "$PORT" > "$PORT_FILE" - echo "$DESTINATION" > "$DESTINATION_FILE" + echo "${PORTS[@]}" > "$PORT_FILE" - echo "$DESTINATION" - - sudo /sbin/iptables -t nat -A DOCKER -p tcp --dport "$PORT" -j DNAT --to-destination "$DESTINATION" + docker run -d --link "$SERVICE_NAME:redis" --name "$EXPOSED_NAME" $(docker_ports_options "${PORTS[@]}") --restart always svendowideit/ambassador > /dev/null if [[ "$LOG_FAIL" == "true" ]]; then - dokku_log_info1 "Service $SERVICE exposed on port $PORT" + dokku_log_info1 "Service $SERVICE exposed on port(s) ${PORTS[*]}" fi } +docker_ports_options() { + local PORTS=("$@") + for (( i=0; i < ${#PLUGIN_DATASTORE_PORTS[@]}; i++ )); do + echo -n "-p ${PORTS[i]}:${PLUGIN_DATASTORE_PORTS[i]} " + done +} + service_start() { local SERVICE="$1" local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" + local SERVICE_NAME=$(get_service_name "$SERVICE") + local ID=$(docker ps -f status=running | grep "$SERVICE_NAME" | awk '{print $1}') || true + [[ -n $ID ]] && dokku_log_fail "Service is already started" dokku_log_verbose_quiet "Starting container" - if [[ -f "$SERVICE_ROOT/ID" ]] && docker ps -aq --no-trunc | grep -q $(cat "$SERVICE_ROOT/ID"); then - ID=$(cat "$SERVICE_ROOT/ID") - docker start "$ID" > /dev/null + local PREVIOUS_ID=$(docker ps -f status=exited | grep "$SERVICE_NAME" | awk '{print $1}') || true + if [[ -n $PREVIOUS_ID ]]; then + docker start "$PREVIOUS_ID" > /dev/null service_port_unpause "$SERVICE" dokku_log_info2 "Container started" else @@ -188,11 +209,13 @@ service_start() { service_stop() { local SERVICE="$1" local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE"; + local SERVICE_NAME=$(get_service_name "$SERVICE") + local ID=$(docker ps -f status=running | grep "$SERVICE_NAME" | awk '{print $1}') || true + [[ -z $ID ]] && dokku_log_fail "Service is already stopped" - if [[ -f "$SERVICE_ROOT/ID" ]] && docker ps -aq --no-trunc | grep -q $(cat "$SERVICE_ROOT/ID"); then + if [[ -n $ID ]]; then dokku_log_verbose_quiet "Stopping container" - ID=$(cat "$SERVICE_ROOT/ID") - docker stop "$ID" > /dev/null + docker stop "$SERVICE_NAME" > /dev/null service_port_pause "$SERVICE" dokku_log_info2 "Container stopped" else @@ -221,7 +244,7 @@ service_url() { local ID="$(cat "$SERVICE_ROOT/ID")" local IP="$(get_container_ip "$ID")" - echo "$PLUGIN_SCHEME://$IP:$PLUGIN_DATASTORE_PORT/0" + echo "$PLUGIN_SCHEME://$IP:${PLUGIN_DATASTORE_PORTS[0]}/0" } is_container_status () { @@ -235,3 +258,8 @@ is_container_status () { return 1 fi } + +get_service_name() { + local SERVICE="$1" + echo "dokku.${PLUGIN_COMMAND_PREFIX}.$SERVICE" +}