From ac50d9c37c0524386f9bfd2c1d0d097025026b35 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 31 Aug 2015 15:29:23 -0400 Subject: [PATCH 01/16] first - broken - pass at start/stop commands and working expose/expose commands note that at the moment the iptables calls complete successfully but the container isn't actually exposed. We'll probably need to use the ambassador pattern to do this properly. --- commands | 37 +++++++++-------------- functions | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ install | 12 ++++++++ 3 files changed, 115 insertions(+), 23 deletions(-) diff --git a/commands b/commands index beeb65a..12f7c31 100755 --- a/commands +++ b/commands @@ -129,6 +129,18 @@ case "$1" in service_logs "$2" "$3" ;; + $PLUGIN_COMMAND_PREFIX:start) + [[ -z $2 ]] && dokku_log_fail "Please specify a name for the service" + verify_service_name "$2" + service_start "$2" + ;; + + $PLUGIN_COMMAND_PREFIX:stop) + [[ -z $2 ]] && dokku_log_fail "Please specify a name for the service" + verify_service_name "$2" + service_stop "$2" + ;; + $PLUGIN_COMMAND_PREFIX:restart) [[ -z $2 ]] && dokku_log_fail "Please specify a name for the service" verify_service_name "$2" @@ -171,34 +183,13 @@ case "$1" in $PLUGIN_COMMAND_PREFIX:expose) [[ -z $2 ]] && dokku_log_fail "Please specify a name for the service" verify_service_name "$2" - SERVICE="$2"; SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE"; PORT_FILE="$SERVICE_ROOT/PORT"; DESTINATION_FILE="$SERVICE_ROOT/IPTABLES_DESTINATION" - - [[ -f "$PORT_FILE" ]] && PORT=$(cat "$PORT_FILE") && dokku_log_fail "Service $SERVICE already exposed on port $PORT" - - ID=$(cat "$SERVICE_ROOT/ID") - IP=$(get_container_ip "$ID") - PORT=$(get_random_port) - echo "$PORT" > "$PORT_FILE" - echo "$IP:$PLUGIN_DATASTORE_PORT" > "$DESTINATION_FILE" - - iptables -t nat -A DOCKER -p tcp --dport "$PORT" -j DNAT --to-destination "$IP:$PLUGIN_DATASTORE_PORT" - dokku_log_info1 "Service $SERVICE exposed on port $PORT" + service_port_expose "$2" ;; $PLUGIN_COMMAND_PREFIX:unexpose) [[ -z $2 ]] && dokku_log_fail "Please specify a name for the service" verify_service_name "$2" - SERVICE="$2"; SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE"; PORT_FILE="$SERVICE_ROOT/PORT"; DESTINATION_FILE="$SERVICE_ROOT/IPTABLES_DESTINATION" - - [[ ! -f "$PORT_FILE" ]] && dokku_log_fail "Service not exposed" - - ID=$(cat "$SERVICE_ROOT/ID") - IP=$(get_container_ip "$ID") - PORT=$(cat "$PORT_FILE") - DESTINATION=$(cat "$DESTINATION_FILE") - - iptables -t nat -D DOCKER -p tcp --dport "$PORT" -j DNAT --to-destination "$DESTINATION" - rm -rf "$PORT_FILE" + service_port_unexpose "$2" ;; help) diff --git a/functions b/functions index abbc6d1..653a0ba 100755 --- a/functions +++ b/functions @@ -111,6 +111,95 @@ service_status() { echo "(stopped)" && return 0 } +service_port_expose() { + service_port_unpause "$1" "true" +} + +service_port_pause() { + local SERVICE="$1" + local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" + local PORT_FILE="$SERVICE_ROOT/PORT" + local DESTINATION_FILE="$SERVICE_ROOT/IPTABLES_DESTINATION" + local LOG_FAIL="$2" + + if [[ "$LOG_FAIL" == "true" ]]; then + [[ ! -f "$PORT_FILE" ]] && dokku_log_fail "Service not exposed" + else + [[ ! -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" +} + +service_port_unexpose() { + service_port_pause "$1" "true" + rm -rf "$PORT_FILE" +} + +service_port_unpause() { + local SERVICE="$1" + local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" + local PORT_FILE="$SERVICE_ROOT/PORT" + local DESTINATION_FILE="$SERVICE_ROOT/IPTABLES_DESTINATION" + local LOG_FAIL="$2" + local PORT=$(get_random_port) + local ID=$(cat "$SERVICE_ROOT/ID") + local IP=$(get_container_ip "$ID") + local DESTINATION="$IP:$PLUGIN_DATASTORE_PORT" + + if [[ "$LOG_FAIL" == "true" ]]; then + [[ -f "$PORT_FILE" ]] && PORT=$(cat "$PORT_FILE") && dokku_log_fail "Service $SERVICE already exposed on port $PORT" + 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" + fi + + echo "$PORT" > "$PORT_FILE" + echo "$DESTINATION" > "$DESTINATION_FILE" + + echo "$DESTINATION" + + sudo /sbin/iptables -t nat -A DOCKER -p tcp --dport "$PORT" -j DNAT --to-destination "$DESTINATION" + if [[ "$LOG_FAIL" == "true" ]]; then + dokku_log_info1 "Service $SERVICE exposed on port $PORT" + fi +} + +service_start() { + local SERVICE="$1" + local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" + + 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 + service_port_unpause "$SERVICE" + dokku_log_info2 "Container started" + else + dokku_log_verbose_quiet "No container exists for $SERVICE" + fi +} + +service_stop() { + local SERVICE="$1" + local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE"; + + if [[ -f "$SERVICE_ROOT/ID" ]] && docker ps -aq --no-trunc | grep -q $(cat "$SERVICE_ROOT/ID"); then + dokku_log_verbose_quiet "Stopping container" + ID=$(cat "$SERVICE_ROOT/ID") + docker stop "$ID" > /dev/null + service_port_pause "$SERVICE" + dokku_log_info2 "Container stopped" + else + dokku_log_verbose_quiet "No container exists for $SERVICE" + fi +} + service_unlink() { local APP="$2" local SERVICE="$1" diff --git a/install b/install index 91a71d1..5b52609 100755 --- a/install +++ b/install @@ -8,3 +8,15 @@ fi mkdir -p $PLUGIN_DATA_ROOT || echo "Failed to create $PLUGIN_SERVICE directory" chown dokku:dokku $PLUGIN_DATA_ROOT + +case "$DOKKU_DISTRO" in + ubuntu) + echo "%dokku ALL=(ALL) NOPASSWD:/sbin/iptables -t nat -A DOCKER -p tcp *, /sbin/iptables -t nat -D DOCKER -p tcp *" > /etc/sudoers.d/dokku-redis + ;; + + opensuse) + echo "%dokku ALL=(ALL) NOPASSWD:/sbin/iptables -t nat -A DOCKER -p tcp *, /sbin/iptables -t nat -D DOCKER -p tcp *" > /etc/sudoers.d/dokku-redis + ;; +esac + +chmod 0440 /etc/sudoers.d/dokku-redis From b2051f86faaf5a2858744c427d5ca2c4dab41b8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Guitaut?= Date: Tue, 1 Sep 2015 23:25:14 +0200 Subject: [PATCH 02/16] Use $PLUGIN_PATH instead of dirname --- commands | 2 +- docker-args | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/commands b/commands index 12f7c31..593186c 100755 --- a/commands +++ b/commands @@ -1,6 +1,6 @@ #!/usr/bin/env bash set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x -source "$(dirname "$0")/../common/functions" +source "$PLUGIN_PATH/common/functions" source "$(dirname "$0")/functions" source "$(dirname "$0")/config" diff --git a/docker-args b/docker-args index 9cf22af..ec4ba7e 100755 --- a/docker-args +++ b/docker-args @@ -1,6 +1,6 @@ #!/usr/bin/env bash set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x -source "$(dirname "$0")/../common/functions" +source "$PLUGIN_PATH/common/functions" source "$(dirname "$0")/functions" source "$(dirname "$0")/config" From 16fb91cf16b35564fefa9aa9aae6839f86caf6ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Guitaut?= Date: Tue, 1 Sep 2015 23:58:04 +0200 Subject: [PATCH 03/16] Enable working expose/unexpose commands `expose` and `unexpose` commands are now fully functionnal using the ambassador pattern. This has the advantage to be a 100% docker solution and to not have to restart the service container. Multiple ports are exposed when service specify them. `start` and `stop` commands have been made more robust. When calling `start` or `stop` on an already started (or stopped) service, an error will be printed out instead of issuing failing commands. Exposed services will still be exposed after a `restart`. Also the service containers (and ambassador containers) will start automatically when docker boot up. --- commands | 21 ++++------- config | 2 +- functions | 110 ++++++++++++++++++++++++++++++++++-------------------- 3 files changed, 78 insertions(+), 55 deletions(-) mode change 100644 => 100755 config 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" +} From 70d86b17f5b74edf1674f3f4baf5dc956c4bf1c0 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 6 Sep 2015 18:01:41 -0400 Subject: [PATCH 04/16] Remove unused iptables sudoers config --- install | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/install b/install index 5b52609..91a71d1 100755 --- a/install +++ b/install @@ -8,15 +8,3 @@ fi mkdir -p $PLUGIN_DATA_ROOT || echo "Failed to create $PLUGIN_SERVICE directory" chown dokku:dokku $PLUGIN_DATA_ROOT - -case "$DOKKU_DISTRO" in - ubuntu) - echo "%dokku ALL=(ALL) NOPASSWD:/sbin/iptables -t nat -A DOCKER -p tcp *, /sbin/iptables -t nat -D DOCKER -p tcp *" > /etc/sudoers.d/dokku-redis - ;; - - opensuse) - echo "%dokku ALL=(ALL) NOPASSWD:/sbin/iptables -t nat -A DOCKER -p tcp *, /sbin/iptables -t nat -D DOCKER -p tcp *" > /etc/sudoers.d/dokku-redis - ;; -esac - -chmod 0440 /etc/sudoers.d/dokku-redis From cf9b8a9a5910212cc05198a908bc7ec93bc3542a Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 6 Sep 2015 18:08:02 -0400 Subject: [PATCH 05/16] Add expose/unexpose to readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f7d0444..c6ffc24 100644 --- a/README.md +++ b/README.md @@ -25,14 +25,14 @@ redis:connect Connect via redis-cli to a redis service redis:create Create a redis service redis:destroy Delete the service and stop its container if there are no links left redis:export NOT IMPLEMENTED -redis:expose NOT IMPLEMENTED +redis:expose [port] Expose a redis service on custom port if provided (random port otherwise) redis:import NOT IMPLEMENTED redis:info Print the connection information redis:link Link the redis service to the app redis:list List all redis services redis:logs [-t] Print the most recent log(s) for this service redis:restart Graceful shutdown and restart of the service container -redis:unexpose NOT IMPLEMENTED +redis:unexpose Unexpose a previously exposed redis service redis:unlink Unlink the redis service from the app ``` From a311957af39ddee9c05d374cb86cef30d5f85454 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 6 Sep 2015 18:08:24 -0400 Subject: [PATCH 06/16] Update docs on start/stop/restart commands --- README.md | 4 +++- commands | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c6ffc24..1ec6ce0 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,9 @@ redis:info Print the connection information redis:link Link the redis service to the app redis:list List all redis services redis:logs [-t] Print the most recent log(s) for this service -redis:restart Graceful shutdown and restart of the service container +redis:restart Graceful shutdown and restart of the redis service container +redis:start Start a previously stopped redis service +redis:stop Stop a running redis service redis:unexpose Unexpose a previously exposed redis service redis:unlink Unlink the redis service from the app ``` diff --git a/commands b/commands index 17b365b..1a97cf2 100755 --- a/commands +++ b/commands @@ -198,12 +198,14 @@ case "$1" in $PLUGIN_COMMAND_PREFIX:import , NOT IMPLEMENTED $PLUGIN_COMMAND_PREFIX:connect , Connect via redis-cli to a $PLUGIN_SERVICE service $PLUGIN_COMMAND_PREFIX:logs [-t], Print the most recent log(s) for this service - $PLUGIN_COMMAND_PREFIX:restart , Graceful shutdown and restart of the service container + $PLUGIN_COMMAND_PREFIX:restart , Graceful shutdown and restart of the $PLUGIN_SERVICE service container $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 [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 + $PLUGIN_COMMAND_PREFIX:start , Start a previously stopped $PLUGIN_SERVICE service + $PLUGIN_COMMAND_PREFIX:stop , Stop a running $PLUGIN_SERVICE service EOF ;; From 418c7bfc66b8648007300d2ae83b4f5ad04d44fb Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 6 Sep 2015 18:10:08 -0400 Subject: [PATCH 07/16] Add docker kill statement back --- commands | 2 ++ 1 file changed, 2 insertions(+) diff --git a/commands b/commands index 1a97cf2..a08363b 100755 --- a/commands +++ b/commands @@ -75,6 +75,8 @@ case "$1" in docker exec -it "$ID" chmod -R 777 /data service_stop "$SERVICE" + dokku_log_verbose_quiet "Killing container" + docker kill "$ID" > /dev/null dokku_log_verbose_quiet "Removing container" docker rm -v "$ID" > /dev/null From 18ad9bb4411ea18b432b5df53de6f1670c213566 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 6 Sep 2015 18:14:28 -0400 Subject: [PATCH 08/16] Add sleep before removing container --- commands | 1 + 1 file changed, 1 insertion(+) diff --git a/commands b/commands index a08363b..2a0b812 100755 --- a/commands +++ b/commands @@ -77,6 +77,7 @@ case "$1" in service_stop "$SERVICE" dokku_log_verbose_quiet "Killing container" docker kill "$ID" > /dev/null + sleep 1 dokku_log_verbose_quiet "Removing container" docker rm -v "$ID" > /dev/null From c2f115df86fb14eb177e8f5bb87775ab4dece05a Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 6 Sep 2015 18:19:22 -0400 Subject: [PATCH 09/16] fix name of container in readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1ec6ce0..c37046d 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ dokku redis:link lolipop playground # the above will expose the following environment variables # # REDIS_URL=redis://172.17.0.1:6379 -# REDIS_NAME=/playground/DATABASE +# REDIS_NAME=/lolipop/DATABASE # REDIS_PORT=tcp://172.17.0.1:6379 # REDIS_PORT_6379_TCP=tcp://172.17.0.1:6379 # REDIS_PORT_6379_TCP_PROTO=tcp @@ -87,7 +87,7 @@ dokku redis:logs lolipop dokku redis:logs lolipop -t # to tail # finally, you can destroy the container -dokku redis:destroy playground +dokku redis:destroy lolipop ``` ## todo From d1f6f64f23baac50ac535cc3fed9471ebf701c9e Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 6 Sep 2015 18:19:35 -0400 Subject: [PATCH 10/16] Pull the ambassador image --- install | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install b/install index 91a71d1..f3b2bed 100755 --- a/install +++ b/install @@ -6,5 +6,7 @@ if ! docker images | grep -e "^$PLUGIN_IMAGE " | grep -q $PLUGIN_IMAGE_VERSION ; docker pull $PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION fi +docker pull svendowideit/ambassador:latest + mkdir -p $PLUGIN_DATA_ROOT || echo "Failed to create $PLUGIN_SERVICE directory" chown dokku:dokku $PLUGIN_DATA_ROOT From f1ac4bbe71b6942759feaa64370ea20946a547f9 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 6 Sep 2015 18:23:52 -0400 Subject: [PATCH 11/16] Fix logging output for start/stop of container --- functions | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/functions b/functions index d33c47a..80d1e58 100755 --- a/functions +++ b/functions @@ -195,7 +195,7 @@ service_start() { 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" + dokku_log_info1_quiet "Starting container" 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 @@ -214,7 +214,7 @@ service_stop() { [[ -z $ID ]] && dokku_log_fail "Service is already stopped" if [[ -n $ID ]]; then - dokku_log_verbose_quiet "Stopping container" + dokku_log_info1_quiet "Stopping container" docker stop "$SERVICE_NAME" > /dev/null service_port_pause "$SERVICE" dokku_log_info2 "Container stopped" From b457a82256f9274b0c0a78409b21653279f005d8 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 6 Sep 2015 19:26:50 -0400 Subject: [PATCH 12/16] Ensure container is running before attempting to delete files in the container --- commands | 1 + 1 file changed, 1 insertion(+) diff --git a/commands b/commands index 2a0b812..bd6bf9a 100755 --- a/commands +++ b/commands @@ -72,6 +72,7 @@ case "$1" in ID=$(cat "$SERVICE_ROOT/ID") dokku_log_verbose_quiet "Deleting container data" + service_start "$SERVICE" docker exec -it "$ID" chmod -R 777 /data service_stop "$SERVICE" From 2289c5f3dcf9a828c6d2703fa5779857db96b1e6 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 6 Sep 2015 19:27:04 -0400 Subject: [PATCH 13/16] Allow docker kill command to fail --- commands | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands b/commands index bd6bf9a..e8216ef 100755 --- a/commands +++ b/commands @@ -77,7 +77,7 @@ case "$1" in service_stop "$SERVICE" dokku_log_verbose_quiet "Killing container" - docker kill "$ID" > /dev/null + docker kill "$ID" > /dev/null || true sleep 1 dokku_log_verbose_quiet "Removing container" From f72bf5402d89262b10f50552cd2e2fbc9c33c1dd Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 6 Sep 2015 19:29:28 -0400 Subject: [PATCH 14/16] Label running containers This will avoid issues where `dokku cleanup` removes the stopped containers (it should not do so, and instead should allow them to stay in stopped mode). Containers will be labeled as follows: - service: dokku=service dokku.service=SERVICE_NAME - ambassador: dokku=ambassador dokku.ambassador=SERVICE_NAME To destroy the containers, simply run the `service:destroy` command. --- commands | 2 +- functions | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/commands b/commands index e8216ef..558bb3f 100755 --- a/commands +++ b/commands @@ -36,7 +36,7 @@ case "$1" in dokku_log_info1 "Starting container" 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") + ID=$(docker run --name "$SERVICE_NAME" -v "$SERVICE_ROOT/data:/data" -v "$SERVICE_ROOT/config:/usr/local/etc/redis" -d --restart always --label dokku=service --label dokku.service=redis "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION") echo "$ID" > "$SERVICE_ROOT/ID" dokku_log_verbose_quiet "Waiting for container to be ready" diff --git a/functions b/functions index 80d1e58..b74f770 100755 --- a/functions +++ b/functions @@ -175,7 +175,7 @@ service_port_unpause() { echo "${PORTS[@]}" > "$PORT_FILE" - docker run -d --link "$SERVICE_NAME:redis" --name "$EXPOSED_NAME" $(docker_ports_options "${PORTS[@]}") --restart always svendowideit/ambassador > /dev/null + docker run -d --link "$SERVICE_NAME:redis" --name "$EXPOSED_NAME" $(docker_ports_options "${PORTS[@]}") --restart always --label dokku=ambassador --label dokku.ambassador=redis svendowideit/ambassador > /dev/null if [[ "$LOG_FAIL" == "true" ]]; then dokku_log_info1 "Service $SERVICE exposed on port(s) ${PORTS[*]}" fi From 61d61eae7085218457ef85d07db2f1f158fa8772 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 6 Sep 2015 19:39:41 -0400 Subject: [PATCH 15/16] Do not fail on service_stop when a service is already stopped The desired state already exists, so this isn't strictly an error state. --- functions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions b/functions index b74f770..9faa338 100755 --- a/functions +++ b/functions @@ -211,7 +211,7 @@ service_stop() { 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" + [[ -z $ID ]] && dokku_log_warn "Service is already stopped" && return 0 if [[ -n $ID ]]; then dokku_log_info1_quiet "Stopping container" From f0c800b81d1d771c980b992fb5e493eda307a789 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 6 Sep 2015 19:59:01 -0400 Subject: [PATCH 16/16] Do not fail on service_start when a service is already started The desired state already exists, so this isn't strictly an error state. --- functions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions b/functions index 9faa338..b78be3e 100755 --- a/functions +++ b/functions @@ -193,7 +193,7 @@ service_start() { 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" + [[ -n $ID ]] && dokku_log_warn "Service is already started" && return 0 dokku_log_info1_quiet "Starting container" local PREVIOUS_ID=$(docker ps -f status=exited | grep "$SERVICE_NAME" | awk '{print $1}') || true