diff --git a/docs/development/plugin-triggers.md b/docs/development/plugin-triggers.md index 347356920..87c9d6feb 100644 --- a/docs/development/plugin-triggers.md +++ b/docs/development/plugin-triggers.md @@ -2297,6 +2297,25 @@ DOKKU_SCHEDULER="$1"; APP="$2"; ARGS="${@:3}"; # TODO ``` +### `scheduler-run-list` + +> Warning: The scheduler plugin trigger apis are under development and may change +> between minor releases until the 1.0 release. + +- Description: Lists all run containers for a given app +- Invoked by: `dokku run` +- Arguments: `$DOKKU_SCHEDULER $APP $FORMAT` +- Example: + +```shell +#!/usr/bin/env bash + +set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x +DOKKU_SCHEDULER="$1"; APP="$2"; FORMAT="$3"; + +# TODO +``` + ### `scheduler-stop` > Warning: The scheduler plugin trigger apis are under development and may change diff --git a/docs/processes/one-off-tasks.md b/docs/processes/one-off-tasks.md index 06ba41ce1..91f03d190 100644 --- a/docs/processes/one-off-tasks.md +++ b/docs/processes/one-off-tasks.md @@ -3,7 +3,7 @@ ``` run [-e|--env KEY=VALUE] [--no-tty] # Run a command in a new container using the current app image run:detached [-e|-env KEY=VALUE] [--no-tty] # Run a command in a new detached container using the current app image -run:list [] # List all run containers for an app +run:list [--format json|stdout] [] # List all run containers for an app ``` Sometimes it is necessary to run a one-off command under an app. Dokku makes it easy to run a fresh container via the `run` command. @@ -85,3 +85,20 @@ node-js-app.run.28689 "/exec sleep 15" 2 seconds ago ``` > The `COMMAND` displayed will be what Docker executes and may not exactly match the command specified by a `dokku run` command. + +The output can also be shown in json format: + +```shell +dokku run:list node-js-app --format json +``` + +``` +[ + { + "name": "node-js-app.run.28689", + "state": "running", + "command": "\"/exec 'sleep 15'\"", + "created_at": "2022-08-03 05:47:44 +0000 UTC" + } +] +``` diff --git a/plugins/run/help-functions b/plugins/run/help-functions index e8e41f6c4..26934a197 100755 --- a/plugins/run/help-functions +++ b/plugins/run/help-functions @@ -29,6 +29,6 @@ fn-help-content() { cat < , Run a command in a new container using the current app image run:detached [-e|-env KEY=VALUE] [--no-tty] , Run a command in a new detached container using the current app image - run:list , List all run containers for an app + run:list [--format json|stdout] , List all run containers for an app help_content } diff --git a/plugins/run/internal-functions b/plugins/run/internal-functions index 933a9b1d8..e52730367 100755 --- a/plugins/run/internal-functions +++ b/plugins/run/internal-functions @@ -80,8 +80,32 @@ cmd-run-list() { declare desc="list all run containers for an app" declare cmd="run:list" [[ "$1" == "$cmd" ]] && shift 1 - declare APP="$1" + declare APP="" + local FORMAT="stdout" + while [[ $# -gt 0 ]]; do + case $1 in + --format=*) + local arg=$(printf "%s" "$1" | sed -E 's/(^--format=)//g') + FORMAT="$arg" + shift + ;; + --format) + if [[ ! $2 ]]; then + dokku_log_warn "expected $1 to have an argument" + break + fi + FORMAT="$2" + shift 2 + ;; + *) + APP="$1" + shift + ;; + esac + done + + verify_app_name "$APP" local DOKKU_SCHEDULER=$(get_app_scheduler "$APP") - plugn trigger scheduler-run-list "$DOKKU_SCHEDULER" "$APP" + plugn trigger scheduler-run-list "$DOKKU_SCHEDULER" "$APP" "$FORMAT" } diff --git a/plugins/scheduler-docker-local/scheduler-run-list b/plugins/scheduler-docker-local/scheduler-run-list index 1bea78c9c..2f4ad57b3 100755 --- a/plugins/scheduler-docker-local/scheduler-run-list +++ b/plugins/scheduler-docker-local/scheduler-run-list @@ -4,18 +4,21 @@ set -eo pipefail source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_AVAILABLE_PATH/config/functions" -trigger-scheduler-docker-local-scheduler-run() { - declare desc="runs command in container based on app image" - declare trigger="scheduler-run" - declare DOKKU_SCHEDULER="$1" APP="$2" +trigger-scheduler-docker-local-scheduler-run-list() { + declare desc="list run containers for an app" + declare trigger="scheduler-run-list" + declare DOKKU_SCHEDULER="$1" APP="$2" FORMAT="$3" - verify_app_name "$APP" if [[ "$DOKKU_SCHEDULER" != "docker-local" ]]; then return fi - dokku_log_info2_quiet "$APP run containers" - docker ps --filter "label=com.dokku.app-name=$APP" --filter "label=com.dokku.container-type=run" --format "table {{.Names}}\t{{.Command}}\t{{.RunningFor}}" + if [[ "$FORMAT" == "stdout" ]]; then + dokku_log_info2_quiet "$APP run containers" + "$DOCKER_BIN" container ls --all --no-trunc --filter "label=com.dokku.app-name=$APP" --filter "label=com.dokku.container-type=run" --format "table {{.Names}}\t{{.Command}}\t{{.RunningFor}}" + else + "$DOCKER_BIN" container ls --all --no-trunc --filter "label=com.dokku.app-name=$APP" --filter "label=com.dokku.container-type=run" --format "{{ json . }}" | jq -s -M 'map({name: .Names, state:.State, command:.Command, created_at:.CreatedAt})' + fi } -trigger-scheduler-docker-local-scheduler-run "$@" +trigger-scheduler-docker-local-scheduler-run-list "$@" diff --git a/tests/unit/run_2.bats b/tests/unit/run_2.bats index 607ea4a8c..5e7b4af3e 100644 --- a/tests/unit/run_2.bats +++ b/tests/unit/run_2.bats @@ -12,7 +12,7 @@ teardown() { global_teardown } -@test "(core) run" { +@test "(run) run" { deploy_app run /bin/bash -c "dokku run $TEST_APP echo $TEST_APP" @@ -26,7 +26,7 @@ teardown() { assert_failure } -@test "(core) run:detached" { +@test "(run) run:detached" { deploy_app RANDOM_RUN_CID="$(dokku --label=com.dokku.test-label=value run:detached $TEST_APP sleep 300)" @@ -52,7 +52,7 @@ teardown() { sleep 5 # wait for dokku cleanup to happen in the background } -@test "(core) run (with tty)" { +@test "(run) run (with tty)" { deploy_app run /bin/bash -c "dokku run $TEST_APP ls /app/null" echo "output: $output" @@ -60,7 +60,7 @@ teardown() { assert_success } -@test "(core) run (without tty)" { +@test "(run) run (without tty)" { deploy_app run /bin/bash -c ": |dokku run $TEST_APP ls /app/null" echo "output: $output" @@ -68,7 +68,7 @@ teardown() { assert_success } -@test "(core) run command from Procfile" { +@test "(run) run command from Procfile" { deploy_app run /bin/bash -c "dokku run $TEST_APP custom 'hi dokku' | tail -n 1" echo "output: $output" @@ -77,3 +77,60 @@ teardown() { assert_success assert_output 'hi dokku' } + +@test "(run) list" { + deploy_app + + run /bin/bash -c "dokku --quiet run:list $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku run:detached $TEST_APP sleep 300" + echo "output: $output" + echo "status: $status" + assert_success + + # includes headers + run /bin/bash -c "dokku --quiet run:list $TEST_APP | wc -l" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "2" + + run /bin/bash -c "dokku run:list $TEST_APP --format json | jq '. | length'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "1" + + run /bin/bash -c "dokku run:list --format json $TEST_APP | jq '. | length'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "1" + + run /bin/bash -c "dokku run:detached $TEST_APP sleep 300" + echo "output: $output" + echo "status: $status" + assert_success + + # includes headers + run /bin/bash -c "dokku --quiet run:list $TEST_APP | wc -l" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "3" + + run /bin/bash -c "dokku run:list $TEST_APP --format json | jq '. | length'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "2" + + run /bin/bash -c "dokku run:list --format json $TEST_APP | jq '. | length'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "2" +}