From baeea9673129eb4f2536f2cfe7cc064216883c17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Guitaut?= Date: Tue, 22 Sep 2015 18:13:57 +0200 Subject: [PATCH] Revamp link/unlink commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously we were exporting `REDIS_URL` via the docker-args* hooks. This seems to confuse our users (since the env var is not displayed when calling `dokku config`) and in some cases it also seems that the env var is not correctly set. Another problem is if several services are linked to the same app and if they are exporting `REDIS_URL` as well. Then we don’t know what will be set. To resolve theses issues, this patch changes the way we manage the env vars. We use standard dokku commands (`config` and `docker-options`) so config is set on the linked application and can be reviewed by the user easily. We also handle the case where `REDIS_URL` is already set on the linked application. When it’s the case, we automatically generate another env var based on the following pattern: DOKKU___URL. For example, this can give: DOKKU_REDIS_BLACK_URL. Since naming is now handled automatically, the `alias` command has been removed. If the user wants to set a different env var on her app, it’s just a matter of using `dokku config:set` and pasting the wanted value. IP in DSN has been removed in favor of host name exported by docker in the container. This is more robust and simpler since the IP can change but the name will remain the same if the service container restarts for instance. With all those changes, a new command has been introduced: `promote`. The goal of this command is to easily set a service as the primary one when several are linked to an app. (see README for an example) --- .gitignore | 1 + README.md | 50 +++++--- commands | 17 +-- config | 1 + docker-args-build | 1 - docker-args-deploy | 31 ----- docker-args-run | 1 - functions | 109 ++++++++++++++---- pre-delete | 16 +++ tests/bin/sudo | 2 + tests/hook_pre_delete.bats | 20 ++++ tests/redis_alias.bats | 32 ----- .../{redis_clone.bats => service_clone.bats} | 0 ...edis_connect.bats => service_connect.bats} | 0 ...{redis_create.bats => service_create.bats} | 0 ...edis_destroy.bats => service_destroy.bats} | 0 ...{redis_export.bats => service_export.bats} | 0 ...{redis_expose.bats => service_expose.bats} | 0 ...{redis_import.bats => service_import.bats} | 0 tests/{redis_info.bats => service_info.bats} | 9 +- tests/{redis_link.bats => service_link.bats} | 28 ++++- tests/{redis_list.bats => service_list.bats} | 0 tests/{redis_logs.bats => service_logs.bats} | 0 tests/service_promote.bats | 53 +++++++++ ...edis_restart.bats => service_restart.bats} | 0 .../{redis_start.bats => service_start.bats} | 0 tests/{redis_stop.bats => service_stop.bats} | 0 ...is_unexpose.bats => service_unexpose.bats} | 0 ...{redis_unlink.bats => service_unlink.bats} | 20 +++- tests/setup.sh | 9 ++ tests/test_helper.bash | 1 + 31 files changed, 280 insertions(+), 121 deletions(-) delete mode 120000 docker-args-build delete mode 100755 docker-args-deploy delete mode 120000 docker-args-run create mode 100755 pre-delete create mode 100755 tests/bin/sudo create mode 100755 tests/hook_pre_delete.bats delete mode 100755 tests/redis_alias.bats rename tests/{redis_clone.bats => service_clone.bats} (100%) rename tests/{redis_connect.bats => service_connect.bats} (100%) rename tests/{redis_create.bats => service_create.bats} (100%) rename tests/{redis_destroy.bats => service_destroy.bats} (100%) rename tests/{redis_export.bats => service_export.bats} (100%) rename tests/{redis_expose.bats => service_expose.bats} (100%) rename tests/{redis_import.bats => service_import.bats} (100%) rename tests/{redis_info.bats => service_info.bats} (60%) rename tests/{redis_link.bats => service_link.bats} (51%) rename tests/{redis_list.bats => service_list.bats} (100%) rename tests/{redis_logs.bats => service_logs.bats} (100%) create mode 100755 tests/service_promote.bats rename tests/{redis_restart.bats => service_restart.bats} (100%) rename tests/{redis_start.bats => service_start.bats} (100%) rename tests/{redis_stop.bats => service_stop.bats} (100%) rename tests/{redis_unexpose.bats => service_unexpose.bats} (100%) rename tests/{redis_unlink.bats => service_unlink.bats} (67%) diff --git a/.gitignore b/.gitignore index c604a48..a722348 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ tests/dokku tests/fixtures +tests/bin/plugn diff --git a/README.md b/README.md index 6fda2dd..f1861e1 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,6 @@ dokku plugin:install https://github.com/dokku/dokku-redis.git redis ## commands ``` -redis:alias Set an alias for the docker link redis:clone Create container then copy data from into redis:connect Connect via redis-cli to a redis service redis:create Create a redis service @@ -34,6 +33,7 @@ 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:promote Promote service as REDIS_URL in 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 @@ -58,8 +58,6 @@ dokku redis:create lolipop # get connection information as follows dokku redis:info lolipop -# lets assume the ip of our redis service is 172.17.0.1 - # a redis service can be linked to a # container this will use native docker # links via the docker-options plugin @@ -69,24 +67,42 @@ dokku redis:link lolipop playground # the above will expose the following environment variables # -# REDIS_URL=redis://172.17.0.1:6379 -# 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 -# REDIS_PORT_6379_TCP_PORT=6379 -# REDIS_PORT_6379_TCP_ADDR=172.17.0.1 +# DOKKU_REDIS_LOLIPOP_NAME=/lolipop/DATABASE +# DOKKU_REDIS_LOLIPOP_PORT=tcp://172.17.0.1:6379 +# DOKKU_REDIS_LOLIPOP_PORT_6379_TCP=tcp://172.17.0.1:6379 +# DOKKU_REDIS_LOLIPOP_PORT_6379_TCP_PROTO=tcp +# DOKKU_REDIS_LOLIPOP_PORT_6379_TCP_PORT=6379 +# DOKKU_REDIS_LOLIPOP_PORT_6379_TCP_ADDR=172.17.0.1 +# +# and the following will be set on the linked application by default +# +# REDIS_URL=redis://dokku-redis-lolipop:6379/0 +# +# NOTE: the host exposed here only works internally in docker containers. If +# you want your container to be reachable from outside, you should use `expose`. -# you can examine the environment variables -# using our 'playground' app's env command -dokku run playground env +# another service can be linked to your app +dokku redis:link other_service playground -# you can customize the environment -# variables through a custom docker link alias -dokku redis:alias lolipop REDIS_DATABASE +# since REDIS_URL is already in use, another environment variable will be +# generated automatically +# +# DOKKU_REDIS_BLUE_URL=redis://dokku-redis-other-service:6379/0 + +# you can then promote the new service to be the primary one +# NOTE: this will restart your app +dokku redis:promote other_service playground + +# this will replace REDIS_URL with the url from other_service and generate +# another environment variable to hold the previous value if necessary. +# you could end up with the following for example: +# +# REDIS_URL=redis://dokku-redis-other-service:6379/0 +# DOKKU_REDIS_BLUE_URL=redis://dokku-redis-other-service:6379/0 +# DOKKU_REDIS_SILVER_URL=redis://dokku-redis-lolipop:6379/lolipop # you can also unlink a redis service -# NOTE: this will restart your app +# NOTE: this will restart your app and unset related environment variables dokku redis:unlink lolipop playground # you can tail logs for a particular service diff --git a/commands b/commands index bea935e..6a59c5c 100755 --- a/commands +++ b/commands @@ -16,13 +16,6 @@ if [[ $1 == $PLUGIN_COMMAND_PREFIX:* ]]; then fi case "$1" in - $PLUGIN_COMMAND_PREFIX:alias) - [[ -z $2 ]] && dokku_log_fail "Please specify a name for the service" - [[ -z $3 ]] && dokku_log_fail "Please specify an alias for the service" - verify_service_name "$2" - service_set_alias "$2" "$3" - ;; - $PLUGIN_COMMAND_PREFIX:create) [[ -z $2 ]] && dokku_log_fail "Please specify a name for the service" [[ ! -d "$PLUGIN_DATA_ROOT/$2" ]] || dokku_log_fail "$PLUGIN_SERVICE service $2 already exists" @@ -203,9 +196,16 @@ case "$1" in service_port_unexpose "$2" ;; + $PLUGIN_COMMAND_PREFIX:promote) + [[ -z $2 ]] && dokku_log_fail "Please specify a name for the service" + [[ -z $3 ]] && dokku_log_fail "Please specify an app to run the command on" + verify_service_name "$2" + verify_app_name "$3" + promote "$2" "$3" + ;; + help | $PLUGIN_COMMAND_PREFIX:help) HELP=$(cat< , Set an alias for the docker link $PLUGIN_COMMAND_PREFIX:create , Create a $PLUGIN_SERVICE service $PLUGIN_COMMAND_PREFIX:destroy , Delete the $PLUGIN_SERVICE service and stop its container if there are no links left $PLUGIN_COMMAND_PREFIX:link , Link the $PLUGIN_SERVICE service to the app @@ -222,6 +222,7 @@ case "$1" in $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 + $PLUGIN_COMMAND_PREFIX:promote , Promote service as ${PLUGIN_DEFAULT_ALIAS}_URL in EOF ) if [[ -n $DOKKU_API_VERSION ]]; then diff --git a/config b/config index 47bdbe8..c8160e7 100755 --- a/config +++ b/config @@ -7,6 +7,7 @@ export PLUGIN_COMMAND_PREFIX="redis" export PLUGIN_DATA_ROOT=$REDIS_ROOT export PLUGIN_DATASTORE_PORTS=(6379) export PLUGIN_DEFAULT_ALIAS="REDIS" +export PLUGIN_ALT_ALIAS="DOKKU_REDIS" export PLUGIN_IMAGE=$REDIS_IMAGE export PLUGIN_IMAGE_VERSION=$REDIS_IMAGE_VERSION export PLUGIN_SCHEME="redis" diff --git a/docker-args-build b/docker-args-build deleted file mode 120000 index 68dea36..0000000 --- a/docker-args-build +++ /dev/null @@ -1 +0,0 @@ -docker-args-deploy \ No newline at end of file diff --git a/docker-args-deploy b/docker-args-deploy deleted file mode 100755 index 2295403..0000000 --- a/docker-args-deploy +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env bash -set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x -PLUGIN_BASE_PATH="$PLUGIN_PATH" -if [[ -n $DOKKU_API_VERSION ]]; then - PLUGIN_BASE_PATH="$PLUGIN_ENABLED_PATH" -fi -source "$PLUGIN_BASE_PATH/common/functions" -source "$(dirname "$0")/functions" -source "$(dirname "$0")/config" - -STDIN=$(cat) -APP="$1" - -output="" -for i in $PLUGIN_DATA_ROOT/*; do - [[ -d $i ]] || continue - SERVICE=$(echo "$i" | cut -d'/' -f 7) - LINKS_FILE="$PLUGIN_DATA_ROOT/$SERVICE/LINKS" - ALIAS="$(service_alias "$SERVICE")" - SERVICE_URL="$(service_url "$SERVICE")" - if [[ -f "$LINKS_FILE" ]]; then - while read line; do - if [[ "$line" == "$APP" ]]; then - output="$output --link dokku.redis.$SERVICE:$ALIAS --env ${ALIAS}_URL=$SERVICE_URL" - break - fi - done < "$LINKS_FILE" - fi -done - -echo "$STDIN$output" diff --git a/docker-args-run b/docker-args-run deleted file mode 120000 index 68dea36..0000000 --- a/docker-args-run +++ /dev/null @@ -1 +0,0 @@ -docker-args-deploy \ No newline at end of file diff --git a/functions b/functions index 44685ce..1a4aee6 100755 --- a/functions +++ b/functions @@ -32,14 +32,8 @@ verify_service_name() { service_alias() { local SERVICE="$1" - local ALIAS_FILE="$PLUGIN_DATA_ROOT/$SERVICE/ALIAS" - - verify_service_name "$1" - if [[ -f "$ALIAS_FILE" ]]; then - cat "$ALIAS_FILE" - else - echo "$PLUGIN_DEFAULT_ALIAS" - fi + local SERVICE_NAME=$(get_service_name "$SERVICE") + echo "$SERVICE_NAME" | tr ._ - } service_info() { @@ -77,16 +71,44 @@ service_exposed_ports() { service_link() { local APP="$2" local SERVICE="$1" + local SERVICE_URL=$(service_url "$SERVICE") + local SERVICE_NAME=$(get_service_name "$SERVICE") local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" + local EXISTING_CONFIG=$(dokku config "$APP") + local LINK=$(echo "$EXISTING_CONFIG" | grep "$SERVICE_URL" | cut -d: -f1) || true + local DEFAULT_ALIAS=$(echo "$EXISTING_CONFIG" | grep "${PLUGIN_DEFAULT_ALIAS}_URL") || true + local SERVICE_ALIAS=$(service_alias "$SERVICE") local LINKS_FILE="$SERVICE_ROOT/LINKS" + [[ -n $LINK ]] && dokku_log_fail "Already linked as $LINK" mkdir -p "$SERVICE_ROOT" || dokku_log_fail "Unable to create service directory" touch "$LINKS_FILE" echo "$APP" >> "$LINKS_FILE" sort "$LINKS_FILE" -u -o "$LINKS_FILE" - dokku_log_info1 "Restarting app $APP" - dokku ps:restart "$APP" + local ALIAS="$PLUGIN_DEFAULT_ALIAS" + if [[ -n $DEFAULT_ALIAS ]]; then + ALIAS=$(service_alternative_alias "$EXISTING_CONFIG") + fi + dokku docker-options:add "$APP" build,deploy,run "--link $SERVICE_NAME:$SERVICE_ALIAS" + dokku config:set "$APP" "${ALIAS}_URL=$SERVICE_URL" +} + +service_alternative_alias() { + local EXISTING_CONFIG="$1" + local COLORS=(AQUA BLACK BLUE FUCHSIA GRAY GREEN LIME MAROON NAVY OLIVE PURPLE RED SILVER TEAL WHITE YELLOW) + local ALIAS; + + while [[ -z $ALIAS ]]; do + local IDX=$((RANDOM % ${#COLORS[*]})) + local COLOR=${COLORS[IDX]} + ALIAS="${PLUGIN_ALT_ALIAS}_${COLOR}" + local IN_USE=$(echo "$EXISTING_CONFIG" | grep "${ALIAS}_URL") + if [[ -n $IN_USE ]]; then + unset ALIAS + fi + done + echo "$ALIAS" } service_logs() { @@ -236,25 +258,23 @@ service_stop() { service_unlink() { local APP="$2" local SERVICE="$1" - local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" - local LINKS_FILE="$SERVICE_ROOT/LINKS" + local SERVICE_URL=$(service_url "$SERVICE") + local SERVICE_NAME=$(get_service_name "$SERVICE") + local EXISTING_CONFIG=$(dokku config "$APP") + local SERVICE_ALIAS=$(service_alias "$SERVICE") + local LINK=($(echo "$EXISTING_CONFIG" | grep "$SERVICE_URL" | cut -d: -f1)) || true - mkdir -p "$SERVICE_ROOT" || dokku_log_fail "Unable to create service directory" - touch "$LINKS_FILE" - sed -i "/^$APP\$/d" "$LINKS_FILE" - sort "$LINKS_FILE" -u -o "$LINKS_FILE" + [[ -z ${LINK[*]} ]] && dokku_log_fail "Not linked to app $APP" + remove_from_links_file "$SERVICE" "$APP" - dokku_log_info1 "Restarting app $APP" - dokku ps:restart "$APP" + dokku docker-options:remove "$APP" build,deploy,run "--link $SERVICE_NAME:$SERVICE_ALIAS" + dokku config:unset "$APP" "${LINK[*]}" } service_url() { local SERVICE="$1" - local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" - - local ID="$(cat "$SERVICE_ROOT/ID")" - local IP="$(get_container_ip "$ID")" - echo "$PLUGIN_SCHEME://$IP:${PLUGIN_DATASTORE_PORTS[0]}/0" + local SERVICE_ALIAS="$(service_alias "$SERVICE")" + echo "$PLUGIN_SCHEME://$SERVICE_ALIAS:${PLUGIN_DATASTORE_PORTS[0]}/0" } is_container_status () { @@ -279,3 +299,46 @@ service_version() { local SERVICE_NAME="$(get_service_name "$SERVICE")" docker inspect -f '{{.Config.Image}}' "$SERVICE_NAME" } + +get_url_from_config() { + local EXISTING_CONFIG="$1" + local CONFIG_VAR="$2" + echo "$EXISTING_CONFIG" | grep "$CONFIG_VAR" | sed "s/$CONFIG_VAR:\s*//" +} + +promote() { + local SERVICE="$1" + local APP="$2" + local PLUGIN_DEFAULT_CONFIG_VAR="${PLUGIN_DEFAULT_ALIAS}_URL" + local EXISTING_CONFIG=$(dokku config "$APP") + local SERVICE_URL=$(service_url "$SERVICE") + local CONFIG_VARS=($(echo "$EXISTING_CONFIG" | grep "$SERVICE_URL" | cut -d: -f1)) || true + local PREVIOUS_DEFAULT_URL=$(get_url_from_config "$EXISTING_CONFIG" "$PLUGIN_DEFAULT_CONFIG_VAR") + + [[ -z ${CONFIG_VARS[*]} ]] && dokku_log_fail "Not linked to app $APP" + [[ ${CONFIG_VARS[*]} =~ $PLUGIN_DEFAULT_CONFIG_VAR ]] && dokku_log_fail "Service $1 already promoted as $PLUGIN_DEFAULT_CONFIG_VAR" + + local NEW_CONFIG_VARS="" + if [[ -n $PREVIOUS_DEFAULT_URL ]]; then + local PREVIOUS_ALIAS=$(echo "$EXISTING_CONFIG" | grep "$PREVIOUS_DEFAULT_URL" | grep -v "$PLUGIN_DEFAULT_CONFIG_VAR") || true + if [[ -z $PREVIOUS_ALIAS ]]; then + local ALIAS=$(service_alternative_alias "$EXISTING_CONFIG") + NEW_CONFIG_VARS+="${ALIAS}_URL=$PREVIOUS_DEFAULT_URL " + fi + fi + local PROMOTE_URL=$(get_url_from_config "$EXISTING_CONFIG" "${CONFIG_VARS[0]}") + NEW_CONFIG_VARS+="$PLUGIN_DEFAULT_CONFIG_VAR=$PROMOTE_URL" + dokku config:set "$APP" $NEW_CONFIG_VARS +} + +remove_from_links_file() { + local SERVICE="$1" + local APP="$2" + local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" + local LINKS_FILE="$SERVICE_ROOT/LINKS" + + mkdir -p "$SERVICE_ROOT" || dokku_log_fail "Unable to create service directory" + touch "$LINKS_FILE" + sed -i "/^$APP\$/d" "$LINKS_FILE" + sort "$LINKS_FILE" -u -o "$LINKS_FILE" +} diff --git a/pre-delete b/pre-delete new file mode 100755 index 0000000..22897dc --- /dev/null +++ b/pre-delete @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x + +PLUGIN_BASE_PATH="$PLUGIN_PATH" +if [[ -n $DOKKU_API_VERSION ]]; then + PLUGIN_BASE_PATH="$PLUGIN_ENABLED_PATH" +fi +source "$PLUGIN_BASE_PATH/common/functions" +source "$(dirname "$0")/functions" +source "$(dirname "$0")/config" + +APP="$1" +for SERVICE in "$PLUGIN_DATA_ROOT"/*; do + remove_from_links_file "$(basename "$SERVICE")" "$APP" +done +exit 0 diff --git a/tests/bin/sudo b/tests/bin/sudo new file mode 100755 index 0000000..742e13d --- /dev/null +++ b/tests/bin/sudo @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +exit 0 diff --git a/tests/hook_pre_delete.bats b/tests/hook_pre_delete.bats new file mode 100755 index 0000000..62b79f4 --- /dev/null +++ b/tests/hook_pre_delete.bats @@ -0,0 +1,20 @@ +#!/usr/bin/env bats +load test_helper + +setup() { + dokku apps:create my_app >&2 + dokku "$PLUGIN_COMMAND_PREFIX:create" l >&2 + dokku "$PLUGIN_COMMAND_PREFIX:link" l my_app >&2 +} + +teardown() { + dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my_app >&2 + dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l >&2 + rm "$DOKKU_ROOT/my_app" -rf +} + +@test "($PLUGIN_COMMAND_PREFIX:hook:pre-delete) removes app from links file when destroying app" { + [[ -n $(< "$PLUGIN_DATA_ROOT/l/LINKS") ]] + dokku --force apps:destroy my_app + [[ -z $(< "$PLUGIN_DATA_ROOT/l/LINKS") ]] +} diff --git a/tests/redis_alias.bats b/tests/redis_alias.bats deleted file mode 100755 index 6d556af..0000000 --- a/tests/redis_alias.bats +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bats -load test_helper - -setup() { - dokku "$PLUGIN_COMMAND_PREFIX:create" l >&2 -} - -teardown() { - dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l >&2 -} - -@test "($PLUGIN_COMMAND_PREFIX:alias) error when there are no arguments" { - run dokku "$PLUGIN_COMMAND_PREFIX:alias" - assert_contains "${lines[*]}" "Please specify a name for the service" -} - -@test "($PLUGIN_COMMAND_PREFIX:alias) error when alias is missing" { - run dokku "$PLUGIN_COMMAND_PREFIX:alias" l - assert_contains "${lines[*]}" "Please specify an alias for the service" -} - -@test "($PLUGIN_COMMAND_PREFIX:alias) error when service does not exist" { - run dokku "$PLUGIN_COMMAND_PREFIX:alias" not_existing_service MY_ALIAS - assert_contains "${lines[*]}" "Redis service not_existing_service does not exist" -} - -@test "($PLUGIN_COMMAND_PREFIX:alias) success" { - run dokku "$PLUGIN_COMMAND_PREFIX:alias" l MY_ALIAS - new_alias=$(cat "$PLUGIN_DATA_ROOT/l/ALIAS") - [[ $new_alias == "MY_ALIAS" ]] -} - diff --git a/tests/redis_clone.bats b/tests/service_clone.bats similarity index 100% rename from tests/redis_clone.bats rename to tests/service_clone.bats diff --git a/tests/redis_connect.bats b/tests/service_connect.bats similarity index 100% rename from tests/redis_connect.bats rename to tests/service_connect.bats diff --git a/tests/redis_create.bats b/tests/service_create.bats similarity index 100% rename from tests/redis_create.bats rename to tests/service_create.bats diff --git a/tests/redis_destroy.bats b/tests/service_destroy.bats similarity index 100% rename from tests/redis_destroy.bats rename to tests/service_destroy.bats diff --git a/tests/redis_export.bats b/tests/service_export.bats similarity index 100% rename from tests/redis_export.bats rename to tests/service_export.bats diff --git a/tests/redis_expose.bats b/tests/service_expose.bats similarity index 100% rename from tests/redis_expose.bats rename to tests/service_expose.bats diff --git a/tests/redis_import.bats b/tests/service_import.bats similarity index 100% rename from tests/redis_import.bats rename to tests/service_import.bats diff --git a/tests/redis_info.bats b/tests/service_info.bats similarity index 60% rename from tests/redis_info.bats rename to tests/service_info.bats index 1fe00b7..5c55e5d 100755 --- a/tests/redis_info.bats +++ b/tests/service_info.bats @@ -21,5 +21,12 @@ teardown() { @test "($PLUGIN_COMMAND_PREFIX:info) success" { run dokku "$PLUGIN_COMMAND_PREFIX:info" l - assert_contains "${lines[*]}" "DSN: redis://172.17.0.34:6379/0" + assert_contains "${lines[*]}" "DSN: redis://dokku-redis-l:6379/0" +} + +@test "($PLUGIN_COMMAND_PREFIX:info) replaces underscores by dash in hostname" { + dokku "$PLUGIN_COMMAND_PREFIX:create" test_with_underscores + run dokku "$PLUGIN_COMMAND_PREFIX:info" test_with_underscores + assert_contains "${lines[*]}" "DSN: redis://dokku-redis-test-with-underscores:6379/0" + dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" test_with_underscores } diff --git a/tests/redis_link.bats b/tests/service_link.bats similarity index 51% rename from tests/redis_link.bats rename to tests/service_link.bats index 047945f..7aacc1a 100755 --- a/tests/redis_link.bats +++ b/tests/service_link.bats @@ -31,8 +31,30 @@ teardown() { assert_contains "${lines[*]}" "Redis service not_existing_service does not exist" } -@test "($PLUGIN_COMMAND_PREFIX:link) success" { +@test "($PLUGIN_COMMAND_PREFIX:link) error when the service is already linked to app" { + dokku "$PLUGIN_COMMAND_PREFIX:link" l my_app run dokku "$PLUGIN_COMMAND_PREFIX:link" l my_app - links=$(cat "$PLUGIN_DATA_ROOT/l/LINKS") - assert_equal "$links" "my_app" + assert_contains "${lines[*]}" "Already linked as REDIS_URL" +} + +@test "($PLUGIN_COMMAND_PREFIX:link) exports REDIS_URL to app" { + dokku "$PLUGIN_COMMAND_PREFIX:link" l my_app + url=$(dokku config:get my_app REDIS_URL) + assert_contains "$url" "redis://dokku-redis-l:6379/0" + dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my_app +} + +@test "($PLUGIN_COMMAND_PREFIX:link) generates an alternate config url when REDIS_URL already in use" { + dokku config:set my_app REDIS_URL=redis://host:6379/0 + dokku "$PLUGIN_COMMAND_PREFIX:link" l my_app + run dokku config my_app + assert_contains "${lines[*]}" "DOKKU_REDIS_" + dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my_app +} + +@test "($PLUGIN_COMMAND_PREFIX:link) links to app with docker-options" { + dokku "$PLUGIN_COMMAND_PREFIX:link" l my_app + run dokku docker-options my_app + assert_contains "${lines[*]}" "--link dokku.redis.l:dokku-redis-l" + dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my_app } diff --git a/tests/redis_list.bats b/tests/service_list.bats similarity index 100% rename from tests/redis_list.bats rename to tests/service_list.bats diff --git a/tests/redis_logs.bats b/tests/service_logs.bats similarity index 100% rename from tests/redis_logs.bats rename to tests/service_logs.bats diff --git a/tests/service_promote.bats b/tests/service_promote.bats new file mode 100755 index 0000000..28ee87a --- /dev/null +++ b/tests/service_promote.bats @@ -0,0 +1,53 @@ +#!/usr/bin/env bats +load test_helper + +setup() { + dokku "$PLUGIN_COMMAND_PREFIX:create" l >&2 + dokku apps:create my_app >&2 + dokku "$PLUGIN_COMMAND_PREFIX:link" l my_app +} + +teardown() { + dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my_app + dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l >&2 + rm "$DOKKU_ROOT/my_app" -rf +} + +@test "($PLUGIN_COMMAND_PREFIX:promote) error when there are no arguments" { + run dokku "$PLUGIN_COMMAND_PREFIX:promote" + assert_contains "${lines[*]}" "Please specify a name for the service" +} + +@test "($PLUGIN_COMMAND_PREFIX:promote) error when the app argument is missing" { + run dokku "$PLUGIN_COMMAND_PREFIX:promote" l + assert_contains "${lines[*]}" "Please specify an app to run the command on" +} + +@test "($PLUGIN_COMMAND_PREFIX:promote) error when the app does not exist" { + run dokku "$PLUGIN_COMMAND_PREFIX:promote" l not_existing_app + assert_contains "${lines[*]}" "App not_existing_app does not exist" +} + +@test "($PLUGIN_COMMAND_PREFIX:promote) error when the service does not exist" { + run dokku "$PLUGIN_COMMAND_PREFIX:promote" not_existing_service my_app + assert_contains "${lines[*]}" "service not_existing_service does not exist" +} + +@test "($PLUGIN_COMMAND_PREFIX:promote) error when the service is already promoted" { + run dokku "$PLUGIN_COMMAND_PREFIX:promote" l my_app + assert_contains "${lines[*]}" "already promoted as REDIS_URL" +} + +@test "($PLUGIN_COMMAND_PREFIX:promote) changes REDIS_URL" { + dokku config:set my_app "REDIS_URL=redis://host:6379/db" "DOKKU_REDIS_BLUE_URL=redis://dokku-redis-l:6379/0" + dokku "$PLUGIN_COMMAND_PREFIX:promote" l my_app + url=$(dokku config:get my_app REDIS_URL) + assert_equal "$url" "redis://dokku-redis-l:6379/0" +} + +@test "($PLUGIN_COMMAND_PREFIX:promote) creates new config url when needed" { + dokku config:set my_app "REDIS_URL=redis://host:6379/db" "DOKKU_REDIS_BLUE_URL=redis://dokku-redis-l:6379/0" + dokku "$PLUGIN_COMMAND_PREFIX:promote" l my_app + run dokku config my_app + assert_contains "${lines[*]}" "DOKKU_REDIS_" +} diff --git a/tests/redis_restart.bats b/tests/service_restart.bats similarity index 100% rename from tests/redis_restart.bats rename to tests/service_restart.bats diff --git a/tests/redis_start.bats b/tests/service_start.bats similarity index 100% rename from tests/redis_start.bats rename to tests/service_start.bats diff --git a/tests/redis_stop.bats b/tests/service_stop.bats similarity index 100% rename from tests/redis_stop.bats rename to tests/service_stop.bats diff --git a/tests/redis_unexpose.bats b/tests/service_unexpose.bats similarity index 100% rename from tests/redis_unexpose.bats rename to tests/service_unexpose.bats diff --git a/tests/redis_unlink.bats b/tests/service_unlink.bats similarity index 67% rename from tests/redis_unlink.bats rename to tests/service_unlink.bats index 18ef349..e0768e2 100755 --- a/tests/redis_unlink.bats +++ b/tests/service_unlink.bats @@ -31,9 +31,21 @@ teardown() { assert_contains "${lines[*]}" "Redis service not_existing_service does not exist" } -@test "($PLUGIN_COMMAND_PREFIX:unlink) success" { - dokku "$PLUGIN_COMMAND_PREFIX:link" l my_app >&2 +@test "($PLUGIN_COMMAND_PREFIX:unlink) error when service not linked to app" { run dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my_app - links=$(cat "$PLUGIN_DATA_ROOT/l/LINKS") - assert_equal "$links" "" + assert_contains "${lines[*]}" "Not linked to app my_app" +} + +@test "($PLUGIN_COMMAND_PREFIX:unlink) removes link from docker-options" { + dokku "$PLUGIN_COMMAND_PREFIX:link" l my_app >&2 + dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my_app + options=$(dokku docker-options my_app) + assert_equal "$options" "" +} + +@test "($PLUGIN_COMMAND_PREFIX:unlink) unsets config url from app" { + dokku "$PLUGIN_COMMAND_PREFIX:link" l my_app >&2 + dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my_app + config=$(dokku config:get my_app REDIS_URL) + assert_equal "$config" "" } diff --git a/tests/setup.sh b/tests/setup.sh index a29514f..e5e0e5e 100644 --- a/tests/setup.sh +++ b/tests/setup.sh @@ -1,6 +1,8 @@ #!/usr/bin/env bash source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/test_helper.bash" +BIN_STUBS="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/bin" + if [[ ! -d $DOKKU_ROOT ]]; then git clone https://github.com/progrium/dokku.git $DOKKU_ROOT > /dev/null fi @@ -13,3 +15,10 @@ cd - rm -rf $DOKKU_ROOT/plugins/service mkdir -p $DOKKU_ROOT/plugins/service find ./ -maxdepth 1 -type f -exec cp '{}' $DOKKU_ROOT/plugins/service \; + +if [[ ! -f $BIN_STUBS/plugn ]]; then + wget -O- "$PLUGN_URL" | tar xzf - -C "$BIN_STUBS" + plugn init + ln -s "$DOKKU_ROOT"/plugins/* "$DOKKU_ROOT"/plugins/available + ln -s "$DOKKU_ROOT"/plugins/* "$DOKKU_ROOT"/plugins/enabled +fi diff --git a/tests/test_helper.bash b/tests/test_helper.bash index 7932203..ca11222 100644 --- a/tests/test_helper.bash +++ b/tests/test_helper.bash @@ -10,6 +10,7 @@ export PLUGIN_AVAILABLE_PATH="$PLUGIN_PATH" export PLUGIN_CORE_AVAILABLE_PATH="$PLUGIN_PATH" export REDIS_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/fixtures" export PLUGIN_DATA_ROOT="$REDIS_ROOT" +export PLUGN_URL="https://github.com/progrium/plugn/releases/download/v0.1.0/plugn_0.1.0_linux_x86_64.tgz" mkdir -p "$PLUGIN_DATA_ROOT" rm -rf "${PLUGIN_DATA_ROOT:?}"/*