From da4361583b3fe3128e5572e7cb463ab65b0c1961 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 20 May 2019 17:56:50 -0700 Subject: [PATCH 1/3] fix: reverse quotes for variable expansion Without reversing quotes, the variables are sometimes improperly expanded, resulting in files not being removed. --- plugins/app-json/internal-functions | 4 ++-- plugins/certs/subcommands/add | 2 +- plugins/certs/subcommands/generate | 2 +- plugins/git/functions | 2 +- plugins/nginx-vhosts/functions | 2 +- plugins/nginx-vhosts/internal-functions | 2 +- plugins/ps/functions | 4 ++-- plugins/scheduler-docker-local/check-deploy | 2 +- plugins/scheduler-docker-local/scheduler-inspect | 2 +- plugins/ssh-keys/functions | 2 +- plugins/ssh-keys/subcommands/add | 2 +- plugins/tar/functions | 2 +- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/plugins/app-json/internal-functions b/plugins/app-json/internal-functions index 1d2dc2341..dbb723b9b 100755 --- a/plugins/app-json/internal-functions +++ b/plugins/app-json/internal-functions @@ -10,7 +10,7 @@ get_phase_script() { declare IMAGE_TAG="$1" PHASE_SCRIPT_KEY="$2" local GET_PHASE_SCRIPT_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_get_phase_script.XXXX") local APP_JSON_FILE="$GET_PHASE_SCRIPT_TMP_WORK_DIR/app.json" - trap 'rm -rf "$GET_PHASE_SCRIPT_TMP_WORK_DIR" >/dev/null' RETURN INT TERM + trap "rm -rf '$GET_PHASE_SCRIPT_TMP_WORK_DIR' >/dev/null" RETURN INT TERM copy_from_image "$IMAGE" "app.json" "$GET_PHASE_SCRIPT_TMP_WORK_DIR" 2>/dev/null || true @@ -26,7 +26,7 @@ get_release_cmd() { declare APP="$1" IMAGE_TAG="$2" extract_procfile "$APP" "$IMAGE_TAG" >/dev/null - trap 'remove_procfile $APP' RETURN INT TERM EXIT + trap "remove_procfile $APP" RETURN INT TERM EXIT get_cmd_from_procfile "$APP" "release" "5000" } diff --git a/plugins/certs/subcommands/add b/plugins/certs/subcommands/add index a40c2d8f4..cb24c69cc 100755 --- a/plugins/certs/subcommands/add +++ b/plugins/certs/subcommands/add @@ -44,7 +44,7 @@ certs_set() { elif is_tar_import; then local CERTS_SET_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_certs_set.XXXX") pushd "$CERTS_SET_TMP_WORK_DIR" &>/dev/null - trap 'popd &>/dev/null || true; rm -rf $CERTS_SET_TMP_WORK_DIR >/dev/null' RETURN + trap "popd &>/dev/null || true; rm -rf '$CERTS_SET_TMP_WORK_DIR' >/dev/null" RETURN tar xvf - <&0 local CRT_FILE_SEARCH=$(find . -not -path '*/\.*' -type f | grep ".crt$") diff --git a/plugins/certs/subcommands/generate b/plugins/certs/subcommands/generate index 984e74518..a35ef408f 100755 --- a/plugins/certs/subcommands/generate +++ b/plugins/certs/subcommands/generate @@ -15,7 +15,7 @@ certs_generate_cmd() { if [[ ! -f "$APP_SSL_PATH/server.key" ]] && [[ ! -f "$APP_SSL_PATH/server.crt" ]]; then local CERTS_GENERATE_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_certs.XXXXXXXXX") pushd "$CERTS_GENERATE_TMP_WORK_DIR" >/dev/null - trap 'popd &>/dev/null || true; rm -rf "$CERTS_GENERATE_TMP_WORK_DIR" >/dev/null' INT TERM EXIT + trap "popd &>/dev/null || true; rm -rf '$CERTS_GENERATE_TMP_WORK_DIR' >/dev/null" INT TERM EXIT openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr diff --git a/plugins/git/functions b/plugins/git/functions index 922f2d4ea..b46971030 100755 --- a/plugins/git/functions +++ b/plugins/git/functions @@ -32,7 +32,7 @@ git_build_app_repo() { # clean up after ourselves local GIT_BUILD_APP_REPO_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_git.XXXX") - trap 'rm -rf "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" >/dev/null' RETURN INT TERM EXIT + trap "rm -rf '$GIT_BUILD_APP_REPO_TMP_WORK_DIR' >/dev/null" RETURN INT TERM EXIT local TMP_TAG="dokku/$REV" chmod 755 "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" diff --git a/plugins/nginx-vhosts/functions b/plugins/nginx-vhosts/functions index 7d3a15ea7..0c41d6093 100755 --- a/plugins/nginx-vhosts/functions +++ b/plugins/nginx-vhosts/functions @@ -304,7 +304,7 @@ nginx_build_config() { local NGINX_CONF=$(mktemp --tmpdir="${NGINX_BUILD_CONFIG_TMP_WORK_DIR}" "nginx.conf.XXXXXX") local CUSTOM_NGINX_TEMPLATE="$NGINX_BUILD_CONFIG_TMP_WORK_DIR/$NGINX_TEMPLATE_NAME" # shellcheck disable=SC2086 - trap 'rm -rf $NGINX_CONF $NGINX_BUILD_CONFIG_TMP_WORK_DIR >/dev/null' RETURN INT TERM EXIT + trap "rm -rf '$NGINX_CONF' '$NGINX_BUILD_CONFIG_TMP_WORK_DIR' >/dev/null" RETURN INT TERM EXIT get_custom_nginx_template "$APP" "$CUSTOM_NGINX_TEMPLATE" 2>/dev/null if [[ -f "$CUSTOM_NGINX_TEMPLATE" ]]; then diff --git a/plugins/nginx-vhosts/internal-functions b/plugins/nginx-vhosts/internal-functions index 2b413c1c3..ff4fa6e1a 100755 --- a/plugins/nginx-vhosts/internal-functions +++ b/plugins/nginx-vhosts/internal-functions @@ -28,7 +28,7 @@ nginx_vhosts_is_valid_nginx_config_func() { declare APP="$1" local VALIDATE_TEMPLATE="$PLUGIN_AVAILABLE_PATH/nginx-vhosts/templates/validate.conf.sigil" local TMP_OUTPUT=$(mktemp "/tmp/${FUNCNAME[0]}.XXXX") - trap 'rm -rf "$TMP_OUTPUT" >/dev/null' RETURN INT TERM EXIT + trap "rm -rf '$TMP_OUTPUT' >/dev/null" RETURN INT TERM EXIT sigil -f "$VALIDATE_TEMPLATE" NGINX_CONF="$DOKKU_ROOT/$APP/nginx.conf" | cat -s >"$TMP_OUTPUT" sudo "$NGINX_LOCATION" -t -c "$TMP_OUTPUT" 2>/dev/null diff --git a/plugins/ps/functions b/plugins/ps/functions index f2de8ed18..b7f4dacb3 100755 --- a/plugins/ps/functions +++ b/plugins/ps/functions @@ -72,7 +72,7 @@ generate_scale_file() { dokku_log_info1_quiet "DOKKU_SCALE file not found in app image. Generating one based on Procfile..." local GENERATE_SCALE_FILE_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_scale.XXXX") - trap 'rm -rf "$GENERATE_SCALE_FILE_TMP_WORK_DIR" >/dev/null' RETURN + trap "rm -rf '$GENERATE_SCALE_FILE_TMP_WORK_DIR' >/dev/null" RETURN if [[ -f $DOKKU_PROCFILE ]]; then while read -r line || [[ -n "$line" ]]; do @@ -99,7 +99,7 @@ set_scale() { shift 1 extract_procfile "$APP" "$IMAGE_TAG" >/dev/null - trap 'remove_procfile $APP' RETURN INT TERM EXIT + trap "remove_procfile $APP" RETURN INT TERM EXIT local SCALE_SETTINGS=("$@") for procscale in "${SCALE_SETTINGS[@]}"; do diff --git a/plugins/scheduler-docker-local/check-deploy b/plugins/scheduler-docker-local/check-deploy index ba136186e..41cb4fe10 100755 --- a/plugins/scheduler-docker-local/check-deploy +++ b/plugins/scheduler-docker-local/check-deploy @@ -99,7 +99,7 @@ scheduler-docker-local-check-deploy() { dokku_log_info2_quiet "end $APP $DOKKU_APP_CONTAINER_TYPE container output" fi } - trap 'checks_check_deploy_cleanup $DOKKU_APP_CONTAINER_ID' RETURN INT TERM EXIT + trap "checks_check_deploy_cleanup $DOKKU_APP_CONTAINER_ID" RETURN INT TERM EXIT if [[ ! -s "${CHECK_DEPLOY_TMP_WORK_DIR}/CHECKS" ]] || [[ "$DOKKU_APP_CONTAINER_TYPE" != "web" ]]; then # We allow custom check for web instances only diff --git a/plugins/scheduler-docker-local/scheduler-inspect b/plugins/scheduler-docker-local/scheduler-inspect index 77916e379..4bfa05c13 100755 --- a/plugins/scheduler-docker-local/scheduler-inspect +++ b/plugins/scheduler-docker-local/scheduler-inspect @@ -14,7 +14,7 @@ scheduler-docker-local-scheduler-inspect() { fi local TMP_INSPECT_CMD=$(mktemp "/tmp/${FUNCNAME[0]}.XXXX") - trap 'rm -rf "$TMP_INSPECT_CMD" >/dev/null' RETURN INT TERM EXIT + trap "rm -rf '$TMP_INSPECT_CMD' >/dev/null" RETURN INT TERM EXIT cat >"$TMP_INSPECT_CMD" </dev/null' RETURN INT TERM EXIT + trap "rm -rf '$TMP_KEY_FILE' >/dev/null" RETURN INT TERM EXIT while read -r key; do line=$((line + 1)) diff --git a/plugins/ssh-keys/subcommands/add b/plugins/ssh-keys/subcommands/add index 89242b8c3..b533a611c 100755 --- a/plugins/ssh-keys/subcommands/add +++ b/plugins/ssh-keys/subcommands/add @@ -11,7 +11,7 @@ add_keys() { declare NAME="$1" KEY_FILE="$2" local TMP_KEY_FILE TMP_KEY_FILE=$(mktemp "/tmp/${FUNCNAME[0]}.XXXX") - trap 'rm -rf "$TMP_KEY_FILE" >/dev/null' RETURN INT TERM EXIT + trap "rm -rf '$TMP_KEY_FILE' >/dev/null" RETURN INT TERM EXIT if [[ -n "$KEY_FILE" ]]; then true diff --git a/plugins/tar/functions b/plugins/tar/functions index d2c5e6624..a38f46633 100755 --- a/plugins/tar/functions +++ b/plugins/tar/functions @@ -12,7 +12,7 @@ tar_build() { # clean up after ourselves local TAR_BUILD_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_tar.XXXX") - trap 'rm -rf "$TAR_BUILD_TMP_WORK_DIR" >/dev/null' RETURN INT TERM EXIT + trap "rm -rf '$TAR_BUILD_TMP_WORK_DIR' >/dev/null" RETURN INT TERM EXIT # extract tar file chmod 755 "$TAR_BUILD_TMP_WORK_DIR" From c8a491ed7f8712d10be8335bcb24888fca462fcf Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 20 May 2019 17:57:13 -0700 Subject: [PATCH 2/3] fix: only use the RETURN signal for the suppress file removal Closes #3473 --- plugins/common/functions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/common/functions b/plugins/common/functions index ae16049dc..94e167534 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -1080,7 +1080,7 @@ suppress_output() { declare desc="suppress all output from a given command unless there is an error" local TMP_COMMAND_OUTPUT TMP_COMMAND_OUTPUT=$(mktemp "/tmp/${FUNCNAME[0]}.XXXX") - trap 'rm -rf "$TMP_COMMAND_OUTPUT" >/dev/null' RETURN INT TERM EXIT + trap "rm -rf '$TMP_COMMAND_OUTPUT' >/dev/null" RETURN "$@" >"$TMP_COMMAND_OUTPUT" 2>&1 || { local exit_code="$?" From 1b92f4a97e3b22118b49c4d6b8456c2fb8cc4d9a Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 20 May 2019 18:00:14 -0700 Subject: [PATCH 3/3] chore: standardize how temporary files are named --- plugins/app-json/internal-functions | 2 +- plugins/certs/subcommands/add | 2 +- plugins/certs/subcommands/generate | 2 +- plugins/common/functions | 2 +- plugins/git/functions | 2 +- plugins/nginx-vhosts/functions | 4 ++-- plugins/nginx-vhosts/internal-functions | 2 +- plugins/ps/functions | 2 +- plugins/scheduler-docker-local/check-deploy | 2 +- plugins/scheduler-docker-local/scheduler-inspect | 2 +- plugins/ssh-keys/functions | 2 +- plugins/ssh-keys/subcommands/add | 2 +- plugins/tar/functions | 2 +- 13 files changed, 14 insertions(+), 14 deletions(-) diff --git a/plugins/app-json/internal-functions b/plugins/app-json/internal-functions index dbb723b9b..72cee342c 100755 --- a/plugins/app-json/internal-functions +++ b/plugins/app-json/internal-functions @@ -8,7 +8,7 @@ source "$PLUGIN_AVAILABLE_PATH/ps/functions" get_phase_script() { declare desc="extracts app.json from app image and returns the appropriate json key/value" declare IMAGE_TAG="$1" PHASE_SCRIPT_KEY="$2" - local GET_PHASE_SCRIPT_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_get_phase_script.XXXX") + local GET_PHASE_SCRIPT_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku-${FUNCNAME[0]}.XXXX") local APP_JSON_FILE="$GET_PHASE_SCRIPT_TMP_WORK_DIR/app.json" trap "rm -rf '$GET_PHASE_SCRIPT_TMP_WORK_DIR' >/dev/null" RETURN INT TERM diff --git a/plugins/certs/subcommands/add b/plugins/certs/subcommands/add index cb24c69cc..03f43f950 100755 --- a/plugins/certs/subcommands/add +++ b/plugins/certs/subcommands/add @@ -42,7 +42,7 @@ certs_set() { # importing from file true elif is_tar_import; then - local CERTS_SET_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_certs_set.XXXX") + local CERTS_SET_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku-${FUNCNAME[0]}.XXXX") pushd "$CERTS_SET_TMP_WORK_DIR" &>/dev/null trap "popd &>/dev/null || true; rm -rf '$CERTS_SET_TMP_WORK_DIR' >/dev/null" RETURN tar xvf - <&0 diff --git a/plugins/certs/subcommands/generate b/plugins/certs/subcommands/generate index a35ef408f..7456481b1 100755 --- a/plugins/certs/subcommands/generate +++ b/plugins/certs/subcommands/generate @@ -13,7 +13,7 @@ certs_generate_cmd() { local APP_SSL_PATH="$DOKKU_ROOT/$APP/tls" if [[ ! -f "$APP_SSL_PATH/server.key" ]] && [[ ! -f "$APP_SSL_PATH/server.crt" ]]; then - local CERTS_GENERATE_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_certs.XXXXXXXXX") + local CERTS_GENERATE_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku-${FUNCNAME[0]}.XXXX") pushd "$CERTS_GENERATE_TMP_WORK_DIR" >/dev/null trap "popd &>/dev/null || true; rm -rf '$CERTS_GENERATE_TMP_WORK_DIR' >/dev/null" INT TERM EXIT diff --git a/plugins/common/functions b/plugins/common/functions index 94e167534..08d921071 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -1079,7 +1079,7 @@ release_advisory_lock() { suppress_output() { declare desc="suppress all output from a given command unless there is an error" local TMP_COMMAND_OUTPUT - TMP_COMMAND_OUTPUT=$(mktemp "/tmp/${FUNCNAME[0]}.XXXX") + TMP_COMMAND_OUTPUT=$(mktemp "/tmp/dokku-${FUNCNAME[0]}.XXXX") trap "rm -rf '$TMP_COMMAND_OUTPUT' >/dev/null" RETURN "$@" >"$TMP_COMMAND_OUTPUT" 2>&1 || { diff --git a/plugins/git/functions b/plugins/git/functions index b46971030..163e0f1bc 100755 --- a/plugins/git/functions +++ b/plugins/git/functions @@ -31,7 +31,7 @@ git_build_app_repo() { verify_app_name "$APP" # clean up after ourselves - local GIT_BUILD_APP_REPO_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_git.XXXX") + local GIT_BUILD_APP_REPO_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku-${FUNCNAME[0]}.XXXX") trap "rm -rf '$GIT_BUILD_APP_REPO_TMP_WORK_DIR' >/dev/null" RETURN INT TERM EXIT local TMP_TAG="dokku/$REV" diff --git a/plugins/nginx-vhosts/functions b/plugins/nginx-vhosts/functions index 0c41d6093..6de04743f 100755 --- a/plugins/nginx-vhosts/functions +++ b/plugins/nginx-vhosts/functions @@ -300,8 +300,8 @@ nginx_build_config() { done local PROXY_UPSTREAM_PORTS="$(echo "$PROXY_UPSTREAM_PORTS" | xargs)" - local NGINX_BUILD_CONFIG_TMP_WORK_DIR=$(mktemp -d /tmp/dokku_nginx_template.XXXXX) - local NGINX_CONF=$(mktemp --tmpdir="${NGINX_BUILD_CONFIG_TMP_WORK_DIR}" "nginx.conf.XXXXXX") + local NGINX_BUILD_CONFIG_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku-${FUNCNAME[0]}.XXXX") + local NGINX_CONF=$(mktemp --tmpdir="${NGINX_BUILD_CONFIG_TMP_WORK_DIR}" "nginx.conf.XXXX") local CUSTOM_NGINX_TEMPLATE="$NGINX_BUILD_CONFIG_TMP_WORK_DIR/$NGINX_TEMPLATE_NAME" # shellcheck disable=SC2086 trap "rm -rf '$NGINX_CONF' '$NGINX_BUILD_CONFIG_TMP_WORK_DIR' >/dev/null" RETURN INT TERM EXIT diff --git a/plugins/nginx-vhosts/internal-functions b/plugins/nginx-vhosts/internal-functions index ff4fa6e1a..587a2722f 100755 --- a/plugins/nginx-vhosts/internal-functions +++ b/plugins/nginx-vhosts/internal-functions @@ -27,7 +27,7 @@ nginx_vhosts_is_valid_nginx_config_func() { declare desc="checks if an app has a valid nginx config" declare APP="$1" local VALIDATE_TEMPLATE="$PLUGIN_AVAILABLE_PATH/nginx-vhosts/templates/validate.conf.sigil" - local TMP_OUTPUT=$(mktemp "/tmp/${FUNCNAME[0]}.XXXX") + local TMP_OUTPUT=$(mktemp "/tmp/dokku-${FUNCNAME[0]}.XXXX") trap "rm -rf '$TMP_OUTPUT' >/dev/null" RETURN INT TERM EXIT sigil -f "$VALIDATE_TEMPLATE" NGINX_CONF="$DOKKU_ROOT/$APP/nginx.conf" | cat -s >"$TMP_OUTPUT" diff --git a/plugins/ps/functions b/plugins/ps/functions index b7f4dacb3..627c2343c 100755 --- a/plugins/ps/functions +++ b/plugins/ps/functions @@ -71,7 +71,7 @@ generate_scale_file() { if [[ ! -f $DOKKU_SCALE_FILE ]]; then dokku_log_info1_quiet "DOKKU_SCALE file not found in app image. Generating one based on Procfile..." - local GENERATE_SCALE_FILE_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_scale.XXXX") + local GENERATE_SCALE_FILE_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku-${FUNCNAME[0]}.XXXX") trap "rm -rf '$GENERATE_SCALE_FILE_TMP_WORK_DIR' >/dev/null" RETURN if [[ -f $DOKKU_PROCFILE ]]; then diff --git a/plugins/scheduler-docker-local/check-deploy b/plugins/scheduler-docker-local/check-deploy index 41cb4fe10..721d9c0e6 100755 --- a/plugins/scheduler-docker-local/check-deploy +++ b/plugins/scheduler-docker-local/check-deploy @@ -84,7 +84,7 @@ scheduler-docker-local-check-deploy() { # docker cp exits with status 1 when run as non-root user when it tries to chown the file # after successfully copying the file. Thus, we suppress stderr. # ref: https://github.com/dotcloud/docker/issues/3986 - local CHECK_DEPLOY_TMP_WORK_DIR=$(mktemp -d /tmp/dokku_CHECKS.XXXXX) + local CHECK_DEPLOY_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku-${FUNCNAME[0]}.XXXX") docker cp "$DOKKU_APP_CONTAINER_ID:/app/CHECKS" "$CHECK_DEPLOY_TMP_WORK_DIR" 2>/dev/null || true local FILENAME=${CHECK_DEPLOY_TMP_WORK_DIR}/CHECKS diff --git a/plugins/scheduler-docker-local/scheduler-inspect b/plugins/scheduler-docker-local/scheduler-inspect index 4bfa05c13..1a4eb6719 100755 --- a/plugins/scheduler-docker-local/scheduler-inspect +++ b/plugins/scheduler-docker-local/scheduler-inspect @@ -13,7 +13,7 @@ scheduler-docker-local-scheduler-inspect() { return fi - local TMP_INSPECT_CMD=$(mktemp "/tmp/${FUNCNAME[0]}.XXXX") + local TMP_INSPECT_CMD=$(mktemp "/tmp/dokku-${FUNCNAME[0]}.XXXX") trap "rm -rf '$TMP_INSPECT_CMD' >/dev/null" RETURN INT TERM EXIT cat >"$TMP_INSPECT_CMD" </dev/null" RETURN INT TERM EXIT while read -r key; do diff --git a/plugins/ssh-keys/subcommands/add b/plugins/ssh-keys/subcommands/add index b533a611c..dd3ba7afc 100755 --- a/plugins/ssh-keys/subcommands/add +++ b/plugins/ssh-keys/subcommands/add @@ -10,7 +10,7 @@ add_keys() { [[ "$1" == "$cmd" ]] && shift 1 declare NAME="$1" KEY_FILE="$2" local TMP_KEY_FILE - TMP_KEY_FILE=$(mktemp "/tmp/${FUNCNAME[0]}.XXXX") + TMP_KEY_FILE=$(mktemp "/tmp/dokku-${FUNCNAME[0]}.XXXX") trap "rm -rf '$TMP_KEY_FILE' >/dev/null" RETURN INT TERM EXIT if [[ -n "$KEY_FILE" ]]; then diff --git a/plugins/tar/functions b/plugins/tar/functions index a38f46633..c399ecc52 100755 --- a/plugins/tar/functions +++ b/plugins/tar/functions @@ -11,7 +11,7 @@ tar_build() { shift 1 # clean up after ourselves - local TAR_BUILD_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_tar.XXXX") + local TAR_BUILD_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku-${FUNCNAME[0]}.XXXX") trap "rm -rf '$TAR_BUILD_TMP_WORK_DIR' >/dev/null" RETURN INT TERM EXIT # extract tar file