├── .gitignore ├── tests ├── bin │ ├── id │ ├── sudo │ └── lsb_release ├── maintenance_off.bats ├── maintenance_on.bats ├── maintenance.bats ├── setup.sh ├── maintenance_custom_page.bats └── test_helper.bash ├── plugin.toml ├── .travis.yml ├── report ├── subcommands ├── off ├── on ├── disable ├── enable ├── report ├── custom-page └── default ├── templates ├── maintenance.conf └── maintenance.html ├── commands ├── config ├── internal-functions ├── LICENSE ├── help-functions ├── Makefile ├── README.md └── command-functions /.gitignore: -------------------------------------------------------------------------------- 1 | tests/dokku 2 | tests/fixtures 3 | -------------------------------------------------------------------------------- /tests/bin/id: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "dokku" 3 | -------------------------------------------------------------------------------- /tests/bin/sudo: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "$(basename "$0") $*" 3 | exit 0 4 | -------------------------------------------------------------------------------- /plugin.toml: -------------------------------------------------------------------------------- 1 | [plugin] 2 | description = "Maintenance mode for apps" 3 | version = "0.8.0" 4 | [plugin.config] 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | language: bash 3 | env: 4 | - DOKKU_VERSION=master 5 | before_install: make setup 6 | script: make test 7 | -------------------------------------------------------------------------------- /tests/bin/lsb_release: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | if [[ "$(uname)" == "Darwin" ]]; then 3 | echo "Darwin" 4 | else 5 | echo "Ubuntu" 6 | fi 7 | -------------------------------------------------------------------------------- /report: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$PLUGIN_AVAILABLE_PATH/maintenance/command-functions" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | 6 | cmd-maintenance-report-single "$@" 7 | -------------------------------------------------------------------------------- /subcommands/off: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$PLUGIN_AVAILABLE_PATH/maintenance/command-functions" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | 6 | cmd-maintenance-disable "$@" 7 | -------------------------------------------------------------------------------- /subcommands/on: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$PLUGIN_AVAILABLE_PATH/maintenance/command-functions" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | 6 | cmd-maintenance-enable "$@" 7 | -------------------------------------------------------------------------------- /subcommands/disable: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$PLUGIN_AVAILABLE_PATH/maintenance/command-functions" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | 6 | cmd-maintenance-disable "$@" 7 | -------------------------------------------------------------------------------- /subcommands/enable: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$PLUGIN_AVAILABLE_PATH/maintenance/command-functions" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | 6 | cmd-maintenance-enable "$@" 7 | -------------------------------------------------------------------------------- /subcommands/report: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$PLUGIN_AVAILABLE_PATH/maintenance/command-functions" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | 6 | cmd-maintenance-report "$@" 7 | -------------------------------------------------------------------------------- /subcommands/custom-page: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$PLUGIN_AVAILABLE_PATH/maintenance/command-functions" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | 6 | cmd-maintenance-custom-page "$@" 7 | -------------------------------------------------------------------------------- /subcommands/default: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$PLUGIN_AVAILABLE_PATH/maintenance/help-functions" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | 6 | cmd-maintenance-help "maintenance:help" 7 | -------------------------------------------------------------------------------- /templates/maintenance.conf: -------------------------------------------------------------------------------- 1 | location ~* ^(.*)$ { 2 | root {APP_ROOT}/maintenance/; 3 | try_files $uri =533; 4 | } 5 | 6 | error_page 533 =503 @maintenance; 7 | 8 | location @maintenance { 9 | root {APP_ROOT}/maintenance/; 10 | rewrite ^(.*)$ /maintenance.html break; 11 | } 12 | -------------------------------------------------------------------------------- /commands: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | [[ " help maintenance:help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT" 3 | source "$PLUGIN_AVAILABLE_PATH/maintenance/help-functions" 4 | set -eo pipefail 5 | [[ $DOKKU_TRACE ]] && set -x 6 | 7 | case "$1" in 8 | help | maintenance:help) 9 | cmd-maintenance-help "$@" 10 | ;; 11 | 12 | *) 13 | exit "$DOKKU_NOT_IMPLEMENTED_EXIT" 14 | ;; 15 | 16 | esac 17 | -------------------------------------------------------------------------------- /config: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | export PLUGIN_COMMAND_PREFIX="maintenance" 3 | export PLUGIN_VARIABLE="MAINTENANCE" 4 | export PLUGIN_BASE_PATH="$PLUGIN_PATH" 5 | export MAINTENANCE_PLUGIN_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 6 | 7 | if [[ -n $DOKKU_API_VERSION ]]; then 8 | export PLUGIN_BASE_PATH="$PLUGIN_ENABLED_PATH" 9 | fi 10 | 11 | if [[ -d "$PLUGIN_DATA_ROOT/*" ]]; then 12 | rm -rf "${PLUGIN_DATA_ROOT:?}/*" 13 | fi 14 | -------------------------------------------------------------------------------- /internal-functions: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | 6 | fn-maintenance-enabled() { 7 | declare desc="check if an app has maintenance enabled" 8 | declare APP="$1" 9 | local APP_ROOT="$DOKKU_ROOT/$APP" 10 | local enabled=false 11 | 12 | if [[ -f "$APP_ROOT/nginx.conf.d/maintenance.conf" ]]; then 13 | enabled=true 14 | fi 15 | 16 | echo "$enabled" 17 | } 18 | -------------------------------------------------------------------------------- /tests/maintenance_off.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | setup() { 5 | dokku apps:create my_app >&2 6 | dokku maintenance:enable my_app >&2 7 | } 8 | 9 | teardown() { 10 | rm -rf "$DOKKU_ROOT/my_app" 11 | } 12 | 13 | @test "(maintenance:disable) error when there are no arguments" { 14 | run dokku maintenance:disable 15 | assert_contains "${lines[*]}" "Please specify an app to run the command on" 16 | } 17 | 18 | @test "(maintenance:disable) error when app does not exist" { 19 | run dokku maintenance:disable non_existing_app 20 | assert_contains "${lines[*]}" "App non_existing_app does not exist" 21 | } 22 | 23 | @test "(maintenance:disable) success" { 24 | run dokku maintenance:disable my_app 25 | [[ ! -f $DOKKU_ROOT/my_app/nginx.conf.d/maintenance.conf ]] 26 | assert_success 27 | } 28 | 29 | -------------------------------------------------------------------------------- /tests/maintenance_on.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | setup() { 5 | dokku apps:create my_app >&2 6 | } 7 | 8 | teardown() { 9 | rm -rf "$DOKKU_ROOT/my_app" 10 | } 11 | 12 | @test "(maintenance:enable) error when there are no arguments" { 13 | run dokku maintenance:enable 14 | assert_contains "${lines[*]}" "Please specify an app to run the command on" 15 | } 16 | 17 | @test "(maintenance:enable) error when app does not exist" { 18 | run dokku maintenance:enable non_existing_app 19 | assert_contains "${lines[*]}" "App non_existing_app does not exist" 20 | } 21 | 22 | @test "(maintenance:enable) success" { 23 | run dokku maintenance:enable my_app 24 | assert_exists "$DOKKU_ROOT/my_app/nginx.conf.d/maintenance.conf" 25 | assert_exists "$DOKKU_ROOT/my_app/maintenance/maintenance.html" 26 | assert_success 27 | } 28 | 29 | -------------------------------------------------------------------------------- /tests/maintenance.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | setup() { 5 | dokku apps:create my_app >&2 6 | } 7 | 8 | teardown() { 9 | rm -rf "$DOKKU_ROOT/my_app" 10 | } 11 | 12 | @test "(maintenance:report) error when there are no arguments" { 13 | run dokku maintenance:report 14 | assert_contains "${lines[*]}" "Please specify an app to run the command on" 15 | } 16 | 17 | @test "(maintenance:report) error when app does not exist" { 18 | run dokku maintenance:report non_existing_app 19 | assert_contains "${lines[*]}" "App non_existing_app does not exist" 20 | } 21 | 22 | @test "(maintenance:report) success when enabled" { 23 | dokku maintenance:enable my_app 24 | run dokku maintenance:report my_app 25 | assert_contains "${lines[*]}" "true" 26 | } 27 | 28 | @test "(maintenance:report) success when disabled" { 29 | run dokku maintenance:report my_app 30 | assert_contains "${lines[*]}" "false" 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Loïc Guitaut 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /help-functions: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eo pipefail 3 | [[ $DOKKU_TRACE ]] && set -x 4 | 5 | cmd-maintenance-help() { 6 | declare desc="help command" 7 | declare CMD="$1" 8 | local plugin_name="maintenance" 9 | local plugin_description="Manage the maintenance mode for an app" 10 | 11 | if [[ "$CMD" == "${plugin_name}:help" ]]; then 12 | echo -e "Usage: dokku ${plugin_name}[:COMMAND]" 13 | echo '' 14 | echo "$plugin_description" 15 | echo '' 16 | echo 'Additional commands:' 17 | fn-help-content | sort | column -c2 -t -s, 18 | elif [[ $(ps -o command= $PPID) == *"--all"* ]]; then 19 | fn-help-content 20 | else 21 | cat <, Imports a tarball from stdin; should contain at least maintenance.html 31 | maintenance:disable , Disable app maintenance mode 32 | maintenance:enable , Enable app maintenance mode 33 | maintenance:report [] [], Displays an maintenance report for one or more apps 34 | help_content 35 | } 36 | -------------------------------------------------------------------------------- /tests/setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/test_helper.bash" 3 | 4 | BIN_STUBS="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/bin" 5 | 6 | if [[ ! -d $DOKKU_ROOT ]]; then 7 | git clone https://github.com/progrium/dokku.git "$DOKKU_ROOT" >/dev/null 8 | fi 9 | 10 | cd "$DOKKU_ROOT" 11 | echo "Dokku version $DOKKU_VERSION" 12 | git checkout "$DOKKU_VERSION" >/dev/null 13 | cd - 14 | 15 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 16 | rm -rf $DOKKU_ROOT/plugins/$PLUGIN_COMMAND_PREFIX 17 | mkdir -p $DOKKU_ROOT/plugins/$PLUGIN_COMMAND_PREFIX $DOKKU_ROOT/plugins/$PLUGIN_COMMAND_PREFIX/subcommands $DOKKU_ROOT/plugins/$PLUGIN_COMMAND_PREFIX/templates 18 | find ./ -maxdepth 1 -type f -exec cp '{}' $DOKKU_ROOT/plugins/$PLUGIN_COMMAND_PREFIX \; 19 | find ./subcommands -maxdepth 1 -type f -exec cp '{}' $DOKKU_ROOT/plugins/$PLUGIN_COMMAND_PREFIX/subcommands \; 20 | find ./templates -maxdepth 1 -type f -exec cp '{}' $DOKKU_ROOT/plugins/$PLUGIN_COMMAND_PREFIX/templates \; 21 | echo "$DOKKU_VERSION" >$DOKKU_ROOT/VERSION 22 | 23 | if [[ ! -f $BIN_STUBS/plugn ]]; then 24 | wget -O- "$PLUGN_URL" | tar xzf - -C "$BIN_STUBS" 25 | plugn init 26 | find "$DOKKU_ROOT/plugins" -mindepth 1 -maxdepth 1 -type d ! -name 'available' ! -name 'enabled' -exec ln -s {} "$DOKKU_ROOT/plugins/available" \; 27 | find "$DOKKU_ROOT/plugins" -mindepth 1 -maxdepth 1 -type d ! -name 'available' ! -name 'enabled' -exec ln -s {} "$DOKKU_ROOT/plugins/enabled" \; 28 | fi 29 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | shellcheck: 2 | ifeq ($(shell shellcheck > /dev/null 2>&1 ; echo $$?),127) 3 | ifeq ($(shell uname),Darwin) 4 | brew install shellcheck 5 | else 6 | sudo add-apt-repository 'deb http://archive.ubuntu.com/ubuntu trusty-backports main restricted universe multiverse' 7 | sudo apt-get update -qq && sudo apt-get install -qq -y shellcheck 8 | endif 9 | endif 10 | 11 | bats: 12 | ifeq ($(shell bats > /dev/null 2>&1 ; echo $$?),127) 13 | ifeq ($(shell uname),Darwin) 14 | git clone https://github.com/sstephenson/bats.git /tmp/bats 15 | cd /tmp/bats && sudo ./install.sh /usr/local 16 | rm -rf /tmp/bats 17 | else 18 | sudo add-apt-repository ppa:duggan/bats --yes 19 | sudo apt-get update -qq && sudo apt-get install -qq -y bats 20 | endif 21 | endif 22 | 23 | ci-dependencies: shellcheck bats 24 | 25 | lint: 26 | # these are disabled due to their expansive existence in the codebase. we should clean it up though 27 | # SC2046: Quote this to prevent word splitting. - https://github.com/koalaman/shellcheck/wiki/SC2046 28 | # SC2068: Double quote array expansions, otherwise they're like $* and break on spaces. - https://github.com/koalaman/shellcheck/wiki/SC2068 29 | # SC2086: Double quote to prevent globbing and word splitting - https://github.com/koalaman/shellcheck/wiki/SC2086 30 | @echo linting... 31 | @$(QUIET) find ./ -maxdepth 1 -not -path '*/\.*' | xargs file | egrep "shell|bash" | awk '{ print $$1 }' | sed 's/://g' | xargs shellcheck -e SC2046,SC2068,SC2086 32 | 33 | unit-tests: 34 | @echo running unit tests... 35 | @$(QUIET) bats tests 36 | 37 | setup: 38 | bash tests/setup.sh 39 | $(MAKE) ci-dependencies 40 | 41 | test: setup lint unit-tests 42 | -------------------------------------------------------------------------------- /templates/maintenance.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Application Offline for Maintenance 5 | 6 | 24 | 25 | 53 | 54 | 55 | 56 |
57 |

Application Offline for Maintenance.

58 |

This application is undergoing maintenance right now. Please check back later.

59 |
60 | 61 | 62 | -------------------------------------------------------------------------------- /tests/maintenance_custom_page.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | create_bad_archive() { 5 | touch "$DOKKU_ROOT/my_app/bad.html" 6 | tar cf "$DOKKU_ROOT/my_app/bad.tar" -C "$DOKKU_ROOT/my_app" bad.html 7 | } 8 | 9 | create_good_archive() { 10 | touch "$DOKKU_ROOT/my_app/maintenance.html" 11 | tar cf "$DOKKU_ROOT/my_app/good.tar" -C "$DOKKU_ROOT/my_app" maintenance.html 12 | } 13 | 14 | setup() { 15 | dokku apps:create my_app >&2 16 | } 17 | 18 | teardown() { 19 | rm -rf "$DOKKU_ROOT/my_app" 20 | } 21 | 22 | @test "(maintenance:custom-page) error when there are no arguments" { 23 | run dokku maintenance:custom-page 24 | assert_contains "${lines[*]}" "Please specify an app to run the command on" 25 | } 26 | 27 | @test "(maintenance:custom-page) error when app does not exist" { 28 | run dokku maintenance:custom-page non_existing_app 29 | assert_contains "${lines[*]}" "App non_existing_app does not exist" 30 | } 31 | 32 | @test "(maintenance:custom-page) error when tar archive not provided" { 33 | run dokku maintenance:custom-page my_app 34 | assert_contains "${lines[*]}" "archive containing at least maintenance.html expected on stdin" 35 | } 36 | 37 | @test "(maintenance:custom-page) error when tar archive not containing maintenance.html" { 38 | create_bad_archive 39 | run dokku maintenance:custom-page my_app < "$DOKKU_ROOT/my_app/bad.tar" 40 | assert_contains "${lines[*]}" "archive missing maintenance.html" 41 | } 42 | 43 | @test "(maintenance:custom-page) success" { 44 | create_good_archive 45 | run dokku maintenance:custom-page my_app < "$DOKKU_ROOT/my_app/good.tar" 46 | assert_exists "$DOKKU_ROOT/my_app/maintenance/maintenance.html" 47 | assert_success 48 | } 49 | 50 | -------------------------------------------------------------------------------- /tests/test_helper.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | export DOKKU_QUIET_OUTPUT=1 3 | export DOKKU_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/dokku" 4 | export DOKKU_VERSION=${DOKKU_VERSION:-"master"} 5 | export PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/bin:$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/dokku:$PATH" 6 | export PLUGIN_COMMAND_PREFIX="maintenance" 7 | export PLUGIN_PATH="$DOKKU_ROOT/plugins" 8 | export PLUGIN_ENABLED_PATH="$PLUGIN_PATH" 9 | export PLUGIN_AVAILABLE_PATH="$PLUGIN_PATH" 10 | export PLUGIN_CORE_AVAILABLE_PATH="$PLUGIN_PATH" 11 | export MAINTENANCE_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/fixtures" 12 | export PLUGIN_DATA_ROOT="$MAINTENANCE_ROOT" 13 | if [[ "$(uname)" == "Darwin" ]]; then 14 | export PLUGN_URL="https://github.com/dokku/plugn/releases/download/v0.3.0/plugn_0.3.0_darwin_x86_64.tgz" 15 | else 16 | export PLUGN_URL="https://github.com/dokku/plugn/releases/download/v0.3.0/plugn_0.3.0_linux_x86_64.tgz" 17 | fi 18 | 19 | mkdir -p "$PLUGIN_DATA_ROOT" 20 | rm -rf "${PLUGIN_DATA_ROOT:?}"/* 21 | 22 | flunk() { 23 | { 24 | if [ "$#" -eq 0 ]; then 25 | cat - 26 | else 27 | echo "$*" 28 | fi 29 | } 30 | return 1 31 | } 32 | 33 | assert_equal() { 34 | if [ "$1" != "$2" ]; then 35 | { 36 | echo "expected: $1" 37 | echo "actual: $2" 38 | } | flunk 39 | fi 40 | } 41 | 42 | assert_exit_status() { 43 | assert_equal "$status" "$1" 44 | } 45 | 46 | assert_success() { 47 | if [ "$status" -ne 0 ]; then 48 | flunk "command failed with exit status $status" 49 | elif [ "$#" -gt 0 ]; then 50 | assert_output "$1" 51 | fi 52 | } 53 | 54 | assert_failure() { 55 | if [[ "$status" -eq 0 ]]; then 56 | flunk "expected failed exit status" 57 | elif [[ "$#" -gt 0 ]]; then 58 | assert_output "$1" 59 | fi 60 | } 61 | 62 | assert_exists() { 63 | if [ ! -f "$1" ]; then 64 | flunk "expected file to exist: $1" 65 | fi 66 | } 67 | 68 | assert_contains() { 69 | if [[ "$1" != *"$2"* ]]; then 70 | flunk "expected $2 to be in: $1" 71 | fi 72 | } 73 | 74 | assert_output() { 75 | local expected 76 | if [ $# -eq 0 ]; then 77 | expected="$(cat -)" 78 | else 79 | expected="$1" 80 | fi 81 | assert_equal "$expected" "$output" 82 | } 83 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dokku-maintenance 2 | 3 | dokku-maintenance is a plugin for [dokku](https://github.com/progrium/dokku) that gives the ability to enable or disable maintenance mode for an application. 4 | 5 | ## requirements 6 | 7 | - dokku 0.4.x+ 8 | - docker 1.8.x 9 | 10 | ## installation 11 | 12 | ```shell 13 | # on 0.4.x+ 14 | sudo dokku plugin:install https://github.com/dokku/dokku-maintenance.git maintenance 15 | ``` 16 | 17 | ## commands 18 | 19 | ``` 20 | $ dokku help 21 | maintenance Display the list of commands 22 | maintenance:custom-page Imports a tarball from stdin; should contain at least maintenance.html 23 | maintenance:disable Disable app maintenance mode 24 | maintenance:enable Enable app maintenance mode 25 | maintenance:report [] [] Displays a maintenance report for one or more apps 26 | ``` 27 | 28 | ## usage 29 | 30 | Check maintenance status of my-app 31 | 32 | ``` 33 | # dokku maintenance:report my-app # Server side 34 | $ ssh dokku@server maintenance:report my-app # Client side 35 | 36 | -----> Maintenance status of my-app: 37 | off 38 | ``` 39 | 40 | Enable maintenance mode for my-app 41 | 42 | ``` 43 | # dokku maintenance:enable my-app # Server side 44 | $ ssh dokku@server maintenance:enable my-app # Client side 45 | 46 | -----> Enabling maintenance mode for ruby-test... 47 | done 48 | ``` 49 | 50 | Disable maintenance mode for my-app 51 | 52 | ``` 53 | # dokku maintenance:disable my-app # Server side 54 | $ ssh dokku@server maintenance:disable my-app # Client side 55 | 56 | -----> Disabling maintenance mode for ruby-test... 57 | done 58 | ``` 59 | 60 | Use a custom page for maintenance 61 | 62 | ``` 63 | # dokku maintenance:custom-page my-app < my-custom-page.tar # Server side 64 | $ ssh dokku@server maintenance:custom-page my-app < my-custom-page.tar # Client side 65 | 66 | -----> Importing custom maintenance page... 67 | maintenance.html 68 | image.jpg 69 | done 70 | ``` 71 | 72 | You have to provide at least a maintenance.html page but you can provide images, css, custom font, etc. if you want. Just write absolute paths in your html and not relative ones (so to serve image.jpg which is at the same level than your maintenance.html page you’ll write “/image.jpg” instead of “./image.jpg” or “image.jpg”). 73 | -------------------------------------------------------------------------------- /command-functions: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/config" 3 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 4 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions" 5 | source "$PLUGIN_AVAILABLE_PATH/maintenance/internal-functions" 6 | source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions" 7 | set -eo pipefail 8 | [[ $DOKKU_TRACE ]] && set -x 9 | 10 | cmd-maintenance-report() { 11 | declare desc="displays a maintenance report for one or more apps" 12 | declare cmd="maintenance:report" 13 | [[ "$1" == "$cmd" ]] && shift 1 14 | declare APP="$1" INFO_FLAG="$2" 15 | local INSTALLED_APPS 16 | INSTALLED_APPS=$(dokku_apps) 17 | 18 | if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then 19 | INFO_FLAG="$APP" 20 | APP="" 21 | fi 22 | 23 | if [[ -z "$APP" ]] && [[ -z "$INFO_FLAG" ]]; then 24 | INFO_FLAG="true" 25 | fi 26 | 27 | if [[ -z "$APP" ]]; then 28 | for app in $INSTALLED_APPS; do 29 | cmd-maintenance-report-single "$app" "$INFO_FLAG" | tee || true 30 | done 31 | else 32 | cmd-maintenance-report-single "$APP" "$INFO_FLAG" 33 | fi 34 | } 35 | 36 | cmd-maintenance-report-single() { 37 | declare APP="$1" INFO_FLAG="$2" 38 | if [[ "$INFO_FLAG" == "true" ]]; then 39 | INFO_FLAG="" 40 | fi 41 | verify_app_name "$APP" 42 | local flag_map=( 43 | "--maintenance-enabled: $(fn-maintenance-enabled "$APP")" 44 | ) 45 | 46 | if [[ -z "$INFO_FLAG" ]]; then 47 | dokku_log_info2_quiet "${APP} maintenance information" 48 | for flag in "${flag_map[@]}"; do 49 | key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')" 50 | dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")" 51 | done 52 | else 53 | local match=false 54 | local value_exists=false 55 | for flag in "${flag_map[@]}"; do 56 | valid_flags="${valid_flags} $(echo "$flag" | cut -d':' -f1)" 57 | if [[ "$flag" == "${INFO_FLAG}:"* ]]; then 58 | value=${flag#*: } 59 | size="${#value}" 60 | if [[ "$size" -ne 0 ]]; then 61 | echo "$value" && match=true && value_exists=true 62 | else 63 | match=true 64 | fi 65 | fi 66 | done 67 | [[ "$match" == "true" ]] || dokku_log_fail "Invalid flag passed, valid flags:${valid_flags}" 68 | [[ "$value_exists" == "true" ]] || dokku_log_fail "not deployed" 69 | fi 70 | } 71 | 72 | cmd-maintenance-custom-page() { 73 | declare desc="imports a tarball from stdin; should contain at least maintenance.html" 74 | declare APP="$2" 75 | local TEMP_DIR 76 | [[ -z "$APP" ]] && dokku_log_fail "Please specify an app to run the command on" 77 | verify_app_name "$APP" 78 | 79 | [[ -t 0 ]] && dokku_log_fail "Tar archive containing at least maintenance.html expected on stdin" 80 | dokku_log_info1 "Importing custom maintenance page..." 81 | TEMP_DIR=$(mktemp -d) 82 | trap 'rm -rf "$TEMP_DIR" > /dev/null' RETURN INT TERM EXIT 83 | 84 | pushd "$TEMP_DIR" >/dev/null 85 | tar xvf - <&0 86 | [[ ! -f "$TEMP_DIR/maintenance.html" ]] && dokku_log_fail "Tar archive missing maintenance.html" 87 | mkdir -p "$DOKKU_ROOT/$APP/maintenance" 88 | 89 | # shellcheck disable=SC2086 90 | mv $TEMP_DIR/* "$DOKKU_ROOT/$APP/maintenance" 91 | popd &>/dev/null || pushd "/tmp" >/dev/null 92 | dokku_log_verbose "Done" 93 | } 94 | 95 | cmd-maintenance-disable() { 96 | declare desc="take the app out of maintenance mode" 97 | declare cmd="maintenance:disable" 98 | [[ "$1" == "$cmd" ]] && shift 1 99 | if [[ "$1" == "maintenance:off" ]]; then 100 | dokku_log_warn "Deprecated: Please use maintenance:disable" 101 | shift 1 102 | fi 103 | 104 | # Support --app/$DOKKU_APP_NAME flag by reordering args into "$cmd $DOKKU_APP_NAME $@" 105 | local argv=("$@") 106 | [[ -n "$DOKKU_APP_NAME" ]] && set -- "$DOKKU_APP_NAME" $@ 107 | ## 108 | 109 | declare APP="$1" 110 | local NGINX_CONF_D="$DOKKU_ROOT/$APP/nginx.conf.d" 111 | 112 | [[ -z "$APP" ]] && dokku_log_fail "Please specify an app to run the command on" 113 | verify_app_name "$APP" 114 | 115 | if [[ ! -f "$NGINX_CONF_D/maintenance.conf" ]]; then 116 | dokku_log_info1 "Maintenance mode already disabled" 117 | return 118 | fi 119 | 120 | dokku_log_info1 "Disabling maintenance mode for $APP..." 121 | [[ -f "$NGINX_CONF_D/maintenance.conf" ]] && rm "$NGINX_CONF_D/maintenance.conf" 122 | validate_nginx "$APP" && restart_nginx "$APP" >/dev/null 123 | dokku_log_verbose "Done" 124 | } 125 | 126 | cmd-maintenance-enable() { 127 | declare desc="put the app into maintenance mode" 128 | declare cmd="maintenance:enable" 129 | [[ "$1" == "$cmd" ]] && shift 1 130 | if [[ "$1" == "maintenance:on" ]]; then 131 | dokku_log_warn "Deprecated: Please use maintenance:enable" 132 | shift 1 133 | fi 134 | 135 | # Support --app/$DOKKU_APP_NAME flag by reordering args into "$cmd $DOKKU_APP_NAME $@" 136 | local argv=("$@") 137 | [[ -n "$DOKKU_APP_NAME" ]] && set -- "$DOKKU_APP_NAME" $@ 138 | ## 139 | 140 | declare APP="$1" 141 | local NGINX_CONF_D="$DOKKU_ROOT/$APP/nginx.conf.d" 142 | local MAINTENANCE_APP_D="$DOKKU_ROOT/$APP/maintenance" 143 | 144 | [[ -z "$APP" ]] && dokku_log_fail "Please specify an app to run the command on" 145 | verify_app_name "$APP" 146 | 147 | if [[ -f "$NGINX_CONF_D/maintenance.conf" ]]; then 148 | dokku_log_info1 "Maintenance mode already enabled" 149 | return 150 | fi 151 | 152 | dokku_log_info1 "Enabling maintenance mode for $APP..." 153 | [[ -d "$NGINX_CONF_D" ]] || mkdir "$NGINX_CONF_D" 154 | 155 | if [[ ! -d "$MAINTENANCE_APP_D" ]]; then 156 | mkdir "$MAINTENANCE_APP_D" 157 | cp "$MAINTENANCE_PLUGIN_ROOT/templates/maintenance.html" "$MAINTENANCE_APP_D" 158 | fi 159 | 160 | cp "$MAINTENANCE_PLUGIN_ROOT/templates/maintenance.conf" "$NGINX_CONF_D" 161 | sed -i "s,{APP_ROOT},$DOKKU_ROOT/$APP," "$NGINX_CONF_D/maintenance.conf" 162 | validate_nginx "$APP" && restart_nginx "$APP" >/dev/null 163 | dokku_log_verbose "Done" 164 | } 165 | --------------------------------------------------------------------------------