From 5075639992e22229d236fd15565f24c85481cf82 Mon Sep 17 00:00:00 2001 From: Kane Date: Fri, 6 Jan 2017 10:49:12 +1100 Subject: [PATCH 1/5] Add initial create-database command --- commands | 5 +++++ functions | 32 +++++++++++++++++++++++++++++++- subcommands/create-database | 15 +++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100755 subcommands/create-database diff --git a/commands b/commands index 1a07da32..e87bc666 100755 --- a/commands +++ b/commands @@ -43,6 +43,10 @@ case "$1" in "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/subcommands/create" "$@" ;; + $PLUGIN_COMMAND_PREFIX:create-database) + "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/subcommands/create-database" "$@" + ;; + $PLUGIN_COMMAND_PREFIX:destroy) "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/subcommands/destroy" "$@" ;; @@ -112,6 +116,7 @@ case "$1" in $PLUGIN_COMMAND_PREFIX:clone , Create container then copy data from into $PLUGIN_COMMAND_PREFIX:connect , Connect via psql to a $PLUGIN_SERVICE service $PLUGIN_COMMAND_PREFIX:create , Create a $PLUGIN_SERVICE service + $PLUGIN_COMMAND_PREFIX:create-database , Create a $PLUGIN_SERVICE database in the specified service $PLUGIN_COMMAND_PREFIX:destroy , Delete the $PLUGIN_SERVICE service and stop its container if there are no links left $PLUGIN_COMMAND_PREFIX:export , Export a dump of the $PLUGIN_SERVICE service database $PLUGIN_COMMAND_PREFIX:expose [port], Expose a $PLUGIN_SERVICE service on custom port if provided (random port otherwise) diff --git a/functions b/functions index d4b4040c..179990ba 100755 --- a/functions +++ b/functions @@ -22,9 +22,12 @@ service_create() { mkdir -p "$SERVICE_ROOT" || dokku_log_fail "Unable to create service directory" mkdir -p "$SERVICE_ROOT/data" || dokku_log_fail "Unable to create service data directory" mkdir -p "$SERVICE_ROOT/config" || dokku_log_fail "Unable to create service config directory" + mkdir -p "$SERVICE_ROOT/databases" || dokku_log_fail "Unable to create service database directory" + mkdir -p "$SERVICE_ROOT/auth" || dokku_log_fail "Unable to create service auth directory" + chmod 750 "$SERVICE_ROOT/auth" touch "$LINKS_FILE" password=$(openssl rand -hex 16) - echo "$password" > "$SERVICE_ROOT/PASSWORD" + echo "$password" > "$SERVICE_ROOT/auth/PASSWORD" chmod 640 "$SERVICE_ROOT/PASSWORD" if [[ -n $POSTGRES_CUSTOM_ENV ]]; then @@ -35,6 +38,33 @@ service_create() { service_create_container "$SERVICE" } +database_create() { + local SERVICE="$1" + local NAME="$2" + [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a name for the service" + [[ -z "$NAME" ]] && dokku_log_fail "Please specify a name for the database" + + local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" + local SERVICE_NAME="$(get_service_name "$SERVICE")" + + dokku_log_verbose_quiet "Creating user" + password=$(openssl rand -hex 16) + if docker exec "$SERVICE_NAME" su - postgres -c "psql -c \"CREATE USER $NAME WITH PASSWORD '$password';\"" 2> /dev/null; then + echo "$password" > "$SERVICE_ROOT/auth/$NAME" + chmod 640 "$SERVICE_ROOT/auth/$NAME" + else + echo 'Already exists' + fi + + dokku_log_verbose_quiet "Creating database" + if docker exec "$SERVICE_NAME" su - postgres -c "createdb -E utf8 $NAME" 2> /dev/null; then + touch "$SERVICE_ROOT/databases/$NAME" + else + echo 'Already exists' + fi + docker exec "$SERVICE_NAME" su - postgres -c "psql -c \"GRANT ALL PRIVILEGES ON DATABASE $NAME TO $NAME;\"" > /dev/null +} + service_create_container() { local SERVICE="$1" local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" diff --git a/subcommands/create-database b/subcommands/create-database new file mode 100755 index 00000000..fe58b6f8 --- /dev/null +++ b/subcommands/create-database @@ -0,0 +1,15 @@ +#!/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" + +postgres-create-database-cmd() { + declare desc="create a $PLUGIN_SERVICE database" + local cmd="$PLUGIN_COMMAND_PREFIX:create-database" argv=("$@"); [[ ${argv[0]} == "$cmd" ]] && shift 1 + declare SERVICE="$1" NAME="$2" + + database_create "$SERVICE" "$NAME" +} + +postgres-create-database-cmd "$@" From f2708661a7009e7d4d68ec0c58ebbe687b2d27c6 Mon Sep 17 00:00:00 2001 From: Kane Date: Fri, 6 Jan 2017 14:43:41 +1100 Subject: [PATCH 2/5] Add username/database arguments to link/unlink --- commands | 4 ++-- common-functions | 51 ++++++++++++++++++++++++++++++++++++++++++---- functions | 23 ++++++++++++--------- subcommands/link | 25 +++++++++++++++++++++-- subcommands/unlink | 24 +++++++++++++++++++++- 5 files changed, 108 insertions(+), 19 deletions(-) diff --git a/commands b/commands index e87bc666..024af59a 100755 --- a/commands +++ b/commands @@ -122,7 +122,7 @@ case "$1" in $PLUGIN_COMMAND_PREFIX:expose [port], Expose a $PLUGIN_SERVICE service on custom port if provided (random port otherwise) $PLUGIN_COMMAND_PREFIX:import < , Import a dump into the $PLUGIN_SERVICE service database $PLUGIN_COMMAND_PREFIX:info , Print the connection information - $PLUGIN_COMMAND_PREFIX:link , Link the $PLUGIN_SERVICE service to the app + $PLUGIN_COMMAND_PREFIX:link [--user user] [--database database], Link the $PLUGIN_SERVICE service to the app $PLUGIN_COMMAND_PREFIX:list, List all $PLUGIN_SERVICE services $PLUGIN_COMMAND_PREFIX:logs [-t], Print the most recent log(s) for this service $PLUGIN_COMMAND_PREFIX:promote , Promote service as ${PLUGIN_DEFAULT_ALIAS}_URL in @@ -130,7 +130,7 @@ case "$1" in $PLUGIN_COMMAND_PREFIX:start , Start a previously stopped $PLUGIN_SERVICE service $PLUGIN_COMMAND_PREFIX:stop , Stop a running $PLUGIN_SERVICE service $PLUGIN_COMMAND_PREFIX:unexpose , Unexpose a previously exposed $PLUGIN_SERVICE service - $PLUGIN_COMMAND_PREFIX:unlink , Unlink the $PLUGIN_SERVICE service from the app + $PLUGIN_COMMAND_PREFIX:unlink [--user user] [--database database], Unlink the $PLUGIN_SERVICE service from the app help_content } diff --git a/common-functions b/common-functions index ebd2c698..9a3b91cb 100755 --- a/common-functions +++ b/common-functions @@ -196,7 +196,8 @@ service_info() { declare desc="Retrieves information about a given service" declare SERVICE="$1" INFO_FLAG="$2" local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" - local SERVICE_URL=$(service_url "$SERVICE") + local PASSWORD=$(cat "$SERVICE_ROOT/auth/postgres") + local SERVICE_URL=$(service_url "$SERVICE" postgres "$PASSWORD" "$SERVICE") local PORT_FILE="$SERVICE_ROOT/PORT" local SERVICE_CONTAINER_ID="$(cat "$SERVICE_ROOT/ID")" local flag key valid_flags @@ -235,9 +236,13 @@ service_link() { declare desc="Links a service to an application" declare SERVICE="$1" APP="$2" update_plugin_scheme_for_app "$APP" - local SERVICE_URL=$(service_url "$SERVICE") - local SERVICE_NAME="$(get_service_name "$SERVICE")" local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" + check_auth_migration "$SERVICE" + local USER=${3:-postgres} + local DATABASE=${4:-$(get_database_name "$SERVICE")} + local PASSWORD=$(cat "$SERVICE_ROOT/auth/$USER") + local SERVICE_URL=$(service_url "$SERVICE" "$USER" "$PASSWORD" "$DATABASE") + local SERVICE_NAME="$(get_service_name "$SERVICE")" local EXISTING_CONFIG=$(config_all "$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 @@ -447,8 +452,12 @@ service_stop() { service_unlink() { declare desc="Unlinks an application from a service" declare SERVICE="$1" APP="$2" + local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" + local USER=${3:-postgres} + local PASSWORD=$(cat "$SERVICE_ROOT/auth/$USER") + local DATABASE=${4:-$(get_database_name "$SERVICE")} update_plugin_scheme_for_app "$APP" - local SERVICE_URL=$(service_url "$SERVICE") + local SERVICE_URL=$(service_url "$SERVICE" "$USER" "$PASSWORD" "$DATABASE") local SERVICE_NAME="$(get_service_name "$SERVICE")" local EXISTING_CONFIG=$(config_all "$APP") local SERVICE_ALIAS=$(service_alias "$SERVICE") @@ -490,3 +499,37 @@ verify_service_name() { [[ ! -d "$PLUGIN_DATA_ROOT/$SERVICE" ]] && dokku_log_fail "$PLUGIN_SERVICE service $SERVICE does not exist" return 0 } + +verify_user_name() { + declare desc="Verifies that a user exists" + declare SERVICE="$1" USER="$2" + [[ ! -n "$SERVICE" ]] && dokku_log_fail "(verify_user_name) SERVICE must not be null" + [[ ! -n "$USER" ]] && dokku_log_fail "(verify_user_name) SERVICE must not be null" + [[ ! -f "$PLUGIN_DATA_ROOT/$SERVICE/auth/$USER" ]] && dokku_log_fail "$PLUGIN_SERVICE user $USER for service $SERVICE does not exist" + return 0 +} + +verify_database_name() { + declare desc="Verifies that a database exists" + declare SERVICE="$1" + declare DATABASE="$2" + [[ ! -n "$SERVICE" ]] && dokku_log_fail "(verify_service_name) SERVICE must not be null" + [[ ! -n "$DATABASE" ]] && dokku_log_fail "(verify_service_name) DATABASE must not be null" + [[ ! -f "$PLUGIN_DATA_ROOT/$SERVICE/databases/$DATABASE" ]] && dokku_log_fail "$PLUGIN_SERVICE database $DATABASE for service $SERVICE does not exist" + return 0 +} + +check_auth_migration() { + declare desc="Check whether root credentials need to be migrated into multi-user format and do so if needed" + declare SERVICE="$1" + [[ ! -n "$SERVICE" ]] && dokku_log_fail "(verify_service_name) SERVICE must not be null" + local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" + if [ -f "$SERVICE_ROOT/PASSWORD" ]; then + dokku_log_verbose_quiet "Migrating root user to multi-user format" + local AUTH_DIR="$SERVICE_ROOT/auth" + mkdir -p "$AUTH_DIR" + chmod 750 "$AUTH_DIR" + mv "$SERVICE_ROOT/PASSWORD" "$AUTH_DIR/postgres" + touch "$SERVICE_ROOT/databases/$SERVICE" + fi +} diff --git a/functions b/functions index 179990ba..f5d7780b 100755 --- a/functions +++ b/functions @@ -27,8 +27,8 @@ service_create() { chmod 750 "$SERVICE_ROOT/auth" touch "$LINKS_FILE" password=$(openssl rand -hex 16) - echo "$password" > "$SERVICE_ROOT/auth/PASSWORD" - chmod 640 "$SERVICE_ROOT/PASSWORD" + echo "$password" > "$SERVICE_ROOT/auth/postgres" + chmod 640 "$SERVICE_ROOT/auth/postgres" if [[ -n $POSTGRES_CUSTOM_ENV ]]; then echo "$POSTGRES_CUSTOM_ENV" | tr ';' "\n" > "$SERVICE_ROOT/ENV" @@ -44,12 +44,14 @@ database_create() { [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a name for the service" [[ -z "$NAME" ]] && dokku_log_fail "Please specify a name for the database" + check_auth_migration "$SERVICE" + local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" local SERVICE_NAME="$(get_service_name "$SERVICE")" dokku_log_verbose_quiet "Creating user" password=$(openssl rand -hex 16) - if docker exec "$SERVICE_NAME" su - postgres -c "psql -c \"CREATE USER $NAME WITH PASSWORD '$password';\"" 2> /dev/null; then + if docker exec "$SERVICE_NAME" su - postgres -c "psql -c \"CREATE USER $NAME WITH PASSWORD '$password';\"" > /dev/null 2>&1; then echo "$password" > "$SERVICE_ROOT/auth/$NAME" chmod 640 "$SERVICE_ROOT/auth/$NAME" else @@ -69,7 +71,7 @@ service_create_container() { local SERVICE="$1" local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" local SERVICE_NAME="$(get_service_name "$SERVICE")" - local PASSWORD="$(cat "$SERVICE_ROOT/PASSWORD")" + local PASSWORD="$(cat "$SERVICE_ROOT/auth/postgres")" local PREVIOUS_ID ID=$(docker run --name "$SERVICE_NAME" -v "$SERVICE_ROOT/data:/var/lib/postgresql/data" -e "POSTGRES_PASSWORD=$PASSWORD" --env-file="$SERVICE_ROOT/ENV" -d --restart always --label dokku=service --label dokku.service=postgres "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION") @@ -99,7 +101,7 @@ service_export() { local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" local SERVICE_NAME="$(get_service_name "$SERVICE")" local DATABASE_NAME="$(get_database_name "$SERVICE")" - local PASSWORD="$(cat "$SERVICE_ROOT/PASSWORD")" + local PASSWORD="$(cat "$SERVICE_ROOT/auth/postgres")" [[ -n $SSH_TTY ]] && stty -opost docker exec "$SERVICE_NAME" env PGPASSWORD="$PASSWORD" pg_dump -Fc --no-acl --no-owner -h localhost -U postgres -w "$DATABASE_NAME" @@ -113,7 +115,7 @@ service_import() { SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" SERVICE_NAME="$(get_service_name "$SERVICE")" DATABASE_NAME="$(get_database_name "$SERVICE")" - PASSWORD="$(cat "$SERVICE_ROOT/PASSWORD")" + PASSWORD="$(cat "$SERVICE_ROOT/auth/postgres")" if [[ -t 0 ]]; then dokku_log_fail "No data provided on stdin." @@ -135,7 +137,7 @@ service_start() { dokku_log_info1_quiet "Starting container" local PREVIOUS_ID=$(docker ps -f status=exited | grep -e "$SERVICE_NAME$" | awk '{print $1}') || true local IMAGE_EXISTS=$(docker images | grep -e "^$PLUGIN_IMAGE " | grep -q " $PLUGIN_IMAGE_VERSION " && true) - local PASSWORD="$(cat "$SERVICE_ROOT/PASSWORD")" + local PASSWORD="$(cat "$SERVICE_ROOT/auth/postgres")" if [[ -n $PREVIOUS_ID ]]; then docker start "$PREVIOUS_ID" > /dev/null @@ -152,8 +154,9 @@ service_url() { local SERVICE="$1" local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" - local PASSWORD="$(cat "$SERVICE_ROOT/PASSWORD")" - local DATABASE_NAME="$(get_database_name "$SERVICE")" + local USER="$2" # postgres + local PASSWORD="$3" + local DATABASE_NAME="$4" local SERVICE_ALIAS="$(service_alias "$SERVICE")" - echo "$PLUGIN_SCHEME://postgres:$PASSWORD@$SERVICE_ALIAS:${PLUGIN_DATASTORE_PORTS[0]}/$DATABASE_NAME" + echo "$PLUGIN_SCHEME://$USER:$PASSWORD@$SERVICE_ALIAS:${PLUGIN_DATASTORE_PORTS[0]}/$DATABASE_NAME" } diff --git a/subcommands/link b/subcommands/link index f1b6cd95..858d61d8 100755 --- a/subcommands/link +++ b/subcommands/link @@ -7,14 +7,35 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" postgres-link-cmd() { declare desc="link the $PLUGIN_SERVICE service to the app" local cmd="$PLUGIN_COMMAND_PREFIX:link" argv=("$@"); [[ ${argv[0]} == "$cmd" ]] && shift 1 - declare SERVICE="$1" APP="$2" + + local USER='' + + local next_index=1; local skip=false; local args=("$@"); local positional=() + for arg in "$@"; do + $skip && skip=false && local next_index=$(( next_index + 1 )) && continue + case "$arg" in + --user) + USER=${args[$next_index]}; skip=true + ;; + --database) + DATABASE=${args[$next_index]}; skip=true + ;; + *) + positional+=("$arg") + esac + local next_index=$(( next_index + 1 )) + done + + declare SERVICE="${positional[0]}" APP="${positional[1]}" APP=${APP:="$DOKKU_APP_NAME"} [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a name for the service" [[ -z "$APP" ]] && dokku_log_fail "Please specify an app to run the command on" verify_app_name "$APP" verify_service_name "$SERVICE" - service_link "$SERVICE" "$APP" + [[ -z "$USER" ]] || verify_user_name "$SERVICE" "$USER" + [[ -z "$DATABASE" ]] || verify_database_name "$SERVICE" "$DATABASE" + service_link "$SERVICE" "$APP" "$USER" "$DATABASE" } postgres-link-cmd "$@" diff --git a/subcommands/unlink b/subcommands/unlink index 5fe75a71..c555a3d2 100755 --- a/subcommands/unlink +++ b/subcommands/unlink @@ -10,11 +10,33 @@ postgres-unlink-cmd() { declare SERVICE="$1" APP="$2" APP=${APP:="$DOKKU_APP_NAME"} + local USER='' + + local next_index=1; local skip=false; local args=("$@"); local positional=() + for arg in "$@"; do + $skip && skip=false && local next_index=$(( next_index + 1 )) && continue + case "$arg" in + --user) + USER=${args[$next_index]}; skip=true + ;; + --database) + DATABASE=${args[$next_index]}; skip=true + ;; + *) + positional+=("$arg") + esac + local next_index=$(( next_index + 1 )) + done + + declare SERVICE="${positional[0]}" APP="${positional[1]}" + [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a name for the service" [[ -z "$APP" ]] && dokku_log_fail "Please specify an app to run the command on" verify_app_name "$APP" verify_service_name "$SERVICE" - service_unlink "$SERVICE" "$APP" + [[ -z "$DATABASE" ]] || verify_database_name "$SERVICE" "$DATABASE" + [[ -z "$USER" ]] || verify_user_name "$SERVICE" "$USER" + service_unlink "$SERVICE" "$APP" "$USER" "$DATABASE" } postgres-unlink-cmd "$@" From 52e566c1288ed13b73b41906d1bced230263c5ae Mon Sep 17 00:00:00 2001 From: Kane Date: Fri, 6 Jan 2017 14:44:02 +1100 Subject: [PATCH 3/5] Show users and databases in list output --- commands | 5 +++++ common-functions | 26 ++++++++++++++++++++++++-- functions | 4 ++-- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/commands b/commands index 024af59a..4345d2e9 100755 --- a/commands +++ b/commands @@ -51,6 +51,10 @@ case "$1" in "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/subcommands/destroy" "$@" ;; + $PLUGIN_COMMAND_PREFIX:destroy-database) + "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/subcommands/destroy-database" "$@" + ;; + $PLUGIN_COMMAND_PREFIX:export) "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/subcommands/export" "$@" ;; @@ -118,6 +122,7 @@ case "$1" in $PLUGIN_COMMAND_PREFIX:create , Create a $PLUGIN_SERVICE service $PLUGIN_COMMAND_PREFIX:create-database , Create a $PLUGIN_SERVICE database in the specified service $PLUGIN_COMMAND_PREFIX:destroy , Delete the $PLUGIN_SERVICE service and stop its container if there are no links left + $PLUGIN_COMMAND_PREFIX:destroy-database , Delete a $PLUGIN_SERVICE database on the specified service $PLUGIN_COMMAND_PREFIX:export , Export a dump of the $PLUGIN_SERVICE service database $PLUGIN_COMMAND_PREFIX:expose [port], Expose a $PLUGIN_SERVICE service on custom port if provided (random port otherwise) $PLUGIN_COMMAND_PREFIX:import < , Import a dump into the $PLUGIN_SERVICE service database diff --git a/common-functions b/common-functions index 9a3b91cb..f328e26a 100755 --- a/common-functions +++ b/common-functions @@ -192,6 +192,28 @@ service_exposed_ports() { done } +service_databases() { + declare desc="Lists databases for a service" + declare SERVICE="$1" + local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" + local DATABASE_DIR="$SERVICE_ROOT/databases" + [[ ! -d $DATABASE_DIR ]] && echo '-' && return 0 + for DATABASE in $DATABASE_DIR/*; do + echo -n "$(basename "$DATABASE") " + done +} + +service_users() { + declare desc="Lists users for a service" + declare SERVICE="$1" + local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" + local USER_DIR="$SERVICE_ROOT/auth" + [[ ! -d $USER_DIR ]] && echo '-' && return 0 + for USER in $USER_DIR/*; do + echo -n "$(basename "$USER") " + done +} + service_info() { declare desc="Retrieves information about a given service" declare SERVICE="$1" INFO_FLAG="$2" @@ -287,9 +309,9 @@ service_list() { if [[ -z $SERVICES ]]; then dokku_log_warn "There are no $PLUGIN_SERVICE services" else - LIST="NAME,VERSION,STATUS,EXPOSED PORTS,LINKS\n" + LIST="NAME,VERSION,STATUS,EXPOSED PORTS,DATABASES,USERS,LINKS\n" for SERVICE in $SERVICES; do - LIST+="$SERVICE,$(service_version "$SERVICE"),$(service_status "$SERVICE"),$(service_exposed_ports "$SERVICE"),$(service_linked_apps "$SERVICE")\n" + LIST+="$SERVICE,$(service_version "$SERVICE"),$(service_status "$SERVICE"),$(service_exposed_ports "$SERVICE"),$(service_databases "$SERVICE"),$(service_users "$SERVICE"),$(service_linked_apps "$SERVICE")\n" done printf "%b" "$LIST" | column -t -s, fi diff --git a/functions b/functions index f5d7780b..38a9458b 100755 --- a/functions +++ b/functions @@ -51,7 +51,7 @@ database_create() { dokku_log_verbose_quiet "Creating user" password=$(openssl rand -hex 16) - if docker exec "$SERVICE_NAME" su - postgres -c "psql -c \"CREATE USER $NAME WITH PASSWORD '$password';\"" > /dev/null 2>&1; then + if docker exec "$SERVICE_NAME" su - postgres -c "psql -c \"CREATE USER \\\"$NAME\\\" WITH PASSWORD '$password';\"" > /dev/null 2>&1; then echo "$password" > "$SERVICE_ROOT/auth/$NAME" chmod 640 "$SERVICE_ROOT/auth/$NAME" else @@ -64,7 +64,7 @@ database_create() { else echo 'Already exists' fi - docker exec "$SERVICE_NAME" su - postgres -c "psql -c \"GRANT ALL PRIVILEGES ON DATABASE $NAME TO $NAME;\"" > /dev/null + docker exec "$SERVICE_NAME" su - postgres -c "psql -c \"GRANT ALL PRIVILEGES ON DATABASE \\\"$NAME\\\" TO \\\"$NAME\\\";\"" > /dev/null } service_create_container() { From 492f172b84d8cb171036366c177f432987adb47a Mon Sep 17 00:00:00 2001 From: Kane Date: Fri, 6 Jan 2017 14:44:11 +1100 Subject: [PATCH 4/5] Add command to destroy databases --- commands | 2 +- subcommands/destroy-database | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100755 subcommands/destroy-database diff --git a/commands b/commands index 4345d2e9..2e03da69 100755 --- a/commands +++ b/commands @@ -122,7 +122,7 @@ case "$1" in $PLUGIN_COMMAND_PREFIX:create , Create a $PLUGIN_SERVICE service $PLUGIN_COMMAND_PREFIX:create-database , Create a $PLUGIN_SERVICE database in the specified service $PLUGIN_COMMAND_PREFIX:destroy , Delete the $PLUGIN_SERVICE service and stop its container if there are no links left - $PLUGIN_COMMAND_PREFIX:destroy-database , Delete a $PLUGIN_SERVICE database on the specified service + $PLUGIN_COMMAND_PREFIX:destroy-database , Delete a $PLUGIN_SERVICE database in the specified service $PLUGIN_COMMAND_PREFIX:export , Export a dump of the $PLUGIN_SERVICE service database $PLUGIN_COMMAND_PREFIX:expose [port], Expose a $PLUGIN_SERVICE service on custom port if provided (random port otherwise) $PLUGIN_COMMAND_PREFIX:import < , Import a dump into the $PLUGIN_SERVICE service database diff --git a/subcommands/destroy-database b/subcommands/destroy-database new file mode 100755 index 00000000..40030c7e --- /dev/null +++ b/subcommands/destroy-database @@ -0,0 +1,29 @@ +#!/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" + +postgres-destroy-database-cmd() { + declare desc="delete a $PLUGIN_SERVICE database from the specified service" + local cmd="$PLUGIN_COMMAND_PREFIX:destroy-database" argv=("$@"); [[ ${argv[0]} == "$cmd" ]] && shift 1 + declare SERVICE="$1" DATABASE="$2" + + [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a name for the service" + [[ -z "$DATABASE" ]] && dokku_log_fail "Please specify a name for the database" + verify_service_name "$SERVICE" + verify_database_name "$SERVICE" "$DATABASE" + SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" + SERVICE_NAME="$(get_service_name "$SERVICE")" + + dokku_log_info1 "Deleting $DATABASE from $SERVICE" + if docker exec "$SERVICE_NAME" su - postgres -c "psql -c \"DROP DATABASE $DATABASE;\"" 2> /dev/null && docker exec "$SERVICE_NAME" su - postgres -c "psql -c \"DROP USER $DATABASE;\"" 2> /dev/null; then + rm -f "$SERVICE_ROOT/databases/$DATABASE" + rm -f "$SERVICE_ROOT/auth/$DATABASE" + dokku_log_info2 "$PLUGIN_SERVICE $SERVICE database deleted: $DATABASE" + else + dokku_log_fail "Could not delete the database" + fi +} + +postgres-destroy-database-cmd "$@" From 72792f192544d6caf7d1ce6dae8e5cbaa8c2950f Mon Sep 17 00:00:00 2001 From: Kane Date: Thu, 26 Jan 2017 10:38:55 +1100 Subject: [PATCH 5/5] Update readme with single container commands --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bc643c89..22c7e2fb 100644 --- a/README.md +++ b/README.md @@ -25,13 +25,15 @@ postgres:backup-unschedule Unschedules the backup of the postgres service postgres:clone Create container then copy data from into postgres:connect Connect via psql to a postgres service postgres:create Create a postgres service with environment variables +postgres:create-database Create a postgres database in the specified service postgres:destroy Delete the service and stop its container if there are no links left +postgres:destroy-database Delete a postgres database in the specified service postgres:enter [command] Enter or run a command in a running postgres service container postgres:export > Export a dump of the postgres service database postgres:expose [port] Expose a postgres service on custom port if provided (random port otherwise) postgres:import < Import a dump into the postgres service database postgres:info Print the connection information -postgres:link Link the postgres service to the app +postgres:link [--user user] [--database database] Link the postgres service to the app 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 @@ -39,7 +41,7 @@ postgres:restart Graceful shutdown and restart of the postgres postgres:start Start a previously stopped postgres service postgres:stop Stop a running postgres service postgres:unexpose Unexpose a previously exposed postgres service -postgres:unlink Unlink the postgres service from the app +postgres:unlink [--user user] [--database database] Unlink the postgres service from the app ``` ## usage