feat: accept --global on :report subcommands

Every `:report` subcommand now recognizes `--global` as a scope selector that limits the report to globally-configured properties, including in JSON form via `--global --format json`. Previously this combination was rejected because `--global` was treated as an info flag, conflicting with `--format`. The shared `common.ParseReportArgs` helper now returns a `ReportArgs` struct exposing the parsed scope; each Go and bash report selects a global-only flag map when scope is global, and skips per-app verification.
This commit is contained in:
Jose Diaz-Gonzalez
2026-04-29 04:47:15 -04:00
parent ec70e10c5d
commit 8282981361
61 changed files with 1379 additions and 518 deletions

View File

@@ -20,6 +20,7 @@
- Fresh apt installs now ship a catch-all default site at `/etc/nginx/conf.d/00-default-vhost.conf` that rejects requests with unknown Host headers using `ssl_reject_handshake on` (HTTPS) and `return 444` (HTTP). This replaces the manual workaround previously documented in the nginx docs. The behavior can be opted out at install time via the `dokku/install_default_site` debconf prompt. See the [Default site documentation](/docs/networking/proxies/nginx.md#default-site).
- The `docker-local` scheduler now sends `SIGTERM` to old containers immediately after a successful deploy, rather than waiting `wait-to-retire` seconds before signaling. This matches Heroku's graceful-shutdown contract and lets applications begin draining in-flight work as soon as proxy traffic switches. The `wait-to-retire` grace period and `stop-timeout-seconds` hard-stop continue to apply as before. See the [zero downtime deploys documentation](/docs/deployment/zero-downtime-deploys.md#wait-to-retire) for more details.
- The `docker-local` scheduler no longer queues an image for retirement when another running container of the same app still uses it. This fixes the case where a `ps:rebuild` against an image-based deploy (`git:from-image`) produced an identical-SHA image and the `dokku-retire` cron timer would log `Image ... has running containers, skipping rm` on every run. Stuck entries from prior versions are pruned automatically on the next `ps:retire` run.
- All `:report` subcommands now accept the `--global` flag, which scopes the report to globally-configured properties. The flag composes with `--format json`, so a JSON report of global properties can be obtained via, for example, `dokku scheduler:report --global --format json`. Previously, combining `--global` with `--format json` was rejected with an "info flag" error, and `--global` on its own was treated as an unknown flag.
### TLS handshake behavior change

View File

@@ -6,14 +6,23 @@ import (
// ReportSingleApp is an internal function that displays the builder report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if err := common.VerifyAppName(appName); err != nil {
return err
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
flags := map[string]common.ReportFunc{
"--app-json-computed-selected": reportComputedAppjsonpath,
"--app-json-global-selected": reportGlobalAppjsonpath,
"--app-json-selected": reportAppjsonpath,
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{
"--app-json-global-selected": reportGlobalAppjsonpath,
}
} else {
flags = map[string]common.ReportFunc{
"--app-json-computed-selected": reportComputedAppjsonpath,
"--app-json-global-selected": reportGlobalAppjsonpath,
"--app-json-selected": reportAppjsonpath,
}
}
flagKeys := []string{}

View File

@@ -21,11 +21,14 @@ func main() {
case "report":
args := flag.NewFlagSet("app-json:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
osArgs, infoFlag, flagErr := common.ParseReportArgs("appjson", os.Args[2:])
reportArgs, flagErr := common.ParseReportArgs("appjson", os.Args[2:])
if flagErr == nil {
args.Parse(osArgs)
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
err = appjson.CommandReport(appName, *format, infoFlag)
if reportArgs.IsGlobal {
appName = "--global"
}
err = appjson.CommandReport(appName, *format, reportArgs.InfoFlag)
}
case "set":
args := flag.NewFlagSet("app-json:set", flag.ExitOnError)

View File

@@ -9,16 +9,23 @@ import (
// ReportSingleApp is an internal function that displays the app report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if err := common.VerifyAppName(appName); err != nil {
return err
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
flags := map[string]common.ReportFunc{
"--app-created-at": reportCreatedAt,
"--app-deploy-source": reportDeploySource,
"--app-deploy-source-metadata": reportDeploySourceMetadata,
"--app-dir": reportDir,
"--app-locked": reportLocked,
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{}
} else {
flags = map[string]common.ReportFunc{
"--app-created-at": reportCreatedAt,
"--app-deploy-source": reportDeploySource,
"--app-deploy-source-metadata": reportDeploySourceMetadata,
"--app-dir": reportDir,
"--app-locked": reportLocked,
}
}
flagKeys := []string{}

View File

@@ -66,11 +66,14 @@ func main() {
case "report":
args := flag.NewFlagSet("apps:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
osArgs, infoFlag, flagErr := common.ParseReportArgs("apps", os.Args[2:])
reportArgs, flagErr := common.ParseReportArgs("apps", os.Args[2:])
if flagErr == nil {
args.Parse(osArgs)
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
err = apps.CommandReport(appName, *format, infoFlag)
if reportArgs.IsGlobal {
appName = "--global"
}
err = apps.CommandReport(appName, *format, reportArgs.InfoFlag)
}
case "set":
args := flag.NewFlagSet("apps:set", flag.ExitOnError)

View File

@@ -8,9 +8,13 @@ cmd-builder-dockerfile-report() {
declare desc="displays a builder-dockerfile report for one or more apps"
declare cmd="builder-dockerfile:report"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" INFO_FLAG="$2"
fn-report-parse-args "$@"
set -- "${REPORT_ARGS[@]}"
declare APP="${1:-}" INFO_FLAG="${2:-}"
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
if [[ "$REPORT_IS_GLOBAL" == "true" ]]; then
APP="--global"
elif [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
INFO_FLAG="$APP"
APP=""
fi
@@ -19,29 +23,49 @@ cmd-builder-dockerfile-report() {
INFO_FLAG="true"
fi
if [[ -z "$APP" ]]; then
if [[ "$APP" == "--global" ]]; then
cmd-builder-dockerfile-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
elif [[ -z "$APP" ]]; then
for app in $(dokku_apps); do
cmd-builder-dockerfile-report-single "$app" "$INFO_FLAG" | tee || true
cmd-builder-dockerfile-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true
done
else
cmd-builder-dockerfile-report-single "$APP" "$INFO_FLAG"
cmd-builder-dockerfile-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
fi
}
cmd-builder-dockerfile-report-single() {
declare APP="$1" INFO_FLAG="$2"
declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}"
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
local flag_map=(
"--builder-dockerfile-computed-dockerfile-path: $(fn-builder-dockerfile-computed-dockerfile-path "$APP")"
"--builder-dockerfile-global-dockerfile-path: $(fn-builder-dockerfile-global-dockerfile-path "$APP")"
"--builder-dockerfile-dockerfile-path: $(fn-builder-dockerfile-dockerfile-path "$APP")"
)
local flag_map=()
if [[ "$APP" == "--global" ]]; then
flag_map=(
"--builder-dockerfile-global-dockerfile-path: $(fn-builder-dockerfile-global-dockerfile-path "$APP")"
)
else
verify_app_name "$APP"
flag_map=(
"--builder-dockerfile-computed-dockerfile-path: $(fn-builder-dockerfile-computed-dockerfile-path "$APP")"
"--builder-dockerfile-global-dockerfile-path: $(fn-builder-dockerfile-global-dockerfile-path "$APP")"
"--builder-dockerfile-dockerfile-path: $(fn-builder-dockerfile-dockerfile-path "$APP")"
)
fi
fn-report-validate-format "$FORMAT" "$INFO_FLAG"
if [[ "$FORMAT" == "json" ]]; then
fn-report-emit-json flag_map "builder-dockerfile"
return
fi
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "${APP} builder-dockerfile information"
if [[ "$APP" == "--global" ]]; then
dokku_log_info2_quiet "global builder-dockerfile information"
else
dokku_log_info2_quiet "${APP} builder-dockerfile information"
fi
for flag in "${flag_map[@]}"; do
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"

View File

@@ -8,9 +8,13 @@ cmd-builder-herokuish-report() {
declare desc="displays a builder-herokuish report for one or more apps"
declare cmd="builder-herokuish:report"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" INFO_FLAG="$2"
fn-report-parse-args "$@"
set -- "${REPORT_ARGS[@]}"
declare APP="${1:-}" INFO_FLAG="${2:-}"
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
if [[ "$REPORT_IS_GLOBAL" == "true" ]]; then
APP="--global"
elif [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
INFO_FLAG="$APP"
APP=""
fi
@@ -19,29 +23,49 @@ cmd-builder-herokuish-report() {
INFO_FLAG="true"
fi
if [[ -z "$APP" ]]; then
if [[ "$APP" == "--global" ]]; then
cmd-builder-herokuish-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
elif [[ -z "$APP" ]]; then
for app in $(dokku_apps); do
cmd-builder-herokuish-report-single "$app" "$INFO_FLAG" | tee || true
cmd-builder-herokuish-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true
done
else
cmd-builder-herokuish-report-single "$APP" "$INFO_FLAG"
cmd-builder-herokuish-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
fi
}
cmd-builder-herokuish-report-single() {
declare APP="$1" INFO_FLAG="$2"
declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}"
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
local flag_map=(
"--builder-herokuish-computed-allowed: $(fn-builder-herokuish-computed-allowed "$APP")"
"--builder-herokuish-global-allowed: $(fn-builder-herokuish-global-allowed)"
"--builder-herokuish-allowed: $(fn-builder-herokuish-allowed "$APP")"
)
local flag_map=()
if [[ "$APP" == "--global" ]]; then
flag_map=(
"--builder-herokuish-global-allowed: $(fn-builder-herokuish-global-allowed)"
)
else
verify_app_name "$APP"
flag_map=(
"--builder-herokuish-computed-allowed: $(fn-builder-herokuish-computed-allowed "$APP")"
"--builder-herokuish-global-allowed: $(fn-builder-herokuish-global-allowed)"
"--builder-herokuish-allowed: $(fn-builder-herokuish-allowed "$APP")"
)
fi
fn-report-validate-format "$FORMAT" "$INFO_FLAG"
if [[ "$FORMAT" == "json" ]]; then
fn-report-emit-json flag_map "builder-herokuish"
return
fi
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "${APP} builder-herokuish information"
if [[ "$APP" == "--global" ]]; then
dokku_log_info2_quiet "global builder-herokuish information"
else
dokku_log_info2_quiet "${APP} builder-herokuish information"
fi
for flag in "${flag_map[@]}"; do
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"

View File

@@ -8,9 +8,13 @@ cmd-builder-lambda-report() {
declare desc="displays a builder-lambda report for one or more apps"
declare cmd="builder-lambda:report"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" INFO_FLAG="$2"
fn-report-parse-args "$@"
set -- "${REPORT_ARGS[@]}"
declare APP="${1:-}" INFO_FLAG="${2:-}"
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
if [[ "$REPORT_IS_GLOBAL" == "true" ]]; then
APP="--global"
elif [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
INFO_FLAG="$APP"
APP=""
fi
@@ -19,29 +23,49 @@ cmd-builder-lambda-report() {
INFO_FLAG="true"
fi
if [[ -z "$APP" ]]; then
if [[ "$APP" == "--global" ]]; then
cmd-builder-lambda-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
elif [[ -z "$APP" ]]; then
for app in $(dokku_apps); do
cmd-builder-lambda-report-single "$app" "$INFO_FLAG" | tee || true
cmd-builder-lambda-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true
done
else
cmd-builder-lambda-report-single "$APP" "$INFO_FLAG"
cmd-builder-lambda-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
fi
}
cmd-builder-lambda-report-single() {
declare APP="$1" INFO_FLAG="$2"
declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}"
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
local flag_map=(
"--builder-lambda-computed-lambdayml-path: $(fn-builder-lambda-computed-lambdayml-path "$APP")"
"--builder-lambda-global-lambdayml-path: $(fn-builder-lambda-global-lambdayml-path "$APP")"
"--builder-lambda-lambdayml-path: $(fn-builder-lambda-lambdayml-path "$APP")"
)
local flag_map=()
if [[ "$APP" == "--global" ]]; then
flag_map=(
"--builder-lambda-global-lambdayml-path: $(fn-builder-lambda-global-lambdayml-path "$APP")"
)
else
verify_app_name "$APP"
flag_map=(
"--builder-lambda-computed-lambdayml-path: $(fn-builder-lambda-computed-lambdayml-path "$APP")"
"--builder-lambda-global-lambdayml-path: $(fn-builder-lambda-global-lambdayml-path "$APP")"
"--builder-lambda-lambdayml-path: $(fn-builder-lambda-lambdayml-path "$APP")"
)
fi
fn-report-validate-format "$FORMAT" "$INFO_FLAG"
if [[ "$FORMAT" == "json" ]]; then
fn-report-emit-json flag_map "builder-lambda"
return
fi
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "${APP} builder-lambda information"
if [[ "$APP" == "--global" ]]; then
dokku_log_info2_quiet "global builder-lambda information"
else
dokku_log_info2_quiet "${APP} builder-lambda information"
fi
for flag in "${flag_map[@]}"; do
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"

View File

@@ -8,9 +8,13 @@ cmd-builder-nixpacks-report() {
declare desc="displays a builder-nixpacks report for one or more apps"
declare cmd="builder-nixpacks:report"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" INFO_FLAG="$2"
fn-report-parse-args "$@"
set -- "${REPORT_ARGS[@]}"
declare APP="${1:-}" INFO_FLAG="${2:-}"
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
if [[ "$REPORT_IS_GLOBAL" == "true" ]]; then
APP="--global"
elif [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
INFO_FLAG="$APP"
APP=""
fi
@@ -19,29 +23,49 @@ cmd-builder-nixpacks-report() {
INFO_FLAG="true"
fi
if [[ -z "$APP" ]]; then
if [[ "$APP" == "--global" ]]; then
cmd-builder-nixpacks-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
elif [[ -z "$APP" ]]; then
for app in $(dokku_apps); do
cmd-builder-nixpacks-report-single "$app" "$INFO_FLAG" | tee || true
cmd-builder-nixpacks-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true
done
else
cmd-builder-nixpacks-report-single "$APP" "$INFO_FLAG"
cmd-builder-nixpacks-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
fi
}
cmd-builder-nixpacks-report-single() {
declare APP="$1" INFO_FLAG="$2"
declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}"
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
local flag_map=(
"--builder-nixpacks-computed-nixpackstoml-path: $(fn-builder-nixpacks-computed-nixpackstoml-path "$APP")"
"--builder-nixpacks-global-nixpackstoml-path: $(fn-builder-nixpacks-global-nixpackstoml-path "$APP")"
"--builder-nixpacks-nixpackstoml-path: $(fn-builder-nixpacks-nixpackstoml-path "$APP")"
)
local flag_map=()
if [[ "$APP" == "--global" ]]; then
flag_map=(
"--builder-nixpacks-global-nixpackstoml-path: $(fn-builder-nixpacks-global-nixpackstoml-path "$APP")"
)
else
verify_app_name "$APP"
flag_map=(
"--builder-nixpacks-computed-nixpackstoml-path: $(fn-builder-nixpacks-computed-nixpackstoml-path "$APP")"
"--builder-nixpacks-global-nixpackstoml-path: $(fn-builder-nixpacks-global-nixpackstoml-path "$APP")"
"--builder-nixpacks-nixpackstoml-path: $(fn-builder-nixpacks-nixpackstoml-path "$APP")"
)
fi
fn-report-validate-format "$FORMAT" "$INFO_FLAG"
if [[ "$FORMAT" == "json" ]]; then
fn-report-emit-json flag_map "builder-nixpacks"
return
fi
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "${APP} builder-nixpacks information"
if [[ "$APP" == "--global" ]]; then
dokku_log_info2_quiet "global builder-nixpacks information"
else
dokku_log_info2_quiet "${APP} builder-nixpacks information"
fi
for flag in "${flag_map[@]}"; do
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"

View File

@@ -8,9 +8,13 @@ cmd-builder-pack-report() {
declare desc="displays a builder-pack report for one or more apps"
declare cmd="builder-pack:report"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" INFO_FLAG="$2"
fn-report-parse-args "$@"
set -- "${REPORT_ARGS[@]}"
declare APP="${1:-}" INFO_FLAG="${2:-}"
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
if [[ "$REPORT_IS_GLOBAL" == "true" ]]; then
APP="--global"
elif [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
INFO_FLAG="$APP"
APP=""
fi
@@ -19,29 +23,49 @@ cmd-builder-pack-report() {
INFO_FLAG="true"
fi
if [[ -z "$APP" ]]; then
if [[ "$APP" == "--global" ]]; then
cmd-builder-pack-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
elif [[ -z "$APP" ]]; then
for app in $(dokku_apps); do
cmd-builder-pack-report-single "$app" "$INFO_FLAG" | tee || true
cmd-builder-pack-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true
done
else
cmd-builder-pack-report-single "$APP" "$INFO_FLAG"
cmd-builder-pack-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
fi
}
cmd-builder-pack-report-single() {
declare APP="$1" INFO_FLAG="$2"
declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}"
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
local flag_map=(
"--builder-pack-computed-projecttoml-path: $(fn-builder-pack-computed-projecttoml-path "$APP")"
"--builder-pack-global-projecttoml-path: $(fn-builder-pack-global-projecttoml-path "$APP")"
"--builder-pack-projecttoml-path: $(fn-builder-pack-projecttoml-path "$APP")"
)
local flag_map=()
if [[ "$APP" == "--global" ]]; then
flag_map=(
"--builder-pack-global-projecttoml-path: $(fn-builder-pack-global-projecttoml-path "$APP")"
)
else
verify_app_name "$APP"
flag_map=(
"--builder-pack-computed-projecttoml-path: $(fn-builder-pack-computed-projecttoml-path "$APP")"
"--builder-pack-global-projecttoml-path: $(fn-builder-pack-global-projecttoml-path "$APP")"
"--builder-pack-projecttoml-path: $(fn-builder-pack-projecttoml-path "$APP")"
)
fi
fn-report-validate-format "$FORMAT" "$INFO_FLAG"
if [[ "$FORMAT" == "json" ]]; then
fn-report-emit-json flag_map "builder-pack"
return
fi
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "${APP} builder-pack information"
if [[ "$APP" == "--global" ]]; then
dokku_log_info2_quiet "global builder-pack information"
else
dokku_log_info2_quiet "${APP} builder-pack information"
fi
for flag in "${flag_map[@]}"; do
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"

View File

@@ -8,9 +8,13 @@ cmd-builder-railpack-report() {
declare desc="displays a builder-railpack report for one or more apps"
declare cmd="builder-railpack:report"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" INFO_FLAG="$2"
fn-report-parse-args "$@"
set -- "${REPORT_ARGS[@]}"
declare APP="${1:-}" INFO_FLAG="${2:-}"
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
if [[ "$REPORT_IS_GLOBAL" == "true" ]]; then
APP="--global"
elif [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
INFO_FLAG="$APP"
APP=""
fi
@@ -19,29 +23,49 @@ cmd-builder-railpack-report() {
INFO_FLAG="true"
fi
if [[ -z "$APP" ]]; then
if [[ "$APP" == "--global" ]]; then
cmd-builder-railpack-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
elif [[ -z "$APP" ]]; then
for app in $(dokku_apps); do
cmd-builder-railpack-report-single "$app" "$INFO_FLAG" | tee || true
cmd-builder-railpack-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true
done
else
cmd-builder-railpack-report-single "$APP" "$INFO_FLAG"
cmd-builder-railpack-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
fi
}
cmd-builder-railpack-report-single() {
declare APP="$1" INFO_FLAG="$2"
declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}"
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
local flag_map=(
"--builder-railpack-computed-railpackjson-path: $(fn-builder-railpack-computed-railpackjson-path "$APP")"
"--builder-railpack-global-railpackjson-path: $(fn-builder-railpack-global-railpackjson-path "$APP")"
"--builder-railpack-railpackjson-path: $(fn-builder-railpack-railpackjson-path "$APP")"
)
local flag_map=()
if [[ "$APP" == "--global" ]]; then
flag_map=(
"--builder-railpack-global-railpackjson-path: $(fn-builder-railpack-global-railpackjson-path "$APP")"
)
else
verify_app_name "$APP"
flag_map=(
"--builder-railpack-computed-railpackjson-path: $(fn-builder-railpack-computed-railpackjson-path "$APP")"
"--builder-railpack-global-railpackjson-path: $(fn-builder-railpack-global-railpackjson-path "$APP")"
"--builder-railpack-railpackjson-path: $(fn-builder-railpack-railpackjson-path "$APP")"
)
fi
fn-report-validate-format "$FORMAT" "$INFO_FLAG"
if [[ "$FORMAT" == "json" ]]; then
fn-report-emit-json flag_map "builder-railpack"
return
fi
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "${APP} builder-railpack information"
if [[ "$APP" == "--global" ]]; then
dokku_log_info2_quiet "global builder-railpack information"
else
dokku_log_info2_quiet "${APP} builder-railpack information"
fi
for flag in "${flag_map[@]}"; do
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"

View File

@@ -6,18 +6,28 @@ import (
// ReportSingleApp is an internal function that displays the builder report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if err := common.VerifyAppName(appName); err != nil {
return err
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
flags := map[string]common.ReportFunc{
"--builder-computed-selected": reportComputedSelected,
"--builder-global-selected": reportGlobalSelected,
"--builder-selected": reportSelected,
"--builder-detected": reportDetected,
"--builder-computed-build-dir": reportComputedBuildDir,
"--builder-global-build-dir": reportGlobalBuildDir,
"--builder-build-dir": reportBuildDir,
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{
"--builder-global-selected": reportGlobalSelected,
"--builder-global-build-dir": reportGlobalBuildDir,
}
} else {
flags = map[string]common.ReportFunc{
"--builder-computed-selected": reportComputedSelected,
"--builder-global-selected": reportGlobalSelected,
"--builder-selected": reportSelected,
"--builder-detected": reportDetected,
"--builder-computed-build-dir": reportComputedBuildDir,
"--builder-global-build-dir": reportGlobalBuildDir,
"--builder-build-dir": reportBuildDir,
}
}
flagKeys := []string{}

View File

@@ -21,11 +21,14 @@ func main() {
case "report":
args := flag.NewFlagSet("builder:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
osArgs, infoFlag, flagErr := common.ParseReportArgs("builder", os.Args[2:])
reportArgs, flagErr := common.ParseReportArgs("builder", os.Args[2:])
if flagErr == nil {
args.Parse(osArgs)
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
err = builder.CommandReport(appName, *format, infoFlag)
if reportArgs.IsGlobal {
appName = "--global"
}
err = builder.CommandReport(appName, *format, reportArgs.InfoFlag)
}
case "set":
args := flag.NewFlagSet("builder:set", flag.ExitOnError)

View File

@@ -9,15 +9,24 @@ import (
// ReportSingleApp is an internal function that displays the buildpacks report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if err := common.VerifyAppName(appName); err != nil {
return err
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
flags := map[string]common.ReportFunc{
"--buildpacks-computed-stack": reportComputedStack,
"--buildpacks-global-stack": reportGlobalStack,
"--buildpacks-list": reportList,
"--buildpacks-stack": reportStack,
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{
"--buildpacks-global-stack": reportGlobalStack,
}
} else {
flags = map[string]common.ReportFunc{
"--buildpacks-computed-stack": reportComputedStack,
"--buildpacks-global-stack": reportGlobalStack,
"--buildpacks-list": reportList,
"--buildpacks-stack": reportStack,
}
}
flagKeys := []string{}

View File

@@ -54,11 +54,14 @@ func main() {
case "report":
args := flag.NewFlagSet("buildpacks:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
osArgs, infoFlag, flagErr := common.ParseReportArgs("buildpacks", os.Args[2:])
reportArgs, flagErr := common.ParseReportArgs("buildpacks", os.Args[2:])
if flagErr == nil {
args.Parse(osArgs)
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
err = buildpacks.CommandReport(appName, *format, infoFlag)
if reportArgs.IsGlobal {
appName = "--global"
}
err = buildpacks.CommandReport(appName, *format, reportArgs.InfoFlag)
}
case "set":
args := flag.NewFlagSet("buildpacks:set", flag.ExitOnError)

View File

@@ -33,9 +33,13 @@ cmd-caddy-report() {
declare desc="displays a caddy report for one or more apps"
declare cmd="caddy:report"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" INFO_FLAG="$2"
fn-report-parse-args "$@"
set -- "${REPORT_ARGS[@]}"
declare APP="${1:-}" INFO_FLAG="${2:-}"
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
if [[ "$REPORT_IS_GLOBAL" == "true" ]]; then
APP="--global"
elif [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
INFO_FLAG="$APP"
APP=""
fi
@@ -44,32 +48,56 @@ cmd-caddy-report() {
INFO_FLAG="true"
fi
if [[ -z "$APP" ]]; then
if [[ "$APP" == "--global" ]]; then
cmd-caddy-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
elif [[ -z "$APP" ]]; then
for app in $(dokku_apps); do
cmd-caddy-report-single "$app" "$INFO_FLAG" | tee || true
cmd-caddy-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true
done
else
cmd-caddy-report-single "$APP" "$INFO_FLAG"
cmd-caddy-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
fi
}
cmd-caddy-report-single() {
declare APP="$1" INFO_FLAG="$2"
declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}"
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
local flag_map=(
"--caddy-image: $(fn-caddy-image)"
"--caddy-letsencrypt-email: $(fn-caddy-letsencrypt-email)"
"--caddy-letsencrypt-server: $(fn-caddy-letsencrypt-server)"
"--caddy-log-level: $(fn-caddy-log-level)"
"--caddy-polling-interval: $(fn-caddy-polling-interval)"
"--caddy-tls-internal: $(fn-caddy-tls-internal "$APP")"
)
local flag_map=()
if [[ "$APP" == "--global" ]]; then
flag_map=(
"--caddy-image: $(fn-caddy-image)"
"--caddy-letsencrypt-email: $(fn-caddy-letsencrypt-email)"
"--caddy-letsencrypt-server: $(fn-caddy-letsencrypt-server)"
"--caddy-log-level: $(fn-caddy-log-level)"
"--caddy-polling-interval: $(fn-caddy-polling-interval)"
)
else
verify_app_name "$APP"
flag_map=(
"--caddy-image: $(fn-caddy-image)"
"--caddy-letsencrypt-email: $(fn-caddy-letsencrypt-email)"
"--caddy-letsencrypt-server: $(fn-caddy-letsencrypt-server)"
"--caddy-log-level: $(fn-caddy-log-level)"
"--caddy-polling-interval: $(fn-caddy-polling-interval)"
"--caddy-tls-internal: $(fn-caddy-tls-internal "$APP")"
)
fi
fn-report-validate-format "$FORMAT" "$INFO_FLAG"
if [[ "$FORMAT" == "json" ]]; then
fn-report-emit-json flag_map "caddy"
return
fi
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "${APP} caddy information"
if [[ "$APP" == "--global" ]]; then
dokku_log_info2_quiet "global caddy information"
else
dokku_log_info2_quiet "${APP} caddy information"
fi
for flag in "${flag_map[@]}"; do
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"

View File

@@ -8,9 +8,13 @@ cmd-certs-report() {
declare desc="displays an ssl report for one or more apps"
declare cmd="certs:report"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" INFO_FLAG="$2"
fn-report-parse-args "$@"
set -- "${REPORT_ARGS[@]}"
declare APP="${1:-}" INFO_FLAG="${2:-}"
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
if [[ "$REPORT_IS_GLOBAL" == "true" ]]; then
APP="--global"
elif [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
INFO_FLAG="$APP"
APP=""
fi
@@ -19,34 +23,50 @@ cmd-certs-report() {
INFO_FLAG="true"
fi
if [[ -z "$APP" ]]; then
if [[ "$APP" == "--global" ]]; then
cmd-certs-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
elif [[ -z "$APP" ]]; then
for app in $(dokku_apps); do
cmd-certs-report-single "$app" "$INFO_FLAG" | tee || true
cmd-certs-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true
done
else
cmd-certs-report-single "$APP" "$INFO_FLAG"
cmd-certs-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
fi
}
cmd-certs-report-single() {
declare APP="$1" INFO_FLAG="$2"
declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}"
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
local flag_map=(
"--ssl-dir: $DOKKU_ROOT/$APP/tls"
"--ssl-enabled: $(fn-ssl-enabled "$APP")"
"--ssl-hostnames: $(fn-ssl-hostnames "$APP")"
"--ssl-expires-at: $(fn-ssl-expires-at "$APP")"
"--ssl-issuer: $(fn-ssl-issuer "$APP")"
"--ssl-starts-at: $(fn-ssl-starts-at "$APP")"
"--ssl-subject: $(fn-ssl-subject "$APP")"
"--ssl-verified: $(fn-ssl-verified "$APP")"
)
local flag_map=()
if [[ "$APP" != "--global" ]]; then
verify_app_name "$APP"
flag_map=(
"--ssl-dir: $DOKKU_ROOT/$APP/tls"
"--ssl-enabled: $(fn-ssl-enabled "$APP")"
"--ssl-hostnames: $(fn-ssl-hostnames "$APP")"
"--ssl-expires-at: $(fn-ssl-expires-at "$APP")"
"--ssl-issuer: $(fn-ssl-issuer "$APP")"
"--ssl-starts-at: $(fn-ssl-starts-at "$APP")"
"--ssl-subject: $(fn-ssl-subject "$APP")"
"--ssl-verified: $(fn-ssl-verified "$APP")"
)
fi
fn-report-validate-format "$FORMAT" "$INFO_FLAG"
if [[ "$FORMAT" == "json" ]]; then
fn-report-emit-json flag_map "ssl"
return
fi
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "$APP ssl information"
if [[ "$APP" == "--global" ]]; then
dokku_log_info2_quiet "global ssl information"
else
dokku_log_info2_quiet "$APP ssl information"
fi
for flag in "${flag_map[@]}"; do
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"

View File

@@ -9,9 +9,13 @@ cmd-checks-report() {
declare desc="shows reports for an app"
declare cmd="checks:report"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" INFO_FLAG="$2"
fn-report-parse-args "$@"
set -- "${REPORT_ARGS[@]}"
declare APP="${1:-}" INFO_FLAG="${2:-}"
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
if [[ "$REPORT_IS_GLOBAL" == "true" ]]; then
APP="--global"
elif [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
INFO_FLAG="$APP"
APP=""
fi
@@ -20,31 +24,51 @@ cmd-checks-report() {
INFO_FLAG="true"
fi
if [[ -z "$APP" ]]; then
if [[ "$APP" == "--global" ]]; then
cmd-checks-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
elif [[ -z "$APP" ]]; then
for app in $(dokku_apps); do
cmd-checks-report-single "$app" "$INFO_FLAG" | tee || true
cmd-checks-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true
done
else
cmd-checks-report-single "$APP" "$INFO_FLAG"
cmd-checks-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
fi
}
cmd-checks-report-single() {
declare APP="$1" INFO_FLAG="$2"
declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}"
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
local flag_map=(
"--checks-disabled-list: $(fn-checks-disabled-list "$APP")"
"--checks-skipped-list: $(fn-checks-skipped-list "$APP")"
"--checks-computed-wait-to-retire: $(fn-checks-computed-wait-to-retire "$APP")"
"--checks-global-wait-to-retire: $(fn-checks-global-wait-to-retire "$APP")"
"--checks-wait-to-retire: $(fn-checks-wait-to-retire "$APP")"
)
local flag_map=()
if [[ "$APP" == "--global" ]]; then
flag_map=(
"--checks-global-wait-to-retire: $(fn-checks-global-wait-to-retire "$APP")"
)
else
verify_app_name "$APP"
flag_map=(
"--checks-disabled-list: $(fn-checks-disabled-list "$APP")"
"--checks-skipped-list: $(fn-checks-skipped-list "$APP")"
"--checks-computed-wait-to-retire: $(fn-checks-computed-wait-to-retire "$APP")"
"--checks-global-wait-to-retire: $(fn-checks-global-wait-to-retire "$APP")"
"--checks-wait-to-retire: $(fn-checks-wait-to-retire "$APP")"
)
fi
fn-report-validate-format "$FORMAT" "$INFO_FLAG"
if [[ "$FORMAT" == "json" ]]; then
fn-report-emit-json flag_map "checks"
return
fi
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "$APP checks information"
if [[ "$APP" == "--global" ]]; then
dokku_log_info2_quiet "global checks information"
else
dokku_log_info2_quiet "$APP checks information"
fi
for flag in "${flag_map[@]}"; do
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"

View File

@@ -713,10 +713,18 @@ func GetenvWithDefault(key string, defaultValue string) (val string) {
return
}
// ReportArgs holds the parsed inputs to a :report subcommand
type ReportArgs struct {
OSArgs []string
InfoFlag string
IsGlobal bool
}
// ParseReportArgs splits out flags from non-flags for input into report commands
func ParseReportArgs(pluginName string, arguments []string) ([]string, string, error) {
func ParseReportArgs(pluginName string, arguments []string) (ReportArgs, error) {
osArgs := []string{}
infoFlags := []string{}
isGlobal := false
skipNext := false
for i, argument := range arguments {
if skipNext {
@@ -728,6 +736,10 @@ func ParseReportArgs(pluginName string, arguments []string) ([]string, string, e
skipNext = true
continue
}
if argument == "--global" {
isGlobal = true
continue
}
if strings.HasPrefix(argument, "--") {
infoFlags = append(infoFlags, argument)
} else {
@@ -736,12 +748,12 @@ func ParseReportArgs(pluginName string, arguments []string) ([]string, string, e
}
if len(infoFlags) == 0 {
return osArgs, "", nil
return ReportArgs{OSArgs: osArgs, IsGlobal: isGlobal}, nil
}
if len(infoFlags) == 1 {
return osArgs, infoFlags[0], nil
return ReportArgs{OSArgs: osArgs, InfoFlag: infoFlags[0], IsGlobal: isGlobal}, nil
}
return osArgs, "", fmt.Errorf("%s:report command allows only a single flag", pluginName)
return ReportArgs{OSArgs: osArgs, IsGlobal: isGlobal}, fmt.Errorf("%s:report command allows only a single flag", pluginName)
}
// ParseScaleOutput allows golang plugins to properly parse the output of ps-current-scale

View File

@@ -115,3 +115,81 @@ func TestCommonStripInlineComments(t *testing.T) {
text := StripInlineComments(strings.Join([]string{testEnvLine, "# testing comment"}, " "))
Expect(text).To(Equal(testEnvLine))
}
func TestParseReportArgsEmpty(t *testing.T) {
RegisterTestingT(t)
args, err := ParseReportArgs("scheduler", []string{})
Expect(err).NotTo(HaveOccurred())
Expect(args.IsGlobal).To(BeFalse())
Expect(args.InfoFlag).To(Equal(""))
Expect(args.OSArgs).To(BeEmpty())
}
func TestParseReportArgsAppOnly(t *testing.T) {
RegisterTestingT(t)
args, err := ParseReportArgs("scheduler", []string{"myapp"})
Expect(err).NotTo(HaveOccurred())
Expect(args.IsGlobal).To(BeFalse())
Expect(args.InfoFlag).To(Equal(""))
Expect(args.OSArgs).To(Equal([]string{"myapp"}))
}
func TestParseReportArgsFormatJSON(t *testing.T) {
RegisterTestingT(t)
args, err := ParseReportArgs("scheduler", []string{"myapp", "--format", "json"})
Expect(err).NotTo(HaveOccurred())
Expect(args.IsGlobal).To(BeFalse())
Expect(args.InfoFlag).To(Equal(""))
Expect(args.OSArgs).To(Equal([]string{"myapp", "--format", "json"}))
}
func TestParseReportArgsGlobalAlone(t *testing.T) {
RegisterTestingT(t)
args, err := ParseReportArgs("scheduler", []string{"--global"})
Expect(err).NotTo(HaveOccurred())
Expect(args.IsGlobal).To(BeTrue())
Expect(args.InfoFlag).To(Equal(""))
Expect(args.OSArgs).To(BeEmpty())
}
func TestParseReportArgsGlobalWithFormat(t *testing.T) {
RegisterTestingT(t)
args, err := ParseReportArgs("scheduler", []string{"--global", "--format", "json"})
Expect(err).NotTo(HaveOccurred())
Expect(args.IsGlobal).To(BeTrue())
Expect(args.InfoFlag).To(Equal(""))
Expect(args.OSArgs).To(Equal([]string{"--format", "json"}))
}
func TestParseReportArgsInfoFlag(t *testing.T) {
RegisterTestingT(t)
args, err := ParseReportArgs("scheduler", []string{"myapp", "--scheduler-selected"})
Expect(err).NotTo(HaveOccurred())
Expect(args.IsGlobal).To(BeFalse())
Expect(args.InfoFlag).To(Equal("--scheduler-selected"))
Expect(args.OSArgs).To(Equal([]string{"myapp"}))
}
func TestParseReportArgsAppThenGlobal(t *testing.T) {
RegisterTestingT(t)
args, err := ParseReportArgs("scheduler", []string{"myapp", "--global"})
Expect(err).NotTo(HaveOccurred())
Expect(args.IsGlobal).To(BeTrue())
Expect(args.InfoFlag).To(Equal(""))
Expect(args.OSArgs).To(Equal([]string{"myapp"}))
}
func TestParseReportArgsGlobalWithInfoFlag(t *testing.T) {
RegisterTestingT(t)
args, err := ParseReportArgs("scheduler", []string{"--global", "--scheduler-global-selected"})
Expect(err).NotTo(HaveOccurred())
Expect(args.IsGlobal).To(BeTrue())
Expect(args.InfoFlag).To(Equal("--scheduler-global-selected"))
Expect(args.OSArgs).To(BeEmpty())
}
func TestParseReportArgsMultipleInfoFlags(t *testing.T) {
RegisterTestingT(t)
_, err := ParseReportArgs("scheduler", []string{"--scheduler-selected", "--scheduler-global-selected"})
Expect(err).To(HaveOccurred())
}

View File

@@ -958,3 +958,62 @@ fn-registry-docker-config-dir() {
echo "$config_dir"
fi
}
fn-report-parse-args() {
declare desc="strips --format and --global flags from a report invocation, populating REPORT_FORMAT, REPORT_IS_GLOBAL, REPORT_ARGS"
REPORT_FORMAT="stdout"
REPORT_IS_GLOBAL="false"
REPORT_ARGS=()
while [[ $# -gt 0 ]]; do
case "$1" in
--format)
REPORT_FORMAT="$2"
shift 2
;;
--global)
REPORT_IS_GLOBAL="true"
shift
;;
*)
REPORT_ARGS+=("$1")
shift
;;
esac
done
}
fn-report-emit-json() {
declare desc="serializes a flag_map array (passed by name) as a JSON object, stripping the --<prefix>- prefix from each key"
declare flag_map_name="$1" prefix="$2"
local -n flag_map_ref="$flag_map_name"
local json_output="{}"
for flag in "${flag_map_ref[@]}"; do
local key value
key="$(echo "$flag" | cut -d':' -f1 | sed "s/^--${prefix}-//")"
value="$(echo "$flag" | cut -d':' -f2- | sed 's/^ //')"
json_output="$(echo "$json_output" | jq -c --arg key "$key" --arg value "$value" '. + {($key): $value}')"
done
echo "$json_output"
}
fn-report-filter-global() {
declare desc="filters a flag_map array (passed by name) in place, keeping only entries with -global- in their flag name"
declare flag_map_name="$1"
local -n flag_map_ref="$flag_map_name"
local filtered=()
for flag in "${flag_map_ref[@]}"; do
local key="$(echo "$flag" | cut -d':' -f1)"
if [[ "$key" == *"-global-"* ]]; then
filtered+=("$flag")
fi
done
flag_map_ref=("${filtered[@]}")
}
fn-report-validate-format() {
declare desc="rejects --format json when an info flag is also specified"
declare FORMAT="$1" INFO_FLAG="$2"
if [[ "$FORMAT" != "stdout" ]] && [[ -n "$INFO_FLAG" ]]; then
dokku_log_fail "--format flag cannot be specified when specifying an info flag"
fi
}

View File

@@ -10,22 +10,33 @@ import (
// ReportSingleApp is an internal function that displays the cron report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if err := common.VerifyAppName(appName); err != nil {
return err
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
flags := map[string]common.ReportFunc{
"--cron-mailfrom": reportMailfrom,
"--cron-mailto": reportMailto,
"--cron-task-count": reportTasks,
"--cron-global-maintenance": reportGlobalMaintenance,
"--cron-computed-maintenance": reportComputedMaintenance,
"--cron-maintenance": reportMaintenance,
}
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{
"--cron-mailfrom": reportMailfrom,
"--cron-mailto": reportMailto,
"--cron-global-maintenance": reportGlobalMaintenance,
}
} else {
flags = map[string]common.ReportFunc{
"--cron-mailfrom": reportMailfrom,
"--cron-mailto": reportMailto,
"--cron-task-count": reportTasks,
"--cron-global-maintenance": reportGlobalMaintenance,
"--cron-computed-maintenance": reportComputedMaintenance,
"--cron-maintenance": reportMaintenance,
}
extraFlags := addCronMaintenanceFlags(appName, infoFlag)
for flag, fn := range extraFlags {
flags[flag] = fn
extraFlags := addCronMaintenanceFlags(appName, infoFlag)
for flag, fn := range extraFlags {
flags[flag] = fn
}
}
flagKeys := []string{}

View File

@@ -31,11 +31,14 @@ func main() {
case "report":
args := flag.NewFlagSet("cron:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
osArgs, infoFlag, flagErr := common.ParseReportArgs("cron", os.Args[2:])
reportArgs, flagErr := common.ParseReportArgs("cron", os.Args[2:])
if flagErr == nil {
args.Parse(osArgs)
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
err = cron.CommandReport(appName, *format, infoFlag)
if reportArgs.IsGlobal {
appName = "--global"
}
err = cron.CommandReport(appName, *format, reportArgs.InfoFlag)
}
case "resume":
args := flag.NewFlagSet("cron:resume", flag.ExitOnError)

View File

@@ -12,14 +12,21 @@ import (
// Process-scoped options surface as dynamic per-process keys, one per
// configured process+phase combination.
func ReportSingleApp(appName string, format string, infoFlag string) error {
if err := common.VerifyAppName(appName); err != nil {
return err
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
flags := map[string]common.ReportFunc{
"--docker-options-build": reportBuildOptions,
"--docker-options-deploy": reportDeployOptions,
"--docker-options-run": reportRunOptions,
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{}
} else {
flags = map[string]common.ReportFunc{
"--docker-options-build": reportBuildOptions,
"--docker-options-deploy": reportDeployOptions,
"--docker-options-run": reportRunOptions,
}
}
processTypes, err := ListProcessTypesWithOptions(appName)

View File

@@ -84,11 +84,14 @@ func main() {
case "report":
args := flag.NewFlagSet("docker-options:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
osArgs, infoFlag, flagErr := common.ParseReportArgs("docker-options", os.Args[2:])
reportArgs, flagErr := common.ParseReportArgs("docker-options", os.Args[2:])
if flagErr == nil {
args.Parse(osArgs)
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
err = dockeroptions.CommandReport(appName, *format, infoFlag)
if reportArgs.IsGlobal {
appName = "--global"
}
err = dockeroptions.CommandReport(appName, *format, reportArgs.InfoFlag)
} else {
err = flagErr
}

View File

@@ -8,14 +8,15 @@ cmd-domains-report() {
declare desc="displays a domains report for one or more apps"
declare cmd="domains:report"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" INFO_FLAG="$2"
fn-report-parse-args "$@"
set -- "${REPORT_ARGS[@]}"
declare APP="${1:-}" INFO_FLAG="${2:-}"
if [[ "$APP" == "--global" ]]; then
cmd-domains-report-single "$APP" "$INFO_FLAG"
return
fi
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
if [[ "$REPORT_IS_GLOBAL" == "true" ]]; then
APP="--global"
elif [[ "$APP" == "--global" ]]; then
:
elif [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
INFO_FLAG="$APP"
APP=""
fi
@@ -24,17 +25,19 @@ cmd-domains-report() {
INFO_FLAG="true"
fi
if [[ -z "$APP" ]]; then
if [[ "$APP" == "--global" ]]; then
cmd-domains-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
elif [[ -z "$APP" ]]; then
for app in $(dokku_apps); do
cmd-domains-report-single "$app" "$INFO_FLAG" | tee || true
cmd-domains-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true
done
else
cmd-domains-report-single "$APP" "$INFO_FLAG"
cmd-domains-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
fi
}
cmd-domains-report-single() {
declare APP="$1" INFO_FLAG="$2"
declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}"
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
@@ -55,6 +58,13 @@ cmd-domains-report-single() {
flag_map=("${app_flags[@]}" "${global_flags[@]}")
fn-report-validate-format "$FORMAT" "$INFO_FLAG"
if [[ "$FORMAT" == "json" ]]; then
fn-report-emit-json flag_map "domains"
return
fi
if [[ -z "$INFO_FLAG" ]]; then
if [[ "$APP" == "--global" ]]; then
dokku_log_info2_quiet "Global domains information"

View File

@@ -316,25 +316,14 @@ cmd-git-report() {
declare desc="displays a git report for one or more apps"
declare cmd="git:report"
[[ "$1" == "$cmd" ]] && shift 1
local FORMAT="stdout"
local args=()
fn-report-parse-args "$@"
set -- "${REPORT_ARGS[@]}"
while [[ $# -gt 0 ]]; do
case "$1" in
--format)
FORMAT="$2"
shift 2
;;
*)
args+=("$1")
shift
;;
esac
done
declare APP="${1:-}" INFO_FLAG="${2:-}"
declare APP="${args[0]:-}" INFO_FLAG="${args[1]:-}"
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
if [[ "$REPORT_IS_GLOBAL" == "true" ]]; then
APP="--global"
elif [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
INFO_FLAG="$APP"
APP=""
fi
@@ -343,12 +332,14 @@ cmd-git-report() {
INFO_FLAG="true"
fi
if [[ -z "$APP" ]]; then
if [[ "$APP" == "--global" ]]; then
cmd-git-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
elif [[ -z "$APP" ]]; then
for app in $(dokku_apps); do
cmd-git-report-single "$app" "$INFO_FLAG" "$FORMAT" | tee || true
cmd-git-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true
done
else
cmd-git-report-single "$APP" "$INFO_FLAG" "$FORMAT"
cmd-git-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
fi
}
@@ -358,35 +349,37 @@ cmd-git-report-single() {
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
local flag_map=(
"--git-deploy-branch: $(fn-plugin-property-get "git" "$APP" "deploy-branch" "master")"
"--git-global-deploy-branch: $(fn-plugin-property-get "git" "--global" "deploy-branch" "master")"
"--git-keep-git-dir: $(fn-plugin-property-get "git" "$APP" "keep-git-dir" "false")"
"--git-rev-env-var: $(fn-plugin-property-get "git" "$APP" "rev-env-var" "GIT_REV")"
"--git-sha: $(fn-git-cmd "$APP_ROOT" rev-parse HEAD 2>/dev/null || false)"
"--git-source-image: $(fn-git-source-image "$APP")"
"--git-last-updated-at: $(fn-git-last-updated-at "$APP")"
)
if [[ "$FORMAT" != "stdout" ]] && [[ -n "$INFO_FLAG" ]]; then
dokku_log_fail "--format flag cannot be specified when specifying an info flag"
local flag_map=()
if [[ "$APP" == "--global" ]]; then
flag_map=(
"--git-global-deploy-branch: $(fn-plugin-property-get "git" "--global" "deploy-branch" "master")"
)
else
verify_app_name "$APP"
flag_map=(
"--git-deploy-branch: $(fn-plugin-property-get "git" "$APP" "deploy-branch" "master")"
"--git-global-deploy-branch: $(fn-plugin-property-get "git" "--global" "deploy-branch" "master")"
"--git-keep-git-dir: $(fn-plugin-property-get "git" "$APP" "keep-git-dir" "false")"
"--git-rev-env-var: $(fn-plugin-property-get "git" "$APP" "rev-env-var" "GIT_REV")"
"--git-sha: $(fn-git-cmd "$APP_ROOT" rev-parse HEAD 2>/dev/null || false)"
"--git-source-image: $(fn-git-source-image "$APP")"
"--git-last-updated-at: $(fn-git-last-updated-at "$APP")"
)
fi
fn-report-validate-format "$FORMAT" "$INFO_FLAG"
if [[ "$FORMAT" == "json" ]]; then
local json_output="{}"
for flag in "${flag_map[@]}"; do
local key value
key="$(echo "$flag" | cut -d':' -f1 | sed 's/^--git-//')"
value="$(echo "$flag" | cut -d':' -f2- | sed 's/^ //')"
json_output="$(echo "$json_output" | jq -c --arg key "$key" --arg value "$value" '. + {($key): $value}')"
done
echo "$json_output"
fn-report-emit-json flag_map "git"
return
fi
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "${APP} git information"
if [[ "$APP" == "--global" ]]; then
dokku_log_info2_quiet "global git information"
else
dokku_log_info2_quiet "${APP} git information"
fi
for flag in "${flag_map[@]}"; do
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"

View File

@@ -33,9 +33,13 @@ cmd-haproxy-report() {
declare desc="displays a haproxy report for one or more apps"
declare cmd="haproxy:report"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" INFO_FLAG="$2"
fn-report-parse-args "$@"
set -- "${REPORT_ARGS[@]}"
declare APP="${1:-}" INFO_FLAG="${2:-}"
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
if [[ "$REPORT_IS_GLOBAL" == "true" ]]; then
APP="--global"
elif [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
INFO_FLAG="$APP"
APP=""
fi
@@ -44,21 +48,25 @@ cmd-haproxy-report() {
INFO_FLAG="true"
fi
if [[ -z "$APP" ]]; then
if [[ "$APP" == "--global" ]]; then
cmd-haproxy-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
elif [[ -z "$APP" ]]; then
for app in $(dokku_apps); do
cmd-haproxy-report-single "$app" "$INFO_FLAG" | tee || true
cmd-haproxy-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true
done
else
cmd-haproxy-report-single "$APP" "$INFO_FLAG"
cmd-haproxy-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
fi
}
cmd-haproxy-report-single() {
declare APP="$1" INFO_FLAG="$2"
declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}"
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
if [[ "$APP" != "--global" ]]; then
verify_app_name "$APP"
fi
local flag_map=(
"--haproxy-image: $(fn-haproxy-image)"
"--haproxy-letsencrypt-email: $(fn-haproxy-letsencrypt-email)"
@@ -66,8 +74,19 @@ cmd-haproxy-report-single() {
"--haproxy-log-level: $(fn-haproxy-log-level)"
)
fn-report-validate-format "$FORMAT" "$INFO_FLAG"
if [[ "$FORMAT" == "json" ]]; then
fn-report-emit-json flag_map "haproxy"
return
fi
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "${APP} haproxy information"
if [[ "$APP" == "--global" ]]; then
dokku_log_info2_quiet "global haproxy information"
else
dokku_log_info2_quiet "${APP} haproxy information"
fi
for flag in "${flag_map[@]}"; do
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"

View File

@@ -9,22 +9,34 @@ import (
// ReportSingleApp is an internal function that displays the logs report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if err := common.VerifyAppName(appName); err != nil {
return err
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
os.Setenv("DOKKU_REPORT_FORMAT", format)
os.Setenv("DOKKU_REPORT_FLAG", infoFlag)
flags := map[string]common.ReportFunc{
"--logs-computed-app-label-alias": reportComputedAppLabelAlias,
"--logs-computed-max-size": reportComputedMaxSize,
"--logs-global-app-label-alias": reportGlobalAppLabelAlias,
"--logs-global-max-size": reportGlobalMaxSize,
"--logs-global-vector-sink": reportGlobalVectorSink,
"--logs-app-label-alias": reportAppLabelAlias,
"--logs-max-size": reportMaxSize,
"--logs-vector-global-image": reportVectorGlobalImage,
"--logs-vector-sink": reportVectorSink,
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{
"--logs-global-app-label-alias": reportGlobalAppLabelAlias,
"--logs-global-max-size": reportGlobalMaxSize,
"--logs-global-vector-sink": reportGlobalVectorSink,
"--logs-vector-global-image": reportVectorGlobalImage,
}
} else {
flags = map[string]common.ReportFunc{
"--logs-computed-app-label-alias": reportComputedAppLabelAlias,
"--logs-computed-max-size": reportComputedMaxSize,
"--logs-global-app-label-alias": reportGlobalAppLabelAlias,
"--logs-global-max-size": reportGlobalMaxSize,
"--logs-global-vector-sink": reportGlobalVectorSink,
"--logs-app-label-alias": reportAppLabelAlias,
"--logs-max-size": reportMaxSize,
"--logs-vector-global-image": reportVectorGlobalImage,
"--logs-vector-sink": reportVectorSink,
}
}
flagKeys := []string{}

View File

@@ -27,11 +27,14 @@ func main() {
case "report":
args := flag.NewFlagSet("logs:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
osArgs, infoFlag, flagErr := common.ParseReportArgs("logs", os.Args[2:])
reportArgs, flagErr := common.ParseReportArgs("logs", os.Args[2:])
if flagErr == nil {
args.Parse(osArgs)
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
err = logs.CommandReport(appName, *format, infoFlag)
if reportArgs.IsGlobal {
appName = "--global"
}
err = logs.CommandReport(appName, *format, reportArgs.InfoFlag)
}
case "set":
args := flag.NewFlagSet("logs:set", flag.ExitOnError)

View File

@@ -8,28 +8,41 @@ import (
// ReportSingleApp is an internal function that displays the network report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if err := common.VerifyAppName(appName); err != nil {
return err
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
flags := map[string]common.ReportFunc{
"--network-bind-all-interfaces": reportBindAllInterfaces,
"--network-attach-post-create": reportAttachPostCreate,
"--network-attach-post-deploy": reportAttachPostDeploy,
"--network-computed-attach-post-create": reportComputedAttachPostCreate,
"--network-computed-attach-post-deploy": reportComputedAttachPostDeploy,
"--network-computed-bind-all-interfaces": reportComputedBindAllInterfaces,
"--network-computed-initial-network": reportComputedInitialNetwork,
"--network-computed-tld": reportComputedTld,
"--network-global-attach-post-create": reportGlobalAttachPostCreate,
"--network-global-attach-post-deploy": reportGlobalAttachPostDeploy,
"--network-global-bind-all-interfaces": reportGlobalBindAllInterfaces,
"--network-global-initial-network": reportGlobalInitialNetwork,
"--network-global-tld": reportGlobalTld,
"--network-initial-network": reportInitialNetwork,
"--network-static-web-listener": reportStaticWebListener,
"--network-tld": reportTld,
"--network-web-listeners": reportWebListeners,
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{
"--network-global-attach-post-create": reportGlobalAttachPostCreate,
"--network-global-attach-post-deploy": reportGlobalAttachPostDeploy,
"--network-global-bind-all-interfaces": reportGlobalBindAllInterfaces,
"--network-global-initial-network": reportGlobalInitialNetwork,
"--network-global-tld": reportGlobalTld,
}
} else {
flags = map[string]common.ReportFunc{
"--network-bind-all-interfaces": reportBindAllInterfaces,
"--network-attach-post-create": reportAttachPostCreate,
"--network-attach-post-deploy": reportAttachPostDeploy,
"--network-computed-attach-post-create": reportComputedAttachPostCreate,
"--network-computed-attach-post-deploy": reportComputedAttachPostDeploy,
"--network-computed-bind-all-interfaces": reportComputedBindAllInterfaces,
"--network-computed-initial-network": reportComputedInitialNetwork,
"--network-computed-tld": reportComputedTld,
"--network-global-attach-post-create": reportGlobalAttachPostCreate,
"--network-global-attach-post-deploy": reportGlobalAttachPostDeploy,
"--network-global-bind-all-interfaces": reportGlobalBindAllInterfaces,
"--network-global-initial-network": reportGlobalInitialNetwork,
"--network-global-tld": reportGlobalTld,
"--network-initial-network": reportInitialNetwork,
"--network-static-web-listener": reportStaticWebListener,
"--network-tld": reportTld,
"--network-web-listeners": reportWebListeners,
}
}
flagKeys := []string{}

View File

@@ -57,11 +57,14 @@ func main() {
case "report":
args := flag.NewFlagSet("network:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
osArgs, infoFlag, flagErr := common.ParseReportArgs("network", os.Args[2:])
reportArgs, flagErr := common.ParseReportArgs("network", os.Args[2:])
if flagErr == nil {
args.Parse(osArgs)
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
err = network.CommandReport(appName, *format, infoFlag)
if reportArgs.IsGlobal {
appName = "--global"
}
err = network.CommandReport(appName, *format, reportArgs.InfoFlag)
}
case "set":
args := flag.NewFlagSet("network:set", flag.ExitOnError)

View File

@@ -10,25 +10,14 @@ cmd-nginx-report() {
declare desc="displays a nginx report for one or more apps"
declare cmd="nginx:report"
[[ "$1" == "$cmd" ]] && shift 1
local FORMAT="stdout"
local args=()
fn-report-parse-args "$@"
set -- "${REPORT_ARGS[@]}"
while [[ $# -gt 0 ]]; do
case "$1" in
--format)
FORMAT="$2"
shift 2
;;
*)
args+=("$1")
shift
;;
esac
done
declare APP="${1:-}" INFO_FLAG="${2:-}"
declare APP="${args[0]:-}" INFO_FLAG="${args[1]:-}"
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
if [[ "$REPORT_IS_GLOBAL" == "true" ]]; then
APP="--global"
elif [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
INFO_FLAG="$APP"
APP=""
fi
@@ -37,12 +26,14 @@ cmd-nginx-report() {
INFO_FLAG="true"
fi
if [[ -z "$APP" ]]; then
if [[ "$APP" == "--global" ]]; then
cmd-nginx-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
elif [[ -z "$APP" ]]; then
for app in $(dokku_apps); do
cmd-nginx-report-single "$app" "$INFO_FLAG" "$FORMAT" | tee || true
cmd-nginx-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true
done
else
cmd-nginx-report-single "$APP" "$INFO_FLAG" "$FORMAT"
cmd-nginx-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
fi
}
@@ -51,7 +42,9 @@ cmd-nginx-report-single() {
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
if [[ "$APP" != "--global" ]]; then
verify_app_name "$APP"
fi
local flag_map=(
"--nginx-access-log-format: $(fn-nginx-access-log-format "$APP")"
"--nginx-computed-access-log-format: $(fn-nginx-computed-access-log-format "$APP")"
@@ -146,24 +139,23 @@ cmd-nginx-report-single() {
"--nginx-global-x-forwarded-ssl: $(fn-nginx-global-x-forwarded-ssl "$APP")"
)
if [[ "$FORMAT" != "stdout" ]] && [[ -n "$INFO_FLAG" ]]; then
dokku_log_fail "--format flag cannot be specified when specifying an info flag"
if [[ "$APP" == "--global" ]]; then
fn-report-filter-global flag_map
fi
fn-report-validate-format "$FORMAT" "$INFO_FLAG"
if [[ "$FORMAT" == "json" ]]; then
local json_output="{}"
for flag in "${flag_map[@]}"; do
local key value
key="$(echo "$flag" | cut -d':' -f1 | sed 's/^--nginx-//')"
value="$(echo "$flag" | cut -d':' -f2- | sed 's/^ //')"
json_output="$(echo "$json_output" | jq -c --arg key "$key" --arg value "$value" '. + {($key): $value}')"
done
echo "$json_output"
fn-report-emit-json flag_map "nginx"
return
fi
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "${APP} nginx information"
if [[ "$APP" == "--global" ]]; then
dokku_log_info2_quiet "global nginx information"
else
dokku_log_info2_quiet "${APP} nginx information"
fi
for flag in "${flag_map[@]}"; do
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"

View File

@@ -33,9 +33,13 @@ cmd-openresty-report() {
declare desc="displays a openresty report for one or more apps"
declare cmd="openresty:report"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" INFO_FLAG="$2"
fn-report-parse-args "$@"
set -- "${REPORT_ARGS[@]}"
declare APP="${1:-}" INFO_FLAG="${2:-}"
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
if [[ "$REPORT_IS_GLOBAL" == "true" ]]; then
APP="--global"
elif [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
INFO_FLAG="$APP"
APP=""
fi
@@ -44,59 +48,83 @@ cmd-openresty-report() {
INFO_FLAG="true"
fi
if [[ -z "$APP" ]]; then
if [[ "$APP" == "--global" ]]; then
cmd-openresty-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
elif [[ -z "$APP" ]]; then
for app in $(dokku_apps); do
cmd-openresty-report-single "$app" "$INFO_FLAG" | tee || true
cmd-openresty-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true
done
else
cmd-openresty-report-single "$APP" "$INFO_FLAG"
cmd-openresty-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
fi
}
cmd-openresty-report-single() {
declare APP="$1" INFO_FLAG="$2"
declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}"
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
local flag_map=(
"--openresty-access-log-format: $(fn-openresty-access-log-format "$APP")"
"--openresty-access-log-path: $(fn-openresty-access-log-path "$APP")"
"--openresty-allowed-letsencrypt-domains-func-base64: $(fn-openresty-allowed-letsencrypt-domains-func-base64)"
"--openresty-bind-address-ipv4: $(fn-openresty-bind-address-ipv4 "$APP")"
"--openresty-bind-address-ipv6: $(fn-openresty-bind-address-ipv6 "$APP")"
"--openresty-client-body-timeout: $(fn-openresty-client-body-timeout "$APP")"
"--openresty-client-header-timeout: $(fn-openresty-client-header-timeout "$APP")"
"--openresty-client-max-body-size: $(fn-openresty-client-max-body-size "$APP")"
"--openresty-error-log-path: $(fn-openresty-error-log-path "$APP")"
"--openresty-global-hsts: $(fn-plugin-property-get-default "openresty" "--global" "hsts" "true")"
"--openresty-computed-hsts: $(fn-openresty-hsts-is-enabled "$APP")"
"--openresty-hsts: $(fn-plugin-property-get-default "openresty" "$APP" "hsts" "")"
"--openresty-hsts-include-subdomains: $(fn-openresty-hsts-include-subdomains "$APP")"
"--openresty-hsts-max-age: $(fn-openresty-hsts-max-age "$APP")"
"--openresty-hsts-preload: $(fn-openresty-hsts-preload "$APP")"
"--openresty-image: $(fn-openresty-image)"
"--openresty-keepalive-timeout: $(fn-openresty-keepalive-timeout "$APP")"
"--openresty-letsencrypt-email: $(fn-openresty-letsencrypt-email)"
"--openresty-letsencrypt-server: $(fn-openresty-letsencrypt-server)"
"--openresty-lingering-timeout: $(fn-openresty-lingering-timeout "$APP")"
"--openresty-proxy-buffer-size: $(fn-openresty-proxy-buffer-size "$APP")"
"--openresty-proxy-buffering: $(fn-openresty-proxy-buffering "$APP")"
"--openresty-proxy-buffers: $(fn-openresty-proxy-buffers "$APP")"
"--openresty-proxy-busy-buffers-size: $(fn-openresty-proxy-busy-buffers-size "$APP")"
"--openresty-proxy-connect-timeout: $(fn-openresty-proxy-connect-timeout "$APP")"
"--openresty-proxy-read-timeout: $(fn-openresty-proxy-read-timeout "$APP")"
"--openresty-proxy-send-timeout: $(fn-openresty-proxy-send-timeout "$APP")"
"--openresty-send-timeout: $(fn-openresty-send-timeout "$APP")"
"--openresty-underscore-in-headers: $(fn-openresty-underscore-in-headers "$APP")"
"--openresty-x-forwarded-for-value: $(fn-openresty-x-forwarded-for-value "$APP")"
"--openresty-x-forwarded-port-value: $(fn-openresty-x-forwarded-port-value "$APP")"
"--openresty-x-forwarded-proto-value: $(fn-openresty-x-forwarded-proto-value "$APP")"
"--openresty-x-forwarded-ssl: $(fn-openresty-x-forwarded-ssl "$APP")"
)
local flag_map=()
if [[ "$APP" == "--global" ]]; then
flag_map=(
"--openresty-allowed-letsencrypt-domains-func-base64: $(fn-openresty-allowed-letsencrypt-domains-func-base64)"
"--openresty-global-hsts: $(fn-plugin-property-get-default "openresty" "--global" "hsts" "true")"
"--openresty-image: $(fn-openresty-image)"
"--openresty-letsencrypt-email: $(fn-openresty-letsencrypt-email)"
"--openresty-letsencrypt-server: $(fn-openresty-letsencrypt-server)"
)
else
verify_app_name "$APP"
flag_map=(
"--openresty-access-log-format: $(fn-openresty-access-log-format "$APP")"
"--openresty-access-log-path: $(fn-openresty-access-log-path "$APP")"
"--openresty-allowed-letsencrypt-domains-func-base64: $(fn-openresty-allowed-letsencrypt-domains-func-base64)"
"--openresty-bind-address-ipv4: $(fn-openresty-bind-address-ipv4 "$APP")"
"--openresty-bind-address-ipv6: $(fn-openresty-bind-address-ipv6 "$APP")"
"--openresty-client-body-timeout: $(fn-openresty-client-body-timeout "$APP")"
"--openresty-client-header-timeout: $(fn-openresty-client-header-timeout "$APP")"
"--openresty-client-max-body-size: $(fn-openresty-client-max-body-size "$APP")"
"--openresty-error-log-path: $(fn-openresty-error-log-path "$APP")"
"--openresty-global-hsts: $(fn-plugin-property-get-default "openresty" "--global" "hsts" "true")"
"--openresty-computed-hsts: $(fn-openresty-hsts-is-enabled "$APP")"
"--openresty-hsts: $(fn-plugin-property-get-default "openresty" "$APP" "hsts" "")"
"--openresty-hsts-include-subdomains: $(fn-openresty-hsts-include-subdomains "$APP")"
"--openresty-hsts-max-age: $(fn-openresty-hsts-max-age "$APP")"
"--openresty-hsts-preload: $(fn-openresty-hsts-preload "$APP")"
"--openresty-image: $(fn-openresty-image)"
"--openresty-keepalive-timeout: $(fn-openresty-keepalive-timeout "$APP")"
"--openresty-letsencrypt-email: $(fn-openresty-letsencrypt-email)"
"--openresty-letsencrypt-server: $(fn-openresty-letsencrypt-server)"
"--openresty-lingering-timeout: $(fn-openresty-lingering-timeout "$APP")"
"--openresty-proxy-buffer-size: $(fn-openresty-proxy-buffer-size "$APP")"
"--openresty-proxy-buffering: $(fn-openresty-proxy-buffering "$APP")"
"--openresty-proxy-buffers: $(fn-openresty-proxy-buffers "$APP")"
"--openresty-proxy-busy-buffers-size: $(fn-openresty-proxy-busy-buffers-size "$APP")"
"--openresty-proxy-connect-timeout: $(fn-openresty-proxy-connect-timeout "$APP")"
"--openresty-proxy-read-timeout: $(fn-openresty-proxy-read-timeout "$APP")"
"--openresty-proxy-send-timeout: $(fn-openresty-proxy-send-timeout "$APP")"
"--openresty-send-timeout: $(fn-openresty-send-timeout "$APP")"
"--openresty-underscore-in-headers: $(fn-openresty-underscore-in-headers "$APP")"
"--openresty-x-forwarded-for-value: $(fn-openresty-x-forwarded-for-value "$APP")"
"--openresty-x-forwarded-port-value: $(fn-openresty-x-forwarded-port-value "$APP")"
"--openresty-x-forwarded-proto-value: $(fn-openresty-x-forwarded-proto-value "$APP")"
"--openresty-x-forwarded-ssl: $(fn-openresty-x-forwarded-ssl "$APP")"
)
fi
fn-report-validate-format "$FORMAT" "$INFO_FLAG"
if [[ "$FORMAT" == "json" ]]; then
fn-report-emit-json flag_map "openresty"
return
fi
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "${APP} openresty information"
if [[ "$APP" == "--global" ]]; then
dokku_log_info2_quiet "global openresty information"
else
dokku_log_info2_quiet "${APP} openresty information"
fi
for flag in "${flag_map[@]}"; do
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"

View File

@@ -8,13 +8,20 @@ import (
// ReportSingleApp is an internal function that displays the ports report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if err := common.VerifyAppName(appName); err != nil {
return err
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
flags := map[string]common.ReportFunc{
"--ports-map": reportPortMap,
"--ports-map-detected": reportPortMapDetected,
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{}
} else {
flags = map[string]common.ReportFunc{
"--ports-map": reportPortMap,
"--ports-map-detected": reportPortMapDetected,
}
}
flagKeys := []string{}

View File

@@ -49,11 +49,14 @@ func main() {
case "report":
args := flag.NewFlagSet("ports:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
osArgs, infoFlag, flagErr := common.ParseReportArgs("ports", os.Args[2:])
reportArgs, flagErr := common.ParseReportArgs("ports", os.Args[2:])
if flagErr == nil {
args.Parse(osArgs)
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
err = ports.CommandReport(appName, *format, infoFlag)
if reportArgs.IsGlobal {
appName = "--global"
}
err = ports.CommandReport(appName, *format, reportArgs.InfoFlag)
}
default:
err = fmt.Errorf("Invalid plugin subcommand call: %s", subcommand)

View File

@@ -6,15 +6,24 @@ import (
// ReportSingleApp is an internal function that displays the proxy report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if err := common.VerifyAppName(appName); err != nil {
return err
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
flags := map[string]common.ReportFunc{
"--proxy-enabled": reportEnabled,
"--proxy-computed-type": reportComputedType,
"--proxy-global-type": reportGlobalType,
"--proxy-type": reportType,
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{
"--proxy-global-type": reportGlobalType,
}
} else {
flags = map[string]common.ReportFunc{
"--proxy-enabled": reportEnabled,
"--proxy-computed-type": reportComputedType,
"--proxy-global-type": reportGlobalType,
"--proxy-type": reportType,
}
}
flagKeys := []string{}

View File

@@ -48,11 +48,14 @@ func main() {
case "report":
args := flag.NewFlagSet("proxy:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
osArgs, infoFlag, flagErr := common.ParseReportArgs("proxy", os.Args[2:])
reportArgs, flagErr := common.ParseReportArgs("proxy", os.Args[2:])
if flagErr == nil {
args.Parse(osArgs)
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
err = proxy.CommandReport(appName, *format, infoFlag)
if reportArgs.IsGlobal {
appName = "--global"
}
err = proxy.CommandReport(appName, *format, reportArgs.InfoFlag)
}
case "set":
args := flag.NewFlagSet("proxy:set", flag.ExitOnError)

View File

@@ -10,28 +10,38 @@ import (
// ReportSingleApp is an internal function that displays the ps report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if err := common.VerifyAppName(appName); err != nil {
return err
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
flags := map[string]common.ReportFunc{
"--deployed": reportDeployed,
"--processes": reportProcesses,
"--ps-can-scale": reportCanScale,
"--ps-restart-policy": reportRestartPolicy,
"--ps-computed-procfile-path": reportComputedProcfilePath,
"--ps-global-procfile-path": reportGlobalProcfilePath,
"--ps-procfile-path": reportProcfilePath,
"--restore": reportRestore,
"--running": reportRunningState,
"--global-stop-timeout-seconds": reportGlobalStopTimeoutSeconds,
"--computed-stop-timeout-seconds": reportComputedStopTimeoutSeconds,
"--stop-timeout-seconds": reportStopTimeoutSeconds,
}
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{
"--ps-global-procfile-path": reportGlobalProcfilePath,
"--global-stop-timeout-seconds": reportGlobalStopTimeoutSeconds,
}
} else {
flags = map[string]common.ReportFunc{
"--deployed": reportDeployed,
"--processes": reportProcesses,
"--ps-can-scale": reportCanScale,
"--ps-restart-policy": reportRestartPolicy,
"--ps-computed-procfile-path": reportComputedProcfilePath,
"--ps-global-procfile-path": reportGlobalProcfilePath,
"--ps-procfile-path": reportProcfilePath,
"--restore": reportRestore,
"--running": reportRunningState,
"--global-stop-timeout-seconds": reportGlobalStopTimeoutSeconds,
"--computed-stop-timeout-seconds": reportComputedStopTimeoutSeconds,
"--stop-timeout-seconds": reportStopTimeoutSeconds,
}
extraFlags := addStatusFlags(appName, infoFlag)
for flag, fn := range extraFlags {
flags[flag] = fn
extraFlags := addStatusFlags(appName, infoFlag)
for flag, fn := range extraFlags {
flags[flag] = fn
}
}
flagKeys := []string{}

View File

@@ -33,11 +33,14 @@ func main() {
case "report":
args := flag.NewFlagSet("ps:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
osArgs, infoFlag, flagErr := common.ParseReportArgs("ps", os.Args[2:])
reportArgs, flagErr := common.ParseReportArgs("ps", os.Args[2:])
if flagErr == nil {
args.Parse(osArgs)
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
err = ps.CommandReport(appName, *format, infoFlag)
if reportArgs.IsGlobal {
appName = "--global"
}
err = ps.CommandReport(appName, *format, reportArgs.InfoFlag)
}
case "restart":
args := flag.NewFlagSet("ps:restart", flag.ExitOnError)

View File

@@ -8,22 +8,33 @@ import (
// ReportSingleApp is an internal function that displays the registry report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if err := common.VerifyAppName(appName); err != nil {
return err
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
flags := map[string]common.ReportFunc{
"--registry-computed-image-repo": reportComputedImageRepo,
"--registry-image-repo": reportImageRepo,
"--registry-computed-push-on-release": reportComputedPushOnRelease,
"--registry-global-push-on-release": reportGlobalPushOnRelease,
"--registry-push-on-release": reportPushOnRelease,
"--registry-computed-server": reportComputedServer,
"--registry-global-server": reportGlobalServer,
"--registry-global-image-repo-template": reportGlobalImageRepoTemplate,
"--registry-server": reportServer,
"--registry-tag-version": reportTagVersion,
"--registry-push-extra-tags": reportPushExtraTags,
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{
"--registry-global-push-on-release": reportGlobalPushOnRelease,
"--registry-global-server": reportGlobalServer,
"--registry-global-image-repo-template": reportGlobalImageRepoTemplate,
}
} else {
flags = map[string]common.ReportFunc{
"--registry-computed-image-repo": reportComputedImageRepo,
"--registry-image-repo": reportImageRepo,
"--registry-computed-push-on-release": reportComputedPushOnRelease,
"--registry-global-push-on-release": reportGlobalPushOnRelease,
"--registry-push-on-release": reportPushOnRelease,
"--registry-computed-server": reportComputedServer,
"--registry-global-server": reportGlobalServer,
"--registry-global-image-repo-template": reportGlobalImageRepoTemplate,
"--registry-server": reportServer,
"--registry-tag-version": reportTagVersion,
"--registry-push-extra-tags": reportPushExtraTags,
}
}
flagKeys := []string{}

View File

@@ -84,11 +84,14 @@ func main() {
case "report":
args := flag.NewFlagSet("registry:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
osArgs, infoFlag, flagErr := common.ParseReportArgs("registry", os.Args[2:])
reportArgs, flagErr := common.ParseReportArgs("registry", os.Args[2:])
if flagErr == nil {
args.Parse(osArgs)
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
err = registry.CommandReport(appName, *format, infoFlag)
if reportArgs.IsGlobal {
appName = "--global"
}
err = registry.CommandReport(appName, *format, reportArgs.InfoFlag)
}
case "set":
args := flag.NewFlagSet("registry:set", flag.ExitOnError)

View File

@@ -19,8 +19,10 @@ type Resource struct {
// ReportSingleApp is an internal function that displays the resource report for one or more apps
func ReportSingleApp(appName, format, infoFlag string) error {
if err := common.VerifyAppName(appName); err != nil {
return err
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
resources, err := common.PropertyGetAll("resource", appName)

View File

@@ -51,11 +51,14 @@ func main() {
case "report":
args := flag.NewFlagSet("resource:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
osArgs, infoFlag, flagErr := common.ParseReportArgs("resource", os.Args[2:])
reportArgs, flagErr := common.ParseReportArgs("resource", os.Args[2:])
if flagErr == nil {
args.Parse(osArgs)
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
err = resource.CommandReport(appName, *format, infoFlag)
if reportArgs.IsGlobal {
appName = "--global"
}
err = resource.CommandReport(appName, *format, reportArgs.InfoFlag)
}
case "reserve":
args := flag.NewFlagSet("resource:reserve", flag.ExitOnError)

View File

@@ -9,9 +9,13 @@ cmd-scheduler-docker-local-report() {
declare desc="displays a scheduler-docker-local report for one or more apps"
declare cmd="scheduler-docker-local:report"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" INFO_FLAG="$2"
fn-report-parse-args "$@"
set -- "${REPORT_ARGS[@]}"
declare APP="${1:-}" INFO_FLAG="${2:-}"
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
if [[ "$REPORT_IS_GLOBAL" == "true" ]]; then
APP="--global"
elif [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
INFO_FLAG="$APP"
APP=""
fi
@@ -20,28 +24,43 @@ cmd-scheduler-docker-local-report() {
INFO_FLAG="true"
fi
if [[ -z "$APP" ]]; then
if [[ "$APP" == "--global" ]]; then
cmd-scheduler-docker-local-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
elif [[ -z "$APP" ]]; then
for app in $(dokku_apps); do
cmd-scheduler-docker-local-report-single "$app" "$INFO_FLAG" | tee || true
cmd-scheduler-docker-local-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true
done
else
cmd-scheduler-docker-local-report-single "$APP" "$INFO_FLAG"
cmd-scheduler-docker-local-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
fi
}
cmd-scheduler-docker-local-report-single() {
declare APP="$1" INFO_FLAG="$2"
declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}"
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
if [[ "$APP" != "--global" ]]; then
verify_app_name "$APP"
fi
local flag_map=(
"--scheduler-docker-local-init-process: $(fn-plugin-property-get "scheduler-docker-local" "$APP" "init-process" "true")"
"--scheduler-docker-local-parallel-schedule-count: $(fn-plugin-property-get "scheduler-docker-local" "$APP" "parallel-schedule-count" "")"
)
fn-report-validate-format "$FORMAT" "$INFO_FLAG"
if [[ "$FORMAT" == "json" ]]; then
fn-report-emit-json flag_map "scheduler-docker-local"
return
fi
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "${APP} scheduler-docker-local information"
if [[ "$APP" == "--global" ]]; then
dokku_log_info2_quiet "global scheduler-docker-local information"
else
dokku_log_info2_quiet "${APP} scheduler-docker-local information"
fi
for flag in "${flag_map[@]}"; do
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"

View File

@@ -9,38 +9,59 @@ import (
// ReportSingleApp is an internal function that displays the scheduler-k3s report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if err := common.VerifyAppName(appName); err != nil {
return err
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
flags := map[string]common.ReportFunc{
"--scheduler-k3s-computed-deploy-timeout": reportComputedDeployTimeout,
"--scheduler-k3s-deploy-timeout": reportDeployTimeout,
"--scheduler-k3s-global-deploy-timeout": reportGlobalDeployTimeout,
"--scheduler-k3s-computed-image-pull-secrets": reportComputedImagePullSecrets,
"--scheduler-k3s-image-pull-secrets": reportImagePullSecrets,
"--scheduler-k3s-global-image-pull-secrets": reportGlobalImagePullSecrets,
"--scheduler-k3s-global-kubeconfig-path": reportGlobalKubeconfigPath,
"--scheduler-k3s-global-kube-context": reportGlobalKubeContext,
"--scheduler-k3s-computed-letsencrypt-server": reportComputedLetsencryptServer,
"--scheduler-k3s-letsencrypt-server": reportLetsencryptServer,
"--scheduler-k3s-global-letsencrypt-server": reportGlobalLetsencryptServer,
"--scheduler-k3s-global-ingress-class": reportGlobalIngressClass,
"--scheduler-k3s-global-letsencrypt-email-prod": reportGlobalLetsencryptEmailProd,
"--scheduler-k3s-global-letsencrypt-email-stag": reportGlobalLetsencryptEmailStag,
"--scheduler-k3s-computed-kustomize-root-path": reportComputedKustomizeRootPath,
"--scheduler-k3s-kustomize-root-path": reportKustomizeRootPath,
"--scheduler-k3s-global-kustomize-root-path": reportGlobalKustomizeRootPath,
"--scheduler-k3s-computed-namespace": reportComputedNamespace,
"--scheduler-k3s-namespace": reportNamespace,
"--scheduler-k3s-global-namespace": reportGlobalNamespace,
"--scheduler-k3s-global-network-interface": reportGlobalNetworkInterface,
"--scheduler-k3s-computed-rollback-on-failure": reportComputedRollbackOnFailure,
"--scheduler-k3s-rollback-on-failure": reportRollbackOnFailure,
"--scheduler-k3s-global-rollback-on-failure": reportGlobalRollbackOnFailure,
"--scheduler-k3s-computed-shm-size": reportComputedShmSize,
"--scheduler-k3s-global-shm-size": reportGlobalShmSize,
"--scheduler-k3s-shm-size": reportShmSize,
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{
"--scheduler-k3s-global-deploy-timeout": reportGlobalDeployTimeout,
"--scheduler-k3s-global-image-pull-secrets": reportGlobalImagePullSecrets,
"--scheduler-k3s-global-kubeconfig-path": reportGlobalKubeconfigPath,
"--scheduler-k3s-global-kube-context": reportGlobalKubeContext,
"--scheduler-k3s-global-letsencrypt-server": reportGlobalLetsencryptServer,
"--scheduler-k3s-global-ingress-class": reportGlobalIngressClass,
"--scheduler-k3s-global-letsencrypt-email-prod": reportGlobalLetsencryptEmailProd,
"--scheduler-k3s-global-letsencrypt-email-stag": reportGlobalLetsencryptEmailStag,
"--scheduler-k3s-global-kustomize-root-path": reportGlobalKustomizeRootPath,
"--scheduler-k3s-global-namespace": reportGlobalNamespace,
"--scheduler-k3s-global-network-interface": reportGlobalNetworkInterface,
"--scheduler-k3s-global-rollback-on-failure": reportGlobalRollbackOnFailure,
"--scheduler-k3s-global-shm-size": reportGlobalShmSize,
}
} else {
flags = map[string]common.ReportFunc{
"--scheduler-k3s-computed-deploy-timeout": reportComputedDeployTimeout,
"--scheduler-k3s-deploy-timeout": reportDeployTimeout,
"--scheduler-k3s-global-deploy-timeout": reportGlobalDeployTimeout,
"--scheduler-k3s-computed-image-pull-secrets": reportComputedImagePullSecrets,
"--scheduler-k3s-image-pull-secrets": reportImagePullSecrets,
"--scheduler-k3s-global-image-pull-secrets": reportGlobalImagePullSecrets,
"--scheduler-k3s-global-kubeconfig-path": reportGlobalKubeconfigPath,
"--scheduler-k3s-global-kube-context": reportGlobalKubeContext,
"--scheduler-k3s-computed-letsencrypt-server": reportComputedLetsencryptServer,
"--scheduler-k3s-letsencrypt-server": reportLetsencryptServer,
"--scheduler-k3s-global-letsencrypt-server": reportGlobalLetsencryptServer,
"--scheduler-k3s-global-ingress-class": reportGlobalIngressClass,
"--scheduler-k3s-global-letsencrypt-email-prod": reportGlobalLetsencryptEmailProd,
"--scheduler-k3s-global-letsencrypt-email-stag": reportGlobalLetsencryptEmailStag,
"--scheduler-k3s-computed-kustomize-root-path": reportComputedKustomizeRootPath,
"--scheduler-k3s-kustomize-root-path": reportKustomizeRootPath,
"--scheduler-k3s-global-kustomize-root-path": reportGlobalKustomizeRootPath,
"--scheduler-k3s-computed-namespace": reportComputedNamespace,
"--scheduler-k3s-namespace": reportNamespace,
"--scheduler-k3s-global-namespace": reportGlobalNamespace,
"--scheduler-k3s-global-network-interface": reportGlobalNetworkInterface,
"--scheduler-k3s-computed-rollback-on-failure": reportComputedRollbackOnFailure,
"--scheduler-k3s-rollback-on-failure": reportRollbackOnFailure,
"--scheduler-k3s-global-rollback-on-failure": reportGlobalRollbackOnFailure,
"--scheduler-k3s-computed-shm-size": reportComputedShmSize,
"--scheduler-k3s-global-shm-size": reportGlobalShmSize,
"--scheduler-k3s-shm-size": reportShmSize,
}
}
chartProperties, err := common.PropertyGetAllByPrefix("scheduler-k3s", "--global", "chart.")

View File

@@ -126,11 +126,14 @@ func main() {
case "report":
args := flag.NewFlagSet("scheduler-k3s:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
osArgs, infoFlag, flagErr := common.ParseReportArgs("scheduler-k3s", os.Args[2:])
reportArgs, flagErr := common.ParseReportArgs("scheduler-k3s", os.Args[2:])
if flagErr == nil {
args.Parse(osArgs)
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
err = scheduler_k3s.CommandReport(appName, *format, infoFlag)
if reportArgs.IsGlobal {
appName = "--global"
}
err = scheduler_k3s.CommandReport(appName, *format, reportArgs.InfoFlag)
}
case "set":
args := flag.NewFlagSet("scheduler-k3s:set", flag.ExitOnError)

View File

@@ -6,14 +6,23 @@ import (
// ReportSingleApp is an internal function that displays the scheduler report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if err := common.VerifyAppName(appName); err != nil {
return err
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
flags := map[string]common.ReportFunc{
"--scheduler-computed-selected": reportComputedSelected,
"--scheduler-global-selected": reportGlobalSelected,
"--scheduler-selected": reportSelected,
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{
"--scheduler-global-selected": reportGlobalSelected,
}
} else {
flags = map[string]common.ReportFunc{
"--scheduler-computed-selected": reportComputedSelected,
"--scheduler-global-selected": reportGlobalSelected,
"--scheduler-selected": reportSelected,
}
}
flagKeys := []string{}

View File

@@ -21,11 +21,14 @@ func main() {
case "report":
args := flag.NewFlagSet("scheduler:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
osArgs, infoFlag, flagErr := common.ParseReportArgs("scheduler", os.Args[2:])
reportArgs, flagErr := common.ParseReportArgs("scheduler", os.Args[2:])
if flagErr == nil {
args.Parse(osArgs)
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
err = scheduler.CommandReport(appName, *format, infoFlag)
if reportArgs.IsGlobal {
appName = "--global"
}
err = scheduler.CommandReport(appName, *format, reportArgs.InfoFlag)
}
case "set":
args := flag.NewFlagSet("scheduler:set", flag.ExitOnError)

View File

@@ -3,14 +3,21 @@ package storage
import "github.com/dokku/dokku/plugins/common"
func ReportSingleApp(appName string, format string, infoFlag string) error {
if err := common.VerifyAppName(appName); err != nil {
return err
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
flags := map[string]common.ReportFunc{
"--storage-build-mounts": reportBuildMounts,
"--storage-deploy-mounts": reportDeployMounts,
"--storage-run-mounts": reportRunMounts,
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{}
} else {
flags = map[string]common.ReportFunc{
"--storage-build-mounts": reportBuildMounts,
"--storage-deploy-mounts": reportDeployMounts,
"--storage-run-mounts": reportRunMounts,
}
}
flagKeys := []string{}

View File

@@ -40,11 +40,14 @@ func main() {
case "report":
args := flag.NewFlagSet("storage:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
osArgs, infoFlag, flagErr := common.ParseReportArgs("storage", os.Args[2:])
reportArgs, flagErr := common.ParseReportArgs("storage", os.Args[2:])
if flagErr == nil {
args.Parse(osArgs)
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
err = storage.CommandReport(appName, *format, infoFlag)
if reportArgs.IsGlobal {
appName = "--global"
}
err = storage.CommandReport(appName, *format, reportArgs.InfoFlag)
}
case "unmount":
args := flag.NewFlagSet("storage:unmount", flag.ExitOnError)

View File

@@ -33,16 +33,12 @@ cmd-traefik-report() {
declare desc="displays a traefik report for one or more apps"
declare cmd="traefik:report"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" INFO_FLAG="$2"
local FORMAT="stdout"
fn-report-parse-args "$@"
set -- "${REPORT_ARGS[@]}"
declare APP="${1:-}" INFO_FLAG="${2:-}"
if [[ -n "$APP" ]] && [[ "$APP" == "--format" ]]; then
FORMAT="$INFO_FLAG"
APP=""
INFO_FLAG=""
elif [[ -n "$INFO_FLAG" ]] && [[ "$INFO_FLAG" == "--format" ]]; then
FORMAT="$3"
INFO_FLAG=""
if [[ "$REPORT_IS_GLOBAL" == "true" ]]; then
APP="--global"
elif [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
INFO_FLAG="$APP"
APP=""
@@ -52,12 +48,14 @@ cmd-traefik-report() {
INFO_FLAG="true"
fi
if [[ -z "$APP" ]]; then
if [[ "$APP" == "--global" ]]; then
cmd-traefik-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
elif [[ -z "$APP" ]]; then
for app in $(dokku_apps); do
cmd-traefik-report-single "$app" "$INFO_FLAG" "$FORMAT" | tee || true
cmd-traefik-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true
done
else
cmd-traefik-report-single "$APP" "$INFO_FLAG" "$FORMAT"
cmd-traefik-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
fi
}
@@ -66,7 +64,9 @@ cmd-traefik-report-single() {
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
if [[ "$APP" != "--global" ]]; then
verify_app_name "$APP"
fi
local flag_map=(
"--traefik-api-enabled: $(fn-traefik-api-enabled)"
"--traefik-api-entry-point: $(fn-traefik-api-entry-point)"
@@ -85,7 +85,6 @@ cmd-traefik-report-single() {
"--traefik-https-entry-point: $(fn-traefik-https-entry-point)"
)
# Get dns-provider-* env vars and add them (masked for stdout, unmasked for json)
local dns_provider_env_vars
dns_provider_env_vars="$(fn-traefik-dns-provider-env-vars)"
if [[ -n "$dns_provider_env_vars" ]]; then
@@ -103,17 +102,19 @@ cmd-traefik-report-single() {
done <<<"$dns_provider_env_vars"
fi
fn-report-validate-format "$FORMAT" "$INFO_FLAG"
if [[ "$FORMAT" == "json" ]]; then
local json_output="{}"
for flag in "${flag_map[@]}"; do
local key value
key="$(echo "$flag" | cut -d':' -f1 | sed 's/^--traefik-//')"
value="$(echo "$flag" | cut -d':' -f2- | sed 's/^ //')"
json_output="$(echo "$json_output" | jq -c --arg key "$key" --arg value "$value" '. + {($key): $value}')"
done
echo "$json_output"
elif [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "${APP} traefik information"
fn-report-emit-json flag_map "traefik"
return
fi
if [[ -z "$INFO_FLAG" ]]; then
if [[ "$APP" == "--global" ]]; then
dokku_log_info2_quiet "global traefik information"
else
dokku_log_info2_quiet "${APP} traefik information"
fi
for flag in "${flag_map[@]}"; do
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"

View File

@@ -12,6 +12,31 @@ teardown() {
destroy_app
}
@test "(builder-dockerfile:report) --global --format json" {
run /bin/bash -c "dokku builder-dockerfile:report --global --format json | jq -e ."
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku builder-dockerfile:report --global --format json | jq -r '.\"global-dockerfile-path\"'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "Dockerfile"
run /bin/bash -c "dokku builder-dockerfile:report --global --format json | jq -r 'has(\"dockerfile-path\")'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "false"
run /bin/bash -c "dokku builder-dockerfile:report --global"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "global builder-dockerfile information"
}
@test "(builder-dockerfile:set)" {
run deploy_app dockerfile
echo "output: $output"

View File

@@ -175,6 +175,40 @@ teardown() {
assert_line 0 "herokuish"
}
@test "(builder:report) --global --format json" {
run /bin/bash -c "dokku builder:set --global selected dockerfile"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku builder:report --global --format json | jq -e ."
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku builder:report --global --format json | jq -r '.\"builder-global-selected\"'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "dockerfile"
run /bin/bash -c "dokku builder:report --global --format json | jq -r 'has(\"builder-selected\")'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "false"
run /bin/bash -c "dokku builder:report --global"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku builder:set --global selected"
echo "output: $output"
echo "status: $status"
assert_success
}
@test "(builder:set)" {
run deploy_app python
echo "output: $output"

View File

@@ -41,6 +41,20 @@ teardown() {
assert_output "$help_output"
}
@test "(certs:report) --global --format json" {
run /bin/bash -c "dokku certs:report --global --format json | jq -e ."
echo "output: $output"
echo "status: $status"
assert_success
assert_output "{}"
run /bin/bash -c "dokku certs:report --global"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "global ssl information"
}
@test "(certs) certs:add" {
run /bin/bash -c "dokku certs:add $TEST_APP $BATS_TMPDIR/tls/server.crt $BATS_TMPDIR/tls/server.key"
echo "output: $output"

View File

@@ -16,6 +16,41 @@ teardown() {
global_teardown
}
@test "(checks:report) --global --format json" {
run /bin/bash -c "dokku checks:set --global wait-to-retire 90"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku checks:report --global --format json | jq -e ."
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku checks:report --global --format json | jq -r '.\"global-wait-to-retire\"'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "90"
run /bin/bash -c "dokku checks:report --global --format json | jq -r 'has(\"wait-to-retire\")'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "false"
run /bin/bash -c "dokku checks:report --global"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "global checks information"
run /bin/bash -c "dokku checks:set --global wait-to-retire"
echo "output: $output"
echo "status: $status"
assert_success
}
@test "(checks) checks:help" {
run /bin/bash -c "dokku checks"
echo "output: $output"

View File

@@ -102,6 +102,28 @@ teardown() {
assert_output_contains "python3 task.py daily"
}
@test "(cron:report) --global --format json" {
run /bin/bash -c "dokku cron:set --global mailto admin@example.com"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku cron:report --global --format json | jq -e ."
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku cron:report --global"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku cron:set --global mailto"
echo "output: $output"
echo "status: $status"
assert_success
}
@test "(cron) create [multiple]" {
run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_valid_multiple
echo "output: $output"

View File

@@ -28,6 +28,25 @@ teardown() {
assert_output "$help_output"
}
@test "(domains:report) --global --format json" {
run /bin/bash -c "dokku domains:report --global --format json | jq -e ."
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku domains:report --global --format json | jq -r 'keys[]' | grep -v 'global-' | wc -l"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "0"
run /bin/bash -c "dokku domains:report --global"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "Global domains information"
}
@test "(domains) domains" {
run /bin/bash -c "dokku domains:report $TEST_APP 2>/dev/null | grep ${TEST_APP}.${DOKKU_DOMAIN}"
echo "output: $output"

View File

@@ -831,3 +831,31 @@ teardown() {
assert_failure
assert_output_contains "--format flag cannot be specified when specifying an info flag"
}
@test "(git:report) --global" {
run /bin/bash -c "dokku git:report --global"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "global git information"
assert_output_contains "Global deploy branch"
}
@test "(git:report) --global --format json" {
run /bin/bash -c "dokku git:report --global --format json | jq -e ."
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku git:report --global --format json | jq -r '.\"global-deploy-branch\"'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "master"
run /bin/bash -c "dokku git:report --global --format json | jq -r 'has(\"deploy-branch\")'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "false"
}

View File

@@ -31,6 +31,41 @@ teardown() {
assert_output "$help_output"
}
@test "(network:report) --global --format json" {
run /bin/bash -c "dokku network:set --global tld dokku.test"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku network:report --global --format json | jq -e ."
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku network:report --global --format json | jq -r '.\"network-global-tld\"'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "dokku.test"
run /bin/bash -c "dokku network:report --global --format json | jq -r 'has(\"network-tld\")'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "false"
run /bin/bash -c "dokku network:report --global"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "--global"
run /bin/bash -c "dokku network:set --global tld"
echo "output: $output"
echo "status: $status"
assert_success
}
@test "(network) network:set bind-all-interfaces" {
run deploy_app
echo "output: $output"

View File

@@ -62,6 +62,25 @@ teardown() {
assert_output_contains "--format flag cannot be specified when specifying an info flag"
}
@test "(nginx:report) --global --format json" {
run /bin/bash -c "dokku nginx:report --global --format json | jq -e ."
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku nginx:report --global --format json | jq -r 'keys[]' | grep -v 'global-' | wc -l"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "0"
run /bin/bash -c "dokku nginx:report --global"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "global nginx information"
}
@test "(nginx-vhosts) proxy:build-config (domains:disable/enable)" {
run deploy_app
echo "output: $output"