From dad5db4e9b10115cec6d68b4bb651e69225c16f8 Mon Sep 17 00:00:00 2001 From: Alex Quick Date: Sun, 17 Mar 2019 19:14:14 -0400 Subject: [PATCH] [feature] add --env to dokku run `dokku run [ --env KEY=VALUE | -e KEY=VALUE ] app command` __note__ this changes the scheduler-run trigger to expect the following arguments: scheduler_name, app_name, env_count, env_0, ..., env_n, app_arg_0, ..., app_arg_n resolves: dokku/dokku#3291 --- docs/deployment/one-off-processes.md | 5 ++- plugins/00_dokku-standard/commands | 2 +- plugins/00_dokku-standard/subcommands/run | 32 ++++++++++++++++++-- plugins/scheduler-docker-local/scheduler-run | 29 ++++++++++-------- tests/unit/40_core_2.bats | 12 ++++++++ 5 files changed, 63 insertions(+), 17 deletions(-) diff --git a/docs/deployment/one-off-processes.md b/docs/deployment/one-off-processes.md index 719adbb46..79dfb5a16 100644 --- a/docs/deployment/one-off-processes.md +++ b/docs/deployment/one-off-processes.md @@ -5,7 +5,7 @@ Sometimes you need to either inspect running containers or run a one-off command ## Run a command in an app environment ``` -run # Run a command in a new container using the current application image +run [ --env KEY=VALUE | -e KEY=VALUE ] # Run a command in a new container using the current application image ``` The `run` command can be used to run a one-off process for a specific command. This will start a new container and run the desired command within that container. Note that this container will be stay around even after command completes. The container will be the same container as was used to start the currently deployed application. @@ -13,6 +13,9 @@ The `run` command can be used to run a one-off process for a specific command. T ```shell # runs `ls -lah` in the `/app` directory of the application `node-js-app` dokku run node-js-app ls -lah + +# optionally, run can be passed custom environment variables +dokku run --env "NODE_ENV=development" --env "PATH=/custom/path" node-js-app npm run mytask ``` The `run` command can also be used to run a command defined in your Procfile: diff --git a/plugins/00_dokku-standard/commands b/plugins/00_dokku-standard/commands index 718ff096b..551d5a405 100755 --- a/plugins/00_dokku-standard/commands +++ b/plugins/00_dokku-standard/commands @@ -9,7 +9,7 @@ case "$1" in help_content_func() { declare desc="return standard plugin help content" cat < , Run a command in a new container using the current application image + run [--env KEY=VALUE] , Run a command in a new container using the current application image trace [on/off], Enable dokku tracing url , Show the first URL for an application (compatibility) urls , Show all URLs for an application diff --git a/plugins/00_dokku-standard/subcommands/run b/plugins/00_dokku-standard/subcommands/run index a8fc3b2fc..22b87748c 100755 --- a/plugins/00_dokku-standard/subcommands/run +++ b/plugins/00_dokku-standard/subcommands/run @@ -6,12 +6,38 @@ source "$PLUGIN_AVAILABLE_PATH/config/functions" dokku_run_cmd() { declare desc="runs command in container based on app image" - declare cmd="run" APP="$2" + declare cmd="run" APP="" + shift + + declare -a RUN_ENV + RUN_ENV=() + while [[ $# -gt 0 ]]; do + case $1 in + -e=* | --env=*) + local arg=$(printf "%s" "$1" | sed -E 's/(^-e=)|(^--env=)//g') + RUN_ENV+=("$arg") + shift + ;; + -e | --env) + if [[ ! $2 ]]; then + dokku_log_warn "expected $1 to have an argument" + break + fi + RUN_ENV+=("$2") + shift 2 + ;; + *) + APP="$1" + shift + break + ;; + esac + done + verify_app_name "$APP" - shift 2 local DOKKU_SCHEDULER=$(get_app_scheduler "$APP") - plugn trigger scheduler-run "$DOKKU_SCHEDULER" "$APP" "$@" + plugn trigger scheduler-run "$DOKKU_SCHEDULER" "$APP" "${#RUN_ENV[@]}" "${RUN_ENV[@]}" "$@" } dokku_run_cmd "$@" diff --git a/plugins/scheduler-docker-local/scheduler-run b/plugins/scheduler-docker-local/scheduler-run index 0b3a228ff..3b6e75121 100755 --- a/plugins/scheduler-docker-local/scheduler-run +++ b/plugins/scheduler-docker-local/scheduler-run @@ -8,8 +8,11 @@ source "$PLUGIN_AVAILABLE_PATH/ps/functions" scheduler-docker-local-scheduler-run() { declare desc="runs command in container based on app image" declare trigger="scheduler-docker-local scheduler-run" - declare DOKKU_SCHEDULER="$1" APP="$2" - shift 2 + declare DOKKU_SCHEDULER="$1" APP="$2" ENV_COUNT="$3" + shift 3 + + declare RUN_ENV=("${@:1:ENV_COUNT}") + shift "$ENV_COUNT" if [[ "$DOKKU_SCHEDULER" != "docker-local" ]]; then return @@ -25,23 +28,25 @@ scheduler-docker-local-scheduler-run() { fi local DOCKER_ARGS=$(: | plugn trigger docker-args-run "$APP" "$IMAGE_TAG") - [[ "$DOKKU_TRACE" ]] && local DOCKER_ARGS+=" -e TRACE=true " + [[ "$DOKKU_TRACE" ]] && DOCKER_ARGS+=" -e TRACE=true " local IMAGE_SOURCE_TYPE="dockerfile" is_image_herokuish_based "$IMAGE" && IMAGE_SOURCE_TYPE="herokuish" DOCKER_ARGS+=$(: | plugn trigger docker-args-process-run "$APP" "$IMAGE_TAG" "$IMAGE_SOURCE_TYPE" "$PHASE_SCRIPT_KEY") - - declare -a ARG_ARRAY - eval "ARG_ARRAY=($DOCKER_ARGS)" - - local DOKKU_RUN_OPTS=" -e DYNO=run.$RANDOM" + DOCKER_ARGS+=" -e DYNO=run.$RANDOM" if [[ "$DOKKU_RM_CONTAINER" ]]; then - DOKKU_RUN_OPTS+=" --rm" + DOCKER_ARGS+=" --rm" elif [[ "$DOKKU_DETACH_CONTAINER" ]]; then - DOKKU_RUN_OPTS+=" --detach" + DOCKER_ARGS+=" --detach" fi + has_tty && DOCKER_ARGS+=" -i -t" + # the output of docker-args-run is possibly quoted/escaped so eval to normalize + declare -a DOCKER_ARGS_ARRAY + eval "DOCKER_ARGS_ARRAY=($DOCKER_ARGS)" + for env_pair in "${RUN_ENV[@]}"; do + DOCKER_ARGS_ARRAY+=("--env=$env_pair") + done - has_tty && DOKKU_RUN_OPTS+=" -i -t" [[ "$IMAGE_SOURCE_TYPE" == "herokuish" ]] && local EXEC_CMD="/exec" DOKKU_QUIET_OUTPUT=1 extract_procfile "$APP" @@ -56,7 +61,7 @@ scheduler-docker-local-scheduler-run() { fi # shellcheck disable=SC2086 - docker run $DOKKU_GLOBAL_RUN_ARGS $DOKKU_RUN_OPTS "${ARG_ARRAY[@]}" $IMAGE $EXEC_CMD "$@" + docker run $DOKKU_GLOBAL_RUN_ARGS "${DOCKER_ARGS_ARRAY[@]}" $IMAGE $EXEC_CMD "$@" } scheduler-docker-local-scheduler-run "$@" diff --git a/tests/unit/40_core_2.bats b/tests/unit/40_core_2.bats index 22ec06ca2..ffd74ff6b 100644 --- a/tests/unit/40_core_2.bats +++ b/tests/unit/40_core_2.bats @@ -39,6 +39,18 @@ assert_url() { assert_success } +@test "(core) run (with --env / -e)" { + deploy_app + run /bin/bash -c "dokku run --env TEST=testvalue -e TEST2=testvalue2 $TEST_APP env | egrep '^TEST=testvalue'" + echo "output: $output" + echo "status: $status" + + run /bin/bash -c "dokku run --env TEST=testvalue -e TEST2=testvalue2 $TEST_APP env | egrep '^TEST2=testvalue2'" + echo "output: $output" + echo "status: $status" + assert_success +} + @test "(core) unknown command" { run /bin/bash -c "dokku fakecommand" echo "output: $output"