├── .devcontainer ├── 20_init_plugin ├── Dockerfile ├── bin │ └── copy-file └── devcontainer.json ├── .editorconfig ├── .github ├── dependabot.yml ├── labels.yml └── workflows │ ├── ci.yml │ └── tagged-release.yml ├── .gitignore ├── Dockerfile ├── LICENSE.txt ├── Makefile ├── README.md ├── Vagrantfile ├── bin └── generate ├── commands ├── common-functions ├── config ├── docs └── README.md ├── functions ├── help-functions ├── install ├── plugin.toml ├── post-app-clone-setup ├── post-app-rename-setup ├── pre-delete ├── pre-restore ├── pre-start ├── scripts └── enable_ssl.sh ├── service-list ├── subcommands ├── app-links ├── backup ├── backup-auth ├── backup-deauth ├── backup-schedule ├── backup-schedule-cat ├── backup-set-encryption ├── backup-set-public-key-encryption ├── backup-unschedule ├── backup-unset-encryption ├── backup-unset-public-key-encryption ├── clone ├── connect ├── create ├── destroy ├── enter ├── exists ├── export ├── expose ├── import ├── info ├── link ├── linked ├── links ├── list ├── logs ├── pause ├── promote ├── restart ├── set ├── start ├── stop ├── unexpose ├── unlink └── upgrade ├── tests ├── hook_pre_delete.bats ├── link_networks.bats ├── service_create.bats ├── service_destroy.bats ├── service_expose.bats ├── service_info.bats ├── service_link.bats ├── service_list.bats ├── service_logs.bats ├── service_pause.bats ├── service_promote.bats ├── service_restart.bats ├── service_start.bats ├── service_stop.bats ├── service_unexpose.bats ├── service_unlink.bats ├── setup.sh ├── shellcheck-exclude ├── shellcheck-to-junit └── test_helper.bash └── update /.devcontainer/20_init_plugin: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eo pipefail 3 | 4 | log-info() { 5 | declare desc="Log info formatter" 6 | echo " $*" 1>&2 7 | } 8 | 9 | log-fail() { 10 | declare desc="Log fail formatter" 11 | echo "! $*" 1>&2 12 | exit 1 13 | } 14 | 15 | main() { 16 | dokku plugin:install 17 | 18 | # built in the Dockerfile 19 | PLUGIN_NAME="$(source /tmp/.env && echo "$PLUGIN_NAME")" 20 | PLUGIN_VARIABLE="$(source /tmp/.env && echo "$PLUGIN_VARIABLE")" 21 | echo "export ${PLUGIN_VARIABLE}_HOST_ROOT=${SERVICE_HOST_ROOT}/$PLUGIN_NAME" >/etc/default/dokku 22 | } 23 | 24 | main "$@" 25 | -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM dokku/dokku:latest 2 | 3 | RUN apt-get update 4 | RUN apt-get install --no-install-recommends -y build-essential file nano && \ 5 | apt-get clean autoclean && \ 6 | apt-get autoremove --yes && \ 7 | rm -rf /var/lib/apt/lists/* && \ 8 | mkdir -p /mnt/dokku/home/dokku /mnt/dokku/var/lib/dokku/config /mnt/dokku/var/lib/dokku/data /mnt/dokku/var/lib/dokku/services && \ 9 | chown -R dokku:dokku /mnt/dokku/home/dokku /mnt/dokku/var/lib/dokku/config /mnt/dokku/var/lib/dokku/data /mnt/dokku/var/lib/dokku/services && \ 10 | echo "dokku.me" > /home/dokku/VHOST 11 | 12 | ADD https://raw.githubusercontent.com/dokku/dokku/master/tests/dhparam.pem /mnt/dokku/etc/nginx/dhparam.pem 13 | 14 | COPY .devcontainer/20_init_plugin /etc/my_init.d/20_init_plugin 15 | COPY .devcontainer/bin/ /usr/local/bin/ 16 | 17 | COPY . . 18 | 19 | RUN source /tmp/config && \ 20 | echo "export ${PLUGIN_DISABLE_PULL_VARIABLE}=true" > /tmp/.env && \ 21 | echo "export PLUGIN_NAME=${PLUGIN_COMMAND_PREFIX}" >> /tmp/.env && \ 22 | echo "export PLUGIN_VARIABLE=${PLUGIN_VARIABLE}" >> /tmp/.env 23 | 24 | RUN source /tmp/.env && \ 25 | dokku plugin:install file:///tmp --name $PLUGIN_NAME && \ 26 | make ci-dependencies 27 | -------------------------------------------------------------------------------- /.devcontainer/bin/copy-file: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | main() { 4 | PLUGIN_NAME="$(source /tmp/.env && echo "$PLUGIN_NAME")" 5 | cp "$1" "/var/lib/dokku/plugins/enabled/$PLUGIN_NAME/$1" 6 | } 7 | 8 | main "$@" 9 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "dockerfile": "Dockerfile", 4 | "context": ".." 5 | }, 6 | "containerEnv": { 7 | "SERVICE_HOST_ROOT": "${localWorkspaceFolder}/tmp/data" 8 | }, 9 | "initializeCommand": ["mkdir", "-p", "tmp/data"], 10 | "mounts": [ 11 | "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind", 12 | "source=${localWorkspaceFolder}/tmp/data/,target=/var/lib/dokku/services/,type=bind" 13 | ], 14 | "overrideCommand": false, 15 | "runArgs": ["--init"] 16 | } 17 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | insert_final_newline = true 5 | indent_style = space 6 | indent_size = 2 7 | 8 | [Makefile] 9 | insert_final_newline = true 10 | indent_style = tab 11 | indent_size = 4 12 | 13 | [*.mk] 14 | insert_final_newline = true 15 | indent_style = tab 16 | indent_size = 4 17 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2 3 | updates: 4 | - package-ecosystem: "docker" 5 | directory: "/" 6 | schedule: 7 | interval: "daily" 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: daily 12 | open-pull-requests-limit: 10 13 | -------------------------------------------------------------------------------- /.github/labels.yml: -------------------------------------------------------------------------------- 1 | labels: 2 | - name: bc-break 3 | color: eb6420 4 | - name: blocks release 5 | color: "000000" 6 | - name: 'difficulty: easy' 7 | color: c5def5 8 | - name: 'difficulty: hard' 9 | color: e99695 10 | - name: 'difficulty: medium' 11 | color: fef2c0 12 | - name: hacktoberfest 13 | color: b0581d 14 | - name: 'needs: documentation' 15 | color: c2e0c6 16 | - name: 'needs: more info' 17 | color: c2e0c6 18 | - name: 'needs: rebase' 19 | color: c2e0c6 20 | - name: 'needs: tests' 21 | color: c2e0c6 22 | - name: 'status: duplicate' 23 | color: cccccc 24 | - name: 'status: fix-provided' 25 | color: c5def5 26 | - name: 'status: future' 27 | color: c5def5 28 | - name: 'status: has plan' 29 | color: c5def5 30 | - name: 'status: invalid' 31 | color: cccccc 32 | - name: 'status: merge for next minor' 33 | color: c5def5 34 | - name: 'status: merge for next patch' 35 | color: c5def5 36 | - name: 'status: wontfix' 37 | color: cccccc 38 | - name: 'type: bug' 39 | color: e01b1b 40 | - name: 'type: documentation' 41 | color: 0052cc 42 | - name: 'type: enhancement' 43 | color: 09ab3c 44 | - name: 'type: question' 45 | color: cc317c 46 | - name: 'type: refactor' 47 | color: 0052cc 48 | - name: 'type: rfc' 49 | color: 0052cc 50 | - name: 'type: roadmap' 51 | color: 0052cc 52 | - name: 'type: service' 53 | color: "5319e7" 54 | - name: 'type: support' 55 | color: cc317c 56 | - name: 'type: tests' 57 | color: 0052cc 58 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: CI 3 | 4 | # yamllint disable-line rule:truthy 5 | on: 6 | pull_request: 7 | branches: 8 | - "*" 9 | push: 10 | branches: 11 | - master 12 | 13 | concurrency: 14 | group: build-${{ github.event.pull_request.number || github.ref }} 15 | cancel-in-progress: true 16 | 17 | jobs: 18 | unit-tests-master: 19 | name: unit-tests 20 | runs-on: ubuntu-24.04 21 | env: 22 | DOKKU_VERSION: master 23 | 24 | steps: 25 | - uses: actions/checkout@v4 26 | with: 27 | fetch-depth: 0 28 | 29 | - uses: actions/setup-python@v5 30 | with: 31 | python-version: "3.13" 32 | 33 | - run: make setup 34 | 35 | - run: sudo sysctl -w vm.max_map_count=262144 36 | 37 | - run: | 38 | git fetch -q origin master 39 | changed=$(git --no-pager diff --name-only $GITHUB_SHA..origin/master) 40 | if [ $changed = "Dockerfile" ]; then 41 | echo "Please run 'make generate' to update the image version in the README.md" 42 | else 43 | make generate 44 | if ! git diff --quiet README.md; then 45 | echo "Please run 'make generate'" 46 | git status --short 47 | git --no-pager diff README.md 48 | exit 1 49 | fi 50 | fi 51 | 52 | - run: make test 53 | 54 | - uses: actions/upload-artifact@v4 55 | if: failure() 56 | with: 57 | name: tmp/test-results 58 | path: test-results 59 | 60 | unit-tests-0_19_0: 61 | name: unit-tests-0.19.0 62 | runs-on: ubuntu-24.04 63 | env: 64 | DOKKU_TAG: v0.19.0 65 | 66 | steps: 67 | - uses: actions/checkout@v4 68 | with: 69 | fetch-depth: 0 70 | 71 | - uses: actions/setup-python@v5 72 | with: 73 | python-version: "3.13" 74 | 75 | - run: make setup 76 | 77 | - run: sudo sysctl -w vm.max_map_count=262144 78 | 79 | - run: | 80 | git fetch -q origin master 81 | changed=$(git --no-pager diff --name-only $GITHUB_SHA..origin/master) 82 | if [ $changed = "Dockerfile" ]; then 83 | echo "Please run 'make generate' to update the image version in the README.md" 84 | else 85 | make generate 86 | if ! git diff --quiet README.md; then 87 | echo "Please run 'make generate'" 88 | git status --short 89 | git --no-pager diff README.md 90 | exit 1 91 | fi 92 | fi 93 | 94 | - run: make test 95 | 96 | - uses: actions/upload-artifact@v4 97 | if: failure() 98 | with: 99 | name: tmp/test-results 100 | path: test-results 101 | -------------------------------------------------------------------------------- /.github/workflows/tagged-release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "tagged-release" 3 | 4 | # yamllint disable-line rule:truthy 5 | on: 6 | push: 7 | tags: 8 | - "*" 9 | 10 | jobs: 11 | tagged-release: 12 | name: tagged-release 13 | runs-on: ubuntu-24.04 14 | 15 | steps: 16 | - name: Release 17 | uses: softprops/action-gh-release@v2.2.2 18 | with: 19 | generate_release_notes: true 20 | make_latest: "true" 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /tmp 2 | .vagrant 3 | bootstrap.sh 4 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM getmeili/meilisearch:v1.14.0 2 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) 2021 Jose Diaz-Gonzalez 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | HARDWARE = $(shell uname -m) 2 | SYSTEM_NAME = $(shell uname -s | tr '[:upper:]' '[:lower:]') 3 | ARCH = $(shell dpkg --print-architecture) 4 | SHFMT_VERSION = 3.0.2 5 | XUNIT_TO_GITHUB_VERSION = 0.3.0 6 | XUNIT_READER_VERSION = 0.1.0 7 | 8 | 9 | bats: 10 | ifeq ($(SYSTEM_NAME),darwin) 11 | ifneq ($(shell bats --version >/dev/null 2>&1 ; echo $$?),0) 12 | brew install bats-core 13 | endif 14 | else 15 | git clone https://github.com/bats-core/bats-core.git /tmp/bats 16 | cd /tmp/bats && sudo ./install.sh /usr/local 17 | rm -rf /tmp/bats 18 | endif 19 | 20 | shellcheck: 21 | ifneq ($(shell shellcheck --version >/dev/null 2>&1 ; echo $$?),0) 22 | ifeq ($(SYSTEM_NAME),darwin) 23 | brew install shellcheck 24 | else 25 | ifeq ($(ARCH),arm64) 26 | sudo add-apt-repository 'deb http://ports.ubuntu.com/ubuntu-ports jammy-backports main restricted universe multiverse' 27 | else 28 | sudo add-apt-repository 'deb http://archive.ubuntu.com/ubuntu jammy-backports main restricted universe multiverse' 29 | endif 30 | sudo rm -rf /var/lib/apt/lists/* && sudo apt-get clean 31 | sudo apt-get update -qq && sudo apt-get install -qq -y shellcheck 32 | endif 33 | endif 34 | 35 | shfmt: 36 | ifneq ($(shell shfmt --version >/dev/null 2>&1 ; echo $$?),0) 37 | ifeq ($(shfmt),Darwin) 38 | brew install shfmt 39 | else 40 | wget -qO /tmp/shfmt https://github.com/mvdan/sh/releases/download/v$(SHFMT_VERSION)/shfmt_v$(SHFMT_VERSION)_linux_amd64 41 | chmod +x /tmp/shfmt 42 | sudo mv /tmp/shfmt /usr/local/bin/shfmt 43 | endif 44 | endif 45 | 46 | readlink: 47 | ifeq ($(shell uname),Darwin) 48 | ifeq ($(shell greadlink > /dev/null 2>&1 ; echo $$?),127) 49 | brew install coreutils 50 | endif 51 | ln -nfs `which greadlink` tests/bin/readlink 52 | endif 53 | 54 | ci-dependencies: shellcheck bats readlink 55 | 56 | lint-setup: 57 | @mkdir -p tmp/test-results/shellcheck tmp/shellcheck 58 | @find . -not -path '*/\.*' -type f | xargs file | grep text | awk -F ':' '{ print $$1 }' | xargs head -n1 | egrep -B1 "bash" | grep "==>" | awk '{ print $$2 }' > tmp/shellcheck/test-files 59 | @cat tests/shellcheck-exclude | sed -n -e '/^# SC/p' | cut -d' ' -f2 | paste -d, -s - > tmp/shellcheck/exclude 60 | 61 | lint: lint-setup 62 | # these are disabled due to their expansive existence in the codebase. we should clean it up though 63 | @cat tests/shellcheck-exclude | sed -n -e '/^# SC/p' 64 | @echo linting... 65 | @cat tmp/shellcheck/test-files | xargs shellcheck -e $(shell cat tmp/shellcheck/exclude) | tests/shellcheck-to-junit --output tmp/test-results/shellcheck/results.xml --files tmp/shellcheck/test-files --exclude $(shell cat tmp/shellcheck/exclude) 66 | 67 | unit-tests: 68 | @echo running unit tests... 69 | @mkdir -p tmp/test-results/bats 70 | @cd tests && echo "executing tests: $(shell cd tests ; ls *.bats | xargs)" 71 | cd tests && bats --report-formatter junit --timing -o ../tmp/test-results/bats *.bats 72 | 73 | tmp/xunit-reader: 74 | mkdir -p tmp 75 | curl -o tmp/xunit-reader.tgz -sL https://github.com/josegonzalez/go-xunit-reader/releases/download/v$(XUNIT_READER_VERSION)/xunit-reader_$(XUNIT_READER_VERSION)_$(SYSTEM_NAME)_$(HARDWARE).tgz 76 | tar xf tmp/xunit-reader.tgz -C tmp 77 | chmod +x tmp/xunit-reader 78 | 79 | setup: 80 | bash tests/setup.sh 81 | $(MAKE) ci-dependencies 82 | 83 | test: lint unit-tests 84 | 85 | report: tmp/xunit-reader 86 | tmp/xunit-reader -p 'tmp/test-results/bats/*.xml' 87 | tmp/xunit-reader -p 'tmp/test-results/shellcheck/*.xml' 88 | 89 | .PHONY: clean 90 | clean: 91 | rm -f README.md 92 | 93 | .PHONY: generate 94 | generate: clean README.md 95 | 96 | .PHONY: README.md 97 | README.md: 98 | bin/generate 99 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dokku meilisearch [![Build Status](https://img.shields.io/github/actions/workflow/status/dokku/dokku-meilisearch/ci.yml?branch=master&style=flat-square "Build Status")](https://github.com/dokku/dokku-meilisearch/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) 2 | 3 | Official meilisearch plugin for dokku. Currently defaults to installing [getmeili/meilisearch v1.14.0](https://hub.docker.com/r/getmeili/meilisearch/). 4 | 5 | ## Requirements 6 | 7 | - dokku 0.19.x+ 8 | - docker 1.8.x 9 | 10 | ## Installation 11 | 12 | ```shell 13 | # on 0.19.x+ 14 | sudo dokku plugin:install https://github.com/dokku/dokku-meilisearch.git --name meilisearch 15 | ``` 16 | 17 | ## Commands 18 | 19 | ``` 20 | meilisearch:app-links # list all meilisearch service links for a given app 21 | meilisearch:backup-set-public-key-encryption # set GPG Public Key encryption for all future backups of meilisearch service 22 | meilisearch:backup-unset-public-key-encryption # unset GPG Public Key encryption for future backups of the meilisearch service 23 | meilisearch:create [--create-flags...] # create a meilisearch service 24 | meilisearch:destroy [-f|--force] # delete the meilisearch service/data/container if there are no links left 25 | meilisearch:enter # enter or run a command in a running meilisearch service container 26 | meilisearch:exists # check if the meilisearch service exists 27 | meilisearch:expose # expose a meilisearch service on custom host:port if provided (random port on the 0.0.0.0 interface if otherwise unspecified) 28 | meilisearch:info [--single-info-flag] # print the service information 29 | meilisearch:link [--link-flags...] # link the meilisearch service to the app 30 | meilisearch:linked # check if the meilisearch service is linked to an app 31 | meilisearch:links # list all apps linked to the meilisearch service 32 | meilisearch:list # list all meilisearch services 33 | meilisearch:logs [-t|--tail] # print the most recent log(s) for this service 34 | meilisearch:pause # pause a running meilisearch service 35 | meilisearch:promote # promote service as MEILISEARCH_URL in 36 | meilisearch:restart # graceful shutdown and restart of the meilisearch service container 37 | meilisearch:set # set or clear a property for a service 38 | meilisearch:start # start a previously stopped meilisearch service 39 | meilisearch:stop # stop a running meilisearch service 40 | meilisearch:unexpose # unexpose a previously exposed meilisearch service 41 | meilisearch:unlink # unlink the meilisearch service from the app 42 | meilisearch:upgrade [--upgrade-flags...] # upgrade service to the specified versions 43 | ``` 44 | 45 | ## Usage 46 | 47 | Help for any commands can be displayed by specifying the command as an argument to meilisearch:help. Plugin help output in conjunction with any files in the `docs/` folder is used to generate the plugin documentation. Please consult the `meilisearch:help` command for any undocumented commands. 48 | 49 | ### Basic Usage 50 | 51 | ### create a meilisearch service 52 | 53 | ```shell 54 | # usage 55 | dokku meilisearch:create [--create-flags...] 56 | ``` 57 | 58 | flags: 59 | 60 | - `-c|--config-options "--args --go=here"`: extra arguments to pass to the container create command (default: `None`) 61 | - `-C|--custom-env "USER=alpha;HOST=beta"`: semi-colon delimited environment variables to start the service with 62 | - `-i|--image IMAGE`: the image name to start the service with 63 | - `-I|--image-version IMAGE_VERSION`: the image version to start the service with 64 | - `-m|--memory MEMORY`: container memory limit in megabytes (default: unlimited) 65 | - `-N|--initial-network INITIAL_NETWORK`: the initial network to attach the service to 66 | - `-p|--password PASSWORD`: override the user-level service password 67 | - `-P|--post-create-network NETWORKS`: a comma-separated list of networks to attach the service container to after service creation 68 | - `-r|--root-password PASSWORD`: override the root-level service password 69 | - `-S|--post-start-network NETWORKS`: a comma-separated list of networks to attach the service container to after service start 70 | - `-s|--shm-size SHM_SIZE`: override shared memory size for meilisearch docker container 71 | 72 | Create a meilisearch service named lollipop: 73 | 74 | ```shell 75 | dokku meilisearch:create lollipop 76 | ``` 77 | 78 | You can also specify the image and image version to use for the service. It *must* be compatible with the getmeili/meilisearch image. 79 | 80 | ```shell 81 | export MEILISEARCH_IMAGE="getmeili/meilisearch" 82 | export MEILISEARCH_IMAGE_VERSION="${PLUGIN_IMAGE_VERSION}" 83 | dokku meilisearch:create lollipop 84 | ``` 85 | 86 | You can also specify custom environment variables to start the meilisearch service in semicolon-separated form. 87 | 88 | ```shell 89 | export MEILISEARCH_CUSTOM_ENV="USER=alpha;HOST=beta" 90 | dokku meilisearch:create lollipop 91 | ``` 92 | 93 | ### print the service information 94 | 95 | ```shell 96 | # usage 97 | dokku meilisearch:info [--single-info-flag] 98 | ``` 99 | 100 | flags: 101 | 102 | - `--config-dir`: show the service configuration directory 103 | - `--data-dir`: show the service data directory 104 | - `--dsn`: show the service DSN 105 | - `--exposed-ports`: show service exposed ports 106 | - `--id`: show the service container id 107 | - `--internal-ip`: show the service internal ip 108 | - `--initial-network`: show the initial network being connected to 109 | - `--links`: show the service app links 110 | - `--post-create-network`: show the networks to attach to after service container creation 111 | - `--post-start-network`: show the networks to attach to after service container start 112 | - `--service-root`: show the service root directory 113 | - `--status`: show the service running status 114 | - `--version`: show the service image version 115 | 116 | Get connection information as follows: 117 | 118 | ```shell 119 | dokku meilisearch:info lollipop 120 | ``` 121 | 122 | You can also retrieve a specific piece of service info via flags: 123 | 124 | ```shell 125 | dokku meilisearch:info lollipop --config-dir 126 | dokku meilisearch:info lollipop --data-dir 127 | dokku meilisearch:info lollipop --dsn 128 | dokku meilisearch:info lollipop --exposed-ports 129 | dokku meilisearch:info lollipop --id 130 | dokku meilisearch:info lollipop --internal-ip 131 | dokku meilisearch:info lollipop --initial-network 132 | dokku meilisearch:info lollipop --links 133 | dokku meilisearch:info lollipop --post-create-network 134 | dokku meilisearch:info lollipop --post-start-network 135 | dokku meilisearch:info lollipop --service-root 136 | dokku meilisearch:info lollipop --status 137 | dokku meilisearch:info lollipop --version 138 | ``` 139 | 140 | ### list all meilisearch services 141 | 142 | ```shell 143 | # usage 144 | dokku meilisearch:list 145 | ``` 146 | 147 | List all services: 148 | 149 | ```shell 150 | dokku meilisearch:list 151 | ``` 152 | 153 | ### print the most recent log(s) for this service 154 | 155 | ```shell 156 | # usage 157 | dokku meilisearch:logs [-t|--tail] 158 | ``` 159 | 160 | flags: 161 | 162 | - `-t|--tail []`: do not stop when end of the logs are reached and wait for additional output 163 | 164 | You can tail logs for a particular service: 165 | 166 | ```shell 167 | dokku meilisearch:logs lollipop 168 | ``` 169 | 170 | By default, logs will not be tailed, but you can do this with the --tail flag: 171 | 172 | ```shell 173 | dokku meilisearch:logs lollipop --tail 174 | ``` 175 | 176 | The default tail setting is to show all logs, but an initial count can also be specified: 177 | 178 | ```shell 179 | dokku meilisearch:logs lollipop --tail 5 180 | ``` 181 | 182 | ### link the meilisearch service to the app 183 | 184 | ```shell 185 | # usage 186 | dokku meilisearch:link [--link-flags...] 187 | ``` 188 | 189 | flags: 190 | 191 | - `-a|--alias "BLUE_DATABASE"`: an alternative alias to use for linking to an app via environment variable 192 | - `-q|--querystring "pool=5"`: ampersand delimited querystring arguments to append to the service link 193 | - `-n|--no-restart "false"`: whether or not to restart the app on link (default: true) 194 | 195 | A meilisearch 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. 196 | 197 | > NOTE: this will restart your app 198 | 199 | ```shell 200 | dokku meilisearch:link lollipop playground 201 | ``` 202 | 203 | The following environment variables will be set automatically by docker (not on the app itself, so they won’t be listed when calling dokku config): 204 | 205 | ``` 206 | DOKKU_MEILISEARCH_LOLLIPOP_NAME=/lollipop/DATABASE 207 | DOKKU_MEILISEARCH_LOLLIPOP_PORT=tcp://172.17.0.1:7700 208 | DOKKU_MEILISEARCH_LOLLIPOP_PORT_7700_TCP=tcp://172.17.0.1:7700 209 | DOKKU_MEILISEARCH_LOLLIPOP_PORT_7700_TCP_PROTO=tcp 210 | DOKKU_MEILISEARCH_LOLLIPOP_PORT_7700_TCP_PORT=7700 211 | DOKKU_MEILISEARCH_LOLLIPOP_PORT_7700_TCP_ADDR=172.17.0.1 212 | ``` 213 | 214 | The following will be set on the linked application by default: 215 | 216 | ``` 217 | MEILISEARCH_URL=http://:SOME_PASSWORD@dokku-meilisearch-lollipop:7700 218 | ``` 219 | 220 | The host exposed here only works internally in docker containers. If you want your container to be reachable from outside, you should use the `expose` subcommand. Another service can be linked to your app: 221 | 222 | ```shell 223 | dokku meilisearch:link other_service playground 224 | ``` 225 | 226 | It is possible to change the protocol for `MEILISEARCH_URL` by setting the environment variable `MEILISEARCH_DATABASE_SCHEME` on the app. Doing so will after linking will cause the plugin to think the service is not linked, and we advise you to unlink before proceeding. 227 | 228 | ```shell 229 | dokku config:set playground MEILISEARCH_DATABASE_SCHEME=http2 230 | dokku meilisearch:link lollipop playground 231 | ``` 232 | 233 | This will cause `MEILISEARCH_URL` to be set as: 234 | 235 | ``` 236 | http2://:SOME_PASSWORD@dokku-meilisearch-lollipop:7700 237 | ``` 238 | 239 | ### unlink the meilisearch service from the app 240 | 241 | ```shell 242 | # usage 243 | dokku meilisearch:unlink 244 | ``` 245 | 246 | flags: 247 | 248 | - `-n|--no-restart "false"`: whether or not to restart the app on unlink (default: true) 249 | 250 | You can unlink a meilisearch service: 251 | 252 | > NOTE: this will restart your app and unset related environment variables 253 | 254 | ```shell 255 | dokku meilisearch:unlink lollipop playground 256 | ``` 257 | 258 | ### set or clear a property for a service 259 | 260 | ```shell 261 | # usage 262 | dokku meilisearch:set 263 | ``` 264 | 265 | Set the network to attach after the service container is started: 266 | 267 | ```shell 268 | dokku meilisearch:set lollipop post-create-network custom-network 269 | ``` 270 | 271 | Set multiple networks: 272 | 273 | ```shell 274 | dokku meilisearch:set lollipop post-create-network custom-network,other-network 275 | ``` 276 | 277 | Unset the post-create-network value: 278 | 279 | ```shell 280 | dokku meilisearch:set lollipop post-create-network 281 | ``` 282 | 283 | ### Service Lifecycle 284 | 285 | The lifecycle of each service can be managed through the following commands: 286 | 287 | ### enter or run a command in a running meilisearch service container 288 | 289 | ```shell 290 | # usage 291 | dokku meilisearch:enter 292 | ``` 293 | 294 | A bash prompt can be opened against a running service. Filesystem changes will not be saved to disk. 295 | 296 | > NOTE: disconnecting from ssh while running this command may leave zombie processes due to moby/moby#9098 297 | 298 | ```shell 299 | dokku meilisearch:enter lollipop 300 | ``` 301 | 302 | You may also run a command directly against the service. Filesystem changes will not be saved to disk. 303 | 304 | ```shell 305 | dokku meilisearch:enter lollipop touch /tmp/test 306 | ``` 307 | 308 | ### expose a meilisearch service on custom host:port if provided (random port on the 0.0.0.0 interface if otherwise unspecified) 309 | 310 | ```shell 311 | # usage 312 | dokku meilisearch:expose 313 | ``` 314 | 315 | Expose the service on the service's normal ports, allowing access to it from the public interface (`0.0.0.0`): 316 | 317 | ```shell 318 | dokku meilisearch:expose lollipop 7700 319 | ``` 320 | 321 | Expose the service on the service's normal ports, with the first on a specified ip address (127.0.0.1): 322 | 323 | ```shell 324 | dokku meilisearch:expose lollipop 127.0.0.1:7700 325 | ``` 326 | 327 | ### unexpose a previously exposed meilisearch service 328 | 329 | ```shell 330 | # usage 331 | dokku meilisearch:unexpose 332 | ``` 333 | 334 | Unexpose the service, removing access to it from the public interface (`0.0.0.0`): 335 | 336 | ```shell 337 | dokku meilisearch:unexpose lollipop 338 | ``` 339 | 340 | ### promote service as MEILISEARCH_URL in 341 | 342 | ```shell 343 | # usage 344 | dokku meilisearch:promote 345 | ``` 346 | 347 | If you have a meilisearch service linked to an app and try to link another meilisearch service another link environment variable will be generated automatically: 348 | 349 | ``` 350 | DOKKU_MEILISEARCH_BLUE_URL=http://other_service:ANOTHER_PASSWORD@dokku-meilisearch-other-service:7700/other_service 351 | ``` 352 | 353 | You can promote the new service to be the primary one: 354 | 355 | > NOTE: this will restart your app 356 | 357 | ```shell 358 | dokku meilisearch:promote other_service playground 359 | ``` 360 | 361 | This will replace `MEILISEARCH_URL` with the url from other_service and generate another environment variable to hold the previous value if necessary. You could end up with the following for example: 362 | 363 | ``` 364 | MEILISEARCH_URL=http://other_service:ANOTHER_PASSWORD@dokku-meilisearch-other-service:7700/other_service 365 | DOKKU_MEILISEARCH_BLUE_URL=http://other_service:ANOTHER_PASSWORD@dokku-meilisearch-other-service:7700/other_service 366 | DOKKU_MEILISEARCH_SILVER_URL=http://lollipop:SOME_PASSWORD@dokku-meilisearch-lollipop:7700/lollipop 367 | ``` 368 | 369 | ### start a previously stopped meilisearch service 370 | 371 | ```shell 372 | # usage 373 | dokku meilisearch:start 374 | ``` 375 | 376 | Start the service: 377 | 378 | ```shell 379 | dokku meilisearch:start lollipop 380 | ``` 381 | 382 | ### stop a running meilisearch service 383 | 384 | ```shell 385 | # usage 386 | dokku meilisearch:stop 387 | ``` 388 | 389 | Stop the service and removes the running container: 390 | 391 | ```shell 392 | dokku meilisearch:stop lollipop 393 | ``` 394 | 395 | ### pause a running meilisearch service 396 | 397 | ```shell 398 | # usage 399 | dokku meilisearch:pause 400 | ``` 401 | 402 | Pause the running container for the service: 403 | 404 | ```shell 405 | dokku meilisearch:pause lollipop 406 | ``` 407 | 408 | ### graceful shutdown and restart of the meilisearch service container 409 | 410 | ```shell 411 | # usage 412 | dokku meilisearch:restart 413 | ``` 414 | 415 | Restart the service: 416 | 417 | ```shell 418 | dokku meilisearch:restart lollipop 419 | ``` 420 | 421 | ### upgrade service to the specified versions 422 | 423 | ```shell 424 | # usage 425 | dokku meilisearch:upgrade [--upgrade-flags...] 426 | ``` 427 | 428 | flags: 429 | 430 | - `-c|--config-options "--args --go=here"`: extra arguments to pass to the container create command (default: `None`) 431 | - `-C|--custom-env "USER=alpha;HOST=beta"`: semi-colon delimited environment variables to start the service with 432 | - `-i|--image IMAGE`: the image name to start the service with 433 | - `-I|--image-version IMAGE_VERSION`: the image version to start the service with 434 | - `-N|--initial-network INITIAL_NETWORK`: the initial network to attach the service to 435 | - `-P|--post-create-network NETWORKS`: a comma-separated list of networks to attach the service container to after service creation 436 | - `-R|--restart-apps "true"`: whether or not to force an app restart (default: false) 437 | - `-S|--post-start-network NETWORKS`: a comma-separated list of networks to attach the service container to after service start 438 | - `-s|--shm-size SHM_SIZE`: override shared memory size for meilisearch docker container 439 | 440 | You can upgrade an existing service to a new image or image-version: 441 | 442 | ```shell 443 | dokku meilisearch:upgrade lollipop 444 | ``` 445 | 446 | ### Service Automation 447 | 448 | Service scripting can be executed using the following commands: 449 | 450 | ### list all meilisearch service links for a given app 451 | 452 | ```shell 453 | # usage 454 | dokku meilisearch:app-links 455 | ``` 456 | 457 | List all meilisearch services that are linked to the `playground` app. 458 | 459 | ```shell 460 | dokku meilisearch:app-links playground 461 | ``` 462 | 463 | ### check if the meilisearch service exists 464 | 465 | ```shell 466 | # usage 467 | dokku meilisearch:exists 468 | ``` 469 | 470 | Here we check if the lollipop meilisearch service exists. 471 | 472 | ```shell 473 | dokku meilisearch:exists lollipop 474 | ``` 475 | 476 | ### check if the meilisearch service is linked to an app 477 | 478 | ```shell 479 | # usage 480 | dokku meilisearch:linked 481 | ``` 482 | 483 | Here we check if the lollipop meilisearch service is linked to the `playground` app. 484 | 485 | ```shell 486 | dokku meilisearch:linked lollipop playground 487 | ``` 488 | 489 | ### list all apps linked to the meilisearch service 490 | 491 | ```shell 492 | # usage 493 | dokku meilisearch:links 494 | ``` 495 | 496 | List all apps linked to the `lollipop` meilisearch service. 497 | 498 | ```shell 499 | dokku meilisearch:links lollipop 500 | ``` 501 | ### Backups 502 | 503 | Datastore backups are supported via AWS S3 and S3 compatible services like [minio](https://github.com/minio/minio). 504 | 505 | You may skip the `backup-auth` step if your dokku install is running within EC2 and has access to the bucket via an IAM profile. In that case, use the `--use-iam` option with the `backup` command. 506 | 507 | Backups can be performed using the backup commands: 508 | 509 | ### set GPG Public Key encryption for all future backups of meilisearch service 510 | 511 | ```shell 512 | # usage 513 | dokku meilisearch:backup-set-public-key-encryption 514 | ``` 515 | 516 | Set the `GPG` Public Key for encrypting backups: 517 | 518 | ```shell 519 | dokku meilisearch:backup-set-public-key-encryption lollipop 520 | ``` 521 | 522 | ### unset GPG Public Key encryption for future backups of the meilisearch service 523 | 524 | ```shell 525 | # usage 526 | dokku meilisearch:backup-unset-public-key-encryption 527 | ``` 528 | 529 | Unset the `GPG` Public Key encryption for backups: 530 | 531 | ```shell 532 | dokku meilisearch:backup-unset-public-key-encryption lollipop 533 | ``` 534 | 535 | ### Disabling `docker image pull` calls 536 | 537 | If you wish to disable the `docker image pull` calls that the plugin triggers, you may set the `MEILISEARCH_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. 538 | 539 | Please ensure the proper images are in place when `docker image pull` is disabled. 540 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | BOX_NAME = ENV["BOX_NAME"] || "bento/ubuntu-24.04" 5 | BOX_MEMORY = ENV["BOX_MEMORY"] || "2048" 6 | DOKKU_VERSION = "master" 7 | 8 | Vagrant.configure(2) do |config| 9 | config.vm.box = BOX_NAME 10 | config.ssh.forward_agent = true 11 | 12 | config.vm.provider :virtualbox do |vb| 13 | vb.customize ["modifyvm", :id, "--memory", BOX_MEMORY] 14 | end 15 | 16 | config.vm.provider :vmware_fusion do |v, override| 17 | v.vmx["memsize"] = BOX_MEMORY 18 | end 19 | 20 | config.vm.define "default", primary: true do |vm| 21 | vm.vm.synced_folder File.dirname(__FILE__), "/vagrant" 22 | 23 | vm.vm.provision :shell, :inline => "apt -q update && apt -y -qq install git software-properties-common" 24 | vm.vm.provision :shell, :inline => "cd /vagrant && DOKKU_VERSION=#{DOKKU_VERSION} make setup" 25 | vm.vm.provision :shell, :inline => "cd /vagrant && DOKKU_TRACE=1 DOKKU_VERSION=#{DOKKU_VERSION} make test" 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /bin/generate: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | from __future__ import print_function 4 | 5 | import os 6 | import re 7 | 8 | 9 | def compile( 10 | service, 11 | version, 12 | variable, 13 | alias, 14 | image, 15 | scheme, 16 | ports, 17 | sponsors, 18 | options, 19 | unimplemented, 20 | dokku_version, 21 | ): 22 | prefix = "\n\n".join( 23 | [ 24 | header(service), 25 | description(service, image, version), 26 | ] 27 | ) 28 | 29 | if len(sponsors) > 0: 30 | prefix += "\n\n" 31 | prefix += sponsors_section(service, sponsors) 32 | 33 | return ( 34 | "\n\n".join( 35 | [ 36 | prefix, 37 | requirements_section(dokku_version), 38 | installation_section(service, dokku_version), 39 | commands_section( 40 | service, variable, alias, image, scheme, ports, unimplemented 41 | ), 42 | usage_section( 43 | service, 44 | variable, 45 | alias, 46 | image, 47 | scheme, 48 | ports, 49 | options, 50 | unimplemented, 51 | ), 52 | ] 53 | ) 54 | .replace("\n\n\n\n\n", "\n") 55 | .replace("\n\n\n\n", "\n") 56 | .replace("\n\n\n", "\n\n") 57 | ) 58 | 59 | 60 | def header(service): 61 | return " ".join( 62 | [ 63 | f"# dokku {service}", 64 | 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)', 65 | f'[![IRC Network](https://img.shields.io/badge/irc-libera-blue.svg?style=flat-square "IRC Libera")](https://webchat.libera.chat/?channels=dokku)', 66 | ] 67 | ) 68 | 69 | 70 | def description(service, full_image, version): 71 | base = "_" 72 | image = full_image 73 | if "/" in full_image: 74 | base = "r/" + full_image.split("/")[0] 75 | image = full_image.split("/")[1] 76 | 77 | return f"Official {service} plugin for dokku. Currently defaults to installing [{full_image} {version}](https://hub.docker.com/{base}/{image}/)." 78 | 79 | 80 | def sponsors_section(service, sponsors): 81 | if len(sponsors) == 0: 82 | return "" 83 | 84 | sponsor_data = [ 85 | "## Sponsors", 86 | "", 87 | f"The {service} plugin was generously sponsored by the following:", 88 | "", 89 | ] 90 | sponsor_data.extend([f"- [{s}](https://github.com/{s})" for s in sponsors]) 91 | 92 | return "\n".join(sponsor_data) 93 | 94 | 95 | def requirements_section(dokku_version): 96 | return "\n".join( 97 | [ 98 | "## Requirements", 99 | "", 100 | f"- dokku {dokku_version}", 101 | "- docker 1.8.x", 102 | ] 103 | ) 104 | 105 | 106 | def installation_section(service, dokku_version): 107 | return "\n".join( 108 | [ 109 | "## Installation", 110 | "", 111 | "```shell", 112 | f"# on {dokku_version}", 113 | f"sudo dokku plugin:install https://github.com/dokku/dokku-{service}.git --name {service}", 114 | "```", 115 | ] 116 | ) 117 | 118 | 119 | def commands_section(service, variable, alias, image, scheme, ports, unimplemented): 120 | content = [ 121 | "## Commands", 122 | "", 123 | "```", 124 | ] 125 | 126 | subcommands = os.listdir("subcommands") 127 | subcommands.sort() 128 | 129 | command_list = [] 130 | descriptions = [] 131 | for filename in subcommands: 132 | if filename in unimplemented: 133 | continue 134 | data = command_data(filename, service, variable, alias, image, scheme, ports) 135 | description = data["description"] 136 | arguments = data["arguments_string"] 137 | 138 | command_list.append(f"{service}:{filename} {arguments}") 139 | descriptions.append(description) 140 | 141 | maxlen = max(map(len, command_list)) 142 | if maxlen > 50: 143 | maxlen = 50 144 | for command, description in zip(command_list, descriptions): 145 | space_count = maxlen - len(command) 146 | content.append("{0}{1} # {2}".format(command, " " * space_count, description)) 147 | 148 | content.append("```") 149 | return "\n".join(content) 150 | 151 | 152 | def usage_section( 153 | service, variable, alias, image, scheme, ports, options, unimplemented 154 | ): 155 | return "\n\n".join( 156 | [ 157 | "## Usage", 158 | f"Help for any commands can be displayed by specifying the command as an argument to {service}:help. Plugin help output in conjunction with any files in the `docs/` folder is used to generate the plugin documentation. Please consult the `{service}:help` command for any undocumented commands.", 159 | usage_intro( 160 | service, variable, alias, image, scheme, ports, options, unimplemented 161 | ), 162 | usage_lifecycle( 163 | service, variable, alias, image, scheme, ports, options, unimplemented 164 | ), 165 | usage_automation( 166 | service, variable, alias, image, scheme, ports, options, unimplemented 167 | ), 168 | usage_data_management( 169 | service, variable, alias, image, scheme, ports, options, unimplemented 170 | ), 171 | usage_backup( 172 | service, variable, alias, image, scheme, ports, options, unimplemented 173 | ), 174 | usage_docker_pull( 175 | service, variable, alias, image, scheme, ports, options, unimplemented 176 | ), 177 | ] 178 | ) 179 | 180 | 181 | def usage_intro(service, variable, alias, image, scheme, ports, options, unimplemented): 182 | commands = ["create", "info", "list", "logs", "link", "unlink", "set"] 183 | content = ["### Basic Usage"] 184 | 185 | return fetch_commands_content( 186 | service, 187 | variable, 188 | alias, 189 | image, 190 | scheme, 191 | ports, 192 | options, 193 | unimplemented, 194 | commands, 195 | content, 196 | ) 197 | 198 | 199 | def usage_lifecycle( 200 | service, variable, alias, image, scheme, ports, options, unimplemented 201 | ): 202 | commands = [ 203 | "connect", 204 | "enter", 205 | "expose", 206 | "unexpose", 207 | "promote", 208 | "start", 209 | "stop", 210 | "pause", 211 | "restart", 212 | "upgrade", 213 | ] 214 | content = [ 215 | "### Service Lifecycle", 216 | "", 217 | "The lifecycle of each service can be managed through the following commands:", 218 | "", 219 | ] 220 | 221 | return fetch_commands_content( 222 | service, 223 | variable, 224 | alias, 225 | image, 226 | scheme, 227 | ports, 228 | options, 229 | unimplemented, 230 | commands, 231 | content, 232 | ) 233 | 234 | 235 | def usage_automation( 236 | service, variable, alias, image, scheme, ports, options, unimplemented 237 | ): 238 | commands = ["app-links", "clone", "exists", "linked", "links"] 239 | content = [ 240 | "### Service Automation", 241 | "", 242 | "Service scripting can be executed using the following commands:", 243 | "", 244 | ] 245 | 246 | return fetch_commands_content( 247 | service, 248 | variable, 249 | alias, 250 | image, 251 | scheme, 252 | ports, 253 | options, 254 | unimplemented, 255 | commands, 256 | content, 257 | ) 258 | 259 | 260 | def usage_data_management( 261 | service, variable, alias, image, scheme, ports, options, unimplemented 262 | ): 263 | commands = ["import", "export"] 264 | content = [ 265 | "### Data Management", 266 | "", 267 | "The underlying service data can be imported and exported with the following commands:", 268 | "", 269 | ] 270 | 271 | return fetch_commands_content( 272 | service, 273 | variable, 274 | alias, 275 | image, 276 | scheme, 277 | ports, 278 | options, 279 | unimplemented, 280 | commands, 281 | content, 282 | ) 283 | 284 | 285 | def usage_backup( 286 | service, variable, alias, image, scheme, ports, options, unimplemented 287 | ): 288 | commands = [ 289 | "backup-auth", 290 | "backup-deauth", 291 | "backup", 292 | "backup-set-encryption", 293 | "backup-set-public-key-encryption", 294 | "backup-unset-encryption", 295 | "backup-unset-public-key-encryption", 296 | "backup-schedule", 297 | "backup-schedule-cat", 298 | "backup-unschedule", 299 | ] 300 | content = [ 301 | "### Backups", 302 | "", 303 | "Datastore backups are supported via AWS S3 and S3 compatible services like [minio](https://github.com/minio/minio).", 304 | "", 305 | "You may skip the `backup-auth` step if your dokku install is running within EC2 and has access to the bucket via an IAM profile. In that case, use the `--use-iam` option with the `backup` command.", 306 | "", 307 | "Backups can be performed using the backup commands:", 308 | "", 309 | ] 310 | 311 | return fetch_commands_content( 312 | service, 313 | variable, 314 | alias, 315 | image, 316 | scheme, 317 | ports, 318 | options, 319 | unimplemented, 320 | commands, 321 | content, 322 | ) 323 | 324 | 325 | def usage_docker_pull( 326 | service, variable, alias, image, scheme, ports, options, unimplemented 327 | ): 328 | service_prefix = service.upper() 329 | return "\n".join( 330 | [ 331 | "### Disabling `docker image pull` calls", 332 | "", 333 | 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.", 334 | "", 335 | "Please ensure the proper images are in place when `docker image pull` is disabled.", 336 | ] 337 | ) 338 | 339 | 340 | def fetch_commands_content( 341 | service, 342 | variable, 343 | alias, 344 | image, 345 | scheme, 346 | ports, 347 | options, 348 | unimplemented, 349 | commands, 350 | content, 351 | ): 352 | i = 0 353 | for command in commands: 354 | output = command_help( 355 | command, 356 | service, 357 | variable, 358 | alias, 359 | image, 360 | scheme, 361 | ports, 362 | options, 363 | unimplemented, 364 | ) 365 | if output == "": 366 | continue 367 | content.append(output) 368 | i += 1 369 | 370 | if i == 0: 371 | return "" 372 | 373 | return "\n".join(content) 374 | 375 | 376 | def parse_args(line): 377 | line = line.strip() 378 | arguments = [] 379 | for arg in re.findall("([A-Z_]+)", line): 380 | arg = arg.replace("_", "-").lower() 381 | if arg.endswith("optional-flag"): 382 | arg = arg.replace("-optional-flag", "") 383 | arguments.append(f"[--{arg}]") 384 | elif arg.endswith("-flag"): 385 | if arg == "info-flag": 386 | arguments.append(f"[--single-info-flag]") 387 | else: 388 | arg = arg.replace("-flag", "") 389 | first_letter = arg[0] 390 | arguments.append(f"[-{first_letter}|--{arg}]") 391 | elif arg.endswith("-flags-list"): 392 | arg = arg.replace("-list", "") 393 | arguments.append(f"[--{arg}...]") 394 | elif arg.endswith("list"): 395 | arg = arg.replace("-list", "") 396 | arguments.append(f"<{arg}...>") 397 | else: 398 | arguments.append(f"<{arg}>") 399 | return " ".join(arguments) 400 | 401 | 402 | def command_help( 403 | command, service, variable, alias, image, scheme, ports, options, unimplemented 404 | ): 405 | if command in unimplemented: 406 | return "" 407 | 408 | data = command_data(command, service, variable, alias, image, scheme, ports) 409 | content = [ 410 | f"### {data['description']}", 411 | "", 412 | "```shell", 413 | "# usage", 414 | f"dokku {service}:{command} {data['arguments_string']}".strip(), 415 | "```", 416 | ] 417 | 418 | # if len(data["arguments"]) > 0: 419 | # content.append("") 420 | # content.append("arguments:") 421 | # content.append("") 422 | # for argument in data["arguments"]: 423 | # content.append(f"- {argument}") 424 | 425 | if len(data["flags"]) > 0: 426 | content.append("") 427 | content.append("flags:") 428 | content.append("") 429 | for flag in data["flags"]: 430 | if "--config-options" in flag and options != "": 431 | flag = f"{flag} (default: `{options}`)" 432 | content.append(f"- {flag}") 433 | 434 | if len(data["examples"]) > 0: 435 | content.append("") 436 | content.append(data["examples"]) 437 | 438 | doc_file = os.path.join("docs", f"{command}.md") 439 | if os.path.isfile(doc_file): 440 | content.append("") 441 | with open(doc_file) as f: 442 | content.append(f.read()) 443 | 444 | return "\n" + "\n".join(content) 445 | 446 | 447 | def command_data(command, service, variable, alias, image, scheme, ports): 448 | description = None 449 | arguments = [] 450 | arguments_string = "" 451 | example_lines = [] 452 | flags = [] 453 | with open(os.path.join("subcommands", command)) as f: 454 | for line in f.readlines(): 455 | line = line.strip() 456 | line = line.replace("$PLUGIN_SERVICE", service) 457 | line = line.replace("$PLUGIN_COMMAND_PREFIX", service) 458 | line = line.replace("${PLUGIN_COMMAND_PREFIX}", service) 459 | line = line.replace("${PLUGIN_VARIABLE}", variable) 460 | line = line.replace("${PLUGIN_DEFAULT_ALIAS}", alias) 461 | line = line.replace("${PLUGIN_IMAGE}", image) 462 | line = line.replace("${PLUGIN_SCHEME}", scheme) 463 | line = line.replace("${PLUGIN_DATASTORE_PORTS[0]}", ports[0]) 464 | line = line.replace("${PLUGIN_DATASTORE_PORTS[@]}", " ".join(ports)) 465 | 466 | if "declare desc" in line: 467 | description = re.search('"(.+)"', line).group(1) 468 | elif "$1" in line: 469 | arguments_string = parse_args(line) 470 | elif line.startswith("#A "): 471 | argument = line.replace("#A ", "") 472 | parts = [a.strip() for a in argument.split(",", 1)] 473 | arguments.append(f"`{parts[0]}`: {parts[1]}") 474 | elif line.startswith("#F "): 475 | flag = line.replace("#F ", "") 476 | parts = [a.strip() for a in flag.split(",", 1)] 477 | flags.append(f"`{parts[0]}`: {parts[1]}") 478 | elif line.startswith("#E "): 479 | example_lines.append(line.replace("#E ", "")) 480 | 481 | examples = [] 482 | sentence_lines = [] 483 | command_lines = [] 484 | codeblock_lines = [] 485 | blockquote_lines = [] 486 | for line in example_lines: 487 | if line.startswith("export") or line.startswith("dokku"): 488 | if len(blockquote_lines) > 0: 489 | examples.append("\n" + process_blockquote(blockquote_lines)) 490 | blockquote_lines = [] 491 | if len(codeblock_lines) > 0: 492 | examples.append("\n" + process_codeblock(codeblock_lines)) 493 | codeblock_lines = [] 494 | if len(sentence_lines) > 0: 495 | examples.append("\n" + process_sentence(sentence_lines)) 496 | sentence_lines = [] 497 | 498 | command_lines.append(line) 499 | elif line.startswith(" "): 500 | if len(blockquote_lines) > 0: 501 | examples.append("\n" + process_blockquote(blockquote_lines)) 502 | blockquote_lines = [] 503 | if len(command_lines) > 0: 504 | examples.append("\n" + process_command(command_lines)) 505 | command_lines = [] 506 | if len(sentence_lines) > 0: 507 | examples.append("\n" + process_sentence(sentence_lines)) 508 | sentence_lines = [] 509 | 510 | codeblock_lines.append(line.strip()) 511 | elif line.startswith(">"): 512 | if len(codeblock_lines) > 0: 513 | examples.append("\n" + process_codeblock(codeblock_lines)) 514 | codeblock_lines = [] 515 | if len(command_lines) > 0: 516 | examples.append("\n" + process_command(command_lines)) 517 | command_lines = [] 518 | if len(sentence_lines) > 0: 519 | examples.append("\n" + process_sentence(sentence_lines)) 520 | sentence_lines = [] 521 | 522 | blockquote_lines.append(line) 523 | else: 524 | if len(blockquote_lines) > 0: 525 | examples.append("\n" + process_blockquote(blockquote_lines)) 526 | blockquote_lines = [] 527 | if len(codeblock_lines) > 0: 528 | examples.append("\n" + process_codeblock(codeblock_lines)) 529 | codeblock_lines = [] 530 | if len(command_lines) > 0: 531 | examples.append("\n" + process_command(command_lines)) 532 | command_lines = [] 533 | 534 | sentence_lines.append(line) 535 | 536 | if len(blockquote_lines) > 0: 537 | examples.append("\n" + process_blockquote(blockquote_lines)) 538 | blockquote_lines = [] 539 | if len(codeblock_lines) > 0: 540 | examples.append("\n" + process_codeblock(codeblock_lines)) 541 | codeblock_lines = [] 542 | if len(command_lines) > 0: 543 | examples.append("\n" + process_command(command_lines)) 544 | command_lines = [] 545 | if len(sentence_lines) > 0: 546 | examples.append("\n" + process_sentence(sentence_lines)) 547 | sentence_lines = [] 548 | 549 | return { 550 | "description": description, 551 | "arguments_string": arguments_string, 552 | "arguments": arguments, 553 | "flags": flags, 554 | "examples": "\n".join(examples).strip(), 555 | } 556 | 557 | 558 | def process_sentence(sentence_lines): 559 | sentence_lines = " ".join(sentence_lines) 560 | sentences = ". ".join( 561 | upperfirst(i.strip()) for i in sentence_lines.split(". ") 562 | ).strip() 563 | if not sentences.endswith(".") and not sentences.endswith(":"): 564 | sentences += ":" 565 | 566 | text = [] 567 | for sentence in sentences.split(". "): 568 | parts = [] 569 | for word in sentence.strip().split(" "): 570 | if word.isupper() and len(word) > 1: 571 | for ending in [":", "."]: 572 | if word.endswith(ending): 573 | word = "`{0}`{1}".format(word[:-1], ending) 574 | else: 575 | word = "`{0}`".format(word) 576 | parts.append(word) 577 | text.append(" ".join(parts)) 578 | 579 | text = ". ".join(text) 580 | 581 | # some cleanup 582 | text = text.replace("(0.0.0.0)", "(`0.0.0.0`)") 583 | text = text.replace("'", "`") 584 | text = text.replace("`s", "'s") 585 | text = text.replace("``", "`") 586 | text = text.strip(" ") 587 | 588 | return text 589 | 590 | 591 | def upperfirst(x): 592 | return x[:1].upper() + x[1:] 593 | 594 | 595 | def process_blockquote(blockquote_lines): 596 | return "\n".join(blockquote_lines) 597 | 598 | 599 | def process_command(command_lines): 600 | command_lines = "\n".join(command_lines) 601 | return f"```shell\n{command_lines}\n```" 602 | 603 | 604 | def process_codeblock(codeblock_lines): 605 | codeblock_lines = "\n".join(codeblock_lines) 606 | return f"```\n{codeblock_lines}\n```" 607 | 608 | 609 | def main(): 610 | service = None 611 | version = None 612 | variable = None 613 | image = None 614 | alias = None 615 | options = None 616 | unimplemented = [] 617 | 618 | with open("Dockerfile") as f: 619 | for line in f.readlines(): 620 | if "FROM " in line: 621 | image, version = line.split(" ")[1].split(":") 622 | image = image.strip() 623 | version = version.strip() 624 | 625 | with open("config") as f: 626 | for line in f.readlines(): 627 | if "PLUGIN_COMMAND_PREFIX=" in line: 628 | service = re.search('"(.+)"', line).group(1) 629 | if "PLUGIN_DEFAULT_ALIAS=" in line: 630 | alias = re.search('"(.+)"', line).group(1) 631 | if "PLUGIN_VARIABLE=" in line: 632 | variable = re.search('"(.+)"', line).group(1) 633 | if "PLUGIN_SCHEME=" in line: 634 | scheme = re.search('"(.+)"', line).group(1) 635 | if "PLUGIN_DATASTORE_PORTS=" in line: 636 | ports = re.search("\((.+)\)", line).group(1).split(" ") 637 | if "PLUGIN_UNIMPLEMENTED_SUBCOMMANDS=" in line: 638 | match = re.search("\((.+)\)", line) 639 | if match is not None: 640 | unimplemented = [s.strip('"') for s in match.group(1).split(" ")] 641 | 642 | with open("config") as f: 643 | for line in f.readlines(): 644 | if f"{variable}_CONFIG_OPTIONS" in line: 645 | match = re.search('"(.+)"', line) 646 | if match is not None: 647 | options = match.group(1) 648 | 649 | sponsors = [] 650 | with open("plugin.toml") as f: 651 | for line in f.readlines(): 652 | if line.startswith("sponsors"): 653 | sponsors = re.search('\[(["\w\s,_-]+)\]', line).group(1) 654 | sponsors = [s.strip('"') for s in sponsors.split(",")] 655 | 656 | text = compile( 657 | service, 658 | version, 659 | variable, 660 | alias, 661 | image, 662 | scheme, 663 | ports, 664 | sponsors, 665 | options, 666 | unimplemented, 667 | "0.19.x+", 668 | ) 669 | 670 | base_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) 671 | readme_file = os.path.join(base_path, "README.md") 672 | with open(readme_file, "w") as f: 673 | f.write(text + "\n") 674 | 675 | 676 | if __name__ == "__main__": 677 | main() 678 | -------------------------------------------------------------------------------- /commands: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/config" 3 | [[ " help $PLUGIN_COMMAND_PREFIX:help $PLUGIN_COMMAND_PREFIX $PLUGIN_COMMAND_PREFIX:default " == *" $1 "* ]] || [[ "$1" == "$PLUGIN_COMMAND_PREFIX:"* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT" 4 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 5 | 6 | set -eo pipefail 7 | [[ $DOKKU_TRACE ]] && set -x 8 | 9 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/help-functions" 10 | 11 | if [[ ! -d $PLUGIN_CONFIG_ROOT ]]; then 12 | dokku_log_fail "$PLUGIN_SERVICE: Please run: sudo dokku plugin:install" 13 | fi 14 | 15 | if [[ ! -d $PLUGIN_DATA_ROOT ]]; then 16 | dokku_log_fail "$PLUGIN_SERVICE: Please run: sudo dokku plugin:install" 17 | fi 18 | 19 | fn-help "$@" 20 | -------------------------------------------------------------------------------- /config: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | _DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 3 | export MEILISEARCH_IMAGE=${MEILISEARCH_IMAGE:="$(awk -F '[ :]' '{print $2}' "${_DIR}/Dockerfile")"} 4 | export MEILISEARCH_IMAGE_VERSION=${MEILISEARCH_IMAGE_VERSION:="$(awk -F '[ :]' '{print $3}' "${_DIR}/Dockerfile")"} 5 | export MEILISEARCH_ROOT=${MEILISEARCH_ROOT:="$DOKKU_LIB_ROOT/services/meilisearch"} 6 | export DOKKU_LIB_HOST_ROOT=${DOKKU_LIB_HOST_ROOT:=$DOKKU_LIB_ROOT} 7 | export MEILISEARCH_HOST_ROOT=${MEILISEARCH_HOST_ROOT:="$DOKKU_LIB_HOST_ROOT/services/meilisearch"} 8 | 9 | export PLUGIN_UNIMPLEMENTED_SUBCOMMANDS=("backup" "backup-auth" "backup-deauth" "backup-schedule" "backup-schedule-cat" "backup-set-encryption" "backup-unschedule" "backup-unset-encryption" "clone" "connect" "export" "import") 10 | export PLUGIN_COMMAND_PREFIX="meilisearch" 11 | export PLUGIN_CONFIG_ROOT=${PLUGIN_CONFIG_ROOT:="$DOKKU_LIB_ROOT/config/$PLUGIN_COMMAND_PREFIX"} 12 | export PLUGIN_DATA_ROOT=$MEILISEARCH_ROOT 13 | export PLUGIN_DATA_HOST_ROOT=$MEILISEARCH_HOST_ROOT 14 | export PLUGIN_DATASTORE_PORTS=(7700) 15 | export PLUGIN_DATASTORE_WAIT_PORT=7700 16 | export PLUGIN_DEFAULT_ALIAS="MEILISEARCH" 17 | export PLUGIN_DISABLE_PULL=${MEILISEARCH_DISABLE_PULL:=} 18 | export PLUGIN_DISABLE_PULL_VARIABLE="MEILISEARCH_DISABLE_PULL" 19 | export PLUGIN_ALT_ALIAS="DOKKU_MEILISEARCH" 20 | export PLUGIN_IMAGE=$MEILISEARCH_IMAGE 21 | export PLUGIN_IMAGE_VERSION=$MEILISEARCH_IMAGE_VERSION 22 | export PLUGIN_SCHEME="http" 23 | export PLUGIN_SERVICE="Meilisearch" 24 | export PLUGIN_VARIABLE="MEILISEARCH" 25 | export PLUGIN_BASE_PATH="$PLUGIN_PATH" 26 | export PLUGIN_CONFIG_SUFFIX="data" 27 | if [[ -n $DOKKU_API_VERSION ]]; then 28 | export PLUGIN_BASE_PATH="$PLUGIN_ENABLED_PATH" 29 | fi 30 | 31 | export PLUGIN_BUSYBOX_IMAGE=${PLUGIN_BUSYBOX_IMAGE:=busybox:1.37.0-uclibc} 32 | export PLUGIN_AMBASSADOR_IMAGE=${PLUGIN_AMBASSADOR_IMAGE:=dokku/ambassador:0.8.2} 33 | export PLUGIN_S3BACKUP_IMAGE=${PLUGIN_S3BACKUP_IMAGE:=dokku/s3backup:0.18.0} 34 | export PLUGIN_WAIT_IMAGE=${PLUGIN_WAIT_IMAGE:=dokku/wait:0.9.3} 35 | 36 | export MEILISEARCH_CONFIG_OPTIONS=${MEILISEARCH_CONFIG_OPTIONS:=""} 37 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Extra Documentation 2 | 3 | The documentation in this folder is supplemental to using this plugin. It is injected automatically into the plugin's readme during documentation generation. 4 | 5 | -------------------------------------------------------------------------------- /functions: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common-functions" 6 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 7 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions" 8 | source "$PLUGIN_AVAILABLE_PATH/config/functions" 9 | if [[ -f "$PLUGIN_AVAILABLE_PATH/docker-options/functions" ]]; then 10 | source "$PLUGIN_AVAILABLE_PATH/docker-options/functions" 11 | fi 12 | 13 | service_connect() { 14 | local SERVICE="$1" 15 | local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" 16 | local SERVICE_NAME="$(get_service_name "$SERVICE")" 17 | local DATABASE_NAME="$(get_database_name "$SERVICE")" 18 | local SERVICE_TTY_OPTS 19 | has_tty && SERVICE_TTY_OPTS="-t" 20 | 21 | dokku_log_fail "Not yet implemented" 22 | } 23 | 24 | service_create() { 25 | local SERVICE="$1" 26 | is_valid_service_name "$SERVICE" || dokku_log_fail "Please specify a valid name for the service. Valid characters are: [A-Za-z0-9_]+" 27 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 28 | [[ ! -d "$PLUGIN_DATA_ROOT/$SERVICE" ]] || dokku_log_fail "$PLUGIN_SERVICE service $SERVICE already exists" 29 | SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" 30 | LINKS_FILE="$SERVICE_ROOT/LINKS" 31 | 32 | service_parse_args "${@:2}" 33 | 34 | if ! service_image_exists "$SERVICE"; then 35 | if [[ "$PLUGIN_DISABLE_PULL" == "true" ]]; then 36 | dokku_log_warn "${PLUGIN_DISABLE_PULL_VARIABLE} environment variable detected. Not running pull command." 1>&2 37 | dokku_log_warn " docker image pull ${IMAGE}" 1>&2 38 | dokku_log_warn "$PLUGIN_SERVICE service creation failed" 39 | exit 1 40 | fi 41 | "$DOCKER_BIN" image pull "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION" || dokku_log_fail "$PLUGIN_SERVICE image $PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION pull failed" 42 | fi 43 | 44 | plugn trigger service-action pre-create "$PLUGIN_COMMAND_PREFIX" "$SERVICE" 45 | mkdir -p "$SERVICE_ROOT" || dokku_log_fail "Unable to create service directory" 46 | mkdir -p "$SERVICE_ROOT/data" || dokku_log_fail "Unable to create service data directory" 47 | touch "$LINKS_FILE" 48 | 49 | PASSWORD=$(openssl rand -hex 16) 50 | if [[ -n "$SERVICE_PASSWORD" ]]; then 51 | PASSWORD="$SERVICE_PASSWORD" 52 | dokku_log_warn "Specified password may not be as secure as the auto-generated password" 53 | fi 54 | echo "$PASSWORD" >"$SERVICE_ROOT/PASSWORD" 55 | chmod 640 "$SERVICE_ROOT/PASSWORD" 56 | 57 | service_commit_config "$SERVICE" 58 | write_database_name "$SERVICE" 59 | plugn trigger service-action post-create "$PLUGIN_COMMAND_PREFIX" "$SERVICE" 60 | service_create_container "$SERVICE" 61 | plugn trigger service-action post-create-complete "$PLUGIN_COMMAND_PREFIX" "$SERVICE" 62 | } 63 | 64 | service_create_container() { 65 | local SERVICE="$1" 66 | local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" 67 | local SERVICE_HOST_ROOT="$PLUGIN_DATA_HOST_ROOT/$SERVICE" 68 | local SERVICE_NAME="$(get_service_name "$SERVICE")" 69 | local PASSWORD="$(service_password "$SERVICE")" 70 | local DATABASE_NAME="$(get_database_name "$SERVICE")" 71 | 72 | if [[ -f "$SERVICE_ROOT/CONFIG_OPTIONS" ]]; then 73 | export CONFIG_OPTIONS="$(cat "$SERVICE_ROOT/CONFIG_OPTIONS")" 74 | fi 75 | 76 | local network_alias="$(service_dns_hostname "$SERVICE")" 77 | 78 | rm -f "$SERVICE_ROOT/ID" 79 | declare -a DOCKER_ARGS 80 | DOCKER_ARGS=() 81 | DOCKER_ARGS+=("--cidfile=$SERVICE_ROOT/ID") 82 | DOCKER_ARGS+=("--env-file=$SERVICE_ROOT/ENV") 83 | DOCKER_ARGS+=("--env=MEILI_HTTP_ADDR=0.0.0.0:7700") 84 | DOCKER_ARGS+=("--env=MEILI_MASTER_KEY=$PASSWORD") 85 | DOCKER_ARGS+=("--env=MEILI_NO_ANALYTICS=true") 86 | DOCKER_ARGS+=("--hostname=$SERVICE_NAME") 87 | DOCKER_ARGS+=("--label=dokku.service=$PLUGIN_COMMAND_PREFIX") 88 | DOCKER_ARGS+=("--label=dokku=service") 89 | DOCKER_ARGS+=("--name=$SERVICE_NAME") 90 | DOCKER_ARGS+=("--restart=always") 91 | DOCKER_ARGS+=("--volume=$SERVICE_HOST_ROOT/data:/data.ms") 92 | 93 | declare -a LINK_CONTAINER_DOCKER_ARGS 94 | LINK_CONTAINER_DOCKER_ARGS=() 95 | LINK_CONTAINER_DOCKER_ARGS+=("--rm") 96 | LINK_CONTAINER_DOCKER_ARGS+=("--link") 97 | LINK_CONTAINER_DOCKER_ARGS+=("$SERVICE_NAME:$network_alias") 98 | 99 | [[ -f "$SERVICE_ROOT/SERVICE_MEMORY" ]] && SERVICE_MEMORY="$(cat "$SERVICE_ROOT/SERVICE_MEMORY")" 100 | if [[ -n "$SERVICE_MEMORY" ]]; then 101 | DOCKER_ARGS+=("--memory=${SERVICE_MEMORY}m") 102 | fi 103 | 104 | [[ -f "$SERVICE_ROOT/SHM_SIZE" ]] && SERVICE_SHM_SIZE="$(cat "$SERVICE_ROOT/SHM_SIZE")" 105 | if [[ -n "$SERVICE_SHM_SIZE" ]]; then 106 | DOCKER_ARGS+=("--shm-size=${SERVICE_SHM_SIZE}") 107 | fi 108 | 109 | [[ -f "$SERVICE_ROOT/IMAGE" ]] && PLUGIN_IMAGE="$(cat "$SERVICE_ROOT/IMAGE")" 110 | [[ -f "$SERVICE_ROOT/IMAGE_VERSION" ]] && PLUGIN_IMAGE_VERSION="$(cat "$SERVICE_ROOT/IMAGE_VERSION")" 111 | 112 | local network="$(fn-plugin-property-get "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "initial-network")" 113 | if [[ -n "$network" ]]; then 114 | DOCKER_ARGS+=("--network=${network}") 115 | DOCKER_ARGS+=("--network-alias=${network_alias}") 116 | LINK_CONTAINER_DOCKER_ARGS+=("--network=${network}") 117 | fi 118 | 119 | # shellcheck disable=SC2086 120 | suppress_output "$DOCKER_BIN" container create "${DOCKER_ARGS[@]}" "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION" $CONFIG_OPTIONS 121 | 122 | if [[ -n "$(fn-plugin-property-get "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "post-create-network")" ]]; then 123 | dokku_log_verbose_quiet "Connecting to networks after container create" 124 | while read -r line || [[ -n "$line" ]]; do 125 | dokku_log_verbose_quiet "- $line" 126 | "$DOCKER_BIN" network connect --alias "$network_alias" "$line" "$SERVICE_NAME" 127 | done < <(fn-plugin-property-get "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "post-create-network" | tr "," "\n") 128 | fi 129 | suppress_output "$DOCKER_BIN" container start "$(cat "$SERVICE_ROOT/ID")" 130 | service_port_reconcile_status "$SERVICE" 131 | 132 | if [[ -n "$(fn-plugin-property-get "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "post-start-network")" ]]; then 133 | dokku_log_verbose_quiet "Connecting to networks after container start" 134 | while read -r line || [[ -n "$line" ]]; do 135 | dokku_log_verbose_quiet "- $line" 136 | "$DOCKER_BIN" network connect --alias "$network_alias" "$line" "$SERVICE_NAME" 137 | done < <(fn-plugin-property-get "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "post-start-network" | tr "," "\n") 138 | fi 139 | 140 | dokku_log_verbose_quiet "Waiting for container to be ready" 141 | if ! suppress_output "$DOCKER_BIN" container run "${LINK_CONTAINER_DOCKER_ARGS[@]}" "$PLUGIN_WAIT_IMAGE" -c "$network_alias:$PLUGIN_DATASTORE_WAIT_PORT"; then 142 | dokku_log_info2_quiet "Start of $SERVICE container output" 143 | dokku_container_log_verbose_quiet "$SERVICE_NAME" 144 | dokku_log_info2_quiet "End of $SERVICE container output" 145 | return 1 146 | fi 147 | 148 | dokku_log_info2 "$PLUGIN_SERVICE container created: $SERVICE" 149 | service_info "$SERVICE" 150 | } 151 | 152 | service_export() { 153 | local SERVICE="$1" 154 | local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" 155 | local SERVICE_NAME="$(get_service_name "$SERVICE")" 156 | local DATABASE_NAME="$(get_database_name "$SERVICE")" 157 | local PASSWORD="$(service_password "$SERVICE")" 158 | 159 | dokku_log_fail "Not yet implemented" 160 | 161 | } 162 | 163 | service_import() { 164 | local SERVICE="$1" 165 | local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" 166 | local SERVICE_HOST_ROOT="$PLUGIN_DATA_HOST_ROOT/$SERVICE" 167 | local SERVICE_NAME="$(get_service_name "$SERVICE")" 168 | local DATABASE_NAME="$(get_database_name "$SERVICE")" 169 | local PASSWORD="$(service_password "$SERVICE")" 170 | 171 | dokku_log_fail "Not yet implemented" 172 | } 173 | 174 | service_start() { 175 | local SERVICE="$1" 176 | local QUIET="$2" 177 | local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" 178 | local SERVICE_NAME="$(get_service_name "$SERVICE")" 179 | local ID=$("$DOCKER_BIN" container ps -aq --no-trunc --filter "status=running" --filter "name=^/$SERVICE_NAME$") || true 180 | if [[ -n $ID ]]; then 181 | [[ -z $QUIET ]] && dokku_log_warn "Service is already started" 182 | if [[ ! -f "$SERVICE_ROOT/ID" ]] || [[ "$(cat "$SERVICE_ROOT/ID")" != "$ID" ]]; then 183 | [[ -z $QUIET ]] && dokku_log_warn "Updating local container ID" 184 | echo "$ID" >"$SERVICE_ROOT/ID" 185 | fi 186 | return 0 187 | fi 188 | 189 | dokku_log_info2_quiet "Starting container" 190 | local PREVIOUS_ID=$("$DOCKER_BIN" container ps -aq --no-trunc --filter "status=exited" --filter "name=^/$SERVICE_NAME$") || true 191 | local PASSWORD="$(service_password "$SERVICE")" 192 | 193 | if [[ -n $PREVIOUS_ID ]]; then 194 | "$DOCKER_BIN" container start "$PREVIOUS_ID" >/dev/null 195 | service_port_reconcile_status "$SERVICE" 196 | dokku_log_info2 "Container started" 197 | elif service_image_exists "$SERVICE" && [[ -n "$PASSWORD" ]]; then 198 | service_create_container "$SERVICE" 199 | else 200 | if ! service_image_exists "$SERVICE"; then 201 | [[ -f "$SERVICE_ROOT/IMAGE" ]] && PLUGIN_IMAGE="$(cat "$SERVICE_ROOT/IMAGE")" 202 | [[ -f "$SERVICE_ROOT/IMAGE_VERSION" ]] && PLUGIN_IMAGE_VERSION="$(cat "$SERVICE_ROOT/IMAGE_VERSION")" 203 | dokku_log_verbose_quiet "Missing image $PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION for $SERVICE" 204 | else 205 | dokku_log_verbose_quiet "Neither container nor valid configuration exists for $SERVICE" 206 | fi 207 | fi 208 | } 209 | 210 | service_url() { 211 | local SERVICE="$1" 212 | local SERVICE_DNS_HOSTNAME="$(service_dns_hostname "$SERVICE")" 213 | local DATABASE_NAME="$(get_database_name "$SERVICE")" 214 | local PASSWORD="$(service_password "$SERVICE")" 215 | echo "$PLUGIN_SCHEME://:$PASSWORD@$SERVICE_DNS_HOSTNAME:${PLUGIN_DATASTORE_PORTS[0]}" 216 | } 217 | -------------------------------------------------------------------------------- /help-functions: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common-functions" 6 | export SUBCOMMAND_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/subcommands" 7 | 8 | fn-help() { 9 | declare CMD="$1" 10 | local cmd EXIT_CODE 11 | 12 | if [[ "$CMD" == "help" ]] || [[ "$CMD" == "$PLUGIN_COMMAND_PREFIX:help" ]] || [[ "$CMD" == "$PLUGIN_COMMAND_PREFIX" ]] || [[ "$CMD" == "$PLUGIN_COMMAND_PREFIX:default" ]]; then 13 | fn-help-all "$@" 14 | exit 0 15 | fi 16 | 17 | pushd "$SUBCOMMAND_ROOT" >/dev/null 2>&1 18 | for cmd in *; do 19 | if [[ "$CMD" == "${PLUGIN_COMMAND_PREFIX}:$cmd" ]]; then 20 | "$SUBCOMMAND_ROOT/$cmd" "$@" 21 | EXIT_CODE="$?" 22 | exit "$EXIT_CODE" 23 | fi 24 | done 25 | popd >/dev/null 2>&1 26 | 27 | exit "$DOKKU_NOT_IMPLEMENTED_EXIT" 28 | } 29 | 30 | fn-help-all() { 31 | declare CMD="$1" SUBCOMMAND="$2" 32 | local CMD_OUTPUT BLUE BOLD FULL_OUTPUT NORMAL 33 | FULL_OUTPUT=true 34 | 35 | if [[ "$CMD" == "$PLUGIN_COMMAND_PREFIX:help" ]] || [[ "$CMD" == "$PLUGIN_COMMAND_PREFIX" ]] || [[ "$CMD" == "$PLUGIN_COMMAND_PREFIX:default" ]]; then 36 | BOLD="$(fn-help-fancy-tput bold)" 37 | NORMAL="$(fn-help-fancy-color "\033[m")" 38 | BLUE="$(fn-help-fancy-color "\033[0;34m")" 39 | CYAN="$(fn-help-fancy-color "\033[1;36m")" 40 | if [[ -n "$SUBCOMMAND" ]] && [[ "$SUBCOMMAND" != "--all" ]]; then 41 | fn-help-contents-subcommand "$SUBCOMMAND" "$FULL_OUTPUT" 42 | return "$?" 43 | fi 44 | 45 | echo -e "${BOLD}usage${NORMAL}: dokku ${PLUGIN_COMMAND_PREFIX}[:COMMAND]" 46 | echo '' 47 | echo -e "${BOLD}List your $PLUGIN_COMMAND_PREFIX services.${NORMAL}" 48 | echo '' 49 | echo -e "${BLUE}Example:${NORMAL}" 50 | echo '' 51 | echo " \$ dokku $PLUGIN_COMMAND_PREFIX:list" 52 | echo '' 53 | fn-help-list-example | column -c5 -t -s, 54 | echo '' 55 | echo -e "dokku ${BOLD}${PLUGIN_COMMAND_PREFIX}${NORMAL} commands: (get help with ${CYAN}dokku ${PLUGIN_COMMAND_PREFIX}:help SUBCOMMAND${NORMAL})" 56 | echo '' 57 | fn-help-contents | sort | column -c2 -t -s, 58 | echo '' 59 | elif [[ $(ps -o command= $PPID) == *"--all"* ]]; then 60 | fn-help-contents 61 | else 62 | cat </dev/null 2>&1 72 | for cmd in *; do 73 | fn-help-contents-subcommand "$cmd" || true 74 | done 75 | } 76 | 77 | fn-help-contents-subcommand() { 78 | declare SUBCOMMAND="$1" FULL_OUTPUT="$2" 79 | local HELP_TMPDIR=$(mktemp -d --tmpdir) 80 | local UNCLEAN_FILE="${HELP_TMPDIR}/cmd-unclean" CLEAN_FILE="${HELP_TMPDIR}/cmd-clean" 81 | local BOLD CMD_OUTPUT CYAN EXAMPLE LIGHT_GRAY NORMAL 82 | trap 'rm -rf "$HELP_TMPDIR" > /dev/null' RETURN INT TERM EXIT 83 | 84 | rm -rf "$UNCLEAN_FILE" "$CLEAN_FILE" 85 | cat "$SUBCOMMAND_ROOT/$SUBCOMMAND" >"$UNCLEAN_FILE" 86 | 87 | fn-help-subcommand-sanitize "$UNCLEAN_FILE" "$CLEAN_FILE" 88 | if ! is_implemented_command "$SUBCOMMAND"; then 89 | return 1 90 | fi 91 | 92 | args="$(fn-help-subcommand-args "$CLEAN_FILE" "$FULL_OUTPUT")" 93 | SUBCOMMAND=":$SUBCOMMAND" 94 | [[ "$SUBCOMMAND" == ":default" ]] && SUBCOMMAND="" 95 | cmd_line="$(echo -e "${SUBCOMMAND} ${args}" | sed -e 's/[[:space:]]*$//')" 96 | desc="$(grep desc "$CLEAN_FILE" | head -1)" 97 | eval "$desc" 98 | 99 | BLUE="$(fn-help-fancy-color "\033[0;34m")" 100 | BOLD="$(fn-help-fancy-tput bold)" 101 | CYAN="$(fn-help-fancy-color "\033[1;36m")" 102 | NORMAL="$(fn-help-fancy-color "\033[m")" 103 | LIGHT_GRAY="$(fn-help-fancy-color "\033[2;37m")" 104 | LIGHT_RED="$(fn-help-fancy-color "\033[1;31m")" 105 | CMD_OUTPUT="$(echo -e " ${PLUGIN_COMMAND_PREFIX}${cmd_line}, ${LIGHT_GRAY}${desc}${NORMAL}")" 106 | if [[ "$FULL_OUTPUT" != "true" ]]; then 107 | echo "$CMD_OUTPUT" 108 | return 0 109 | fi 110 | 111 | echo -e "${BOLD}usage:${NORMAL} dokku ${PLUGIN_COMMAND_PREFIX}${cmd_line}" 112 | echo '' 113 | echo -e "${BOLD}${desc}${NORMAL}" 114 | echo '' 115 | 116 | ARGS="$(fn-help-subcommand-list-args "$CLEAN_FILE")" 117 | if [[ -n "$ARGS" ]]; then 118 | echo -e "${CYAN}arguments:${NORMAL}" 119 | echo '' 120 | echo "$ARGS" | column -c2 -t -s, 121 | echo '' 122 | fi 123 | 124 | FLAGS="$(fn-help-subcommand-list-flags "$CLEAN_FILE")" 125 | if [[ -n "$FLAGS" ]]; then 126 | echo -e "${BLUE}flags:${NORMAL}" 127 | echo '' 128 | echo "$FLAGS" | column -c2 -t -s, 129 | echo '' 130 | fi 131 | 132 | EXAMPLE="$(fn-help-subcommand-example "$CLEAN_FILE")" 133 | if [[ -n "$EXAMPLE" ]]; then 134 | echo -e "${LIGHT_RED}examples:${NORMAL}" 135 | echo '' 136 | echo "$EXAMPLE" 137 | echo '' 138 | fi 139 | 140 | return 0 141 | } 142 | 143 | fn-help-fancy-tput() { 144 | declare desc="a wrapper around tput" 145 | 146 | if [[ -n "$DOKKU_NO_COLOR" ]] || [[ "$TERM" == "unknown" ]] || [[ "$TERM" == "dumb" ]]; then 147 | return 148 | fi 149 | 150 | tput "$@" 151 | } 152 | 153 | fn-help-fancy-color() { 154 | declare desc="a wrapper around colors" 155 | 156 | if [[ -n "$DOKKU_NO_COLOR" ]] || [[ "$TERM" == "unknown" ]] || [[ "$TERM" == "dumb" ]]; then 157 | return 158 | fi 159 | 160 | echo "$@" 161 | } 162 | 163 | fn-help-list-example() { 164 | # shellcheck disable=SC2034 165 | declare desc="return $PLUGIN_COMMAND_PREFIX plugin help content" 166 | cat <* ]] && line="\n ${BOLD}${line}${NORMAL}" 243 | # shellcheck disable=SC2001 244 | [[ "$line" == " "* ]] && line=" ${OTHER_GRAY}$(echo "$line" | sed -e 's/^[[:space:]]*//')${NORMAL}" 245 | echo -e "${NEWLINE}${line}" 246 | LAST_LINE="sentence" 247 | NEWLINE="\n" 248 | fi 249 | done 250 | } 251 | 252 | fn-help-subcommand-list-args() { 253 | declare FUNC_FILE="$1" 254 | local EXAMPLE LIGHT_GRAY NORMAL 255 | 256 | FLAGS=$(grep "#A" "$FUNC_FILE" | cut -d'A' -f2- | sed -e 's/^[[:space:]]*//' || true) 257 | if [[ -z "$FLAGS" ]]; then 258 | return 0 259 | fi 260 | 261 | NORMAL="$(fn-help-fancy-color "\033[m")" 262 | LIGHT_GRAY="$(fn-help-fancy-color "\033[2;37m")" 263 | 264 | _fn-help-apply-shell-expansion "$FLAGS" | while read -r line; do 265 | echo -e "$(echo "$line" | cut -d',' -f1),${LIGHT_GRAY}$(echo "$line" | cut -d',' -f2-)${NORMAL}" 266 | done 267 | } 268 | 269 | fn-help-subcommand-list-flags() { 270 | declare FUNC_FILE="$1" 271 | local EXAMPLE LIGHT_GRAY NORMAL 272 | 273 | FLAGS=$(grep "#F" "$FUNC_FILE" | cut -d'F' -f2- | sed -e 's/^[[:space:]]*//' || true) 274 | if [[ -z "$FLAGS" ]]; then 275 | return 0 276 | fi 277 | 278 | NORMAL="$(fn-help-fancy-color "\033[m")" 279 | LIGHT_GRAY="$(fn-help-fancy-color "\033[2;37m")" 280 | 281 | _fn-help-apply-shell-expansion "$FLAGS" | while read -r line; do 282 | echo -e "$(echo "$line" | cut -d',' -f1),${LIGHT_GRAY}$(echo "$line" | cut -d',' -f2-)${NORMAL}" 283 | done 284 | } 285 | 286 | fn-help-subcommand-sanitize() { 287 | declare FUNC_FILE="$1" OUTGOING_FUNC_FILE="$2" 288 | local FUNCTION_FOUND=false 289 | local IFS OIFS 290 | 291 | touch "$OUTGOING_FUNC_FILE" 292 | 293 | OIFS="$IFS" 294 | IFS=, 295 | while read -r p; do 296 | IFS="$OIFS" 297 | if [[ "$p" == *"-cmd \"\$@\""* ]] || [[ "$p" == "" ]]; then 298 | continue 299 | fi 300 | 301 | if [[ "$FUNCTION_FOUND" == true ]]; then 302 | echo "$p" >>"$OUTGOING_FUNC_FILE" 303 | continue 304 | fi 305 | 306 | if [[ "$p" == *"()"* ]]; then 307 | FUNCTION_FOUND=true 308 | echo "$p" >>"$OUTGOING_FUNC_FILE" 309 | continue 310 | fi 311 | done <"$FUNC_FILE" 312 | } 313 | 314 | _fn-help-apply-shell-expansion() { 315 | declare desc="expand environment variables for a shell command" 316 | declare data="$1" 317 | declare delimiter="__apply_shell_expansion_delimiter__" 318 | declare command="cat <<$delimiter"$'\n'"$data"$'\n'"$delimiter" 319 | eval "$command" 320 | } 321 | -------------------------------------------------------------------------------- /install: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/config" 3 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common-functions" 4 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions" 5 | set -eo pipefail 6 | [[ $DOKKU_TRACE ]] && set -x 7 | 8 | plugin-install() { 9 | pull-docker-image() { 10 | declare IMAGE="$1" 11 | if [[ "$PLUGIN_DISABLE_PULL" == "true" ]]; then 12 | echo " ! ${PLUGIN_DISABLE_PULL_VARIABLE} environment variable detected. Not running pull command." 1>&2 13 | echo " ! docker image pull ${IMAGE}" 1>&2 14 | return 15 | fi 16 | if [[ "$("$DOCKER_BIN" image ls -q "${IMAGE}" 2>/dev/null)" == "" ]]; then 17 | "$DOCKER_BIN" image pull "${IMAGE}" 18 | fi 19 | } 20 | 21 | fn-plugin-property-setup "$PLUGIN_COMMAND_PREFIX" 22 | pull-docker-image "${PLUGIN_IMAGE}:${PLUGIN_IMAGE_VERSION}" 23 | pull-docker-image "$PLUGIN_BUSYBOX_IMAGE" 24 | pull-docker-image "$PLUGIN_AMBASSADOR_IMAGE" 25 | pull-docker-image "$PLUGIN_S3BACKUP_IMAGE" 26 | pull-docker-image "$PLUGIN_WAIT_IMAGE" 27 | 28 | mkdir -p "$PLUGIN_DATA_ROOT" || echo "Failed to create $PLUGIN_SERVICE data directory" 29 | chown "${DOKKU_SYSTEM_USER}:${DOKKU_SYSTEM_GROUP}" "$PLUGIN_DATA_ROOT" 30 | 31 | mkdir -p "$PLUGIN_CONFIG_ROOT" || echo "Failed to create $PLUGIN_SERVICE config directory" 32 | chown "${DOKKU_SYSTEM_USER}:${DOKKU_SYSTEM_GROUP}" "$PLUGIN_CONFIG_ROOT" 33 | 34 | rm -f "/etc/sudoers.d/dokku-${PLUGIN_COMMAND_PREFIX}*" 35 | _SUDOERS_FILE="/etc/sudoers.d/dokku-${PLUGIN_COMMAND_PREFIX}" 36 | 37 | touch "$_SUDOERS_FILE" 38 | cat >"$_SUDOERS_FILE" <"$SERVICE_ROOT/IMAGE" 56 | echo "${image##*:}" >"$SERVICE_ROOT/IMAGE_VERSION" 57 | fi 58 | fi 59 | 60 | chown "${DOKKU_SYSTEM_USER}:${DOKKU_SYSTEM_GROUP}" "$SERVICE_ROOT/IMAGE" "$SERVICE_ROOT/IMAGE_VERSION" 61 | 62 | if [[ -f "$SERVICE_ROOT/${PLUGIN_VARIABLE}_CONFIG_OPTIONS" ]]; then 63 | mv "$SERVICE_ROOT/${PLUGIN_VARIABLE}_CONFIG_OPTIONS" "$SERVICE_ROOT/CONFIG_OPTIONS" 64 | chown "${DOKKU_SYSTEM_USER}:${DOKKU_SYSTEM_GROUP}" "$SERVICE_ROOT/CONFIG_OPTIONS" 65 | fi 66 | done 67 | } 68 | 69 | plugin-install "$@" 70 | -------------------------------------------------------------------------------- /plugin.toml: -------------------------------------------------------------------------------- 1 | [plugin] 2 | description = "dokku meilisearch service plugin" 3 | version = "1.47.4" 4 | [plugin.config] 5 | -------------------------------------------------------------------------------- /post-app-clone-setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/config" 3 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common-functions" 4 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/functions" 5 | set -eo pipefail 6 | [[ $DOKKU_TRACE ]] && set -x 7 | 8 | plugin-post-app-clone-setup() { 9 | declare OLD_APP_NAME="$1" NEW_APP_NAME="$2" 10 | 11 | for SERVICE in $(fn-services-list false); do 12 | if in_links_file "$SERVICE" "$OLD_APP_NAME"; then 13 | add_to_links_file "$SERVICE" "$NEW_APP_NAME" 14 | fi 15 | done 16 | } 17 | 18 | plugin-post-app-clone-setup "$@" 19 | -------------------------------------------------------------------------------- /post-app-rename-setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/config" 3 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common-functions" 4 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/functions" 5 | set -eo pipefail 6 | [[ $DOKKU_TRACE ]] && set -x 7 | 8 | plugin-post-app-rename-setup() { 9 | declare OLD_APP_NAME="$1" NEW_APP_NAME="$2" 10 | 11 | for SERVICE in $(fn-services-list false); do 12 | if in_links_file "$SERVICE" "$OLD_APP_NAME"; then 13 | add_to_links_file "$SERVICE" "$NEW_APP_NAME" 14 | fi 15 | done 16 | } 17 | 18 | plugin-post-app-rename-setup "$@" 19 | -------------------------------------------------------------------------------- /pre-delete: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 3 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/config" 4 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/functions" 5 | set -eo pipefail 6 | [[ $DOKKU_TRACE ]] && set -x 7 | 8 | APP="$1" 9 | for SERVICE in $(fn-services-list false); do 10 | [[ -n "$SERVICE" ]] || continue 11 | dokku_log_verbose_quiet "Unlinking from $SERVICE" 12 | remove_from_links_file "$(basename "$SERVICE")" "$APP" 13 | done 14 | -------------------------------------------------------------------------------- /pre-restore: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/config" 3 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common-functions" 4 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/functions" 5 | set -eo pipefail 6 | [[ $DOKKU_TRACE ]] && set -x 7 | 8 | plugin-pre-restore() { 9 | declare SCHEDULER="$1" APP="$2" 10 | local status 11 | 12 | if [[ "$SCHEDULER" != "docker-local" ]]; then 13 | return 14 | fi 15 | 16 | for SERVICE in $(fn-services-list false); do 17 | if ! in_links_file "$SERVICE" "$APP"; then 18 | continue 19 | fi 20 | 21 | status="$(service_status "$SERVICE")" 22 | if [[ "$status" == "running" ]]; then 23 | continue 24 | fi 25 | 26 | if [[ "$status" == "restarting" ]]; then 27 | dokku_log_warn "$PLUGIN_SERVICE service $SERVICE is restarting and may cause issues with linked app $APP" 28 | continue 29 | fi 30 | 31 | dokku_log_warn "$PLUGIN_SERVICE service $SERVICE is not running, issuing service start" 32 | service_start "$SERVICE" 33 | done 34 | } 35 | 36 | plugin-pre-restore "$@" 37 | -------------------------------------------------------------------------------- /pre-start: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/config" 3 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common-functions" 4 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/functions" 5 | set -eo pipefail 6 | [[ $DOKKU_TRACE ]] && set -x 7 | 8 | plugin-pre-start() { 9 | declare APP="$1" 10 | local status 11 | 12 | for SERVICE in $(fn-services-list false); do 13 | if ! in_links_file "$SERVICE" "$APP"; then 14 | continue 15 | fi 16 | 17 | status="$(service_status "$SERVICE")" 18 | if [[ "$status" == "running" ]]; then 19 | continue 20 | fi 21 | 22 | if [[ "$status" == "restarting" ]]; then 23 | dokku_log_warn "$PLUGIN_SERVICE service $SERVICE is restarting and may cause issues with linked app $APP" 24 | continue 25 | fi 26 | 27 | dokku_log_warn "$PLUGIN_SERVICE service $SERVICE is not running, issuing service start" 28 | service_start "$SERVICE" 29 | done 30 | } 31 | 32 | plugin-pre-start "$@" 33 | -------------------------------------------------------------------------------- /scripts/enable_ssl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | pushd /var/lib/meilisearchql/data >/dev/null 3 | openssl req -new -newkey rsa:4096 -x509 -nodes -out server.crt -keyout server.key -batch 4 | chmod 600 server.key 5 | sed -i "s/^#ssl = off/ssl = on/" meilisearchql.conf 6 | sed -i "s/^#ssl_ciphers =.*/ssl_ciphers = 'AES256+EECDH:AES256+EDH'/" meilisearchql.conf 7 | popd >/dev/null 8 | -------------------------------------------------------------------------------- /service-list: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/config" 3 | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common-functions" 4 | set -eo pipefail 5 | [[ $DOKKU_TRACE ]] && set -x 6 | 7 | plugin-service-list() { 8 | declare desc="allows listing all services for use by other dokku plugins" 9 | declare SERVICE_TYPE="$1" 10 | 11 | if [[ -n "$SERVICE_TYPE" ]] && [[ "$SERVICE_TYPE" != "$PLUGIN_COMMAND_PREFIX" ]]; then 12 | return 13 | fi 14 | 15 | for service in $(fn-services-list false); do 16 | echo "$PLUGIN_COMMAND_PREFIX:$service" 17 | done 18 | } 19 | 20 | plugin-service-list "$@" 21 | -------------------------------------------------------------------------------- /subcommands/app-links: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-app-links-cmd() { 9 | #E list all $PLUGIN_COMMAND_PREFIX services that are linked to the 'playground' app. 10 | #E dokku $PLUGIN_COMMAND_PREFIX:app-links playground 11 | #A app, app to run command against 12 | declare desc="list all $PLUGIN_SERVICE service links for a given app" 13 | local cmd="$PLUGIN_COMMAND_PREFIX:app-links" argv=("$@") 14 | [[ ${argv[0]} == "$cmd" ]] && shift 1 15 | declare APP="$1" 16 | APP=${APP:="$DOKKU_APP_NAME"} 17 | 18 | [[ -z "$APP" ]] && dokku_log_fail "Please specify an app to run the command on" 19 | verify_app_name "$APP" 20 | service_app_links "$APP" 21 | } 22 | 23 | service-app-links-cmd "$@" 24 | -------------------------------------------------------------------------------- /subcommands/backup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-backup-cmd() { 9 | #E backup the 'lollipop' service to the 'my-s3-bucket' bucket on AWS 10 | #E dokku $PLUGIN_COMMAND_PREFIX:backup lollipop my-s3-bucket --use-iam 11 | #E restore a backup file (assuming it was extracted via 'tar -xf backup.tgz') 12 | #E dokku $PLUGIN_COMMAND_PREFIX:import lollipop < backup-folder/export 13 | #F -u|--use-iam, use the IAM profile associated with the current server 14 | #A service, service to run command against 15 | #A bucket-name, name of the s3 bucket to upload backups to 16 | declare desc="create a backup of the $PLUGIN_SERVICE service to an existing s3 bucket" 17 | local cmd="$PLUGIN_COMMAND_PREFIX:backup" argv=("$@") 18 | [[ ${argv[0]} == "$cmd" ]] && shift 1 19 | declare SERVICE="$1" BUCKET_NAME="$2" USE_IAM_OPTIONAL_FLAG="$3" 20 | is_implemented_command "$cmd" || dokku_log_fail "Not yet implemented" 21 | 22 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 23 | [[ -z "$BUCKET_NAME" ]] && dokku_log_fail "Please specify an aws bucket for the backup" 24 | verify_service_name "$SERVICE" 25 | service_backup "$SERVICE" "$BUCKET_NAME" "$USE_IAM_OPTIONAL_FLAG" 26 | } 27 | 28 | service-backup-cmd "$@" 29 | -------------------------------------------------------------------------------- /subcommands/backup-auth: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-backup-auth-cmd() { 9 | #E setup s3 backup authentication 10 | #E dokku $PLUGIN_COMMAND_PREFIX:backup-auth lollipop AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY 11 | #E setup s3 backup authentication with different region 12 | #E dokku $PLUGIN_COMMAND_PREFIX:backup-auth lollipop AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_REGION 13 | #E setup s3 backup authentication with different signature version and endpoint 14 | #E dokku $PLUGIN_COMMAND_PREFIX:backup-auth lollipop AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_REGION AWS_SIGNATURE_VERSION ENDPOINT_URL 15 | #E more specific example for minio auth 16 | #E dokku $PLUGIN_COMMAND_PREFIX:backup-auth lollipop MINIO_ACCESS_KEY_ID MINIO_SECRET_ACCESS_KEY us-east-1 s3v4 https://YOURMINIOSERVICE 17 | #A service, service to run command against 18 | #A access-key-id, an amazon AWS_ACCESS_KEY_ID 19 | #A aws-secret-access-key, an amazon AWS_SECRET_ACCESS_KEY 20 | #A aws-default-region, (optional) a valid amazon S3 region 21 | #A aws-signature-version, (optional) the AWS signature version to use when signing S3 requests 22 | #A endpoint-url, (optional) an aws endpoint to upload to 23 | declare desc="set up authentication for backups on the $PLUGIN_SERVICE service" 24 | local cmd="$PLUGIN_COMMAND_PREFIX:backup-auth" argv=("$@") 25 | [[ ${argv[0]} == "$cmd" ]] && shift 1 26 | declare SERVICE="$1" AWS_ACCESS_KEY_ID="$2" AWS_SECRET_ACCESS_KEY="$3" AWS_DEFAULT_REGION="$4" AWS_SIGNATURE_VERSION="$5" ENDPOINT_URL="$6" 27 | is_implemented_command "$cmd" || dokku_log_fail "Not yet implemented" 28 | 29 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 30 | [[ -z "$AWS_ACCESS_KEY_ID" ]] && dokku_log_fail "Please specify an aws access key id" 31 | [[ -z "$AWS_SECRET_ACCESS_KEY" ]] && dokku_log_fail "Please specify an aws secret access key" 32 | verify_service_name "$SERVICE" 33 | service_backup_auth "$SERVICE" "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" "$AWS_DEFAULT_REGION" "$AWS_SIGNATURE_VERSION" "$ENDPOINT_URL" 34 | } 35 | 36 | service-backup-auth-cmd "$@" 37 | -------------------------------------------------------------------------------- /subcommands/backup-deauth: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-backup-deauth-cmd() { 9 | #E remove s3 authentication 10 | #E dokku $PLUGIN_COMMAND_PREFIX:backup-deauth lollipop 11 | #A service, service to run command against 12 | declare desc="remove backup authentication for the $PLUGIN_SERVICE service" 13 | local cmd="$PLUGIN_COMMAND_PREFIX:backup-deauth" argv=("$@") 14 | [[ ${argv[0]} == "$cmd" ]] && shift 1 15 | declare SERVICE="$1" 16 | is_implemented_command "$cmd" || dokku_log_fail "Not yet implemented" 17 | 18 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 19 | verify_service_name "$SERVICE" 20 | service_backup_deauth "$SERVICE" 21 | } 22 | 23 | service-backup-deauth-cmd "$@" 24 | -------------------------------------------------------------------------------- /subcommands/backup-schedule: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-backup-schedule-cmd() { 9 | #E schedule a backup 10 | #E > 'schedule' is a crontab expression, eg. "0 3 * * *" for each day at 3am 11 | #E dokku $PLUGIN_COMMAND_PREFIX:backup-schedule lollipop "0 3 * * *" my-s3-bucket 12 | #E schedule a backup and authenticate via iam 13 | #E dokku $PLUGIN_COMMAND_PREFIX:backup-schedule lollipop "0 3 * * *" my-s3-bucket --use-iam 14 | #F -u|--use-iam, use the IAM profile associated with the current server 15 | #A service, service to run command against 16 | #A schedule, a cron schedule to run backups on 17 | #A bucket-name, name of the s3 bucket to upload backups to 18 | declare desc="schedule a backup of the $PLUGIN_SERVICE service" 19 | local cmd="$PLUGIN_COMMAND_PREFIX:backup-schedule" argv=("$@") 20 | [[ ${argv[0]} == "$cmd" ]] && shift 1 21 | declare SERVICE="$1" SCHEDULE="$2" BUCKET_NAME="$3" USE_IAM_OPTIONAL_FLAG="$4" 22 | is_implemented_command "$cmd" || dokku_log_fail "Not yet implemented" 23 | 24 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 25 | [[ -z "$SCHEDULE" ]] && dokku_log_fail "Please specify a schedule for the backup" 26 | [[ -z "$BUCKET_NAME" ]] && dokku_log_fail "Please specify an aws bucket for the backup" 27 | verify_service_name "$SERVICE" 28 | service_backup_schedule "$SERVICE" "$SCHEDULE" "$BUCKET_NAME" "$USE_IAM_OPTIONAL_FLAG" 29 | } 30 | 31 | service-backup-schedule-cmd "$@" 32 | -------------------------------------------------------------------------------- /subcommands/backup-schedule-cat: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-backup-schedule-cat-cmd() { 9 | #E cat the contents of the configured backup cronfile for the service 10 | #E dokku $PLUGIN_COMMAND_PREFIX:backup-schedule-cat lollipop 11 | #A service, service to run command against 12 | declare desc="cat the contents of the configured backup cronfile for the service" 13 | local cmd="$PLUGIN_COMMAND_PREFIX:backup-schedule-cat" argv=("$@") 14 | [[ ${argv[0]} == "$cmd" ]] && shift 1 15 | declare SERVICE="$1" 16 | 17 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 18 | verify_service_name "$SERVICE" 19 | service_backup_schedule_cat "$SERVICE" 20 | } 21 | 22 | service-backup-schedule-cat-cmd "$@" 23 | -------------------------------------------------------------------------------- /subcommands/backup-set-encryption: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-backup-set-encryption-cmd() { 9 | #E set the GPG-compatible passphrase for encrypting backups for backups 10 | #E dokku $PLUGIN_COMMAND_PREFIX:backup-set-encryption lollipop 11 | #A service, service to run command against 12 | #A passphrase, a GPG-compatible passphrase 13 | declare desc="set encryption for all future backups of $PLUGIN_SERVICE service" 14 | local cmd="$PLUGIN_COMMAND_PREFIX:backup-set-encryption" argv=("$@") 15 | [[ ${argv[0]} == "$cmd" ]] && shift 1 16 | declare SERVICE="$1" PASSPHRASE="$2" 17 | is_implemented_command "$cmd" || dokku_log_fail "Not yet implemented" 18 | 19 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 20 | [[ -z "$PASSPHRASE" ]] && dokku_log_fail "Please specify a GPG backup passphrase" 21 | verify_service_name "$SERVICE" 22 | service_backup_set_encryption "$SERVICE" "$PASSPHRASE" 23 | } 24 | 25 | service-backup-set-encryption-cmd "$@" 26 | -------------------------------------------------------------------------------- /subcommands/backup-set-public-key-encryption: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-backup-set-public-key-encryption-cmd() { 9 | #E set the GPG Public Key for encrypting backups 10 | #E dokku $PLUGIN_COMMAND_PREFIX:backup-set-public-key-encryption lollipop 11 | #A service, service to run command against 12 | #A public-key-id, a GPG Public Key ID (or fingerprint) to use for encryption. Must be uploaded to the GPG keyserver beforehand. 13 | declare desc="set GPG Public Key encryption for all future backups of $PLUGIN_SERVICE service" 14 | local cmd="$PLUGIN_COMMAND_PREFIX:backup-set-public-key-encryption" argv=("$@") 15 | [[ ${argv[0]} == "$cmd" ]] && shift 1 16 | declare SERVICE="$1" PUBLIC_KEY_ID="$2" 17 | is_implemented_command "$cmd" || dokku_log_fail "Not yet implemented" 18 | 19 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 20 | [[ -z "$PUBLIC_KEY_ID" ]] && dokku_log_fail "Please specify a valid GPG Public Key ID (or fingerprint)" 21 | verify_service_name "$SERVICE" 22 | service_backup_set_public_key_encryption "$SERVICE" "$PUBLIC_KEY_ID" 23 | } 24 | 25 | service-backup-set-public-key-encryption-cmd "$@" 26 | -------------------------------------------------------------------------------- /subcommands/backup-unschedule: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-backup-unschedule-cmd() { 9 | #E remove the scheduled backup from cron 10 | #E dokku $PLUGIN_COMMAND_PREFIX:backup-unschedule lollipop 11 | #A service, service to run command against 12 | declare desc="unschedule the backup of the $PLUGIN_SERVICE service" 13 | local cmd="$PLUGIN_COMMAND_PREFIX:backup-unschedule" argv=("$@") 14 | [[ ${argv[0]} == "$cmd" ]] && shift 1 15 | declare SERVICE="$1" 16 | is_implemented_command "$cmd" || dokku_log_fail "Not yet implemented" 17 | 18 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 19 | verify_service_name "$SERVICE" 20 | service_backup_unschedule "$SERVICE" 21 | } 22 | 23 | service-backup-unschedule-cmd "$@" 24 | -------------------------------------------------------------------------------- /subcommands/backup-unset-encryption: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-backup-unset-encryption-cmd() { 9 | #E unset the GPG encryption passphrase for backups 10 | #E dokku $PLUGIN_COMMAND_PREFIX:backup-unset-encryption lollipop 11 | #A service, service to run command against 12 | declare desc="unset encryption for future backups of the $PLUGIN_SERVICE service" 13 | local cmd="$PLUGIN_COMMAND_PREFIX:backup-unset-encryption" argv=("$@") 14 | [[ ${argv[0]} == "$cmd" ]] && shift 1 15 | declare SERVICE="$1" 16 | is_implemented_command "$cmd" || dokku_log_fail "Not yet implemented" 17 | 18 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 19 | verify_service_name "$SERVICE" 20 | service_backup_unset_encryption "$SERVICE" 21 | } 22 | 23 | service-backup-unset-encryption-cmd "$@" 24 | -------------------------------------------------------------------------------- /subcommands/backup-unset-public-key-encryption: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-backup-unset-public-key-encryption-cmd() { 9 | #E unset the GPG Public Key encryption for backups 10 | #E dokku $PLUGIN_COMMAND_PREFIX:backup-unset-public-key-encryption lollipop 11 | #A service, service to run command against 12 | declare desc="unset GPG Public Key encryption for future backups of the $PLUGIN_SERVICE service" 13 | local cmd="$PLUGIN_COMMAND_PREFIX:backup-unset-public-key-encryption" argv=("$@") 14 | [[ ${argv[0]} == "$cmd" ]] && shift 1 15 | declare SERVICE="$1" 16 | is_implemented_command "$cmd" || dokku_log_fail "Not yet implemented" # TODO: [22.03.2024 by Mykola] 17 | 18 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 19 | verify_service_name "$SERVICE" 20 | service_backup_unset_public_key_encryption "$SERVICE" # TODO: [22.03.2024 by Mykola] 21 | } 22 | 23 | service-backup-unset-encryption-cmd "$@" 24 | -------------------------------------------------------------------------------- /subcommands/clone: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-clone-cmd() { 9 | #E you can clone an existing service to a new one 10 | #E dokku $PLUGIN_COMMAND_PREFIX:clone lollipop lollipop-2 11 | #A service, service to run command against 12 | #A new-service, name of new service 13 | #F -c|--config-options "--args --go=here", extra arguments to pass to the container create command 14 | #F -C|--custom-env "USER=alpha;HOST=beta", semi-colon delimited environment variables to start the service with 15 | #F -i|--image IMAGE, the image name to start the service with 16 | #F -I|--image-version IMAGE_VERSION, the image version to start the service with 17 | #F -m|--memory MEMORY, container memory limit in megabytes (default: unlimited) 18 | #F -N|--initial-network INITIAL_NETWORK, the initial network to attach the service to 19 | #F -p|--password PASSWORD, override the user-level service password 20 | #F -P|--post-create-network NETWORKS, a comma-separated list of networks to attach the service container to after service creation 21 | #F -r|--root-password PASSWORD, override the root-level service password 22 | #F -S|--post-start-network NETWORKS, a comma-separated list of networks to attach the service container to after service start 23 | #F -s|--shm-size SHM_SIZE, override shared memory size for $PLUGIN_COMMAND_PREFIX docker container 24 | declare desc="create container then copy data from into " 25 | local cmd="$PLUGIN_COMMAND_PREFIX:clone" argv=("$@") 26 | [[ ${argv[0]} == "$cmd" ]] && shift 1 27 | declare SERVICE="$1" NEW_SERVICE="$2" CLONE_FLAGS_LIST=("${@:3}") 28 | is_implemented_command "$cmd" || dokku_log_fail "Not yet implemented" 29 | 30 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 31 | [[ -z "$NEW_SERVICE" ]] && dokku_log_fail "Please specify a name for the new service" 32 | verify_service_name "$SERVICE" 33 | if service_exists "$NEW_SERVICE"; then 34 | dokku_log_fail "Invalid service name $NEW_SERVICE. Verify the service name is not already in use." 35 | fi 36 | 37 | local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" 38 | local ID="$(cat "$SERVICE_ROOT/ID")" 39 | is_container_status "$ID" "Running" || dokku_log_fail "Service ${SERVICE} container is not running" 40 | 41 | PLUGIN_IMAGE=$(service_version "$SERVICE" | grep -o "^.*:" | sed -r "s/://g") 42 | PLUGIN_IMAGE_VERSION=$(service_version "$SERVICE" | grep -o ":.*$" | sed -r "s/://g") 43 | 44 | service_parse_args "${@:3}" 45 | 46 | dokku_log_info2 "Cloning $SERVICE to $NEW_SERVICE @ $PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION" 47 | service_create "$NEW_SERVICE" "${@:3}" 48 | dokku_log_info1 "Copying data from $SERVICE to $NEW_SERVICE" 49 | service_export "$SERVICE" | service_import "$NEW_SERVICE" >/dev/null 2>&1 || true 50 | dokku_log_info2 "Done" 51 | } 52 | 53 | service-clone-cmd "$@" 54 | -------------------------------------------------------------------------------- /subcommands/connect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-connect-cmd() { 9 | #E connect to the service via the $PLUGIN_COMMAND_PREFIX connection tool 10 | #E > NOTE: disconnecting from ssh while running this command may leave zombie processes due to moby/moby#9098 11 | #E dokku $PLUGIN_COMMAND_PREFIX:connect lollipop 12 | #A service, service to run command against 13 | declare desc="connect to the service via the $PLUGIN_COMMAND_PREFIX connection tool" 14 | local cmd="$PLUGIN_COMMAND_PREFIX:connect" argv=("$@") 15 | [[ ${argv[0]} == "$cmd" ]] && shift 1 16 | declare SERVICE="$1" 17 | is_implemented_command "$cmd" || dokku_log_fail "Not yet implemented" 18 | 19 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 20 | verify_service_name "$SERVICE" 21 | service_connect "$SERVICE" 22 | } 23 | 24 | service-connect-cmd "$@" 25 | -------------------------------------------------------------------------------- /subcommands/create: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-create-cmd() { 9 | #E create a $PLUGIN_COMMAND_PREFIX service named lollipop 10 | #E dokku $PLUGIN_COMMAND_PREFIX:create lollipop 11 | #E you can also specify the image and image version to use for the service. 12 | #E it *must* be compatible with the ${PLUGIN_IMAGE} image. 13 | #E export ${PLUGIN_VARIABLE}_IMAGE="${PLUGIN_IMAGE}" 14 | #E export ${PLUGIN_VARIABLE}_IMAGE_VERSION="${PLUGIN_IMAGE_VERSION}" 15 | #E dokku $PLUGIN_COMMAND_PREFIX:create lollipop 16 | #E you can also specify custom environment variables to start 17 | #E the ${PLUGIN_COMMAND_PREFIX} service in semicolon-separated form. 18 | #E export ${PLUGIN_VARIABLE}_CUSTOM_ENV="USER=alpha;HOST=beta" 19 | #E dokku $PLUGIN_COMMAND_PREFIX:create lollipop 20 | #A service, service to run command against 21 | #F -c|--config-options "--args --go=here", extra arguments to pass to the container create command 22 | #F -C|--custom-env "USER=alpha;HOST=beta", semi-colon delimited environment variables to start the service with 23 | #F -i|--image IMAGE, the image name to start the service with 24 | #F -I|--image-version IMAGE_VERSION, the image version to start the service with 25 | #F -m|--memory MEMORY, container memory limit in megabytes (default: unlimited) 26 | #F -N|--initial-network INITIAL_NETWORK, the initial network to attach the service to 27 | #F -p|--password PASSWORD, override the user-level service password 28 | #F -P|--post-create-network NETWORKS, a comma-separated list of networks to attach the service container to after service creation 29 | #F -r|--root-password PASSWORD, override the root-level service password 30 | #F -S|--post-start-network NETWORKS, a comma-separated list of networks to attach the service container to after service start 31 | #F -s|--shm-size SHM_SIZE, override shared memory size for $PLUGIN_COMMAND_PREFIX docker container 32 | declare desc="create a $PLUGIN_SERVICE service" 33 | local cmd="$PLUGIN_COMMAND_PREFIX:create" argv=("$@") 34 | [[ ${argv[0]} == "$cmd" ]] && shift 1 35 | declare SERVICE="$1" CREATE_FLAGS_LIST=("${@:2}") 36 | 37 | service_create "$SERVICE" "${@:2}" 38 | } 39 | 40 | service-create-cmd "$@" 41 | -------------------------------------------------------------------------------- /subcommands/destroy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-destroy-cmd() { 9 | #E destroy the service, it's data, and the running container 10 | #E dokku $PLUGIN_COMMAND_PREFIX:destroy lollipop 11 | #A service, service to run command against 12 | #F -f|--force, force destroy without asking for confirmation 13 | declare desc="delete the $PLUGIN_SERVICE service/data/container if there are no links left" 14 | local cmd="$PLUGIN_COMMAND_PREFIX:destroy" argv=("$@") 15 | [[ ${argv[0]} == "$cmd" ]] && shift 1 16 | declare SERVICE="$1" FORCE_FLAG="$2" 17 | 18 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 19 | verify_service_name "$SERVICE" 20 | SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" 21 | LINKS_FILE="$SERVICE_ROOT/LINKS" 22 | SERVICE_HOST_ROOT="$PLUGIN_DATA_HOST_ROOT/$SERVICE" 23 | SERVICE_NAME="$(get_service_name "$SERVICE")" 24 | 25 | [[ -s "$LINKS_FILE" ]] && dokku_log_fail "Cannot delete linked service" 26 | 27 | if [[ "$FORCE_FLAG" == "force" ]] || [[ "$FORCE_FLAG" == "-f" ]] || [[ "$FORCE_FLAG" == "--force" ]]; then 28 | DOKKU_APPS_FORCE_DELETE=1 29 | fi 30 | if [[ -z "$DOKKU_APPS_FORCE_DELETE" ]]; then 31 | dokku_log_warn "WARNING: Potentially Destructive Action" 32 | dokku_log_warn "This command will destroy $SERVICE $PLUGIN_SERVICE service." 33 | dokku_log_warn "To proceed, type \"$SERVICE\"" 34 | echo "" 35 | 36 | read -rp "> " service_name 37 | if [[ "$service_name" != "$SERVICE" ]]; then 38 | dokku_log_warn "Confirmation did not match $SERVICE. Aborted." 39 | exit 1 40 | fi 41 | fi 42 | 43 | dokku_log_info2_quiet "Deleting $SERVICE" 44 | plugn trigger service-action pre-delete "$PLUGIN_COMMAND_PREFIX" "$SERVICE" 45 | service_backup_unschedule "$SERVICE" 46 | service_container_rm "$SERVICE" 47 | 48 | dokku_log_verbose_quiet "Removing data" 49 | "$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 50 | rm -rf "$SERVICE_ROOT" 51 | 52 | fn-plugin-property-destroy "$PLUGIN_COMMAND_PREFIX" "$SERVICE" 53 | 54 | plugn trigger service-action post-delete "$PLUGIN_COMMAND_PREFIX" "$SERVICE" 55 | dokku_log_info2 "$PLUGIN_SERVICE container deleted: $SERVICE" 56 | } 57 | 58 | service-destroy-cmd "$@" 59 | -------------------------------------------------------------------------------- /subcommands/enter: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-enter-cmd() { 9 | #E a bash prompt can be opened against a running service. 10 | #E filesystem changes will not be saved to disk. 11 | #E > NOTE: disconnecting from ssh while running this command may leave zombie processes due to moby/moby#9098 12 | #E dokku $PLUGIN_COMMAND_PREFIX:enter lollipop 13 | #E you may also run a command directly against the service. 14 | #E filesystem changes will not be saved to disk. 15 | #E dokku $PLUGIN_COMMAND_PREFIX:enter lollipop touch /tmp/test 16 | #A service, service to run command against 17 | declare desc="enter or run a command in a running $PLUGIN_SERVICE service container" 18 | local cmd="$PLUGIN_COMMAND_PREFIX:enter" argv=("$@") 19 | [[ ${argv[0]} == "$cmd" ]] && shift 1 20 | declare SERVICE="$1" 21 | 22 | verify_service_name "$SERVICE" 23 | dokku_log_info1_quiet "Filesystem changes may not persist after container restarts" 24 | service_enter "$SERVICE" "${@:2}" 25 | } 26 | 27 | service-enter-cmd "$@" 28 | -------------------------------------------------------------------------------- /subcommands/exists: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-exists-cmd() { 9 | #E here we check if the lollipop $PLUGIN_COMMAND_PREFIX service exists. 10 | #E dokku $PLUGIN_COMMAND_PREFIX:exists lollipop 11 | #A service, service to run command against 12 | declare desc="check if the $PLUGIN_SERVICE service exists" 13 | local cmd="$PLUGIN_COMMAND_PREFIX:exists" argv=("$@") 14 | [[ ${argv[0]} == "$cmd" ]] && shift 1 15 | declare SERVICE="$1" 16 | 17 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 18 | verify_service_name "$SERVICE" 19 | dokku_log_info1 "Service $SERVICE exists" 20 | } 21 | 22 | service-exists-cmd "$@" 23 | -------------------------------------------------------------------------------- /subcommands/export: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-export-cmd() { 9 | #E by default, datastore output is exported to stdout 10 | #E dokku $PLUGIN_COMMAND_PREFIX:export lollipop 11 | #E you can redirect this output to a file 12 | #E dokku $PLUGIN_COMMAND_PREFIX:export lollipop > data.dump 13 | #A service, service to run command against 14 | declare desc="export a dump of the $PLUGIN_SERVICE service database" 15 | local cmd="$PLUGIN_COMMAND_PREFIX:export" argv=("$@") 16 | [[ ${argv[0]} == "$cmd" ]] && shift 1 17 | declare SERVICE="$1" 18 | is_implemented_command "$cmd" || dokku_log_fail "Not yet implemented" 19 | 20 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 21 | verify_service_name "$SERVICE" 22 | service_export "$SERVICE" 23 | } 24 | 25 | service-export-cmd "$@" 26 | -------------------------------------------------------------------------------- /subcommands/expose: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-expose-cmd() { 9 | #E expose the service on the service's normal ports, allowing access to it from the public interface (0.0.0.0) 10 | #E dokku $PLUGIN_COMMAND_PREFIX:expose lollipop ${PLUGIN_DATASTORE_PORTS[@]} 11 | #E expose the service on the service's normal ports, with the first on a specified ip address (127.0.0.1) 12 | #E dokku $PLUGIN_COMMAND_PREFIX:expose lollipop 127.0.0.1:${PLUGIN_DATASTORE_PORTS[@]} 13 | #A service, service to run command against 14 | #A ports, a list of ports to run against 15 | declare desc="expose a $PLUGIN_SERVICE service on custom host:port if provided (random port on the 0.0.0.0 interface if otherwise unspecified)" 16 | local cmd="$PLUGIN_COMMAND_PREFIX:expose" argv=("$@") 17 | [[ ${argv[0]} == "$cmd" ]] && shift 1 18 | declare SERVICE="$1" PORTS_LIST=("${@:2}") 19 | 20 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 21 | verify_service_name "$SERVICE" 22 | service_port_expose "$SERVICE" "${@:2}" 23 | } 24 | 25 | service-expose-cmd "$@" 26 | -------------------------------------------------------------------------------- /subcommands/import: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-import-cmd() { 9 | #E import a datastore dump 10 | #E dokku $PLUGIN_COMMAND_PREFIX:import lollipop < data.dump 11 | #A service, service to run command against 12 | declare desc="import a dump into the $PLUGIN_SERVICE service database" 13 | local cmd="$PLUGIN_COMMAND_PREFIX:import" argv=("$@") 14 | [[ ${argv[0]} == "$cmd" ]] && shift 1 15 | declare SERVICE="$1" 16 | is_implemented_command "$cmd" || dokku_log_fail "Not yet implemented" 17 | 18 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 19 | verify_service_name "$SERVICE" 20 | service_import "$SERVICE" 21 | } 22 | 23 | service-import-cmd "$@" 24 | -------------------------------------------------------------------------------- /subcommands/info: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-info-cmd() { 9 | #E get connection information as follows: 10 | #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop 11 | #E you can also retrieve a specific piece of service info via flags: 12 | #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --config-dir 13 | #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --data-dir 14 | #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --dsn 15 | #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --exposed-ports 16 | #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --id 17 | #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --internal-ip 18 | #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --initial-network 19 | #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --links 20 | #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --post-create-network 21 | #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --post-start-network 22 | #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --service-root 23 | #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --status 24 | #E dokku $PLUGIN_COMMAND_PREFIX:info lollipop --version 25 | #A service, service to run command against 26 | #F --config-dir, show the service configuration directory 27 | #F --data-dir, show the service data directory 28 | #F --dsn, show the service DSN 29 | #F --exposed-ports, show service exposed ports 30 | #F --id, show the service container id 31 | #F --internal-ip, show the service internal ip 32 | #F --initial-network, show the initial network being connected to 33 | #F --links, show the service app links 34 | #F --post-create-network, show the networks to attach to after service container creation 35 | #F --post-start-network, show the networks to attach to after service container start 36 | #F --service-root, show the service root directory 37 | #F --status, show the service running status 38 | #F --version, show the service image version 39 | declare desc="print the service information" 40 | local cmd="$PLUGIN_COMMAND_PREFIX:info" argv=("$@") 41 | [[ ${argv[0]} == "$cmd" ]] && shift 1 42 | declare SERVICE="$1" INFO_FLAG="$2" 43 | 44 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 45 | verify_service_name "$SERVICE" 46 | service_info "$SERVICE" "$INFO_FLAG" 47 | } 48 | 49 | service-info-cmd "$@" 50 | -------------------------------------------------------------------------------- /subcommands/link: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-link-cmd() { 9 | #E a $PLUGIN_COMMAND_PREFIX service can be linked to a container. 10 | #E this will use native docker links via the docker-options plugin. 11 | #E here we link it to our 'playground' app. 12 | #E > NOTE: this will restart your app 13 | #E dokku $PLUGIN_COMMAND_PREFIX:link lollipop playground 14 | #E the following environment variables will be set automatically by docker 15 | #E (not on the app itself, so they won’t be listed when calling dokku config): 16 | #E 17 | #E DOKKU_${PLUGIN_VARIABLE}_LOLLIPOP_NAME=/lollipop/DATABASE 18 | #E DOKKU_${PLUGIN_VARIABLE}_LOLLIPOP_PORT=tcp://172.17.0.1:${PLUGIN_DATASTORE_PORTS[0]} 19 | #E DOKKU_${PLUGIN_VARIABLE}_LOLLIPOP_PORT_${PLUGIN_DATASTORE_PORTS[0]}_TCP=tcp://172.17.0.1:${PLUGIN_DATASTORE_PORTS[0]} 20 | #E DOKKU_${PLUGIN_VARIABLE}_LOLLIPOP_PORT_${PLUGIN_DATASTORE_PORTS[0]}_TCP_PROTO=tcp 21 | #E DOKKU_${PLUGIN_VARIABLE}_LOLLIPOP_PORT_${PLUGIN_DATASTORE_PORTS[0]}_TCP_PORT=${PLUGIN_DATASTORE_PORTS[0]} 22 | #E DOKKU_${PLUGIN_VARIABLE}_LOLLIPOP_PORT_${PLUGIN_DATASTORE_PORTS[0]}_TCP_ADDR=172.17.0.1 23 | #E 24 | #E the following will be set on the linked application by default: 25 | #E 26 | #E ${PLUGIN_DEFAULT_ALIAS}_URL=${PLUGIN_SCHEME}://:SOME_PASSWORD@dokku-${PLUGIN_COMMAND_PREFIX}-lollipop:${PLUGIN_DATASTORE_PORTS[0]} 27 | #E 28 | #E the host exposed here only works internally in docker containers. 29 | #E if you want your container to be reachable from outside, you should 30 | #E use the 'expose' subcommand. another service can be linked to your app: 31 | #E dokku $PLUGIN_COMMAND_PREFIX:link other_service playground 32 | #E it is possible to change the protocol for ${PLUGIN_DEFAULT_ALIAS}_URL by setting the 33 | #E environment variable ${PLUGIN_VARIABLE}_DATABASE_SCHEME on the app. doing so will 34 | #E after linking will cause the plugin to think the service is not 35 | #E linked, and we advise you to unlink before proceeding. 36 | #E dokku config:set playground ${PLUGIN_VARIABLE}_DATABASE_SCHEME=${PLUGIN_SCHEME}2 37 | #E dokku $PLUGIN_COMMAND_PREFIX:link lollipop playground 38 | #E this will cause ${PLUGIN_DEFAULT_ALIAS}_URL to be set as: 39 | #E 40 | #E ${PLUGIN_SCHEME}2://:SOME_PASSWORD@dokku-${PLUGIN_COMMAND_PREFIX}-lollipop:${PLUGIN_DATASTORE_PORTS[0]} 41 | #A service, service to run command against 42 | #A app, app to run command against 43 | #F -a|--alias "BLUE_DATABASE", an alternative alias to use for linking to an app via environment variable 44 | #F -q|--querystring "pool=5", ampersand delimited querystring arguments to append to the service link 45 | #F -n|--no-restart "false", whether or not to restart the app on link (default: true) 46 | declare desc="link the $PLUGIN_SERVICE service to the app" 47 | local cmd="$PLUGIN_COMMAND_PREFIX:link" argv=("$@") 48 | [[ ${argv[0]} == "$cmd" ]] && shift 1 49 | declare SERVICE="$1" APP="$2" LINK_FLAGS_LIST=("${@:3}") 50 | APP=${APP:="$DOKKU_APP_NAME"} 51 | 52 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 53 | [[ -z "$APP" ]] && dokku_log_fail "Please specify an app to run the command on" 54 | verify_app_name "$APP" 55 | verify_service_name "$SERVICE" 56 | 57 | service_parse_args "${@:3}" 58 | service_link "$SERVICE" "$APP" 59 | } 60 | 61 | service-link-cmd "$@" 62 | -------------------------------------------------------------------------------- /subcommands/linked: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-linked-cmd() { 9 | #E here we check if the lollipop $PLUGIN_COMMAND_PREFIX service is linked to the 'playground' app. 10 | #E dokku $PLUGIN_COMMAND_PREFIX:linked lollipop playground 11 | #A service, service to run command against 12 | #A app, app to run command against 13 | declare desc="check if the $PLUGIN_SERVICE service is linked to an app" 14 | local cmd="$PLUGIN_COMMAND_PREFIX:linked" argv=("$@") 15 | [[ ${argv[0]} == "$cmd" ]] && shift 1 16 | declare SERVICE="$1" APP="$2" 17 | APP=${APP:="$DOKKU_APP_NAME"} 18 | 19 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 20 | [[ -z "$APP" ]] && dokku_log_fail "Please specify an app to run the command on" 21 | verify_app_name "$APP" 22 | verify_service_name "$SERVICE" 23 | service_is_linked "$SERVICE" "$APP" 24 | } 25 | 26 | service-linked-cmd "$@" 27 | -------------------------------------------------------------------------------- /subcommands/links: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-links-cmd() { 9 | #E list all apps linked to the 'lollipop' $PLUGIN_COMMAND_PREFIX service. 10 | #E dokku $PLUGIN_COMMAND_PREFIX:links lollipop 11 | #A service, service to run command against 12 | declare desc="list all apps linked to the $PLUGIN_SERVICE service" 13 | local cmd="$PLUGIN_COMMAND_PREFIX:links" argv=("$@") 14 | [[ ${argv[0]} == "$cmd" ]] && shift 1 15 | declare SERVICE="$1" 16 | local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" 17 | local LINKS_FILE="$SERVICE_ROOT/LINKS" 18 | 19 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 20 | verify_service_name "$SERVICE" 21 | service_links "$SERVICE" 22 | } 23 | 24 | service-links-cmd "$@" 25 | -------------------------------------------------------------------------------- /subcommands/list: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-list-cmd() { 9 | #E list all services 10 | #E dokku $PLUGIN_COMMAND_PREFIX:list 11 | declare desc="list all $PLUGIN_SERVICE services" 12 | local cmd="$PLUGIN_COMMAND_PREFIX:list" argv=("$@") 13 | [[ ${argv[0]} == "$cmd" ]] && shift 1 14 | 15 | service_list 16 | } 17 | 18 | service-list-cmd "$@" 19 | -------------------------------------------------------------------------------- /subcommands/logs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-logs-cmd() { 9 | #E you can tail logs for a particular service: 10 | #E dokku $PLUGIN_COMMAND_PREFIX:logs lollipop 11 | #E by default, logs will not be tailed, but you can do this with the --tail flag: 12 | #E dokku $PLUGIN_COMMAND_PREFIX:logs lollipop --tail 13 | #E the default tail setting is to show all logs, but an initial count can also be specified 14 | #E dokku $PLUGIN_COMMAND_PREFIX:logs lollipop --tail 5 15 | #A service, service to run command against 16 | #F -t|--tail [], do not stop when end of the logs are reached and wait for additional output 17 | declare desc="print the most recent log(s) for this service" 18 | local cmd="$PLUGIN_COMMAND_PREFIX:logs" argv=("$@") 19 | [[ ${argv[0]} == "$cmd" ]] && shift 1 20 | declare SERVICE="$1" TAIL_FLAG="$2" TAIL_NUM_OPTIONAL="${3:-all}" 21 | 22 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 23 | verify_service_name "$SERVICE" 24 | service_logs "$SERVICE" "$TAIL_FLAG" "$TAIL_NUM_OPTIONAL" 25 | } 26 | 27 | service-logs-cmd "$@" 28 | -------------------------------------------------------------------------------- /subcommands/pause: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-pause-cmd() { 9 | #E pause the running container for the service 10 | #E dokku $PLUGIN_COMMAND_PREFIX:pause lollipop 11 | #A service, service to run command against 12 | declare desc="pause a running $PLUGIN_SERVICE service" 13 | local cmd="$PLUGIN_COMMAND_PREFIX:pause" argv=("$@") 14 | [[ ${argv[0]} == "$cmd" ]] && shift 1 15 | declare SERVICE="$1" 16 | 17 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 18 | verify_service_name "$SERVICE" 19 | service_pause "$SERVICE" 20 | } 21 | 22 | service-pause-cmd "$@" 23 | -------------------------------------------------------------------------------- /subcommands/promote: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-promote-cmd() { 9 | #E if you have a $PLUGIN_COMMAND_PREFIX service linked to an app and try to link another $PLUGIN_COMMAND_PREFIX service 10 | #E another link environment variable will be generated automatically: 11 | #E 12 | #E DOKKU_${PLUGIN_DEFAULT_ALIAS}_BLUE_URL=${PLUGIN_SCHEME}://other_service:ANOTHER_PASSWORD@dokku-${PLUGIN_COMMAND_PREFIX}-other-service:${PLUGIN_DATASTORE_PORTS[0]}/other_service 13 | #E 14 | #E you can promote the new service to be the primary one 15 | #E > NOTE: this will restart your app 16 | #E dokku $PLUGIN_COMMAND_PREFIX:promote other_service playground 17 | #E this will replace ${PLUGIN_DEFAULT_ALIAS}_URL with the url from other_service and generate 18 | #E another environment variable to hold the previous value if necessary. 19 | #E you could end up with the following for example: 20 | #E 21 | #E ${PLUGIN_DEFAULT_ALIAS}_URL=${PLUGIN_SCHEME}://other_service:ANOTHER_PASSWORD@dokku-${PLUGIN_COMMAND_PREFIX}-other-service:${PLUGIN_DATASTORE_PORTS[0]}/other_service 22 | #E DOKKU_${PLUGIN_DEFAULT_ALIAS}_BLUE_URL=${PLUGIN_SCHEME}://other_service:ANOTHER_PASSWORD@dokku-${PLUGIN_COMMAND_PREFIX}-other-service:${PLUGIN_DATASTORE_PORTS[0]}/other_service 23 | #E DOKKU_${PLUGIN_DEFAULT_ALIAS}_SILVER_URL=${PLUGIN_SCHEME}://lollipop:SOME_PASSWORD@dokku-${PLUGIN_COMMAND_PREFIX}-lollipop:${PLUGIN_DATASTORE_PORTS[0]}/lollipop 24 | #A service, service to run command against 25 | #A app, app to run command against 26 | declare desc="promote service as ${PLUGIN_DEFAULT_ALIAS}_URL in " 27 | local cmd="$PLUGIN_COMMAND_PREFIX:promote" argv=("$@") 28 | [[ ${argv[0]} == "$cmd" ]] && shift 1 29 | declare SERVICE="$1" APP="$2" 30 | APP=${APP:="$DOKKU_APP_NAME"} 31 | 32 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 33 | [[ -z "$APP" ]] && dokku_log_fail "Please specify an app to run the command on" 34 | verify_service_name "$SERVICE" 35 | verify_app_name "$APP" 36 | service_promote "$SERVICE" "$APP" 37 | } 38 | 39 | service-promote-cmd "$@" 40 | -------------------------------------------------------------------------------- /subcommands/restart: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-restart-cmd() { 9 | #E restart the service 10 | #E dokku $PLUGIN_COMMAND_PREFIX:restart lollipop 11 | #A service, service to run command against 12 | declare desc="graceful shutdown and restart of the $PLUGIN_SERVICE service container" 13 | local cmd="$PLUGIN_COMMAND_PREFIX:restart" argv=("$@") 14 | [[ ${argv[0]} == "$cmd" ]] && shift 1 15 | declare SERVICE="$1" 16 | 17 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 18 | verify_service_name "$SERVICE" 19 | service_pause "$SERVICE" 20 | service_start "$SERVICE" 21 | dokku_log_info1 "Please call dokku ps:restart on all linked apps" 22 | } 23 | 24 | service-restart-cmd "$@" 25 | -------------------------------------------------------------------------------- /subcommands/set: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions" 7 | source "$(cd "$(dirname "$(dirname "${BASH_SOURCE[0]}")")" && pwd)/common-functions" 8 | 9 | service-set-cmd() { 10 | #E set the network to attach after the service container is started 11 | #E dokku $PLUGIN_COMMAND_PREFIX:set lollipop post-create-network custom-network 12 | #E set multiple networks 13 | #E dokku $PLUGIN_COMMAND_PREFIX:set lollipop post-create-network custom-network,other-network 14 | #E unset the post-create-network value 15 | #E dokku $PLUGIN_COMMAND_PREFIX:set lollipop post-create-network 16 | #A service, service to run command against 17 | #A key, property name to set 18 | #A value, optional property value to set or empty to unset key 19 | declare desc="set or clear a property for a service" 20 | local cmd="$PLUGIN_COMMAND_PREFIX:set" argv=("$@") 21 | [[ ${argv[0]} == "$cmd" ]] && shift 1 22 | declare SERVICE="$1" KEY="$2" VALUE="$3" 23 | local VALID_KEYS=("initial-network" "post-create-network" "post-start-network") 24 | verify_service_name "$SERVICE" 25 | 26 | [[ -z "$KEY" ]] && dokku_log_fail "No key specified" 27 | 28 | if ! fn-in-array "$KEY" "${VALID_KEYS[@]}"; then 29 | dokku_log_fail "Invalid key specified, valid keys include: initial-network, post-create-network, post-start-network" 30 | fi 31 | 32 | if [[ -n "$VALUE" ]]; then 33 | dokku_log_info2_quiet "Setting ${KEY} to ${VALUE}" 34 | fn-plugin-property-write "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "$KEY" "$VALUE" 35 | else 36 | dokku_log_info2_quiet "Unsetting ${KEY}" 37 | if [[ "$KEY" == "rev-env-var" ]]; then 38 | fn-plugin-property-write "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "$KEY" "$VALUE" 39 | else 40 | fn-plugin-property-delete "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "$KEY" 41 | fi 42 | fi 43 | } 44 | 45 | service-set-cmd "$@" 46 | -------------------------------------------------------------------------------- /subcommands/start: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-start-cmd() { 9 | #E start the service 10 | #E dokku $PLUGIN_COMMAND_PREFIX:start lollipop 11 | #A service, service to run command against 12 | declare desc="start a previously stopped $PLUGIN_SERVICE service" 13 | local cmd="$PLUGIN_COMMAND_PREFIX:start" argv=("$@") 14 | [[ ${argv[0]} == "$cmd" ]] && shift 1 15 | declare SERVICE="$1" 16 | 17 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 18 | verify_service_name "$SERVICE" 19 | service_start "$SERVICE" 20 | } 21 | 22 | service-start-cmd "$@" 23 | -------------------------------------------------------------------------------- /subcommands/stop: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-stop-cmd() { 9 | #E stop the service and removes the running container 10 | #E dokku $PLUGIN_COMMAND_PREFIX:stop lollipop 11 | #A service, service to run command against 12 | declare desc="stop a running $PLUGIN_SERVICE service" 13 | local cmd="$PLUGIN_COMMAND_PREFIX:stop" argv=("$@") 14 | [[ ${argv[0]} == "$cmd" ]] && shift 1 15 | declare SERVICE="$1" 16 | 17 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 18 | verify_service_name "$SERVICE" 19 | service_container_rm "$SERVICE" 20 | } 21 | 22 | service-stop-cmd "$@" 23 | -------------------------------------------------------------------------------- /subcommands/unexpose: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-unexpose-cmd() { 9 | #E unexpose the service, removing access to it from the public interface (0.0.0.0) 10 | #E dokku $PLUGIN_COMMAND_PREFIX:unexpose lollipop 11 | #A service, service to run command against 12 | declare desc="unexpose a previously exposed $PLUGIN_SERVICE service" 13 | local cmd="$PLUGIN_COMMAND_PREFIX:unexpose" argv=("$@") 14 | [[ ${argv[0]} == "$cmd" ]] && shift 1 15 | declare SERVICE="$1" 16 | 17 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 18 | verify_service_name "$SERVICE" 19 | service_port_unexpose "$SERVICE" 20 | } 21 | 22 | service-unexpose-cmd "$@" 23 | -------------------------------------------------------------------------------- /subcommands/unlink: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | 8 | service-unlink-cmd() { 9 | #E you can unlink a $PLUGIN_COMMAND_PREFIX service 10 | #E > NOTE: this will restart your app and unset related environment variables 11 | #E dokku $PLUGIN_COMMAND_PREFIX:unlink lollipop playground 12 | #A service, service to run command against 13 | #A app, app to run command against 14 | #F -n|--no-restart "false", whether or not to restart the app on unlink (default: true) 15 | declare desc="unlink the $PLUGIN_SERVICE service from the app" 16 | local cmd="$PLUGIN_COMMAND_PREFIX:unlink" argv=("$@") 17 | [[ ${argv[0]} == "$cmd" ]] && shift 1 18 | declare SERVICE="$1" APP="$2" 19 | APP=${APP:="$DOKKU_APP_NAME"} 20 | 21 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 22 | [[ -z "$APP" ]] && dokku_log_fail "Please specify an app to run the command on" 23 | verify_service_name "$SERVICE" 24 | verify_app_name "$APP" 25 | service_unlink "$SERVICE" "$APP" 26 | } 27 | 28 | service-unlink-cmd "$@" 29 | -------------------------------------------------------------------------------- /subcommands/upgrade: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 3 | set -eo pipefail 4 | [[ $DOKKU_TRACE ]] && set -x 5 | source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" 6 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions" 7 | source "$PLUGIN_AVAILABLE_PATH/ps/functions" 8 | 9 | service-upgrade-cmd() { 10 | #E you can upgrade an existing service to a new image or image-version 11 | #E dokku $PLUGIN_COMMAND_PREFIX:upgrade lollipop 12 | #A service, service to run command against 13 | #F -c|--config-options "--args --go=here", extra arguments to pass to the container create command 14 | #F -C|--custom-env "USER=alpha;HOST=beta", semi-colon delimited environment variables to start the service with 15 | #F -i|--image IMAGE, the image name to start the service with 16 | #F -I|--image-version IMAGE_VERSION, the image version to start the service with 17 | #F -N|--initial-network INITIAL_NETWORK, the initial network to attach the service to 18 | #F -P|--post-create-network NETWORKS, a comma-separated list of networks to attach the service container to after service creation 19 | #F -R|--restart-apps "true", whether or not to force an app restart (default: false) 20 | #F -S|--post-start-network NETWORKS, a comma-separated list of networks to attach the service container to after service start 21 | #F -s|--shm-size SHM_SIZE, override shared memory size for $PLUGIN_COMMAND_PREFIX docker container 22 | declare desc="upgrade service to the specified versions" 23 | local cmd="$PLUGIN_COMMAND_PREFIX:upgrade" argv=("$@") 24 | [[ ${argv[0]} == "$cmd" ]] && shift 1 25 | declare SERVICE="$1" UPGRADE_FLAGS_LIST=("${@:2}") 26 | 27 | [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service" 28 | verify_service_name "$SERVICE" 29 | 30 | local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" 31 | 32 | service_parse_args "${@:2}" 33 | 34 | if ! service_image_exists "$SERVICE" "$PLUGIN_IMAGE" "$PLUGIN_IMAGE_VERSION"; then 35 | if [[ "$PLUGIN_DISABLE_PULL" == "true" ]]; then 36 | dokku_log_warn "${PLUGIN_DISABLE_PULL_VARIABLE} environment variable detected. Not running pull command." 1>&2 37 | dokku_log_warn " docker image pull ${IMAGE}" 1>&2 38 | dokku_log_warn "$PLUGIN_SERVICE service $SERVICE upgrade failed" 39 | exit 1 40 | fi 41 | "$DOCKER_BIN" image pull "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION" || dokku_log_fail "$PLUGIN_SERVICE image $PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION pull failed" 42 | fi 43 | 44 | local NEW_PLUGIN_IMAGE_TAG="$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION" 45 | if [[ "$(service_version "$SERVICE")" == "$NEW_PLUGIN_IMAGE_TAG" ]]; then 46 | dokku_log_info1 "Service $SERVICE already running $NEW_PLUGIN_IMAGE_TAG" 47 | return 48 | fi 49 | 50 | service_commit_config "$SERVICE" 51 | 52 | dokku_log_info2 "Upgrading $SERVICE to $NEW_PLUGIN_IMAGE_TAG" 53 | if [[ "$SERVICE_RESTART_APPS" == "true" ]]; then 54 | dokku_log_info2 "Stopping all linked services" 55 | for app in $(service_linked_apps "$SERVICE"); do 56 | [[ "$app" == "-" ]] && continue 57 | ps_stop "$app" 58 | done 59 | fi 60 | 61 | dokku_log_info2 "Stopping $SERVICE" 62 | service_container_rm "$SERVICE" 63 | service_start "$SERVICE" "${@:2}" 64 | 65 | if [[ "$SERVICE_RESTART_APPS" == "true" ]]; then 66 | dokku_log_info2 "Starting all linked services" 67 | for app in $(service_linked_apps "$SERVICE"); do 68 | [[ "$app" == "-" ]] && continue 69 | ps_start "$app" 70 | done 71 | fi 72 | 73 | dokku_log_info2 "Done" 74 | } 75 | 76 | service-upgrade-cmd "$@" 77 | -------------------------------------------------------------------------------- /tests/hook_pre_delete.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | setup() { 5 | dokku apps:create my-app 6 | dokku "$PLUGIN_COMMAND_PREFIX:create" ls 7 | dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app >&2 8 | } 9 | 10 | teardown() { 11 | dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app >&2 12 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" ls 13 | dokku --force apps:destroy my-app || true 14 | } 15 | 16 | @test "($PLUGIN_COMMAND_PREFIX:hook:pre-delete) removes app from links file when destroying app" { 17 | [[ -n $(<"$PLUGIN_DATA_ROOT/ls/LINKS") ]] 18 | dokku --force apps:destroy my-app 19 | [[ -z $(<"$PLUGIN_DATA_ROOT/ls/LINKS") ]] 20 | } 21 | -------------------------------------------------------------------------------- /tests/link_networks.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | setup() { 5 | dokku "$PLUGIN_COMMAND_PREFIX:create" ls 6 | dokku network:create custom-network 7 | } 8 | 9 | teardown() { 10 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" ls || true 11 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" lsa || true 12 | dokku network:destroy --force custom-network 13 | } 14 | 15 | @test "($PLUGIN_COMMAND_PREFIX:set) set initial-network" { 16 | run dokku "$PLUGIN_COMMAND_PREFIX:set" ls initial-network custom-network 17 | echo "output: $output" 18 | echo "status: $status" 19 | assert_success 20 | 21 | run dokku "$PLUGIN_COMMAND_PREFIX:info" ls --initial-network 22 | echo "output: $output" 23 | echo "status: $status" 24 | assert_output "custom-network" 25 | assert_success 26 | 27 | run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' 28 | echo "output: $output" 29 | echo "status: $status" 30 | assert_success 31 | assert_output_contains bridge 32 | assert_output_contains custom-network 0 33 | 34 | run dokku "$PLUGIN_COMMAND_PREFIX:stop" ls 35 | echo "output: $output" 36 | echo "status: $status" 37 | assert_success 38 | 39 | run dokku "$PLUGIN_COMMAND_PREFIX:start" ls 40 | echo "output: $output" 41 | echo "status: $status" 42 | assert_success 43 | 44 | run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' 45 | echo "output: $output" 46 | echo "status: $status" 47 | assert_success 48 | assert_output_contains bridge 0 49 | assert_output_contains custom-network 50 | 51 | run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{range $k,$alias := $v.DNSNames}}{{printf "alias:%s\n" $alias}}{{end}}{{end}}' 52 | echo "output: $output" 53 | echo "status: $status" 54 | assert_success 55 | assert_output_contains "alias:dokku.$PLUGIN_COMMAND_PREFIX.ls" 56 | assert_output_contains "alias:dokku-$PLUGIN_COMMAND_PREFIX-ls" 57 | 58 | run dokku "$PLUGIN_COMMAND_PREFIX:set" ls initial-network 59 | echo "output: $output" 60 | echo "status: $status" 61 | assert_success 62 | 63 | run dokku "$PLUGIN_COMMAND_PREFIX:info" ls --initial-network 64 | echo "output: $output" 65 | echo "status: $status" 66 | assert_output "" 67 | assert_success 68 | 69 | run dokku "$PLUGIN_COMMAND_PREFIX:stop" ls 70 | echo "output: $output" 71 | echo "status: $status" 72 | assert_success 73 | 74 | run dokku "$PLUGIN_COMMAND_PREFIX:start" ls 75 | echo "output: $output" 76 | echo "status: $status" 77 | assert_success 78 | 79 | run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' 80 | echo "output: $output" 81 | echo "status: $status" 82 | assert_success 83 | assert_output_contains bridge 84 | assert_output_contains custom-network 0 85 | } 86 | 87 | @test "($PLUGIN_COMMAND_PREFIX:set) set post-create-network" { 88 | run dokku "$PLUGIN_COMMAND_PREFIX:set" ls post-create-network custom-network 89 | echo "output: $output" 90 | echo "status: $status" 91 | assert_success 92 | 93 | run dokku "$PLUGIN_COMMAND_PREFIX:info" ls --post-create-network 94 | echo "output: $output" 95 | echo "status: $status" 96 | assert_output "custom-network" 97 | assert_success 98 | 99 | run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' 100 | echo "output: $output" 101 | echo "status: $status" 102 | assert_success 103 | assert_output_contains bridge 104 | assert_output_contains custom-network 0 105 | 106 | run dokku "$PLUGIN_COMMAND_PREFIX:stop" ls 107 | echo "output: $output" 108 | echo "status: $status" 109 | assert_success 110 | 111 | run dokku "$PLUGIN_COMMAND_PREFIX:start" ls 112 | echo "output: $output" 113 | echo "status: $status" 114 | assert_success 115 | 116 | run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' 117 | echo "output: $output" 118 | echo "status: $status" 119 | assert_success 120 | assert_output_contains custom-network 121 | assert_output_contains bridge 122 | 123 | run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{range $k,$alias := $v.DNSNames}}{{printf "alias:%s\n" $alias}}{{end}}{{end}}' 124 | echo "output: $output" 125 | echo "status: $status" 126 | assert_success 127 | assert_output_contains "alias:dokku.$PLUGIN_COMMAND_PREFIX.ls" 128 | assert_output_contains "alias:dokku-$PLUGIN_COMMAND_PREFIX-ls" 129 | 130 | run dokku "$PLUGIN_COMMAND_PREFIX:set" ls post-create-network 131 | echo "output: $output" 132 | echo "status: $status" 133 | assert_success 134 | 135 | run dokku "$PLUGIN_COMMAND_PREFIX:info" ls --post-create-network 136 | echo "output: $output" 137 | echo "status: $status" 138 | assert_output "" 139 | assert_success 140 | 141 | run dokku "$PLUGIN_COMMAND_PREFIX:stop" ls 142 | echo "output: $output" 143 | echo "status: $status" 144 | assert_success 145 | 146 | run dokku "$PLUGIN_COMMAND_PREFIX:start" ls 147 | echo "output: $output" 148 | echo "status: $status" 149 | assert_success 150 | 151 | run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' 152 | echo "output: $output" 153 | echo "status: $status" 154 | assert_success 155 | assert_output_contains bridge 156 | assert_output_contains custom-network 0 157 | } 158 | 159 | @test "($PLUGIN_COMMAND_PREFIX:set) set an post-start-network" { 160 | run dokku "$PLUGIN_COMMAND_PREFIX:set" ls post-start-network custom-network 161 | echo "output: $output" 162 | echo "status: $status" 163 | assert_success 164 | 165 | run dokku "$PLUGIN_COMMAND_PREFIX:info" ls --post-start-network 166 | echo "output: $output" 167 | echo "status: $status" 168 | assert_output "custom-network" 169 | assert_success 170 | 171 | run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' 172 | echo "output: $output" 173 | echo "status: $status" 174 | assert_success 175 | assert_output_contains bridge 176 | assert_output_contains custom-network 0 177 | 178 | run dokku "$PLUGIN_COMMAND_PREFIX:stop" ls 179 | echo "output: $output" 180 | echo "status: $status" 181 | assert_success 182 | 183 | run dokku "$PLUGIN_COMMAND_PREFIX:start" ls 184 | echo "output: $output" 185 | echo "status: $status" 186 | assert_success 187 | 188 | run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' 189 | echo "output: $output" 190 | echo "status: $status" 191 | assert_success 192 | assert_output_contains bridge 193 | assert_output_contains custom-network 194 | 195 | run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{range $k,$alias := $v.DNSNames}}{{printf "alias:%s\n" $alias}}{{end}}{{end}}' 196 | echo "output: $output" 197 | echo "status: $status" 198 | assert_success 199 | assert_output_contains "alias:dokku.$PLUGIN_COMMAND_PREFIX.ls" 200 | assert_output_contains "alias:dokku-$PLUGIN_COMMAND_PREFIX-ls" 201 | 202 | run dokku "$PLUGIN_COMMAND_PREFIX:set" ls post-start-network 203 | echo "output: $output" 204 | echo "status: $status" 205 | assert_success 206 | 207 | run dokku "$PLUGIN_COMMAND_PREFIX:info" ls --post-start-network 208 | echo "output: $output" 209 | echo "status: $status" 210 | assert_output "" 211 | assert_success 212 | 213 | run dokku "$PLUGIN_COMMAND_PREFIX:stop" ls 214 | echo "output: $output" 215 | echo "status: $status" 216 | assert_success 217 | 218 | run dokku "$PLUGIN_COMMAND_PREFIX:start" ls 219 | echo "output: $output" 220 | echo "status: $status" 221 | assert_success 222 | 223 | run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.ls -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' 224 | echo "output: $output" 225 | echo "status: $status" 226 | assert_success 227 | assert_output_contains bridge 228 | assert_output_contains custom-network 0 229 | } 230 | 231 | @test "($PLUGIN_COMMAND_PREFIX:create) flags" { 232 | run dokku "$PLUGIN_COMMAND_PREFIX:create" lsa --initial-network custom-network 233 | echo "output: $output" 234 | echo "status: $status" 235 | assert_success 236 | 237 | run docker inspect "dokku.$PLUGIN_COMMAND_PREFIX.lsa" -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' 238 | echo "output: $output" 239 | echo "status: $status" 240 | assert_success 241 | assert_output_contains bridge 0 242 | assert_output_contains custom-network 243 | 244 | run dokku "$PLUGIN_COMMAND_PREFIX:destroy" lsa --force 245 | echo "output: $output" 246 | echo "status: $status" 247 | assert_success 248 | 249 | run dokku "$PLUGIN_COMMAND_PREFIX:create" lsa --post-create-network custom-network 250 | echo "output: $output" 251 | echo "status: $status" 252 | assert_success 253 | 254 | run docker inspect "dokku.$PLUGIN_COMMAND_PREFIX.lsa" -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' 255 | echo "output: $output" 256 | echo "status: $status" 257 | assert_success 258 | assert_output_contains bridge 259 | assert_output_contains custom-network 260 | 261 | run docker inspect dokku.$PLUGIN_COMMAND_PREFIX.lsa -f '{{range $net,$v := .NetworkSettings.Networks}}{{range $k,$alias := $v.DNSNames}}{{printf "alias:%s\n" $alias}}{{end}}{{end}}' 262 | echo "output: $output" 263 | echo "status: $status" 264 | assert_success 265 | assert_output_contains "alias:dokku.$PLUGIN_COMMAND_PREFIX.lsa" 266 | assert_output_contains "alias:dokku-$PLUGIN_COMMAND_PREFIX-lsa" 267 | 268 | run dokku "$PLUGIN_COMMAND_PREFIX:destroy" lsa --force 269 | echo "output: $output" 270 | echo "status: $status" 271 | assert_success 272 | 273 | run dokku "$PLUGIN_COMMAND_PREFIX:create" lsa --post-start-network custom-network 274 | echo "output: $output" 275 | echo "status: $status" 276 | assert_success 277 | 278 | run docker inspect "dokku.$PLUGIN_COMMAND_PREFIX.lsa" -f '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' 279 | echo "output: $output" 280 | echo "status: $status" 281 | assert_success 282 | assert_output_contains bridge 283 | assert_output_contains custom-network 284 | 285 | run dokku "$PLUGIN_COMMAND_PREFIX:destroy" lsa --force 286 | echo "output: $output" 287 | echo "status: $status" 288 | assert_success 289 | } 290 | -------------------------------------------------------------------------------- /tests/service_create.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | @test "($PLUGIN_COMMAND_PREFIX:create) success" { 5 | run dokku "$PLUGIN_COMMAND_PREFIX:create" l 6 | assert_contains "${lines[*]}" "container created: l" 7 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l 8 | } 9 | 10 | @test "($PLUGIN_COMMAND_PREFIX:create) service with dashes" { 11 | run dokku "$PLUGIN_COMMAND_PREFIX:create" service-with-dashes 12 | assert_contains "${lines[*]}" "container created: service-with-dashes" 13 | assert_contains "${lines[*]}" "dokku-$PLUGIN_COMMAND_PREFIX-service-with-dashes" 14 | 15 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" service-with-dashes 16 | } 17 | 18 | @test "($PLUGIN_COMMAND_PREFIX:create) error when there are no arguments" { 19 | run dokku "$PLUGIN_COMMAND_PREFIX:create" 20 | assert_contains "${lines[*]}" "Please specify a valid name for the service" 21 | } 22 | 23 | @test "($PLUGIN_COMMAND_PREFIX:create) error when there is an invalid name specified" { 24 | run dokku "$PLUGIN_COMMAND_PREFIX:create" d.erp 25 | assert_failure 26 | } 27 | -------------------------------------------------------------------------------- /tests/service_destroy.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | @test "($PLUGIN_COMMAND_PREFIX:destroy) success with --force" { 5 | dokku "$PLUGIN_COMMAND_PREFIX:create" l 6 | run dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l 7 | assert_contains "${lines[*]}" "container deleted: l" 8 | } 9 | 10 | @test "($PLUGIN_COMMAND_PREFIX:destroy) error when there are no arguments" { 11 | run dokku "$PLUGIN_COMMAND_PREFIX:destroy" 12 | assert_contains "${lines[*]}" "Please specify a valid name for the service" 13 | } 14 | 15 | @test "($PLUGIN_COMMAND_PREFIX:destroy) error when container does not exist" { 16 | run dokku "$PLUGIN_COMMAND_PREFIX:destroy" non_existing_container 17 | assert_contains "${lines[*]}" "service non_existing_container does not exist" 18 | } 19 | 20 | @test "($PLUGIN_COMMAND_PREFIX:destroy) error when container is linked to an app" { 21 | dokku "$PLUGIN_COMMAND_PREFIX:create" l 22 | dokku apps:create app 23 | dokku "$PLUGIN_COMMAND_PREFIX:link" l app 24 | run dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l 25 | assert_contains "${lines[*]}" "Cannot delete linked service" 26 | 27 | dokku "$PLUGIN_COMMAND_PREFIX:unlink" l app 28 | run dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l 29 | assert_contains "${lines[*]}" "container deleted: l" 30 | } 31 | -------------------------------------------------------------------------------- /tests/service_expose.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | setup() { 5 | dokku "$PLUGIN_COMMAND_PREFIX:create" ls 6 | } 7 | 8 | teardown() { 9 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" ls 10 | } 11 | 12 | @test "($PLUGIN_COMMAND_PREFIX:expose) error when there are no arguments" { 13 | run dokku "$PLUGIN_COMMAND_PREFIX:expose" 14 | echo "output: $output" 15 | echo "status: $status" 16 | assert_failure 17 | assert_contains "${lines[*]}" "Please specify a valid name for the service" 18 | } 19 | 20 | @test "($PLUGIN_COMMAND_PREFIX:expose) error when service does not exist" { 21 | run dokku "$PLUGIN_COMMAND_PREFIX:expose" not_existing_service 22 | echo "output: $output" 23 | echo "status: $status" 24 | assert_failure 25 | assert_contains "${lines[*]}" "service not_existing_service does not exist" 26 | } 27 | 28 | @test "($PLUGIN_COMMAND_PREFIX:expose) error when already exposed" { 29 | run dokku "$PLUGIN_COMMAND_PREFIX:expose" ls 30 | echo "output: $output" 31 | echo "status: $status" 32 | assert_success 33 | 34 | run dokku "$PLUGIN_COMMAND_PREFIX:expose" ls 35 | echo "output: $output" 36 | echo "status: $status" 37 | assert_failure 38 | assert_contains "${lines[*]}" "Service ls already exposed on port(s)" 39 | 40 | run sudo rm "$PLUGIN_DATA_ROOT/ls/PORT" 41 | echo "output: $output" 42 | echo "status: $status" 43 | assert_success 44 | 45 | run dokku "$PLUGIN_COMMAND_PREFIX:expose" ls 46 | echo "output: $output" 47 | echo "status: $status" 48 | assert_success 49 | assert_contains "${lines[*]}" "Service ls has an untracked expose container, removing" 50 | } 51 | 52 | @test "($PLUGIN_COMMAND_PREFIX:expose) success when not providing custom ports" { 53 | run dokku "$PLUGIN_COMMAND_PREFIX:expose" ls 54 | echo "output: $output" 55 | echo "status: $status" 56 | assert_success 57 | [[ "${lines[*]}" =~ exposed\ on\ port\(s\)\ \[container\-\>host\]\:\ [[:digit:]]+ ]] 58 | } 59 | 60 | @test "($PLUGIN_COMMAND_PREFIX:expose) success when providing custom ports" { 61 | run dokku "$PLUGIN_COMMAND_PREFIX:expose" ls 4242 62 | echo "output: $output" 63 | echo "status: $status" 64 | assert_success 65 | assert_contains "${lines[*]}" "exposed on port(s) [container->host]: 7700->4242" 66 | } 67 | -------------------------------------------------------------------------------- /tests/service_info.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | setup() { 5 | dokku "$PLUGIN_COMMAND_PREFIX:create" l 6 | } 7 | 8 | teardown() { 9 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l 10 | } 11 | 12 | @test "($PLUGIN_COMMAND_PREFIX:info) error when there are no arguments" { 13 | run dokku "$PLUGIN_COMMAND_PREFIX:info" 14 | assert_contains "${lines[*]}" "Please specify a valid name for the service" 15 | } 16 | 17 | @test "($PLUGIN_COMMAND_PREFIX:info) error when service does not exist" { 18 | run dokku "$PLUGIN_COMMAND_PREFIX:info" not_existing_service 19 | assert_contains "${lines[*]}" "service not_existing_service does not exist" 20 | } 21 | 22 | @test "($PLUGIN_COMMAND_PREFIX:info) success" { 23 | run dokku "$PLUGIN_COMMAND_PREFIX:info" l 24 | local password="$(sudo cat "$PLUGIN_DATA_ROOT/l/PASSWORD")" 25 | assert_contains "${lines[*]}" "http://:$password@dokku-meilisearch-l:7700" 26 | } 27 | 28 | @test "($PLUGIN_COMMAND_PREFIX:info) replaces underscores by dash in hostname" { 29 | dokku "$PLUGIN_COMMAND_PREFIX:create" test_with_underscores 30 | run dokku "$PLUGIN_COMMAND_PREFIX:info" test_with_underscores 31 | local password="$(sudo cat "$PLUGIN_DATA_ROOT/test_with_underscores/PASSWORD")" 32 | assert_contains "${lines[*]}" "http://:$password@dokku-meilisearch-test-with-underscores:7700" 33 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" test_with_underscores 34 | } 35 | 36 | @test "($PLUGIN_COMMAND_PREFIX:info) success with flag" { 37 | run dokku "$PLUGIN_COMMAND_PREFIX:info" l --dsn 38 | local password="$(sudo cat "$PLUGIN_DATA_ROOT/l/PASSWORD")" 39 | assert_output "http://:$password@dokku-meilisearch-l:7700" 40 | 41 | run dokku "$PLUGIN_COMMAND_PREFIX:info" l --config-dir 42 | assert_success 43 | 44 | run dokku "$PLUGIN_COMMAND_PREFIX:info" l --data-dir 45 | assert_success 46 | 47 | run dokku "$PLUGIN_COMMAND_PREFIX:info" l --dsn 48 | assert_success 49 | 50 | run dokku "$PLUGIN_COMMAND_PREFIX:info" l --exposed-ports 51 | assert_success 52 | 53 | run dokku "$PLUGIN_COMMAND_PREFIX:info" l --id 54 | assert_success 55 | 56 | run dokku "$PLUGIN_COMMAND_PREFIX:info" l --internal-ip 57 | assert_success 58 | 59 | run dokku "$PLUGIN_COMMAND_PREFIX:info" l --links 60 | assert_success 61 | 62 | run dokku "$PLUGIN_COMMAND_PREFIX:info" l --service-root 63 | assert_success 64 | 65 | run dokku "$PLUGIN_COMMAND_PREFIX:info" l --status 66 | assert_success 67 | 68 | run dokku "$PLUGIN_COMMAND_PREFIX:info" l --version 69 | assert_success 70 | } 71 | 72 | @test "($PLUGIN_COMMAND_PREFIX:info) error when invalid flag" { 73 | run dokku "$PLUGIN_COMMAND_PREFIX:info" l --invalid-flag 74 | assert_failure 75 | } 76 | -------------------------------------------------------------------------------- /tests/service_link.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | setup() { 5 | dokku "$PLUGIN_COMMAND_PREFIX:create" ls 6 | dokku "$PLUGIN_COMMAND_PREFIX:create" ms 7 | dokku apps:create my-app 8 | } 9 | 10 | teardown() { 11 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" ms 12 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" ls 13 | dokku --force apps:destroy my-app 14 | } 15 | 16 | @test "($PLUGIN_COMMAND_PREFIX:link) error when there are no arguments" { 17 | run dokku "$PLUGIN_COMMAND_PREFIX:link" 18 | echo "output: $output" 19 | echo "status: $status" 20 | assert_contains "${lines[*]}" "Please specify a valid name for the service" 21 | assert_failure 22 | } 23 | 24 | @test "($PLUGIN_COMMAND_PREFIX:link) error when the app argument is missing" { 25 | run dokku "$PLUGIN_COMMAND_PREFIX:link" ls 26 | echo "output: $output" 27 | echo "status: $status" 28 | assert_contains "${lines[*]}" "Please specify an app to run the command on" 29 | assert_failure 30 | } 31 | 32 | @test "($PLUGIN_COMMAND_PREFIX:link) error when the app does not exist" { 33 | run dokku "$PLUGIN_COMMAND_PREFIX:link" ls not_existing_app 34 | echo "output: $output" 35 | echo "status: $status" 36 | assert_contains "${lines[*]}" "App not_existing_app does not exist" 37 | assert_failure 38 | } 39 | 40 | @test "($PLUGIN_COMMAND_PREFIX:link) error when the service does not exist" { 41 | run dokku "$PLUGIN_COMMAND_PREFIX:link" not_existing_service my-app 42 | echo "output: $output" 43 | echo "status: $status" 44 | assert_contains "${lines[*]}" "service not_existing_service does not exist" 45 | assert_failure 46 | } 47 | 48 | @test "($PLUGIN_COMMAND_PREFIX:link) error when the service is already linked to app" { 49 | dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app 50 | run dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app 51 | echo "output: $output" 52 | echo "status: $status" 53 | assert_contains "${lines[*]}" "Already linked as MEILISEARCH_URL" 54 | assert_failure 55 | 56 | dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app 57 | } 58 | 59 | @test "($PLUGIN_COMMAND_PREFIX:link) exports MEILISEARCH_URL to app" { 60 | run dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app 61 | echo "output: $output" 62 | echo "status: $status" 63 | url=$(dokku config:get my-app MEILISEARCH_URL) 64 | password="$(sudo cat "$PLUGIN_DATA_ROOT/ls/PASSWORD")" 65 | assert_contains "$url" "http://:$password@dokku-meilisearch-ls:7700" 66 | assert_success 67 | dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app 68 | } 69 | 70 | @test "($PLUGIN_COMMAND_PREFIX:link) generates an alternate config url when MEILISEARCH_URL already in use" { 71 | dokku config:set my-app MEILISEARCH_URL=http://user:pass@host:7700/db 72 | dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app 73 | run dokku config my-app 74 | assert_contains "${lines[*]}" "DOKKU_MEILISEARCH_AQUA_URL" 75 | assert_success 76 | 77 | dokku "$PLUGIN_COMMAND_PREFIX:link" ms my-app 78 | run dokku config my-app 79 | assert_contains "${lines[*]}" "DOKKU_MEILISEARCH_BLACK_URL" 80 | assert_success 81 | dokku "$PLUGIN_COMMAND_PREFIX:unlink" ms my-app 82 | dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app 83 | } 84 | 85 | @test "($PLUGIN_COMMAND_PREFIX:link) links to app with docker-options" { 86 | dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app 87 | run dokku docker-options:report my-app 88 | assert_contains "${lines[*]}" "--link dokku.meilisearch.ls:dokku-meilisearch-ls" 89 | assert_success 90 | dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app 91 | } 92 | 93 | @test "($PLUGIN_COMMAND_PREFIX:link) uses apps MEILISEARCH_DATABASE_SCHEME variable" { 94 | dokku config:set my-app MEILISEARCH_DATABASE_SCHEME=http2 95 | dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app 96 | url=$(dokku config:get my-app MEILISEARCH_URL) 97 | password="$(sudo cat "$PLUGIN_DATA_ROOT/ls/PASSWORD")" 98 | assert_contains "$url" "http2://:$password@dokku-meilisearch-ls:7700" 99 | assert_success 100 | dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app 101 | } 102 | 103 | @test "($PLUGIN_COMMAND_PREFIX:link) adds a querystring" { 104 | dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app --querystring "pool=5" 105 | url=$(dokku config:get my-app MEILISEARCH_URL) 106 | assert_contains "$url" "?pool=5" 107 | assert_success 108 | dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app 109 | } 110 | 111 | @test "($PLUGIN_COMMAND_PREFIX:link) uses a specified config url when alias is specified" { 112 | dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app --alias "ALIAS" 113 | url=$(dokku config:get my-app ALIAS_URL) 114 | password="$(sudo cat "$PLUGIN_DATA_ROOT/ls/PASSWORD")" 115 | assert_contains "$url" "http://:$password@dokku-meilisearch-ls:7700" 116 | assert_success 117 | dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app 118 | } 119 | 120 | @test "($PLUGIN_COMMAND_PREFIX:link) respects --no-restart" { 121 | run dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app 122 | echo "output: $output" 123 | echo "status: $status" 124 | assert_output_contains "Skipping restart of linked app" 0 125 | assert_success 126 | 127 | run dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app 128 | echo "output: $output" 129 | echo "status: $status" 130 | assert_success 131 | 132 | run dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app --no-restart 133 | echo "output: $output" 134 | echo "status: $status" 135 | assert_output_contains "Skipping restart of linked app" 136 | assert_success 137 | 138 | run dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app 139 | echo "output: $output" 140 | echo "status: $status" 141 | assert_success 142 | } 143 | -------------------------------------------------------------------------------- /tests/service_list.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | setup() { 5 | dokku "$PLUGIN_COMMAND_PREFIX:create" l 6 | } 7 | 8 | teardown() { 9 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l 10 | } 11 | 12 | @test "($PLUGIN_COMMAND_PREFIX:list) with no exposed ports, no linked apps" { 13 | run dokku --quiet "$PLUGIN_COMMAND_PREFIX:list" 14 | assert_output "l" 15 | } 16 | 17 | @test "($PLUGIN_COMMAND_PREFIX:list) when there are no services" { 18 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l 19 | run dokku "$PLUGIN_COMMAND_PREFIX:list" 20 | assert_output "${lines[*]}" "There are no $PLUGIN_SERVICE services" 21 | dokku "$PLUGIN_COMMAND_PREFIX:create" l 22 | } 23 | -------------------------------------------------------------------------------- /tests/service_logs.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | setup() { 5 | dokku "$PLUGIN_COMMAND_PREFIX:create" l 6 | } 7 | 8 | teardown() { 9 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l 10 | } 11 | 12 | @test "($PLUGIN_COMMAND_PREFIX:logs) error when there are no arguments" { 13 | run dokku "$PLUGIN_COMMAND_PREFIX:logs" 14 | echo "output: $output" 15 | echo "status: $status" 16 | assert_contains "${lines[*]}" "Please specify a valid name for the service" 17 | assert_failure 18 | } 19 | 20 | @test "($PLUGIN_COMMAND_PREFIX:logs) error when service does not exist" { 21 | run dokku "$PLUGIN_COMMAND_PREFIX:logs" not_existing_service 22 | echo "output: $output" 23 | echo "status: $status" 24 | assert_contains "${lines[*]}" "service not_existing_service does not exist" 25 | assert_failure 26 | } 27 | 28 | @test "($PLUGIN_COMMAND_PREFIX:logs) success when not tailing" { 29 | skip "This may fail if there is no log output" 30 | run dokku "$PLUGIN_COMMAND_PREFIX:logs" l 31 | echo "output: $output" 32 | echo "status: $status" 33 | assert_success 34 | } 35 | 36 | @test "($PLUGIN_COMMAND_PREFIX:logs) success when tailing" { 37 | skip "This will hang as it waits for log output" 38 | run dokku "$PLUGIN_COMMAND_PREFIX:logs" l -t 39 | echo "output: $output" 40 | echo "status: $status" 41 | assert_success 42 | } 43 | -------------------------------------------------------------------------------- /tests/service_pause.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | setup() { 5 | dokku "$PLUGIN_COMMAND_PREFIX:create" l 6 | } 7 | 8 | teardown() { 9 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l 10 | } 11 | 12 | @test "($PLUGIN_COMMAND_PREFIX:pause) error when there are no arguments" { 13 | run dokku "$PLUGIN_COMMAND_PREFIX:pause" 14 | assert_contains "${lines[*]}" "Please specify a valid name for the service" 15 | } 16 | 17 | @test "($PLUGIN_COMMAND_PREFIX:pause) error when service does not exist" { 18 | run dokku "$PLUGIN_COMMAND_PREFIX:pause" not_existing_service 19 | assert_contains "${lines[*]}" "service not_existing_service does not exist" 20 | } 21 | 22 | @test "($PLUGIN_COMMAND_PREFIX:pause) success" { 23 | run dokku "$PLUGIN_COMMAND_PREFIX:pause" l 24 | assert_success 25 | } 26 | -------------------------------------------------------------------------------- /tests/service_promote.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | setup() { 5 | dokku "$PLUGIN_COMMAND_PREFIX:create" l 6 | dokku apps:create my-app 7 | dokku "$PLUGIN_COMMAND_PREFIX:link" l my-app 8 | } 9 | 10 | teardown() { 11 | dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my-app 12 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l 13 | dokku --force apps:destroy my-app 14 | } 15 | 16 | @test "($PLUGIN_COMMAND_PREFIX:promote) error when there are no arguments" { 17 | run dokku "$PLUGIN_COMMAND_PREFIX:promote" 18 | assert_contains "${lines[*]}" "Please specify a valid name for the service" 19 | } 20 | 21 | @test "($PLUGIN_COMMAND_PREFIX:promote) error when the app argument is missing" { 22 | run dokku "$PLUGIN_COMMAND_PREFIX:promote" l 23 | assert_contains "${lines[*]}" "Please specify an app to run the command on" 24 | } 25 | 26 | @test "($PLUGIN_COMMAND_PREFIX:promote) error when the app does not exist" { 27 | run dokku "$PLUGIN_COMMAND_PREFIX:promote" l not_existing_app 28 | assert_contains "${lines[*]}" "App not_existing_app does not exist" 29 | } 30 | 31 | @test "($PLUGIN_COMMAND_PREFIX:promote) error when the service does not exist" { 32 | run dokku "$PLUGIN_COMMAND_PREFIX:promote" not_existing_service my-app 33 | assert_contains "${lines[*]}" "service not_existing_service does not exist" 34 | } 35 | 36 | @test "($PLUGIN_COMMAND_PREFIX:promote) error when the service is already promoted" { 37 | run dokku "$PLUGIN_COMMAND_PREFIX:promote" l my-app 38 | assert_contains "${lines[*]}" "already promoted as MEILISEARCH_URL" 39 | } 40 | 41 | @test "($PLUGIN_COMMAND_PREFIX:promote) changes MEILISEARCH_URL" { 42 | password="$(sudo cat "$PLUGIN_DATA_ROOT/l/PASSWORD")" 43 | dokku config:set my-app "MEILISEARCH_URL=http://:p@host:7700" "DOKKU_MEILISEARCH_BLUE_URL=http://:$password@dokku-meilisearch-l:7700" 44 | dokku "$PLUGIN_COMMAND_PREFIX:promote" l my-app 45 | url=$(dokku config:get my-app MEILISEARCH_URL) 46 | assert_equal "$url" "http://:$password@dokku-meilisearch-l:7700" 47 | } 48 | 49 | @test "($PLUGIN_COMMAND_PREFIX:promote) creates new config url when needed" { 50 | password="$(sudo cat "$PLUGIN_DATA_ROOT/l/PASSWORD")" 51 | dokku config:set my-app "MEILISEARCH_URL=http://:p@host:7700" "DOKKU_MEILISEARCH_BLUE_URL=http://:$password@dokku-meilisearch-l:7700" 52 | dokku "$PLUGIN_COMMAND_PREFIX:promote" l my-app 53 | run dokku config my-app 54 | assert_contains "${lines[*]}" "DOKKU_MEILISEARCH_" 55 | } 56 | @test "($PLUGIN_COMMAND_PREFIX:promote) uses MEILISEARCH_DATABASE_SCHEME variable" { 57 | password="$(sudo cat "$PLUGIN_DATA_ROOT/l/PASSWORD")" 58 | dokku config:set my-app "MEILISEARCH_DATABASE_SCHEME=http2" "MEILISEARCH_URL=http://:p@host:7700" "DOKKU_MEILISEARCH_BLUE_URL=http2://:$password@dokku-meilisearch-l:7700" 59 | dokku "$PLUGIN_COMMAND_PREFIX:promote" l my-app 60 | url=$(dokku config:get my-app MEILISEARCH_URL) 61 | assert_contains "$url" "http2://:$password@dokku-meilisearch-l:7700" 62 | } 63 | -------------------------------------------------------------------------------- /tests/service_restart.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | setup() { 5 | dokku "$PLUGIN_COMMAND_PREFIX:create" l 6 | } 7 | 8 | teardown() { 9 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l 10 | } 11 | 12 | @test "($PLUGIN_COMMAND_PREFIX:restart) error when there are no arguments" { 13 | run dokku "$PLUGIN_COMMAND_PREFIX:restart" 14 | assert_contains "${lines[*]}" "Please specify a valid name for the service" 15 | } 16 | 17 | @test "($PLUGIN_COMMAND_PREFIX:restart) error when service does not exist" { 18 | run dokku "$PLUGIN_COMMAND_PREFIX:restart" not_existing_service 19 | assert_contains "${lines[*]}" "service not_existing_service does not exist" 20 | } 21 | 22 | @test "($PLUGIN_COMMAND_PREFIX:restart) success" { 23 | run dokku "$PLUGIN_COMMAND_PREFIX:restart" l 24 | assert_success 25 | } 26 | -------------------------------------------------------------------------------- /tests/service_start.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | setup() { 5 | dokku "$PLUGIN_COMMAND_PREFIX:create" l 6 | } 7 | 8 | teardown() { 9 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l 10 | } 11 | 12 | @test "($PLUGIN_COMMAND_PREFIX:start) error when there are no arguments" { 13 | run dokku "$PLUGIN_COMMAND_PREFIX:start" 14 | assert_contains "${lines[*]}" "Please specify a valid name for the service" 15 | } 16 | 17 | @test "($PLUGIN_COMMAND_PREFIX:start) error when service does not exist" { 18 | run dokku "$PLUGIN_COMMAND_PREFIX:start" not_existing_service 19 | assert_contains "${lines[*]}" "service not_existing_service does not exist" 20 | } 21 | 22 | @test "($PLUGIN_COMMAND_PREFIX:start) success" { 23 | run dokku "$PLUGIN_COMMAND_PREFIX:start" l 24 | assert_success 25 | } 26 | -------------------------------------------------------------------------------- /tests/service_stop.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | setup() { 5 | dokku "$PLUGIN_COMMAND_PREFIX:create" l 6 | } 7 | 8 | teardown() { 9 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l 10 | } 11 | 12 | @test "($PLUGIN_COMMAND_PREFIX:stop) error when there are no arguments" { 13 | run dokku "$PLUGIN_COMMAND_PREFIX:stop" 14 | assert_contains "${lines[*]}" "Please specify a valid name for the service" 15 | } 16 | 17 | @test "($PLUGIN_COMMAND_PREFIX:stop) error when service does not exist" { 18 | run dokku "$PLUGIN_COMMAND_PREFIX:stop" not_existing_service 19 | assert_contains "${lines[*]}" "service not_existing_service does not exist" 20 | } 21 | 22 | @test "($PLUGIN_COMMAND_PREFIX:stop) success" { 23 | run dokku "$PLUGIN_COMMAND_PREFIX:stop" l 24 | assert_success 25 | } 26 | -------------------------------------------------------------------------------- /tests/service_unexpose.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | setup() { 5 | dokku "$PLUGIN_COMMAND_PREFIX:create" l 6 | } 7 | 8 | teardown() { 9 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" l 10 | } 11 | 12 | @test "($PLUGIN_COMMAND_PREFIX:unexpose) error when there are no arguments" { 13 | run dokku "$PLUGIN_COMMAND_PREFIX:unexpose" 14 | assert_contains "${lines[*]}" "Please specify a valid name for the service" 15 | } 16 | 17 | @test "($PLUGIN_COMMAND_PREFIX:unexpose) error when service does not exist" { 18 | run dokku "$PLUGIN_COMMAND_PREFIX:unexpose" not_existing_service 19 | assert_contains "${lines[*]}" "service not_existing_service does not exist" 20 | } 21 | 22 | @test "($PLUGIN_COMMAND_PREFIX:unexpose) success" { 23 | dokku "$PLUGIN_COMMAND_PREFIX:expose" l 24 | run dokku "$PLUGIN_COMMAND_PREFIX:unexpose" l 25 | [[ ! -f $PLUGIN_DATA_ROOT/PORT ]] 26 | assert_contains "${lines[*]}" "Service l unexposed" 27 | } 28 | -------------------------------------------------------------------------------- /tests/service_unlink.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | setup() { 5 | dokku apps:create my-app 6 | dokku "$PLUGIN_COMMAND_PREFIX:create" ls 7 | } 8 | 9 | teardown() { 10 | dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" ls 11 | dokku --force apps:destroy my-app 12 | } 13 | 14 | @test "($PLUGIN_COMMAND_PREFIX:unlink) error when there are no arguments" { 15 | run dokku "$PLUGIN_COMMAND_PREFIX:unlink" 16 | assert_contains "${lines[*]}" "Please specify a valid name for the service" 17 | } 18 | 19 | @test "($PLUGIN_COMMAND_PREFIX:unlink) error when the app argument is missing" { 20 | run dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls 21 | assert_contains "${lines[*]}" "Please specify an app to run the command on" 22 | } 23 | 24 | @test "($PLUGIN_COMMAND_PREFIX:unlink) error when the app does not exist" { 25 | run dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls not_existing_app 26 | assert_contains "${lines[*]}" "App not_existing_app does not exist" 27 | } 28 | 29 | @test "($PLUGIN_COMMAND_PREFIX:unlink) error when the service does not exist" { 30 | run dokku "$PLUGIN_COMMAND_PREFIX:unlink" not_existing_service my-app 31 | assert_contains "${lines[*]}" "service not_existing_service does not exist" 32 | } 33 | 34 | @test "($PLUGIN_COMMAND_PREFIX:unlink) error when service not linked to app" { 35 | run dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app 36 | assert_contains "${lines[*]}" "Not linked to app my-app" 37 | } 38 | 39 | @test "($PLUGIN_COMMAND_PREFIX:unlink) removes link from docker-options" { 40 | dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app >&2 41 | dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app 42 | 43 | check_value="Docker options build: Docker options deploy: --restart=on-failure:10 Docker options run:" 44 | options=$(dokku --quiet docker-options:report my-app | xargs) 45 | assert_equal "$options" "$check_value" 46 | } 47 | 48 | @test "($PLUGIN_COMMAND_PREFIX:unlink) unsets config url from app" { 49 | dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app >&2 50 | dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app 51 | config=$(dokku config:get my-app MEILISEARCH_URL || true) 52 | assert_equal "$config" "" 53 | } 54 | 55 | @test "($PLUGIN_COMMAND_PREFIX:unlink) respects --no-restart" { 56 | run dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app 57 | echo "output: $output" 58 | echo "status: $status" 59 | assert_success 60 | 61 | run dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app 62 | echo "output: $output" 63 | echo "status: $status" 64 | assert_output_contains "Skipping restart of linked app" 0 65 | assert_success 66 | 67 | run dokku "$PLUGIN_COMMAND_PREFIX:link" ls my-app 68 | echo "output: $output" 69 | echo "status: $status" 70 | assert_success 71 | 72 | run dokku "$PLUGIN_COMMAND_PREFIX:unlink" ls my-app --no-restart 73 | echo "output: $output" 74 | echo "status: $status" 75 | assert_output_contains "Skipping restart of linked app" 76 | assert_success 77 | } 78 | -------------------------------------------------------------------------------- /tests/setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eo pipefail 3 | [[ $TRACE ]] && set -x 4 | sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 762E3157 5 | echo "deb http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list 6 | curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add - 7 | 8 | sudo mkdir -p /etc/nginx 9 | sudo curl https://raw.githubusercontent.com/dokku/dokku/master/tests/dhparam.pem -o /etc/nginx/dhparam.pem 10 | 11 | echo "dokku dokku/skip_key_file boolean true" | sudo debconf-set-selections 12 | wget https://raw.githubusercontent.com/dokku/dokku/master/bootstrap.sh 13 | if [[ "$DOKKU_VERSION" == "master" ]]; then 14 | sudo bash bootstrap.sh 15 | else 16 | sudo DOKKU_TAG="$DOKKU_VERSION" bash bootstrap.sh 17 | fi 18 | echo "Dokku version $DOKKU_VERSION" 19 | 20 | export DOKKU_LIB_ROOT="/var/lib/dokku" 21 | export DOKKU_PLUGINS_ROOT="$DOKKU_LIB_ROOT/plugins/available" 22 | pushd "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")" >/dev/null 23 | source "config" 24 | popd >/dev/null 25 | sudo rm -rf "$DOKKU_PLUGINS_ROOT/$PLUGIN_COMMAND_PREFIX" 26 | sudo mkdir -p "$DOKKU_PLUGINS_ROOT/$PLUGIN_COMMAND_PREFIX" "$DOKKU_PLUGINS_ROOT/$PLUGIN_COMMAND_PREFIX/subcommands" "$DOKKU_PLUGINS_ROOT/$PLUGIN_COMMAND_PREFIX/scripts" "$DOKKU_PLUGINS_ROOT/$PLUGIN_COMMAND_PREFIX/templates" 27 | sudo find ./ -maxdepth 1 -type f -exec cp '{}' "$DOKKU_PLUGINS_ROOT/$PLUGIN_COMMAND_PREFIX" \; 28 | [[ -d "./scripts" ]] && sudo find ./scripts -maxdepth 1 -type f -exec cp '{}' "$DOKKU_PLUGINS_ROOT/$PLUGIN_COMMAND_PREFIX/scripts" \; 29 | [[ -d "./subcommands" ]] && sudo find ./subcommands -maxdepth 1 -type f -exec cp '{}' "$DOKKU_PLUGINS_ROOT/$PLUGIN_COMMAND_PREFIX/subcommands" \; 30 | [[ -d "./templates" ]] && sudo find ./templates -maxdepth 1 -type f -exec cp '{}' "$DOKKU_PLUGINS_ROOT/$PLUGIN_COMMAND_PREFIX/templates" \; 31 | sudo mkdir -p "$PLUGIN_CONFIG_ROOT" "$PLUGIN_DATA_ROOT" 32 | sudo dokku plugin:enable "$PLUGIN_COMMAND_PREFIX" 33 | sudo dokku plugin:install 34 | -------------------------------------------------------------------------------- /tests/shellcheck-exclude: -------------------------------------------------------------------------------- 1 | # SC1090 - Can't follow non-constant source. Use a directive to specify location - https://github.com/koalaman/shellcheck/wiki/SC1090 2 | # SC1091 - Not following - 3 | # SC2034 - Variable appears unused. Verify it or export it - https://github.com/koalaman/shellcheck/wiki/SC2034 4 | # SC2155 - Declare and assign separately to avoid masking return values - https://github.com/koalaman/shellcheck/wiki/SC2155 5 | # SC2206 - Quote to prevent word splitting/globbing, or split robustly with mapfile or read -a - https://github.com/koalaman/shellcheck/wiki/SC2206 6 | # SC2207 - Prefer mapfile or read -a to split command output (or quote to avoid splitting) - https://github.com/koalaman/shellcheck/wiki/SC2207 7 | # SC2220 - Invalid flags are not handled. Add a *) case - https://github.com/koalaman/shellcheck/wiki/SC2220 8 | # SC2230 - which is non-standard. Use builtin 'command -v' instead - https://github.com/koalaman/shellcheck/wiki/SC2230 9 | -------------------------------------------------------------------------------- /tests/shellcheck-to-junit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | from __future__ import print_function 4 | import argparse 5 | import collections 6 | import datetime 7 | import re 8 | import socket 9 | import sys 10 | 11 | from xml.etree import ElementTree 12 | 13 | 14 | def CDATA(text=None): 15 | element = ElementTree.Element('![CDATA[') 16 | element.text = text 17 | return element 18 | 19 | 20 | def _serialize_xml(write, elem, qnames, namespaces,short_empty_elements, **kwargs): 21 | 22 | if elem.tag == '![CDATA[': 23 | write("\n<{}{}]]>\n".format(elem.tag, elem.text)) 24 | if elem.tail: 25 | write(ElementTree._escape_cdata(elem.tail)) 26 | else: 27 | return ElementTree._original_serialize_xml(write, elem, qnames, namespaces,short_empty_elements, **kwargs) 28 | 29 | 30 | ElementTree._original_serialize_xml = ElementTree._serialize_xml 31 | ElementTree._serialize_xml = ElementTree._serialize['xml'] = _serialize_xml 32 | 33 | 34 | def read_in(): 35 | lines = sys.stdin.readlines() 36 | for i in range(len(lines)): 37 | lines[i] = lines[i].rstrip() 38 | return lines 39 | 40 | 41 | def process_lines(lines): 42 | files = {} 43 | current_file = None 44 | previous_line = None 45 | line_no = None 46 | new_issues = [] 47 | code = None 48 | 49 | RE_VIOLATION = re.compile(r"\^-- (SC[\w]+): (.*)") 50 | RE_VIOLATION_NEW = re.compile(r"\^[-]+\^ (SC[\w]+): (.*)") 51 | 52 | for line in lines: 53 | # start a new block 54 | if line == '': 55 | if current_file is not None: 56 | file_data = files.get(current_file, {}) 57 | files[current_file] = file_data 58 | 59 | issue_data = file_data.get(line_no, {}) 60 | issue_data['code'] = code 61 | files[current_file][line_no] = issue_data 62 | 63 | issues = issue_data.get('issues', []) 64 | issues.extend(new_issues) 65 | issue_data['issues'] = issues 66 | 67 | files[current_file][line_no] = issue_data 68 | 69 | code = None 70 | current_file = None 71 | line_no = None 72 | elif line.startswith('In ./') and not previous_line: 73 | current_file = line.split(' ')[1].replace('./', '') 74 | line_no = line.split(' ')[3] 75 | new_issues = [] 76 | code = None 77 | elif code is None and len(new_issues) == 0: 78 | code = line 79 | else: 80 | match = RE_VIOLATION.match(line.strip()) 81 | if not match: 82 | match = RE_VIOLATION_NEW.match(line.strip()) 83 | 84 | if not match: 85 | if 'https://www.shellcheck.net/wiki/SC' in line: 86 | continue 87 | if 'For more information:' == line: 88 | continue 89 | print('Error: Issue parsing line "{0}"'.format(line.strip())) 90 | else: 91 | new_issues.append({ 92 | 'shellcheck_id': match.group(1), 93 | 'message': match.group(2), 94 | 'original_message': line 95 | }) 96 | 97 | previous_line = line 98 | 99 | return files 100 | 101 | 102 | def output_junit(files, args): 103 | timestamp = datetime.datetime.now().replace(microsecond=0).isoformat() 104 | failures = 0 105 | for file, data in files.items(): 106 | for line, issue_data in data.items(): 107 | code = issue_data.get('code') 108 | for issue in issue_data.get('issues', []): 109 | failures += 1 110 | 111 | tests = 0 112 | if args.files: 113 | with open(args.files, 'r') as f: 114 | tests = len(f.readlines()) 115 | 116 | root = ElementTree.Element("testsuite", 117 | name="shellcheck", 118 | tests="{0}".format(tests), 119 | failures="{0}".format(failures), 120 | errors="0", 121 | skipped="0", 122 | timestamp=timestamp, 123 | time="0", 124 | hostname=socket.gethostname()) 125 | 126 | properties = ElementTree.SubElement(root, "properties") 127 | if args.exclude: 128 | ElementTree.SubElement(properties, 129 | "property", 130 | name="exclude", 131 | value=args.exclude) 132 | 133 | if args.files: 134 | with open(args.files, 'r') as f: 135 | lines = f.readlines() 136 | for i in range(len(lines)): 137 | file = lines[i].rstrip().replace('./', '') 138 | data = files.get(file, None) 139 | if data: 140 | for line, issue_data in data.items(): 141 | code = issue_data.get('code') 142 | for issue in issue_data.get('issues', []): 143 | testcase = ElementTree.SubElement(root, 144 | "testcase", 145 | classname=file, 146 | name=file, 147 | time="0") 148 | shellcheck_id = issue.get('shellcheck_id') 149 | message = 'line {0}: {1}'.format( 150 | line, issue.get('message')) 151 | original_message = issue.get('original_message') 152 | e = ElementTree.Element("failure", 153 | type=shellcheck_id, 154 | message=message) 155 | cdata = CDATA("\n".join([code, original_message])) 156 | e.append(cdata) 157 | testcase.append(e) 158 | ElementTree.SubElement(root, 159 | "testcase", 160 | classname=file, 161 | name=file, 162 | time="0") 163 | 164 | ElementTree.SubElement(root, "system-out") 165 | ElementTree.SubElement(root, "system-err") 166 | 167 | content = ElementTree.tostring(root, encoding='UTF-8', method='xml') 168 | if args.output: 169 | with open(args.output, 'w') as f: 170 | try: 171 | f.write(content) 172 | except TypeError: 173 | f.write(content.decode("utf-8")) 174 | 175 | 176 | def main(): 177 | parser = argparse.ArgumentParser( 178 | description='Process shellcheck output to junit.') 179 | parser.add_argument('--output', 180 | dest='output', 181 | action='store', 182 | default=None, 183 | help='file to write shellcheck output') 184 | parser.add_argument('--files', 185 | dest='files', 186 | action='store', 187 | default=None, 188 | help='a file containing a list of all files processed by shellcheck') 189 | parser.add_argument('--exclude', 190 | dest='exclude', 191 | action='store', 192 | default=None, 193 | help='a comma-separated list of rules being excluded by shellcheck') 194 | args = parser.parse_args() 195 | 196 | lines = read_in() 197 | files = process_lines(lines) 198 | files = collections.OrderedDict(sorted(files.items())) 199 | output_junit(files, args) 200 | for line in lines: 201 | print(line) 202 | 203 | 204 | if __name__ == '__main__': 205 | main() 206 | -------------------------------------------------------------------------------- /tests/test_helper.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | export DOKKU_LIB_ROOT="/var/lib/dokku" 3 | source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config" 4 | 5 | flunk() { 6 | { 7 | if [ "$#" -eq 0 ]; then 8 | cat - 9 | else 10 | echo "$*" 11 | fi 12 | } 13 | return 1 14 | } 15 | 16 | assert_equal() { 17 | if [ "$1" != "$2" ]; then 18 | { 19 | echo "expected: $1" 20 | echo "actual: $2" 21 | } | flunk 22 | fi 23 | } 24 | 25 | # ShellCheck doesn't know about $status from Bats 26 | # shellcheck disable=SC2154 27 | assert_exit_status() { 28 | assert_equal "$1" "$status" 29 | } 30 | 31 | # ShellCheck doesn't know about $status from Bats 32 | # shellcheck disable=SC2154 33 | # shellcheck disable=SC2120 34 | assert_success() { 35 | if [ "$status" -ne 0 ]; then 36 | flunk "command failed with exit status $status" 37 | elif [ "$#" -gt 0 ]; then 38 | assert_output "$1" 39 | fi 40 | } 41 | 42 | assert_failure() { 43 | if [[ "$status" -eq 0 ]]; then 44 | flunk "expected failed exit status" 45 | elif [[ "$#" -gt 0 ]]; then 46 | assert_output "$1" 47 | fi 48 | } 49 | 50 | assert_exists() { 51 | if [ ! -f "$1" ]; then 52 | flunk "expected file to exist: $1" 53 | fi 54 | } 55 | 56 | assert_contains() { 57 | if [[ "$1" != *"$2"* ]]; then 58 | flunk "expected $2 to be in: $1" 59 | fi 60 | } 61 | 62 | # ShellCheck doesn't know about $output from Bats 63 | # shellcheck disable=SC2154 64 | assert_output() { 65 | local expected 66 | if [ $# -eq 0 ]; then 67 | expected="$(cat -)" 68 | else 69 | expected="$1" 70 | fi 71 | assert_equal "$expected" "$output" 72 | } 73 | 74 | # ShellCheck doesn't know about $output from Bats 75 | # shellcheck disable=SC2154 76 | assert_output_contains() { 77 | local input="$output" 78 | local expected="$1" 79 | local count="${2:-1}" 80 | local found=0 81 | until [ "${input/$expected/}" = "$input" ]; do 82 | input="${input/$expected/}" 83 | found=$((found + 1)) 84 | done 85 | assert_equal "$count" "$found" 86 | } 87 | -------------------------------------------------------------------------------- /update: -------------------------------------------------------------------------------- 1 | install --------------------------------------------------------------------------------