diff --git a/docs/advanced-usage/builds.md b/docs/advanced-usage/builds.md index 91e31ef4b..82e81a720 100644 --- a/docs/advanced-usage/builds.md +++ b/docs/advanced-usage/builds.md @@ -169,3 +169,26 @@ Available flags: - `--builds-computed-retention`: the resolved retention applied to this app `--build-status` returns the **display** status, so an abandoned in-flight build shows `abandoned` rather than `running`. The raw on-disk status is only visible by reading the JSON record directly. + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `retention` | app + global | `20` | `--builds-retention`, `--builds-global-retention`, `--builds-computed-retention` | Number of recent build records kept per app; older finalized records are pruned at the end of each deploy | + +### Read-only flags + +The following flags surface in `builds:report` but are not managed by `builds:set` - they are derived metadata recorded during the build: + +| Flag | Description | +|---|---| +| `--build-id` | Unique identifier of the most recent build for the app | +| `--build-kind` | Whether the record was a `build` or a `deploy` | +| `--build-status` | Display status (`running`, `succeeded`, `failed`, `canceled`, `abandoned`); computed at read time | +| `--build-source` | Trigger that started the build (e.g. `git-hook`, `ps:rebuild`, `ps:restart`) | +| `--build-pid` | PID of the build process | +| `--build-started-at` | UNIX timestamp the build started | +| `--build-finished-at` | UNIX timestamp the build finished | +| `--build-exit-code` | Exit code of the build process | diff --git a/docs/advanced-usage/deployment-tasks.md b/docs/advanced-usage/deployment-tasks.md index cf4907350..1c278a803 100644 --- a/docs/advanced-usage/deployment-tasks.md +++ b/docs/advanced-usage/deployment-tasks.md @@ -101,18 +101,20 @@ dokku app-json:report ``` =====> node-js-app app-json information App-json computed appjson path: app2.json - App-json global appjson path: app.json + App-json global appjson path: App-json appjson path: app2.json =====> python-sample app-json information App-json computed appjson path: app.json - App-json global appjson path: app.json + App-json global appjson path: App-json appjson path: =====> ruby-sample app-json information App-json computed appjson path: app.json - App-json global appjson path: app.json + App-json global appjson path: App-json appjson path: ``` +The `appjson-path` and `global-appjson-path` keys hold the raw per-app and global value respectively, and are empty when nothing has been set. The `computed-appjson-path` key holds the effective value used at deploy time, falling back to the global value (where one has been set) and then to the built-in default of `app.json`. + You can run the command for a specific app also. ```shell @@ -122,7 +124,7 @@ dokku app-json:report node-js-app ``` =====> node-js-app app-json information App-json computed appjson path: app2.json - App-json global appjson path: app.json + App-json global appjson path: App-json appjson path: app2.json ``` diff --git a/docs/advanced-usage/docker-options.md b/docs/advanced-usage/docker-options.md index 0d70721f2..326f76862 100644 --- a/docs/advanced-usage/docker-options.md +++ b/docs/advanced-usage/docker-options.md @@ -230,3 +230,13 @@ The `docker-options:list` command prints the options stored for a single process dokku docker-options:list node-js-app --process web --phase deploy dokku docker-options:list node-js-app --phase deploy ``` + +## Properties + +### Internal properties + +The following property is recorded internally by the docker-options plugin and is not exposed via `docker-options:report`: + +| Property | Description | Source | +|---|---|---| +| `migrated-from-files` | Global migration sentinel that records that the legacy `DOCKER_OPTIONS_` flat-file store has been drained into plugin properties | `plugins/docker-options/functions.go` writes `"true"` once the install-time migration runs | diff --git a/docs/advanced-usage/registry-management.md b/docs/advanced-usage/registry-management.md index 8f33ee319..51b041493 100644 --- a/docs/advanced-usage/registry-management.md +++ b/docs/advanced-usage/registry-management.md @@ -208,3 +208,15 @@ dokku registry:set node-js-app push-extra-tags # globally dokku registry:set --global push-extra-tags ``` + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `image-repo` | app only | `dokku/` | `--registry-image-repo`, `--registry-computed-image-repo` | Repository name used when pushing the app's image (overrides the global template) | +| `image-repo-template` | global only | `dokku/{{ .AppName }}` | `--registry-global-image-repo-template` | Go template used to compute the per-app image repository when `image-repo` is unset | +| `push-extra-tags` | app + global | none | `--registry-push-extra-tags` | Comma-separated list of additional tags pushed alongside the deploy tag | +| `push-on-release` | app + global | `false` | `--registry-push-on-release`, `--registry-global-push-on-release`, `--registry-computed-push-on-release` | When `true`, pushes the image to the registry on every successful build | +| `server` | app + global | none | `--registry-server`, `--registry-global-server`, `--registry-computed-server` | Registry server host (e.g. `ghcr.io`) used when pushing images | diff --git a/docs/appendices/0.38.0-migration-guide.md b/docs/appendices/0.38.0-migration-guide.md index 6b01d0620..bd1f3f426 100644 --- a/docs/appendices/0.38.0-migration-guide.md +++ b/docs/appendices/0.38.0-migration-guide.md @@ -21,6 +21,7 @@ - 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. +- Every `:report` key of the form `-global-` now returns the raw stored global value (empty when the property has never been set) instead of the resolved value with the built-in default substituted in. A new `-computed-` key has been added wherever a default existed and returns the effective value (per-app value, falling back to the global value, then to the built-in default). This affects `caddy`, `haproxy`, `traefik`, `app-json`, `builder-dockerfile`, `builder-herokuish`, `builder-lambda`, `builder-nixpacks`, `builder-pack`, `builder-railpack`, `checks`, `git`, `logs`, `network`, `proxy`, and `scheduler`. External tooling that read `-global-` and depended on the default value should switch to `-computed-`. The bare `-` keys for caddy/haproxy/traefik global-only properties (`caddy-image`, `haproxy-log-level`, `traefik-api-enabled`, etc.) have also been replaced by the `global-` and `computed-` pair. - The `scheduler-k3s` plugin now manages env config and the dokku-generated image pull Secret as their own helm releases with stable names (`config-{app}` and `pull-secret-{app}`) rather than bundling them into the app helm chart with a per-deploy timestamp suffix (`env-{app}.{ts}` / `ims-{app}.{ts}`). This fixes two bugs: a helm rollback of the app chart no longer deletes Secrets that older ReplicaSets still reference, and the Deployment's `imagePullSecrets` list no longer accumulates references to nonexistent Secrets across deploys. The next deploy of an app switches the Deployment's `envFrom` and `imagePullSecrets` references to the stable names and prunes any leaked entries; existing live Deployments do not need to be patched manually. App rename now also uninstalls the old `tls-{app}`, `config-{app}`, and `pull-secret-{app}` releases under the previous app name; the new name's releases are recreated on the next deploy or certs sync. - The storage plugin now treats persistent volumes as named, scheduler-aware first-class resources via `storage:create`, `storage:mount`, `storage:set`, and `storage:destroy`. The legacy `storage:mount :` colon form continues to work on docker-local apps but is deprecated; on k3s apps it is rejected. Existing colon-form mounts are migrated automatically the first time the new storage plugin runs (during the install trigger) - they appear as `legacy-` entries in `storage:list-entries`. The migration is idempotent and tied to a per-app flag file at `$DOKKU_LIB_ROOT/config/storage/.migrated/`; deleting that file forces a re-scan on the next install. The `storage:ensure-directory` command keeps working but now emits a deprecation warning - prefer `storage:create []` (the path defaults to the same `$DOKKU_LIB_ROOT/data/storage/` location). Storage entry names must now be DNS-1123 labels of 45 characters or less so they can be used verbatim as Helm release and Kubernetes resource names; underscores and uppercase characters that the older `ensure-directory` validator accepted are rejected for new names. The migration synthesizer always uses lowercase hex hashes so existing data is never locked out. diff --git a/docs/appendices/file-formats/app-json.md b/docs/appendices/file-formats/app-json.md index 6a0cf767b..6d4c2554b 100644 --- a/docs/appendices/file-formats/app-json.md +++ b/docs/appendices/file-formats/app-json.md @@ -288,3 +288,11 @@ An autoscaling trigger consists of the following properties: - Example use-cases - Setting up OAuth clients and DNS - Loading seed/test data into the app’s test database + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `appjson-path` | app + global | `app.json` | `--app-json-appjson-path`, `--app-json-global-appjson-path`, `--app-json-computed-appjson-path` | Path within the app to the `app.json` manifest, relative to the build root | diff --git a/docs/configuration/environment-variables.md b/docs/configuration/environment-variables.md index c4f8885ec..8f07fdc6f 100644 --- a/docs/configuration/environment-variables.md +++ b/docs/configuration/environment-variables.md @@ -129,3 +129,13 @@ The following config variables have special meanings and can be set in a variety | `DOKKU_TRACE` | none | `dokku trace:on`
`dokku trace:off`
`--trace` flag | Turn on very verbose debugging. | | `DOKKU_SYSTEM_GROUP` | `dokku` | `/etc/environment`
`~dokku/.dokkurc`
`~dokku/.dokkurc/*` | System group to chown files as. | | `DOKKU_SYSTEM_USER` | `dokku` | `/etc/environment`
`~dokku/.dokkurc`
`~dokku/.dokkurc/*` | System user to chown files as. | + +## Properties + +### Internal properties + +The following property is recorded internally by the config plugin and is not exposed via `config:report`: + +| Property | Description | Source | +|---|---|---| +| `env-migrated` | Migration sentinel that records the per-app or global `DOKKU_*` env-var → property migration completed for 0.38.0 | `plugins/config/triggers.go` writes `"true"` after the upgrade-time pass | diff --git a/docs/configuration/ssl.md b/docs/configuration/ssl.md index 4bf3550cd..a5f492f24 100644 --- a/docs/configuration/ssl.md +++ b/docs/configuration/ssl.md @@ -150,3 +150,20 @@ If an `https:443:*` port mapping already exists when a certificate is installed ### Running behind a proxy (`X-Forwarded-Ssl`, etc.) See the [running behind another proxy documentation](/docs/networking/proxies/nginx.md#running-behind-another-proxy--configuring-x-forwarded--headers) for more information on how to configure your Nginx config when your server is running behind a proxy (e.g. load balancer, etc.). + +## Properties + +### Read-only flags + +The following flags surface in `certs:report` but are not managed by `certs:set` - they are derived from the on-disk certificate: + +| Flag | Description | +|---|---| +| `--ssl-enabled` | `true` when an SSL certificate is installed for the app | +| `--ssl-dir` | Absolute path to the per-app certificate directory | +| `--ssl-hostnames` | Hostnames the certificate covers (CN plus Subject Alternative Names) | +| `--ssl-issuer` | Certificate issuer DN | +| `--ssl-subject` | Certificate subject DN | +| `--ssl-verified` | `true` if the certificate chain verifies against the system CA bundle | +| `--ssl-expires-at` | Certificate `notAfter` timestamp | +| `--ssl-starts-at` | Certificate `notBefore` timestamp | diff --git a/docs/deployment/application-management.md b/docs/deployment/application-management.md index cf1869afd..608e4f655 100644 --- a/docs/deployment/application-management.md +++ b/docs/deployment/application-management.md @@ -312,3 +312,17 @@ You can pass flags which will output only the value of the specific information ```shell dokku apps:report node-js-app --app-dir ``` + +## Properties + +### Read-only flags + +The following flags surface in `apps:report` but are not managed by `apps:set`: + +| Flag | Description | +|---|---| +| `--app-created-at` | UNIX timestamp of app creation | +| `--app-deploy-source` | Source kind of the last deploy (`git`, `archive`, `docker-image`, `git-sync`) | +| `--app-deploy-source-metadata` | Free-form metadata for the deploy source (commit sha, image ref, URL) | +| `--app-dir` | Absolute path of the app root on disk | +| `--app-locked` | `true` while a deploy or rebuild holds the app lock | diff --git a/docs/deployment/builders/builder-management.md b/docs/deployment/builders/builder-management.md index 600478a22..593ce20a0 100644 --- a/docs/deployment/builders/builder-management.md +++ b/docs/deployment/builders/builder-management.md @@ -172,3 +172,21 @@ Custom plugins names _must_ have the prefix `builder-` or builder overriding via Builders can use any tools available on the system to build the docker image, and may even be used to schedule building off-server. The only current requirement is that the image must exist on the server at the end of the `builder-build` command, though this requirement may be relaxed in a future release. For a simple example of how to implement this trigger, see `builder-pack`, which utilizes a cli tool - `pack-cli` - to generate an OCI image that is compatible with Docker and can be scheduled by the official scheduling plugins. + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `build-dir` | app + global | none | `--builder-build-dir`, `--builder-global-build-dir`, `--builder-computed-build-dir` | Subdirectory within the repository to use as the build context | +| `selected` | app + global | none | `--builder-selected`, `--builder-global-selected`, `--builder-computed-selected` | Builder plugin to use; overrides automatic detection | +| `skip-cleanup` | app + global | none | (not in report) | When `true`, leaves intermediate build artifacts in place after the build | + +### Read-only flags + +The following flags surface in `builder:report` but are not managed by `builder:set`: + +| Flag | Description | +|---|---| +| `--builder-detected` | Builder auto-selected for the app when `selected` is unset | diff --git a/docs/deployment/builders/buildpack-management.md b/docs/deployment/builders/buildpack-management.md index a2b876b9f..423c32722 100644 --- a/docs/deployment/builders/buildpack-management.md +++ b/docs/deployment/builders/buildpack-management.md @@ -190,3 +190,13 @@ You can pass flags which will output only the value of the specific information ```shell dokku buildpacks:report node-js-app --buildpacks-list ``` + +## Properties + +### Settable properties + +These properties are managed via `buildpacks:set-property` (the legacy command name for this plugin). + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `stack` | app + global | none | `--buildpacks-stack`, `--buildpacks-global-stack`, `--buildpacks-computed-stack` | Herokuish stack image used to compile the app (e.g. `heroku/heroku:24`) | diff --git a/docs/deployment/builders/cloud-native-buildpacks.md b/docs/deployment/builders/cloud-native-buildpacks.md index f6a3ebb83..7728978aa 100644 --- a/docs/deployment/builders/cloud-native-buildpacks.md +++ b/docs/deployment/builders/cloud-native-buildpacks.md @@ -98,18 +98,20 @@ dokku builder-pack:report ``` =====> node-js-app builder-pack information Builder pack computed projecttoml path: project2.toml - Builder pack global projecttoml path: project.toml + Builder pack global projecttoml path: Builder pack projecttoml path: project2.toml =====> python-sample builder-pack information Builder pack computed projecttoml path: project.toml - Builder pack global projecttoml path: project.toml + Builder pack global projecttoml path: Builder pack projecttoml path: =====> ruby-sample builder-pack information Builder pack computed projecttoml path: project.toml - Builder pack global projecttoml path: project.json + Builder pack global projecttoml path: Builder pack projecttoml path: ``` +The `projecttoml-path` and `global-projecttoml-path` keys hold the raw per-app and global value respectively, and are empty when nothing has been set. The `computed-projecttoml-path` key holds the effective value used at build time, falling back to the global value (where one has been set) and then to the built-in default of `project.toml`. + You can run the command for a specific app also. ```shell @@ -119,7 +121,7 @@ dokku builder-pack:report node-js-app ``` =====> node-js-app builder-pack information Builder pack computed projecttoml path: project2.toml - Builder pack global projecttoml path: project.toml + Builder pack global projecttoml path: Builder pack projecttoml path: project2.toml ``` @@ -165,3 +167,11 @@ dokku buildpacks:set-property --global stack ### Specifying commands via Procfile See the [Procfile documentation](/docs/processes/process-management.md#procfile) for more information on how to specify different processes for your app. + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `projecttoml-path` | app + global | `project.toml` | `--builder-pack-projecttoml-path`, `--builder-pack-global-projecttoml-path`, `--builder-pack-computed-projecttoml-path` | Path within the app to the CNB `project.toml` manifest, relative to the build root | diff --git a/docs/deployment/builders/dockerfiles.md b/docs/deployment/builders/dockerfiles.md index eb8ac066e..ce48be6c1 100644 --- a/docs/deployment/builders/dockerfiles.md +++ b/docs/deployment/builders/dockerfiles.md @@ -82,18 +82,20 @@ dokku builder-dockerfile:report ``` =====> node-js-app builder-dockerfile information Builder dockerfile computed dockerfile path: Dockerfile2 - Builder dockerfile global dockerfile path: Dockerfile + Builder dockerfile global dockerfile path: Builder dockerfile dockerfile path: Dockerfile2 =====> python-sample builder-dockerfile information Builder dockerfile computed dockerfile path: Dockerfile - Builder dockerfile global dockerfile path: Dockerfile + Builder dockerfile global dockerfile path: Builder dockerfile dockerfile path: =====> ruby-sample builder-dockerfile information Builder dockerfile computed dockerfile path: Dockerfile - Builder dockerfile global dockerfile path: Dockerfile + Builder dockerfile global dockerfile path: Builder dockerfile dockerfile path: ``` +The `dockerfile-path` and `global-dockerfile-path` keys hold the raw per-app and global value respectively, and are empty when nothing has been set. The `computed-dockerfile-path` key holds the effective value used at deploy time, falling back to the global value (where one has been set) and then to the built-in default of `Dockerfile`. + You can run the command for a specific app also. ```shell @@ -103,7 +105,7 @@ dokku builder-dockerfile:report node-js-app ``` =====> node-js-app builder-dockerfile information Builder dockerfile computed dockerfile path: Dockerfile2 - Builder dockerfile global dockerfile path: Dockerfile + Builder dockerfile global dockerfile path: Builder dockerfile dockerfile path: Dockerfile2 ``` @@ -213,3 +215,11 @@ See the [Procfile documentation](/docs/processes/process-management.md#procfile) ### Exposed ports See the [port management documentation](/docs/networking/port-management.md) for more information on how Dokku exposes ports for applications and how you can configure these for your app. + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `dockerfile-path` | app + global | `Dockerfile` | `--builder-dockerfile-dockerfile-path`, `--builder-dockerfile-global-dockerfile-path`, `--builder-dockerfile-computed-dockerfile-path` | Path within the app to the Dockerfile used by the dockerfile builder | diff --git a/docs/deployment/builders/herokuish-buildpacks.md b/docs/deployment/builders/herokuish-buildpacks.md index dfaedfbd2..f4ca34a97 100644 --- a/docs/deployment/builders/herokuish-buildpacks.md +++ b/docs/deployment/builders/herokuish-buildpacks.md @@ -117,18 +117,20 @@ dokku builder-herokuish:report ``` =====> node-js-app builder-herokuish information Builder herokuish computed allowed: false - Builder herokuish global allowed: true + Builder herokuish global allowed: Builder herokuish allowed: false =====> python-sample builder-herokuish information Builder herokuish computed allowed: true - Builder herokuish global allowed: true + Builder herokuish global allowed: Builder herokuish allowed: =====> ruby-sample builder-herokuish information Builder herokuish computed allowed: true - Builder herokuish global allowed: true + Builder herokuish global allowed: Builder herokuish allowed: ``` +The `allowed` and `global-allowed` keys hold the raw per-app and global value respectively, and are empty when nothing has been set. The `computed-allowed` key holds the effective value used at build time, falling back to the global value (where one has been set) and then to the built-in default (`true` on amd64, `false` otherwise). + You can run the command for a specific app also. ```shell @@ -138,7 +140,7 @@ dokku builder-herokuish:report node-js-app ``` =====> node-js-app builder-herokuish information Builder herokuish computed allowed: false - Builder herokuish global allowed: true + Builder herokuish global allowed: Builder herokuish allowed: false ``` @@ -208,4 +210,12 @@ See the [buildpack management documentation](/docs/processes/process-management. ### Displaying buildpack reports for an app -See the [buildpack management documentation](/docs/processes/process-management.md#displaying-buildpack-reports-for-an-app) for more information on how to display buildpack reports for an app. \ No newline at end of file +See the [buildpack management documentation](/docs/processes/process-management.md#displaying-buildpack-reports-for-an-app) for more information on how to display buildpack reports for an app. + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `allowed` | app + global | `true` | `--builder-herokuish-allowed`, `--builder-herokuish-global-allowed`, `--builder-herokuish-computed-allowed` | When `false`, the herokuish builder is skipped during builder detection for this app | \ No newline at end of file diff --git a/docs/deployment/builders/lambda.md b/docs/deployment/builders/lambda.md index 48e8a27bd..114f486fd 100644 --- a/docs/deployment/builders/lambda.md +++ b/docs/deployment/builders/lambda.md @@ -84,18 +84,20 @@ dokku builder-lambda:report ``` =====> node-js-app builder-lambda information Builder lambda computed lambdayml path: lambda2.yml - Builder lambda global lambdayml path: lambda.yml + Builder lambda global lambdayml path: Builder lambda lambdayml path: lambda2.yml =====> python-sample builder-lambda information Builder lambda computed lambdayml path: lambda.yml - Builder lambda global lambdayml path: lambda.yml + Builder lambda global lambdayml path: Builder lambda lambdayml path: =====> ruby-sample builder-lambda information Builder lambda computed lambdayml path: lambda.yml - Builder lambda global lambdayml path: lambda.yml + Builder lambda global lambdayml path: Builder lambda lambdayml path: ``` +The `lambdayml-path` and `global-lambdayml-path` keys hold the raw per-app and global value respectively, and are empty when nothing has been set. The `computed-lambdayml-path` key holds the effective value used at build time, falling back to the global value (where one has been set) and then to the built-in default of `lambda.yml`. + You can run the command for a specific app also. ```shell @@ -105,7 +107,7 @@ dokku builder-lambda:report node-js-app ``` =====> node-js-app builder-lambda information Builder lambda computed lambdayml path: lambda2.yml - Builder lambda global lambdayml path: lambda.yml + Builder lambda global lambdayml path: Builder lambda lambdayml path: lambda2.yml ``` @@ -118,3 +120,11 @@ dokku builder-lambda:report node-js-app --builder-lambda-lambdayml-path ``` lambda2.yml ``` + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `lambdayml-path` | app + global | `lambda.yml` | `--builder-lambda-lambdayml-path`, `--builder-lambda-global-lambdayml-path`, `--builder-lambda-computed-lambdayml-path` | Path within the app to the `lambda.yml` manifest used by the lambda builder | diff --git a/docs/deployment/builders/nixpacks.md b/docs/deployment/builders/nixpacks.md index 945b424c3..2d441c7aa 100644 --- a/docs/deployment/builders/nixpacks.md +++ b/docs/deployment/builders/nixpacks.md @@ -97,18 +97,20 @@ dokku builder-nixpacks:report ``` =====> node-js-app builder-nixpacks information Builder-nixpacks computed nixpackstoml path: nixpacks2.toml - Builder-nixpacks global nixpackstoml path: nixpacks.toml + Builder-nixpacks global nixpackstoml path: Builder-nixpacks nixpackstoml path: nixpacks2.toml =====> python-sample builder-nixpacks information Builder-nixpacks computed nixpackstoml path: nixpacks.toml - Builder-nixpacks global nixpackstoml path: nixpacks.toml + Builder-nixpacks global nixpackstoml path: Builder-nixpacks nixpackstoml path: =====> ruby-sample builder-nixpacks information Builder-nixpacks computed nixpackstoml path: nixpacks.toml - Builder-nixpacks global nixpackstoml path: nixpacks.toml + Builder-nixpacks global nixpackstoml path: Builder-nixpacks nixpackstoml path: ``` +The `nixpackstoml-path` and `global-nixpackstoml-path` keys hold the raw per-app and global value respectively, and are empty when nothing has been set. The `computed-nixpackstoml-path` key holds the effective value used at build time, falling back to the global value (where one has been set) and then to the built-in default of `nixpacks.toml`. + You can run the command for a specific app also. ```shell @@ -118,7 +120,7 @@ dokku builder-nixpacks:report node-js-app ``` =====> node-js-app builder-nixpacks information Builder-nixpacks computed nixpackstoml path: nixpacks2.toml - Builder-nixpacks global nixpackstoml path: nixpacks.toml + Builder-nixpacks global nixpackstoml path: Builder-nixpacks nixpackstoml path: nixpacks2.toml ``` @@ -131,3 +133,11 @@ dokku builder-nixpacks:report node-js-app --builder-nixpacks-nixpackstoml-path ``` nixpacks2.toml ``` + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `nixpackstoml-path` | app + global | `nixpacks.toml` | `--builder-nixpacks-nixpackstoml-path`, `--builder-nixpacks-global-nixpackstoml-path`, `--builder-nixpacks-computed-nixpackstoml-path` | Path within the app to the `nixpacks.toml` manifest used by the nixpacks builder | diff --git a/docs/deployment/builders/railpack.md b/docs/deployment/builders/railpack.md index 6ee0b2cc6..ac289b536 100644 --- a/docs/deployment/builders/railpack.md +++ b/docs/deployment/builders/railpack.md @@ -106,18 +106,20 @@ dokku builder-railpack:report ``` =====> node-js-app builder-railpack information Builder-railpack computed railpackjson path: railpack2.json - Builder-railpack global railpackjson path: railpack.json + Builder-railpack global railpackjson path: Builder-railpack railpackjson path: railpack2.json =====> python-sample builder-railpack information Builder-railpack computed railpackjson path: railpack.json - Builder-railpack global railpackjson path: railpack.json + Builder-railpack global railpackjson path: Builder-railpack railpackjson path: =====> ruby-sample builder-railpack information Builder-railpack computed railpackjson path: railpack.json - Builder-railpack global railpackjson path: railpack.json + Builder-railpack global railpackjson path: Builder-railpack railpackjson path: ``` +The `railpackjson-path` and `global-railpackjson-path` keys hold the raw per-app and global value respectively, and are empty when nothing has been set. The `computed-railpackjson-path` key holds the effective value used at build time, falling back to the global value (where one has been set) and then to the built-in default of `railpack.json`. + You can run the command for a specific app also. ```shell @@ -127,7 +129,7 @@ dokku builder-railpack:report node-js-app ``` =====> node-js-app builder-railpack information Builder-railpack computed railpackjson path: railpack2.json - Builder-railpack global railpackjson path: railpack.json + Builder-railpack global railpackjson path: Builder-railpack railpackjson path: railpack2.json ``` @@ -140,3 +142,11 @@ dokku builder-railpack:report node-js-app --builder-railpack-railpackjson-path ``` railpack2.json ``` + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `railpackjson-path` | app + global | `railpack.json` | `--builder-railpack-railpackjson-path`, `--builder-railpack-global-railpackjson-path`, `--builder-railpack-computed-railpackjson-path` | Path within the app to the `railpack.json` manifest used by the railpack builder | diff --git a/docs/deployment/logs.md b/docs/deployment/logs.md index 2e6ed0772..fded8d606 100644 --- a/docs/deployment/logs.md +++ b/docs/deployment/logs.md @@ -311,3 +311,15 @@ As with app-specific label alias settings, the global value may also be cleared ```shell dokku logs:set --global app-label-alias ``` + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `app-label-alias` | app + global | `com.dokku.app-name` | `--logs-app-label-alias`, `--logs-global-app-label-alias`, `--logs-computed-app-label-alias` | Docker label key whose value is used to identify the app when shipping logs | +| `max-size` | app + global | `10m` | `--logs-max-size`, `--logs-global-max-size`, `--logs-computed-max-size` | Maximum size of an individual log file before rotation | +| `vector-image` | global only | _parsed from `plugins/logs/Dockerfile`_ | `--logs-global-vector-image`, `--logs-computed-vector-image` | Docker image used to run the vector log-shipper container | +| `vector-networks` | global only | none | `--logs-global-vector-networks`, `--logs-computed-vector-networks` | Comma-separated list of docker networks the vector container is attached to | +| `vector-sink` | app + global | none | `--logs-vector-sink`, `--logs-global-vector-sink`, `--logs-computed-vector-sink` | DSN-style sink configuration for vector (e.g. `console://` or `loki://...`) | diff --git a/docs/deployment/methods/git.md b/docs/deployment/methods/git.md index bc7ce87f3..64a7e61c3 100644 --- a/docs/deployment/methods/git.md +++ b/docs/deployment/methods/git.md @@ -281,12 +281,15 @@ dokku git:report ``` =====> node-js-app git information + Git computed archive max files: 10000 + Git computed archive max size: 1073741824 Git computed deploy branch: master Git computed keep git dir: false Git deploy branch: - Git global archive max files: 10000 - Git global archive max size: 1073741824 - Git global deploy branch: master + Git global archive max files: + Git global archive max size: + Git global deploy branch: + Git global keep git dir: Git keep git dir: Git rev env var: GIT_REV Git sha: a1b2c3d @@ -294,7 +297,7 @@ dokku git:report Git last updated at: 1700000000 ``` -The `deploy-branch` and `keep-git-dir` keys hold the raw per-app value and are empty when nothing has been set on the app. The `computed-deploy-branch` and `computed-keep-git-dir` keys hold the effective value used at deploy time, falling back to the corresponding global value (where one exists) and then to the built-in default. +The bare per-app keys (`deploy-branch`, `keep-git-dir`) and the `global-` keys hold the raw per-app or global value respectively, and are empty when nothing has been set. The `computed-` keys hold the effective value used at deploy time, falling back to the global value (where one has been set) and then to the built-in default. You can run the command for a specific app also. @@ -315,3 +318,25 @@ dokku git:report node-js-app --format json ``` The `--format` flag cannot be combined with an info flag. + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `archive-max-files` | app + global | none | `--git-global-archive-max-files`, `--git-computed-archive-max-files` | Maximum number of files allowed in an uploaded archive deploy | +| `archive-max-size` | app + global | none | `--git-global-archive-max-size`, `--git-computed-archive-max-size` | Maximum total size of an uploaded archive deploy | +| `deploy-branch` | app + global | `master` | `--git-deploy-branch`, `--git-global-deploy-branch`, `--git-computed-deploy-branch` | Branch name pushed by the git remote that triggers a deploy | +| `keep-git-dir` | app + global | `false` | `--git-keep-git-dir`, `--git-global-keep-git-dir`, `--git-computed-keep-git-dir` | When `true`, retains the `.git` directory inside the build context | +| `rev-env-var` | app + global | `GIT_REV` | `--git-rev-env-var` | Environment variable name receiving the deployed commit SHA; empty disables injection | +| `source-image` | app + global | none | `--git-source-image` | Docker image to clone application source from when deploying from an image | + +### Read-only flags + +The following flags surface in `git:report` but are not managed by `git:set` - they are derived from repository state: + +| Flag | Description | +|---|---| +| `--git-sha` | HEAD commit SHA of the app's git repo | +| `--git-last-updated-at` | UNIX timestamp of the last write to the deploy branch ref | diff --git a/docs/deployment/schedulers/docker-local.md b/docs/deployment/schedulers/docker-local.md index aeb96cf97..089db7113 100644 --- a/docs/deployment/schedulers/docker-local.md +++ b/docs/deployment/schedulers/docker-local.md @@ -216,3 +216,12 @@ The `docker-local` scheduler supports a minimal list of resource _limits_ and _r - memory: (docker option: `--memory-reservation`) should be specified with a suffix of `b` (bytes), `k` (kilobytes), `m` (megabytes), `g` (gigabytes). Default unit is `m` (megabytes). - See the ["Memory" section](https://docs.docker.com/config/containers/resource_constraints/#memory) of the Docker Runtime Options documentation for more information. + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `init-process` | app + global | `true` | `--scheduler-docker-local-init-process`, `--scheduler-docker-local-global-init-process`, `--scheduler-docker-local-computed-init-process` | When `true`, runs containers with Docker's `--init` flag (reaping zombie processes) | +| `parallel-schedule-count` | app + global | `1` | `--scheduler-docker-local-parallel-schedule-count`, `--scheduler-docker-local-global-parallel-schedule-count`, `--scheduler-docker-local-computed-parallel-schedule-count` | Maximum number of containers scheduled in parallel during a deploy | diff --git a/docs/deployment/schedulers/k3s.md b/docs/deployment/schedulers/k3s.md index b3fa64432..3ffc770d6 100644 --- a/docs/deployment/schedulers/k3s.md +++ b/docs/deployment/schedulers/k3s.md @@ -787,3 +787,25 @@ If unspecified for any task, the default reservation will be `.1` CPU and `128Mi > [!NOTE] > Cron tasks retrieve resource limits based on the computed cron task ID. + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `deploy-timeout` | app + global | `300s` | `--scheduler-k3s-deploy-timeout`, `--scheduler-k3s-global-deploy-timeout`, `--scheduler-k3s-computed-deploy-timeout` | Timeout for a single helm install/upgrade cycle | +| `image-pull-secrets` | app + global | none | `--scheduler-k3s-image-pull-secrets`, `--scheduler-k3s-global-image-pull-secrets`, `--scheduler-k3s-computed-image-pull-secrets` | Comma-separated list of Kubernetes secret names used to pull private images | +| `ingress-class` | global only | `nginx` | `--scheduler-k3s-global-ingress-class` | IngressClass name used for app ingresses (e.g. `nginx`, `traefik`) | +| `kube-context` | global only | none | `--scheduler-k3s-global-kube-context` | Kube context name used by helm and kubectl invocations | +| `kubeconfig-path` | global only | `/etc/rancher/k3s/k3s.yaml` | `--scheduler-k3s-global-kubeconfig-path` | Filesystem path to the kubeconfig used to talk to the cluster | +| `kustomize-root-path` | app + global | none | `--scheduler-k3s-kustomize-root-path`, `--scheduler-k3s-global-kustomize-root-path`, `--scheduler-k3s-computed-kustomize-root-path` | Path within the app to a kustomize root applied after the helm install | +| `letsencrypt-email-prod` | global only | none | `--scheduler-k3s-global-letsencrypt-email-prod` | Contact email for the production cert-manager ClusterIssuer | +| `letsencrypt-email-stag` | global only | none | `--scheduler-k3s-global-letsencrypt-email-stag` | Contact email for the staging cert-manager ClusterIssuer | +| `letsencrypt-server` | app + global | `prod` | `--scheduler-k3s-letsencrypt-server`, `--scheduler-k3s-global-letsencrypt-server`, `--scheduler-k3s-computed-letsencrypt-server` | ACME directory (`prod` or `staging`) used for app certificates | +| `namespace` | app + global | `default` | `--scheduler-k3s-namespace`, `--scheduler-k3s-global-namespace`, `--scheduler-k3s-computed-namespace` | Kubernetes namespace into which the app's resources are installed | +| `network-interface` | global only | none | `--scheduler-k3s-global-network-interface` | Host network interface used by k3s | +| `rollback-on-failure` | app + global | `false` | `--scheduler-k3s-rollback-on-failure`, `--scheduler-k3s-global-rollback-on-failure`, `--scheduler-k3s-computed-rollback-on-failure` | When `true`, helm rolls back the release if a deploy fails | +| `shm-size` | app + global | none | `--scheduler-k3s-shm-size`, `--scheduler-k3s-global-shm-size`, `--scheduler-k3s-computed-shm-size` | `/dev/shm` size override applied to app containers | +| `token` | global only | none | (not in report) | Cluster join token used by `scheduler-k3s:cluster-add` | +| `chart..` | global only | none | `--scheduler-k3s-global-chart..` (dynamic per chart/property) | Override a value injected into the helm chart named `` (one row per chart/property pair) | diff --git a/docs/deployment/schedulers/scheduler-management.md b/docs/deployment/schedulers/scheduler-management.md index 27ed1fedc..0fcde8b65 100644 --- a/docs/deployment/schedulers/scheduler-management.md +++ b/docs/deployment/schedulers/scheduler-management.md @@ -80,14 +80,16 @@ dokku scheduler:report Scheduler selected: herokuish =====> python-sample scheduler information Scheduler computed selected: dockerfile - Scheduler global selected: herokuish + Scheduler global selected: Scheduler selected: dockerfile =====> ruby-sample scheduler information - Scheduler computed selected: herokuish - Scheduler global selected: herokuish + Scheduler computed selected: docker-local + Scheduler global selected: Scheduler selected: ``` +The `selected` and `global-selected` keys hold the raw per-app and global value respectively, and are empty when nothing has been set. The `computed-selected` key holds the effective value used at deploy time, falling back to the global value (where one has been set) and then to the built-in default of `docker-local`. + You can run the command for a specific app also. ```shell @@ -96,6 +98,8 @@ dokku scheduler:report node-js-app ``` =====> node-js-app scheduler information + Scheduler computed selected: herokuish + Scheduler global selected: Scheduler selected: herokuish ``` @@ -143,3 +147,12 @@ Schedulers may decide to omit some functionality here, or use plugin triggers to Schedulers can use any tools available on the system to build the docker image, and may even be used to interact with off-server systems. The only current requirement is that the scheduler must have access to the image built in the build phase. If this is not the case, the registry plugin can be used to push the image to a registry that the scheduler software can access. Deployment tasks are currently executed directly on the primary Dokku server. + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `selected` | app + global | `docker-local` | `--scheduler-selected`, `--scheduler-global-selected`, `--scheduler-computed-selected` | Scheduler plugin used to deploy this app (`docker-local`, `k3s`, etc.) | +| `shell` | app + global | none | (not in report) | Shell used by `enter`/`run` commands when entering a container | diff --git a/docs/deployment/zero-downtime-deploys.md b/docs/deployment/zero-downtime-deploys.md index d321f1ed3..c737f56e1 100644 --- a/docs/deployment/zero-downtime-deploys.md +++ b/docs/deployment/zero-downtime-deploys.md @@ -95,22 +95,24 @@ dokku checks:report Checks disabled list: none Checks skipped list: none Checks computed wait to retire: 60 - Checks global wait to retire: 60 + Checks global wait to retire: Checks wait to retire: =====> python-app checks information Checks disabled list: none Checks skipped list: none Checks computed wait to retire: 60 - Checks global wait to retire: 60 + Checks global wait to retire: Checks wait to retire: =====> ruby-app checks information Checks disabled list: _all_ Checks skipped list: none Checks computed wait to retire: 60 - Checks global wait to retire: 60 + Checks global wait to retire: Checks wait to retire: ``` +The `wait-to-retire` and `global-wait-to-retire` keys hold the raw per-app and global value respectively, and are empty when nothing has been set. The `computed-wait-to-retire` key holds the effective value used at deploy time, falling back to the global value (where one has been set) and then to the built-in default of `60`. + You can run the command for a specific app also. ```shell @@ -120,10 +122,10 @@ dokku checks:report node-js-app ``` =====> node-js-app checks information Checks disabled list: none - Checks skipped list: none + Checks skipped list: none Checks computed wait to retire: 60 - Checks global wait to retire: 60 - Checks wait to retire: + Checks global wait to retire: + Checks wait to retire: ``` You can pass flags which will output only the value of the specific information you want. For example: @@ -263,3 +265,11 @@ dokku checks:run node-js-app web.3 -----> Running pre-flight checks Invalid container id specified (APP.web.3) ``` + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `wait-to-retire` | app + global | `60` | `--checks-wait-to-retire`, `--checks-global-wait-to-retire`, `--checks-computed-wait-to-retire` | Seconds to wait between deploying the new container and stopping the old one | diff --git a/docs/networking/network.md b/docs/networking/network.md index 5a67265bc..54443ffad 100644 --- a/docs/networking/network.md +++ b/docs/networking/network.md @@ -428,7 +428,7 @@ dokku network:report =====> node-js-app network information Network attach post create: Network attach post deploy: - Network bind all interfaces: false + Network bind all interfaces: Network computed attach post create: Network computed attach post deploy: Network computed bind all interfaces:false @@ -436,7 +436,7 @@ dokku network:report Network computed tld: Network global attach post create: Network global attach post deploy: - Network global bind all interfaces:false + Network global bind all interfaces: Network global initial network: Network global tld: Network initial network: @@ -445,7 +445,7 @@ dokku network:report =====> python-sample network information Network attach post create: Network attach post deploy: - Network bind all interfaces: false + Network bind all interfaces: Network computed attach post create: Network computed attach post deploy: Network computed bind all interfaces:false @@ -453,7 +453,7 @@ dokku network:report Network computed tld: Network global attach post create: Network global attach post deploy: - Network global bind all interfaces:false + Network global bind all interfaces: Network global initial network: Network global tld: Network initial network: @@ -462,7 +462,7 @@ dokku network:report =====> ruby-sample network information Network attach post create: Network attach post deploy: - Network bind all interfaces: false + Network bind all interfaces: Network computed attach post create: Network computed attach post deploy: Network computed bind all interfaces:false @@ -470,7 +470,7 @@ dokku network:report Network computed tld: Network global attach post create: Network global attach post deploy: - Network global bind all interfaces:false + Network global bind all interfaces: Network global initial network: Network global tld: Network initial network: @@ -478,6 +478,8 @@ dokku network:report Network web listeners: ``` +The per-app and `global-` keys for each property hold the raw values and are empty when nothing has been set. The `computed-` keys hold the effective value, falling back to the global value (where one has been set) and then to the built-in default (`false` for `bind-all-interfaces`, empty otherwise). + You can run the command for a specific app also. ```shell @@ -488,7 +490,7 @@ dokku network:report node-js-app =====> node-js-app network information Network attach post create: Network attach post deploy: - Network bind all interfaces: false + Network bind all interfaces: Network computed attach post create: Network computed attach post deploy: Network computed bind all interfaces:false @@ -496,7 +498,7 @@ dokku network:report node-js-app Network computed tld: Network global attach post create: Network global attach post deploy: - Network global bind all interfaces:false + Network global bind all interfaces: Network global initial network: Network global tld: Network initial network: @@ -509,3 +511,24 @@ You can pass flags which will output only the value of the specific information ```shell dokku network:report node-js-app --network-bind-all-interfaces ``` + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `attach-post-create` | app + global | none | `--network-attach-post-create`, `--network-global-attach-post-create`, `--network-computed-attach-post-create` | Networks attached to a container immediately after creation, before the deploy phase | +| `attach-post-deploy` | app + global | none | `--network-attach-post-deploy`, `--network-global-attach-post-deploy`, `--network-computed-attach-post-deploy` | Networks attached to a container after it passes healthchecks | +| `bind-all-interfaces` | app + global | `false` | `--network-bind-all-interfaces`, `--network-global-bind-all-interfaces`, `--network-computed-bind-all-interfaces` | When `true`, binds containers to `0.0.0.0` instead of the default Docker network address | +| `initial-network` | app + global | none | `--network-initial-network`, `--network-global-initial-network`, `--network-computed-initial-network` | Network attached at container creation time | +| `static-web-listener` | app only | none | `--network-static-web-listener` | Static `host:port` override used in proxy templates when no container is running | +| `tld` | app + global | none | `--network-tld`, `--network-global-tld`, `--network-computed-tld` | Top-level domain appended to auto-generated app vhosts | + +### Read-only flags + +The following flag surfaces in `network:report` but is not managed by `network:set` - it is derived from the running app state: + +| Flag | Description | +|---|---| +| `--network-web-listeners` | Current `web` process listeners (host:port) for the deployed app | diff --git a/docs/networking/port-management.md b/docs/networking/port-management.md index 557c86927..f22e9c737 100644 --- a/docs/networking/port-management.md +++ b/docs/networking/port-management.md @@ -220,3 +220,13 @@ You can pass flags which will output only the value of the specific information ```shell dokku ports:report node-js-app --ports-map ``` + +## Properties + +### Read-only flags + +The following flags surface in `ports:report` but are not managed by `ports:set` - they are derived from the deploy: + +| Flag | Description | +|---|---| +| `--ports-map-detected` | Port mapping inferred from `EXPOSE` directives or the running container | diff --git a/docs/networking/proxies/caddy.md b/docs/networking/proxies/caddy.md index 579691811..e126dd7d8 100644 --- a/docs/networking/proxies/caddy.md +++ b/docs/networking/proxies/caddy.md @@ -220,35 +220,22 @@ dokku caddy:report ``` =====> node-js-app caddy information - Caddy computed tls internal: false - Caddy global tls internal: false - Caddy image: lucaslorentz/caddy-docker-proxy:2.7 - Caddy letsencrypt email: - Caddy letsencrypt server: - Caddy log level: ERROR - Caddy polling interval: 5s - Caddy tls internal: -=====> python-app caddy information - Caddy computed tls internal: false - Caddy global tls internal: false - Caddy image: lucaslorentz/caddy-docker-proxy:2.7 - Caddy letsencrypt email: - Caddy letsencrypt server: - Caddy log level: ERROR - Caddy polling interval: 5s - Caddy tls internal: -=====> ruby-app caddy information - Caddy computed tls internal: false - Caddy global tls internal: false - Caddy image: lucaslorentz/caddy-docker-proxy:2.7 - Caddy letsencrypt email: - Caddy letsencrypt server: - Caddy log level: ERROR - Caddy polling interval: 5s + Caddy computed image: lucaslorentz/caddy-docker-proxy:2.7 + Caddy computed letsencrypt email: + Caddy computed letsencrypt server: https://acme-v02.api.letsencrypt.org/directory + Caddy computed log level: ERROR + Caddy computed polling interval: 5s + Caddy computed tls internal: false + Caddy global image: + Caddy global letsencrypt email: + Caddy global letsencrypt server: + Caddy global log level: + Caddy global polling interval: + Caddy global tls internal: Caddy tls internal: ``` -The `tls-internal` key holds the raw per-app value and is empty when nothing has been set on the app. The `computed-tls-internal` key holds the effective value used at deploy time, falling back to the global value and then to the built-in default of `false`. The `global-tls-internal` key holds the global value. +The `global-` keys hold the raw global value and are empty when nothing has been set globally. The `computed-` keys hold the effective value used at deploy time, falling back to the global value (where one has been set) and then to the built-in default. The bare `tls-internal` key holds the raw per-app value. You can run the command for a specific app also. @@ -258,18 +245,44 @@ dokku caddy:report node-js-app ``` =====> node-js-app caddy information - Caddy computed tls internal: false - Caddy global tls internal: false - Caddy image: lucaslorentz/caddy-docker-proxy:2.7 - Caddy letsencrypt email: - Caddy letsencrypt server: - Caddy log level: ERROR - Caddy polling interval: 5s + Caddy computed image: lucaslorentz/caddy-docker-proxy:2.7 + Caddy computed letsencrypt email: + Caddy computed letsencrypt server: https://acme-v02.api.letsencrypt.org/directory + Caddy computed log level: ERROR + Caddy computed polling interval: 5s + Caddy computed tls internal: false + Caddy global image: + Caddy global letsencrypt email: + Caddy global letsencrypt server: + Caddy global log level: + Caddy global polling interval: + Caddy global tls internal: Caddy tls internal: ``` You can pass flags which will output only the value of the specific information you want. For example: ```shell -dokku caddy:report node-js-app --caddy-image +dokku caddy:report node-js-app --caddy-computed-image ``` + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `image` | global only | _parsed from `plugins/caddy-vhosts/Dockerfile`_ | `--caddy-global-image`, `--caddy-computed-image` | Docker image used to run the Caddy container | +| `letsencrypt-email` | global only | none | `--caddy-global-letsencrypt-email`, `--caddy-computed-letsencrypt-email` | Contact email enabling letsencrypt; empty disables https issuance | +| `letsencrypt-server` | global only | `https://acme-v02.api.letsencrypt.org/directory` | `--caddy-global-letsencrypt-server`, `--caddy-computed-letsencrypt-server` | ACME directory used when requesting certificates | +| `log-level` | global only | `ERROR` | `--caddy-global-log-level`, `--caddy-computed-log-level` | Caddy log level | +| `polling-interval` | global only | `5s` | `--caddy-global-polling-interval`, `--caddy-computed-polling-interval` | Frequency at which Caddy polls the Docker API for label changes | +| `tls-internal` | app + global | `false` | `--caddy-tls-internal`, `--caddy-global-tls-internal`, `--caddy-computed-tls-internal` | When `true`, uses Caddy's built-in self-signed TLS instead of letsencrypt | + +### Internal properties + +The following properties are not managed by `caddy:set` but are recorded internally by the plugin: + +| Property | Description | Source | +|---|---|---| +| `proxy-status` | `started`/`stopped` state of the caddy compose project | `cmd-caddy-start`/`cmd-caddy-stop` in `plugins/caddy-vhosts/command-functions` | diff --git a/docs/networking/proxies/haproxy.md b/docs/networking/proxies/haproxy.md index 248306938..4f393ca18 100644 --- a/docs/networking/proxies/haproxy.md +++ b/docs/networking/proxies/haproxy.md @@ -205,13 +205,20 @@ dokku haproxy:report ``` =====> node-js-app haproxy information - Haproxy image: byjg/easy-haproxy:4.0.0 -=====> python-app haproxy information - Haproxy image: byjg/easy-haproxy:4.0.0 -=====> ruby-app haproxy information - Haproxy image: byjg/easy-haproxy:4.0.0 + Haproxy computed image: byjg/easy-haproxy:4.0.0 + Haproxy computed letsencrypt email: + Haproxy computed letsencrypt server: https://acme-v02.api.letsencrypt.org/directory + Haproxy computed log level: ERROR + Haproxy computed refresh conf: 10 + Haproxy global image: + Haproxy global letsencrypt email: + Haproxy global letsencrypt server: + Haproxy global log level: + Haproxy global refresh conf: ``` +The `global-` keys hold the raw global value and are empty when nothing has been set globally. The `computed-` keys hold the effective value used at deploy time, falling back to the built-in default when the global value is empty. + You can run the command for a specific app also. ```shell @@ -220,11 +227,42 @@ dokku haproxy:report node-js-app ``` =====> node-js-app haproxy information - Haproxy image: byjg/easy-haproxy:4.0.0 + Haproxy computed image: byjg/easy-haproxy:4.0.0 + Haproxy computed letsencrypt email: + Haproxy computed letsencrypt server: https://acme-v02.api.letsencrypt.org/directory + Haproxy computed log level: ERROR + Haproxy computed refresh conf: 10 + Haproxy global image: + Haproxy global letsencrypt email: + Haproxy global letsencrypt server: + Haproxy global log level: + Haproxy global refresh conf: ``` You can pass flags which will output only the value of the specific information you want. For example: ```shell -dokku haproxy:report node-js-app --haproxy-image +dokku haproxy:report node-js-app --haproxy-computed-image ``` + +## Properties + +### Settable properties + +All haproxy properties are global only. Set with `haproxy:set --global `. + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `image` | global only | _parsed from `plugins/haproxy-vhosts/Dockerfile`_ | `--haproxy-global-image`, `--haproxy-computed-image` | Docker image used to run the Haproxy container | +| `letsencrypt-email` | global only | none | `--haproxy-global-letsencrypt-email`, `--haproxy-computed-letsencrypt-email` | Contact email enabling letsencrypt; empty disables https issuance | +| `letsencrypt-server` | global only | `https://acme-v02.api.letsencrypt.org/directory` | `--haproxy-global-letsencrypt-server`, `--haproxy-computed-letsencrypt-server` | ACME directory used when requesting certificates | +| `log-level` | global only | `ERROR` | `--haproxy-global-log-level`, `--haproxy-computed-log-level` | Haproxy log level | +| `refresh-conf` | global only | `10` | `--haproxy-global-refresh-conf`, `--haproxy-computed-refresh-conf` | Seconds between Haproxy polls of the Docker API for label changes | + +### Internal properties + +The following properties are not managed by `haproxy:set` but are recorded internally by the plugin: + +| Property | Description | Source | +|---|---|---| +| `proxy-status` | `started`/`stopped` state of the haproxy compose project | `cmd-haproxy-start`/`cmd-haproxy-stop` in `plugins/haproxy-vhosts/command-functions` | diff --git a/docs/networking/proxies/nginx.md b/docs/networking/proxies/nginx.md index 16a91837a..bf6900ef6 100644 --- a/docs/networking/proxies/nginx.md +++ b/docs/networking/proxies/nginx.md @@ -620,3 +620,60 @@ See the [ports documentation](/docs/networking/port-management.md) for more info ### Regenerating nginx config See the [proxy documentation](/docs/networking/proxy-management.md#regenerating-proxy-config) for more information on how to rebuild the nginx proxy configuration for your app. + +## Properties + +### Settable properties + +All nginx-vhosts properties are settable at both the app and global scope. + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `access-log-format` | app + global | none | `--nginx-access-log-format`, `--nginx-global-access-log-format`, `--nginx-computed-access-log-format` | Custom nginx `log_format` directive used for the access log | +| `access-log-path` | app + global | _`{nginx-log-root}/{app}-access.log`_ | `--nginx-access-log-path`, `--nginx-global-access-log-path`, `--nginx-computed-access-log-path` | Path inside the nginx container where access logs are written | +| `bind-address-ipv4` | app + global | none | `--nginx-bind-address-ipv4`, `--nginx-global-bind-address-ipv4`, `--nginx-computed-bind-address-ipv4` | IPv4 address the nginx server block binds to | +| `bind-address-ipv6` | app + global | `::` | `--nginx-bind-address-ipv6`, `--nginx-global-bind-address-ipv6`, `--nginx-computed-bind-address-ipv6` | IPv6 address the nginx server block binds to | +| `client-body-timeout` | app + global | `60s` | `--nginx-client-body-timeout`, `--nginx-global-client-body-timeout`, `--nginx-computed-client-body-timeout` | Time allowed to read the request body from the client | +| `client-header-timeout` | app + global | `60s` | `--nginx-client-header-timeout`, `--nginx-global-client-header-timeout`, `--nginx-computed-client-header-timeout` | Time allowed to read the request header from the client | +| `client-max-body-size` | app + global | `1m` | `--nginx-client-max-body-size`, `--nginx-global-client-max-body-size`, `--nginx-computed-client-max-body-size` | Maximum allowed request body size | +| `disable-custom-config` | app + global | `false` | `--nginx-disable-custom-config`, `--nginx-global-disable-custom-config`, `--nginx-computed-disable-custom-config` | When `true`, ignores app-supplied `nginx.conf.d/*.conf` snippets | +| `error-log-path` | app + global | _`{nginx-log-root}/{app}-error.log`_ | `--nginx-error-log-path`, `--nginx-global-error-log-path`, `--nginx-computed-error-log-path` | Path inside the nginx container where error logs are written | +| `hsts` | app + global | `true` | `--nginx-hsts`, `--nginx-global-hsts`, `--nginx-computed-hsts` | When `true`, emits a `Strict-Transport-Security` header on HTTPS responses | +| `hsts-include-subdomains` | app + global | `true` | `--nginx-hsts-include-subdomains`, `--nginx-global-hsts-include-subdomains`, `--nginx-computed-hsts-include-subdomains` | Adds the `includeSubDomains` directive to the HSTS header | +| `hsts-max-age` | app + global | `15724800` | `--nginx-hsts-max-age`, `--nginx-global-hsts-max-age`, `--nginx-computed-hsts-max-age` | `max-age` value (seconds) in the HSTS header | +| `hsts-preload` | app + global | `false` | `--nginx-hsts-preload`, `--nginx-global-hsts-preload`, `--nginx-computed-hsts-preload` | Adds the `preload` directive to the HSTS header | +| `keepalive-timeout` | app + global | `75s` | `--nginx-keepalive-timeout`, `--nginx-global-keepalive-timeout`, `--nginx-computed-keepalive-timeout` | Time an idle keep-alive connection stays open | +| `lingering-timeout` | app + global | `5s` | `--nginx-lingering-timeout`, `--nginx-global-lingering-timeout`, `--nginx-computed-lingering-timeout` | Time nginx waits for more client data when closing a connection | +| `nginx-conf-sigil-path` | app + global | `nginx.conf.sigil` | `--nginx-nginx-conf-sigil-path`, `--nginx-global-nginx-conf-sigil-path`, `--nginx-computed-nginx-conf-sigil-path` | Path within the app to a custom `nginx.conf.sigil` template | +| `nginx-service-command` | app + global | none | (not in report) | Override command used by `nginx:start`/`nginx:stop`/`nginx:reload` | +| `proxy-buffer-size` | app + global | _system pagesize_ | `--nginx-proxy-buffer-size`, `--nginx-global-proxy-buffer-size`, `--nginx-computed-proxy-buffer-size` | Buffer size for reading the first part of the upstream response | +| `proxy-buffering` | app + global | `on` | `--nginx-proxy-buffering`, `--nginx-global-proxy-buffering`, `--nginx-computed-proxy-buffering` | Whether nginx buffers upstream responses (`on` or `off`) | +| `proxy-buffers` | app + global | _`8 {pagesize}`_ | `--nginx-proxy-buffers`, `--nginx-global-proxy-buffers`, `--nginx-computed-proxy-buffers` | Number and size of buffers used for an upstream response | +| `proxy-busy-buffers-size` | app + global | _`2 * pagesize`_ | `--nginx-proxy-busy-buffers-size`, `--nginx-global-proxy-busy-buffers-size`, `--nginx-computed-proxy-busy-buffers-size` | Maximum buffer size that can be busy sending a response to the client | +| `proxy-connect-timeout` | app + global | `60s` | `--nginx-proxy-connect-timeout`, `--nginx-global-proxy-connect-timeout`, `--nginx-computed-proxy-connect-timeout` | Time to establish a connection to the upstream | +| `proxy-keepalive` | app + global | none | `--nginx-proxy-keepalive`, `--nginx-global-proxy-keepalive`, `--nginx-computed-proxy-keepalive` | Number of idle keep-alive connections to upstream servers held open per worker | +| `proxy-read-timeout` | app + global | `60s` | `--nginx-proxy-read-timeout`, `--nginx-global-proxy-read-timeout`, `--nginx-computed-proxy-read-timeout` | Time to read a response from the upstream | +| `proxy-send-timeout` | app + global | `60s` | `--nginx-proxy-send-timeout`, `--nginx-global-proxy-send-timeout`, `--nginx-computed-proxy-send-timeout` | Time to transmit a request to the upstream | +| `send-timeout` | app + global | `60s` | `--nginx-send-timeout`, `--nginx-global-send-timeout`, `--nginx-computed-send-timeout` | Time between two successive write operations to the client | +| `underscore-in-headers` | app + global | `off` | `--nginx-underscore-in-headers`, `--nginx-global-underscore-in-headers`, `--nginx-computed-underscore-in-headers` | Whether to allow underscores in client request header field names | +| `x-forwarded-for-value` | app + global | `$remote_addr` | `--nginx-x-forwarded-for-value`, `--nginx-global-x-forwarded-for-value`, `--nginx-computed-x-forwarded-for-value` | Value used for the `X-Forwarded-For` header | +| `x-forwarded-port-value` | app + global | `$server_port` | `--nginx-x-forwarded-port-value`, `--nginx-global-x-forwarded-port-value`, `--nginx-computed-x-forwarded-port-value` | Value used for the `X-Forwarded-Port` header | +| `x-forwarded-proto-value` | app + global | `$scheme` | `--nginx-x-forwarded-proto-value`, `--nginx-global-x-forwarded-proto-value`, `--nginx-computed-x-forwarded-proto-value` | Value used for the `X-Forwarded-Proto` header | +| `x-forwarded-ssl` | app + global | none | `--nginx-x-forwarded-ssl`, `--nginx-global-x-forwarded-ssl`, `--nginx-computed-x-forwarded-ssl` | Value used for the `X-Forwarded-Ssl` header (e.g. `on`/`off`) | + +### Read-only flags + +The following flag surfaces in `nginx:report` but is not managed by `nginx:set`: + +| Flag | Description | +|---|---| +| `--nginx-last-visited-at` | UNIX timestamp of the last request served by nginx for the app | + +### Internal properties + +The following properties are recorded internally by the plugin and are not exposed via `nginx:report`: + +| Property | Description | Source | +|---|---|---| +| `proxy-status` | `started`/`stopped` state of the nginx system service | `cmd-nginx-start`/`cmd-nginx-stop` | +| `nginx-conf-sigil-migrated` | Migration sentinel set the first time a v1 template is rewritten to the current schema | `plugins/nginx-vhosts/install` writes `"true"` once the install-time migration runs | diff --git a/docs/networking/proxies/openresty.md b/docs/networking/proxies/openresty.md index d7b6c64d5..dd79f94e1 100644 --- a/docs/networking/proxies/openresty.md +++ b/docs/networking/proxies/openresty.md @@ -279,3 +279,46 @@ You can pass flags which will output only the value of the specific information ```shell dokku openresty:report node-js-app --openresty-letsencrypt-email ``` + +## Properties + +### Settable properties + +Five properties (`image`, `log-level`, `letsencrypt-email`, `letsencrypt-server`, `allowed-letsencrypt-domains-func-base64`) are global only. The rest are app only - they cannot be set with `--global`. + +`openresty:report` currently exposes a single raw flag per property (no `--global-` / `--computed-` split) except for `hsts`, which has all three flag shapes. + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `access-log-format` | app only | none | `--openresty-access-log-format` | Custom nginx `log_format` directive used for the access log | +| `access-log-path` | app only | _`/var/log/nginx/{app}-access.log`_ | `--openresty-access-log-path` | Path inside the openresty container where access logs are written | +| `allowed-letsencrypt-domains-func-base64` | global only | _allow-all stub_ | `--openresty-allowed-letsencrypt-domains-func-base64` | Base64-encoded Lua function deciding which domains may request a letsencrypt certificate | +| `bind-address-ipv4` | app only | none | `--openresty-bind-address-ipv4` | IPv4 address the openresty server block binds to | +| `bind-address-ipv6` | app only | `::` | `--openresty-bind-address-ipv6` | IPv6 address the openresty server block binds to | +| `client-body-timeout` | app only | `60s` | `--openresty-client-body-timeout` | Time allowed to read the request body from the client | +| `client-header-timeout` | app only | `60s` | `--openresty-client-header-timeout` | Time allowed to read the request header from the client | +| `client-max-body-size` | app only | `1m` | `--openresty-client-max-body-size` | Maximum allowed request body size | +| `error-log-path` | app only | _`/var/log/nginx/{app}-error.log`_ | `--openresty-error-log-path` | Path inside the openresty container where error logs are written | +| `hsts` | app only | `true` | `--openresty-hsts`, `--openresty-global-hsts`, `--openresty-computed-hsts` | When `true`, emits a `Strict-Transport-Security` header on HTTPS responses | +| `hsts-include-subdomains` | app only | `true` | `--openresty-hsts-include-subdomains` | Adds the `includeSubDomains` directive to the HSTS header | +| `hsts-max-age` | app only | `15724800` | `--openresty-hsts-max-age` | `max-age` value (seconds) in the HSTS header | +| `hsts-preload` | app only | `false` | `--openresty-hsts-preload` | Adds the `preload` directive to the HSTS header | +| `image` | global only | _parsed from `plugins/openresty-vhosts/Dockerfile`_ | `--openresty-image` | Docker image used to run the openresty container | +| `keepalive-timeout` | app only | `75s` | `--openresty-keepalive-timeout` | Time an idle keep-alive connection stays open | +| `letsencrypt-email` | global only | none | `--openresty-letsencrypt-email` | Contact email enabling letsencrypt; empty disables https issuance | +| `letsencrypt-server` | global only | `https://acme-v02.api.letsencrypt.org/directory` | `--openresty-letsencrypt-server` | ACME directory used when requesting certificates | +| `lingering-timeout` | app only | `5s` | `--openresty-lingering-timeout` | Time openresty waits for more client data when closing a connection | +| `log-level` | global only | `ERROR` | (not in report) | Openresty log level | +| `proxy-buffer-size` | app only | _system pagesize_ | `--openresty-proxy-buffer-size` | Buffer size for reading the first part of the upstream response | +| `proxy-buffering` | app only | `on` | `--openresty-proxy-buffering` | Whether openresty buffers upstream responses (`on` or `off`) | +| `proxy-buffers` | app only | _`8 {pagesize}`_ | `--openresty-proxy-buffers` | Number and size of buffers used for an upstream response | +| `proxy-busy-buffers-size` | app only | _`2 * pagesize`_ | `--openresty-proxy-busy-buffers-size` | Maximum buffer size that can be busy sending a response to the client | +| `proxy-connect-timeout` | app only | `60s` | `--openresty-proxy-connect-timeout` | Time to establish a connection to the upstream | +| `proxy-read-timeout` | app only | `60s` | `--openresty-proxy-read-timeout` | Time to read a response from the upstream | +| `proxy-send-timeout` | app only | `60s` | `--openresty-proxy-send-timeout` | Time to transmit a request to the upstream | +| `send-timeout` | app only | `60s` | `--openresty-send-timeout` | Time between two successive write operations to the client | +| `underscore-in-headers` | app only | `off` | `--openresty-underscore-in-headers` | Whether to allow underscores in client request header field names | +| `x-forwarded-for-value` | app only | `$remote_addr` | `--openresty-x-forwarded-for-value` | Value used for the `X-Forwarded-For` header | +| `x-forwarded-port-value` | app only | `$server_port` | `--openresty-x-forwarded-port-value` | Value used for the `X-Forwarded-Port` header | +| `x-forwarded-proto-value` | app only | `$scheme` | `--openresty-x-forwarded-proto-value` | Value used for the `X-Forwarded-Proto` header | +| `x-forwarded-ssl` | app only | none | `--openresty-x-forwarded-ssl` | Value used for the `X-Forwarded-Ssl` header (e.g. `on`/`off`) | diff --git a/docs/networking/proxies/traefik.md b/docs/networking/proxies/traefik.md index 0d2fbf70b..9eb00db7f 100644 --- a/docs/networking/proxies/traefik.md +++ b/docs/networking/proxies/traefik.md @@ -331,43 +331,30 @@ dokku traefik:report ``` =====> node-js-app traefik information - Traefik api enabled: false - Traefik api vhost: traefik.dokku.me - Traefik basic auth password: password - Traefik basic auth username: user - Traefik challenge mode: tls - Traefik dashboard enabled: false - Traefik dns provider: - Traefik image: traefik:v2.8 - Traefik letsencrypt email: - Traefik letsencrypt server: - Traefik log level: ERROR -=====> python-app traefik information - Traefik api enabled: false - Traefik api vhost: traefik.dokku.me - Traefik basic auth password: password - Traefik basic auth username: user - Traefik challenge mode: tls - Traefik dashboard enabled: false - Traefik dns provider: - Traefik image: traefik:v2.8 - Traefik letsencrypt email: - Traefik letsencrypt server: - Traefik log level: ERROR -=====> ruby-app traefik information - Traefik api enabled: false - Traefik api vhost: traefik.dokku.me - Traefik basic auth password: password - Traefik basic auth username: user - Traefik challenge mode: tls - Traefik dashboard enabled: false - Traefik dns provider: - Traefik image: traefik:v2.8 - Traefik letsencrypt email: - Traefik letsencrypt server: - Traefik log level: ERROR + Traefik computed api enabled: false + Traefik computed api vhost: traefik.dokku.me + Traefik computed challenge mode: tls + Traefik computed dashboard enabled: false + Traefik computed http entry point: http + Traefik computed https entry point: https + Traefik computed image: traefik:v2.8 + Traefik computed letsencrypt email: + Traefik computed letsencrypt server: https://acme-v02.api.letsencrypt.org/directory + Traefik computed log level: ERROR + Traefik global api enabled: + Traefik global api vhost: + Traefik global challenge mode: + Traefik global dashboard enabled: + Traefik global http entry point: + Traefik global https entry point: + Traefik global image: + Traefik global letsencrypt email: + Traefik global letsencrypt server: + Traefik global log level: ``` +The `global-` keys hold the raw global value and are empty when nothing has been set globally. The `computed-` keys hold the effective value used at deploy time, falling back to the built-in default when the global value is empty. + You can run the command for a specific app also. ```shell @@ -376,21 +363,63 @@ dokku traefik:report node-js-app ``` =====> node-js-app traefik information - Traefik api enabled: false - Traefik api vhost: traefik.dokku.me - Traefik basic auth password: password - Traefik basic auth username: user - Traefik challenge mode: tls - Traefik dashboard enabled: false - Traefik dns provider: - Traefik image: traefik:v2.8 - Traefik letsencrypt email: - Traefik letsencrypt server: - Traefik log level: ERROR + Traefik computed api enabled: false + Traefik computed api vhost: traefik.dokku.me + Traefik computed challenge mode: tls + Traefik computed dashboard enabled: false + Traefik computed http entry point: http + Traefik computed https entry point: https + Traefik computed image: traefik:v2.8 + Traefik computed letsencrypt email: + Traefik computed letsencrypt server: https://acme-v02.api.letsencrypt.org/directory + Traefik computed log level: ERROR + Traefik global api enabled: + Traefik global api vhost: + Traefik global challenge mode: + Traefik global dashboard enabled: + Traefik global http entry point: + Traefik global https entry point: + Traefik global image: + Traefik global letsencrypt email: + Traefik global letsencrypt server: + Traefik global log level: ``` You can pass flags which will output only the value of the specific information you want. For example: ```shell -dokku traefik:report node-js-app --traefik-api-enabled +dokku traefik:report node-js-app --traefik-computed-api-enabled ``` + +## Properties + +### Settable properties + +All traefik properties are global only. Set with `traefik:set --global `. + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `api-enabled` | global only | `false` | `--traefik-global-api-enabled`, `--traefik-computed-api-enabled` | When `true`, enables the Traefik HTTP API | +| `api-entry-point` | global only | none | `--traefik-global-api-entry-point`, `--traefik-computed-api-entry-point` | Name of the entry point used by the Traefik API | +| `api-entry-point-address` | global only | none | `--traefik-global-api-entry-point-address`, `--traefik-computed-api-entry-point-address` | Address (`host:port`) the Traefik API listens on | +| `api-vhost` | global only | `traefik.dokku.me` | `--traefik-global-api-vhost`, `--traefik-computed-api-vhost` | Virtual host that routes to the Traefik API | +| `basic-auth-password` | global only | none | `--traefik-global-basic-auth-password`, `--traefik-computed-basic-auth-password` | Password for basic auth in front of the API/dashboard | +| `basic-auth-username` | global only | none | `--traefik-global-basic-auth-username`, `--traefik-computed-basic-auth-username` | Username for basic auth in front of the API/dashboard | +| `challenge-mode` | global only | `tls` | `--traefik-global-challenge-mode`, `--traefik-computed-challenge-mode` | ACME challenge method used by Traefik (`tls`, `http`, or `dns`) | +| `dashboard-enabled` | global only | `false` | `--traefik-global-dashboard-enabled`, `--traefik-computed-dashboard-enabled` | When `true`, enables the Traefik dashboard | +| `dns-provider` | global only | none | `--traefik-global-dns-provider`, `--traefik-computed-dns-provider` | Lego DNS provider name used when `challenge-mode` is `dns` | +| `dns-provider-` | global only | none | (no report flag) | Per-provider environment variables passed to the Traefik container; `` is the upstream variable name (e.g. `dns-provider-cloudflare-api-token`) | +| `http-entry-point` | global only | `http` | `--traefik-global-http-entry-point`, `--traefik-computed-http-entry-point` | Entry point name handling plaintext HTTP traffic | +| `https-entry-point` | global only | `https` | `--traefik-global-https-entry-point`, `--traefik-computed-https-entry-point` | Entry point name handling TLS-terminated HTTPS traffic | +| `image` | global only | _parsed from `plugins/traefik-vhosts/Dockerfile`_ | `--traefik-global-image`, `--traefik-computed-image` | Docker image used to run the Traefik container | +| `letsencrypt-email` | global only | none | `--traefik-global-letsencrypt-email`, `--traefik-computed-letsencrypt-email` | Contact email enabling letsencrypt; empty disables https issuance | +| `letsencrypt-server` | global only | `https://acme-v02.api.letsencrypt.org/directory` | `--traefik-global-letsencrypt-server`, `--traefik-computed-letsencrypt-server` | ACME directory used when requesting certificates | +| `log-level` | global only | `ERROR` | `--traefik-global-log-level`, `--traefik-computed-log-level` | Traefik log level | + +### Internal properties + +The following properties are not managed by `traefik:set` but are recorded internally by the plugin: + +| Property | Description | Source | +|---|---|---| +| `proxy-status` | `started`/`stopped` state of the traefik compose project | `cmd-traefik-start`/`cmd-traefik-stop` in `plugins/traefik-vhosts/command-functions` | diff --git a/docs/networking/proxy-management.md b/docs/networking/proxy-management.md index 29c1e5249..242b77b64 100644 --- a/docs/networking/proxy-management.md +++ b/docs/networking/proxy-management.md @@ -142,16 +142,24 @@ dokku proxy:report ``` =====> node-js-app proxy information + Proxy computed type: nginx Proxy enabled: true - Proxy type: nginx + Proxy global type: + Proxy type: =====> python-sample proxy information + Proxy computed type: nginx Proxy enabled: true - Proxy type: nginx + Proxy global type: + Proxy type: =====> ruby-sample proxy information + Proxy computed type: nginx Proxy enabled: true - Proxy type: nginx + Proxy global type: + Proxy type: ``` +The `type` and `global-type` keys hold the raw per-app and global value respectively, and are empty when nothing has been set. The `computed-type` key holds the effective value used at deploy time, falling back to the global value (where one has been set) and then to the built-in default of `nginx`. + You can run the command for a specific app also. ```shell @@ -160,14 +168,16 @@ dokku proxy:report node-js-app ``` =====> node-js-app proxy information + Proxy computed type: nginx Proxy enabled: true - Proxy type: nginx + Proxy global type: + Proxy type: ``` You can pass flags which will output only the value of the specific information you want. For example: ```shell -dokku proxy:report node-js-app --proxy-type +dokku proxy:report node-js-app --proxy-computed-type ``` #### Proxy Port Scheme @@ -226,3 +236,22 @@ Proxy implementations may decide to omit some functionality here, or use plugin Individual proxy implementations _may_ trigger app rebuilds, depending on how proxy metadata is exposed for the proxy implementation. Finally, proxy implementations _may_ install extra software needed for the proxy itself in whatever manner deemed fit. Proxy software can run on the host itself or within a running Docker container with either exposed ports or host networking. + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `disabled` | app only | `false` | (exposed inverted as `--proxy-enabled`) | When `true`, disables proxy integration for this app (`proxy:enable`/`proxy:disable` write this) | +| `proxy-port` | app + global | none | (not in report) | Override port used for the HTTP listener in the generated proxy config | +| `proxy-ssl-port` | app + global | none | (not in report) | Override port used for the HTTPS listener in the generated proxy config | +| `type` | app + global | `nginx` | `--proxy-type`, `--proxy-global-type`, `--proxy-computed-type` | Proxy implementation handling traffic for the app (`nginx`, `caddy`, `haproxy`, `traefik`, `openresty`, or a custom plugin) | + +### Read-only flags + +The following flags surface in `proxy:report` but are not managed by `proxy:set`: + +| Flag | Description | +|---|---| +| `--proxy-enabled` | `true` when the app's `disabled` property is not `true` | diff --git a/docs/processes/process-management.md b/docs/processes/process-management.md index ca8525aea..318341dbf 100644 --- a/docs/processes/process-management.md +++ b/docs/processes/process-management.md @@ -463,3 +463,29 @@ The default value (`true`) may be restored by passing an empty value: ```shell dokku ps:set node-js-app restore ``` + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `dockerfile-start-cmd` | app only | none | (not in report) | Override `CMD` for Dockerfile-based apps | +| `procfile-path` | app + global | `Procfile` | `--ps-procfile-path`, `--ps-global-procfile-path`, `--ps-computed-procfile-path` | Path to the app's Procfile, relative to the build root | +| `restart-policy` | app only | `on-failure:10` | `--ps-restart-policy` | Docker restart policy applied to deployed containers (`no`, `always`, `unless-stopped`, `on-failure[:max-retries]`) | +| `restore` | app only | `true` | `--restore` | When `true`, the app is restarted automatically by `ps:retire` after a host reboot | +| `skip-deploy` | app + global | `false` | (not in report) | When `true`, skips the deploy phase after a successful build | +| `start-cmd` | app only | none | (not in report) | Override start command for buildpack apps | +| `stop-timeout-seconds` | app + global | `30` | `--stop-timeout-seconds`, `--global-stop-timeout-seconds`, `--computed-stop-timeout-seconds` | Seconds Docker waits before SIGKILLing a container on stop | + +### Read-only flags + +The following flags surface in `ps:report` but are not managed by `ps:set` - they are derived from the running process state: + +| Flag | Description | +|---|---| +| `--ps-can-scale` | `false` when the app's procfile or builder forbids horizontal scaling | +| `--deployed` | `true` after the first successful deploy | +| `--running` | `true` while any container for the app is running | +| `--processes` | Total scaled process count across all proctypes | +| `--status-` | Container status and ID for each running proctype (one entry per Procfile process type) | diff --git a/docs/processes/scheduled-cron-tasks.md b/docs/processes/scheduled-cron-tasks.md index 5bb9b6b3d..1df1f2537 100644 --- a/docs/processes/scheduled-cron-tasks.md +++ b/docs/processes/scheduled-cron-tasks.md @@ -295,3 +295,14 @@ SHELL=/bin/bash ### PLACE ALL CRON TASKS ABOVE, DO NOT REMOVE THE WHITESPACE AFTER THIS LINE ``` + +## Properties + +### Settable properties + +| Property | Scope | Default | Report flags | Description | +|---|---|---|---|---| +| `mailfrom` | app + global | none | `--cron-mailfrom` | `From:` address used in cron failure emails | +| `mailto` | app + global | none | `--cron-mailto` | Recipient address for cron failure emails; empty disables email | +| `maintenance` | app + global | `false` | `--cron-maintenance`, `--cron-global-maintenance`, `--cron-computed-maintenance` | When `true`, suspends all cron tasks for the app (or globally) | +| `maintenance.` | app only | `false` | `--cron-maintenance-` (dynamic per task) | Suspends an individual cron task by its computed ID (one row per task); written by `cron:suspend`/`cron:resume` | diff --git a/plugins/app-json/report.go b/plugins/app-json/report.go index 3daee5739..af5f68d07 100644 --- a/plugins/app-json/report.go +++ b/plugins/app-json/report.go @@ -15,7 +15,8 @@ func ReportSingleApp(appName string, format string, infoFlag string) error { var flags map[string]common.ReportFunc if appName == "--global" { flags = map[string]common.ReportFunc{ - "--app-json-global-appjson-path": reportGlobalAppjsonpath, + "--app-json-computed-appjson-path": reportComputedAppjsonpath, + "--app-json-global-appjson-path": reportGlobalAppjsonpath, } } else { flags = map[string]common.ReportFunc{ @@ -41,12 +42,15 @@ func reportComputedAppjsonpath(appName string) string { if value == "" { value = reportGlobalAppjsonpath(appName) } + if value == "" { + value = "app.json" + } return value } func reportGlobalAppjsonpath(appName string) string { - return common.PropertyGetDefault("app-json", "--global", "appjson-path", "app.json") + return common.PropertyGet("app-json", "--global", "appjson-path") } func reportAppjsonpath(appName string) string { diff --git a/plugins/builder-dockerfile/internal-functions b/plugins/builder-dockerfile/internal-functions index 85fdb9f24..a7c6a236a 100755 --- a/plugins/builder-dockerfile/internal-functions +++ b/plugins/builder-dockerfile/internal-functions @@ -44,6 +44,7 @@ cmd-builder-dockerfile-report-single() { local flag_map=() if [[ "$APP" == "--global" ]]; then 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")" ) else @@ -97,6 +98,9 @@ fn-builder-dockerfile-computed-dockerfile-path() { if [[ "$file" == "" ]]; then file="$(fn-builder-dockerfile-global-dockerfile-path "$APP")" fi + if [[ "$file" == "" ]]; then + file="Dockerfile" + fi echo "$file" } @@ -104,7 +108,7 @@ fn-builder-dockerfile-computed-dockerfile-path() { fn-builder-dockerfile-global-dockerfile-path() { declare APP="$1" - fn-plugin-property-get-default "builder-dockerfile" "--global" "dockerfile-path" "Dockerfile" + fn-plugin-property-get-default "builder-dockerfile" "--global" "dockerfile-path" "" } fn-builder-dockerfile-dockerfile-path() { diff --git a/plugins/builder-herokuish/internal-functions b/plugins/builder-herokuish/internal-functions index 78c93f514..a5cf4182e 100755 --- a/plugins/builder-herokuish/internal-functions +++ b/plugins/builder-herokuish/internal-functions @@ -44,6 +44,7 @@ cmd-builder-herokuish-report-single() { local flag_map=() if [[ "$APP" == "--global" ]]; then flag_map=( + "--builder-herokuish-computed-allowed: $(fn-builder-herokuish-computed-allowed "$APP")" "--builder-herokuish-global-allowed: $(fn-builder-herokuish-global-allowed)" ) else @@ -97,16 +98,16 @@ fn-builder-herokuish-computed-allowed() { if [[ -z "$allowed" ]]; then allowed="$(fn-builder-herokuish-global-allowed)" fi + if [[ -z "$allowed" ]]; then + allowed="true" + [[ "$(dpkg --print-architecture 2>/dev/null || true)" != "amd64" ]] && allowed="false" + fi echo "$allowed" } fn-builder-herokuish-global-allowed() { - local default_value="true" - - [[ "$(dpkg --print-architecture 2>/dev/null || true)" != "amd64" ]] && default_value="false" - - fn-plugin-property-get-default "builder-herokuish" "--global" "allowed" "$default_value" + fn-plugin-property-get-default "builder-herokuish" "--global" "allowed" "" } fn-builder-herokuish-allowed() { diff --git a/plugins/builder-lambda/internal-functions b/plugins/builder-lambda/internal-functions index 1459dc0f3..98af8d6b7 100755 --- a/plugins/builder-lambda/internal-functions +++ b/plugins/builder-lambda/internal-functions @@ -44,6 +44,7 @@ cmd-builder-lambda-report-single() { local flag_map=() if [[ "$APP" == "--global" ]]; then 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")" ) else @@ -97,6 +98,9 @@ fn-builder-lambda-computed-lambdayml-path() { if [[ "$file" == "" ]]; then file="$(fn-builder-lambda-global-lambdayml-path "$APP")" fi + if [[ "$file" == "" ]]; then + file="lambda.yml" + fi echo "$file" } @@ -104,7 +108,7 @@ fn-builder-lambda-computed-lambdayml-path() { fn-builder-lambda-global-lambdayml-path() { declare APP="$1" - fn-plugin-property-get-default "builder-lambda" "--global" "lambdayml-path" "lambda.yml" + fn-plugin-property-get-default "builder-lambda" "--global" "lambdayml-path" "" } fn-builder-lambda-lambdayml-path() { diff --git a/plugins/builder-nixpacks/internal-functions b/plugins/builder-nixpacks/internal-functions index 1f41c319e..2350bd4ea 100755 --- a/plugins/builder-nixpacks/internal-functions +++ b/plugins/builder-nixpacks/internal-functions @@ -44,6 +44,7 @@ cmd-builder-nixpacks-report-single() { local flag_map=() if [[ "$APP" == "--global" ]]; then 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")" ) else @@ -97,6 +98,9 @@ fn-builder-nixpacks-computed-nixpackstoml-path() { if [[ "$file" == "" ]]; then file="$(fn-builder-nixpacks-global-nixpackstoml-path "$APP")" fi + if [[ "$file" == "" ]]; then + file="nixpacks.toml" + fi echo "$file" } @@ -104,7 +108,7 @@ fn-builder-nixpacks-computed-nixpackstoml-path() { fn-builder-nixpacks-global-nixpackstoml-path() { declare APP="$1" - fn-plugin-property-get "builder-nixpacks" "--global" "nixpackstoml-path" "nixpacks.toml" + fn-plugin-property-get "builder-nixpacks" "--global" "nixpackstoml-path" "" } fn-builder-nixpacks-nixpackstoml-path() { diff --git a/plugins/builder-pack/internal-functions b/plugins/builder-pack/internal-functions index 548fbe2b2..f127f77a0 100755 --- a/plugins/builder-pack/internal-functions +++ b/plugins/builder-pack/internal-functions @@ -44,6 +44,7 @@ cmd-builder-pack-report-single() { local flag_map=() if [[ "$APP" == "--global" ]]; then 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")" ) else @@ -97,6 +98,9 @@ fn-builder-pack-computed-projecttoml-path() { if [[ "$file" == "" ]]; then file="$(fn-builder-pack-global-projecttoml-path "$APP")" fi + if [[ "$file" == "" ]]; then + file="project.toml" + fi echo "$file" } @@ -104,7 +108,7 @@ fn-builder-pack-computed-projecttoml-path() { fn-builder-pack-global-projecttoml-path() { declare APP="$1" - fn-plugin-property-get-default "builder-pack" "--global" "projecttoml-path" "project.toml" + fn-plugin-property-get-default "builder-pack" "--global" "projecttoml-path" "" } fn-builder-pack-projecttoml-path() { diff --git a/plugins/builder-railpack/internal-functions b/plugins/builder-railpack/internal-functions index 3d3e31297..0dc979e46 100755 --- a/plugins/builder-railpack/internal-functions +++ b/plugins/builder-railpack/internal-functions @@ -44,6 +44,7 @@ cmd-builder-railpack-report-single() { local flag_map=() if [[ "$APP" == "--global" ]]; then 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")" ) else @@ -97,6 +98,9 @@ fn-builder-railpack-computed-railpackjson-path() { if [[ "$file" == "" ]]; then file="$(fn-builder-railpack-global-railpackjson-path "$APP")" fi + if [[ "$file" == "" ]]; then + file="railpack.json" + fi echo "$file" } @@ -104,7 +108,7 @@ fn-builder-railpack-computed-railpackjson-path() { fn-builder-railpack-global-railpackjson-path() { declare APP="$1" - fn-plugin-property-get "builder-railpack" "--global" "railpackjson-path" "railpack.json" + fn-plugin-property-get "builder-railpack" "--global" "railpackjson-path" "" } fn-builder-railpack-railpackjson-path() { diff --git a/plugins/caddy-vhosts/certs-force b/plugins/caddy-vhosts/certs-force index a01fd5d5a..60b79c18d 100755 --- a/plugins/caddy-vhosts/certs-force +++ b/plugins/caddy-vhosts/certs-force @@ -13,7 +13,7 @@ trigger-caddy-vhosts-certs-force() { return fi - if [[ -n "$(fn-caddy-letsencrypt-email)" ]]; then + if [[ -n "$(fn-caddy-computed-letsencrypt-email)" ]]; then echo true fi } diff --git a/plugins/caddy-vhosts/command-functions b/plugins/caddy-vhosts/command-functions index 5508f1e47..c13c65be1 100755 --- a/plugins/caddy-vhosts/command-functions +++ b/plugins/caddy-vhosts/command-functions @@ -70,23 +70,34 @@ cmd-caddy-report-single() { local flag_map=() if [[ "$APP" == "--global" ]]; then flag_map=( + "--caddy-computed-image: $(fn-caddy-computed-image)" + "--caddy-computed-letsencrypt-email: $(fn-caddy-computed-letsencrypt-email)" + "--caddy-computed-letsencrypt-server: $(fn-caddy-computed-letsencrypt-server)" + "--caddy-computed-log-level: $(fn-caddy-computed-log-level)" + "--caddy-computed-polling-interval: $(fn-caddy-computed-polling-interval)" + "--caddy-computed-tls-internal: $(fn-caddy-computed-tls-internal "$APP")" + "--caddy-global-image: $(fn-caddy-global-image)" + "--caddy-global-letsencrypt-email: $(fn-caddy-global-letsencrypt-email)" + "--caddy-global-letsencrypt-server: $(fn-caddy-global-letsencrypt-server)" + "--caddy-global-log-level: $(fn-caddy-global-log-level)" + "--caddy-global-polling-interval: $(fn-caddy-global-polling-interval)" "--caddy-global-tls-internal: $(fn-caddy-global-tls-internal)" - "--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-computed-image: $(fn-caddy-computed-image)" + "--caddy-computed-letsencrypt-email: $(fn-caddy-computed-letsencrypt-email)" + "--caddy-computed-letsencrypt-server: $(fn-caddy-computed-letsencrypt-server)" + "--caddy-computed-log-level: $(fn-caddy-computed-log-level)" + "--caddy-computed-polling-interval: $(fn-caddy-computed-polling-interval)" "--caddy-computed-tls-internal: $(fn-caddy-computed-tls-internal "$APP")" + "--caddy-global-image: $(fn-caddy-global-image)" + "--caddy-global-letsencrypt-email: $(fn-caddy-global-letsencrypt-email)" + "--caddy-global-letsencrypt-server: $(fn-caddy-global-letsencrypt-server)" + "--caddy-global-log-level: $(fn-caddy-global-log-level)" + "--caddy-global-polling-interval: $(fn-caddy-global-polling-interval)" "--caddy-global-tls-internal: $(fn-caddy-global-tls-internal)" - "--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 diff --git a/plugins/caddy-vhosts/docker-args-process-deploy b/plugins/caddy-vhosts/docker-args-process-deploy index b44256827..828c8c5e5 100755 --- a/plugins/caddy-vhosts/docker-args-process-deploy +++ b/plugins/caddy-vhosts/docker-args-process-deploy @@ -68,7 +68,7 @@ trigger-caddy-vhosts-docker-args-process-deploy() { fi done < <(plugn trigger ports-get "$APP") - letsencrypt_email="$(fn-caddy-letsencrypt-email)" + letsencrypt_email="$(fn-caddy-computed-letsencrypt-email)" if [[ -n "$letsencrypt_email" ]] && [[ -z "$proxy_container_https_port" ]]; then proxy_container_https_port_candidate="$proxy_container_http_port_candidate" proxy_host_https_port_candidate="$proxy_host_http_port_candidate" diff --git a/plugins/caddy-vhosts/internal-functions b/plugins/caddy-vhosts/internal-functions index 9df6483c9..8a4ee43c3 100755 --- a/plugins/caddy-vhosts/internal-functions +++ b/plugins/caddy-vhosts/internal-functions @@ -36,35 +36,73 @@ fn-caddy-template-compose-file() { fi local SIGIL_PARAMS=(CADDY_DATA_DIR="${DOKKU_LIB_ROOT}/data/caddy" - 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_IMAGE="$(fn-caddy-computed-image)" + CADDY_LETSENCRYPT_EMAIL="$(fn-caddy-computed-letsencrypt-email)" + CADDY_LETSENCRYPT_SERVER="$(fn-caddy-computed-letsencrypt-server)" + CADDY_LOG_LEVEL="$(fn-caddy-computed-log-level)" + CADDY_POLLING_INTERVAL="$(fn-caddy-computed-polling-interval)") sigil -f "$COMPOSE_TEMPLATE" "${SIGIL_PARAMS[@]}" | cat -s >"$OUTPUT_PATH" } -fn-caddy-image() { - fn-plugin-property-get-default "caddy" "--global" "image" "$(grep "FROM" "$PLUGIN_AVAILABLE_PATH/caddy-vhosts/Dockerfile" | awk '{print $2}')" +fn-caddy-global-image() { + fn-plugin-property-get-default "caddy" "--global" "image" "" } -fn-caddy-letsencrypt-email() { +fn-caddy-computed-image() { + local value + value="$(fn-caddy-global-image)" + if [[ -z "$value" ]]; then + value="$(grep "FROM" "$PLUGIN_AVAILABLE_PATH/caddy-vhosts/Dockerfile" | awk '{print $2}')" + fi + echo "$value" +} + +fn-caddy-global-letsencrypt-email() { fn-plugin-property-get-default "caddy" "--global" "letsencrypt-email" "" } -fn-caddy-letsencrypt-server() { - fn-plugin-property-get-default "caddy" "--global" "letsencrypt-server" "https://acme-v02.api.letsencrypt.org/directory" +fn-caddy-computed-letsencrypt-email() { + fn-caddy-global-letsencrypt-email } -fn-caddy-log-level() { - local log_level - log_level="$(fn-plugin-property-get-default "caddy" "--global" "log-level" "ERROR")" - echo "${log_level^^}" +fn-caddy-global-letsencrypt-server() { + fn-plugin-property-get-default "caddy" "--global" "letsencrypt-server" "" } -fn-caddy-polling-interval() { - fn-plugin-property-get-default "caddy" "--global" "polling-interval" "5s" +fn-caddy-computed-letsencrypt-server() { + local value + value="$(fn-caddy-global-letsencrypt-server)" + if [[ -z "$value" ]]; then + value="https://acme-v02.api.letsencrypt.org/directory" + fi + echo "$value" +} + +fn-caddy-global-log-level() { + fn-plugin-property-get-default "caddy" "--global" "log-level" "" +} + +fn-caddy-computed-log-level() { + local value + value="$(fn-caddy-global-log-level)" + if [[ -z "$value" ]]; then + value="ERROR" + fi + echo "${value^^}" +} + +fn-caddy-global-polling-interval() { + fn-plugin-property-get-default "caddy" "--global" "polling-interval" "" +} + +fn-caddy-computed-polling-interval() { + local value + value="$(fn-caddy-global-polling-interval)" + if [[ -z "$value" ]]; then + value="5s" + fi + echo "$value" } fn-caddy-tls-internal() { @@ -79,9 +117,12 @@ fn-caddy-computed-tls-internal() { if [[ -z "$value" ]]; then value="$(fn-caddy-global-tls-internal)" fi + if [[ -z "$value" ]]; then + value="false" + fi echo "$value" } fn-caddy-global-tls-internal() { - fn-plugin-property-get-default "caddy" "--global" "tls-internal" "false" + fn-plugin-property-get-default "caddy" "--global" "tls-internal" "" } diff --git a/plugins/checks/internal-functions b/plugins/checks/internal-functions index 47c1b4953..9e4dacd84 100755 --- a/plugins/checks/internal-functions +++ b/plugins/checks/internal-functions @@ -45,6 +45,7 @@ cmd-checks-report-single() { local flag_map=() if [[ "$APP" == "--global" ]]; then flag_map=( + "--checks-computed-wait-to-retire: $(fn-checks-computed-wait-to-retire "$APP")" "--checks-global-wait-to-retire: $(fn-checks-global-wait-to-retire "$APP")" ) else @@ -116,6 +117,9 @@ fn-checks-computed-wait-to-retire() { if [[ "$file" == "" ]]; then file="$(fn-checks-global-wait-to-retire "$APP")" fi + if [[ "$file" == "" ]]; then + file="60" + fi echo "$file" } @@ -123,7 +127,7 @@ fn-checks-computed-wait-to-retire() { fn-checks-global-wait-to-retire() { declare APP="$1" - fn-plugin-property-get-default "checks" "--global" "wait-to-retire" "60" + fn-plugin-property-get-default "checks" "--global" "wait-to-retire" "" } fn-checks-wait-to-retire() { diff --git a/plugins/common/archive-functions b/plugins/common/archive-functions index 9ed12ccc9..60dd2c1c1 100755 --- a/plugins/common/archive-functions +++ b/plugins/common/archive-functions @@ -11,12 +11,12 @@ fi DOKKU_ARCHIVE_MAX_SIZE_DEFAULT="1073741824" DOKKU_ARCHIVE_MAX_FILES_DEFAULT="10000" -fn-archive-max-size() { +fn-archive-computed-max-size() { declare desc="returns the configured max archive size in bytes" fn-plugin-property-get "git" "--global" "archive-max-size" "$DOKKU_ARCHIVE_MAX_SIZE_DEFAULT" } -fn-archive-max-files() { +fn-archive-computed-max-files() { declare desc="returns the configured max archive entry count" fn-plugin-property-get "git" "--global" "archive-max-files" "$DOKKU_ARCHIVE_MAX_FILES_DEFAULT" } @@ -43,8 +43,8 @@ fn-archive-check-bomb-protection() { declare desc="validates archive against bomb protection limits" declare ARCHIVE_PATH="$1" ARCHIVE_TYPE="$2" local MAX_SIZE MAX_FILES - MAX_SIZE="$(fn-archive-max-size)" - MAX_FILES="$(fn-archive-max-files)" + MAX_SIZE="$(fn-archive-computed-max-size)" + MAX_FILES="$(fn-archive-computed-max-files)" local ARCHIVE_SIZE ARCHIVE_SIZE="$(stat -c %s "$ARCHIVE_PATH" 2>/dev/null || stat -f %z "$ARCHIVE_PATH" 2>/dev/null || echo 0)" @@ -190,8 +190,8 @@ fn-archive-extract-zip() { declare desc="safely extracts a zip archive with post-extraction symlink validation" declare ARCHIVE_PATH="$1" DEST_DIR="$2" local MAX_SIZE MAX_FILES - MAX_SIZE="$(fn-archive-max-size)" - MAX_FILES="$(fn-archive-max-files)" + MAX_SIZE="$(fn-archive-computed-max-size)" + MAX_FILES="$(fn-archive-computed-max-files)" local ARCHIVE_SIZE ARCHIVE_SIZE="$(stat -c %s "$ARCHIVE_PATH" 2>/dev/null || stat -f %z "$ARCHIVE_PATH" 2>/dev/null || echo 0)" diff --git a/plugins/git/functions b/plugins/git/functions index 764942437..9c9b9206c 100755 --- a/plugins/git/functions +++ b/plugins/git/functions @@ -65,7 +65,7 @@ cmd-git-hook() { plugn trigger app-exists "$APP" 2>/dev/null || is_valid_app_name "$APP" - DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")" + DOKKU_DEPLOY_BRANCH="$(fn-git-computed-deploy-branch "$APP")" if ! git check-ref-format --branch "$DOKKU_DEPLOY_BRANCH" &>/dev/null; then echo $'\e[1G\e[K'"-----> WARNING: Invalid branch name '$DOKKU_DEPLOY_BRANCH' specified via deploy-branch setting." echo $'\e[1G\e[K'"-----> For more details, please see the man page for 'git-check-ref-format.'" @@ -84,7 +84,7 @@ cmd-git-hook() { if [[ $(find "$PLUGIN_PATH"/enabled/*/receive-branch 2>/dev/null | wc -l) != 1 ]]; then plugn trigger receive-branch "$APP" "$newrev" "$refname" plugn trigger deploy-source-set "$APP" "git-push" "$newrev" - elif [[ -z "$(fn-git-deploy-branch "$APP" "")" ]]; then + elif [[ -z "$(fn-git-computed-deploy-branch "$APP" "")" ]]; then local deploy_branch="${refname/refs\/heads\//}" deploy_branch="${deploy_branch/refs\/tags\//}" @@ -115,7 +115,7 @@ git_build() { fi local REF="$REV" else - DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")" + DOKKU_DEPLOY_BRANCH="$(fn-git-computed-deploy-branch "$APP")" if [[ -f "$DOKKU_ROOT/$APP/refs/heads/$DOKKU_DEPLOY_BRANCH" ]]; then REF=$(<"$DOKKU_ROOT/$APP/refs/heads/$DOKKU_DEPLOY_BRANCH") else diff --git a/plugins/git/git-deploy-branch b/plugins/git/git-deploy-branch index 3ec00749b..f0f5e50fd 100755 --- a/plugins/git/git-deploy-branch +++ b/plugins/git/git-deploy-branch @@ -8,7 +8,7 @@ trigger-git-git-deploy-branch() { declare trigger="git-deploy-branch" declare APP="$1" - fn-git-deploy-branch "$APP" + fn-git-computed-deploy-branch "$APP" } trigger-git-git-deploy-branch "$@" diff --git a/plugins/git/git-from-directory b/plugins/git/git-from-directory index 238fb297b..87dddadd3 100755 --- a/plugins/git/git-from-directory +++ b/plugins/git/git-from-directory @@ -11,7 +11,7 @@ trigger-git-git-from-directory() { declare APP="$1" SOURCECODE_WORK_DIR="$2" USER_NAME="${3:-Dokku}" USER_EMAIL="${4:-automated@dokku.sh}" local APP_ROOT="$DOKKU_ROOT/$APP" - local DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")" + local DOKKU_DEPLOY_BRANCH="$(fn-git-computed-deploy-branch "$APP")" local REV local TMP_WORK_DIR=$(mktemp -d "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX") local TMP_WORK_DIR_2=$(mktemp -d "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX") @@ -25,7 +25,7 @@ trigger-git-git-from-directory() { dokku_log_info1 "Updating git repository with specified build context" if [[ "$has_code" == "false" ]]; then # setup new repo - local DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")" + local DEPLOY_BRANCH="$(fn-git-computed-deploy-branch "$APP")" cp -rT "$SOURCECODE_WORK_DIR" "$TMP_WORK_DIR" suppress_output fn-git-cmd "$TMP_WORK_DIR" init suppress_output fn-git-cmd "$TMP_WORK_DIR" checkout -b "$DEPLOY_BRANCH" @@ -64,7 +64,7 @@ trigger-git-git-from-directory() { return else local exit_code=$? - local DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")" + local DOKKU_DEPLOY_BRANCH="$(fn-git-computed-deploy-branch "$APP")" if [[ "$has_code" == "false" ]]; then fn-git-cmd "$APP_ROOT" update-ref -d HEAD else diff --git a/plugins/git/internal-functions b/plugins/git/internal-functions index 63c898840..916c70ca5 100755 --- a/plugins/git/internal-functions +++ b/plugins/git/internal-functions @@ -1,6 +1,7 @@ #!/usr/bin/env bash source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions" +source "$PLUGIN_CORE_AVAILABLE_PATH/common/archive-functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x @@ -273,7 +274,7 @@ cmd-git-sync() { fi local APP_ROOT="$DOKKU_ROOT/$APP" - DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")" + DOKKU_DEPLOY_BRANCH="$(fn-git-computed-deploy-branch "$APP")" CURRENT_REF="$(fn-git-cmd "$APP_ROOT" rev-parse "$DOKKU_DEPLOY_BRANCH" 2>/dev/null || true)" dokku_setup_build_capture "$APP" "git:sync" @@ -369,19 +370,27 @@ cmd-git-report-single() { local flag_map=() if [[ "$APP" == "--global" ]]; then flag_map=( - "--git-global-archive-max-files: $(fn-plugin-property-get "git" "--global" "archive-max-files" "10000")" - "--git-global-archive-max-size: $(fn-plugin-property-get "git" "--global" "archive-max-size" "1073741824")" - "--git-global-deploy-branch: $(fn-plugin-property-get "git" "--global" "deploy-branch" "master")" + "--git-computed-archive-max-files: $(fn-archive-computed-max-files)" + "--git-computed-archive-max-size: $(fn-archive-computed-max-size)" + "--git-computed-deploy-branch: $(fn-git-computed-deploy-branch "$APP")" + "--git-computed-keep-git-dir: $(fn-git-computed-keep-git-dir "$APP")" + "--git-global-archive-max-files: $(fn-plugin-property-get "git" "--global" "archive-max-files" "")" + "--git-global-archive-max-size: $(fn-plugin-property-get "git" "--global" "archive-max-size" "")" + "--git-global-deploy-branch: $(fn-plugin-property-get "git" "--global" "deploy-branch" "")" + "--git-global-keep-git-dir: $(fn-plugin-property-get "git" "--global" "keep-git-dir" "")" ) else verify_app_name "$APP" flag_map=( - "--git-computed-deploy-branch: $(fn-git-deploy-branch "$APP")" - "--git-computed-keep-git-dir: $(fn-git-keep-git-dir "$APP")" + "--git-computed-archive-max-files: $(fn-archive-computed-max-files)" + "--git-computed-archive-max-size: $(fn-archive-computed-max-size)" + "--git-computed-deploy-branch: $(fn-git-computed-deploy-branch "$APP")" + "--git-computed-keep-git-dir: $(fn-git-computed-keep-git-dir "$APP")" "--git-deploy-branch: $(fn-plugin-property-get "git" "$APP" "deploy-branch" "")" - "--git-global-archive-max-files: $(fn-plugin-property-get "git" "--global" "archive-max-files" "10000")" - "--git-global-archive-max-size: $(fn-plugin-property-get "git" "--global" "archive-max-size" "1073741824")" - "--git-global-deploy-branch: $(fn-plugin-property-get "git" "--global" "deploy-branch" "master")" + "--git-global-archive-max-files: $(fn-plugin-property-get "git" "--global" "archive-max-files" "")" + "--git-global-archive-max-size: $(fn-plugin-property-get "git" "--global" "archive-max-size" "")" + "--git-global-deploy-branch: $(fn-plugin-property-get "git" "--global" "deploy-branch" "")" + "--git-global-keep-git-dir: $(fn-plugin-property-get "git" "--global" "keep-git-dir" "")" "--git-keep-git-dir: $(fn-plugin-property-get "git" "$APP" "keep-git-dir" "")" "--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)" @@ -475,13 +484,13 @@ fn-git-clone() { local APP_ROOT="$DOKKU_ROOT/$APP" [[ -z "$APP" ]] && dokku_log_fail "Please specify an app to run the command on" - local DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")" + local DOKKU_DEPLOY_BRANCH="$(fn-git-computed-deploy-branch "$APP")" if fn-git-cmd "$APP_ROOT" rev-parse "$DOKKU_DEPLOY_BRANCH" &>/dev/null; then dokku_log_fail "The clone subcommand can only be executed for new applications" fi if [[ -z "$GIT_REF" ]]; then - GIT_REF="$(fn-git-deploy-branch "$APP")" + GIT_REF="$(fn-git-computed-deploy-branch "$APP")" fi local TMP_IS_REF_DIR=$(mktemp -d "/tmp/dokku-ref-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX") @@ -511,7 +520,7 @@ fn-git-clone() { fi fi - DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")" + DOKKU_DEPLOY_BRANCH="$(fn-git-computed-deploy-branch "$APP")" if [[ "$GIT_REF" != "$DOKKU_DEPLOY_BRANCH" ]]; then if [[ "$is_ref" == "true" ]]; then fn-git-cmd "$TMP_CLONE_DIR" branch -qq -D "$DOKKU_DEPLOY_BRANCH" 2>/dev/null || true @@ -542,12 +551,12 @@ fn-git-fetch() { local DOKKU_DEPLOY_BRANCH local APP_ROOT="$DOKKU_ROOT/$APP" - local DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")" + local DOKKU_DEPLOY_BRANCH="$(fn-git-computed-deploy-branch "$APP")" if ! fn-git-cmd "$APP_ROOT" rev-parse "$DOKKU_DEPLOY_BRANCH" &>/dev/null; then dokku_log_fail "The fetch subcommand can only be executed for existing applications" fi - DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")" + DOKKU_DEPLOY_BRANCH="$(fn-git-computed-deploy-branch "$APP")" if ! fn-git-cmd "$APP_ROOT" check-ref-format --branch "$DOKKU_DEPLOY_BRANCH" &>/dev/null; then dokku_log_warn "Invalid branch name '$DOKKU_DEPLOY_BRANCH' specified via deploy-branch setting." dokku_log_warn "For more details, please see the man page for 'git-check-ref-format.'" @@ -571,7 +580,7 @@ fn-git-has-code() { declare APP="$1" DOKKU_DEPLOY_BRANCH="$2" if [[ -z "$DOKKU_DEPLOY_BRANCH" ]]; then - DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")" + DOKKU_DEPLOY_BRANCH="$(fn-git-computed-deploy-branch "$APP")" fi local HEAD_FILE="$DOKKU_ROOT/$APP/refs/heads/$DOKKU_DEPLOY_BRANCH" @@ -585,7 +594,7 @@ fn-git-has-code() { fn-git-last-updated-at() { declare desc="retrieve the deploy branch for a given application" declare APP="$1" - local DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")" + local DOKKU_DEPLOY_BRANCH="$(fn-git-computed-deploy-branch "$APP")" local HEAD_FILE="$DOKKU_ROOT/$APP/refs/heads/$DOKKU_DEPLOY_BRANCH" if [[ -f "$HEAD_FILE" ]]; then @@ -593,7 +602,7 @@ fn-git-last-updated-at() { fi } -fn-git-deploy-branch() { +fn-git-computed-deploy-branch() { declare desc="retrieve the deploy branch for a given application" local APP="$1" local DEFAULT_BRANCH="${2-master}" @@ -609,14 +618,17 @@ fn-git-deploy-branch() { fi } -fn-git-keep-git-dir() { +fn-git-computed-keep-git-dir() { declare desc="retrieve the keep-git-dir value for a given application" local APP="$1" local DEFAULT_KEEP_GIT_DIR="${2-false}" local DOKKU_KEEP_GIT_DIR="$(fn-plugin-property-get "git" "$APP" "keep-git-dir" "")" + local DOKKU_GLOBAL_KEEP_GIT_DIR="$(fn-plugin-property-get "git" "--global" "keep-git-dir" "")" if [[ -n "$DOKKU_KEEP_GIT_DIR" ]]; then echo "$DOKKU_KEEP_GIT_DIR" + elif [[ -n "$DOKKU_GLOBAL_KEEP_GIT_DIR" ]]; then + echo "$DOKKU_GLOBAL_KEEP_GIT_DIR" else echo "$DEFAULT_KEEP_GIT_DIR" fi @@ -624,7 +636,7 @@ fn-git-keep-git-dir() { fn-git-setup-build-dir() { declare APP="$1" GIT_WORKDIR="$2" REV="$3" - local DOKKU_KEEP_GIT_DIR="$(fn-git-keep-git-dir "$APP")" + local DOKKU_KEEP_GIT_DIR="$(fn-git-computed-keep-git-dir "$APP")" if [[ "$DOKKU_KEEP_GIT_DIR" == "true" ]]; then fn-git-setup-build-dir-new "$APP" "$GIT_WORKDIR" "$REV" @@ -636,7 +648,7 @@ fn-git-setup-build-dir() { fn-git-setup-build-dir-new() { declare APP="$1" GIT_WORKDIR="$2" REV="$3" local APP_ROOT="$DOKKU_ROOT/$APP" - local DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")" + local DOKKU_DEPLOY_BRANCH="$(fn-git-computed-deploy-branch "$APP")" # unset the git quarantine path to allow us to use 2.13.0+ # See this issue for more information: https://github.com/dokku/dokku/issues/2796 @@ -671,7 +683,7 @@ fn-git-setup-build-dir-worktree() { fn-git-setup-build-dir-submodules() { declare APP="$1" GIT_WORKDIR="$2" - local DOKKU_KEEP_GIT_DIR="$(fn-git-keep-git-dir "$APP")" + local DOKKU_KEEP_GIT_DIR="$(fn-git-computed-keep-git-dir "$APP")" # unset the git quarantine path to allow us to use 2.13.0+ # See this issue for more information: https://github.com/dokku/dokku/issues/2796 diff --git a/plugins/haproxy-vhosts/certs-force b/plugins/haproxy-vhosts/certs-force index 69bab2c83..91d6266cc 100755 --- a/plugins/haproxy-vhosts/certs-force +++ b/plugins/haproxy-vhosts/certs-force @@ -13,7 +13,7 @@ trigger-haproxy-vhosts-certs-force() { return fi - if [[ -n "$(fn-haproxy-letsencrypt-email)" ]]; then + if [[ -n "$(fn-haproxy-computed-letsencrypt-email)" ]]; then echo true fi } diff --git a/plugins/haproxy-vhosts/command-functions b/plugins/haproxy-vhosts/command-functions index fb0e92e3a..23e654591 100755 --- a/plugins/haproxy-vhosts/command-functions +++ b/plugins/haproxy-vhosts/command-functions @@ -71,11 +71,16 @@ cmd-haproxy-report-single() { verify_app_name "$APP" fi local flag_map=( - "--haproxy-image: $(fn-haproxy-image)" - "--haproxy-letsencrypt-email: $(fn-haproxy-letsencrypt-email)" - "--haproxy-letsencrypt-server: $(fn-haproxy-letsencrypt-server)" - "--haproxy-log-level: $(fn-haproxy-log-level)" - "--haproxy-refresh-conf: $(fn-haproxy-refresh-conf)" + "--haproxy-computed-image: $(fn-haproxy-computed-image)" + "--haproxy-computed-letsencrypt-email: $(fn-haproxy-computed-letsencrypt-email)" + "--haproxy-computed-letsencrypt-server: $(fn-haproxy-computed-letsencrypt-server)" + "--haproxy-computed-log-level: $(fn-haproxy-computed-log-level)" + "--haproxy-computed-refresh-conf: $(fn-haproxy-computed-refresh-conf)" + "--haproxy-global-image: $(fn-haproxy-global-image)" + "--haproxy-global-letsencrypt-email: $(fn-haproxy-global-letsencrypt-email)" + "--haproxy-global-letsencrypt-server: $(fn-haproxy-global-letsencrypt-server)" + "--haproxy-global-log-level: $(fn-haproxy-global-log-level)" + "--haproxy-global-refresh-conf: $(fn-haproxy-global-refresh-conf)" ) fn-report-validate-format "$FORMAT" "$INFO_FLAG" diff --git a/plugins/haproxy-vhosts/docker-args-process-deploy b/plugins/haproxy-vhosts/docker-args-process-deploy index 94eed72dd..36724804a 100755 --- a/plugins/haproxy-vhosts/docker-args-process-deploy +++ b/plugins/haproxy-vhosts/docker-args-process-deploy @@ -68,7 +68,7 @@ trigger-haproxy-vhosts-docker-args-process-deploy() { fi done < <(plugn trigger ports-get "$APP") - letsencrypt_email="$(fn-haproxy-letsencrypt-email)" + letsencrypt_email="$(fn-haproxy-computed-letsencrypt-email)" if [[ -n "$letsencrypt_email" ]] && [[ -z "$proxy_container_https_port" ]]; then proxy_container_https_port_candidate="$proxy_container_http_port_candidate" proxy_host_https_port_candidate="$proxy_host_http_port_candidate" diff --git a/plugins/haproxy-vhosts/internal-functions b/plugins/haproxy-vhosts/internal-functions index c4b8d80ac..3ee7d43a5 100755 --- a/plugins/haproxy-vhosts/internal-functions +++ b/plugins/haproxy-vhosts/internal-functions @@ -35,33 +35,71 @@ fn-haproxy-template-compose-file() { COMPOSE_TEMPLATE="$CUSTOM_COMPOSE_TEMPLATE" fi - local SIGIL_PARAMS=(HAPROXY_IMAGE="$(fn-haproxy-image)" - HAPROXY_LOG_LEVEL="$(fn-haproxy-log-level)" - HAPROXY_LETSENCRYPT_EMAIL="$(fn-haproxy-letsencrypt-email)" - HAPROXY_LETSENCRYPT_SERVER="$(fn-haproxy-letsencrypt-server)" - HAPROXY_REFRESH_CONF="$(fn-haproxy-refresh-conf)") + local SIGIL_PARAMS=(HAPROXY_IMAGE="$(fn-haproxy-computed-image)" + HAPROXY_LOG_LEVEL="$(fn-haproxy-computed-log-level)" + HAPROXY_LETSENCRYPT_EMAIL="$(fn-haproxy-computed-letsencrypt-email)" + HAPROXY_LETSENCRYPT_SERVER="$(fn-haproxy-computed-letsencrypt-server)" + HAPROXY_REFRESH_CONF="$(fn-haproxy-computed-refresh-conf)") sigil -f "$COMPOSE_TEMPLATE" "${SIGIL_PARAMS[@]}" | cat -s >"$OUTPUT_PATH" } -fn-haproxy-image() { - fn-plugin-property-get-default "haproxy" "--global" "image" "$(grep "FROM" "$PLUGIN_AVAILABLE_PATH/haproxy-vhosts/Dockerfile" | awk '{print $2}')" +fn-haproxy-global-image() { + fn-plugin-property-get-default "haproxy" "--global" "image" "" } -fn-haproxy-log-level() { - local log_level - log_level="$(fn-plugin-property-get-default "haproxy" "--global" "log-level" "ERROR")" - echo "${log_level^^}" +fn-haproxy-computed-image() { + local value + value="$(fn-haproxy-global-image)" + if [[ -z "$value" ]]; then + value="$(grep "FROM" "$PLUGIN_AVAILABLE_PATH/haproxy-vhosts/Dockerfile" | awk '{print $2}')" + fi + echo "$value" } -fn-haproxy-letsencrypt-email() { +fn-haproxy-global-log-level() { + fn-plugin-property-get-default "haproxy" "--global" "log-level" "" +} + +fn-haproxy-computed-log-level() { + local value + value="$(fn-haproxy-global-log-level)" + if [[ -z "$value" ]]; then + value="ERROR" + fi + echo "${value^^}" +} + +fn-haproxy-global-letsencrypt-email() { fn-plugin-property-get-default "haproxy" "--global" "letsencrypt-email" "" } -fn-haproxy-letsencrypt-server() { - fn-plugin-property-get-default "haproxy" "--global" "letsencrypt-server" "https://acme-v02.api.letsencrypt.org/directory" +fn-haproxy-computed-letsencrypt-email() { + fn-haproxy-global-letsencrypt-email } -fn-haproxy-refresh-conf() { - fn-plugin-property-get-default "haproxy" "--global" "refresh-conf" "10" +fn-haproxy-global-letsencrypt-server() { + fn-plugin-property-get-default "haproxy" "--global" "letsencrypt-server" "" +} + +fn-haproxy-computed-letsencrypt-server() { + local value + value="$(fn-haproxy-global-letsencrypt-server)" + if [[ -z "$value" ]]; then + value="https://acme-v02.api.letsencrypt.org/directory" + fi + echo "$value" +} + +fn-haproxy-global-refresh-conf() { + fn-plugin-property-get-default "haproxy" "--global" "refresh-conf" "" +} + +fn-haproxy-computed-refresh-conf() { + local value + value="$(fn-haproxy-global-refresh-conf)" + if [[ -z "$value" ]]; then + value="10" + fi + echo "$value" } diff --git a/plugins/logs/functions.go b/plugins/logs/functions.go index 95b522329..2669202ba 100644 --- a/plugins/logs/functions.go +++ b/plugins/logs/functions.go @@ -222,7 +222,7 @@ func writeVectorConfig() error { data.Sources["docker-global-source"] = vectorSource{ Type: "docker_logs", - IncludeLabels: []string{reportGlobalAppLabelAlias("global")}, + IncludeLabels: []string{reportComputedAppLabelAlias("global")}, } data.Sinks["docker-global-sink"] = sink diff --git a/plugins/logs/report.go b/plugins/logs/report.go index af7953b26..a786ece6d 100644 --- a/plugins/logs/report.go +++ b/plugins/logs/report.go @@ -20,23 +20,31 @@ func ReportSingleApp(appName string, format string, infoFlag string) error { 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, - "--logs-vector-global-networks": reportVectorGlobalNetworks, + "--logs-computed-app-label-alias": reportComputedAppLabelAlias, + "--logs-computed-max-size": reportComputedMaxSize, + "--logs-computed-vector-image": reportComputedVectorImage, + "--logs-computed-vector-networks": reportComputedVectorNetworks, + "--logs-computed-vector-sink": reportComputedVectorSink, + "--logs-global-app-label-alias": reportGlobalAppLabelAlias, + "--logs-global-max-size": reportGlobalMaxSize, + "--logs-global-vector-image": reportGlobalVectorImage, + "--logs-global-vector-networks": reportGlobalVectorNetworks, + "--logs-global-vector-sink": reportGlobalVectorSink, } } else { flags = map[string]common.ReportFunc{ + "--logs-app-label-alias": reportAppLabelAlias, "--logs-computed-app-label-alias": reportComputedAppLabelAlias, "--logs-computed-max-size": reportComputedMaxSize, + "--logs-computed-vector-image": reportComputedVectorImage, + "--logs-computed-vector-networks": reportComputedVectorNetworks, + "--logs-computed-vector-sink": reportComputedVectorSink, "--logs-global-app-label-alias": reportGlobalAppLabelAlias, "--logs-global-max-size": reportGlobalMaxSize, + "--logs-global-vector-image": reportGlobalVectorImage, + "--logs-global-vector-networks": reportGlobalVectorNetworks, "--logs-global-vector-sink": reportGlobalVectorSink, - "--logs-app-label-alias": reportAppLabelAlias, "--logs-max-size": reportMaxSize, - "--logs-vector-global-image": reportVectorGlobalImage, - "--logs-vector-global-networks": reportVectorGlobalNetworks, "--logs-vector-sink": reportVectorSink, } } @@ -57,12 +65,15 @@ func reportComputedAppLabelAlias(appName string) string { if value == "" { value = reportGlobalAppLabelAlias(appName) } + if value == "" { + value = AppLabelAlias + } return value } func reportGlobalAppLabelAlias(appName string) string { - return common.PropertyGetDefault("logs", "--global", "app-label-alias", AppLabelAlias) + return common.PropertyGet("logs", "--global", "app-label-alias") } func reportAppLabelAlias(appName string) string { @@ -74,22 +85,41 @@ func reportComputedMaxSize(appName string) string { if value == "" { value = reportGlobalMaxSize(appName) } + if value == "" { + value = MaxSize + } return value } func reportGlobalMaxSize(appName string) string { - return common.PropertyGetDefault("logs", "--global", "max-size", MaxSize) + return common.PropertyGet("logs", "--global", "max-size") } -func reportVectorGlobalImage(appName string) string { +func reportGlobalVectorImage(appName string) string { + return common.PropertyGet("logs", "--global", "vector-image") +} + +func reportComputedVectorImage(appName string) string { return getComputedVectorImage() } -func reportVectorGlobalNetworks(appName string) string { +func reportGlobalVectorNetworks(appName string) string { return common.PropertyGet("logs", "--global", "vector-networks") } +func reportComputedVectorNetworks(appName string) string { + return reportGlobalVectorNetworks(appName) +} + +func reportComputedVectorSink(appName string) string { + value := reportVectorSink(appName) + if value == "" { + value = reportGlobalVectorSink(appName) + } + return value +} + func reportGlobalVectorSink(appName string) string { value := common.PropertyGet("logs", "--global", "vector-sink") if value == "" { diff --git a/plugins/network/report.go b/plugins/network/report.go index 9ddfcd67b..38deeed1d 100644 --- a/plugins/network/report.go +++ b/plugins/network/report.go @@ -17,11 +17,16 @@ func ReportSingleApp(appName string, format string, infoFlag string) error { 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, + "--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, } } else { flags = map[string]common.ReportFunc{ @@ -91,6 +96,9 @@ func reportComputedBindAllInterfaces(appName string) string { if value == "" { value = reportGlobalBindAllInterfaces(appName) } + if value == "" { + value = "false" + } return value } @@ -122,7 +130,7 @@ func reportGlobalAttachPostDeploy(appName string) string { } func reportGlobalBindAllInterfaces(appName string) string { - return common.PropertyGetDefault("network", "--global", "bind-all-interfaces", "false") + return common.PropertyGet("network", "--global", "bind-all-interfaces") } func reportGlobalInitialNetwork(appName string) string { diff --git a/plugins/nginx-vhosts/src/nginx-property/nginx-property.go b/plugins/nginx-vhosts/src/nginx-property/nginx-property.go index ce61ef4ae..74f9e09a9 100644 --- a/plugins/nginx-vhosts/src/nginx-property/nginx-property.go +++ b/plugins/nginx-vhosts/src/nginx-property/nginx-property.go @@ -184,9 +184,9 @@ func globalValue(appName string, property string) string { case "bind-address-ipv6": value = nginx_vhosts.GlobalBindAddressIPv6() case "client-body-timeout": - value = nginx_vhosts.ComputedClientBodyTimeout(appName) + value = nginx_vhosts.GlobalClientBodyTimeout() case "client-header-timeout": - value = nginx_vhosts.ComputedClientHeaderTimeout(appName) + value = nginx_vhosts.GlobalClientHeaderTimeout() case "client-max-body-size": value = nginx_vhosts.GlobalClientMaxBodySize() case "disable-custom-config": @@ -202,9 +202,9 @@ func globalValue(appName string, property string) string { case "hsts": value = nginx_vhosts.GlobalHSTS() case "keepalive-timeout": - value = nginx_vhosts.ComputedKeepaliveTimeout(appName) + value = nginx_vhosts.GlobalKeepaliveTimeout() case "lingering-timeout": - value = nginx_vhosts.ComputedLingeringTimeout(appName) + value = nginx_vhosts.GlobalLingeringTimeout() case "nginx-conf-sigil-path": value = nginx_vhosts.GlobalNginxConfSigilPath() case "nginx-service-command": diff --git a/plugins/proxy/functions.go b/plugins/proxy/functions.go index 11b4823b5..ec3f4ed75 100644 --- a/plugins/proxy/functions.go +++ b/plugins/proxy/functions.go @@ -13,10 +13,13 @@ func getComputedProxyType(appName string) string { if proxyType == "" { proxyType = getGlobalProxyType() } + if proxyType == "" { + proxyType = "nginx" + } return proxyType } func getGlobalProxyType() string { - return common.PropertyGetDefault("proxy", "--global", "type", "nginx") + return common.PropertyGet("proxy", "--global", "type") } diff --git a/plugins/proxy/report.go b/plugins/proxy/report.go index 305e808e0..1f55a7c78 100644 --- a/plugins/proxy/report.go +++ b/plugins/proxy/report.go @@ -15,7 +15,8 @@ func ReportSingleApp(appName string, format string, infoFlag string) error { var flags map[string]common.ReportFunc if appName == "--global" { flags = map[string]common.ReportFunc{ - "--proxy-global-type": reportGlobalType, + "--proxy-computed-type": reportComputedType, + "--proxy-global-type": reportGlobalType, } } else { flags = map[string]common.ReportFunc{ @@ -47,12 +48,7 @@ func reportEnabled(appName string) string { } func reportComputedType(appName string) string { - proxyType := getGlobalProxyType() - if proxyType == "" { - proxyType = getAppProxyType(appName) - } - - return proxyType + return getComputedProxyType(appName) } func reportGlobalType(appName string) string { diff --git a/plugins/ps/report.go b/plugins/ps/report.go index 1ccfd3e3f..0f312e288 100644 --- a/plugins/ps/report.go +++ b/plugins/ps/report.go @@ -102,12 +102,15 @@ func reportComputedProcfilePath(appName string) string { if value == "" { value = reportGlobalProcfilePath(appName) } + if value == "" { + value = "Procfile" + } return value } func reportGlobalProcfilePath(appName string) string { - return common.PropertyGetDefault("ps", "--global", "procfile-path", "Procfile") + return common.PropertyGet("ps", "--global", "procfile-path") } func reportProcfilePath(appName string) string { @@ -154,14 +157,17 @@ func reportComputedStopTimeoutSeconds(appName string) string { if value == "" { value = reportGlobalStopTimeoutSeconds(appName) } + if value == "" { + value = "30" + } return value } func reportGlobalStopTimeoutSeconds(appName string) string { - return common.PropertyGetDefault("ps", "--global", "stop-timeout-seconds", "30") + return common.PropertyGet("ps", "--global", "stop-timeout-seconds") } func reportStopTimeoutSeconds(appName string) string { - return common.PropertyGetDefault("ps", appName, "stop-timeout-seconds", "30") + return common.PropertyGet("ps", appName, "stop-timeout-seconds") } diff --git a/plugins/scheduler-docker-local/internal-functions b/plugins/scheduler-docker-local/internal-functions index 921678500..3bf7115f7 100755 --- a/plugins/scheduler-docker-local/internal-functions +++ b/plugins/scheduler-docker-local/internal-functions @@ -45,6 +45,8 @@ cmd-scheduler-docker-local-report-single() { local flag_map=() if [[ "$APP" == "--global" ]]; then flag_map=( + "--scheduler-docker-local-computed-init-process: $(fn-scheduler-docker-local-computed-init-process "$APP")" + "--scheduler-docker-local-computed-parallel-schedule-count: $(fn-scheduler-docker-local-computed-parallel-schedule-count "$APP")" "--scheduler-docker-local-global-init-process: $(fn-scheduler-docker-local-global-init-process "$APP")" "--scheduler-docker-local-global-parallel-schedule-count: $(fn-scheduler-docker-local-global-parallel-schedule-count "$APP")" ) @@ -107,12 +109,15 @@ fn-scheduler-docker-local-computed-init-process() { if [[ -z "$value" ]]; then value="$(fn-scheduler-docker-local-global-init-process "$APP")" fi + if [[ -z "$value" ]]; then + value="true" + fi echo "$value" } fn-scheduler-docker-local-global-init-process() { declare APP="$1" - fn-plugin-property-get-default "scheduler-docker-local" "--global" "init-process" "true" + fn-plugin-property-get-default "scheduler-docker-local" "--global" "init-process" "" } fn-scheduler-docker-local-parallel-schedule-count() { @@ -127,12 +132,15 @@ fn-scheduler-docker-local-computed-parallel-schedule-count() { if [[ -z "$value" ]]; then value="$(fn-scheduler-docker-local-global-parallel-schedule-count "$APP")" fi + if [[ -z "$value" ]]; then + value="1" + fi echo "$value" } fn-scheduler-docker-local-global-parallel-schedule-count() { declare APP="$1" - fn-plugin-property-get-default "scheduler-docker-local" "--global" "parallel-schedule-count" "1" + fn-plugin-property-get-default "scheduler-docker-local" "--global" "parallel-schedule-count" "" } fn-scheduler-docker-local-get-checks-file-path() { diff --git a/plugins/scheduler/report.go b/plugins/scheduler/report.go index 095fe851b..801b3fb4b 100644 --- a/plugins/scheduler/report.go +++ b/plugins/scheduler/report.go @@ -15,7 +15,8 @@ func ReportSingleApp(appName string, format string, infoFlag string) error { var flags map[string]common.ReportFunc if appName == "--global" { flags = map[string]common.ReportFunc{ - "--scheduler-global-selected": reportGlobalSelected, + "--scheduler-computed-selected": reportComputedSelected, + "--scheduler-global-selected": reportGlobalSelected, } } else { flags = map[string]common.ReportFunc{ @@ -41,12 +42,15 @@ func reportComputedSelected(appName string) string { if value == "" { value = reportGlobalSelected(appName) } + if value == "" { + value = "docker-local" + } return value } func reportGlobalSelected(appName string) string { - return common.PropertyGetDefault("scheduler", "--global", "selected", "docker-local") + return common.PropertyGet("scheduler", "--global", "selected") } func reportSelected(appName string) string { diff --git a/plugins/traefik-vhosts/certs-force b/plugins/traefik-vhosts/certs-force index 665717bad..922850f71 100755 --- a/plugins/traefik-vhosts/certs-force +++ b/plugins/traefik-vhosts/certs-force @@ -13,7 +13,7 @@ trigger-traefik-vhosts-certs-force() { return fi - if [[ -n "$(fn-traefik-letsencrypt-email)" ]]; then + if [[ -n "$(fn-traefik-computed-letsencrypt-email)" ]]; then echo true fi } diff --git a/plugins/traefik-vhosts/command-functions b/plugins/traefik-vhosts/command-functions index 9f350edf1..6ccf88128 100755 --- a/plugins/traefik-vhosts/command-functions +++ b/plugins/traefik-vhosts/command-functions @@ -71,21 +71,36 @@ cmd-traefik-report-single() { verify_app_name "$APP" fi local flag_map=( - "--traefik-api-enabled: $(fn-traefik-api-enabled)" - "--traefik-api-entry-point: $(fn-traefik-api-entry-point)" - "--traefik-api-entry-point-address: $(fn-traefik-api-entry-point-address)" - "--traefik-api-vhost: $(fn-traefik-api-vhost)" - "--traefik-basic-auth-password: $(fn-traefik-basic-auth-password)" - "--traefik-basic-auth-username: $(fn-traefik-basic-auth-username)" - "--traefik-challenge-mode: $(fn-traefik-challenge-mode)" - "--traefik-dashboard-enabled: $(fn-traefik-dashboard-enabled)" - "--traefik-dns-provider: $(fn-traefik-dns-provider)" - "--traefik-image: $(fn-traefik-image)" - "--traefik-letsencrypt-email: $(fn-traefik-letsencrypt-email)" - "--traefik-letsencrypt-server: $(fn-traefik-letsencrypt-server)" - "--traefik-log-level: $(fn-traefik-log-level)" - "--traefik-http-entry-point: $(fn-traefik-http-entry-point)" - "--traefik-https-entry-point: $(fn-traefik-https-entry-point)" + "--traefik-computed-api-enabled: $(fn-traefik-computed-api-enabled)" + "--traefik-computed-api-entry-point: $(fn-traefik-computed-api-entry-point)" + "--traefik-computed-api-entry-point-address: $(fn-traefik-computed-api-entry-point-address)" + "--traefik-computed-api-vhost: $(fn-traefik-computed-api-vhost)" + "--traefik-computed-basic-auth-password: $(fn-traefik-computed-basic-auth-password)" + "--traefik-computed-basic-auth-username: $(fn-traefik-computed-basic-auth-username)" + "--traefik-computed-challenge-mode: $(fn-traefik-computed-challenge-mode)" + "--traefik-computed-dashboard-enabled: $(fn-traefik-computed-dashboard-enabled)" + "--traefik-computed-dns-provider: $(fn-traefik-computed-dns-provider)" + "--traefik-computed-http-entry-point: $(fn-traefik-computed-http-entry-point)" + "--traefik-computed-https-entry-point: $(fn-traefik-computed-https-entry-point)" + "--traefik-computed-image: $(fn-traefik-computed-image)" + "--traefik-computed-letsencrypt-email: $(fn-traefik-computed-letsencrypt-email)" + "--traefik-computed-letsencrypt-server: $(fn-traefik-computed-letsencrypt-server)" + "--traefik-computed-log-level: $(fn-traefik-computed-log-level)" + "--traefik-global-api-enabled: $(fn-traefik-global-api-enabled)" + "--traefik-global-api-entry-point: $(fn-traefik-global-api-entry-point)" + "--traefik-global-api-entry-point-address: $(fn-traefik-global-api-entry-point-address)" + "--traefik-global-api-vhost: $(fn-traefik-global-api-vhost)" + "--traefik-global-basic-auth-password: $(fn-traefik-global-basic-auth-password)" + "--traefik-global-basic-auth-username: $(fn-traefik-global-basic-auth-username)" + "--traefik-global-challenge-mode: $(fn-traefik-global-challenge-mode)" + "--traefik-global-dashboard-enabled: $(fn-traefik-global-dashboard-enabled)" + "--traefik-global-dns-provider: $(fn-traefik-global-dns-provider)" + "--traefik-global-http-entry-point: $(fn-traefik-global-http-entry-point)" + "--traefik-global-https-entry-point: $(fn-traefik-global-https-entry-point)" + "--traefik-global-image: $(fn-traefik-global-image)" + "--traefik-global-letsencrypt-email: $(fn-traefik-global-letsencrypt-email)" + "--traefik-global-letsencrypt-server: $(fn-traefik-global-letsencrypt-server)" + "--traefik-global-log-level: $(fn-traefik-global-log-level)" ) local dns_provider_env_vars diff --git a/plugins/traefik-vhosts/docker-args-process-deploy b/plugins/traefik-vhosts/docker-args-process-deploy index be8196862..ea4782555 100755 --- a/plugins/traefik-vhosts/docker-args-process-deploy +++ b/plugins/traefik-vhosts/docker-args-process-deploy @@ -68,7 +68,7 @@ trigger-traefik-vhosts-docker-args-process-deploy() { fi done < <(plugn trigger ports-get "$APP") - letsencrypt_email="$(fn-traefik-letsencrypt-email)" + letsencrypt_email="$(fn-traefik-computed-letsencrypt-email)" if [[ -n "$letsencrypt_email" ]] && [[ -z "$proxy_container_https_port" ]]; then proxy_container_https_port_candidate="$proxy_container_http_port_candidate" proxy_host_https_port_candidate="$proxy_host_http_port_candidate" @@ -107,7 +107,7 @@ trigger-traefik-vhosts-docker-args-process-deploy() { fi output="$output --label traefik.http.services.$APP-$PROC_TYPE-http.loadbalancer.server.port=$proxy_container_http_port" - output="$output --label traefik.http.routers.$APP-$PROC_TYPE-http.entrypoints=$(fn-traefik-http-entry-point)" + output="$output --label traefik.http.routers.$APP-$PROC_TYPE-http.entrypoints=$(fn-traefik-computed-http-entry-point)" output="$output --label traefik.http.routers.$APP-$PROC_TYPE-http.service=$APP-$PROC_TYPE-http" if [[ -n "$traefik_domains" ]]; then output="$output --label \"traefik.http.routers.$APP-$PROC_TYPE-http.rule=$traefik_domains\"" @@ -122,7 +122,7 @@ trigger-traefik-vhosts-docker-args-process-deploy() { fi output="$output --label traefik.http.services.$APP-$PROC_TYPE-https.loadbalancer.server.port=$proxy_container_https_port" - output="$output --label traefik.http.routers.$APP-$PROC_TYPE-https.entrypoints=$(fn-traefik-https-entry-point)" + output="$output --label traefik.http.routers.$APP-$PROC_TYPE-https.entrypoints=$(fn-traefik-computed-https-entry-point)" output="$output --label traefik.http.routers.$APP-$PROC_TYPE-https.service=$APP-$PROC_TYPE-https" output="$output --label traefik.http.routers.$APP-$PROC_TYPE-https.tls.certresolver=leresolver" if [[ -n "$traefik_domains" ]]; then diff --git a/plugins/traefik-vhosts/internal-functions b/plugins/traefik-vhosts/internal-functions index fcb570fc5..49b9afc5c 100755 --- a/plugins/traefik-vhosts/internal-functions +++ b/plugins/traefik-vhosts/internal-functions @@ -36,106 +36,209 @@ fn-traefik-template-compose-file() { COMPOSE_TEMPLATE="$CUSTOM_COMPOSE_TEMPLATE" fi - basic_auth_password="$(fn-traefik-basic-auth-password)" - basic_auth_username="$(fn-traefik-basic-auth-username)" + basic_auth_password="$(fn-traefik-computed-basic-auth-password)" + basic_auth_username="$(fn-traefik-computed-basic-auth-username)" if [[ -n "$basic_auth_password" ]] && [[ -n "$basic_auth_username" ]]; then basic_auth="$(htpasswd -nb "$basic_auth_username" "$basic_auth_password" | sed -e s/\\$/\\$\\$/g)" fi local dns_provider_env_vars="" local dns_provider - dns_provider="$(fn-traefik-dns-provider)" + dns_provider="$(fn-traefik-computed-dns-provider)" if [[ -n "$dns_provider" ]]; then dns_provider_env_vars="$(fn-traefik-dns-provider-env-vars)" fi local api_entry_point_address api_entry_point_port="" - api_entry_point_address="$(fn-traefik-api-entry-point-address)" + api_entry_point_address="$(fn-traefik-computed-api-entry-point-address)" if [[ -n "$api_entry_point_address" ]]; then api_entry_point_port="${api_entry_point_address##*:}" fi - local SIGIL_PARAMS=(TRAEFIK_API_ENABLED="$(fn-traefik-api-enabled)" - TRAEFIK_API_ENTRY_POINT="$(fn-traefik-api-entry-point)" + local SIGIL_PARAMS=(TRAEFIK_API_ENABLED="$(fn-traefik-computed-api-enabled)" + TRAEFIK_API_ENTRY_POINT="$(fn-traefik-computed-api-entry-point)" TRAEFIK_API_ENTRY_POINT_ADDRESS="$api_entry_point_address" TRAEFIK_API_ENTRY_POINT_PORT="$api_entry_point_port" - TRAEFIK_API_VHOST="$(fn-traefik-api-vhost)" + TRAEFIK_API_VHOST="$(fn-traefik-computed-api-vhost)" TRAEFIK_BASIC_AUTH="$basic_auth" - TRAEFIK_CHALLENGE_MODE="$(fn-traefik-challenge-mode)" - TRAEFIK_DASHBOARD_ENABLED="$(fn-traefik-dashboard-enabled)" + TRAEFIK_CHALLENGE_MODE="$(fn-traefik-computed-challenge-mode)" + TRAEFIK_DASHBOARD_ENABLED="$(fn-traefik-computed-dashboard-enabled)" TRAEFIK_DATA_DIR="${DOKKU_LIB_ROOT}/data/traefik" TRAEFIK_DNS_PROVIDER="$dns_provider" TRAEFIK_DNS_PROVIDER_ENV_VARS="$dns_provider_env_vars" - TRAEFIK_IMAGE="$(fn-traefik-image)" - TRAEFIK_LETSENCRYPT_EMAIL="$(fn-traefik-letsencrypt-email)" - TRAEFIK_LETSENCRYPT_SERVER="$(fn-traefik-letsencrypt-server)" - TRAEFIK_LOG_LEVEL="$(fn-traefik-log-level)") + TRAEFIK_IMAGE="$(fn-traefik-computed-image)" + TRAEFIK_LETSENCRYPT_EMAIL="$(fn-traefik-computed-letsencrypt-email)" + TRAEFIK_LETSENCRYPT_SERVER="$(fn-traefik-computed-letsencrypt-server)" + TRAEFIK_LOG_LEVEL="$(fn-traefik-computed-log-level)") sigil -f "$COMPOSE_TEMPLATE" "${SIGIL_PARAMS[@]}" | cat -s >"$OUTPUT_PATH" } -fn-traefik-api-enabled() { - fn-plugin-property-get-default "traefik" "--global" "api-enabled" "false" +fn-traefik-global-api-enabled() { + fn-plugin-property-get-default "traefik" "--global" "api-enabled" "" } -fn-traefik-api-vhost() { - fn-plugin-property-get-default "traefik" "--global" "api-vhost" "traefik.dokku.me" +fn-traefik-computed-api-enabled() { + local value + value="$(fn-traefik-global-api-enabled)" + if [[ -z "$value" ]]; then + value="false" + fi + echo "$value" } -fn-traefik-basic-auth-password() { +fn-traefik-global-api-vhost() { + fn-plugin-property-get-default "traefik" "--global" "api-vhost" "" +} + +fn-traefik-computed-api-vhost() { + local value + value="$(fn-traefik-global-api-vhost)" + if [[ -z "$value" ]]; then + value="traefik.dokku.me" + fi + echo "$value" +} + +fn-traefik-global-basic-auth-password() { fn-plugin-property-get-default "traefik" "--global" "basic-auth-password" "" } -fn-traefik-basic-auth-username() { +fn-traefik-computed-basic-auth-password() { + fn-traefik-global-basic-auth-password +} + +fn-traefik-global-basic-auth-username() { fn-plugin-property-get-default "traefik" "--global" "basic-auth-username" "" } -fn-traefik-dashboard-enabled() { - fn-plugin-property-get-default "traefik" "--global" "dashboard-enabled" "false" +fn-traefik-computed-basic-auth-username() { + fn-traefik-global-basic-auth-username } -fn-traefik-image() { - fn-plugin-property-get-default "traefik" "--global" "image" "$(grep "FROM" "$PLUGIN_AVAILABLE_PATH/traefik-vhosts/Dockerfile" | awk '{print $2}')" +fn-traefik-global-dashboard-enabled() { + fn-plugin-property-get-default "traefik" "--global" "dashboard-enabled" "" } -fn-traefik-letsencrypt-email() { +fn-traefik-computed-dashboard-enabled() { + local value + value="$(fn-traefik-global-dashboard-enabled)" + if [[ -z "$value" ]]; then + value="false" + fi + echo "$value" +} + +fn-traefik-global-image() { + fn-plugin-property-get-default "traefik" "--global" "image" "" +} + +fn-traefik-computed-image() { + local value + value="$(fn-traefik-global-image)" + if [[ -z "$value" ]]; then + value="$(grep "FROM" "$PLUGIN_AVAILABLE_PATH/traefik-vhosts/Dockerfile" | awk '{print $2}')" + fi + echo "$value" +} + +fn-traefik-global-letsencrypt-email() { fn-plugin-property-get-default "traefik" "--global" "letsencrypt-email" "" } -fn-traefik-letsencrypt-server() { - fn-plugin-property-get-default "traefik" "--global" "letsencrypt-server" "https://acme-v02.api.letsencrypt.org/directory" +fn-traefik-computed-letsencrypt-email() { + fn-traefik-global-letsencrypt-email } -fn-traefik-log-level() { - local log_level - log_level="$(fn-plugin-property-get-default "traefik" "--global" "log-level" "ERROR")" - echo "${log_level^^}" +fn-traefik-global-letsencrypt-server() { + fn-plugin-property-get-default "traefik" "--global" "letsencrypt-server" "" } -fn-traefik-http-entry-point() { - fn-plugin-property-get-default "traefik" "--global" "http-entry-point" "http" +fn-traefik-computed-letsencrypt-server() { + local value + value="$(fn-traefik-global-letsencrypt-server)" + if [[ -z "$value" ]]; then + value="https://acme-v02.api.letsencrypt.org/directory" + fi + echo "$value" } -fn-traefik-https-entry-point() { - fn-plugin-property-get-default "traefik" "--global" "https-entry-point" "https" +fn-traefik-global-log-level() { + fn-plugin-property-get-default "traefik" "--global" "log-level" "" } -fn-traefik-api-entry-point() { +fn-traefik-computed-log-level() { + local value + value="$(fn-traefik-global-log-level)" + if [[ -z "$value" ]]; then + value="ERROR" + fi + echo "${value^^}" +} + +fn-traefik-global-http-entry-point() { + fn-plugin-property-get-default "traefik" "--global" "http-entry-point" "" +} + +fn-traefik-computed-http-entry-point() { + local value + value="$(fn-traefik-global-http-entry-point)" + if [[ -z "$value" ]]; then + value="http" + fi + echo "$value" +} + +fn-traefik-global-https-entry-point() { + fn-plugin-property-get-default "traefik" "--global" "https-entry-point" "" +} + +fn-traefik-computed-https-entry-point() { + local value + value="$(fn-traefik-global-https-entry-point)" + if [[ -z "$value" ]]; then + value="https" + fi + echo "$value" +} + +fn-traefik-global-api-entry-point() { fn-plugin-property-get-default "traefik" "--global" "api-entry-point" "" } -fn-traefik-api-entry-point-address() { +fn-traefik-computed-api-entry-point() { + fn-traefik-global-api-entry-point +} + +fn-traefik-global-api-entry-point-address() { fn-plugin-property-get-default "traefik" "--global" "api-entry-point-address" "" } -fn-traefik-challenge-mode() { - fn-plugin-property-get-default "traefik" "--global" "challenge-mode" "tls" +fn-traefik-computed-api-entry-point-address() { + fn-traefik-global-api-entry-point-address } -fn-traefik-dns-provider() { +fn-traefik-global-challenge-mode() { + fn-plugin-property-get-default "traefik" "--global" "challenge-mode" "" +} + +fn-traefik-computed-challenge-mode() { + local value + value="$(fn-traefik-global-challenge-mode)" + if [[ -z "$value" ]]; then + value="tls" + fi + echo "$value" +} + +fn-traefik-global-dns-provider() { fn-plugin-property-get-default "traefik" "--global" "dns-provider" "" } +fn-traefik-computed-dns-provider() { + fn-traefik-global-dns-provider +} + fn-traefik-dns-provider-env-vars() { declare desc="returns all dns-provider-* environment variables" fn-plugin-property-get-all-by-prefix "traefik" "--global" "dns-provider-" diff --git a/tests/unit/app-json.bats b/tests/unit/app-json.bats index 6a05be9d3..4becfed65 100644 --- a/tests/unit/app-json.bats +++ b/tests/unit/app-json.bats @@ -278,7 +278,7 @@ teardown() { echo "output: $output" echo "status: $status" assert_success - assert_output "app.json" + assert_output "" run /bin/bash -c "dokku app-json:report $TEST_APP --format json" echo "output: $output" @@ -286,7 +286,7 @@ teardown() { assert_success assert_output_contains '"app-json-appjson-path":"app2.json"' assert_output_contains '"app-json-computed-appjson-path":"app2.json"' - assert_output_contains '"app-json-global-appjson-path":"app.json"' + assert_output_contains '"app-json-global-appjson-path":""' assert_output_contains "app-json-selected" 0 run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-selected" @@ -313,6 +313,55 @@ teardown() { assert_output "app.json" } +@test "(app-json:report) appjson-path raw vs computed vs global" { + run /bin/bash -c "dokku app-json:set --global appjson-path" + assert_success + + run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-appjson-path" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-global-appjson-path" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-computed-appjson-path" + assert_success + assert_output "app.json" + + run /bin/bash -c "dokku app-json:set --global appjson-path app.global.json" + assert_success + + run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-global-appjson-path" + assert_success + assert_output "app.global.json" + + run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-computed-appjson-path" + assert_success + assert_output "app.global.json" + + run /bin/bash -c "dokku app-json:set $TEST_APP appjson-path app.app.json" + assert_success + + run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-appjson-path" + assert_success + assert_output "app.app.json" + + run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-global-appjson-path" + assert_success + assert_output "app.global.json" + + run /bin/bash -c "dokku app-json:report $TEST_APP --app-json-computed-appjson-path" + assert_success + assert_output "app.app.json" + + run /bin/bash -c "dokku app-json:set $TEST_APP appjson-path" + assert_success + + run /bin/bash -c "dokku app-json:set --global appjson-path" + assert_success +} + copy_app_json_to_sub_app() { local APP="$1" local APP_REPO_DIR="$2" diff --git a/tests/unit/archive-security.bats b/tests/unit/archive-security.bats index be4607922..03b4be01f 100644 --- a/tests/unit/archive-security.bats +++ b/tests/unit/archive-security.bats @@ -228,12 +228,24 @@ PY echo "output: $output" echo "status: $status" assert_success + assert_output "" + + run /bin/bash -c "dokku git:report --global --git-computed-archive-max-size" + echo "output: $output" + echo "status: $status" + assert_success assert_output "1073741824" run /bin/bash -c "dokku git:report --global --git-global-archive-max-files" echo "output: $output" echo "status: $status" assert_success + assert_output "" + + run /bin/bash -c "dokku git:report --global --git-computed-archive-max-files" + echo "output: $output" + echo "status: $status" + assert_success assert_output "10000" run /bin/bash -c "dokku git:set --global archive-max-size 2147483648" @@ -244,6 +256,12 @@ PY assert_success assert_output "2147483648" + run /bin/bash -c "dokku git:report --global --git-computed-archive-max-size" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "2147483648" + run /bin/bash -c "dokku git:set --global archive-max-size" assert_success } diff --git a/tests/unit/builder-dockerfile.bats b/tests/unit/builder-dockerfile.bats index e8f4cd6a9..93d662f00 100644 --- a/tests/unit/builder-dockerfile.bats +++ b/tests/unit/builder-dockerfile.bats @@ -46,7 +46,7 @@ teardown() { echo "output: $output" echo "status: $status" assert_success - assert_output "Dockerfile" + assert_output "" run /bin/bash -c "dokku builder-dockerfile:report --global --format json | jq -r 'has(\"dockerfile-path\")'" echo "output: $output" @@ -64,6 +64,75 @@ teardown() { echo "output: $output" echo "status: $status" assert_success + assert_output "" + + run /bin/bash -c "dokku builder-dockerfile:set --global dockerfile-path Dockerfile.custom" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku builder-dockerfile:report --global --builder-dockerfile-global-dockerfile-path" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "Dockerfile.custom" + + run /bin/bash -c "dokku builder-dockerfile:set --global dockerfile-path" + echo "output: $output" + echo "status: $status" + assert_success +} + +@test "(builder-dockerfile:report) dockerfile-path raw vs computed vs global" { + run /bin/bash -c "dokku builder-dockerfile:set --global dockerfile-path" + assert_success + + run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-dockerfile-path" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-global-dockerfile-path" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-computed-dockerfile-path" + assert_success + assert_output "Dockerfile" + + run /bin/bash -c "dokku builder-dockerfile:set --global dockerfile-path Dockerfile.global" + assert_success + + run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-global-dockerfile-path" + assert_success + assert_output "Dockerfile.global" + + run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-computed-dockerfile-path" + assert_success + assert_output "Dockerfile.global" + + run /bin/bash -c "dokku builder-dockerfile:set $TEST_APP dockerfile-path Dockerfile.app" + assert_success + + run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-dockerfile-path" + assert_success + assert_output "Dockerfile.app" + + run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-global-dockerfile-path" + assert_success + assert_output "Dockerfile.global" + + run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-computed-dockerfile-path" + assert_success + assert_output "Dockerfile.app" + + run /bin/bash -c "dokku builder-dockerfile:set $TEST_APP dockerfile-path" + assert_success + + run /bin/bash -c "dokku builder-dockerfile:set --global dockerfile-path" + assert_success + + run /bin/bash -c "dokku builder-dockerfile:report $TEST_APP --builder-dockerfile-computed-dockerfile-path" + assert_success assert_output "Dockerfile" } diff --git a/tests/unit/builder-herokuish.bats b/tests/unit/builder-herokuish.bats index a96728654..e01ef454c 100644 --- a/tests/unit/builder-herokuish.bats +++ b/tests/unit/builder-herokuish.bats @@ -52,6 +52,58 @@ teardown() { assert_success } +@test "(builder-herokuish:report) allowed raw vs computed vs global" { + local default_allowed="true" + [[ "$(dpkg --print-architecture 2>/dev/null || true)" != "amd64" ]] && default_allowed="false" + + run /bin/bash -c "dokku builder-herokuish:set --global allowed" + assert_success + + run /bin/bash -c "dokku builder-herokuish:report $TEST_APP --builder-herokuish-allowed" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder-herokuish:report $TEST_APP --builder-herokuish-global-allowed" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder-herokuish:report $TEST_APP --builder-herokuish-computed-allowed" + assert_success + assert_output "$default_allowed" + + run /bin/bash -c "dokku builder-herokuish:set --global allowed false" + assert_success + + run /bin/bash -c "dokku builder-herokuish:report $TEST_APP --builder-herokuish-global-allowed" + assert_success + assert_output "false" + + run /bin/bash -c "dokku builder-herokuish:report $TEST_APP --builder-herokuish-computed-allowed" + assert_success + assert_output "false" + + run /bin/bash -c "dokku builder-herokuish:set $TEST_APP allowed true" + assert_success + + run /bin/bash -c "dokku builder-herokuish:report $TEST_APP --builder-herokuish-allowed" + assert_success + assert_output "true" + + run /bin/bash -c "dokku builder-herokuish:report $TEST_APP --builder-herokuish-global-allowed" + assert_success + assert_output "false" + + run /bin/bash -c "dokku builder-herokuish:report $TEST_APP --builder-herokuish-computed-allowed" + assert_success + assert_output "true" + + run /bin/bash -c "dokku builder-herokuish:set $TEST_APP allowed" + assert_success + + run /bin/bash -c "dokku builder-herokuish:set --global allowed" + assert_success +} + @test "(builder-herouish:build .env)" { run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP echo "output: $output" diff --git a/tests/unit/builder-lambda.bats b/tests/unit/builder-lambda.bats index af2be7121..9fa0ac841 100644 --- a/tests/unit/builder-lambda.bats +++ b/tests/unit/builder-lambda.bats @@ -52,6 +52,55 @@ teardown() { assert_success } +@test "(builder-lambda:report) lambdayml-path raw vs computed vs global" { + run /bin/bash -c "dokku builder-lambda:set --global lambdayml-path" + assert_success + + run /bin/bash -c "dokku builder-lambda:report $TEST_APP --builder-lambda-lambdayml-path" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder-lambda:report $TEST_APP --builder-lambda-global-lambdayml-path" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder-lambda:report $TEST_APP --builder-lambda-computed-lambdayml-path" + assert_success + assert_output "lambda.yml" + + run /bin/bash -c "dokku builder-lambda:set --global lambdayml-path lambda.global.yml" + assert_success + + run /bin/bash -c "dokku builder-lambda:report $TEST_APP --builder-lambda-global-lambdayml-path" + assert_success + assert_output "lambda.global.yml" + + run /bin/bash -c "dokku builder-lambda:report $TEST_APP --builder-lambda-computed-lambdayml-path" + assert_success + assert_output "lambda.global.yml" + + run /bin/bash -c "dokku builder-lambda:set $TEST_APP lambdayml-path lambda.app.yml" + assert_success + + run /bin/bash -c "dokku builder-lambda:report $TEST_APP --builder-lambda-lambdayml-path" + assert_success + assert_output "lambda.app.yml" + + run /bin/bash -c "dokku builder-lambda:report $TEST_APP --builder-lambda-global-lambdayml-path" + assert_success + assert_output "lambda.global.yml" + + run /bin/bash -c "dokku builder-lambda:report $TEST_APP --builder-lambda-computed-lambdayml-path" + assert_success + assert_output "lambda.app.yml" + + run /bin/bash -c "dokku builder-lambda:set $TEST_APP lambdayml-path" + assert_success + + run /bin/bash -c "dokku builder-lambda:set --global lambdayml-path" + assert_success +} + @test "(builder-lambda:set)" { run /bin/bash -c "dokku config:set $TEST_APP SECRET_KEY=fjdkslafjdk" echo "output: $output" diff --git a/tests/unit/builder-nixpacks.bats b/tests/unit/builder-nixpacks.bats index a87259bf2..2458774c9 100644 --- a/tests/unit/builder-nixpacks.bats +++ b/tests/unit/builder-nixpacks.bats @@ -56,6 +56,55 @@ teardown() { assert_success } +@test "(builder-nixpacks:report) nixpackstoml-path raw vs computed vs global" { + run /bin/bash -c "dokku builder-nixpacks:set --global nixpackstoml-path" + assert_success + + run /bin/bash -c "dokku builder-nixpacks:report $TEST_APP --builder-nixpacks-nixpackstoml-path" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder-nixpacks:report $TEST_APP --builder-nixpacks-global-nixpackstoml-path" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder-nixpacks:report $TEST_APP --builder-nixpacks-computed-nixpackstoml-path" + assert_success + assert_output "nixpacks.toml" + + run /bin/bash -c "dokku builder-nixpacks:set --global nixpackstoml-path nixpacks.global.toml" + assert_success + + run /bin/bash -c "dokku builder-nixpacks:report $TEST_APP --builder-nixpacks-global-nixpackstoml-path" + assert_success + assert_output "nixpacks.global.toml" + + run /bin/bash -c "dokku builder-nixpacks:report $TEST_APP --builder-nixpacks-computed-nixpackstoml-path" + assert_success + assert_output "nixpacks.global.toml" + + run /bin/bash -c "dokku builder-nixpacks:set $TEST_APP nixpackstoml-path nixpacks.app.toml" + assert_success + + run /bin/bash -c "dokku builder-nixpacks:report $TEST_APP --builder-nixpacks-nixpackstoml-path" + assert_success + assert_output "nixpacks.app.toml" + + run /bin/bash -c "dokku builder-nixpacks:report $TEST_APP --builder-nixpacks-global-nixpackstoml-path" + assert_success + assert_output "nixpacks.global.toml" + + run /bin/bash -c "dokku builder-nixpacks:report $TEST_APP --builder-nixpacks-computed-nixpackstoml-path" + assert_success + assert_output "nixpacks.app.toml" + + run /bin/bash -c "dokku builder-nixpacks:set $TEST_APP nixpackstoml-path" + assert_success + + run /bin/bash -c "dokku builder-nixpacks:set --global nixpackstoml-path" + assert_success +} + @test "(builder-nixpacks:set)" { run /bin/bash -c "dokku config:set $TEST_APP SECRET_KEY=fjdkslafjdk" echo "output: $output" diff --git a/tests/unit/builder-pack.bats b/tests/unit/builder-pack.bats index a580a2575..2e8d5876c 100644 --- a/tests/unit/builder-pack.bats +++ b/tests/unit/builder-pack.bats @@ -58,6 +58,55 @@ teardown() { assert_success } +@test "(builder-pack:report) projecttoml-path raw vs computed vs global" { + run /bin/bash -c "dokku builder-pack:set --global projecttoml-path" + assert_success + + run /bin/bash -c "dokku builder-pack:report $TEST_APP --builder-pack-projecttoml-path" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder-pack:report $TEST_APP --builder-pack-global-projecttoml-path" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder-pack:report $TEST_APP --builder-pack-computed-projecttoml-path" + assert_success + assert_output "project.toml" + + run /bin/bash -c "dokku builder-pack:set --global projecttoml-path project.global.toml" + assert_success + + run /bin/bash -c "dokku builder-pack:report $TEST_APP --builder-pack-global-projecttoml-path" + assert_success + assert_output "project.global.toml" + + run /bin/bash -c "dokku builder-pack:report $TEST_APP --builder-pack-computed-projecttoml-path" + assert_success + assert_output "project.global.toml" + + run /bin/bash -c "dokku builder-pack:set $TEST_APP projecttoml-path project.app.toml" + assert_success + + run /bin/bash -c "dokku builder-pack:report $TEST_APP --builder-pack-projecttoml-path" + assert_success + assert_output "project.app.toml" + + run /bin/bash -c "dokku builder-pack:report $TEST_APP --builder-pack-global-projecttoml-path" + assert_success + assert_output "project.global.toml" + + run /bin/bash -c "dokku builder-pack:report $TEST_APP --builder-pack-computed-projecttoml-path" + assert_success + assert_output "project.app.toml" + + run /bin/bash -c "dokku builder-pack:set $TEST_APP projecttoml-path" + assert_success + + run /bin/bash -c "dokku builder-pack:set --global projecttoml-path" + assert_success +} + @test "(builder-pack:set)" { run /bin/bash -c "dokku config:set $TEST_APP SECRET_KEY=fjdkslafjdk" echo "output: $output" diff --git a/tests/unit/builder-railpack.bats b/tests/unit/builder-railpack.bats index 626288cd9..4959bc39f 100644 --- a/tests/unit/builder-railpack.bats +++ b/tests/unit/builder-railpack.bats @@ -67,6 +67,55 @@ teardown() { assert_success } +@test "(builder-railpack:report) railpackjson-path raw vs computed vs global" { + run /bin/bash -c "dokku builder-railpack:set --global railpackjson-path" + assert_success + + run /bin/bash -c "dokku builder-railpack:report $TEST_APP --builder-railpack-railpackjson-path" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder-railpack:report $TEST_APP --builder-railpack-global-railpackjson-path" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder-railpack:report $TEST_APP --builder-railpack-computed-railpackjson-path" + assert_success + assert_output "railpack.json" + + run /bin/bash -c "dokku builder-railpack:set --global railpackjson-path railpack.global.json" + assert_success + + run /bin/bash -c "dokku builder-railpack:report $TEST_APP --builder-railpack-global-railpackjson-path" + assert_success + assert_output "railpack.global.json" + + run /bin/bash -c "dokku builder-railpack:report $TEST_APP --builder-railpack-computed-railpackjson-path" + assert_success + assert_output "railpack.global.json" + + run /bin/bash -c "dokku builder-railpack:set $TEST_APP railpackjson-path railpack.app.json" + assert_success + + run /bin/bash -c "dokku builder-railpack:report $TEST_APP --builder-railpack-railpackjson-path" + assert_success + assert_output "railpack.app.json" + + run /bin/bash -c "dokku builder-railpack:report $TEST_APP --builder-railpack-global-railpackjson-path" + assert_success + assert_output "railpack.global.json" + + run /bin/bash -c "dokku builder-railpack:report $TEST_APP --builder-railpack-computed-railpackjson-path" + assert_success + assert_output "railpack.app.json" + + run /bin/bash -c "dokku builder-railpack:set $TEST_APP railpackjson-path" + assert_success + + run /bin/bash -c "dokku builder-railpack:set --global railpackjson-path" + assert_success +} + @test "(builder-railpack:set)" { run /bin/bash -c "dokku config:set $TEST_APP SECRET_KEY=fjdkslafjdk" echo "output: $output" diff --git a/tests/unit/builder.bats b/tests/unit/builder.bats index 770b9f0a7..2e7574631 100644 --- a/tests/unit/builder.bats +++ b/tests/unit/builder.bats @@ -209,6 +209,104 @@ teardown() { assert_success } +@test "(builder:report) selected raw vs computed vs global" { + run /bin/bash -c "dokku builder:set --global selected" + assert_success + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-selected" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-global-selected" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-computed-selected" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder:set --global selected dockerfile" + assert_success + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-global-selected" + assert_success + assert_output "dockerfile" + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-computed-selected" + assert_success + assert_output "dockerfile" + + run /bin/bash -c "dokku builder:set $TEST_APP selected herokuish" + assert_success + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-selected" + assert_success + assert_output "herokuish" + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-global-selected" + assert_success + assert_output "dockerfile" + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-computed-selected" + assert_success + assert_output "herokuish" + + run /bin/bash -c "dokku builder:set $TEST_APP selected" + assert_success + + run /bin/bash -c "dokku builder:set --global selected" + assert_success +} + +@test "(builder:report) build-dir raw vs computed vs global" { + run /bin/bash -c "dokku builder:set --global build-dir" + assert_success + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-build-dir" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-global-build-dir" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-computed-build-dir" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder:set --global build-dir global/subdir" + assert_success + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-global-build-dir" + assert_success + assert_output "global/subdir" + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-computed-build-dir" + assert_success + assert_output "global/subdir" + + run /bin/bash -c "dokku builder:set $TEST_APP build-dir app/subdir" + assert_success + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-build-dir" + assert_success + assert_output "app/subdir" + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-global-build-dir" + assert_success + assert_output "global/subdir" + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-computed-build-dir" + assert_success + assert_output "app/subdir" + + run /bin/bash -c "dokku builder:set $TEST_APP build-dir" + assert_success + + run /bin/bash -c "dokku builder:set --global build-dir" + assert_success +} + @test "(builder:set)" { run deploy_app python echo "output: $output" diff --git a/tests/unit/buildpacks.bats b/tests/unit/buildpacks.bats index 59e9b4438..6c4ff9ec2 100644 --- a/tests/unit/buildpacks.bats +++ b/tests/unit/buildpacks.bats @@ -191,6 +191,51 @@ teardown() { assert_success } +@test "(buildpacks:report) stack raw vs computed vs global" { + run /bin/bash -c "dokku buildpacks:set-property --global stack" + assert_success + + run /bin/bash -c "dokku buildpacks:report $TEST_APP --format json | jq -r '.\"buildpacks-stack\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku buildpacks:report $TEST_APP --format json | jq -r '.\"buildpacks-global-stack\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku buildpacks:set-property --global stack gliderlabs/herokuish:global" + assert_success + + run /bin/bash -c "dokku buildpacks:report $TEST_APP --format json | jq -r '.\"buildpacks-global-stack\"'" + assert_success + assert_output "gliderlabs/herokuish:global" + + run /bin/bash -c "dokku buildpacks:report $TEST_APP --format json | jq -r '.\"buildpacks-computed-stack\"'" + assert_success + assert_output "gliderlabs/herokuish:global" + + run /bin/bash -c "dokku buildpacks:set-property $TEST_APP stack gliderlabs/herokuish:app" + assert_success + + run /bin/bash -c "dokku buildpacks:report $TEST_APP --format json | jq -r '.\"buildpacks-stack\"'" + assert_success + assert_output "gliderlabs/herokuish:app" + + run /bin/bash -c "dokku buildpacks:report $TEST_APP --format json | jq -r '.\"buildpacks-global-stack\"'" + assert_success + assert_output "gliderlabs/herokuish:global" + + run /bin/bash -c "dokku buildpacks:report $TEST_APP --format json | jq -r '.\"buildpacks-computed-stack\"'" + assert_success + assert_output "gliderlabs/herokuish:app" + + run /bin/bash -c "dokku buildpacks:set-property $TEST_APP stack" + assert_success + + run /bin/bash -c "dokku buildpacks:set-property --global stack" + assert_success +} + @test "(buildpacks) buildpacks:remove" { run /bin/bash -c "dokku buildpacks:set $TEST_APP heroku/nodejs" echo "output: $output" diff --git a/tests/unit/caddy.bats b/tests/unit/caddy.bats index e338c6fa7..dd1e48658 100644 --- a/tests/unit/caddy.bats +++ b/tests/unit/caddy.bats @@ -18,13 +18,31 @@ teardown() { dokku nginx:start } -@test "(caddy:report) --global --caddy-log-level" { +@test "(caddy:report) --global global vs computed log-level" { + run /bin/bash -c "dokku caddy:report --global --caddy-global-log-level" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "" + + run /bin/bash -c "dokku caddy:report --global --caddy-computed-log-level" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "ERROR" + run /bin/bash -c "dokku caddy:set --global log-level DEBUG" echo "output: $output" echo "status: $status" assert_success - run /bin/bash -c "dokku caddy:report --global --caddy-log-level" + run /bin/bash -c "dokku caddy:report --global --caddy-global-log-level" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "DEBUG" + + run /bin/bash -c "dokku caddy:report --global --caddy-computed-log-level" echo "output: $output" echo "status: $status" assert_success @@ -34,6 +52,44 @@ teardown() { echo "output: $output" echo "status: $status" assert_success + + run /bin/bash -c "dokku caddy:report --global --caddy-global-log-level" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "" + + run /bin/bash -c "dokku caddy:report --global --caddy-computed-log-level" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "ERROR" +} + +@test "(caddy:report) --global raw and computed keys in --format json" { + run /bin/bash -c "dokku caddy:report --global --format json | jq -r '.\"global-image\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "" + + run /bin/bash -c "dokku caddy:report --global --format json | jq -r '.\"computed-image\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_exists + + run /bin/bash -c "dokku caddy:report --global --format json | jq -r '.\"global-polling-interval\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "" + + run /bin/bash -c "dokku caddy:report --global --format json | jq -r '.\"computed-polling-interval\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "5s" } @test "(caddy) global-only keys" { @@ -80,7 +136,7 @@ teardown() { echo "output: $output" echo "status: $status" assert_success - assert_output "false" + assert_output "" run /bin/bash -c "dokku caddy:set $TEST_APP tls-internal true" echo "output: $output" @@ -294,12 +350,12 @@ teardown() { assert_success assert_output "$TEST_APP.${DOKKU_DOMAIN}" - run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map" + run /bin/bash -c "dokku ports:report $TEST_APP --ports-map" echo "output: $output" echo "status: $status" assert_output_not_exists - run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-detected" + run /bin/bash -c "dokku ports:report $TEST_APP --ports-map-detected" echo "output: $output" echo "status: $status" assert_output "http:80:5000 https:443:5000" diff --git a/tests/unit/checks.bats b/tests/unit/checks.bats index 5c60f5b86..365702002 100644 --- a/tests/unit/checks.bats +++ b/tests/unit/checks.bats @@ -41,7 +41,7 @@ teardown() { } @test "(checks:report) --global --format json" { - run /bin/bash -c "dokku checks:set --global wait-to-retire 90" + run /bin/bash -c "dokku checks:set --global wait-to-retire" echo "output: $output" echo "status: $status" assert_success @@ -55,13 +55,30 @@ teardown() { echo "output: $output" echo "status: $status" assert_success - assert_output "90" + assert_output "" - run /bin/bash -c "dokku checks:report --global --format json | jq -r 'has(\"wait-to-retire\")'" + run /bin/bash -c "dokku checks:report --global --format json | jq -r '.\"computed-wait-to-retire\"'" echo "output: $output" echo "status: $status" assert_success - assert_output "false" + assert_output "60" + + 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 -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 '.\"computed-wait-to-retire\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "90" run /bin/bash -c "dokku checks:report --global" echo "output: $output" @@ -69,16 +86,22 @@ teardown() { assert_success assert_output_contains "global checks information" - run /bin/bash -c "dokku checks:report --global --checks-global-wait-to-retire" - echo "output: $output" - echo "status: $status" - assert_success - assert_output "90" - run /bin/bash -c "dokku checks:set --global wait-to-retire" echo "output: $output" echo "status: $status" assert_success + + run /bin/bash -c "dokku checks:report --global --checks-global-wait-to-retire" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "" + + run /bin/bash -c "dokku checks:report --global --checks-computed-wait-to-retire" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "60" } @test "(checks) checks:help" { diff --git a/tests/unit/cron.bats b/tests/unit/cron.bats index ab7cebe88..c81f69f5b 100644 --- a/tests/unit/cron.bats +++ b/tests/unit/cron.bats @@ -186,6 +186,59 @@ teardown() { assert_output_not_contains "unknown flag" } +@test "(cron:report) maintenance raw vs computed vs global" { + run /bin/bash -c "dokku cron:set --global maintenance" + assert_success + + run /bin/bash -c "dokku cron:report $TEST_APP --format json | jq -r '.\"cron-maintenance\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku cron:report $TEST_APP --format json | jq -r '.\"cron-global-maintenance\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku cron:report $TEST_APP --format json | jq -r '.\"cron-computed-maintenance\"'" + assert_success + assert_output "false" + + run /bin/bash -c "dokku cron:set --global maintenance true" + assert_success + + run /bin/bash -c "dokku cron:report $TEST_APP --format json | jq -r '.\"cron-global-maintenance\"'" + assert_success + assert_output "true" + + run /bin/bash -c "dokku cron:report $TEST_APP --format json | jq -r '.\"cron-computed-maintenance\"'" + assert_success + assert_output "true" + + run /bin/bash -c "dokku cron:set $TEST_APP maintenance true" + assert_success + + run /bin/bash -c "dokku cron:report $TEST_APP --format json | jq -r '.\"cron-maintenance\"'" + assert_success + assert_output "true" + + run /bin/bash -c "dokku cron:report $TEST_APP --format json | jq -r '.\"cron-global-maintenance\"'" + assert_success + assert_output "true" + + # cron computed-maintenance returns "true" if either per-app or global is + # "true" (cron's logic at plugins/cron/report.go::reportComputedMaintenance + # is OR-not-override: any "true" wins). This is intentional for maintenance + # mode - a per-app "false" does NOT override a global "true". + run /bin/bash -c "dokku cron:report $TEST_APP --format json | jq -r '.\"cron-computed-maintenance\"'" + assert_success + assert_output "true" + + run /bin/bash -c "dokku cron:set $TEST_APP maintenance" + assert_success + + run /bin/bash -c "dokku cron:set --global maintenance" + assert_success +} + @test "(cron:set) --global rejects task maintenance properties" { run /bin/bash -c "dokku cron:set --global maintenance.fakeid true" echo "output: $output" diff --git a/tests/unit/git_1.bats b/tests/unit/git_1.bats index bd0eaeae7..46410f0c9 100644 --- a/tests/unit/git_1.bats +++ b/tests/unit/git_1.bats @@ -71,52 +71,88 @@ teardown() { assert_output_contains "Invalid flag passed" } -@test "(git:report) keep-git-dir raw vs computed" { - run /bin/bash -c "dokku git:report $TEST_APP --git-keep-git-dir" - echo "output: $output" - echo "status: $status" +@test "(git:report) keep-git-dir raw vs computed vs global" { + run /bin/bash -c "dokku git:set --global keep-git-dir" assert_success - assert_output "" + + run /bin/bash -c "dokku git:report $TEST_APP --git-keep-git-dir" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku git:report $TEST_APP --git-global-keep-git-dir" + assert_success + assert_output_not_exists run /bin/bash -c "dokku git:report $TEST_APP --git-computed-keep-git-dir" - echo "output: $output" - echo "status: $status" assert_success assert_output "false" - run /bin/bash -c "dokku git:set $TEST_APP keep-git-dir true" - echo "output: $output" - echo "status: $status" + run /bin/bash -c "dokku git:set --global keep-git-dir true" assert_success - run /bin/bash -c "dokku git:report $TEST_APP --git-keep-git-dir" - echo "output: $output" - echo "status: $status" + run /bin/bash -c "dokku git:report $TEST_APP --git-global-keep-git-dir" assert_success assert_output "true" run /bin/bash -c "dokku git:report $TEST_APP --git-computed-keep-git-dir" - echo "output: $output" - echo "status: $status" assert_success assert_output "true" + run /bin/bash -c "dokku git:set $TEST_APP keep-git-dir false" + assert_success + + run /bin/bash -c "dokku git:report $TEST_APP --git-keep-git-dir" + assert_success + assert_output "false" + + run /bin/bash -c "dokku git:report $TEST_APP --git-global-keep-git-dir" + assert_success + assert_output "true" + + run /bin/bash -c "dokku git:report $TEST_APP --git-computed-keep-git-dir" + assert_success + assert_output "false" + run /bin/bash -c "dokku git:set $TEST_APP keep-git-dir" - echo "output: $output" - echo "status: $status" assert_success - run /bin/bash -c "dokku git:report $TEST_APP --git-keep-git-dir" - echo "output: $output" - echo "status: $status" + run /bin/bash -c "dokku git:set --global keep-git-dir" assert_success - assert_output "" +} - run /bin/bash -c "dokku git:report $TEST_APP --git-computed-keep-git-dir" - echo "output: $output" - echo "status: $status" +@test "(git:report) rev-env-var raw" { + # Unset the per-app property file if a previous test left it written-empty + # (git:set rev-env-var "" intentionally writes an empty file as the + # documented "unset" behavior, which masks the report's default fallback). + run /bin/bash -c "dokku git:set $TEST_APP rev-env-var COMMIT_SHA" assert_success - assert_output "false" + + run /bin/bash -c "dokku git:report $TEST_APP --git-rev-env-var" + assert_success + assert_output "COMMIT_SHA" + + run /bin/bash -c "dokku git:set $TEST_APP rev-env-var" + assert_success +} + +@test "(git:report) source-image raw" { + run /bin/bash -c "dokku git:report $TEST_APP --git-source-image" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku git:set $TEST_APP source-image alpine:3.20" + assert_success + + run /bin/bash -c "dokku git:report $TEST_APP --git-source-image" + assert_success + assert_output "alpine:3.20" + + run /bin/bash -c "dokku git:set $TEST_APP source-image" + assert_success + + run /bin/bash -c "dokku git:report $TEST_APP --git-source-image" + assert_success + assert_output_not_exists } @test "(git:report) raw and computed keys in --format json" { @@ -145,6 +181,60 @@ teardown() { assert_output "false" } +@test "(git:report) --global raw and computed keys" { + 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 "" + + run /bin/bash -c "dokku git:report --global --format json | jq -r '.\"computed-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 '.\"global-archive-max-files\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "" + + run /bin/bash -c "dokku git:report --global --format json | jq -r '.\"computed-archive-max-files\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "10000" + + run /bin/bash -c "dokku git:set --global deploy-branch main" + 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 "main" + + run /bin/bash -c "dokku git:report --global --format json | jq -r '.\"computed-deploy-branch\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "main" + + run /bin/bash -c "dokku git:set --global deploy-branch" + 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 "" +} + @test "(git) git:help" { run /bin/bash -c "dokku git" echo "output: $output" diff --git a/tests/unit/git_3.bats b/tests/unit/git_3.bats index 01d04aeca..069816cd4 100644 --- a/tests/unit/git_3.bats +++ b/tests/unit/git_3.bats @@ -887,7 +887,13 @@ teardown() { echo "output: $output" echo "status: $status" assert_success - assert_output "master" + assert_output "" + + run /bin/bash -c "dokku git:report $TEST_APP --format json | jq -r '.\"computed-deploy-branch\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "main" run /bin/bash -c "dokku git:report $TEST_APP --format json | jq -e ." echo "output: $output" @@ -925,6 +931,12 @@ teardown() { echo "output: $output" echo "status: $status" assert_success + assert_output "" + + run /bin/bash -c "dokku git:report --global --format json | jq -r '.\"computed-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\")'" @@ -937,5 +949,11 @@ teardown() { echo "output: $output" echo "status: $status" assert_success + assert_output "" + + run /bin/bash -c "dokku git:report --global --git-computed-deploy-branch" + echo "output: $output" + echo "status: $status" + assert_success assert_output "master" } diff --git a/tests/unit/haproxy.bats b/tests/unit/haproxy.bats index 5004ac516..6edc97db8 100644 --- a/tests/unit/haproxy.bats +++ b/tests/unit/haproxy.bats @@ -57,7 +57,13 @@ teardown() { echo "status: $status" assert_success - run /bin/bash -c "dokku haproxy:report --global --haproxy-refresh-conf" + run /bin/bash -c "dokku haproxy:report --global --haproxy-global-refresh-conf" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "5" + + run /bin/bash -c "dokku haproxy:report --global --haproxy-computed-refresh-conf" echo "output: $output" echo "status: $status" assert_success @@ -74,7 +80,42 @@ teardown() { echo "status: $status" assert_success - run /bin/bash -c "dokku haproxy:report --global --haproxy-refresh-conf" + run /bin/bash -c "dokku haproxy:report --global --haproxy-global-refresh-conf" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "" + + run /bin/bash -c "dokku haproxy:report --global --haproxy-computed-refresh-conf" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "10" +} + +@test "(haproxy:report) --global raw and computed keys in --format json" { + run /bin/bash -c "dokku haproxy:set --global refresh-conf" + assert_success + + run /bin/bash -c "dokku haproxy:report --global --format json | jq -r '.\"global-image\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "" + + run /bin/bash -c "dokku haproxy:report --global --format json | jq -r '.\"computed-image\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_exists + + run /bin/bash -c "dokku haproxy:report --global --format json | jq -r '.\"global-refresh-conf\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "" + + run /bin/bash -c "dokku haproxy:report --global --format json | jq -r '.\"computed-refresh-conf\"'" echo "output: $output" echo "status: $status" assert_success @@ -205,12 +246,12 @@ teardown() { assert_success assert_output "true" - run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map" + run /bin/bash -c "dokku ports:report $TEST_APP --ports-map" echo "output: $output" echo "status: $status" assert_output_not_exists - run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-detected" + run /bin/bash -c "dokku ports:report $TEST_APP --ports-map-detected" echo "output: $output" echo "status: $status" assert_output "http:80:5000 https:443:5000" diff --git a/tests/unit/logs.bats b/tests/unit/logs.bats index c0802531e..de05193cb 100644 --- a/tests/unit/logs.bats +++ b/tests/unit/logs.bats @@ -9,6 +9,7 @@ setup() { teardown() { destroy_app + dokku logs:set --global vector-image >/dev/null 2>/dev/null || true dokku logs:set --global vector-networks >/dev/null 2>/dev/null || true docker network rm test-vector-net-a >/dev/null || true docker network rm test-vector-net-b >/dev/null || true @@ -57,7 +58,7 @@ teardown() { echo "status: $status" assert_failure assert_output_contains "$TEST_APP logs information" 0 - assert_output_contains "Invalid flag passed, valid flags: --logs-app-label-alias, --logs-computed-app-label-alias, --logs-computed-max-size, --logs-global-app-label-alias, --logs-global-max-size, --logs-global-vector-sink, --logs-max-size, --logs-vector-global-image, --logs-vector-global-networks, --logs-vector-sink" + assert_output_contains "Invalid flag passed, valid flags: --logs-app-label-alias, --logs-computed-app-label-alias, --logs-computed-max-size, --logs-computed-vector-image, --logs-computed-vector-networks, --logs-computed-vector-sink, --logs-global-app-label-alias, --logs-global-max-size, --logs-global-vector-image, --logs-global-vector-networks, --logs-global-vector-sink, --logs-max-size, --logs-vector-sink" run /bin/bash -c "dokku logs:report $TEST_APP --logs-vector-sink 2>&1" echo "output: $output" @@ -74,6 +75,14 @@ teardown() { assert_output_contains "Invalid flag passed" 0 } +@test "(logs) logs:report --global invalid flag" { + run /bin/bash -c "dokku logs:report --global --invalid-flag 2>&1" + echo "output: $output" + echo "status: $status" + assert_failure + assert_output_contains "Invalid flag passed, valid flags: --logs-computed-app-label-alias, --logs-computed-max-size, --logs-computed-vector-image, --logs-computed-vector-networks, --logs-computed-vector-sink, --logs-global-app-label-alias, --logs-global-max-size, --logs-global-vector-image, --logs-global-vector-networks, --logs-global-vector-sink" +} + @test "(logs) logs:set [error]" { run /bin/bash -c "dokku logs:set 2>&1" echo "output: $output" @@ -412,7 +421,7 @@ teardown() { assert_success assert_output_not_exists - run /bin/bash -c "dokku logs:report $TEST_APP --logs-global-max-size 2>&1" + run /bin/bash -c "dokku logs:report $TEST_APP --logs-computed-max-size 2>&1" echo "output: $output" echo "status: $status" assert_success @@ -428,6 +437,12 @@ teardown() { echo "output: $output" echo "status: $status" assert_success + assert_output_not_exists + + run /bin/bash -c "dokku logs:report $TEST_APP --logs-computed-max-size 2>&1" + echo "output: $output" + echo "status: $status" + assert_success assert_output "10m" run /bin/bash -c "dokku logs:set --global max-size 20m" 2>&1 @@ -442,6 +457,12 @@ teardown() { assert_success assert_output "20m" + run /bin/bash -c "dokku logs:report $TEST_APP --logs-computed-max-size 2>&1" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "20m" + run /bin/bash -c "dokku logs:set --global max-size unlimited" 2>&1 echo "output: $output" echo "status: $status" @@ -464,9 +485,81 @@ teardown() { echo "output: $output" echo "status: $status" assert_success + assert_output_not_exists + + run /bin/bash -c "dokku logs:report $TEST_APP --logs-computed-max-size 2>&1" + echo "output: $output" + echo "status: $status" + assert_success assert_output "10m" } +@test "(logs:report) vector-sink raw vs global" { + run create_app + assert_success + + run /bin/bash -c "dokku logs:set --global vector-sink" + assert_success + + run /bin/bash -c "dokku logs:report $TEST_APP --format json | jq -r '.\"logs-vector-sink\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku logs:report $TEST_APP --format json | jq -r '.\"logs-global-vector-sink\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku logs:set --global vector-sink console://?encoding[codec]=json" + assert_success + + run /bin/bash -c "dokku logs:report $TEST_APP --format json | jq -r '.\"logs-global-vector-sink\"'" + assert_success + assert_output "console://?encoding[codec]=json" + + run /bin/bash -c "dokku logs:set $TEST_APP vector-sink datadog_logs://?api_key=abc" + assert_success + + run /bin/bash -c "dokku logs:report $TEST_APP --format json | jq -r '.\"logs-vector-sink\"'" + assert_success + assert_output "datadog_logs://?api_key=abc" + + run /bin/bash -c "dokku logs:set $TEST_APP vector-sink" + assert_success + + run /bin/bash -c "dokku logs:set --global vector-sink" + assert_success +} + +@test "(logs:report) vector-global-image and vector-global-networks raw" { + run create_app + assert_success + + run /bin/bash -c "dokku logs:set --global vector-image" + assert_success + + run /bin/bash -c "dokku logs:report --global --format json | jq -r '.\"logs-global-vector-image\"'" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku logs:report --global --format json | jq -r '.\"logs-computed-vector-image\"'" + assert_success + assert_output_exists + + run /bin/bash -c "dokku logs:set --global vector-image timberio/vector:custom" + assert_success + + run /bin/bash -c "dokku logs:report --global --format json | jq -r '.\"logs-global-vector-image\"'" + assert_success + assert_output "timberio/vector:custom" + + run /bin/bash -c "dokku logs:set --global vector-image" + assert_success + + run /bin/bash -c "dokku logs:report --global --format json | jq -r '.\"logs-global-vector-networks\"'" + assert_success + assert_output "" +} + @test "(logs) logs:set --global vector-networks" { docker network create test-vector-net-a >/dev/null docker network create test-vector-net-b >/dev/null @@ -506,7 +599,7 @@ teardown() { assert_success assert_output_contains "Setting vector-networks" - run /bin/bash -c "dokku logs:report --global --logs-vector-global-networks 2>&1" + run /bin/bash -c "dokku logs:report --global --logs-global-vector-networks 2>&1" echo "output: $output" echo "status: $status" assert_success @@ -518,7 +611,7 @@ teardown() { assert_success assert_output_contains "Setting vector-networks" - run /bin/bash -c "dokku logs:report --global --logs-vector-global-networks 2>&1" + run /bin/bash -c "dokku logs:report --global --logs-global-vector-networks 2>&1" echo "output: $output" echo "status: $status" assert_success @@ -530,7 +623,7 @@ teardown() { assert_success assert_output_contains "Unsetting vector-networks" - run /bin/bash -c "dokku logs:report --global --logs-vector-global-networks 2>&1" + run /bin/bash -c "dokku logs:report --global --logs-global-vector-networks 2>&1" echo "output: $output" echo "status: $status" assert_success diff --git a/tests/unit/network.bats b/tests/unit/network.bats index 311fa3154..79f7e9ed3 100644 --- a/tests/unit/network.bats +++ b/tests/unit/network.bats @@ -66,6 +66,141 @@ teardown() { assert_success } +@test "(network:report) tld raw vs computed" { + run /bin/bash -c "dokku network:set --global tld" + 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 "" + + run /bin/bash -c "dokku network:set --global tld example.test" + 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 "example.test" + + run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-global-tld\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "example.test" + + run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-computed-tld\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "example.test" + + run /bin/bash -c "dokku network:set --global tld" + echo "output: $output" + echo "status: $status" + assert_success +} + +@test "(network:report) attach-post-create raw vs computed vs global" { + docker network create create-network-x >/dev/null + run /bin/bash -c "dokku network:set --global attach-post-create" + assert_success + + run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-attach-post-create\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-global-attach-post-create\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-computed-attach-post-create\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku network:set --global attach-post-create create-network-x" + assert_success + + run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-global-attach-post-create\"'" + assert_success + assert_output "create-network-x" + + run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-computed-attach-post-create\"'" + assert_success + assert_output "create-network-x" + + run /bin/bash -c "dokku network:set --global attach-post-create" + assert_success + + docker network rm create-network-x >/dev/null +} + +@test "(network:report) attach-post-deploy raw vs computed vs global" { + docker network create deploy-network-x >/dev/null + run /bin/bash -c "dokku network:set --global attach-post-deploy" + assert_success + + run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-attach-post-deploy\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-global-attach-post-deploy\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku network:set --global attach-post-deploy deploy-network-x" + assert_success + + run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-global-attach-post-deploy\"'" + assert_success + assert_output "deploy-network-x" + + run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-computed-attach-post-deploy\"'" + assert_success + assert_output "deploy-network-x" + + run /bin/bash -c "dokku network:set --global attach-post-deploy" + assert_success + + docker network rm deploy-network-x >/dev/null +} + +@test "(network:report) initial-network raw vs computed vs global" { + docker network create initial-network-x >/dev/null + run /bin/bash -c "dokku network:set --global initial-network" + assert_success + + run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-initial-network\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-global-initial-network\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku network:set --global initial-network initial-network-x" + assert_success + + run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-global-initial-network\"'" + assert_success + assert_output "initial-network-x" + + run /bin/bash -c "dokku network:report $TEST_APP --format json | jq -r '.\"network-computed-initial-network\"'" + assert_success + assert_output "initial-network-x" + + run /bin/bash -c "dokku network:set --global initial-network" + assert_success + + docker network rm initial-network-x >/dev/null +} + @test "(network) network:set bind-all-interfaces" { run deploy_app echo "output: $output" diff --git a/tests/unit/nginx-vhosts_properties.bats b/tests/unit/nginx-vhosts_properties.bats new file mode 100644 index 000000000..accc328d6 --- /dev/null +++ b/tests/unit/nginx-vhosts_properties.bats @@ -0,0 +1,103 @@ +#!/usr/bin/env bats + +load test_helper + +setup() { + global_setup + create_app +} + +teardown() { + destroy_app + global_teardown +} + +# assert_nginx_property_set_get verifies that for a given nginx property, +# (a) the raw per-app and global keys cycle through set/unset states, +# (b) the computed key always returns a non-empty value when defaults exist, +# and (c) the computed key falls back through per-app -> global. +# +# This intentionally does not pin the exact default value for properties whose +# default is computed at runtime (e.g. proxy-buffer-size depends on the host's +# page size) - those would be brittle to assert verbatim. The set/unset cycle +# is the canonical test for the report convention. +assert_nginx_property_set_get() { + declare prop="$1" app_value="$2" global_value="$3" + + run /bin/bash -c "dokku nginx:set --global $prop" + assert_success + + run /bin/bash -c "dokku nginx:set --global $prop '$global_value'" + assert_success + + run /bin/bash -c "dokku nginx:report $TEST_APP --format json | jq -r '.\"global-$prop\"'" + assert_success + assert_output "$global_value" + + run /bin/bash -c "dokku nginx:report $TEST_APP --format json | jq -r '.\"computed-$prop\"'" + assert_success + assert_output "$global_value" + + run /bin/bash -c "dokku nginx:set $TEST_APP $prop '$app_value'" + assert_success + + run /bin/bash -c "dokku nginx:report $TEST_APP --format json | jq -r '.\"$prop\"'" + assert_success + assert_output "$app_value" + + run /bin/bash -c "dokku nginx:report $TEST_APP --format json | jq -r '.\"global-$prop\"'" + assert_success + assert_output "$global_value" + + run /bin/bash -c "dokku nginx:report $TEST_APP --format json | jq -r '.\"computed-$prop\"'" + assert_success + assert_output "$app_value" + + run /bin/bash -c "dokku nginx:set $TEST_APP $prop" + assert_success + + run /bin/bash -c "dokku nginx:set --global $prop" + assert_success +} + +@test "(nginx:report) timeout properties raw/global/computed" { + for prop in client-body-timeout client-header-timeout keepalive-timeout lingering-timeout send-timeout proxy-connect-timeout proxy-read-timeout proxy-send-timeout; do + assert_nginx_property_set_get "$prop" "30s" "45s" + done +} + +@test "(nginx:report) buffer properties raw/global/computed" { + assert_nginx_property_set_get "proxy-buffer-size" "8k" "16k" + assert_nginx_property_set_get "proxy-buffering" "off" "on" + assert_nginx_property_set_get "proxy-buffers" "16 16k" "32 16k" + assert_nginx_property_set_get "proxy-busy-buffers-size" "16k" "32k" + assert_nginx_property_set_get "client-max-body-size" "10m" "20m" +} + +@test "(nginx:report) hsts properties raw/global/computed" { + assert_nginx_property_set_get "hsts" "false" "true" + assert_nginx_property_set_get "hsts-include-subdomains" "false" "true" + assert_nginx_property_set_get "hsts-max-age" "3600" "7200" + assert_nginx_property_set_get "hsts-preload" "true" "false" +} + +@test "(nginx:report) x-forwarded properties raw/global/computed" { + assert_nginx_property_set_get "x-forwarded-for-value" "\$remote_addr" "\$proxy_add_x_forwarded_for" + assert_nginx_property_set_get "x-forwarded-port-value" "8080" "8443" + assert_nginx_property_set_get "x-forwarded-proto-value" "https" "http" + assert_nginx_property_set_get "x-forwarded-ssl" "on" "off" +} + +@test "(nginx:report) log/address properties raw/global/computed" { + assert_nginx_property_set_get "bind-address-ipv4" "127.0.0.1" "0.0.0.0" + assert_nginx_property_set_get "bind-address-ipv6" "::1" "::" + assert_nginx_property_set_get "access-log-format" "main" "combined" + assert_nginx_property_set_get "access-log-path" "/var/log/nginx/app-access.log" "/dev/stdout" + assert_nginx_property_set_get "error-log-path" "/var/log/nginx/app-error.log" "/dev/stderr" +} + +@test "(nginx:report) misc properties raw/global/computed" { + assert_nginx_property_set_get "disable-custom-config" "false" "true" + assert_nginx_property_set_get "underscore-in-headers" "on" "off" + assert_nginx_property_set_get "proxy-keepalive" "8" "16" +} diff --git a/tests/unit/proxy.bats b/tests/unit/proxy.bats index 259c3435d..77d9cd625 100644 --- a/tests/unit/proxy.bats +++ b/tests/unit/proxy.bats @@ -28,6 +28,103 @@ teardown() { assert_output "$help_output" } +@test "(proxy:report) --global raw vs computed type" { + run /bin/bash -c "dokku proxy:report --global --format json | jq -r '.\"proxy-global-type\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "" + + run /bin/bash -c "dokku proxy:report --global --format json | jq -r '.\"proxy-computed-type\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "nginx" + + run /bin/bash -c "dokku proxy:set --global type caddy" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku proxy:report --global --format json | jq -r '.\"proxy-global-type\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "caddy" + + run /bin/bash -c "dokku proxy:report --global --format json | jq -r '.\"proxy-computed-type\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "caddy" + + run /bin/bash -c "dokku proxy:set --global type" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku proxy:report --global --format json | jq -r '.\"proxy-global-type\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "" + + run /bin/bash -c "dokku proxy:report --global --format json | jq -r '.\"proxy-computed-type\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "nginx" +} + +@test "(proxy:report) type raw vs computed vs global" { + run /bin/bash -c "dokku proxy:set --global type" + assert_success + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-type\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-global-type\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-type\"'" + assert_success + assert_output "nginx" + + run /bin/bash -c "dokku proxy:set --global type caddy" + assert_success + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-global-type\"'" + assert_success + assert_output "caddy" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-type\"'" + assert_success + assert_output "caddy" + + run /bin/bash -c "dokku proxy:set $TEST_APP type traefik" + assert_success + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-type\"'" + assert_success + assert_output "traefik" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-global-type\"'" + assert_success + assert_output "caddy" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-type\"'" + assert_success + assert_output "traefik" + + run /bin/bash -c "dokku proxy:set $TEST_APP type" + assert_success + + run /bin/bash -c "dokku proxy:set --global type" + assert_success +} + @test "(proxy:set) invalid port mapping set" { run /bin/bash -c "dokku proxy:set $TEST_APP http:80:80" echo "output: $output" diff --git a/tests/unit/ps-general-1.bats b/tests/unit/ps-general-1.bats index a6fb02da1..24a38c9c4 100644 --- a/tests/unit/ps-general-1.bats +++ b/tests/unit/ps-general-1.bats @@ -83,7 +83,7 @@ teardown() { run /bin/bash -c "dokku ps:report $TEST_APP --ps-global-procfile-path" echo "output: $output" echo "status: $status" - assert_output "Procfile" + assert_output "" assert_success run /bin/bash -c "dokku ps:report $TEST_APP --ps-procfile-path" @@ -168,8 +168,57 @@ web assert_success } +@test "(ps:report) stop-timeout-seconds raw vs computed vs global" { + run /bin/bash -c "dokku ps:set --global stop-timeout-seconds" + assert_success + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"stop-timeout-seconds\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"global-stop-timeout-seconds\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"computed-stop-timeout-seconds\"'" + assert_success + assert_output "30" + + run /bin/bash -c "dokku ps:set --global stop-timeout-seconds 90" + assert_success + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"global-stop-timeout-seconds\"'" + assert_success + assert_output "90" + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"computed-stop-timeout-seconds\"'" + assert_success + assert_output "90" + + run /bin/bash -c "dokku ps:set $TEST_APP stop-timeout-seconds 45" + assert_success + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"stop-timeout-seconds\"'" + assert_success + assert_output "45" + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"global-stop-timeout-seconds\"'" + assert_success + assert_output "90" + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"computed-stop-timeout-seconds\"'" + assert_success + assert_output "45" + + run /bin/bash -c "dokku ps:set $TEST_APP stop-timeout-seconds" + assert_success + + run /bin/bash -c "dokku ps:set --global stop-timeout-seconds" + assert_success +} + @test "(ps:restart-policy) default policy" { - run /bin/bash -c "dokku --quiet ps:report $TEST_APP --ps-restart-policy" + run /bin/bash -c "dokku ps:report $TEST_APP --ps-restart-policy" echo "output: $output" echo "status: $status" assert_output "on-failure:10" @@ -182,7 +231,7 @@ web echo "status: $status" assert_success - run /bin/bash -c "dokku --quiet ps:report $TEST_APP --ps-restart-policy" + run /bin/bash -c "dokku ps:report $TEST_APP --ps-restart-policy" echo "output: $output" echo "status: $status" assert_output "$policy" @@ -196,7 +245,7 @@ web echo "status: $status" assert_success - run /bin/bash -c "dokku --quiet ps:report $TEST_APP --ps-restart-policy" + run /bin/bash -c "dokku ps:report $TEST_APP --ps-restart-policy" echo "output: $output" echo "status: $status" assert_output "$test_restart_policy" diff --git a/tests/unit/registry.bats b/tests/unit/registry.bats index a6dba06bd..b027bf03c 100644 --- a/tests/unit/registry.bats +++ b/tests/unit/registry.bats @@ -133,6 +133,115 @@ teardown() { create_app } +@test "(registry:report) image-repo raw vs computed vs global" { + run /bin/bash -c "dokku registry:set --global image-repo-template" + assert_success + + run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-image-repo\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-global-image-repo-template\"'" + assert_success + assert_output "" + + # When neither per-app image-repo nor a global image-repo-template are set, + # reportComputedImageRepo falls back to common.GetAppImageRepo which returns + # the default dokku/ image name. + run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-image-repo\"'" + assert_success + assert_output "dokku/$TEST_APP" + + run /bin/bash -c "dokku registry:set --global image-repo-template 'dokku/{{ APP }}'" + assert_success + + run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-global-image-repo-template\"'" + assert_success + assert_output 'dokku/{{ APP }}' + + run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-image-repo\"'" + assert_success + assert_output "dokku/$TEST_APP" + + run /bin/bash -c "dokku registry:set $TEST_APP image-repo my/$TEST_APP" + assert_success + + run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-image-repo\"'" + assert_success + assert_output "my/$TEST_APP" + + run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-image-repo\"'" + assert_success + assert_output "my/$TEST_APP" + + run /bin/bash -c "dokku registry:set $TEST_APP image-repo" + assert_success + + run /bin/bash -c "dokku registry:set --global image-repo-template" + assert_success +} + +@test "(registry:report) push-on-release raw vs computed vs global" { + run /bin/bash -c "dokku registry:set --global push-on-release" + assert_success + + run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-push-on-release\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-global-push-on-release\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-push-on-release\"'" + assert_success + assert_output "false" + + run /bin/bash -c "dokku registry:set --global push-on-release true" + assert_success + + run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-global-push-on-release\"'" + assert_success + assert_output "true" + + run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-push-on-release\"'" + assert_success + assert_output "true" + + run /bin/bash -c "dokku registry:set $TEST_APP push-on-release false" + assert_success + + run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-push-on-release\"'" + assert_success + assert_output "false" + + run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-computed-push-on-release\"'" + assert_success + assert_output "false" + + run /bin/bash -c "dokku registry:set $TEST_APP push-on-release" + assert_success + + run /bin/bash -c "dokku registry:set --global push-on-release" + assert_success +} + +@test "(registry:report) push-extra-tags raw" { + run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-push-extra-tags\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku registry:set $TEST_APP push-extra-tags release,stable" + assert_success + + run /bin/bash -c "dokku registry:report $TEST_APP --format json | jq -r '.\"registry-push-extra-tags\"'" + assert_success + assert_output "release,stable" + + run /bin/bash -c "dokku registry:set $TEST_APP push-extra-tags" + assert_success +} + @test "(registry) registry:set server" { run /bin/bash -c "dokku registry:set --global server ghcr.io" echo "output: $output" diff --git a/tests/unit/scheduler-docker-local.bats b/tests/unit/scheduler-docker-local.bats index f5ef9ec5d..29c76196c 100644 --- a/tests/unit/scheduler-docker-local.bats +++ b/tests/unit/scheduler-docker-local.bats @@ -10,17 +10,29 @@ teardown() { global_teardown } -@test "(scheduler-docker-local:report) --global --scheduler-docker-local-global-init-process" { +@test "(scheduler-docker-local:report) --global raw and computed keys" { run /bin/bash -c "dokku scheduler-docker-local:report --global --scheduler-docker-local-global-init-process" echo "output: $output" echo "status: $status" assert_success + assert_output "" + + run /bin/bash -c "dokku scheduler-docker-local:report --global --scheduler-docker-local-computed-init-process" + echo "output: $output" + echo "status: $status" + assert_success assert_output "true" run /bin/bash -c "dokku scheduler-docker-local:report --global --scheduler-docker-local-global-parallel-schedule-count" echo "output: $output" echo "status: $status" assert_success + assert_output "" + + run /bin/bash -c "dokku scheduler-docker-local:report --global --scheduler-docker-local-computed-parallel-schedule-count" + echo "output: $output" + echo "status: $status" + assert_success assert_output "1" } @@ -46,7 +58,7 @@ teardown() { echo "output: $output" echo "status: $status" assert_success - assert_output "1" + assert_output "" run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --scheduler-docker-local-init-process" echo "output: $output" @@ -64,7 +76,7 @@ teardown() { echo "output: $output" echo "status: $status" assert_success - assert_output "true" + assert_output "" run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --scheduler-docker-local-invalid-flag" echo "output: $output" @@ -99,7 +111,7 @@ teardown() { run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"global-init-process\"'" echo "output: $output" echo "status: $status" - assert_output "true" + assert_output "" run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"parallel-schedule-count\"'" echo "output: $output" @@ -114,7 +126,7 @@ teardown() { run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"global-parallel-schedule-count\"'" echo "output: $output" echo "status: $status" - assert_output "1" + assert_output "" run /bin/bash -c "dokku scheduler-docker-local:set $TEST_APP init-process false" echo "output: $output" diff --git a/tests/unit/scheduler.bats b/tests/unit/scheduler.bats new file mode 100644 index 000000000..9cee44778 --- /dev/null +++ b/tests/unit/scheduler.bats @@ -0,0 +1,97 @@ +#!/usr/bin/env bats + +load test_helper + +setup() { + global_setup + create_app +} + +teardown() { + dokku scheduler:set --global selected >/dev/null 2>&1 || true + destroy_app + global_teardown +} + +@test "(scheduler) scheduler:help" { + run /bin/bash -c "dokku scheduler" + echo "output: $output" + echo "status: $status" + assert_output_contains "Manage scheduler settings" + help_output="$output" + + run /bin/bash -c "dokku scheduler:help" + echo "output: $output" + echo "status: $status" + assert_output_contains "Manage scheduler settings" + assert_output "$help_output" +} + +@test "(scheduler:report) selected raw vs computed vs global" { + run /bin/bash -c "dokku scheduler:set --global selected" + assert_success + + run /bin/bash -c "dokku scheduler:report $TEST_APP --format json | jq -r '.\"scheduler-selected\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku scheduler:report $TEST_APP --format json | jq -r '.\"scheduler-global-selected\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku scheduler:report $TEST_APP --format json | jq -r '.\"scheduler-computed-selected\"'" + assert_success + assert_output "docker-local" + + run /bin/bash -c "dokku scheduler:set --global selected null" + assert_success + + run /bin/bash -c "dokku scheduler:report $TEST_APP --format json | jq -r '.\"scheduler-global-selected\"'" + assert_success + assert_output "null" + + run /bin/bash -c "dokku scheduler:report $TEST_APP --format json | jq -r '.\"scheduler-computed-selected\"'" + assert_success + assert_output "null" + + run /bin/bash -c "dokku scheduler:set $TEST_APP selected docker-local" + assert_success + + run /bin/bash -c "dokku scheduler:report $TEST_APP --format json | jq -r '.\"scheduler-selected\"'" + assert_success + assert_output "docker-local" + + run /bin/bash -c "dokku scheduler:report $TEST_APP --format json | jq -r '.\"scheduler-global-selected\"'" + assert_success + assert_output "null" + + run /bin/bash -c "dokku scheduler:report $TEST_APP --format json | jq -r '.\"scheduler-computed-selected\"'" + assert_success + assert_output "docker-local" + + run /bin/bash -c "dokku scheduler:set $TEST_APP selected" + assert_success + + run /bin/bash -c "dokku scheduler:set --global selected" + assert_success +} + +@test "(scheduler:report) --global --format json" { + run /bin/bash -c "dokku scheduler:set --global selected" + assert_success + + run /bin/bash -c "dokku scheduler:report --global --format json | jq -e ." + assert_success + + run /bin/bash -c "dokku scheduler:report --global --format json | jq -r '.\"scheduler-global-selected\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku scheduler:report --global --format json | jq -r '.\"scheduler-computed-selected\"'" + assert_success + assert_output "docker-local" + + run /bin/bash -c "dokku scheduler:report --global --format json | jq -r 'has(\"scheduler-selected\")'" + assert_success + assert_output "false" +} diff --git a/tests/unit/storage.bats b/tests/unit/storage.bats index 9b2548755..a93c40428 100644 --- a/tests/unit/storage.bats +++ b/tests/unit/storage.bats @@ -184,6 +184,38 @@ teardown() { assert_output "mount_volume:/mount" } +@test "(storage:report) build/deploy/run mounts raw" { + run /bin/bash -c "dokku storage:report $TEST_APP --format json | jq -r '.\"storage-build-mounts\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku storage:report $TEST_APP --format json | jq -r '.\"storage-deploy-mounts\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku storage:report $TEST_APP --format json | jq -r '.\"storage-run-mounts\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku storage:mount $TEST_APP /tmp/storage-mount:/mount" + assert_success + + run /bin/bash -c "dokku storage:report $TEST_APP --format json | jq -r '.\"storage-deploy-mounts\"'" + assert_success + assert_output "-v /tmp/storage-mount:/mount" + + run /bin/bash -c "dokku storage:report $TEST_APP --format json | jq -r '.\"storage-run-mounts\"'" + assert_success + assert_output "-v /tmp/storage-mount:/mount" + + run /bin/bash -c "dokku storage:report $TEST_APP --format json | jq -r '.\"storage-build-mounts\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku storage:unmount $TEST_APP /tmp/storage-mount:/mount" + assert_success +} + @test "(storage) storage:create / storage:list-entries / storage:destroy" { run /bin/bash -c "dokku storage:create rdmtest-entry" echo "output: $output" diff --git a/tests/unit/traefik.bats b/tests/unit/traefik.bats index 1f2937084..ac9edf1b8 100644 --- a/tests/unit/traefik.bats +++ b/tests/unit/traefik.bats @@ -23,13 +23,31 @@ teardown() { dokku nginx:start } -@test "(traefik:report) --global --traefik-log-level" { +@test "(traefik:report) --global global vs computed log-level" { + run /bin/bash -c "dokku traefik:report --global --traefik-global-log-level" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "" + + run /bin/bash -c "dokku traefik:report --global --traefik-computed-log-level" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "ERROR" + run /bin/bash -c "dokku traefik:set --global log-level DEBUG" echo "output: $output" echo "status: $status" assert_success - run /bin/bash -c "dokku traefik:report --global --traefik-log-level" + run /bin/bash -c "dokku traefik:report --global --traefik-global-log-level" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "DEBUG" + + run /bin/bash -c "dokku traefik:report --global --traefik-computed-log-level" echo "output: $output" echo "status: $status" assert_success @@ -39,6 +57,44 @@ teardown() { echo "output: $output" echo "status: $status" assert_success + + run /bin/bash -c "dokku traefik:report --global --traefik-global-log-level" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "" + + run /bin/bash -c "dokku traefik:report --global --traefik-computed-log-level" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "ERROR" +} + +@test "(traefik:report) --global raw and computed keys in --format json" { + run /bin/bash -c "dokku traefik:report --global --format json | jq -r '.\"global-api-vhost\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "" + + run /bin/bash -c "dokku traefik:report --global --format json | jq -r '.\"computed-api-vhost\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "traefik.dokku.me" + + run /bin/bash -c "dokku traefik:report --global --format json | jq -r '.\"global-dashboard-enabled\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "" + + run /bin/bash -c "dokku traefik:report --global --format json | jq -r '.\"computed-dashboard-enabled\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "false" } @test "(traefik) global-only keys" { @@ -244,12 +300,12 @@ teardown() { assert_success assert_output "5000" - run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map" + run /bin/bash -c "dokku ports:report $TEST_APP --ports-map" echo "output: $output" echo "status: $status" assert_output_not_exists - run /bin/bash -c "dokku --quiet ports:report $TEST_APP --ports-map-detected" + run /bin/bash -c "dokku ports:report $TEST_APP --ports-map-detected" echo "output: $output" echo "status: $status" assert_output "http:80:5000 https:443:5000" @@ -409,7 +465,7 @@ teardown() { } @test "(traefik) [dns-01] challenge-mode property" { - run /bin/bash -c "dokku traefik:report $TEST_APP --traefik-challenge-mode" + run /bin/bash -c "dokku traefik:report $TEST_APP --traefik-computed-challenge-mode" echo "output: $output" echo "status: $status" assert_success @@ -420,7 +476,7 @@ teardown() { echo "status: $status" assert_success - run /bin/bash -c "dokku traefik:report $TEST_APP --traefik-challenge-mode" + run /bin/bash -c "dokku traefik:report $TEST_APP --traefik-computed-challenge-mode" echo "output: $output" echo "status: $status" assert_success @@ -431,7 +487,7 @@ teardown() { echo "status: $status" assert_success - run /bin/bash -c "dokku traefik:report $TEST_APP --traefik-challenge-mode" + run /bin/bash -c "dokku traefik:report $TEST_APP --traefik-computed-challenge-mode" echo "output: $output" echo "status: $status" assert_success @@ -439,7 +495,7 @@ teardown() { } @test "(traefik) [dns-01] dns-provider property" { - run /bin/bash -c "dokku traefik:report $TEST_APP --traefik-dns-provider" + run /bin/bash -c "dokku traefik:report $TEST_APP --traefik-computed-dns-provider" echo "output: $output" echo "status: $status" assert_success @@ -450,7 +506,7 @@ teardown() { echo "status: $status" assert_success - run /bin/bash -c "dokku traefik:report $TEST_APP --traefik-dns-provider" + run /bin/bash -c "dokku traefik:report $TEST_APP --traefik-computed-dns-provider" echo "output: $output" echo "status: $status" assert_success @@ -461,7 +517,7 @@ teardown() { echo "status: $status" assert_success - run /bin/bash -c "dokku traefik:report $TEST_APP --traefik-dns-provider" + run /bin/bash -c "dokku traefik:report $TEST_APP --traefik-computed-dns-provider" echo "output: $output" echo "status: $status" assert_success @@ -594,7 +650,7 @@ teardown() { } @test "(traefik) api-entry-point property" { - run /bin/bash -c "dokku traefik:report $TEST_APP --traefik-api-entry-point" + run /bin/bash -c "dokku traefik:report $TEST_APP --traefik-computed-api-entry-point" echo "output: $output" echo "status: $status" assert_success @@ -605,7 +661,7 @@ teardown() { echo "status: $status" assert_success - run /bin/bash -c "dokku traefik:report $TEST_APP --traefik-api-entry-point" + run /bin/bash -c "dokku traefik:report $TEST_APP --traefik-computed-api-entry-point" echo "output: $output" echo "status: $status" assert_success @@ -616,7 +672,7 @@ teardown() { echo "status: $status" assert_success - run /bin/bash -c "dokku traefik:report $TEST_APP --traefik-api-entry-point" + run /bin/bash -c "dokku traefik:report $TEST_APP --traefik-computed-api-entry-point" echo "output: $output" echo "status: $status" assert_success