#!/usr/bin/env bash set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x source "$(dirname $0)/../common/functions" config_create () { [ -f $ENV_FILE ] || { touch $ENV_FILE } } config_styled_hash () { vars="$1" prefix="$2" longest="" while read -r word; do KEY=$(echo $word | cut -d"=" -f1) if [ ${#KEY} -gt ${#longest} ]; then longest=$KEY fi done <<< "$vars" while read -r word; do KEY=$(echo $word | cut -d"=" -f1) VALUE=$(echo $word | cut -d"=" -f2- | sed -e "s/^'//" -e "s/'$//" -e "s/\$$//g") num_zeros=$((${#longest} - ${#KEY})) zeros=" " while [ $num_zeros -gt 0 ]; do zeros="$zeros " num_zeros=$((num_zeros - 1)) done echo "$prefix$KEY:$zeros$VALUE" done <<< "$vars" } config_write() { ENV_TEMP="$1" ENV_FILE_TEMP="${ENV_FILE}.tmp" echo "$ENV_TEMP" | sed '/^$/d' | sort > $ENV_FILE_TEMP if ! cmp -s $ENV_FILE $ENV_FILE_TEMP; then cp -f $ENV_FILE_TEMP $ENV_FILE chmod 600 $ENV_FILE fi rm -f $ENV_FILE_TEMP } parse_config_args() { case "$2" in --global) ENV_FILE="$DOKKU_ROOT/ENV" DOKKU_CONFIG_TYPE="global" DOKKU_CONFIG_RESTART=false ;; --no-restart) APP="$3" ENV_FILE="$DOKKU_ROOT/$APP/ENV" DOKKU_CONFIG_RESTART=false DOKKU_CONFIG_TYPE="app" set -- "${@:1:1}" "${@:3}" esac APP=${APP:="$2"} ENV_FILE=${ENV_FILE:="$DOKKU_ROOT/$APP/ENV"} DOKKU_CONFIG_TYPE=${DOKKU_CONFIG_TYPE:="app"} DOKKU_CONFIG_RESTART=${DOKKU_CONFIG_RESTART:=true} if [[ "$DOKKU_CONFIG_TYPE" = "app" ]]; then if [[ -z $APP ]]; then echo "Please specify an app to run the command on" >&2 && exit 1 else verify_app_name "$2" fi fi export APP ENV_FILE DOKKU_CONFIG_TYPE DOKKU_CONFIG_RESTART } case "$1" in config) parse_config_args "$@" config_create [[ "$APP" ]] && DOKKU_CONFIG_TYPE=$APP [[ ! -s $ENV_FILE ]] && echo "no config vars for $DOKKU_CONFIG_TYPE" && exit 1 VARS=$(grep -Eo "export ([a-zA-Z_][a-zA-Z0-9_]*=.*)" $ENV_FILE | cut -d" " -f2-) for var in "$@"; do if [[ "$var" == "--shell" ]]; then echo $VARS exit 0 fi done dokku_log_info2_quiet "$DOKKU_CONFIG_TYPE config vars" config_styled_hash "$VARS" ;; config:get) parse_config_args "$@" if [[ -z $3 ]]; then echo "Usage: dokku config:get APP KEY" echo "Must specify KEY." exit 1 fi config_create if [[ ! -s $ENV_FILE ]] ; then exit 0 fi KEY="$3" grep -Eo "export ([a-zA-Z_][a-zA-Z0-9_]*=.*)" $ENV_FILE | grep "^export $KEY=" | cut -d"=" -f2- | sed -e "s/^'//" -e "s/'$//" ;; config:set) parse_config_args "$@" [[ "$2" = "--no-restart" ]] && set -- "${@:1:1}" "${@:3}" if [[ -z "${*:3}" ]]; then echo "Usage: dokku config:set APP KEY1=VALUE1 [KEY2=VALUE2 ...]" echo "Must specify KEY and VALUE to set." exit 1 fi config_create ENV_ADD="" ENV_TEMP=$(cat "${ENV_FILE}") RESTART_APP=false shift 2 for var; do if [[ $var != *"="* ]]; then echo "Usage: dokku config:set APP KEY1=VALUE1 [KEY2=VALUE2 ...]" echo "Must specify KEY and VALUE to set." exit 1 fi done for var; do KEY=$(echo ${var} | cut -d"=" -f1) VALUE=$(echo ${var} | cut -d"=" -f2-) if [[ $KEY =~ [a-zA-Z_][a-zA-Z0-9_]* ]]; then RESTART_APP=true ENV_TEMP=$(echo "${ENV_TEMP}" | sed "/^export $KEY=/ d") ENV_TEMP="${ENV_TEMP} export $KEY='$VALUE'" ENV_ADD=$(echo -e "${ENV_ADD}" | sed "/^$KEY=/ d") ENV_ADD="${ENV_ADD}$ ${var}" fi done ENV_ADD=$(echo "$ENV_ADD" | tail -n +2) #remove first empty line if [ $RESTART_APP ]; then dokku_log_info1 "Setting config vars" config_styled_hash "$ENV_ADD" " " config_write "$ENV_TEMP" fi if [[ "$DOKKU_CONFIG_RESTART" == "true" ]]; then dokku_log_info1 "Restarting app $APP" dokku ps:restart $APP fi ;; config:unset) parse_config_args "$@" [[ "$2" = "--no-restart" ]] && set -- "${@:1:1}" "${@:3}" if [[ -z $3 ]]; then echo "Usage: dokku config:unset APP KEY1 [KEY2 ...]" echo "Must specify KEY to unset." exit 1 fi config_create ENV_TEMP=$(cat "${ENV_FILE}") VARS="${*:3}" for var in $VARS; do dokku_log_info1 "Unsetting $var" ENV_TEMP=$(echo -e "${ENV_TEMP}" | sed "/^export $var=/ d") config_write "$ENV_TEMP" done if [[ "$DOKKU_CONFIG_RESTART" == "true" ]]; then dokku_log_info1 "Restarting app $APP" dokku ps:restart $APP fi ;; config:set-norestart) dokku_log_info2 "$1 is deprecated as of v0.3.22" shift 1 dokku config:set --no-restart "$@" ;; config:unset-norestart) dokku_log_info2 "$1 is deprecated as of v0.3.22" shift 1 dokku config:unset --no-restart "$@" ;; help | config:help) cat && cat<|--global) Display all global or app-specific config vars config:get (|--global) KEY Display a global or app-specific config value config:set (|--global) KEY1=VALUE1 [KEY2=VALUE2 ...] Set one or more config vars config:unset (|--global) KEY1 [KEY2 ...] Unset one or more config vars EOF ;; *) exit $DOKKU_NOT_IMPLEMENTED_EXIT ;; esac