Merge pull request #8498 from dokku/migrate-env-vars-to-properties

Migrate environment variables to plugin properties
This commit is contained in:
Jose Diaz-Gonzalez
2026-04-26 04:05:59 -04:00
committed by GitHub
53 changed files with 648 additions and 508 deletions

View File

@@ -98,26 +98,34 @@ The following config variables have special meanings and can be set in a variety
| `DOKKU_QUIET_OUTPUT` | none | `--quiet` flag | Silences certain header output for `dokku` commands. |
| `DOKKU_RM_CONTAINER` | none | `dokku config:set` <br /> | Deprecated: Whether to keep `dokku run` containers around or not. |
| `DOKKU_TRACE` | none | `dokku trace:on` <br /> `dokku trace:off` <br /> `--trace` flag | Turn on very verbose debugging. |
| `DOKKU_APP_PROXY_TYPE` | `nginx` | `dokku proxy:set` | |
| `DOKKU_APP_RESTORE` | `1` | `dokku config:set` <br /> `dokku ps:stop` | |
| `DOKKU_APP_SHELL` | `/bin/bash` | `dokku config:set` | Allows users to change the default shell used by Dokku for `dokku enter` and execution of deployment tasks. |
| `DOKKU_CHECKS_DISABLED` | none | `dokku checks:disable` | |
| `DOKKU_CHECKS_ENABLED` | none | `dokku checks:enable` | |
| `DOKKU_CHECKS_SKIPPED` | none | `dokku checks:skip` | |
| `DOKKU_CHECKS_WAIT` | `5` | `dokku config:set` | Wait this many seconds for the container to start before running checks.
| `DOKKU_CHECKS_TIMEOUT` | `30` | `dokku config:set` | Wait this many seconds for each response before marking it as a failure.
| `DOKKU_CHECKS_ATTEMPTS` | `5` | `dokku config:set` | Number of retries for to run for a specific check before marking it as a failure
| `DOKKU_DEFAULT_CHECKS_WAIT` | `10` | `dokku config:set` | If no user-defined checks are specified - or if the process being checked is not a `web` process - this is the period of time Dokku will wait before checking that a container is still running. |
| `DOKKU_DISABLE_PROXY` | none | `dokku proxy:disable` <br /> `dokku proxy:enable` | Disables the proxy in front of your application, resulting in publicly routing the docker container. |
| `DOKKU_DISABLE_APP_AUTOCREATION` | none | `dokku config:set` | Disables automatic creation of a non-existent app on deploy. |
| `DOKKU_DOCKERFILE_START_CMD` | none | `dokku config:set` | |
| `DOKKU_PARALLEL_ARGUMENTS`. | none | `dokku config:set` | Allows passing custom arguments to parallel for `ps:*all` commands |
| `DOKKU_PROXY_PORT` | automatically assigned | `/etc/environment` <br /> `~dokku/.dokkurc` <br /> `~dokku/.dokkurc/*` <br /> `dokku config:set` | |
| `DOKKU_PROXY_SSL_PORT` | automatically assigned | `/etc/environment` <br /> `~dokku/.dokkurc` <br /> `~dokku/.dokkurc/*` <br /> `dokku config:set` | |
| `DOKKU_SKIP_ALL_CHECKS` | none | `dokku config:set` | |
| `DOKKU_SKIP_CLEANUP` | | `/etc/environment` <br /> `~dokku/.dokkurc` <br /> `~dokku/.dokkurc/*` | When a deploy is triggered, if this is set to a non-empty value, then old docker containers and images will not be removed. |
| `DOKKU_SKIP_DEFAULT_CHECKS` | | `dokku config:set` | |
| `DOKKU_SKIP_DEPLOY` | | `dokku config:set` | |
| `DOKKU_START_CMD` | none | `dokku config:set` | Command to run instead of `/start $PROC_TYPE` |
| `DOKKU_SKIP_CLEANUP` | | `/etc/environment` <br /> `~dokku/.dokkurc` <br /> `~dokku/.dokkurc/*` | When a deploy is triggered, if this is set to a non-empty value, then old docker containers and images will not be removed. Falls back to the `builder:set skip-cleanup` property. |
| `DOKKU_SYSTEM_GROUP` | `dokku` | `/etc/environment` <br /> `~dokku/.dokkurc` <br /> `~dokku/.dokkurc/*` | System group to chown files as. |
| `DOKKU_SYSTEM_USER` | `dokku` | `/etc/environment` <br /> `~dokku/.dokkurc` <br /> `~dokku/.dokkurc/*` | System user to chown files as. |
## Deprecated Environment Variables
The following environment variables have been migrated to plugin properties. Existing values will be automatically migrated on upgrade. Use the corresponding property commands going forward.
| Deprecated Env Var | Replacement Command |
|---|---|
| `DOKKU_APP_PROXY_TYPE` | `dokku proxy:set <app> type <value>` |
| `DOKKU_APP_RESTORE` | `dokku ps:set <app> restore <true\|false>` |
| `DOKKU_APP_SHELL` | `dokku scheduler:set <app> shell <value>` |
| `DOKKU_CHECKS_DISABLED` | `dokku checks:disable <app> [proctypes]` |
| `DOKKU_CHECKS_ENABLED` | `dokku checks:enable <app> [proctypes]` |
| `DOKKU_CHECKS_SKIPPED` | `dokku checks:skip <app> [proctypes]` |
| `DOKKU_CHECKS_WAIT` | `dokku checks:set <app> wait <value>` |
| `DOKKU_CHECKS_TIMEOUT` | `dokku checks:set <app> timeout <value>` |
| `DOKKU_CHECKS_ATTEMPTS` | `dokku checks:set <app> attempts <value>` |
| `DOKKU_DEFAULT_CHECKS_WAIT` | `dokku checks:set --global default-wait <value>` |
| `DOKKU_DISABLE_APP_AUTOCREATION` | `dokku apps:set --global disable-autocreation <true\|false>` |
| `DOKKU_DISABLE_PROXY` | `dokku proxy:disable <app>` / `dokku proxy:enable <app>` |
| `DOKKU_DOCKERFILE_START_CMD` | `dokku ps:set <app> dockerfile-start-cmd <value>` |
| `DOKKU_PARALLEL_ARGUMENTS` | Removed. No longer supported. |
| `DOKKU_PROXY_PORT` | `dokku proxy:set <app> proxy-port <value>` |
| `DOKKU_PROXY_SSL_PORT` | `dokku proxy:set <app> proxy-ssl-port <value>` |
| `DOKKU_SKIP_ALL_CHECKS` | `dokku checks:disable <app>` |
| `DOKKU_SKIP_CLEANUP` | `dokku builder:set <app> skip-cleanup <true\|false>` |
| `DOKKU_SKIP_DEFAULT_CHECKS` | `dokku checks:skip <app>` |
| `DOKKU_SKIP_DEPLOY` | `dokku ps:set <app> skip-deploy <true\|false>` |
| `DOKKU_START_CMD` | `dokku ps:set <app> start-cmd <value>` |

View File

@@ -143,11 +143,11 @@ dokku letsencrypt:cron-job --add
### Skipping deployment
If you only want to rebuild and tag a container, you can skip the deployment phase by setting `$DOKKU_SKIP_DEPLOY` to `true` by running:
If you only want to rebuild and tag a container, you can skip the deployment phase by setting the `skip-deploy` property to `true`:
``` shell
# on the Dokku host
dokku config:set ruby-getting-started DOKKU_SKIP_DEPLOY=true
dokku ps:set ruby-getting-started skip-deploy true
```
### Redeploying or restarting

View File

@@ -40,17 +40,17 @@ Defaults to `60`.
You can set the `stop-timeout-seconds` property on the `ps` plugin to change this value (default: `30`). See the [process management documentation](/docs/processes/process-management.md#changing-process-management-settings) for more information.
## Configuring check settings using the `config` plugin
## Configuring check settings
There are certain settings that can be configured via environment variables:
There are certain settings that can be configured via the `checks` plugin properties:
- `DOKKU_DEFAULT_CHECKS_WAIT`: (default: `10`) If no user-defined checks are specified - or if the process being checked is not a `web` process - this is the period of time Dokku will wait before checking that a container is still running.
- `default-wait`: (default: `10`) If no user-defined checks are specified - or if the process being checked is not a `web` process - this is the period of time Dokku will wait before checking that a container is still running. Set globally via `dokku checks:set --global default-wait <value>`.
The following settings may also be specified in the `app.json` file, though are available as environment variables in order to ease application reuse.
The following settings may also be specified in the `app.json` file, though are available as properties in order to ease application reuse.
- `DOKKU_CHECKS_WAIT`: (default: `5`) Wait this many seconds for the container to start before running checks.
- `DOKKU_CHECKS_TIMEOUT`: (default: `30`) Wait this many seconds for each response before marking it as a failure.
- `DOKKU_CHECKS_ATTEMPTS`: (default: `5`) Number of retries for to run for a specific check before marking it as a failure
- `wait`: (default: `5`) Wait this many seconds for the container to start before running checks. Set via `dokku checks:set <app> wait <value>`.
- `timeout`: (default: `30`) Wait this many seconds for each response before marking it as a failure. Set via `dokku checks:set <app> timeout <value>`.
- `attempts`: (default: `5`) Number of retries for to run for a specific check before marking it as a failure. Set via `dokku checks:set <app> attempts <value>`.
## Skipping and Disabling Checks

View File

@@ -1,4 +1,4 @@
SUBCOMMANDS = subcommands/clone subcommands/create subcommands/destroy subcommands/exists subcommands/list subcommands/lock subcommands/locked subcommands/rename subcommands/report subcommands/unlock
SUBCOMMANDS = subcommands/clone subcommands/create subcommands/destroy subcommands/exists subcommands/list subcommands/lock subcommands/locked subcommands/rename subcommands/report subcommands/set subcommands/unlock
TRIGGERS = triggers/app-create triggers/app-destroy triggers/app-exists triggers/app-maybe-create triggers/deploy-source-set triggers/install triggers/post-app-clone-setup triggers/post-app-rename triggers/post-app-rename-setup triggers/post-create triggers/post-delete triggers/report
BUILD = commands subcommands triggers
PLUGIN_NAME = apps

View File

@@ -5,11 +5,13 @@ var (
DefaultProperties = map[string]string{
"deploy-source": "",
"deploy-source-metadata": "",
"disable-autocreation": "",
}
// GlobalProperties is a map of all valid global apps properties
GlobalProperties = map[string]bool{
"deploy-source": true,
"deploy-source-metadata": true,
"disable-autocreation": true,
}
)

View File

@@ -132,11 +132,7 @@ func maybeCreateApp(appName string) error {
return nil
}
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get-global",
Args: []string{"DOKKU_DISABLE_APP_AUTOCREATION"},
})
disableAutocreate := results.StdoutContents()
disableAutocreate := common.PropertyGetDefault("apps", "--global", "disable-autocreation", "")
if disableAutocreate == "true" {
common.LogWarn("App auto-creation disabled.")
return fmt.Errorf("Re-enable app auto-creation or create an app with 'dokku apps:create %s'", appName)

View File

@@ -28,6 +28,7 @@ Additional commands:`
apps:locked <app>, Checks if an app is locked for deployment
apps:rename <old-app> <new-app>, Rename an app
apps:report [<app>] [<flag>], Display report about an app
apps:set <app>|--global <key> <value>, Set or clear an apps property
apps:unlock <app>, Unlocks an app for deployment`
)

View File

@@ -72,6 +72,19 @@ func main() {
appName := args.Arg(0)
err = apps.CommandReport(appName, *format, infoFlag)
}
case "set":
args := flag.NewFlagSet("apps:set", flag.ExitOnError)
global := args.Bool("global", false, "--global: set a global property")
args.Parse(os.Args[2:])
appName := args.Arg(0)
property := args.Arg(1)
value := args.Arg(2)
if *global {
appName = "--global"
property = args.Arg(0)
value = args.Arg(1)
}
err = apps.CommandSet(appName, property, value)
case "unlock":
args := flag.NewFlagSet("apps:unlock", flag.ExitOnError)
args.Parse(os.Args[2:])

View File

@@ -226,6 +226,12 @@ func CommandReport(appName string, format string, infoFlag string) error {
return ReportSingleApp(appName, format, infoFlag)
}
// CommandSet set or clear an apps property for an app
func CommandSet(appName string, property string, value string) error {
common.CommandPropertySet("apps", appName, property, value, DefaultProperties, GlobalProperties)
return nil
}
// CommandUnlock unlocks an app for deployment
func CommandUnlock(appName string) error {
if err := common.VerifyAppName(appName); err != nil {

View File

@@ -53,6 +53,15 @@ func TriggerInstall() error {
return nil
}
if err := common.MigrateConfigToProperties("apps", []common.MigrateConfigEntry{
{
GlobalConfigVar: "DOKKU_DISABLE_APP_AUTOCREATION",
Property: "disable-autocreation",
},
}); err != nil {
return err
}
// migrate all created-at values from app mod-time to property
for _, appName := range apps {
if common.PropertyExists("apps", appName, "created-at") {

View File

@@ -3,14 +3,16 @@ package builder
var (
// DefaultProperties is a map of all valid builder properties with corresponding default property values
DefaultProperties = map[string]string{
"selected": "",
"detected": "",
"build-dir": "",
"build-dir": "",
"detected": "",
"selected": "",
"skip-cleanup": "",
}
// GlobalProperties is a map of all valid global builder properties
GlobalProperties = map[string]bool{
"selected": true,
"build-dir": true,
"build-dir": true,
"selected": true,
"skip-cleanup": true,
}
)

View File

@@ -108,30 +108,21 @@ func TriggerInstall() error {
return fmt.Errorf("Unable to install the builder plugin: %s", err.Error())
}
apps, err := common.UnfilteredDokkuApps()
if err != nil && !errors.Is(err, common.NoAppsExist) {
return nil
if err := common.MigrateConfigToProperties("builder", []common.MigrateConfigEntry{
{
ConfigVar: "DOKKU_APP_TYPE",
Property: "detected",
},
{
ConfigVar: "DOKKU_SKIP_CLEANUP",
GlobalConfigVar: "DOKKU_SKIP_CLEANUP",
Property: "skip-cleanup",
},
}); err != nil {
return err
}
for _, appName := range apps {
if common.PropertyExists("builder", appName, "detected") {
continue
}
results, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_APP_TYPE"},
})
if err != nil {
return err
}
if results.StdoutContents() != "" {
common.PropertyWrite("builder", appName, "detected", results.StdoutContents())
}
}
_, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
_, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "install-builder-prune",
})

View File

@@ -2,13 +2,13 @@
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
is_app_proctype_checks_disabled() {
declare desc="return true if app's proctype(s) checks are disabled"
local APP="$1"
local PROCTYPE="$2" status=false
local DOKKU_CHECKS_DISABLED=$(config_get "$APP" DOKKU_CHECKS_DISABLED || true)
local DOKKU_CHECKS_DISABLED=$(fn-plugin-property-get-default "checks" "$APP" "disabled" "")
if [[ "$DOKKU_CHECKS_DISABLED" == "_all_" ]] || [[ "$(is_val_in_list "$PROCTYPE" "$DOKKU_CHECKS_DISABLED")" == "true" ]]; then
status=true
@@ -21,7 +21,7 @@ is_app_proctype_checks_skipped() {
declare desc="return true if app's proctype(s) checks are skipped"
local APP="$1"
local PROCTYPE="$2" status=false
local DOKKU_CHECKS_SKIPPED=$(config_get "$APP" DOKKU_CHECKS_SKIPPED || true)
local DOKKU_CHECKS_SKIPPED=$(fn-plugin-property-get-default "checks" "$APP" "skipped" "")
if [[ "$DOKKU_CHECKS_SKIPPED" == "_all_" ]] || [[ "$(is_val_in_list "$PROCTYPE" "$DOKKU_CHECKS_SKIPPED")" == "true" ]]; then
status=true

View File

@@ -3,16 +3,14 @@ set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
migrate_checks_vars_0_29_0() {
declare desc="migrates deprecated DOKKU_WAIT_TO_RETIRE config variables to property counter part introduced in 0.29.x"
fn-migrate-config-to-property "checks" "wait-to-retire" "DOKKU_WAIT_TO_RETIRE" "DOKKU_WAIT_TO_RETIRE"
}
migrate_checks_vars_0_5_0() {
declare desc="migrates deprecated CHECKS config variables to simplified counter part introduced in 0.5.x"
if ! declare -f -F config_get >/dev/null; then
source "$PLUGIN_AVAILABLE_PATH/config/functions"
fi
local GLOBAL_SKIP_ALL_CHECKS=$(config_get --global DOKKU_SKIP_ALL_CHECKS || true)
local GLOBAL_SKIP_DEFAULT_CHECKS=$(config_get --global DOKKU_SKIP_DEFAULT_CHECKS || true)
@@ -20,13 +18,13 @@ migrate_checks_vars_0_5_0() {
local APP_SKIP_ALL_CHECKS=$(config_get "$app" DOKKU_SKIP_ALL_CHECKS || true)
local APP_SKIP_DEFAULT_CHECKS=$(config_get "$app" DOKKU_SKIP_DEFAULT_CHECKS || true)
if [[ "$APP_SKIP_ALL_CHECKS" == "true" ]] || [[ "$APP_SKIP_DEFAULT_CHECKS" == "true" ]] || [[ "$GLOBAL_SKIP_ALL_CHECKS" == "true" ]] || [[ "$GLOBAL_SKIP_DEFAULT_CHECKS" == "true" ]]; then
dokku_log_info1 "Migrating zero downtime env variables to 0.5.x. The following variables have been deprecated"
dokku_log_info2 "DOKKU_SKIP_ALL_CHECKS DOKKU_SKIP_DEFAULT_CHECKS"
dokku_log_info2 "Please use dokku checks:[disable|enable] <app> to control zero downtime functionality"
dokku_log_info2 ""
dokku_log_info2 "Zero downtime checks disabled for app ($app)"
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$app" DOKKU_CHECKS_ENABLED=0
if [[ "$APP_SKIP_ALL_CHECKS" == "true" ]] || [[ "$GLOBAL_SKIP_ALL_CHECKS" == "true" ]]; then
dokku_log_info1 "Migrating DOKKU_SKIP_ALL_CHECKS to checks disabled property for $app. Use 'dokku checks:set $app disabled <value>' to manage this going forward."
fn-plugin-property-write "checks" "$app" "disabled" "_all_"
fi
if [[ "$APP_SKIP_DEFAULT_CHECKS" == "true" ]] || [[ "$GLOBAL_SKIP_DEFAULT_CHECKS" == "true" ]]; then
dokku_log_info1 "Migrating DOKKU_SKIP_DEFAULT_CHECKS to checks skipped property for $app. Use 'dokku checks:set $app skipped <value>' to manage this going forward."
fn-plugin-property-write "checks" "$app" "skipped" "_all_"
fi
if [[ -n "$APP_SKIP_ALL_CHECKS" ]] || [[ -n "$APP_SKIP_DEFAULT_CHECKS" ]]; then
DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$app" DOKKU_SKIP_ALL_CHECKS DOKKU_SKIP_DEFAULT_CHECKS
@@ -34,7 +32,6 @@ migrate_checks_vars_0_5_0() {
done
if [[ -n "$GLOBAL_SKIP_ALL_CHECKS" ]] || [[ -n "$GLOBAL_SKIP_DEFAULT_CHECKS" ]]; then
dokku_log_info1 "Removing global zero downtime settings"
DOKKU_QUIET_OUTPUT=1 config_unset --global DOKKU_SKIP_ALL_CHECKS DOKKU_SKIP_DEFAULT_CHECKS
fi
}
@@ -42,15 +39,16 @@ migrate_checks_vars_0_5_0() {
migrate_checks_vars_0_6_0() {
declare desc="migrates CHECKS config variables from 0.5.x to support fully-disabled zero-downtime checks"
if ! declare -f -F config_get >/dev/null; then
source "$PLUGIN_AVAILABLE_PATH/config/functions"
fi
for app in $(dokku_apps "false" 2>/dev/null); do
local APP_DOKKU_CHECKS_ENABLED=$(config_get "$app" DOKKU_CHECKS_ENABLED || true)
if [[ $APP_DOKKU_CHECKS_ENABLED ]]; then
dokku_log_info1 "Migrating zero downtime env variables to 0.6.x. The following variables will be migrated"
dokku_log_info2 "DOKKU_CHECKS_ENABLED -> DOKKU_CHECKS_SKIPPED"
if [[ -n "$APP_DOKKU_CHECKS_ENABLED" ]]; then
if [[ "$APP_DOKKU_CHECKS_ENABLED" == "0" ]]; then
dokku_log_info2 ""
dokku_log_info2 "Zero downtime checks disabled for app ($app)"
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$app" DOKKU_CHECKS_SKIPPED="_all_"
dokku_log_info1 "Migrating DOKKU_CHECKS_ENABLED to checks skipped property for $app. Use 'dokku checks:set $app skipped <value>' to manage this going forward."
fn-plugin-property-write "checks" "$app" "skipped" "_all_"
fi
DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$app" DOKKU_CHECKS_ENABLED || true
fi
@@ -64,7 +62,14 @@ trigger-checks-install() {
fn-plugin-property-setup "checks"
migrate_checks_vars_0_5_0 "$@"
migrate_checks_vars_0_6_0 "$@"
migrate_checks_vars_0_29_0 "$@"
"$PLUGIN_CORE_AVAILABLE_PATH/common/prop" migrate-config-to-property checks wait-to-retire DOKKU_WAIT_TO_RETIRE --global-config-var DOKKU_WAIT_TO_RETIRE
"$PLUGIN_CORE_AVAILABLE_PATH/common/prop" migrate-config-to-property checks disabled DOKKU_CHECKS_DISABLED
"$PLUGIN_CORE_AVAILABLE_PATH/common/prop" migrate-config-to-property checks skipped DOKKU_CHECKS_SKIPPED
"$PLUGIN_CORE_AVAILABLE_PATH/common/prop" migrate-config-to-property checks wait DOKKU_CHECKS_WAIT --global-config-var DOKKU_CHECKS_WAIT
"$PLUGIN_CORE_AVAILABLE_PATH/common/prop" migrate-config-to-property checks timeout DOKKU_CHECKS_TIMEOUT --global-config-var DOKKU_CHECKS_TIMEOUT
"$PLUGIN_CORE_AVAILABLE_PATH/common/prop" migrate-config-to-property checks attempts DOKKU_CHECKS_ATTEMPTS --global-config-var DOKKU_CHECKS_ATTEMPTS
"$PLUGIN_CORE_AVAILABLE_PATH/common/prop" migrate-config-to-property checks default-wait DOKKU_DEFAULT_CHECKS_WAIT --global-config-var DOKKU_DEFAULT_CHECKS_WAIT
}
trigger-checks-install "$@"

View File

@@ -72,7 +72,7 @@ cmd-checks-report-single() {
fn-checks-disabled-list() {
declare APP="$1"
local DOKKU_CHECKS_DISABLED=$(config_get "$APP" DOKKU_CHECKS_DISABLED)
local DOKKU_CHECKS_DISABLED=$(fn-plugin-property-get-default "checks" "$APP" "disabled" "")
DOKKU_CHECKS_DISABLED="${DOKKU_CHECKS_DISABLED:-none}"
echo "$DOKKU_CHECKS_DISABLED"
}
@@ -80,7 +80,7 @@ fn-checks-disabled-list() {
fn-checks-skipped-list() {
declare APP="$1"
local DOKKU_CHECKS_SKIPPED=$(config_get "$APP" DOKKU_CHECKS_SKIPPED)
local DOKKU_CHECKS_SKIPPED=$(fn-plugin-property-get-default "checks" "$APP" "skipped" "")
DOKKU_CHECKS_SKIPPED="${DOKKU_CHECKS_SKIPPED:-none}"
echo "$DOKKU_CHECKS_SKIPPED"
}

View File

@@ -2,7 +2,7 @@
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/checks/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
cmd-checks-disable() {
declare desc="disable zero-downtime checks for app/proctypes"
@@ -12,13 +12,13 @@ cmd-checks-disable() {
verify_app_name "$APP"
local PROCTYPES="${2:-_all_}"
local DOKKU_CHECKS_DISABLED=$(config_get "$APP" DOKKU_CHECKS_DISABLED || true)
local DOKKU_CHECKS_SKIPPED=$(config_get "$APP" DOKKU_CHECKS_SKIPPED || true)
local DOKKU_CHECKS_DISABLED=$(fn-plugin-property-get-default "checks" "$APP" "disabled" "")
local DOKKU_CHECKS_SKIPPED=$(fn-plugin-property-get-default "checks" "$APP" "skipped" "")
if [[ "$PROCTYPES" == "_all_" ]]; then
dokku_log_info1 "Disabling zero downtime for app ($APP)"
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" DOKKU_CHECKS_DISABLED="$PROCTYPES"
DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$APP" DOKKU_CHECKS_SKIPPED
fn-plugin-property-write "checks" "$APP" "disabled" "$PROCTYPES"
fn-plugin-property-delete "checks" "$APP" "skipped"
else
dokku_log_info1 "Disabling zero downtime for app's ($APP) proctypes ($PROCTYPES)"
local PROCTYPE OIFS="$IFS" IFS=,
@@ -31,15 +31,15 @@ cmd-checks-disable() {
done
DOKKU_CHECKS_DISABLED="$(remove_val_from_list "_all_" "$DOKKU_CHECKS_DISABLED")"
if [[ -z "$DOKKU_CHECKS_DISABLED" ]]; then
DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$APP" DOKKU_CHECKS_DISABLED
fn-plugin-property-delete "checks" "$APP" "disabled"
else
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" DOKKU_CHECKS_DISABLED="$DOKKU_CHECKS_DISABLED"
fn-plugin-property-write "checks" "$APP" "disabled" "$DOKKU_CHECKS_DISABLED"
fi
if [[ -z "$DOKKU_CHECKS_SKIPPED" ]]; then
DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$APP" DOKKU_CHECKS_SKIPPED
fn-plugin-property-delete "checks" "$APP" "skipped"
else
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" DOKKU_CHECKS_SKIPPED="$DOKKU_CHECKS_SKIPPED"
fn-plugin-property-write "checks" "$APP" "skipped" "$DOKKU_CHECKS_SKIPPED"
fi
fi
}

View File

@@ -2,7 +2,7 @@
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/checks/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
cmd-checks-enable() {
declare desc="enable zero-downtime checks for app/proctypes"
@@ -13,13 +13,13 @@ cmd-checks-enable() {
verify_app_name "$APP"
local PROCTYPES="${2:-_all_}"
local DOKKU_CHECKS_DISABLED=$(config_get "$APP" DOKKU_CHECKS_DISABLED || true)
local DOKKU_CHECKS_SKIPPED=$(config_get "$APP" DOKKU_CHECKS_SKIPPED || true)
local DOKKU_CHECKS_DISABLED=$(fn-plugin-property-get-default "checks" "$APP" "disabled" "")
local DOKKU_CHECKS_SKIPPED=$(fn-plugin-property-get-default "checks" "$APP" "skipped" "")
if [[ "$PROCTYPES" == "_all_" ]]; then
dokku_log_info1 "Enabling zero downtime for app's ($APP)"
DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$APP" DOKKU_CHECKS_DISABLED
DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$APP" DOKKU_CHECKS_SKIPPED
fn-plugin-property-delete "checks" "$APP" "disabled"
fn-plugin-property-delete "checks" "$APP" "skipped"
else
dokku_log_info1 "Enabling zero downtime for app's ($APP) proctypes ($PROCTYPES)"
local PROCTYPE OIFS="$IFS" IFS=,
@@ -30,15 +30,15 @@ cmd-checks-enable() {
IFS="$OIFS"
if [[ -z "$DOKKU_CHECKS_DISABLED" ]]; then
DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$APP" DOKKU_CHECKS_DISABLED
fn-plugin-property-delete "checks" "$APP" "disabled"
else
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" DOKKU_CHECKS_DISABLED="$DOKKU_CHECKS_DISABLED"
fn-plugin-property-write "checks" "$APP" "disabled" "$DOKKU_CHECKS_DISABLED"
fi
if [[ -z "$DOKKU_CHECKS_SKIPPED" ]]; then
DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$APP" DOKKU_CHECKS_SKIPPED
fn-plugin-property-delete "checks" "$APP" "skipped"
else
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" DOKKU_CHECKS_SKIPPED="$DOKKU_CHECKS_SKIPPED"
fn-plugin-property-write "checks" "$APP" "skipped" "$DOKKU_CHECKS_SKIPPED"
fi
fi
}

View File

@@ -2,7 +2,7 @@
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/checks/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
cmd-checks-skip() {
declare desc="skip zero-downtime checks for app/proctypes"
@@ -12,13 +12,13 @@ cmd-checks-skip() {
verify_app_name "$APP"
local PROCTYPES="${2:-_all_}"
local DOKKU_CHECKS_DISABLED=$(config_get "$APP" DOKKU_CHECKS_DISABLED || true)
local DOKKU_CHECKS_SKIPPED=$(config_get "$APP" DOKKU_CHECKS_SKIPPED || true)
local DOKKU_CHECKS_DISABLED=$(fn-plugin-property-get-default "checks" "$APP" "disabled" "")
local DOKKU_CHECKS_SKIPPED=$(fn-plugin-property-get-default "checks" "$APP" "skipped" "")
if [[ "$PROCTYPES" == "_all_" ]]; then
dokku_log_info1 "Skipping zero downtime for app ($APP)"
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" DOKKU_CHECKS_SKIPPED="$PROCTYPES"
DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$APP" DOKKU_CHECKS_DISABLED
fn-plugin-property-write "checks" "$APP" "skipped" "$PROCTYPES"
fn-plugin-property-delete "checks" "$APP" "disabled"
else
dokku_log_info1 "Skipping zero downtime for app's ($APP) proctypes ($PROCTYPES)"
local PROCTYPE OIFS="$IFS" IFS=,
@@ -31,15 +31,15 @@ cmd-checks-skip() {
done
DOKKU_CHECKS_SKIPPED="$(remove_val_from_list "_all_" "$DOKKU_CHECKS_SKIPPED")"
if [[ -z "$DOKKU_CHECKS_DISABLED" ]]; then
DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$APP" DOKKU_CHECKS_DISABLED
fn-plugin-property-delete "checks" "$APP" "disabled"
else
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" DOKKU_CHECKS_DISABLED="$DOKKU_CHECKS_DISABLED"
fn-plugin-property-write "checks" "$APP" "disabled" "$DOKKU_CHECKS_DISABLED"
fi
if [[ -z "$DOKKU_CHECKS_SKIPPED" ]]; then
DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$APP" DOKKU_CHECKS_SKIPPED
fn-plugin-property-delete "checks" "$APP" "skipped"
else
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" DOKKU_CHECKS_SKIPPED="$DOKKU_CHECKS_SKIPPED"
fn-plugin-property-write "checks" "$APP" "skipped" "$DOKKU_CHECKS_SKIPPED"
fi
fi
}

View File

@@ -606,37 +606,12 @@ func GetRunningImageTag(appName string, imageTag string) (string, error) {
// GetDokkuAppShell returns the shell for a given app
func GetDokkuAppShell(appName string) string {
shell := "/bin/bash"
globalShell := ""
appShell := ""
ctx := context.Background()
errs, ctx := errgroup.WithContext(ctx)
errs.Go(func() error {
results, _ := CallPlugnTriggerWithContext(ctx, PlugnTriggerInput{
Trigger: "config-get-global",
Args: []string{"DOKKU_APP_SHELL"},
})
globalShell = results.StdoutContents()
return nil
})
errs.Go(func() error {
results, _ := CallPlugnTriggerWithContext(ctx, PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_APP_SHELL"},
})
appShell = results.StdoutContents()
return nil
})
errs.Wait()
appShell := PropertyGet("scheduler", appName, "shell")
if appShell != "" {
shell = appShell
} else if globalShell != "" {
shell = globalShell
return appShell
}
return shell
return PropertyGetDefault("scheduler", "--global", "shell", "/bin/bash")
}
// DokkuApps returns a list of all local apps

View File

@@ -390,23 +390,17 @@ func DockerBin() string {
func DockerCleanup(appName string, forceCleanup bool) error {
if !forceCleanup {
skipCleanup := false
if appName != "" {
triggerName := "config-get"
triggerArgs := []string{appName, "DOKKU_SKIP_CLEANUP"}
if appName == "--global" {
triggerName = "config-get-global"
triggerArgs = []string{"DOKKU_SKIP_CLEANUP"}
}
results, _ := CallPlugnTrigger(PlugnTriggerInput{
Trigger: triggerName,
Args: triggerArgs,
})
if results.StdoutContents() == "true" {
if appName != "" && appName != "--global" {
if PropertyGet("builder", appName, "skip-cleanup") == "true" {
skipCleanup = true
}
}
if !skipCleanup && PropertyGet("builder", "--global", "skip-cleanup") == "true" {
skipCleanup = true
}
// Fallback for .dokkurc compatibility
if skipCleanup || os.Getenv("DOKKU_SKIP_CLEANUP") == "true" {
LogInfo1("DOKKU_SKIP_CLEANUP set. Skipping dokku cleanup")
return nil

View File

@@ -632,8 +632,8 @@ release_and_deploy() {
if verify_image "$IMAGE"; then
IMAGE_SOURCE_TYPE="$(get_image_builder_type "$IMAGE" "$APP")"
local DOKKU_APP_SKIP_DEPLOY="$(config_get "$APP" DOKKU_SKIP_DEPLOY || true)"
local DOKKU_GLOBAL_SKIP_DEPLOY="$(config_get --global DOKKU_SKIP_DEPLOY || true)"
local DOKKU_APP_SKIP_DEPLOY="$(fn-plugin-property-get-default "ps" "$APP" "skip-deploy" "")"
local DOKKU_GLOBAL_SKIP_DEPLOY="$(fn-plugin-property-get-default "ps" "--global" "skip-deploy" "")"
local DOKKU_SKIP_DEPLOY=${DOKKU_APP_SKIP_DEPLOY:="$DOKKU_GLOBAL_SKIP_DEPLOY"}
@@ -917,7 +917,7 @@ suppress_output() {
}
fn-migrate-config-to-property() {
declare desc="migrates deprecated config variables to property counterpart"
declare desc="[deprecated] migrates deprecated config variables to property counterpart. Use 'prop migrate-config-to-property' instead."
declare PLUGIN="$1" KEY="$2" CONFIG_VAR="$3" GLOBAL_CONFIG_VAR="$4"
# todo: refactor to remove config_unset usage

View File

@@ -548,6 +548,121 @@ func PropertySetupApp(pluginName string, appName string) error {
return nil
}
// MigrateConfigEntry describes a single config-to-property migration
type MigrateConfigEntry struct {
// ConfigVar is the per-app environment variable name (e.g. "DOKKU_APP_PROXY_TYPE")
ConfigVar string
// GlobalConfigVar is the global environment variable name (e.g. "DOKKU_PROXY_TYPE"), empty if none
GlobalConfigVar string
// Property is the target property name (e.g. "type")
Property string
// Transform is an optional value transformation function applied before writing
Transform func(value string) string
// ListProperty indicates the value should be written as a list property via PropertyListWrite
ListProperty bool
}
// MigrateConfigToProperties migrates config variables to properties for a given plugin
// across all apps and optionally globally. It is idempotent: if the property already
// exists, the migration is skipped for that app/entry.
func MigrateConfigToProperties(pluginName string, entries []MigrateConfigEntry) error {
apps, err := UnfilteredDokkuApps()
if err != nil && !errors.Is(err, NoAppsExist) {
return nil
}
for _, entry := range entries {
if entry.GlobalConfigVar != "" {
if err := migrateConfigEntry(pluginName, "--global", entry.GlobalConfigVar, entry); err != nil {
return err
}
}
for _, appName := range apps {
if entry.ConfigVar == "" {
continue
}
if err := migrateConfigEntry(pluginName, appName, entry.ConfigVar, entry); err != nil {
return err
}
}
}
return nil
}
// migrateConfigEntry migrates a single config variable to a property for a given app
func migrateConfigEntry(pluginName string, appName string, configVar string, entry MigrateConfigEntry) error {
if entry.ListProperty {
if exists, _ := PropertyListLength(pluginName, appName, entry.Property); exists > 0 {
return nil
}
} else if PropertyExists(pluginName, appName, entry.Property) {
return nil
}
triggerName := "config-get"
triggerArgs := []string{appName, configVar}
if appName == "--global" {
triggerName = "config-get-global"
triggerArgs = []string{configVar}
}
results, _ := CallPlugnTrigger(PlugnTriggerInput{
Trigger: triggerName,
Args: triggerArgs,
})
value := results.StdoutContents()
if value == "" {
return nil
}
if entry.Transform != nil {
value = entry.Transform(value)
}
if appName == "--global" {
LogInfo1(fmt.Sprintf("Migrating deprecated global %s to %s %s property. Use 'dokku %s:set --global %s <value>' to manage this going forward.", configVar, pluginName, entry.Property, pluginName, entry.Property))
} else {
LogInfo1(fmt.Sprintf("Migrating deprecated %s to %s %s property for %s. Use 'dokku %s:set %s %s <value>' to manage this going forward.", configVar, pluginName, entry.Property, appName, pluginName, appName, entry.Property))
}
if entry.ListProperty {
values := strings.Split(value, " ")
if err := PropertyListWrite(pluginName, appName, entry.Property, values); err != nil {
return err
}
} else {
if err := PropertyWrite(pluginName, appName, entry.Property, value); err != nil {
return err
}
}
unsetTrigger := "config-unset"
unsetArgs := []string{appName, configVar}
if appName == "--global" {
unsetArgs = []string{"--global", configVar}
}
_, err := CallPlugnTrigger(PlugnTriggerInput{
Trigger: unsetTrigger,
Args: unsetArgs,
Env: map[string]string{
"DOKKU_QUIET_OUTPUT": "1",
},
})
if err != nil {
LogWarn(err.Error())
}
return nil
}
func getPropertyPath(pluginName string, appName string, property string) string {
pluginAppConfigRoot := getPluginAppPropertyPath(pluginName, appName)
return filepath.Join(pluginAppConfigRoot, property)

View File

@@ -192,6 +192,76 @@ func main() {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
case "migrate-config-to-property":
property := flag.Arg(2)
configVar := flag.Arg(3)
globalConfigVar := ""
transformName := ""
listProperty := false
for i := 4; i < flag.NArg(); i++ {
arg := flag.Arg(i)
switch {
case arg == "--list":
listProperty = true
case arg == "--global-config-var" && i+1 < flag.NArg():
i++
globalConfigVar = flag.Arg(i)
case arg == "--transform" && i+1 < flag.NArg():
i++
transformName = flag.Arg(i)
}
}
var transform func(string) string
switch transformName {
case "restore-bool":
transform = func(value string) string {
if value == "0" {
return "false"
}
return "true"
}
case "non-empty-to-true":
transform = func(value string) string {
if value != "" {
return "true"
}
return value
}
case "skip-all-checks-to-disabled":
transform = func(value string) string {
if value == "true" {
return "_all_"
}
return ""
}
case "checks-enabled-to-skipped":
transform = func(value string) string {
if value == "0" {
return "_all_"
}
return ""
}
case "":
// no transform
default:
fmt.Fprintf(os.Stderr, "Unknown transform: %s\n", transformName)
os.Exit(1)
}
entry := common.MigrateConfigEntry{
ConfigVar: configVar,
GlobalConfigVar: globalConfigVar,
Property: property,
Transform: transform,
ListProperty: listProperty,
}
if err := common.MigrateConfigToProperties(pluginName, []common.MigrateConfigEntry{entry}); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
case "set":
appName := flag.Arg(2)
property := flag.Arg(3)

View File

@@ -62,7 +62,7 @@ func SetMany(appName string, entries map[string]string, replace bool, restart bo
})
triggerUpdate(appName, "set", keys)
}
if !global && restart && env.GetBoolDefault("DOKKU_APP_RESTORE", true) {
if !global && restart && shouldRestart(appName) {
triggerRestart(appName)
}
return
@@ -98,7 +98,7 @@ func UnsetMany(appName string, keys []string, restart bool) (err error) {
})
triggerUpdate(appName, "unset", keys)
}
if !global && restart && env.GetBoolDefault("DOKKU_APP_RESTORE", true) {
if !global && restart && shouldRestart(appName) {
triggerRestart(appName)
}
return
@@ -125,12 +125,20 @@ func UnsetAll(appName string, restart bool) (err error) {
})
triggerUpdate(appName, "clear", []string{})
}
if !global && restart && env.GetBoolDefault("DOKKU_APP_RESTORE", true) {
if !global && restart && shouldRestart(appName) {
triggerRestart(appName)
}
return
}
func shouldRestart(appName string) bool {
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "ps-get-property",
Args: []string{appName, "restore"},
})
return results.StdoutContents() != "false"
}
func triggerRestart(appName string) {
if !common.IsDeployed(appName) {
return

View File

@@ -227,8 +227,8 @@ nginx_build_config() {
# setup nginx listen ports
plugn trigger ports-configure "$APP"
local PROXY_PORT=$(config_get "$APP" DOKKU_PROXY_PORT)
local PROXY_SSL_PORT=$(config_get "$APP" DOKKU_PROXY_SSL_PORT)
local PROXY_PORT=$(plugn trigger ports-get-property "$APP" "proxy-port")
local PROXY_SSL_PORT=$(plugn trigger ports-get-property "$APP" "proxy-ssl-port")
local PORT_MAP PROXY_PORT_MAP proxy_port_map
while read -r PORT_MAP; do

View File

@@ -7,26 +7,8 @@ source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/internal-functions"
fn-nginx-vhosts-migrate-env-vars() {
# @TODO: Remove this after a few versions
for app in $(dokku_apps "false" 2>/dev/null); do
nginx_port="$(config_get "$app" DOKKU_NGINX_PORT || true)"
nginx_ssl_port="$(config_get "$app" DOKKU_NGINX_SSL_PORT || true)"
if [[ -n "$nginx_port" ]] || [[ -n "$nginx_ssl_port" ]]; then
dokku_log_info1 "Migrating DOKKU_NGINX env variables. The following variables will be migrated"
dokku_log_info2 "DOKKU_NGINX_PORT -> DOKKU_PROXY_PORT"
dokku_log_info2 "DOKKU_NGINX_SSL_PORT -> DOKKU_PROXY_SSL_PORT"
fi
if [[ -n "$nginx_port" ]]; then
dokku_log_info1 "Migrating DOKKU_NGINX_PORT to DOKKU_PROXY_PORT for $app"
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$app" DOKKU_PROXY_PORT="$nginx_port"
DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$app" DOKKU_NGINX_PORT
fi
if [[ -n "$nginx_ssl_port" ]]; then
dokku_log_info1 "Migrating DOKKU_NGINX_SSL_PORT to DOKKU_PROXY_SSL_PORT for $app"
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$app" DOKKU_PROXY_SSL_PORT="$nginx_ssl_port"
DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$app" DOKKU_NGINX_SSL_PORT
fi
done
"$PLUGIN_CORE_AVAILABLE_PATH/common/prop" migrate-config-to-property proxy proxy-port DOKKU_NGINX_PORT
"$PLUGIN_CORE_AVAILABLE_PATH/common/prop" migrate-config-to-property proxy proxy-ssl-port DOKKU_NGINX_SSL_PORT
}
fn-nginx-vhosts-migrate-nginx-conf-sigil() {

View File

@@ -2,7 +2,7 @@
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
trigger-nginx-vhosts-pre-disable-vhost() {
declare desc="unset port prior to vhosts being disabled"
@@ -14,19 +14,14 @@ trigger-nginx-vhosts-pre-disable-vhost() {
fi
# only clear ports if they are port 80 or 443
local PROXY_PORT=$(config_get "$APP" DOKKU_PROXY_PORT)
local PROXY_SSL_PORT=$(config_get "$APP" DOKKU_PROXY_SSL_PORT)
local PROXY_PORT=$(plugn trigger ports-get-property "$APP" "proxy-port")
local PROXY_SSL_PORT=$(plugn trigger ports-get-property "$APP" "proxy-ssl-port")
ports_to_clear=()
if [[ "$PROXY_PORT" == "80" ]]; then
ports_to_clear+=("DOKKU_PROXY_PORT")
fn-plugin-property-delete "proxy" "$APP" "proxy-port"
fi
if [[ "$PROXY_SSL_PORT" == "443" ]]; then
ports_to_clear+=("DOKKU_PROXY_SSL_PORT")
fi
if [[ "${#ports_to_clear[@]}" -gt 0 ]]; then
DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$APP" "${ports_to_clear[@]}"
fn-plugin-property-delete "proxy" "$APP" "proxy-ssl-port"
fi
# clear ports if there is a mapping starting with http:80 or https:443

View File

@@ -2,7 +2,7 @@
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
trigger-nginx-vhosts-pre-enable-vhost() {
declare desc="unset port prior to vhosts being enabled"
@@ -14,19 +14,14 @@ trigger-nginx-vhosts-pre-enable-vhost() {
fi
# only clear ports if they are port 80 or 443
local PROXY_PORT=$(config_get "$APP" DOKKU_PROXY_PORT)
local PROXY_SSL_PORT=$(config_get "$APP" DOKKU_PROXY_SSL_PORT)
local PROXY_PORT=$(plugn trigger ports-get-property "$APP" "proxy-port")
local PROXY_SSL_PORT=$(plugn trigger ports-get-property "$APP" "proxy-ssl-port")
ports_to_clear=()
if [[ "$PROXY_PORT" == "80" ]]; then
ports_to_clear+=("DOKKU_PROXY_PORT")
fn-plugin-property-delete "proxy" "$APP" "proxy-port"
fi
if [[ "$PROXY_SSL_PORT" == "443" ]]; then
ports_to_clear+=("DOKKU_PROXY_SSL_PORT")
fi
if [[ "${#ports_to_clear[@]}" -gt 0 ]]; then
DOKKU_QUIET_OUTPUT=1 config_unset --no-restart "$APP" "${ports_to_clear[@]}"
fn-plugin-property-delete "proxy" "$APP" "proxy-ssl-port"
fi
# clear ports if there is a mapping starting with http:80 or https:443

View File

@@ -10,7 +10,6 @@ import (
"strings"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/config"
"github.com/ryanuber/columnize"
)
@@ -162,11 +161,8 @@ func getDetectedPortMaps(appName string) []PortMap {
// getGlobalProxyPort gets the global proxy port
func getGlobalProxyPort() int {
port := 0
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get-global",
Args: []string{"DOKKU_PROXY_PORT"},
})
if intVar, err := strconv.Atoi(results.StdoutContents()); err == nil {
value := common.PropertyGet("proxy", "--global", "proxy-port")
if intVar, err := strconv.Atoi(value); err == nil {
port = intVar
}
@@ -176,11 +172,8 @@ func getGlobalProxyPort() int {
// getGlobalProxySSLPort gets the global proxy ssl port
func getGlobalProxySSLPort() int {
port := 0
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get-global",
Args: []string{"DOKKU_PROXY_SSL_PORT"},
})
if intVar, err := strconv.Atoi(results.StdoutContents()); err == nil {
value := common.PropertyGet("proxy", "--global", "proxy-ssl-port")
if intVar, err := strconv.Atoi(value); err == nil {
port = intVar
}
@@ -201,11 +194,8 @@ func getPortMaps(appName string) []PortMap {
// getProxyPort gets the proxy port for an app
func getProxyPort(appName string) int {
port := 0
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_PROXY_PORT"},
})
if intVar, err := strconv.Atoi(results.StdoutContents()); err == nil {
value := common.PropertyGet("proxy", appName, "proxy-port")
if intVar, err := strconv.Atoi(value); err == nil {
port = intVar
}
@@ -215,11 +205,8 @@ func getProxyPort(appName string) int {
// getProxySSLPort gets the proxy ssl port for an app
func getProxySSLPort(appName string) int {
port := 0
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_PROXY_SSL_PORT"},
})
if intVar, err := strconv.Atoi(results.StdoutContents()); err == nil {
value := common.PropertyGet("proxy", appName, "proxy-ssl-port")
if intVar, err := strconv.Atoi(value); err == nil {
port = intVar
}
@@ -445,22 +432,22 @@ func setPortMaps(appName string, portMaps []PortMap) error {
// setProxyPort sets the proxy port for an app
func setProxyPort(appName string, port int) error {
return common.EnvWrap(func() error {
entries := map[string]string{
"DOKKU_PROXY_PORT": fmt.Sprint(port),
}
return config.SetMany(appName, entries, false, false)
}, map[string]string{"DOKKU_QUIET_OUTPUT": "1"})
return common.PropertyWrite("proxy", appName, "proxy-port", fmt.Sprint(port))
}
// setProxySSLPort sets the proxy ssl port for an app
func setProxySSLPort(appName string, port int) error {
return common.EnvWrap(func() error {
entries := map[string]string{
"DOKKU_PROXY_SSL_PORT": fmt.Sprint(port),
}
return config.SetMany(appName, entries, false, false)
}, map[string]string{"DOKKU_QUIET_OUTPUT": "1"})
return common.PropertyWrite("proxy", appName, "proxy-ssl-port", fmt.Sprint(port))
}
// transformPortMap normalizes a port map string for migration to list properties
func transformPortMap(value string) string {
portMaps, _ := parsePortMapString(value)
var parts []string
for _, portMap := range portMaps {
parts = append(parts, portMap.String())
}
return strings.Join(parts, " ")
}
// uniquePortMaps returns a unique set of port maps

View File

@@ -4,6 +4,7 @@ import (
"fmt"
)
// PortMap is a struct that contains a scheme:host-port:container-port mapping
type PortMap struct {
// ContainerPort is the port on the container

View File

@@ -2,12 +2,10 @@ package ports
import (
"encoding/json"
"errors"
"fmt"
"sort"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/config"
)
// TriggerInstall migrates the ports config to properties
@@ -16,44 +14,15 @@ func TriggerInstall() error {
return fmt.Errorf("Unable to install the ports plugin: %s", err.Error())
}
apps, err := common.UnfilteredDokkuApps()
if err != nil && !errors.Is(err, common.NoAppsExist) {
return nil
}
for _, appName := range apps {
if common.PropertyExists("ports", appName, "map") {
continue
}
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_PROXY_PORT_MAP"},
})
portMapString := results.StdoutContents()
if portMapString == "" {
continue
}
common.LogVerboseQuiet(fmt.Sprintf("Setting %s ports property 'map' to %v", appName, portMapString))
portMaps, _ := parsePortMapString(portMapString)
propertyValue := []string{}
for _, portMap := range portMaps {
propertyValue = append(propertyValue, portMap.String())
}
if err := common.PropertyListWrite("ports", appName, "map", propertyValue); err != nil {
return err
}
_, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-unset",
Args: []string{appName, "DOKKU_PROXY_PORT_MAP"},
})
if err != nil {
return err
}
if err := common.MigrateConfigToProperties("ports", []common.MigrateConfigEntry{
{
ConfigVar: "DOKKU_PROXY_PORT_MAP",
Property: "map",
ListProperty: true,
Transform: transformPortMap,
},
}); err != nil {
return err
}
return nil
@@ -185,34 +154,26 @@ func TriggerPostAppRenameSetup(oldAppName string, newAppName string) error {
return nil
}
// TriggerPostCertsRemove unsets port config vars after SSL cert is added
// TriggerPostCertsRemove unsets port properties after SSL cert is removed
func TriggerPostCertsRemove(appName string) error {
keys := []string{"DOKKU_PROXY_SSL_PORT"}
if err := config.UnsetMany(appName, keys, false); err != nil {
if err := common.PropertyDelete("proxy", appName, "proxy-ssl-port"); err != nil {
return err
}
return removePortMaps(appName, filterAppPortMaps(appName, "https", 443))
}
// TriggerPostCertsUpdate sets port config vars after SSL cert is added
// TriggerPostCertsUpdate sets port properties after SSL cert is added
func TriggerPostCertsUpdate(appName string) error {
port := config.GetWithDefault(appName, "DOKKU_PROXY_PORT", "")
sslPort := config.GetWithDefault(appName, "DOKKU_PROXY_SSL_PORT", "")
port := common.PropertyGet("proxy", appName, "proxy-port")
sslPort := common.PropertyGet("proxy", appName, "proxy-ssl-port")
portMaps := getPortMaps(appName)
toUnset := []string{}
if port == "80" {
toUnset = append(toUnset, "DOKKU_PROXY_PORT")
common.PropertyDelete("proxy", appName, "proxy-port")
}
if sslPort == "443" {
toUnset = append(toUnset, "DOKKU_PROXY_SSL_PORT")
}
if len(toUnset) > 0 {
if err := config.UnsetMany(appName, toUnset, false); err != nil {
return err
}
common.PropertyDelete("proxy", appName, "proxy-ssl-port")
}
var http80Ports []PortMap

View File

@@ -1,5 +1,5 @@
SUBCOMMANDS = subcommands/build-config subcommands/clear-config subcommands/disable subcommands/enable subcommands/ports subcommands/ports-add subcommands/ports-clear subcommands/ports-remove subcommands/ports-set subcommands/report subcommands/set
TRIGGERS = triggers/proxy-is-enabled triggers/proxy-type triggers/report
TRIGGERS = triggers/install triggers/proxy-is-enabled triggers/proxy-type triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-delete triggers/report
BUILD = commands subcommands triggers
PLUGIN_NAME = proxy

View File

@@ -1,11 +1,11 @@
package proxy
import (
"github.com/dokku/dokku/plugins/config"
"github.com/dokku/dokku/plugins/common"
)
func getAppProxyType(appName string) string {
return config.GetWithDefault(appName, "DOKKU_APP_PROXY_TYPE", "")
return common.PropertyGet("proxy", appName, "type")
}
func getComputedProxyType(appName string) string {
@@ -18,5 +18,5 @@ func getComputedProxyType(appName string) string {
}
func getGlobalProxyType() string {
return config.GetWithDefault("--global", "DOKKU_PROXY_TYPE", "nginx")
return common.PropertyGetDefault("proxy", "--global", "type", "nginx")
}

View File

@@ -2,13 +2,29 @@ package proxy
import (
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/config"
)
// RunInSerial is the default value for whether to run a command in parallel or not
// and defaults to -1 (false)
const RunInSerial = 0
var (
// DefaultProperties is a map of all valid proxy properties with corresponding default property values
DefaultProperties = map[string]string{
"disabled": "false",
"proxy-port": "",
"proxy-ssl-port": "",
"type": "",
}
// GlobalProperties is a map of all valid global proxy properties
GlobalProperties = map[string]bool{
"proxy-port": true,
"proxy-ssl-port": true,
"type": true,
}
)
// BuildConfig rebuilds the proxy config for the specified app
func BuildConfig(appName string) error {
_, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
@@ -37,11 +53,7 @@ func Disable(appName string) error {
}
common.LogInfo1("Disabling proxy for app")
entries := map[string]string{
"DOKKU_DISABLE_PROXY": "1",
}
if err := config.SetMany(appName, entries, false, false); err != nil {
if err := common.PropertyWrite("proxy", appName, "disabled", "true"); err != nil {
return err
}
@@ -61,10 +73,10 @@ func Enable(appName string) error {
}
common.LogInfo1("Enabling proxy for app")
keys := []string{"DOKKU_DISABLE_PROXY"}
if err := config.UnsetMany(appName, keys, false); err != nil {
if err := common.PropertyDelete("proxy", appName, "disabled"); err != nil {
return err
}
_, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "proxy-enable",
Args: []string{appName},
@@ -75,10 +87,5 @@ func Enable(appName string) error {
// IsAppProxyEnabled returns true if proxy is enabled; otherwise return false
func IsAppProxyEnabled(appName string) bool {
proxyEnabled := true
disableProxy := config.GetWithDefault(appName, "DOKKU_DISABLE_PROXY", "")
if disableProxy != "" {
proxyEnabled = false
}
return proxyEnabled
return common.PropertyGetDefault("proxy", appName, "disabled", "false") != "true"
}

View File

@@ -59,12 +59,14 @@ func main() {
global := args.Bool("global", false, "--global: set a global property")
args.Parse(os.Args[2:])
appName := args.Arg(0)
proxyType := args.Arg(1)
property := args.Arg(1)
value := args.Arg(2)
if *global {
appName = "--global"
proxyType = args.Arg(0)
property = args.Arg(0)
value = args.Arg(1)
}
err = proxy.CommandSet(appName, proxyType)
err = proxy.CommandSet(appName, property, value)
default:
err = fmt.Errorf("Invalid plugin subcommand call: %s", subcommand)
}

View File

@@ -18,12 +18,25 @@ func main() {
var err error
switch trigger {
case "install":
err = proxy.TriggerInstall()
case "proxy-is-enabled":
appName := flag.Arg(0)
err = proxy.TriggerProxyIsEnabled(appName)
case "proxy-type":
appName := flag.Arg(0)
err = proxy.TriggerProxyType(appName)
case "post-app-clone-setup":
oldAppName := flag.Arg(0)
newAppName := flag.Arg(1)
err = proxy.TriggerPostAppCloneSetup(oldAppName, newAppName)
case "post-app-rename-setup":
oldAppName := flag.Arg(0)
newAppName := flag.Arg(1)
err = proxy.TriggerPostAppRenameSetup(oldAppName, newAppName)
case "post-delete":
appName := flag.Arg(0)
err = proxy.TriggerPostDelete(appName)
case "report":
appName := flag.Arg(0)
err = proxy.ReportSingleApp(appName, "", "")

View File

@@ -5,7 +5,6 @@ import (
"strings"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/config"
)
// CommandBuildConfig rebuilds config for a given app
@@ -82,29 +81,19 @@ func CommandReport(appName string, format string, infoFlag string) error {
return ReportSingleApp(appName, format, infoFlag)
}
// CommandSet sets a proxy for an app
func CommandSet(appName string, proxyType string) error {
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
// CommandSet set or clear a proxy property for an app
func CommandSet(appName string, property string, value string) error {
// backward compatibility: `proxy:set <app> <proxy-type>` is treated as
// `proxy:set <app> type <proxy-type>`
if _, ok := DefaultProperties[property]; !ok && value == "" {
if strings.Contains(property, ":") {
common.LogWarn("Detected potential port mapping instead of proxy type")
return errors.New("Consider using ports:set command or specifying a valid proxy")
}
value = property
property = "type"
}
if len(proxyType) < 2 {
return errors.New("Please specify a proxy type")
}
if strings.Contains(proxyType, ":") {
common.LogWarn("Detected potential port mapping instead of proxy type")
return errors.New("Consider using ports:set command or specifying a valid proxy")
}
key := "DOKKU_APP_PROXY_TYPE"
if appName == "--global" {
key = "DOKKU_PROXY_TYPE"
}
entries := map[string]string{
key: proxyType,
}
return config.SetMany(appName, entries, false, false)
common.CommandPropertySet("proxy", appName, property, value, DefaultProperties, GlobalProperties)
return nil
}

View File

@@ -2,8 +2,49 @@ package proxy
import (
"fmt"
"github.com/dokku/dokku/plugins/common"
)
// TriggerInstall runs the install step for the proxy plugin
func TriggerInstall() error {
if err := common.PropertySetup("proxy"); err != nil {
return fmt.Errorf("Unable to install the proxy plugin: %s", err.Error())
}
if err := common.MigrateConfigToProperties("proxy", []common.MigrateConfigEntry{
{
ConfigVar: "DOKKU_APP_PROXY_TYPE",
GlobalConfigVar: "DOKKU_PROXY_TYPE",
Property: "type",
},
{
ConfigVar: "DOKKU_DISABLE_PROXY",
Property: "disabled",
Transform: func(value string) string {
if value != "" {
return "true"
}
return value
},
},
{
ConfigVar: "DOKKU_PROXY_PORT",
GlobalConfigVar: "DOKKU_PROXY_PORT",
Property: "proxy-port",
},
{
ConfigVar: "DOKKU_PROXY_SSL_PORT",
GlobalConfigVar: "DOKKU_PROXY_SSL_PORT",
Property: "proxy-ssl-port",
},
}); err != nil {
return err
}
return nil
}
// TriggerProxyIsEnabled prints true or false depending on whether the proxy is enabled
func TriggerProxyIsEnabled(appName string) error {
if IsAppProxyEnabled(appName) {
@@ -22,3 +63,22 @@ func TriggerProxyType(appName string) error {
return nil
}
// TriggerPostAppCloneSetup creates new proxy files
func TriggerPostAppCloneSetup(oldAppName string, newAppName string) error {
return common.PropertyClone("proxy", oldAppName, newAppName)
}
// TriggerPostAppRenameSetup renames proxy files
func TriggerPostAppRenameSetup(oldAppName string, newAppName string) error {
if err := common.PropertyClone("proxy", oldAppName, newAppName); err != nil {
return err
}
return common.PropertyDestroy("proxy", oldAppName)
}
// TriggerPostDelete destroys the proxy property for a given app container
func TriggerPostDelete(appName string) error {
return common.PropertyDestroy("proxy", appName)
}

View File

@@ -13,14 +13,19 @@ const RunInSerial = 0
var (
// DefaultProperties is a map of all valid ps properties with corresponding default property values
DefaultProperties = map[string]string{
"restart-policy": "on-failure:10",
"dockerfile-start-cmd": "",
"procfile-path": "",
"restart-policy": "on-failure:10",
"restore": "true",
"skip-deploy": "",
"start-cmd": "",
"stop-timeout-seconds": "30",
}
// GlobalProperties is a map of all valid global ps properties
GlobalProperties = map[string]bool{
"procfile-path": true,
"skip-deploy": true,
"stop-timeout-seconds": true,
}
)
@@ -165,13 +170,9 @@ func Restore(appName string) error {
return nil
}
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_APP_RESTORE"},
})
restore := results.StdoutContents()
if restore == "0" {
common.LogWarn(fmt.Sprintf("Skipping ps:restore for %s as DOKKU_APP_RESTORE=%s", appName, restore))
restore := common.PropertyGetDefault("ps", appName, "restore", "true")
if restore == "false" {
common.LogWarn(fmt.Sprintf("Skipping ps:restore for %s as restore property is false", appName))
return nil
}

View File

@@ -132,18 +132,7 @@ func reportRestartPolicy(appName string) string {
}
func reportRestore(appName string) string {
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_APP_RESTORE"},
})
restore := results.StdoutContents()
if restore == "0" {
restore = "false"
} else {
restore = "true"
}
return restore
return common.PropertyGetDefault("ps", appName, "restore", "true")
}
func reportRunningState(appName string) string {

View File

@@ -9,7 +9,6 @@ import (
"strings"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/config"
dockeroptions "github.com/dokku/dokku/plugins/docker-options"
)
@@ -37,13 +36,7 @@ func TriggerCorePostDeploy(appName string) error {
return err
}
entries := map[string]string{
"DOKKU_APP_RESTORE": "1",
}
return common.SuppressOutput(func() error {
return config.SetMany(appName, entries, false, false)
})
return common.PropertyWrite("ps", appName, "restore", "true")
}
// TriggerCorePostExtract ensures that the main Procfile is the one specified by procfile-path
@@ -135,29 +128,40 @@ func TriggerInstall() error {
if common.FileExists(dokkuScaleExtracted) {
os.Remove(dokkuScaleExtracted)
}
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_DOCKER_STOP_TIMEOUT"},
})
stopTimeout := results.StdoutContents()
if stopTimeout == "" {
continue
}
common.LogVerboseQuiet(fmt.Sprintf("Setting %s ps property 'stop-timeout-seconds' to %v", appName, stopTimeout))
if err := common.PropertyWrite("ps", appName, "stop-timeout-seconds", stopTimeout); err != nil {
return err
}
_, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-unset",
Args: []string{appName, "DOKKU_DOCKER_STOP_TIMEOUT"},
})
if err != nil {
return err
}
}
if err := common.MigrateConfigToProperties("ps", []common.MigrateConfigEntry{
{
ConfigVar: "DOKKU_DOCKER_STOP_TIMEOUT",
Property: "stop-timeout-seconds",
},
{
ConfigVar: "DOKKU_APP_RESTORE",
Property: "restore",
Transform: func(value string) string {
if value == "0" {
return "false"
}
return "true"
},
},
{
ConfigVar: "DOKKU_SKIP_DEPLOY",
GlobalConfigVar: "DOKKU_SKIP_DEPLOY",
Property: "skip-deploy",
},
{
ConfigVar: "DOKKU_START_CMD",
Property: "start-cmd",
},
{
ConfigVar: "DOKKU_DOCKERFILE_START_CMD",
Property: "dockerfile-start-cmd",
},
}); err != nil {
return err
}
return nil
}
@@ -240,13 +244,7 @@ func TriggerPostDelete(appName string) error {
// TriggerPostStop sets the restore property to false
func TriggerPostStop(appName string) error {
entries := map[string]string{
"DOKKU_APP_RESTORE": "0",
}
return common.SuppressOutput(func() error {
return config.SetMany(appName, entries, false, false)
})
return common.PropertyWrite("ps", appName, "restore", "false")
}
// TriggerPostReleaseBuilder ensures an app has an up to date scale parameters
@@ -321,14 +319,24 @@ func TriggerPsSetScale(appName string, skipDeploy bool, clearExisting bool, proc
func TriggerPsGetProperty(appName string, property string) error {
computedValueMap := map[string]common.ReportFunc{
"restore": reportRestore,
"skip-deploy": reportComputedSkipDeploy,
"stop-timeout-seconds": reportComputedStopTimeoutSeconds,
}
fn, ok := computedValueMap[property]
if !ok {
return fmt.Errorf("Invalid network property specified: %v", property)
return fmt.Errorf("Invalid ps property specified: %v", property)
}
fmt.Println(fn(appName))
return nil
}
func reportComputedSkipDeploy(appName string) string {
value := common.PropertyGet("ps", appName, "skip-deploy")
if value == "" {
value = common.PropertyGet("ps", "--global", "skip-deploy")
}
return value
}

View File

@@ -2,6 +2,7 @@
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
source "$PLUGIN_AVAILABLE_PATH/scheduler-docker-local/internal-functions"
main() {
@@ -122,7 +123,7 @@ fn-scheduler-docker-local-extract-start-cmd() {
return
fi
DOKKU_DOCKERFILE_START_CMD=$(config_get "$APP" DOKKU_DOCKERFILE_START_CMD || true)
DOKKU_DOCKERFILE_START_CMD=$(fn-plugin-property-get-default "ps" "$APP" "dockerfile-start-cmd" "")
DOKKU_PROCFILE_START_CMD=$(plugn trigger procfile-get-command "$APP" "$PROC_TYPE" "$PORT" 2>/dev/null || echo '')
START_CMD=${DOKKU_DOCKERFILE_START_CMD:-$DOKKU_PROCFILE_START_CMD}
echo "$START_CMD"

View File

@@ -36,6 +36,7 @@
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
source "$PLUGIN_AVAILABLE_PATH/checks/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/scheduler-docker-local/internal-functions"
@@ -59,21 +60,17 @@ trigger-scheduler-docker-local-check-deploy() {
local DOKKU_APP_CONTAINER_ID=${DOKKU_APP_CIDS[0]}
fi
# source global and in-app envs to get DOKKU_CHECKS_WAIT and any other necessary vars
eval "$(config_export global)"
eval "$(config_export app "$APP")"
if [[ "$(is_app_proctype_checks_skipped "$APP" "$DOKKU_APP_CONTAINER_TYPE")" == "true" ]]; then
dokku_log_info2_quiet "Zero downtime checks have been skipped ($DOKKU_APP_CONTAINER_TYPE.$CONTAINER_INDEX)"
exit 0
fi
# Wait this many seconds (default 5) for server to start before running checks.
local WAIT="${DOKKU_CHECKS_WAIT:-5}"
local WAIT="$(fn-plugin-property-get-default "checks" "$APP" "wait" "5")"
# Wait this many seconds (default 30) for each response.
local TIMEOUT="${DOKKU_CHECKS_TIMEOUT:-30}"
local TIMEOUT="$(fn-plugin-property-get-default "checks" "$APP" "timeout" "30")"
# use this number of retries for checks
local ATTEMPTS="${DOKKU_CHECKS_ATTEMPTS:-5}"
local ATTEMPTS="$(fn-plugin-property-get-default "checks" "$APP" "attempts" "5")"
local CHECKS_FILENAME="$(fn-scheduler-docker-local-get-process-specific-checks-file-path "$APP")"
local IMAGE_TAG="$(get_running_image_tag "$APP")"
@@ -121,7 +118,7 @@ trigger-scheduler-docker-local-check-deploy() {
}
trap "checks_check_deploy_cleanup $APP $DOKKU_APP_CONTAINER_TYPE $DOKKU_APP_CONTAINER_ID $CONTAINER_INDEX $TMP_APP_JSON_OUTPUT" RETURN INT TERM EXIT
local DOKKU_DEFAULT_CHECKS_WAIT="${DOKKU_DEFAULT_CHECKS_WAIT:-10}"
local DOKKU_DEFAULT_CHECKS_WAIT="$(fn-plugin-property-get-default "checks" "--global" "default-wait" "10")"
content="$(docker-container-healthchecker add "$DOKKU_APP_CONTAINER_TYPE" --app-json "$TMP_APP_JSON_OUTPUT" --if-empty --pretty --uptime "$DOKKU_DEFAULT_CHECKS_WAIT")"
echo "$content" >"$TMP_APP_JSON_OUTPUT"

View File

@@ -2,6 +2,7 @@
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
source "$PLUGIN_AVAILABLE_PATH/checks/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/scheduler-docker-local/internal-functions"
@@ -35,7 +36,7 @@ trigger-scheduler-docker-local-scheduler-deploy() {
DOKKU_DOCKER_STOP_TIMEOUT="$(plugn trigger ps-get-property "$APP" stop-timeout-seconds)"
[[ $DOKKU_DOCKER_STOP_TIMEOUT ]] && DOCKER_STOP_TIME_ARG="-t=${DOKKU_DOCKER_STOP_TIMEOUT}"
DOKKU_START_CMD="$(config_get "$APP" DOKKU_START_CMD || true)"
DOKKU_START_CMD="$(fn-plugin-property-get-default "ps" "$APP" "start-cmd" "")"
local PROCFILE_EXISTS=false
if plugn trigger procfile-exists "$APP" 2>/dev/null; then

View File

@@ -1,5 +1,6 @@
#!/usr/bin/env bash
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
@@ -92,10 +93,9 @@ trigger-scheduler-docker-local-scheduler-enter() {
shift
fi
local DOKKU_APP_SHELL="/bin/bash"
DOKKU_APP_SHELL="$(config_get --global DOKKU_APP_SHELL || echo "$DOKKU_APP_SHELL")"
DOKKU_APP_SHELL="$(config_get "$APP" DOKKU_APP_SHELL || echo "$DOKKU_APP_SHELL")"
[[ -z "$DOKKU_APP_SHELL" ]] && DOKKU_APP_SHELL="/bin/bash"
local DOKKU_APP_SHELL
DOKKU_APP_SHELL="$(fn-plugin-property-get-default "scheduler" "$APP" "shell" "")"
[[ -z "$DOKKU_APP_SHELL" ]] && DOKKU_APP_SHELL="$(fn-plugin-property-get-default "scheduler" "--global" "shell" "/bin/bash")"
local EXEC_CMD=""
has_tty && local DOKKU_RUN_OPTS+=" -i -t"

View File

@@ -2,6 +2,7 @@
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/scheduler-docker-local/internal-functions"
@@ -137,8 +138,8 @@ trigger-scheduler-docker-local-scheduler-run() {
RUN_COMMAND=("$@")
if [[ "${#RUN_COMMAND[@]}" -eq 0 ]]; then
if [[ -z "$DOKKU_SHELL" ]]; then
local DOKKU_APP_SHELL=$(config_get "$APP" DOKKU_APP_SHELL || true)
local DOKKU_GLOBAL_SHELL=$(config_get --global DOKKU_APP_SHELL || true)
local DOKKU_APP_SHELL=$(fn-plugin-property-get-default "scheduler" "$APP" "shell" "")
local DOKKU_GLOBAL_SHELL=$(fn-plugin-property-get-default "scheduler" "--global" "shell" "")
local DOKKU_SHELL=${DOKKU_APP_SHELL:="$DOKKU_GLOBAL_SHELL"}
fi

View File

@@ -434,21 +434,13 @@ func extractStartCommand(input StartCommandInput) string {
return "/start " + input.ProcessType
}
resp, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{input.AppName, "DOKKU_START_CMD"},
})
if err == nil && resp.ExitCode == 0 && len(resp.Stdout) > 0 {
command = strings.TrimSpace(resp.Stdout)
if startCmd := common.PropertyGet("ps", input.AppName, "start-cmd"); startCmd != "" {
command = startCmd
}
if input.ImageSourceType == "dockerfile" {
resp, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{input.AppName, "DOKKU_DOCKERFILE_START_CMD"},
})
if err == nil && resp.ExitCode == 0 && len(resp.Stdout) > 0 {
command = strings.TrimSpace(resp.Stdout)
if dockerfileStartCmd := common.PropertyGet("ps", input.AppName, "dockerfile-start-cmd"); dockerfileStartCmd != "" {
command = dockerfileStartCmd
}
}

View File

@@ -4,10 +4,12 @@ var (
// DefaultProperties is a map of all valid scheduler properties with corresponding default property values
DefaultProperties = map[string]string{
"selected": "docker-local",
"shell": "",
}
// GlobalProperties is a map of all valid global scheduler properties
GlobalProperties = map[string]bool{
"selected": true,
"shell": true,
}
)

View File

@@ -1,7 +1,6 @@
package scheduler
import (
"errors"
"fmt"
"github.com/dokku/dokku/plugins/common"
@@ -31,53 +30,19 @@ func TriggerInstall() error {
return fmt.Errorf("Unable to install the scheduler plugin: %s", err.Error())
}
apps, err := common.UnfilteredDokkuApps()
if err != nil && !errors.Is(err, common.NoAppsExist) {
return nil
}
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get-global",
Args: []string{"DOKKU_SCHEDULER"},
})
globalScheduler := results.StdoutContents()
if globalScheduler != "" {
common.LogVerboseQuiet(fmt.Sprintf("Setting scheduler property 'selected' to %v", globalScheduler))
if err := common.PropertyWrite("scheduler", "--global", "selected", globalScheduler); err != nil {
return err
}
_, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-unset",
Args: []string{"--global", "DOKKU_SCHEDULER"},
})
if err != nil {
common.LogWarn(err.Error())
}
}
for _, appName := range apps {
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_SCHEDULER"},
})
scheduler := results.StdoutContents()
if scheduler == "" {
continue
}
common.LogVerboseQuiet(fmt.Sprintf("Setting %s scheduler property 'selected' to %v", appName, scheduler))
if err := common.PropertyWrite("scheduler", appName, "selected", scheduler); err != nil {
return err
}
_, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-unset",
Args: []string{appName, "DOKKU_SCHEDULER"},
})
if err != nil {
common.LogWarn(err.Error())
}
if err := common.MigrateConfigToProperties("scheduler", []common.MigrateConfigEntry{
{
ConfigVar: "DOKKU_SCHEDULER",
GlobalConfigVar: "DOKKU_SCHEDULER",
Property: "selected",
},
{
ConfigVar: "DOKKU_APP_SHELL",
GlobalConfigVar: "DOKKU_APP_SHELL",
Property: "shell",
},
}); err != nil {
return err
}
return nil

View File

@@ -113,7 +113,7 @@ teardown() {
}
@test "(apps) app autocreate disabled" {
run /bin/bash -c "dokku config:set --no-restart --global DOKKU_DISABLE_APP_AUTOCREATION='true'"
run /bin/bash -c "dokku apps:set --global disable-autocreation true"
echo "output: $output"
echo "status: $status"
assert_success
@@ -122,7 +122,7 @@ teardown() {
echo "output: $output"
echo "status: $status"
assert_failure
run /bin/bash -c "dokku config:unset --no-restart --global DOKKU_DISABLE_APP_AUTOCREATION"
run /bin/bash -c "dokku apps:set --global disable-autocreation"
}
@test "(apps) apps:destroy" {

View File

@@ -116,7 +116,7 @@ teardown() {
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku config:set --no-restart $TEST_APP DOKKU_PROXY_SSL_PORT=443"
run /bin/bash -c "dokku proxy:set $TEST_APP proxy-ssl-port 443"
echo "output: $output"
echo "status: $status"
assert_success
@@ -132,10 +132,6 @@ teardown() {
echo "output: $output"
echo "status: $status"
assert_output "http 80 5000"
run /bin/bash -c "dokku config:get app-without-ssl DOKKU_PROXY_SSL_PORT"
echo "output: $output"
echo "status: $status"
assert_output_not_exists
run /bin/bash -c "dokku --force apps:destroy app-without-ssl"
echo "output: $output"
echo "status: $status"

View File

@@ -36,7 +36,7 @@ teardown() {
echo "status: $status"
assert_success
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_DISABLED"
run /bin/bash -c "dokku checks:report $TEST_APP --checks-disabled-list"
echo "output: $output"
echo "status: $status"
assert_output "_all_"
@@ -48,30 +48,30 @@ teardown() {
echo "status: $status"
assert_success
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_DISABLED"
run /bin/bash -c "dokku checks:report $TEST_APP --checks-disabled-list"
echo "output: $output"
echo "status: $status"
assert_output "_all_"
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_SKIPPED"
run /bin/bash -c "dokku checks:report $TEST_APP --checks-skipped-list"
echo "output: $output"
echo "status: $status"
assert_output_not_exists
assert_output "none"
run /bin/bash -c "dokku checks:enable $TEST_APP"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_DISABLED"
run /bin/bash -c "dokku checks:report $TEST_APP --checks-disabled-list"
echo "output: $output"
echo "status: $status"
assert_output_not_exists
assert_output "none"
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_SKIPPED"
run /bin/bash -c "dokku checks:report $TEST_APP --checks-skipped-list"
echo "output: $output"
echo "status: $status"
assert_output_not_exists
assert_output "none"
}
@test "(checks) checks:disable -> checks:skip" {
@@ -80,27 +80,27 @@ teardown() {
echo "status: $status"
assert_success
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_DISABLED"
run /bin/bash -c "dokku checks:report $TEST_APP --checks-disabled-list"
echo "output: $output"
echo "status: $status"
assert_output "web,worker,urgentworker,notifications"
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_SKIPPED"
run /bin/bash -c "dokku checks:report $TEST_APP --checks-skipped-list"
echo "output: $output"
echo "status: $status"
assert_output_not_exists
assert_output "none"
run /bin/bash -c "dokku checks:skip $TEST_APP urgentworker,worker"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_SKIPPED"
run /bin/bash -c "dokku checks:report $TEST_APP --checks-skipped-list"
echo "output: $output"
echo "status: $status"
assert_output "urgentworker,worker"
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_DISABLED"
run /bin/bash -c "dokku checks:report $TEST_APP --checks-disabled-list"
echo "output: $output"
echo "status: $status"
assert_output "web,notifications"
@@ -112,7 +112,7 @@ teardown() {
echo "status: $status"
assert_success
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_SKIPPED"
run /bin/bash -c "dokku checks:report $TEST_APP --checks-skipped-list"
echo "output: $output"
echo "status: $status"
assert_output "_all_"
@@ -124,30 +124,30 @@ teardown() {
echo "status: $status"
assert_success
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_SKIPPED"
run /bin/bash -c "dokku checks:report $TEST_APP --checks-skipped-list"
echo "output: $output"
echo "status: $status"
assert_output "_all_"
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_DISABLED"
run /bin/bash -c "dokku checks:report $TEST_APP --checks-disabled-list"
echo "output: $output"
echo "status: $status"
assert_output_not_exists
assert_output "none"
run /bin/bash -c "dokku checks:enable $TEST_APP"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_SKIPPED"
run /bin/bash -c "dokku checks:report $TEST_APP --checks-skipped-list"
echo "output: $output"
echo "status: $status"
assert_output_not_exists
assert_output "none"
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_DISABLED"
run /bin/bash -c "dokku checks:report $TEST_APP --checks-disabled-list"
echo "output: $output"
echo "status: $status"
assert_output_not_exists
assert_output "none"
}
@test "(checks) checks:skip -> checks:disable" {
@@ -156,27 +156,27 @@ teardown() {
echo "status: $status"
assert_success
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_SKIPPED"
run /bin/bash -c "dokku checks:report $TEST_APP --checks-skipped-list"
echo "output: $output"
echo "status: $status"
assert_output "web,worker,urgentworker,notifications"
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_DISABLED"
run /bin/bash -c "dokku checks:report $TEST_APP --checks-disabled-list"
echo "output: $output"
echo "status: $status"
assert_output_not_exists
assert_output "none"
run /bin/bash -c "dokku checks:disable $TEST_APP urgentworker,worker"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_DISABLED"
run /bin/bash -c "dokku checks:report $TEST_APP --checks-disabled-list"
echo "output: $output"
echo "status: $status"
assert_output "urgentworker,worker"
run /bin/bash -c "dokku config:get $TEST_APP DOKKU_CHECKS_SKIPPED"
run /bin/bash -c "dokku checks:report $TEST_APP --checks-skipped-list"
echo "output: $output"
echo "status: $status"
assert_output "web,notifications"

View File

@@ -60,9 +60,9 @@ teardown() {
assert_success
}
@test "(nginx-vhosts) proxy:build-config (global DOKKU_PROXY_PORT)" {
@test "(nginx-vhosts) proxy:build-config (global proxy-port)" {
local GLOBAL_PORT=30999
run /bin/bash -c "dokku config:set --global DOKKU_PROXY_PORT=${GLOBAL_PORT}"
run /bin/bash -c "dokku proxy:set --global proxy-port ${GLOBAL_PORT}"
echo "output: $output"
echo "status: $status"
assert_success
@@ -74,7 +74,7 @@ teardown() {
check_urls "http://${TEST_APP}.${DOKKU_DOMAIN}:${GLOBAL_PORT}"
assert_http_success "http://${TEST_APP}.${DOKKU_DOMAIN}:${GLOBAL_PORT}"
run /bin/bash -c "dokku config:unset --global DOKKU_PROXY_PORT"
run /bin/bash -c "dokku proxy:set --global proxy-port"
echo "output: $output"
echo "status: $status"
assert_success