diff --git a/README.md b/README.md index 2bcceb1..2d47277 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ postgres:list List all postgres services postgres:logs [-t] Print the most recent log(s) for this service postgres:promote Promote service as DATABASE_URL in postgres:restart Graceful shutdown and restart of the postgres service container +postgres:reset Delete all data in the postgres service postgres:start Start a previously stopped postgres service postgres:stop Stop a running postgres service postgres:unexpose Unexpose a previously exposed postgres service @@ -152,6 +153,9 @@ dokku postgres:import lolipop < database.dump # you can clone an existing database to a new one dokku postgres:clone lolipop new_database +# you can reset a database to delete all its data +dokku postgres:reset lolipop + # finally, you can destroy the container dokku postgres:destroy lolipop ``` diff --git a/common-functions b/common-functions index df0534c..66b11e1 100755 --- a/common-functions +++ b/common-functions @@ -100,6 +100,26 @@ is_valid_service_name() { return 1 } +prompt_confirmation() { + declare desc="Prompts user to confirm destructive action" + declare MESSAGE="$1" SERVICE="$2" FORCE_FLAG="$3" + + if [[ "$FORCE_FLAG" == "force" ]] || [[ "$FORCE_FLAG" == "-f" ]] || [[ "$FORCE_FLAG" == "--force" ]]; then + DOKKU_APPS_FORCE_DELETE=1 + fi + if [[ -z "$DOKKU_APPS_FORCE_DELETE" ]]; then + dokku_log_warn "WARNING: Potentially Destructive Action" + dokku_log_warn "$MESSAGE" + dokku_log_warn "To proceed, type \"$SERVICE\"" + echo "" + + read -rp "> " service_name + if [[ "$service_name" != "$SERVICE" ]]; then + dokku_log_fail "Confirmation did not match $SERVICE. Aborted." + fi + fi +} + remove_from_links_file() { declare desc="Removes an app from the service link file" declare SERVICE="$1" APP="$2" diff --git a/functions b/functions index 7b9b00c..d9f1433 100755 --- a/functions +++ b/functions @@ -121,6 +121,17 @@ service_import() { docker exec -i "$SERVICE_NAME" env PGPASSWORD="$PASSWORD" pg_restore -h localhost -cO --if-exists -d "$DATABASE_NAME" -U postgres -w } +service_reset() { + local SERVICE="$1" + local SERVICE_NAME="$(get_service_name "$SERVICE")" + local DATABASE_NAME="$(get_database_name "$SERVICE")" + + dokku_log_info2_quiet "Deleting all data in $SERVICE" + docker exec "$SERVICE_NAME" su - postgres -c "dropdb $DATABASE_NAME" + docker exec "$SERVICE_NAME" su - postgres -c "createdb -E utf8 $DATABASE_NAME" + dokku_log_info2 "All $SERVICE data deleted" +} + service_start() { local SERVICE="$1" local QUIET="$2" diff --git a/subcommands/destroy b/subcommands/destroy index 5b5d776..44f9a5b 100755 --- a/subcommands/destroy +++ b/subcommands/destroy @@ -24,21 +24,8 @@ service-destroy-cmd() { [[ -s "$LINKS_FILE" ]] && dokku_log_fail "Cannot delete linked service" - if [[ "$FORCE_FLAG" == "force" ]] || [[ "$FORCE_FLAG" == "-f" ]] || [[ "$FORCE_FLAG" == "--force" ]]; then - DOKKU_APPS_FORCE_DELETE=1 - fi - if [[ -z "$DOKKU_APPS_FORCE_DELETE" ]]; then - dokku_log_warn "WARNING: Potentially Destructive Action" - dokku_log_warn "This command will destroy $SERVICE $PLUGIN_SERVICE service." - dokku_log_warn "To proceed, type \"$SERVICE\"" - echo "" - - read -rp "> " service_name - if [[ "$service_name" != "$SERVICE" ]]; then - dokku_log_warn "Confirmation did not match $SERVICE. Aborted." - exit 1 - fi - fi + local message="This command will destroy $SERVICE $PLUGIN_SERVICE service." + prompt_confirmation "$message" "$SERVICE" "$FORCE_FLAG" dokku_log_info2_quiet "Deleting $SERVICE" service_backup_unschedule "$SERVICE" diff --git a/subcommands/reset b/subcommands/reset new file mode 100755 index 0000000..a2e499e --- /dev/null +++ b/subcommands/reset @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" +set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x +source "$PLUGIN_BASE_PATH/common/functions" +source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" + +service-reset-cmd() { + #E delete all data in $PLUGIN_COMMAND_PREFIX service named lolipop + #E dokku $PLUGIN_COMMAND_PREFIX:reset lolipop + #A service, service to run command against + #F -f|--force, force delete without asking for confirmation + declare desc="delete all data in $PLUGIN_SERVICE service" + local cmd="$PLUGIN_COMMAND_PREFIX:reset" argv=("$@"); [[ ${argv[0]} == "$cmd" ]] && shift 1 + declare SERVICE="$1" FORCE_FLAG="$2" + + [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a name for the service" + verify_service_name "$SERVICE" + + local message="This command will delete all data in $SERVICE $PLUGIN_SERVICE service." + prompt_confirmation "$message" "$SERVICE" "$FORCE_FLAG" + + service_reset "$SERVICE" +} + +service-reset-cmd "$@" diff --git a/tests/service_reset.bats b/tests/service_reset.bats new file mode 100755 index 0000000..ead4489 --- /dev/null +++ b/tests/service_reset.bats @@ -0,0 +1,28 @@ +#!/usr/bin/env bats +load test_helper + +setup() { + dokku "$PLUGIN_COMMAND_PREFIX:create" l +} + +teardown() { + dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l +} + +@test "($PLUGIN_COMMAND_PREFIX:reset) success with --force" { + run dokku --force "$PLUGIN_COMMAND_PREFIX:reset" l + assert_contains "${lines[*]}" "All l data deleted" + assert_success +} + +@test "($PLUGIN_COMMAND_PREFIX:reset) error when there are no arguments" { + run dokku "$PLUGIN_COMMAND_PREFIX:reset" + assert_contains "${lines[*]}" "Please specify a name for the service" + assert_failure +} + +@test "($PLUGIN_COMMAND_PREFIX:reset) error when service does not exist" { + run dokku "$PLUGIN_COMMAND_PREFIX:reset" not_existing_service + assert_contains "${lines[*]}" "service not_existing_service does not exist" + assert_failure +}