diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 313f059..9d47985 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,6 +1,12 @@ +--- version: 2 updates: - package-ecosystem: "docker" directory: "/" schedule: interval: "daily" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 89fe4e7..06f39ab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,21 +10,23 @@ on: branches: - master +concurrency: + group: build-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: unit-tests-master: name: unit-tests - runs-on: ubuntu-18.04 - strategy: - fail-fast: true + runs-on: ubuntu-20.04 env: DOKKU_VERSION: master steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v4 with: python-version: '3.7.x' @@ -49,7 +51,7 @@ jobs: - run: make test - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 if: failure() with: name: tmp/test-results @@ -57,18 +59,16 @@ jobs: unit-tests-0_19_0: name: unit-tests-0.19.0 - runs-on: ubuntu-18.04 - strategy: - fail-fast: true + runs-on: ubuntu-20.04 env: DOKKU_TAG: v0.19.0 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v4 with: python-version: '3.7.x' @@ -93,7 +93,7 @@ jobs: - run: make test - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 if: failure() with: name: tmp/test-results diff --git a/.github/workflows/tagged-release.yml b/.github/workflows/tagged-release.yml new file mode 100644 index 0000000..846c457 --- /dev/null +++ b/.github/workflows/tagged-release.yml @@ -0,0 +1,19 @@ +--- +name: "tagged-release" + +# yamllint disable-line rule:truthy +on: + push: + tags: + - '*' + +jobs: + tagged-release: + name: tagged-release + runs-on: ubuntu-20.04 + + steps: + - uses: "marvinpinto/action-automatic-releases@v1.2.1" + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + prerelease: false diff --git a/Dockerfile b/Dockerfile index 113d98e..43c80f9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1 +1 @@ -FROM postgres:14.4 +FROM postgres:15.3 diff --git a/README.md b/README.md index 6e46a4f..f712160 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# dokku postgres [![Build Status](https://img.shields.io/github/workflow/status/dokku/dokku-postgres/CI/master?style=flat-square "Build Status")](https://github.com/dokku/dokku-postgres/actions/workflows/ci.yml?query=branch%3Amaster) [![IRC Network](https://img.shields.io/badge/irc-libera-blue.svg?style=flat-square "IRC Libera")](https://webchat.libera.chat/?channels=dokku) +# dokku postgres [![Build Status](https://img.shields.io/github/actions/workflow/status/dokku/dokku-postgres/ci.yml?branch=master&style=flat-square "Build Status")](https://github.com/dokku/dokku-postgres/actions/workflows/ci.yml?query=branch%3Amaster) [![IRC Network](https://img.shields.io/badge/irc-libera-blue.svg?style=flat-square "IRC Libera")](https://webchat.libera.chat/?channels=dokku) -Official postgres plugin for dokku. Currently defaults to installing [postgres 14.4](https://hub.docker.com/_/postgres/). +Official postgres plugin for dokku. Currently defaults to installing [postgres 15.3](https://hub.docker.com/_/postgres/). ## Requirements @@ -41,8 +41,10 @@ postgres:linked # check if the postgres servi postgres:links # list all apps linked to the postgres service postgres:list # list all postgres services postgres:logs [-t|--tail] # print the most recent log(s) for this service +postgres:pause # pause a running postgres service postgres:promote # promote service as DATABASE_URL in postgres:restart # graceful shutdown and restart of the postgres service container +postgres:set # set or clear a property for a service postgres:start # start a previously stopped postgres service postgres:stop # stop a running postgres service postgres:unexpose # unexpose a previously exposed postgres service @@ -70,8 +72,11 @@ flags: - `-i|--image IMAGE`: the image name to start the service with - `-I|--image-version IMAGE_VERSION`: the image version to start the service with - `-m|--memory MEMORY`: container memory limit in megabytes (default: unlimited) +- `-N|--initial-network INITIAL_NETWORK`: the initial network to attach the service to - `-p|--password PASSWORD`: override the user-level service password +- `-P|--post-create-network NETWORKS`: a comman-separated list of networks to attach the service container to after service creation - `-r|--root-password PASSWORD`: override the root-level service password +- `-S|--post-start-network NETWORKS`: a comman-separated list of networks to attach the service container to after service start - `-s|--shm-size SHM_SIZE`: override shared memory size for postgres docker container Create a postgres service named lollipop: @@ -95,7 +100,7 @@ export POSTGRES_CUSTOM_ENV="USER=alpha;HOST=beta" dokku postgres:create lollipop ``` -Official Postgres docker images does not include postgis extension (amongst others). The following example creates a new postgres service using `postgis/postgis:13-3.1` image, which includes the `postgis` extension. +Official Postgres "$DOCKER_BIN" image ls does not include postgis extension (amongst others). The following example creates a new postgres service using `postgis/postgis:13-3.1` image, which includes the `postgis` extension. ```shell dokku postgres:create postgis-database --image "postgis/postgis" --image-version "13-3.1" @@ -116,7 +121,10 @@ flags: - `--exposed-ports`: show service exposed ports - `--id`: show the service container id - `--internal-ip`: show the service internal ip +- `--initial-network`: show the initial network being connected to - `--links`: show the service app links +- `--post-create-network`: show the networks to attach to after service container creation +- `--post-start-network`: show the networks to attach to after service container start - `--service-root`: show the service root directory - `--status`: show the service running status - `--version`: show the service image version @@ -136,7 +144,10 @@ dokku postgres:info lollipop --dsn dokku postgres:info lollipop --exposed-ports dokku postgres:info lollipop --id dokku postgres:info lollipop --internal-ip +dokku postgres:info lollipop --initial-network dokku postgres:info lollipop --links +dokku postgres:info lollipop --post-create-network +dokku postgres:info lollipop --post-start-network dokku postgres:info lollipop --service-root dokku postgres:info lollipop --status dokku postgres:info lollipop --version @@ -195,6 +206,7 @@ flags: - `-a|--alias "BLUE_DATABASE"`: an alternative alias to use for linking to an app via environment variable - `-q|--querystring "pool=5"`: ampersand delimited querystring arguments to append to the service link +- `-n|--no-restart "false"`: whether or not to restart the app on link (default: true) A postgres service can be linked to a container. This will use native docker links via the docker-options plugin. Here we link it to our `playground` app. @@ -247,6 +259,10 @@ postgres2://lollipop:SOME_PASSWORD@dokku-postgres-lollipop:5432/lollipop dokku postgres:unlink ``` +flags: + +- `-n|--no-restart "false"`: whether or not to restart the app on unlink (default: true) + You can unlink a postgres service: > NOTE: this will restart your app and unset related environment variables @@ -255,6 +271,31 @@ You can unlink a postgres service: dokku postgres:unlink lollipop playground ``` +### set or clear a property for a service + +```shell +# usage +dokku postgres:set +``` + +Set the network to attach after the service container is started: + +```shell +dokku postgres:set lollipop post-create-network custom-network +``` + +Set multiple networks: + +```shell +dokku postgres:set lollipop post-create-network custom-network,other-network +``` + +Unset the post-create-network value: + +```shell +dokku postgres:set lollipop post-create-network +``` + ### Service Lifecycle The lifecycle of each service can be managed through the following commands: @@ -376,12 +417,25 @@ dokku postgres:start lollipop dokku postgres:stop ``` -Stop the service and the running container: +Stop the service and removes the running container: ```shell dokku postgres:stop lollipop ``` +### pause a running postgres service + +```shell +# usage +dokku postgres:pause +``` + +Pause the running container for the service: + +```shell +dokku postgres:pause lollipop +``` + ### graceful shutdown and restart of the postgres service container ```shell @@ -408,7 +462,10 @@ flags: - `-C|--custom-env "USER=alpha;HOST=beta"`: semi-colon delimited environment variables to start the service with - `-i|--image IMAGE`: the image name to start the service with - `-I|--image-version IMAGE_VERSION`: the image version to start the service with -- `-R|--restart-apps "true"`: whether to force an app restart +- `-N|--initial-network INITIAL_NETWORK`: the initial network to attach the service to +- `-P|--post-create-network NETWORKS`: a comman-separated list of networks to attach the service container to after service creation +- `-R|--restart-apps "true"`: whether or not to force an app restart (default: false) +- `-S|--post-start-network NETWORKS`: a comman-separated list of networks to attach the service container to after service start - `-s|--shm-size SHM_SIZE`: override shared memory size for postgres docker container You can upgrade an existing service to a new image or image-version: @@ -479,8 +536,11 @@ flags: - `-i|--image IMAGE`: the image name to start the service with - `-I|--image-version IMAGE_VERSION`: the image version to start the service with - `-m|--memory MEMORY`: container memory limit in megabytes (default: unlimited) +- `-N|--initial-network INITIAL_NETWORK`: the initial network to attach the service to - `-p|--password PASSWORD`: override the user-level service password +- `-P|--post-create-network NETWORKS`: a comman-separated list of networks to attach the service container to after service creation - `-r|--root-password PASSWORD`: override the root-level service password +- `-S|--post-start-network NETWORKS`: a comman-separated list of networks to attach the service container to after service start - `-s|--shm-size SHM_SIZE`: override shared memory size for postgres docker container You can clone an existing service to a new one: @@ -722,8 +782,8 @@ Remove the scheduled backup from cron: dokku postgres:backup-unschedule lollipop ``` -### Disabling `docker pull` calls +### Disabling `docker image pull` calls -If you wish to disable the `docker pull` calls that the plugin triggers, you may set the `POSTGRES_DISABLE_PULL` environment variable to `true`. Once disabled, you will need to pull the service image you wish to deploy as shown in the `stderr` output. +If you wish to disable the `docker image pull` calls that the plugin triggers, you may set the `POSTGRES_DISABLE_PULL` environment variable to `true`. Once disabled, you will need to pull the service image you wish to deploy as shown in the `stderr` output. -Please ensure the proper images are in place when `docker pull` is disabled. +Please ensure the proper images are in place when `docker image pull` is disabled. diff --git a/Vagrantfile b/Vagrantfile index e17cf9a..4aec135 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -1,7 +1,7 @@ # -*- mode: ruby -*- # vi: set ft=ruby : -BOX_NAME = ENV["BOX_NAME"] || "bento/ubuntu-18.04" +BOX_NAME = ENV["BOX_NAME"] || "bento/ubuntu-20.04" BOX_MEMORY = ENV["BOX_MEMORY"] || "2048" DOKKU_VERSION = "master" diff --git a/bin/generate b/bin/generate index 2e19392..89b9999 100755 --- a/bin/generate +++ b/bin/generate @@ -35,7 +35,7 @@ def header(service): return " ".join( [ f"# dokku {service}", - f'[![Build Status](https://img.shields.io/github/workflow/status/dokku/dokku-{service}/CI/master?style=flat-square "Build Status")](https://github.com/dokku/dokku-{service}/actions/workflows/ci.yml?query=branch%3Amaster)', + f'[![Build Status](https://img.shields.io/github/actions/workflow/status/dokku/dokku-{service}/ci.yml?branch=master&style=flat-square "Build Status")](https://github.com/dokku/dokku-{service}/actions/workflows/ci.yml?query=branch%3Amaster)', f'[![IRC Network](https://img.shields.io/badge/irc-libera-blue.svg?style=flat-square "IRC Libera")](https://webchat.libera.chat/?channels=dokku)', ] ) @@ -131,7 +131,7 @@ def usage_section(service, variable, alias, image, scheme, ports, options, unimp def usage_intro(service, variable, alias, image, scheme, ports, options, unimplemented): - commands = ["create", "info", "list", "logs", "link", "unlink"] + commands = ["create", "info", "list", "logs", "link", "unlink", "set"] content = ["### Basic Usage"] return fetch_commands_content( @@ -148,6 +148,7 @@ def usage_lifecycle(service, variable, alias, image, scheme, ports, options, uni "promote", "start", "stop", + "pause", "restart", "upgrade", ] @@ -222,11 +223,11 @@ def usage_docker_pull(service, variable, alias, image, scheme, ports, options, u service_prefix = service.upper() return "\n".join( [ - "### Disabling `docker pull` calls", + "### Disabling `docker image pull` calls", "", - f"If you wish to disable the `docker pull` calls that the plugin triggers, you may set the `{service_prefix}_DISABLE_PULL` environment variable to `true`. Once disabled, you will need to pull the service image you wish to deploy as shown in the `stderr` output.", + f"If you wish to disable the `docker image pull` calls that the plugin triggers, you may set the `{service_prefix}_DISABLE_PULL` environment variable to `true`. Once disabled, you will need to pull the service image you wish to deploy as shown in the `stderr` output.", "", - "Please ensure the proper images are in place when `docker pull` is disabled.", + "Please ensure the proper images are in place when `docker image pull` is disabled.", ] ) diff --git a/commands b/commands index 2fb4cda..0b22b42 100755 --- a/commands +++ b/commands @@ -2,6 +2,7 @@ source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/config" [[ " help $PLUGIN_COMMAND_PREFIX:help $PLUGIN_COMMAND_PREFIX $PLUGIN_COMMAND_PREFIX:default " == *" $1 "* ]] || [[ "$1" == "$PLUGIN_COMMAND_PREFIX:"* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT" source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" + set -eo pipefail [[ $DOKKU_TRACE ]] && set -x diff --git a/common-functions b/common-functions index d2630be..168a48d 100755 --- a/common-functions +++ b/common-functions @@ -2,6 +2,7 @@ source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x +source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions" source "$PLUGIN_AVAILABLE_PATH/config/functions" add_to_links_file() { @@ -61,7 +62,7 @@ fn-services-list() { [[ -d $f ]] || continue services+=("$f") done - popd &>/dev/null || pushd "/tmp" >/dev/null + popd >/dev/null 2>&1 || pushd "/tmp" >/dev/null if [[ "${#services[@]}" -eq 0 ]]; then return @@ -94,7 +95,7 @@ docker_ports_options() { get_container_ip() { declare desc="retrieve the ip address of a container" declare CONTAINER_ID="$1" - docker inspect --format '{{ .NetworkSettings.IPAddress }}' "$CONTAINER_ID" 2>/dev/null + "$DOCKER_BIN" container inspect --format '{{ .NetworkSettings.IPAddress }}' "$CONTAINER_ID" 2>/dev/null } get_database_name() { @@ -153,7 +154,7 @@ is_container_status() { declare desc="return 0 or 1 depending upon whether a given container has a certain status" declare CID="$1" STATUS="$2" local TEMPLATE="{{.State.$STATUS}}" - local CONTAINER_STATUS=$(docker inspect -f "$TEMPLATE" "$CID" 2>/dev/null || true) + local CONTAINER_STATUS=$("$DOCKER_BIN" container inspect -f "$TEMPLATE" "$CID" 2>/dev/null || true) if [[ "$CONTAINER_STATUS" == "true" ]]; then return 0 @@ -208,7 +209,7 @@ retry-docker-command() { local i=0 success=false until [ $i -ge 100 ]; do set +e - suppress_output docker exec "$ID" sh -c "$COMMAND" + suppress_output "$DOCKER_BIN" container exec "$ID" sh -c "$COMMAND" exit_code=$? set -e if [[ "$exit_code" == 0 ]]; then @@ -281,7 +282,7 @@ service_backup() { BACKUP_TMPDIR=$(mktemp -d --tmpdir) trap 'rm -rf "$BACKUP_TMPDIR" > /dev/null' RETURN INT TERM EXIT - docker inspect "$ID" &>/dev/null || dokku_log_fail "Service container does not exist" + "$DOCKER_BIN" container inspect "$ID" >/dev/null 2>&1 || dokku_log_fail "Service container does not exist" is_container_status "$ID" "Running" || dokku_log_fail "Service container is not running" (service_export "$SERVICE" >"${BACKUP_TMPDIR}/export") @@ -308,7 +309,7 @@ service_backup() { fi # shellcheck disable=SC2086 - docker run --rm $BACKUP_PARAMETERS "$PLUGIN_S3BACKUP_IMAGE" + "$DOCKER_BIN" container run --rm $BACKUP_PARAMETERS "$PLUGIN_S3BACKUP_IMAGE" } service_commit_config() { @@ -348,6 +349,18 @@ service_commit_config() { if [[ -n "$PLUGIN_IMAGE_VERSION" ]]; then echo "$PLUGIN_IMAGE_VERSION" >"$SERVICE_ROOT/IMAGE_VERSION" fi + + if [[ -n "$SERVICE_INITIAL_NETWORK" ]]; then + fn-plugin-property-write "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "initial-network" "$SERVICE_INITIAL_NETWORK" + fi + + if [[ -n "$SERVICE_POST_CREATE_NETWORK" ]]; then + fn-plugin-property-write "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "post-create-network" "$SERVICE_POST_CREATE_NETWORK" + fi + + if [[ -n "$SERVICE_POST_START_NETWORK" ]]; then + fn-plugin-property-write "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "post-start-network" "$SERVICE_POST_START_NETWORK" + fi } service_backup_auth() { @@ -443,16 +456,16 @@ service_container_rm() { local SERVICE_NAME="$(get_service_name "$SERVICE")" local ID - service_stop "$SERVICE" - ID=$(docker ps -aq --no-trunc --filter "name=^/$SERVICE_NAME$" --format '{{ .ID }}') || true + service_pause "$SERVICE" + ID=$("$DOCKER_BIN" container ps -aq --no-trunc --filter "name=^/$SERVICE_NAME$" --format '{{ .ID }}') || true # this may be 'true' in tests... if [[ -z "$ID" ]] || [[ "$ID" == "true" ]]; then return 0 fi dokku_log_verbose_quiet "Removing container" - docker update --restart=no "$SERVICE_NAME" >/dev/null 2>&1 - if ! docker rm "$SERVICE_NAME" >/dev/null 2>&1; then + "$DOCKER_BIN" container update --restart=no "$SERVICE_NAME" >/dev/null 2>&1 + if ! "$DOCKER_BIN" container rm "$SERVICE_NAME" >/dev/null 2>&1; then dokku_log_fail "Unable to remove container for service $SERVICE" fi } @@ -470,13 +483,13 @@ service_enter() { local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" local ID="$(cat "$SERVICE_ROOT/ID")" - docker inspect "$ID" &>/dev/null || dokku_log_fail "Service container does not exist" + "$DOCKER_BIN" container inspect "$ID" >/dev/null 2>&1 || dokku_log_fail "Service container does not exist" is_container_status "$ID" "Running" || dokku_log_fail "Service container is not running" local EXEC_CMD="" has_tty && local DOKKU_RUN_OPTS+=" -i -t" # shellcheck disable=SC2086 - docker exec $DOKKU_RUN_OPTS $ID $EXEC_CMD "${@:-/bin/bash}" + "$DOCKER_BIN" container exec $DOKKU_RUN_OPTS $ID $EXEC_CMD "${@:-/bin/bash}" } service_exists() { @@ -501,15 +514,21 @@ service_exposed_ports() { service_image_exists() { declare desc="check if the current image exists" - declare SERVICE="$1" + declare SERVICE="$1" PLUGIN_IMAGE="${2:-$PLUGIN_IMAGE}" PLUGIN_IMAGE_VERSION="${3:-$PLUGIN_IMAGE_VERSION}" local plugin_image="$PLUGIN_IMAGE" local plugin_image_version="$PLUGIN_IMAGE_VERSION" - [[ -f "$SERVICE_ROOT/IMAGE" ]] && plugin_image="$(cat "$SERVICE_ROOT/IMAGE")" - [[ -f "$SERVICE_ROOT/IMAGE_VERSION" ]] && plugin_image_version="$(cat "$SERVICE_ROOT/IMAGE_VERSION")" + if [[ -z "$PLUGIN_IMAGE" ]] && [[ -f "$SERVICE_ROOT/IMAGE" ]]; then + plugin_image="$(cat "$SERVICE_ROOT/IMAGE")" + fi + + if [[ -z "$PLUGIN_IMAGE_VERSION" ]] && [[ -f "$SERVICE_ROOT/IMAGE_VERSION" ]]; then + plugin_image_version="$(cat "$SERVICE_ROOT/IMAGE_VERSION")" + fi + local IMAGE="$plugin_image:$plugin_image_version" - if [[ "$(docker images -q "$IMAGE" 2>/dev/null)" == "" ]]; then + if [[ "$("$DOCKER_BIN" image ls -q "$IMAGE" 2>/dev/null)" == "" ]]; then return 1 fi @@ -533,7 +552,10 @@ service_info() { "--exposed-ports: $(service_exposed_ports "$SERVICE")" "--id: ${SERVICE_CONTAINER_ID}" "--internal-ip: $(get_container_ip "${SERVICE_CONTAINER_ID}")" + "--initial-network: $(fn-plugin-property-get "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "initial-network")" "--links: $(service_linked_apps "$SERVICE")" + "--post-create-network: $(fn-plugin-property-get "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "post-create-network")" + "--post-start-network: $(fn-plugin-property-get "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "post-start-network")" "--service-root: ${SERVICE_ROOT}" "--status: $(service_status "$SERVICE")" "--version: $(service_version "$SERVICE")" @@ -609,8 +631,9 @@ service_link() { fi [[ -n "$SERVICE_QUERYSTRING" ]] && SERVICE_URL="${SERVICE_URL}?${SERVICE_QUERYSTRING}" plugn trigger service-action post-link "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "$APP" - if [[ "$DOKKU_GLOBAL_FLAGS" == *"--no-restart"* ]]; then + if [[ "$DOKKU_GLOBAL_FLAGS" == *"--no-restart"* ]] || [[ "$SERVICE_RESTART_APPS" == "false" ]]; then config_set --no-restart "$APP" "${ALIAS}_URL=$SERVICE_URL" + dokku_log_verbose "Skipping restart of linked app" else config_set "$APP" "${ALIAS}_URL=$SERVICE_URL" fi @@ -668,11 +691,11 @@ service_logs() { DOKKU_LOGS_ARGS+=" --follow" fi - docker inspect "$ID" &>/dev/null || dokku_log_fail "Service container does not exist" + "$DOCKER_BIN" container inspect "$ID" >/dev/null 2>&1 || dokku_log_fail "Service container does not exist" is_container_status "$ID" "Running" || dokku_log_warn "Service logs may not be output as service is not running" # shellcheck disable=SC2086 - docker logs $DOKKU_LOGS_ARGS "$ID" 2>&1 + "$DOCKER_BIN" container logs $DOKKU_LOGS_ARGS "$ID" 2>&1 } service_parse_args() { @@ -689,9 +712,13 @@ service_parse_args() { "--custom-env") set -- "$@" "-C" ;; "--database") set -- "$@" "-d" ;; "--image-version") set -- "$@" "-I" ;; + "--initial-network") set -- "$@" "-N" ;; "--image") set -- "$@" "-i" ;; "--memory") set -- "$@" "-m" ;; + "--no-restart") set -- "$@" "-n" ;; "--password") set -- "$@" "-p" ;; + "--post-create-network") set -- "$@" "-P" ;; + "--post-start-network") set -- "$@" "-S" ;; "--querystring") set -- "$@" "-q" ;; "--restart-apps") set -- "$@" "-R" ;; "--root-password") set -- "$@" "-r" ;; @@ -702,7 +729,7 @@ service_parse_args() { done OPTIND=1 - while getopts "a:c:C:d:i:I:m:p:q:R:r:s:u:" opt; do + while getopts "na:c:C:d:i:I:m:n:N:p:P:q:R:r:s:S:u:" opt; do case "$opt" in a) SERVICE_ALIAS="${OPTARG^^}" @@ -726,9 +753,18 @@ service_parse_args() { m) export SERVICE_MEMORY=$OPTARG ;; + n) + export SERVICE_RESTART_APPS=false + ;; + N) + export SERVICE_INITIAL_NETWORK=$OPTARG + ;; p) export SERVICE_PASSWORD=$OPTARG ;; + P) + export SERVICE_POST_CREATE_NETWORK=$OPTARG + ;; q) export SERVICE_QUERYSTRING=${OPTARG#"?"} ;; @@ -741,6 +777,9 @@ service_parse_args() { s) export SERVICE_SHM_SIZE=$OPTARG ;; + S) + export SERVICE_POST_START_NETWORK=$OPTARG + ;; u) export SERVICE_USER=$OPTARG ;; @@ -771,39 +810,36 @@ service_root_password() { service_port_expose() { declare desc="wrapper for exposing service ports" - declare SERVICE="$1" - service_start "$SERVICE" "true" - service_port_unpause "$SERVICE" "true" "${@:2}" -} - -service_port_pause() { - declare desc="pause service exposure" - declare SERVICE="$1" LOG_FAIL="$2" + declare SERVICE="$1" PORTS=(${@:2}) local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" - local EXPOSED_NAME="$(get_service_name "$SERVICE").ambassador" local PORT_FILE="$SERVICE_ROOT/PORT" + local SERVICE_NAME="$(get_service_name "$SERVICE")" + local EXPOSED_NAME="$SERVICE_NAME.ambassador" - if [[ "$LOG_FAIL" == "true" ]]; then - [[ ! -f "$PORT_FILE" ]] && dokku_log_fail "Service not exposed" - else - [[ ! -f "$PORT_FILE" ]] && return 0 + if [[ ${#PORTS[@]} -eq 0 ]]; then + # shellcheck disable=SC2206 + PORTS=(${PORTS[@]:-$(get_random_ports ${#PLUGIN_DATASTORE_PORTS[@]})}) fi - local GREP_NAME="^/${EXPOSED_NAME}$" - local CONTAINER_NAME="$(docker ps -f name="$GREP_NAME" --format "{{.Names}}")" - if [[ -z "$CONTAINER_NAME" ]]; then - if [[ "$LOG_FAIL" == "true" ]]; then - dokku_log_info1 "Service $SERVICE unexposed" - fi + [[ "${#PORTS[@]}" != "${#PLUGIN_DATASTORE_PORTS[@]}" ]] && dokku_log_fail "${#PLUGIN_DATASTORE_PORTS[@]} ports to be exposed need to be provided in the following order: ${PLUGIN_DATASTORE_PORTS[*]}" - return + if [[ -s "$PORT_FILE" ]]; then + # shellcheck disable=SC2207 + PORTS=($(cat "$PORT_FILE")) + dokku_log_fail "Service $SERVICE already exposed on port(s) ${PORTS[*]}" fi - docker stop "$EXPOSED_NAME" >/dev/null 2>&1 || true - docker rm "$EXPOSED_NAME" >/dev/null 2>&1 || true - if [[ "$LOG_FAIL" == "true" ]]; then - dokku_log_info1 "Service $SERVICE unexposed" + if "$DOCKER_BIN" container inspect "$EXPOSED_NAME" >/dev/null 2>&1; then + dokku_log_warn "Service $SERVICE has an untracked expose container, removing" + "$DOCKER_BIN" container stop "$EXPOSED_NAME" >/dev/null 2>&1 || true + suppress_output "$DOCKER_BIN" container rm "$EXPOSED_NAME" fi + + echo "${PORTS[@]}" >"$PORT_FILE" + + service_start "$SERVICE" "true" + service_port_reconcile_status "$SERVICE" + dokku_log_info1 "Service $SERVICE exposed on port(s) [container->host]: $(service_exposed_ports "$SERVICE")" } service_port_unexpose() { @@ -811,39 +847,41 @@ service_port_unexpose() { declare 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_reconcile_status "$SERVICE" + dokku_log_info1 "Service $SERVICE unexposed" } -service_port_unpause() { - declare desc="start service exposure" - declare SERVICE="$1" LOG_FAIL="$2" +service_port_reconcile_status() { + declare 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" - # shellcheck disable=SC2068 - local PORTS=(${@:3}) - # shellcheck disable=SC2068 - PORTS=(${PORTS[@]:-$(get_random_ports ${#PLUGIN_DATASTORE_PORTS[@]})}) - local ID=$(cat "$SERVICE_ROOT/ID") + local SERVICE_NAME="$(get_service_name "$SERVICE")" + local EXPOSED_NAME="$SERVICE_NAME.ambassador" - [[ "${#PORTS[@]}" != "${#PLUGIN_DATASTORE_PORTS[@]}" ]] && dokku_log_fail "${#PLUGIN_DATASTORE_PORTS[@]} ports to be exposed need to be provided in the following order: ${PLUGIN_DATASTORE_PORTS[*]}" - - if [[ "$LOG_FAIL" == "true" ]]; then - [[ -f "$PORT_FILE" ]] && PORTS=($(cat "$PORT_FILE")) && dokku_log_fail "Service $SERVICE already exposed on port(s) ${PORTS[*]}" - else - [[ ! -f "$PORT_FILE" ]] && return 0 - PORTS=($(cat "$PORT_FILE")) + if [[ ! -s "$PORT_FILE" ]]; then + if "$DOCKER_BIN" container inspect "$EXPOSED_NAME" >/dev/null 2>&1; then + "$DOCKER_BIN" container stop "$EXPOSED_NAME" >/dev/null 2>&1 || true + suppress_output "$DOCKER_BIN" container rm "$EXPOSED_NAME" + return $? + fi + return fi - echo "${PORTS[@]}" >"$PORT_FILE" + if is_container_status "$EXPOSED_NAME" "Running"; then + return + fi + if "$DOCKER_BIN" container inspect "$EXPOSED_NAME" >/dev/null 2>&1; then + suppress_output "$DOCKER_BIN" container start "$EXPOSED_NAME" + return $? + fi + + # shellcheck disable=SC2207 + PORTS=($(cat "$PORT_FILE")) # shellcheck disable=SC2046 - docker run -d --link "$SERVICE_NAME:$PLUGIN_COMMAND_PREFIX" --name "$EXPOSED_NAME" $(docker_ports_options "${PORTS[@]}") --restart always --label dokku=ambassador --label "dokku.ambassador=$PLUGIN_COMMAND_PREFIX" "$PLUGIN_AMBASSADOR_IMAGE" >/dev/null - if [[ "$LOG_FAIL" == "true" ]]; then - dokku_log_info1 "Service $SERVICE exposed on port(s) [container->host]: $(service_exposed_ports "$SERVICE")" - fi + "$DOCKER_BIN" container run -d --link "$SERVICE_NAME:$PLUGIN_COMMAND_PREFIX" --name "$EXPOSED_NAME" $(docker_ports_options "${PORTS[@]}") --restart always --label dokku=ambassador --label "dokku.ambassador=$PLUGIN_COMMAND_PREFIX" "$PLUGIN_AMBASSADOR_IMAGE" >/dev/null } service_promote() { @@ -891,24 +929,26 @@ service_status() { local ID="$(cat "$SERVICE_ROOT/ID")" local CONTAINER_STATUS - CONTAINER_STATUS=$(docker inspect -f "{{.State.Status}}" "$ID" 2>/dev/null || true) + CONTAINER_STATUS=$("$DOCKER_BIN" container inspect -f "{{.State.Status}}" "$ID" 2>/dev/null || true) [[ -n "$CONTAINER_STATUS" ]] && echo "$CONTAINER_STATUS" && return 0 echo "missing" && return 0 } -service_stop() { - declare desc="stop a running service" +service_pause() { + declare desc="pause a running service" declare SERVICE="$1" local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" local SERVICE_NAME="$(get_service_name "$SERVICE")" - local ID=$(docker ps -aq --no-trunc --filter "name=^/$SERVICE_NAME$" --format '{{ .ID }}') || true - [[ -z $ID ]] && dokku_log_warn "Service is already stopped" && return 0 + local ID=$("$DOCKER_BIN" container ps -aq --no-trunc --filter "name=^/$SERVICE_NAME$" --format '{{ .ID }}') || true + [[ -z $ID ]] && dokku_log_warn "Service is already paused" && return 0 if [[ -n $ID ]]; then - dokku_log_info2_quiet "Stopping container" - docker stop "$SERVICE_NAME" >/dev/null - service_port_pause "$SERVICE" - dokku_log_verbose_quiet "Container stopped" + dokku_log_info2_quiet "Pausing container" + "$DOCKER_BIN" container stop "$SERVICE_NAME" >/dev/null + if "$DOCKER_BIN" container inspect "$ID" >/dev/null 2>&1; then + "$DOCKER_BIN" container stop "$SERVICE_NAME.ambassador" >/dev/null 2>&1 || true + fi + dokku_log_verbose_quiet "Container paused" else dokku_log_verbose_quiet "No container exists for $SERVICE" fi @@ -937,8 +977,9 @@ service_unlink() { [[ -z ${LINK[*]} ]] && dokku_log_fail "Not linked to app $APP" plugn trigger service-action post-unlink "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "$APP" - if [[ "$DOKKU_GLOBAL_FLAGS" == *"--no-restart"* ]]; then + if [[ "$DOKKU_GLOBAL_FLAGS" == *"--no-restart"* ]] || [[ "$SERVICE_RESTART_APPS" == "false" ]]; then config_unset --no-restart "$APP" "${LINK[@]}" + dokku_log_verbose "Skipping restart of linked app" else config_unset "$APP" "${LINK[@]}" fi @@ -949,7 +990,7 @@ service_version() { declare desc="display the running version for an image" declare SERVICE="$1" local SERVICE_NAME="$(get_service_name "$SERVICE")" - docker inspect -f '{{.Config.Image}}' "$SERVICE_NAME" 2>/dev/null || true + "$DOCKER_BIN" container inspect -f '{{.Config.Image}}' "$SERVICE_NAME" 2>/dev/null || true } update_plugin_scheme_for_app() { diff --git a/config b/config index 3931d44..2743176 100644 --- a/config +++ b/config @@ -3,7 +3,8 @@ _DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" export POSTGRES_IMAGE=${POSTGRES_IMAGE:="$(awk -F '[ :]' '{print $2}' "${_DIR}/Dockerfile")"} export POSTGRES_IMAGE_VERSION=${POSTGRES_IMAGE_VERSION:="$(awk -F '[ :]' '{print $3}' "${_DIR}/Dockerfile")"} export POSTGRES_ROOT=${POSTGRES_ROOT:="$DOKKU_LIB_ROOT/services/postgres"} -export POSTGRES_HOST_ROOT=${POSTGRES_HOST_ROOT:=$POSTGRES_ROOT} +export DOKKU_LIB_HOST_ROOT=${DOKKU_LIB_HOST_ROOT:=$DOKKU_LIB_ROOT} +export POSTGRES_HOST_ROOT=${POSTGRES_HOST_ROOT:="$DOKKU_LIB_HOST_ROOT/services/postgres"} export PLUGIN_UNIMPLEMENTED_SUBCOMMANDS=() export PLUGIN_COMMAND_PREFIX="postgres" @@ -27,9 +28,9 @@ if [[ -n $DOKKU_API_VERSION ]]; then export PLUGIN_BASE_PATH="$PLUGIN_ENABLED_PATH" fi -export PLUGIN_BUSYBOX_IMAGE="busybox:1.31.1-uclibc" -export PLUGIN_AMBASSADOR_IMAGE="dokku/ambassador:0.3.3" -export PLUGIN_S3BACKUP_IMAGE="dokku/s3backup:0.10.3" -export PLUGIN_WAIT_IMAGE="dokku/wait:0.4.3" +export PLUGIN_BUSYBOX_IMAGE="busybox:1.34.1-uclibc" +export PLUGIN_AMBASSADOR_IMAGE="dokku/ambassador:0.5.0" +export PLUGIN_S3BACKUP_IMAGE="dokku/s3backup:0.14.0" +export PLUGIN_WAIT_IMAGE="dokku/wait:0.6.0" export POSTGRES_CONFIG_OPTIONS=${POSTGRES_CONFIG_OPTIONS:=""} diff --git a/docs/create.md b/docs/create.md index fecb7a5..1d70706 100644 --- a/docs/create.md +++ b/docs/create.md @@ -1,4 +1,4 @@ -Official Postgres docker images does not include postgis extension (amongst others). The following example creates a new postgres service using `postgis/postgis:13-3.1` image, which includes the `postgis` extension. +Official Postgres "$DOCKER_BIN" image ls does not include postgis extension (amongst others). The following example creates a new postgres service using `postgis/postgis:13-3.1` image, which includes the `postgis` extension. ```shell dokku postgres:create postgis-database --image "postgis/postgis" --image-version "13-3.1" diff --git a/functions b/functions index aaa4b96..c60a132 100755 --- a/functions +++ b/functions @@ -4,6 +4,7 @@ set -eo pipefail [[ $DOKKU_TRACE ]] && set -x source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common-functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions" source "$PLUGIN_AVAILABLE_PATH/config/functions" if [[ -f "$PLUGIN_AVAILABLE_PATH/docker-options/functions" ]]; then source "$PLUGIN_AVAILABLE_PATH/docker-options/functions" @@ -17,7 +18,7 @@ service_connect() { local SERVICE_TTY_OPTS has_tty && SERVICE_TTY_OPTS="-t" - docker exec --env=LANG=C.UTF-8 --env=LC_ALL=C.UTF-8 -i $SERVICE_TTY_OPTS "$SERVICE_NAME" psql -h localhost -U postgres "$DATABASE_NAME" + "$DOCKER_BIN" container exec --env=LANG=C.UTF-8 --env=LC_ALL=C.UTF-8 -i $SERVICE_TTY_OPTS "$SERVICE_NAME" psql -h localhost -U postgres "$DATABASE_NAME" } service_create() { @@ -33,11 +34,11 @@ service_create() { if ! service_image_exists "$SERVICE"; then if [[ "$PLUGIN_DISABLE_PULL" == "true" ]]; then dokku_log_warn "${PLUGIN_DISABLE_PULL_VARIABLE} environment variable detected. Not running pull command." 1>&2 - dokku_log_warn " docker pull ${IMAGE}" 1>&2 + dokku_log_warn " docker image pull ${IMAGE}" 1>&2 dokku_log_warn "$PLUGIN_SERVICE service creation failed" exit 1 fi - docker pull "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION" || dokku_log_fail "$PLUGIN_SERVICE image $PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION pull failed" + "$DOCKER_BIN" image pull "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION" || dokku_log_fail "$PLUGIN_SERVICE image $PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION pull failed" fi plugn trigger service-action pre-create "$PLUGIN_COMMAND_PREFIX" "$SERVICE" @@ -73,38 +74,87 @@ service_create_container() { export CONFIG_OPTIONS="$(cat "$SERVICE_ROOT/CONFIG_OPTIONS")" fi + local network_alias="$(service_dns_hostname "$SERVICE")" + + rm -f "$SERVICE_ROOT/ID" + declare -a DOCKER_ARGS + DOCKER_ARGS=() + DOCKER_ARGS+=("--cidfile=$SERVICE_ROOT/ID") + DOCKER_ARGS+=("--env-file=$SERVICE_ROOT/ENV") + DOCKER_ARGS+=("--env=POSTGRES_PASSWORD=$PASSWORD") + DOCKER_ARGS+=("--hostname=$SERVICE_NAME") + DOCKER_ARGS+=("--label=dokku.service=$PLUGIN_COMMAND_PREFIX") + DOCKER_ARGS+=("--label=dokku=service") + DOCKER_ARGS+=("--name=$SERVICE_NAME") + DOCKER_ARGS+=("--restart=always") + DOCKER_ARGS+=("--volume=$SERVICE_HOST_ROOT/data:/var/lib/postgresql/data") + + declare -a LINK_CONTAINER_DOCKER_ARGS + LINK_CONTAINER_DOCKER_ARGS=() + LINK_CONTAINER_DOCKER_ARGS+=("--rm") + LINK_CONTAINER_DOCKER_ARGS+=("--link") + LINK_CONTAINER_DOCKER_ARGS+=("$SERVICE_NAME:$network_alias") + [[ -f "$SERVICE_ROOT/SERVICE_MEMORY" ]] && SERVICE_MEMORY="$(cat "$SERVICE_ROOT/SERVICE_MEMORY")" if [[ -n "$SERVICE_MEMORY" ]]; then - MEMORY_LIMIT="--memory=${SERVICE_MEMORY}m" + DOCKER_ARGS+=("--memory=${SERVICE_MEMORY}m") fi [[ -f "$SERVICE_ROOT/SHM_SIZE" ]] && SERVICE_SHM_SIZE="$(cat "$SERVICE_ROOT/SHM_SIZE")" if [[ -n "$SERVICE_SHM_SIZE" ]]; then - SHM_SIZE="--shm-size=${SERVICE_SHM_SIZE}" + DOCKER_ARGS+=("--shm-size=${SERVICE_SHM_SIZE}") fi [[ -f "$SERVICE_ROOT/IMAGE" ]] && PLUGIN_IMAGE="$(cat "$SERVICE_ROOT/IMAGE")" [[ -f "$SERVICE_ROOT/IMAGE_VERSION" ]] && PLUGIN_IMAGE_VERSION="$(cat "$SERVICE_ROOT/IMAGE_VERSION")" + local network="$(fn-plugin-property-get "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "initial-network")" + if [[ -n "$network" ]]; then + DOCKER_ARGS+=("--network=${network}") + DOCKER_ARGS+=("--network-alias=${network_alias}") + LINK_CONTAINER_DOCKER_ARGS+=("--network=${network}") + fi + # shellcheck disable=SC2086 - ID=$(docker run --name "$SERVICE_NAME" $MEMORY_LIMIT $SHM_SIZE -v "$SERVICE_HOST_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" $CONFIG_OPTIONS) - echo "$ID" >"$SERVICE_ROOT/ID" + suppress_output "$DOCKER_BIN" container create "${DOCKER_ARGS[@]}" "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION" $CONFIG_OPTIONS + + if [[ -n "$(fn-plugin-property-get "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "post-create-network")" ]]; then + dokku_log_verbose_quiet "Connecting to networks after container create" + while read -r line || [[ -n "$line" ]]; do + dokku_log_verbose_quiet "- $line" + "$DOCKER_BIN" network connect --alias "$network_alias" "$line" "$SERVICE_NAME" + done < <(fn-plugin-property-get "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "post-create-network" | tr "," "\n") + fi + suppress_output "$DOCKER_BIN" container start "$(cat "$SERVICE_ROOT/ID")" + service_port_reconcile_status "$SERVICE" + + if [[ -n "$(fn-plugin-property-get "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "post-start-network")" ]]; then + dokku_log_verbose_quiet "Connecting to networks after container start" + while read -r line || [[ -n "$line" ]]; do + dokku_log_verbose_quiet "- $line" + "$DOCKER_BIN" network connect --alias "$network_alias" "$line" "$SERVICE_NAME" + done < <(fn-plugin-property-get "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "post-start-network" | tr "," "\n") + fi dokku_log_verbose_quiet "Waiting for container to be ready" - docker run --rm --link "$SERVICE_NAME:$PLUGIN_COMMAND_PREFIX" "$PLUGIN_WAIT_IMAGE" -p "$PLUGIN_DATASTORE_WAIT_PORT" >/dev/null + if ! suppress_output "$DOCKER_BIN" container run "${LINK_CONTAINER_DOCKER_ARGS[@]}" "$PLUGIN_WAIT_IMAGE" -c "$network_alias:$PLUGIN_DATASTORE_WAIT_PORT"; then + dokku_log_info2_quiet "Start of $SERVICE container output" + dokku_container_log_verbose_quiet "$SERVICE_NAME" + dokku_log_info2_quiet "End of $SERVICE container output" + return 1 + fi dokku_log_verbose_quiet "Creating container database" - docker exec "$SERVICE_NAME" su - postgres -c "createdb -E utf8 $DATABASE_NAME" 2>/dev/null || dokku_log_verbose_quiet 'Already exists' + "$DOCKER_BIN" container exec "$SERVICE_NAME" su - postgres -c "createdb -E utf8 $DATABASE_NAME" 2>/dev/null || dokku_log_verbose_quiet 'Already exists' dokku_log_verbose_quiet "Securing connection to database" - service_stop "$SERVICE" >/dev/null + service_pause "$SERVICE" >/dev/null "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/create_ssl_certs.sh" "$SERVICE_HOST_ROOT" &>/dev/null - docker run --rm -i -v "$SERVICE_HOST_ROOT/data:/var/lib/postgresql/data" -v "$SERVICE_HOST_ROOT/certs:/var/lib/postgresql/certs" "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION" bash -s <"$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/enable_ssl.sh" &>/dev/null + "$DOCKER_BIN" container run --rm -i -v "$SERVICE_HOST_ROOT/data:/var/lib/postgresql/data" -v "$SERVICE_HOST_ROOT/certs:/var/lib/postgresql/certs" "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION" bash -s <"$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/enable_ssl.sh" &>/dev/null rm -rf "$SERVICE_HOST_ROOT/certs" - PREVIOUS_ID=$(docker ps -aq --no-trunc --filter "status=exited" --filter "name=^/$SERVICE_NAME$" --format '{{ .ID }}') || true - docker start "$PREVIOUS_ID" >/dev/null - service_port_unpause "$SERVICE" + suppress_output "$DOCKER_BIN" container start "$(cat "$SERVICE_ROOT/ID")" + service_port_reconcile_status "$SERVICE" dokku_log_info2 "$PLUGIN_SERVICE container created: $SERVICE" service_info "$SERVICE" @@ -118,7 +168,7 @@ service_export() { local PASSWORD="$(service_password "$SERVICE")" [[ -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" + "$DOCKER_BIN" container exec "$SERVICE_NAME" env PGPASSWORD="$PASSWORD" pg_dump -Fc --no-acl --no-owner -h localhost -U postgres -w "$DATABASE_NAME" status=$? [[ -n $SSH_TTY ]] && stty opost exit $status @@ -135,7 +185,7 @@ service_import() { if [[ -t 0 ]]; then dokku_log_fail "No data provided on stdin." fi - docker exec -i "$SERVICE_NAME" env PGPASSWORD="$PASSWORD" pg_restore -h localhost -cO --if-exists -d "$DATABASE_NAME" -U postgres -w + "$DOCKER_BIN" container exec -i "$SERVICE_NAME" env PGPASSWORD="$PASSWORD" pg_restore -h localhost -cO --if-exists -d "$DATABASE_NAME" -U postgres -w } service_start() { @@ -143,7 +193,7 @@ service_start() { local QUIET="$2" local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" local SERVICE_NAME="$(get_service_name "$SERVICE")" - local ID=$(docker ps -aq --no-trunc --filter "status=running" --filter "name=^/$SERVICE_NAME$" --format '{{ .ID }}') || true + local ID=$("$DOCKER_BIN" container ps -aq --no-trunc --filter "status=running" --filter "name=^/$SERVICE_NAME$" --format '{{ .ID }}') || true if [[ -n $ID ]]; then [[ -z $QUIET ]] && dokku_log_warn "Service is already started" if [[ ! -f "$SERVICE_ROOT/ID" ]] || [[ "$(cat "$SERVICE_ROOT/ID")" != "$ID" ]]; then @@ -154,12 +204,12 @@ service_start() { fi dokku_log_info2_quiet "Starting container" - local PREVIOUS_ID=$(docker ps -aq --no-trunc --filter "status=exited" --filter "name=^/$SERVICE_NAME$" --format '{{ .ID }}') || true + local PREVIOUS_ID=$("$DOCKER_BIN" container ps -aq --no-trunc --filter "status=exited" --filter "name=^/$SERVICE_NAME$" --format '{{ .ID }}') || true local PASSWORD="$(service_password "$SERVICE")" if [[ -n $PREVIOUS_ID ]]; then - docker start "$PREVIOUS_ID" >/dev/null - service_port_unpause "$SERVICE" + "$DOCKER_BIN" container start "$PREVIOUS_ID" >/dev/null + service_port_reconcile_status "$SERVICE" dokku_log_info2 "Container started" elif service_image_exists "$SERVICE" && [[ -n "$PASSWORD" ]]; then service_create_container "$SERVICE" diff --git a/install b/install index d1ef8e3..f8fc404 100755 --- a/install +++ b/install @@ -1,6 +1,7 @@ #!/usr/bin/env bash source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/config" source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common-functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x @@ -9,14 +10,15 @@ plugin-install() { declare IMAGE="$1" if [[ "$PLUGIN_DISABLE_PULL" == "true" ]]; then echo " ! ${PLUGIN_DISABLE_PULL_VARIABLE} environment variable detected. Not running pull command." 1>&2 - echo " ! docker pull ${IMAGE}" 1>&2 + echo " ! docker image pull ${IMAGE}" 1>&2 return fi - if [[ "$(docker images -q "${IMAGE}" 2>/dev/null)" == "" ]]; then - docker pull "${IMAGE}" + if [[ "$("$DOCKER_BIN" image ls -q "${IMAGE}" 2>/dev/null)" == "" ]]; then + "$DOCKER_BIN" image pull "${IMAGE}" fi } + fn-plugin-property-setup "$PLUGIN_COMMAND_PREFIX" pull-docker-image "${PLUGIN_IMAGE}:${PLUGIN_IMAGE_VERSION}" pull-docker-image "$PLUGIN_BUSYBOX_IMAGE" pull-docker-image "$PLUGIN_AMBASSADOR_IMAGE" diff --git a/plugin.toml b/plugin.toml index a7fca9b..aad8051 100644 --- a/plugin.toml +++ b/plugin.toml @@ -1,4 +1,4 @@ [plugin] description = "dokku postgres service plugin" -version = "1.24.0" +version = "1.33.1" [plugin.config] diff --git a/subcommands/app-links b/subcommands/app-links index b6df3a1..6b0a0eb 100755 --- a/subcommands/app-links +++ b/subcommands/app-links @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-app-links-cmd() { diff --git a/subcommands/backup b/subcommands/backup index 161c191..354ed9b 100755 --- a/subcommands/backup +++ b/subcommands/backup @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-backup-cmd() { diff --git a/subcommands/backup-auth b/subcommands/backup-auth index 992b295..050397b 100755 --- a/subcommands/backup-auth +++ b/subcommands/backup-auth @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-backup-auth-cmd() { diff --git a/subcommands/backup-deauth b/subcommands/backup-deauth index d1d70cd..19cbe8a 100755 --- a/subcommands/backup-deauth +++ b/subcommands/backup-deauth @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-backup-deauth-cmd() { diff --git a/subcommands/backup-schedule b/subcommands/backup-schedule index 448f930..594c748 100755 --- a/subcommands/backup-schedule +++ b/subcommands/backup-schedule @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-backup-schedule-cmd() { diff --git a/subcommands/backup-schedule-cat b/subcommands/backup-schedule-cat index 0e3f2df..56a388a 100755 --- a/subcommands/backup-schedule-cat +++ b/subcommands/backup-schedule-cat @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-backup-schedule-cat-cmd() { diff --git a/subcommands/backup-set-encryption b/subcommands/backup-set-encryption index 3ad29e5..27cb86e 100755 --- a/subcommands/backup-set-encryption +++ b/subcommands/backup-set-encryption @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-backup-set-encryption-cmd() { diff --git a/subcommands/backup-unschedule b/subcommands/backup-unschedule index c3d3e31..874a22a 100755 --- a/subcommands/backup-unschedule +++ b/subcommands/backup-unschedule @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-backup-unschedule-cmd() { diff --git a/subcommands/backup-unset-encryption b/subcommands/backup-unset-encryption index f783220..c046a55 100755 --- a/subcommands/backup-unset-encryption +++ b/subcommands/backup-unset-encryption @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-backup-unset-encryption-cmd() { diff --git a/subcommands/clone b/subcommands/clone index a7e2f64..eb10519 100755 --- a/subcommands/clone +++ b/subcommands/clone @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-clone-cmd() { @@ -15,8 +15,11 @@ service-clone-cmd() { #F -i|--image IMAGE, the image name to start the service with #F -I|--image-version IMAGE_VERSION, the image version to start the service with #F -m|--memory MEMORY, container memory limit in megabytes (default: unlimited) + #F -N|--initial-network INITIAL_NETWORK, the initial network to attach the service to #F -p|--password PASSWORD, override the user-level service password + #F -P|--post-create-network NETWORKS, a comman-separated list of networks to attach the service container to after service creation #F -r|--root-password PASSWORD, override the root-level service password + #F -S|--post-start-network NETWORKS, a comman-separated list of networks to attach the service container to after service start #F -s|--shm-size SHM_SIZE, override shared memory size for $PLUGIN_COMMAND_PREFIX docker container declare desc="create container then copy data from into " local cmd="$PLUGIN_COMMAND_PREFIX:clone" argv=("$@") diff --git a/subcommands/connect b/subcommands/connect index 37d05a8..ad6abca 100755 --- a/subcommands/connect +++ b/subcommands/connect @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-connect-cmd() { diff --git a/subcommands/create b/subcommands/create index 557b8b8..87135e5 100755 --- a/subcommands/create +++ b/subcommands/create @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-create-cmd() { @@ -23,8 +23,11 @@ service-create-cmd() { #F -i|--image IMAGE, the image name to start the service with #F -I|--image-version IMAGE_VERSION, the image version to start the service with #F -m|--memory MEMORY, container memory limit in megabytes (default: unlimited) + #F -N|--initial-network INITIAL_NETWORK, the initial network to attach the service to #F -p|--password PASSWORD, override the user-level service password + #F -P|--post-create-network NETWORKS, a comman-separated list of networks to attach the service container to after service creation #F -r|--root-password PASSWORD, override the root-level service password + #F -S|--post-start-network NETWORKS, a comman-separated list of networks to attach the service container to after service start #F -s|--shm-size SHM_SIZE, override shared memory size for $PLUGIN_COMMAND_PREFIX docker container declare desc="create a $PLUGIN_SERVICE service" local cmd="$PLUGIN_COMMAND_PREFIX:create" argv=("$@") diff --git a/subcommands/destroy b/subcommands/destroy index c8534c4..cffe32d 100755 --- a/subcommands/destroy +++ b/subcommands/destroy @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-destroy-cmd() { @@ -46,9 +46,11 @@ service-destroy-cmd() { service_container_rm "$SERVICE" dokku_log_verbose_quiet "Removing data" - docker run --rm -v "$SERVICE_HOST_ROOT/data:/data" -v "$SERVICE_HOST_ROOT/$PLUGIN_CONFIG_SUFFIX:/config" "$PLUGIN_BUSYBOX_IMAGE" chmod 777 -R /config /data + "$DOCKER_BIN" container run --rm -v "$SERVICE_HOST_ROOT/data:/data" -v "$SERVICE_HOST_ROOT/$PLUGIN_CONFIG_SUFFIX:/config" "$PLUGIN_BUSYBOX_IMAGE" chmod 777 -R /config /data rm -rf "$SERVICE_ROOT" + fn-plugin-property-destroy "$PLUGIN_COMMAND_PREFIX" "$SERVICE" + plugn trigger service-action post-delete "$PLUGIN_COMMAND_PREFIX" "$SERVICE" dokku_log_info2 "$PLUGIN_SERVICE container deleted: $SERVICE" } diff --git a/subcommands/enter b/subcommands/enter index 13f6a31..9062beb 100755 --- a/subcommands/enter +++ b/subcommands/enter @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-enter-cmd() { diff --git a/subcommands/exists b/subcommands/exists index ae59eee..6fd1bfc 100755 --- a/subcommands/exists +++ b/subcommands/exists @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-exists-cmd() { diff --git a/subcommands/export b/subcommands/export index 7e5bc69..d77dd47 100755 --- a/subcommands/export +++ b/subcommands/export @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-export-cmd() { diff --git a/subcommands/expose b/subcommands/expose index 57ead49..1e6b081 100755 --- a/subcommands/expose +++ b/subcommands/expose @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-expose-cmd() { diff --git a/subcommands/import b/subcommands/import index fd2b89f..441f415 100755 --- a/subcommands/import +++ b/subcommands/import @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-import-cmd() { diff --git a/subcommands/info b/subcommands/info index 7f4b7aa..f9970d3 100755 --- a/subcommands/info +++ b/subcommands/info @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-info-cmd() { @@ -15,7 +15,10 @@ service-info-cmd() { #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --exposed-ports #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --id #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --internal-ip + #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --initial-network #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --links + #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --post-create-network + #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --post-start-network #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --service-root #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --status #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --version @@ -26,7 +29,10 @@ service-info-cmd() { #F --exposed-ports, show service exposed ports #F --id, show the service container id #F --internal-ip, show the service internal ip + #F --initial-network, show the initial network being connected to #F --links, show the service app links + #F --post-create-network, show the networks to attach to after service container creation + #F --post-start-network, show the networks to attach to after service container start #F --service-root, show the service root directory #F --status, show the service running status #F --version, show the service image version diff --git a/subcommands/link b/subcommands/link index 73c6291..3d8e153 100755 --- a/subcommands/link +++ b/subcommands/link @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-link-cmd() { @@ -42,6 +42,7 @@ service-link-cmd() { #A app, app to run command against #F -a|--alias "BLUE_DATABASE", an alternative alias to use for linking to an app via environment variable #F -q|--querystring "pool=5", ampersand delimited querystring arguments to append to the service link + #F -n|--no-restart "false", whether or not to restart the app on link (default: true) declare desc="link the $PLUGIN_SERVICE service to the app" local cmd="$PLUGIN_COMMAND_PREFIX:link" argv=("$@") [[ ${argv[0]} == "$cmd" ]] && shift 1 diff --git a/subcommands/linked b/subcommands/linked index 38cbc67..5d61d79 100755 --- a/subcommands/linked +++ b/subcommands/linked @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-linked-cmd() { diff --git a/subcommands/links b/subcommands/links index 9f3609b..35586aa 100755 --- a/subcommands/links +++ b/subcommands/links @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-links-cmd() { diff --git a/subcommands/list b/subcommands/list index cd4d52e..cebe31c 100755 --- a/subcommands/list +++ b/subcommands/list @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-list-cmd() { diff --git a/subcommands/logs b/subcommands/logs index 55f13ac..7f2e90e 100755 --- a/subcommands/logs +++ b/subcommands/logs @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-logs-cmd() { diff --git a/subcommands/pause b/subcommands/pause new file mode 100755 index 0000000..91d51fe --- /dev/null +++ b/subcommands/pause @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" +set -eo pipefail +[[ $DOKKU_TRACE ]] && set -x +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" + +service-pause-cmd() { + #E pause the running container for the service + #E dokku $PLUGIN_COMMAND_PREFIX:pause lollipop + #A service, service to run command against + declare desc="pause a running $PLUGIN_SERVICE service" + local cmd="$PLUGIN_COMMAND_PREFIX:pause" argv=("$@") + [[ ${argv[0]} == "$cmd" ]] && shift 1 + declare SERVICE="$1" + + [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" + verify_service_name "$SERVICE" + service_pause "$SERVICE" +} + +service-pause-cmd "$@" diff --git a/subcommands/promote b/subcommands/promote index cbd5cda..ddf35ad 100755 --- a/subcommands/promote +++ b/subcommands/promote @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-promote-cmd() { diff --git a/subcommands/restart b/subcommands/restart index df9a051..9ff6b03 100755 --- a/subcommands/restart +++ b/subcommands/restart @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-restart-cmd() { @@ -16,7 +16,7 @@ service-restart-cmd() { [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" verify_service_name "$SERVICE" - service_stop "$SERVICE" + service_pause "$SERVICE" service_start "$SERVICE" dokku_log_info1 "Please call dokku ps:restart on all linked apps" } diff --git a/subcommands/set b/subcommands/set new file mode 100755 index 0000000..0bcf474 --- /dev/null +++ b/subcommands/set @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" +set -eo pipefail +[[ $DOKKU_TRACE ]] && set -x +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions" +source "$(cd "$(dirname "$(dirname "${BASH_SOURCE[0]}")")" && pwd)/common-functions" + +service-set-cmd() { + #E set the network to attach after the service container is started + #E dokku $PLUGIN_COMMAND_PREFIX:set lollipop post-create-network custom-network + #E set multiple networks + #E dokku $PLUGIN_COMMAND_PREFIX:set lollipop post-create-network custom-network,other-network + #E unset the post-create-network value + #E dokku $PLUGIN_COMMAND_PREFIX:set lollipop post-create-network + #A service, service to run command against + #A key, property name to set + #A value, optional property value to set or empty to unset key + declare desc="set or clear a property for a service" + local cmd="$PLUGIN_COMMAND_PREFIX:set" argv=("$@") + [[ ${argv[0]} == "$cmd" ]] && shift 1 + declare SERVICE="$1" KEY="$2" VALUE="$3" + local VALID_KEYS=("initial-network" "post-create-network" "post-start-network") + verify_service_name "$SERVICE" + + [[ -z "$KEY" ]] && dokku_log_fail "No key specified" + + if ! fn-in-array "$KEY" "${VALID_KEYS[@]}"; then + dokku_log_fail "Invalid key specified, valid keys include: initial-network, post-create-network, post-start-network" + fi + + if [[ -n "$VALUE" ]]; then + dokku_log_info2_quiet "Setting ${KEY} to ${VALUE}" + fn-plugin-property-write "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "$KEY" "$VALUE" + else + dokku_log_info2_quiet "Unsetting ${KEY}" + if [[ "$KEY" == "rev-env-var" ]]; then + fn-plugin-property-write "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "$KEY" "$VALUE" + else + fn-plugin-property-delete "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "$KEY" + fi + fi +} + +service-set-cmd "$@" diff --git a/subcommands/start b/subcommands/start index 8416745..c928f3a 100755 --- a/subcommands/start +++ b/subcommands/start @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-start-cmd() { diff --git a/subcommands/stop b/subcommands/stop index 0ac3a17..9680ea5 100755 --- a/subcommands/stop +++ b/subcommands/stop @@ -2,11 +2,11 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-stop-cmd() { - #E stop the service and the running container + #E stop the service and removes the running container #E dokku $PLUGIN_COMMAND_PREFIX:stop lollipop #A service, service to run command against declare desc="stop a running $PLUGIN_SERVICE service" @@ -16,7 +16,7 @@ service-stop-cmd() { [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" verify_service_name "$SERVICE" - service_stop "$SERVICE" + service_container_rm "$SERVICE" } service-stop-cmd "$@" diff --git a/subcommands/unexpose b/subcommands/unexpose index 83e5239..a3e990a 100755 --- a/subcommands/unexpose +++ b/subcommands/unexpose @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-unexpose-cmd() { diff --git a/subcommands/unlink b/subcommands/unlink index b1e37d6..63c4c97 100755 --- a/subcommands/unlink +++ b/subcommands/unlink @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" service-unlink-cmd() { @@ -11,6 +11,7 @@ service-unlink-cmd() { #E dokku $PLUGIN_COMMAND_PREFIX:unlink lollipop playground #A service, service to run command against #A app, app to run command against + #F -n|--no-restart "false", whether or not to restart the app on unlink (default: true) declare desc="unlink the $PLUGIN_SERVICE service from the app" local cmd="$PLUGIN_COMMAND_PREFIX:unlink" argv=("$@") [[ ${argv[0]} == "$cmd" ]] && shift 1 diff --git a/subcommands/upgrade b/subcommands/upgrade index 899f7e2..93352c1 100755 --- a/subcommands/upgrade +++ b/subcommands/upgrade @@ -2,7 +2,7 @@ source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_BASE_PATH/common/functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" source "$PLUGIN_AVAILABLE_PATH/ps/functions" @@ -14,7 +14,10 @@ service-upgrade-cmd() { #F -C|--custom-env "USER=alpha;HOST=beta", semi-colon delimited environment variables to start the service with #F -i|--image IMAGE, the image name to start the service with #F -I|--image-version IMAGE_VERSION, the image version to start the service with - #F -R|--restart-apps "true", whether to force an app restart + #F -N|--initial-network INITIAL_NETWORK, the initial network to attach the service to + #F -P|--post-create-network NETWORKS, a comman-separated list of networks to attach the service container to after service creation + #F -R|--restart-apps "true", whether or not to force an app restart (default: false) + #F -S|--post-start-network NETWORKS, a comman-separated list of networks to attach the service container to after service start #F -s|--shm-size SHM_SIZE, override shared memory size for $PLUGIN_COMMAND_PREFIX docker container declare desc="upgrade service to the specified versions" local cmd="$PLUGIN_COMMAND_PREFIX:upgrade" argv=("$@") @@ -28,8 +31,14 @@ service-upgrade-cmd() { service_parse_args "${@:2}" - if ! service_image_exists "$SERVICE"; then - dokku_log_fail "Unable to proceed with upgrade, image ${PLUGIN_IMAGE}:${PLUGIN_IMAGE_VERSION} does not exist" + if ! service_image_exists "$SERVICE" "$PLUGIN_IMAGE" "$PLUGIN_IMAGE_VERSION"; then + if [[ "$PLUGIN_DISABLE_PULL" == "true" ]]; then + dokku_log_warn "${PLUGIN_DISABLE_PULL_VARIABLE} environment variable detected. Not running pull command." 1>&2 + dokku_log_warn " docker image pull ${IMAGE}" 1>&2 + dokku_log_warn "$PLUGIN_SERVICE service $SERVICE upgrade failed" + exit 1 + fi + "$DOCKER_BIN" image pull "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION" || dokku_log_fail "$PLUGIN_SERVICE image $PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION pull failed" fi local NEW_PLUGIN_IMAGE_TAG="$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION" diff --git a/tests/hook_pre_delete.bats b/tests/hook_pre_delete.bats index e849887..600b8b0 100755 --- a/tests/hook_pre_delete.bats +++ b/tests/hook_pre_delete.bats @@ -3,17 +3,18 @@ load test_helper setup() { dokku apps:create my-app - dokku "$PLUGIN_COMMAND_PREFIX:create" l - dokku "$PLUGIN_COMMAND_PREFIX:link" l my-app >&2 + dokku "$PLUGIN_COMMAND_PREFIX:create" ls + dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app >&2 } teardown() { - dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my-app >&2 - dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l + dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app >&2 + dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" ls + dokku --force apps:destroy my-app || true } @test "($PLUGIN_COMMAND_PREFIX:hook:pre-delete) removes app from links file when destroying app" { - [[ -n $(<"$PLUGIN_DATA_ROOT/l/LINKS") ]] + [[ -n $(<"$PLUGIN_DATA_ROOT/ls/LINKS") ]] dokku --force apps:destroy my-app - [[ -z $(<"$PLUGIN_DATA_ROOT/l/LINKS") ]] + [[ -z $(<"$PLUGIN_DATA_ROOT/ls/LINKS") ]] } diff --git a/tests/link_networks.bats b/tests/link_networks.bats new file mode 100755 index 0000000..f75dfbe --- /dev/null +++ b/tests/link_networks.bats @@ -0,0 +1,289 @@ +#!/usr/bin/env bats +load test_helper + +setup() { + dokku "$PLUGIN_COMMAND_PREFIX:create" ls + dokku network:create custom-network +} + +teardown() { + dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" ls || true + dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" lsa || true + dokku network:destroy --force custom-network +} + +@test "($PLUGIN_COMMAND_PREFIX:set) set initial-network" { + run dokku "$PLUGIN_COMMAND_PREFIX:set" ls initial-network custom-network + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:info" ls --initial-network + echo "output: $output" + echo "status: $status" + assert_output "custom-network" + assert_success + + run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains bridge + assert_output_contains custom-network 0 + + run dokku "$PLUGIN_COMMAND_PREFIX:stop" ls + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:start" ls + echo "output: $output" + echo "status: $status" + assert_success + + run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains bridge 0 + assert_output_contains custom-network + + run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{range $k,$alias := $v.Aliases}}{{printf "alias:%s\n" $alias}}{{end}}{{end}}' + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "alias:dokku.$PLUGIN_COMMAND_PREFIX.ls" + assert_output_contains "alias:dokku-$PLUGIN_COMMAND_PREFIX-ls" + + run dokku "$PLUGIN_COMMAND_PREFIX:set" ls initial-network + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:info" ls --initial-network + echo "output: $output" + echo "status: $status" + assert_output "" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:stop" ls + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:start" ls + echo "output: $output" + echo "status: $status" + assert_success + + run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains bridge + assert_output_contains custom-network 0 +} + +@test "($PLUGIN_COMMAND_PREFIX:set) set post-create-network" { + run dokku "$PLUGIN_COMMAND_PREFIX:set" ls post-create-network custom-network + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:info" ls --post-create-network + echo "output: $output" + echo "status: $status" + assert_output "custom-network" + assert_success + + run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains bridge + assert_output_contains custom-network 0 + + run dokku "$PLUGIN_COMMAND_PREFIX:stop" ls + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:start" ls + echo "output: $output" + echo "status: $status" + assert_success + + run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains custom-network + assert_output_contains bridge + + run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{range $k,$alias := $v.Aliases}}{{printf "alias:%s\n" $alias}}{{end}}{{end}}' + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "alias:dokku.$PLUGIN_COMMAND_PREFIX.ls" + assert_output_contains "alias:dokku-$PLUGIN_COMMAND_PREFIX-ls" + + run dokku "$PLUGIN_COMMAND_PREFIX:set" ls post-create-network + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:info" ls --post-create-network + echo "output: $output" + echo "status: $status" + assert_output "" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:stop" ls + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:start" ls + echo "output: $output" + echo "status: $status" + assert_success + + run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains bridge + assert_output_contains custom-network 0 +} + +@test "($PLUGIN_COMMAND_PREFIX:set) set an post-start-network" { + run dokku "$PLUGIN_COMMAND_PREFIX:set" ls post-start-network custom-network + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:info" ls --post-start-network + echo "output: $output" + echo "status: $status" + assert_output "custom-network" + assert_success + + run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains bridge + assert_output_contains custom-network 0 + + run dokku "$PLUGIN_COMMAND_PREFIX:stop" ls + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:start" ls + echo "output: $output" + echo "status: $status" + assert_success + + run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains bridge + assert_output_contains custom-network + + run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{range $k,$alias := $v.Aliases}}{{printf "alias:%s\n" $alias}}{{end}}{{end}}' + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "alias:dokku.$PLUGIN_COMMAND_PREFIX.ls" + assert_output_contains "alias:dokku-$PLUGIN_COMMAND_PREFIX-ls" + + run dokku "$PLUGIN_COMMAND_PREFIX:set" ls post-start-network + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:info" ls --post-start-network + echo "output: $output" + echo "status: $status" + assert_output "" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:stop" ls + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:start" ls + echo "output: $output" + echo "status: $status" + assert_success + + run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains bridge + assert_output_contains custom-network 0 +} + +@test "($PLUGIN_COMMAND_PREFIX:create) flags" { + run dokku "$PLUGIN_COMMAND_PREFIX:create" lsa --initial-network custom-network + echo "output: $output" + echo "status: $status" + assert_success + + run docker inspect "dokku.$PLUGIN_COMMAND_PREFIX.lsa" -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains bridge 0 + assert_output_contains custom-network + + run dokku "$PLUGIN_COMMAND_PREFIX:destroy" lsa --force + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:create" lsa --post-create-network custom-network + echo "output: $output" + echo "status: $status" + assert_success + + run docker inspect "dokku.$PLUGIN_COMMAND_PREFIX.lsa" -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains bridge + assert_output_contains custom-network + + run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.lsa -f '{{range $net,$v := .NetworkSettings.Networks}}{{range $k,$alias := $v.Aliases}}{{printf "alias:%s\n" $alias}}{{end}}{{end}}' + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "alias:dokku.$PLUGIN_COMMAND_PREFIX.lsa" + assert_output_contains "alias:dokku-$PLUGIN_COMMAND_PREFIX-lsa" + + run dokku "$PLUGIN_COMMAND_PREFIX:destroy" lsa --force + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:create" lsa --post-start-network custom-network + echo "output: $output" + echo "status: $status" + assert_success + + run docker inspect "dokku.$PLUGIN_COMMAND_PREFIX.lsa" -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains bridge + assert_output_contains custom-network + + run dokku "$PLUGIN_COMMAND_PREFIX:destroy" lsa --force + echo "output: $output" + echo "status: $status" + assert_success +} diff --git a/tests/service_expose.bats b/tests/service_expose.bats index a0ae4b0..0bfa302 100755 --- a/tests/service_expose.bats +++ b/tests/service_expose.bats @@ -2,29 +2,65 @@ load test_helper setup() { - dokku "$PLUGIN_COMMAND_PREFIX:create" l + dokku "$PLUGIN_COMMAND_PREFIX:create" ls } teardown() { - dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l + dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" ls } @test "($PLUGIN_COMMAND_PREFIX:expose) error when there are no arguments" { run dokku "$PLUGIN_COMMAND_PREFIX:expose" + echo "output: $output" + echo "status: $status" + assert_failure assert_contains "${lines[*]}" "Please specify a valid name for the service" } @test "($PLUGIN_COMMAND_PREFIX:expose) error when service does not exist" { run dokku "$PLUGIN_COMMAND_PREFIX:expose" not_existing_service + echo "output: $output" + echo "status: $status" + assert_failure assert_contains "${lines[*]}" "service not_existing_service does not exist" } +@test "($PLUGIN_COMMAND_PREFIX:expose) error when already exposed" { + run dokku "$PLUGIN_COMMAND_PREFIX:expose" ls + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:expose" ls + echo "output: $output" + echo "status: $status" + assert_failure + assert_contains "${lines[*]}" "Service ls already exposed on port(s)" + + run sudo rm "$PLUGIN_DATA_ROOT/ls/PORT" + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:expose" ls + echo "output: $output" + echo "status: $status" + assert_success + assert_contains "${lines[*]}" "Service ls has an untracked expose container, removing" +} + @test "($PLUGIN_COMMAND_PREFIX:expose) success when not providing custom ports" { - run dokku "$PLUGIN_COMMAND_PREFIX:expose" l + run dokku "$PLUGIN_COMMAND_PREFIX:expose" ls + echo "output: $output" + echo "status: $status" + assert_success [[ "${lines[*]}" =~ exposed\ on\ port\(s\)\ \[container\-\>host\]\:\ [[:digit:]]+ ]] } @test "($PLUGIN_COMMAND_PREFIX:expose) success when providing custom ports" { - run dokku "$PLUGIN_COMMAND_PREFIX:expose" l 4242 + run dokku "$PLUGIN_COMMAND_PREFIX:expose" ls 4242 + echo "output: $output" + echo "status: $status" + assert_success assert_contains "${lines[*]}" "exposed on port(s) [container->host]: 5432->4242" } diff --git a/tests/service_link.bats b/tests/service_link.bats index eda2626..4bc1729 100755 --- a/tests/service_link.bats +++ b/tests/service_link.bats @@ -2,14 +2,14 @@ load test_helper setup() { - dokku "$PLUGIN_COMMAND_PREFIX:create" l - dokku "$PLUGIN_COMMAND_PREFIX:create" m + dokku "$PLUGIN_COMMAND_PREFIX:create" ls + dokku "$PLUGIN_COMMAND_PREFIX:create" ms dokku apps:create my-app } teardown() { - dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" m - dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l + dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" ms + dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" ls dokku --force apps:destroy my-app } @@ -22,7 +22,7 @@ teardown() { } @test "($PLUGIN_COMMAND_PREFIX:link) error when the app argument is missing" { - run dokku "$PLUGIN_COMMAND_PREFIX:link" l + run dokku "$PLUGIN_COMMAND_PREFIX:link" ls echo "output: $output" echo "status: $status" assert_contains "${lines[*]}" "Please specify an app to run the command on" @@ -30,7 +30,7 @@ teardown() { } @test "($PLUGIN_COMMAND_PREFIX:link) error when the app does not exist" { - run dokku "$PLUGIN_COMMAND_PREFIX:link" l not_existing_app + run dokku "$PLUGIN_COMMAND_PREFIX:link" ls not_existing_app echo "output: $output" echo "status: $status" assert_contains "${lines[*]}" "App not_existing_app does not exist" @@ -46,73 +46,97 @@ teardown() { } @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 + dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app + run dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app echo "output: $output" echo "status: $status" assert_contains "${lines[*]}" "Already linked as DATABASE_URL" assert_failure - dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my-app + dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app } @test "($PLUGIN_COMMAND_PREFIX:link) exports DATABASE_URL to app" { - run dokku "$PLUGIN_COMMAND_PREFIX:link" l my-app + run dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app echo "output: $output" echo "status: $status" url=$(dokku config:get my-app DATABASE_URL) - password="$(sudo cat "$PLUGIN_DATA_ROOT/l/PASSWORD")" - assert_contains "$url" "postgres://postgres:$password@dokku-postgres-l:5432/l" + password="$(sudo cat "$PLUGIN_DATA_ROOT/ls/PASSWORD")" + assert_contains "$url" "postgres://postgres:$password@dokku-postgres-ls:5432/ls" assert_success - dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my-app + dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app } @test "($PLUGIN_COMMAND_PREFIX:link) generates an alternate config url when DATABASE_URL already in use" { dokku config:set my-app DATABASE_URL=postgres://user:pass@host:5432/db - dokku "$PLUGIN_COMMAND_PREFIX:link" l my-app + dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app run dokku config my-app assert_contains "${lines[*]}" "DOKKU_POSTGRES_AQUA_URL" assert_success - dokku "$PLUGIN_COMMAND_PREFIX:link" m my-app + dokku "$PLUGIN_COMMAND_PREFIX:link" ms my-app run dokku config my-app assert_contains "${lines[*]}" "DOKKU_POSTGRES_BLACK_URL" assert_success - dokku "$PLUGIN_COMMAND_PREFIX:unlink" m my-app - dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my-app + dokku "$PLUGIN_COMMAND_PREFIX:unlink" ms my-app + dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app } @test "($PLUGIN_COMMAND_PREFIX:link) links to app with docker-options" { - dokku "$PLUGIN_COMMAND_PREFIX:link" l my-app + dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app run dokku docker-options:report my-app - assert_contains "${lines[*]}" "--link dokku.postgres.l:dokku-postgres-l" + assert_contains "${lines[*]}" "--link dokku.postgres.ls:dokku-postgres-ls" assert_success - dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my-app + dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app } @test "($PLUGIN_COMMAND_PREFIX:link) uses apps POSTGRES_DATABASE_SCHEME variable" { dokku config:set my-app POSTGRES_DATABASE_SCHEME=postgres2 - dokku "$PLUGIN_COMMAND_PREFIX:link" l my-app + dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app url=$(dokku config:get my-app DATABASE_URL) - password="$(sudo cat "$PLUGIN_DATA_ROOT/l/PASSWORD")" - assert_contains "$url" "postgres2://postgres:$password@dokku-postgres-l:5432/l" + password="$(sudo cat "$PLUGIN_DATA_ROOT/ls/PASSWORD")" + assert_contains "$url" "postgres2://postgres:$password@dokku-postgres-ls:5432/ls" assert_success - dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my-app + dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app } @test "($PLUGIN_COMMAND_PREFIX:link) adds a querystring" { - dokku "$PLUGIN_COMMAND_PREFIX:link" l my-app --querystring "pool=5" + dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app --querystring "pool=5" url=$(dokku config:get my-app DATABASE_URL) assert_contains "$url" "?pool=5" assert_success - dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my-app + dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app } @test "($PLUGIN_COMMAND_PREFIX:link) uses a specified config url when alias is specified" { - dokku "$PLUGIN_COMMAND_PREFIX:link" l my-app --alias "ALIAS" + dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app --alias "ALIAS" url=$(dokku config:get my-app ALIAS_URL) - password="$(sudo cat "$PLUGIN_DATA_ROOT/l/PASSWORD")" - assert_contains "$url" "postgres://postgres:$password@dokku-postgres-l:5432/l" + password="$(sudo cat "$PLUGIN_DATA_ROOT/ls/PASSWORD")" + assert_contains "$url" "postgres://postgres:$password@dokku-postgres-ls:5432/ls" + assert_success + dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app +} + +@test "($PLUGIN_COMMAND_PREFIX:link) respects --no-restart" { + run dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app + echo "output: $output" + echo "status: $status" + assert_output_contains "Skipping restart of linked app" 0 + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app --no-restart + echo "output: $output" + echo "status: $status" + assert_output_contains "Skipping restart of linked app" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app + echo "output: $output" + echo "status: $status" assert_success - dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my-app } diff --git a/tests/service_pause.bats b/tests/service_pause.bats new file mode 100755 index 0000000..a2a2a69 --- /dev/null +++ b/tests/service_pause.bats @@ -0,0 +1,25 @@ +#!/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:pause) error when there are no arguments" { + run dokku "$PLUGIN_COMMAND_PREFIX:pause" + assert_contains "${lines[*]}" "Please specify a valid name for the service" +} + +@test "($PLUGIN_COMMAND_PREFIX:pause) error when service does not exist" { + run dokku "$PLUGIN_COMMAND_PREFIX:pause" not_existing_service + assert_contains "${lines[*]}" "service not_existing_service does not exist" +} + +@test "($PLUGIN_COMMAND_PREFIX:pause) success" { + run dokku "$PLUGIN_COMMAND_PREFIX:pause" l + assert_success +} diff --git a/tests/service_unlink.bats b/tests/service_unlink.bats index d4f0dbd..164baf2 100755 --- a/tests/service_unlink.bats +++ b/tests/service_unlink.bats @@ -3,11 +3,11 @@ load test_helper setup() { dokku apps:create my-app - dokku "$PLUGIN_COMMAND_PREFIX:create" l + dokku "$PLUGIN_COMMAND_PREFIX:create" ls } teardown() { - dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l + dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" ls dokku --force apps:destroy my-app } @@ -17,12 +17,12 @@ teardown() { } @test "($PLUGIN_COMMAND_PREFIX:unlink) error when the app argument is missing" { - run dokku "$PLUGIN_COMMAND_PREFIX:unlink" l + run dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls assert_contains "${lines[*]}" "Please specify an app to run the command on" } @test "($PLUGIN_COMMAND_PREFIX:unlink) error when the app does not exist" { - run dokku "$PLUGIN_COMMAND_PREFIX:unlink" l not_existing_app + run dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls not_existing_app assert_contains "${lines[*]}" "App not_existing_app does not exist" } @@ -32,13 +32,13 @@ teardown() { } @test "($PLUGIN_COMMAND_PREFIX:unlink) error when service not linked to app" { - run dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my-app + run dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app 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 + dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app >&2 + dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app check_value="Docker options build: Docker options deploy: --restart=on-failure:10 Docker options run:" options=$(dokku --quiet docker-options:report my-app | xargs) @@ -46,8 +46,32 @@ teardown() { } @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 + dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app >&2 + dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app config=$(dokku config:get my-app DATABASE_URL || true) assert_equal "$config" "" } + +@test "($PLUGIN_COMMAND_PREFIX:unlink) respects --no-restart" { + run dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app + echo "output: $output" + echo "status: $status" + assert_output_contains "Skipping restart of linked app" 0 + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app + echo "output: $output" + echo "status: $status" + assert_success + + run dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app --no-restart + echo "output: $output" + echo "status: $status" + assert_output_contains "Skipping restart of linked app" + assert_success +} diff --git a/tests/test_helper.bash b/tests/test_helper.bash index 8a0d1ee..fb397ab 100755 --- a/tests/test_helper.bash +++ b/tests/test_helper.bash @@ -70,3 +70,17 @@ assert_output() { fi assert_equal "$expected" "$output" } + +# ShellCheck doesn't know about $output from Bats +# shellcheck disable=SC2154 +assert_output_contains() { + local input="$output" + local expected="$1" + local count="${2:-1}" + local found=0 + until [ "${input/$expected/}" = "$input" ]; do + input="${input/$expected/}" + found=$((found + 1)) + done + assert_equal "$count" "$found" +}