From 348a593ee85221b501fce31c3d2a3a00cfb1fd33 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 27 Nov 2022 19:50:57 -0500 Subject: [PATCH 01/13] refactor trigger proxy-build-config from nginx#core-post-deploy This reduces the duplicated code in the plugin. --- plugins/nginx-vhosts/core-post-deploy | 15 +-------------- plugins/nginx-vhosts/proxy-build-config | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/plugins/nginx-vhosts/core-post-deploy b/plugins/nginx-vhosts/core-post-deploy index 00a9ceea1..5fdde3b94 100755 --- a/plugins/nginx-vhosts/core-post-deploy +++ b/plugins/nginx-vhosts/core-post-deploy @@ -14,20 +14,7 @@ trigger-nginx-vhosts-core-post-deploy() { return fi - HAS_NETWORK_CONFIG="$(plugn trigger network-config-exists "$APP")" - if [[ "$HAS_NETWORK_CONFIG" == "true" ]]; then - plugn trigger domains-setup "$APP" - nginx_build_config "$APP" - if [[ -f "${DOKKU_LIB_ROOT}/data/nginx-vhosts/app-$APP/nginx.conf.sigil.$DOKKU_PID" ]]; then - mv "${DOKKU_LIB_ROOT}/data/nginx-vhosts/app-$APP/nginx.conf.sigil.$DOKKU_PID" "${DOKKU_LIB_ROOT}/data/nginx-vhosts/app-$APP/nginx.conf.sigil" - fi - if [[ -f "${DOKKU_LIB_ROOT}/data/nginx-vhosts/app-$APP/nginx.conf.sigil.$DOKKU_PID.missing" ]]; then - rm -f "${DOKKU_LIB_ROOT}/data/nginx-vhosts/app-$APP/nginx.conf.sigil.$DOKKU_PID.missing" - rm -f "${DOKKU_LIB_ROOT}/data/nginx-vhosts/app-$APP/nginx.conf.sigil" - fi - else - nginx_clear_config "$APP" - fi + plugn trigger proxy-build-config "$APP" } trigger-nginx-vhosts-core-post-deploy "$@" diff --git a/plugins/nginx-vhosts/proxy-build-config b/plugins/nginx-vhosts/proxy-build-config index f69cb6447..4b860dad1 100755 --- a/plugins/nginx-vhosts/proxy-build-config +++ b/plugins/nginx-vhosts/proxy-build-config @@ -8,12 +8,28 @@ trigger-nginx-vhosts-proxy-build-config() { declare desc="build nginx config to proxy app containers from command line" declare trigger="proxy-build-config" declare APP="$1" + local HAS_NETWORK_CONFIG - [[ -z "$APP" ]] && dokku_log_fail "Please specify an app to run the command on" - if [[ "$(plugn trigger proxy-type "$APP")" == "nginx" ]]; then + if [[ "$(plugn trigger proxy-type "$APP")" != "nginx" ]]; then + return + fi + + HAS_NETWORK_CONFIG="$(plugn trigger network-config-exists "$APP")" + if [[ "$HAS_NETWORK_CONFIG" == "true" ]]; then + plugn trigger domains-setup "$APP" plugn trigger network-build-config "$APP" nginx_build_config "$APP" + if [[ -f "${DOKKU_LIB_ROOT}/data/nginx-vhosts/app-$APP/nginx.conf.sigil.$DOKKU_PID" ]]; then + mv "${DOKKU_LIB_ROOT}/data/nginx-vhosts/app-$APP/nginx.conf.sigil.$DOKKU_PID" "${DOKKU_LIB_ROOT}/data/nginx-vhosts/app-$APP/nginx.conf.sigil" + fi + if [[ -f "${DOKKU_LIB_ROOT}/data/nginx-vhosts/app-$APP/nginx.conf.sigil.$DOKKU_PID.missing" ]]; then + rm -f "${DOKKU_LIB_ROOT}/data/nginx-vhosts/app-$APP/nginx.conf.sigil.$DOKKU_PID.missing" + rm -f "${DOKKU_LIB_ROOT}/data/nginx-vhosts/app-$APP/nginx.conf.sigil" + fi + else + nginx_clear_config "$APP" fi + } trigger-nginx-vhosts-proxy-build-config "$@" From 78438dfb7488ca3662373e472565397bc6510165 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 27 Nov 2022 19:51:12 -0500 Subject: [PATCH 02/13] chore: do not rework network config if the scheduler is not docker-local --- plugins/network/network.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/network/network.go b/plugins/network/network.go index 24b8e45a8..23d8c0b13 100644 --- a/plugins/network/network.go +++ b/plugins/network/network.go @@ -61,6 +61,10 @@ func BuildConfig(appName string) error { return nil } + if common.GetAppScheduler(appName) != "docker-local" { + return nil + } + image := common.GetAppImageName(appName, "", "") isHerokuishContainer := common.IsImageHerokuishBased(image, appName) common.LogInfo1(fmt.Sprintf("Ensuring network configuration is in sync for %s", appName)) From 203a56fa115f2d9ce128880eb1777e8d81c869ab Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 27 Nov 2022 19:53:54 -0500 Subject: [PATCH 03/13] chore: remote whitespace --- plugins/nginx-vhosts/proxy-build-config | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/nginx-vhosts/proxy-build-config b/plugins/nginx-vhosts/proxy-build-config index 4b860dad1..4e85e32ca 100755 --- a/plugins/nginx-vhosts/proxy-build-config +++ b/plugins/nginx-vhosts/proxy-build-config @@ -29,7 +29,6 @@ trigger-nginx-vhosts-proxy-build-config() { else nginx_clear_config "$APP" fi - } trigger-nginx-vhosts-proxy-build-config "$@" From 1fab98286b7a7a74ba36a4ebf60734d8810147f4 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 28 Nov 2022 01:34:02 -0500 Subject: [PATCH 04/13] fix: also report that there is a network config if a static-web-listener is specified --- plugins/network/network.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/network/network.go b/plugins/network/network.go index 23d8c0b13..26e636aef 100644 --- a/plugins/network/network.go +++ b/plugins/network/network.go @@ -225,7 +225,11 @@ func HasNetworkConfig(appName string) bool { ipfile := fmt.Sprintf("%v/IP.web.1", appRoot) portfile := fmt.Sprintf("%v/PORT.web.1", appRoot) - return common.FileExists(ipfile) && common.FileExists(portfile) + if common.FileExists(ipfile) && common.FileExists(portfile) { + return true + } + + return reportStaticWebListener(appName) != "" } // ClearNetworkConfig removes old IP and PORT files for a newly cloned app From 9eab17af116a7030d30a18a59713702f7db53b90 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Thu, 1 Dec 2022 21:47:59 -0500 Subject: [PATCH 05/13] refactor: setup app domains in the post-create hook This is more consistent with app setup, at the cost of making it so developers must disable domains manually afterwards. --- docs/appendices/0.29.0-migration-guide.md | 1 + docs/development/plugin-triggers.md | 15 --------------- plugins/caddy-vhosts/docker-args-process-deploy | 3 --- plugins/domains/{domains-setup => post-create} | 8 ++++---- plugins/nginx-vhosts/proxy-build-config | 1 - plugins/traefik-vhosts/docker-args-process-deploy | 3 --- 6 files changed, 5 insertions(+), 26 deletions(-) rename plugins/domains/{domains-setup => post-create} (74%) diff --git a/docs/appendices/0.29.0-migration-guide.md b/docs/appendices/0.29.0-migration-guide.md index ee8cb8578..0dc3d4ffe 100644 --- a/docs/appendices/0.29.0-migration-guide.md +++ b/docs/appendices/0.29.0-migration-guide.md @@ -12,3 +12,4 @@ - The `DOKKU_WAIT_TO_RETIRE` environment variable has been migrated to a `checks` property named `wait-to-retire` and will be ignored if set as an environment variable. - The `Procfile` is now extracted when source code is extracted for a build and not from the built image. Users can specify alternative paths via the `procfile-path` property of the `ps` plugin. See the [process management documentation](/docs/processes/process-management.md#changing-the-procfile-location) for more information on how to configure the `Procfile` path for your application. +- The `domains-setup` trigger has been removed. Initial app domains will now be automatically setup during app creation. diff --git a/docs/development/plugin-triggers.md b/docs/development/plugin-triggers.md index eca55a663..743ffcc6a 100644 --- a/docs/development/plugin-triggers.md +++ b/docs/development/plugin-triggers.md @@ -713,21 +713,6 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x # TODO ``` -### `domains-setup` - -- Description: Initializes domains for an app if enabled -- Invoked by: -- Arguments: `$APP` -- Example: - -```shell -#!/usr/bin/env bash - -set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x - -# TODO -``` - ### `domains-vhost-enabled` - Description: Checks if a virtual hosts are enabled for an app diff --git a/plugins/caddy-vhosts/docker-args-process-deploy b/plugins/caddy-vhosts/docker-args-process-deploy index 7272a741c..60a4c232e 100755 --- a/plugins/caddy-vhosts/docker-args-process-deploy +++ b/plugins/caddy-vhosts/docker-args-process-deploy @@ -30,9 +30,6 @@ trigger-caddy-vhosts-docker-args-process-deploy() { return fi - # run this silently or the output will be set as a label - plugn trigger domains-setup "$APP" >/dev/null - # ensure we have a port mapping plugn trigger proxy-configure-ports "$APP" diff --git a/plugins/domains/domains-setup b/plugins/domains/post-create similarity index 74% rename from plugins/domains/domains-setup rename to plugins/domains/post-create index 1ace670ce..9ba77db67 100755 --- a/plugins/domains/domains-setup +++ b/plugins/domains/post-create @@ -3,17 +3,17 @@ source "$PLUGIN_AVAILABLE_PATH/domains/functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -trigger-domains-domains-setup() { +trigger-domains-post-create() { declare desc="creates vhost files as necessary" - declare trigger="domains-setup" + declare trigger="post-create" declare APP="$1" if [[ "$(is_app_vhost_enabled "$APP")" == "false" ]]; then - dokku_log_info1 "App virtual host support disabled, skipping domains setup" + dokku_log_info1 "App virtual host support disabled, skipping domain setup" return fi domains_setup "$APP" } -trigger-domains-domains-setup "$@" +trigger-domains-post-create "$@" diff --git a/plugins/nginx-vhosts/proxy-build-config b/plugins/nginx-vhosts/proxy-build-config index 4e85e32ca..c9c330e6c 100755 --- a/plugins/nginx-vhosts/proxy-build-config +++ b/plugins/nginx-vhosts/proxy-build-config @@ -16,7 +16,6 @@ trigger-nginx-vhosts-proxy-build-config() { HAS_NETWORK_CONFIG="$(plugn trigger network-config-exists "$APP")" if [[ "$HAS_NETWORK_CONFIG" == "true" ]]; then - plugn trigger domains-setup "$APP" plugn trigger network-build-config "$APP" nginx_build_config "$APP" if [[ -f "${DOKKU_LIB_ROOT}/data/nginx-vhosts/app-$APP/nginx.conf.sigil.$DOKKU_PID" ]]; then diff --git a/plugins/traefik-vhosts/docker-args-process-deploy b/plugins/traefik-vhosts/docker-args-process-deploy index 83e7d1da5..7eb3d2b47 100755 --- a/plugins/traefik-vhosts/docker-args-process-deploy +++ b/plugins/traefik-vhosts/docker-args-process-deploy @@ -30,9 +30,6 @@ trigger-traefik-vhosts-docker-args-process-deploy() { return fi - # run this silently or the output will be set as a label - plugn trigger domains-setup "$APP" >/dev/null - # ensure we have a port mapping plugn trigger proxy-configure-ports "$APP" From d18cb3766c31c2293d37f7a9da61dccc5d585a0b Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Thu, 1 Dec 2022 21:51:47 -0500 Subject: [PATCH 06/13] fix: correct tests for new domain initialization method --- tests/unit/core_2.bats | 12 ++++-------- tests/unit/test_helper.bash | 6 ------ 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/tests/unit/core_2.bats b/tests/unit/core_2.bats index ab699655d..1a165098f 100644 --- a/tests/unit/core_2.bats +++ b/tests/unit/core_2.bats @@ -38,17 +38,15 @@ teardown() { } @test "(core) urls (non-ssl)" { - assert_urls "http://dokku.me" - build_nginx_config assert_urls "http://${TEST_APP}.dokku.me" add_domain "test.dokku.me" assert_urls "http://${TEST_APP}.dokku.me" "http://test.dokku.me" } @test "(core) urls (app ssl)" { + assert_urls "http://${TEST_APP}.dokku.me" setup_test_tls - assert_urls "https://dokku.me" - build_nginx_config + dokku proxy:build-config "$TEST_APP" assert_urls "http://${TEST_APP}.dokku.me" "https://${TEST_APP}.dokku.me" add_domain "test.dokku.me" assert_urls "http://${TEST_APP}.dokku.me" "http://test.dokku.me" "https://${TEST_APP}.dokku.me" "https://test.dokku.me" @@ -56,15 +54,13 @@ teardown() { @test "(core) url (app ssl)" { setup_test_tls - assert_url "https://dokku.me" - build_nginx_config + dokku proxy:build-config "$TEST_APP" assert_url "https://${TEST_APP}.dokku.me" } @test "(core) urls (wildcard ssl)" { setup_test_tls wildcard - assert_urls "https://dokku.me" - build_nginx_config + dokku proxy:build-config "$TEST_APP" assert_urls "http://${TEST_APP}.dokku.me" "https://${TEST_APP}.dokku.me" add_domain "test.dokku.me" assert_urls "http://${TEST_APP}.dokku.me" "http://test.dokku.me" "https://${TEST_APP}.dokku.me" "https://test.dokku.me" diff --git a/tests/unit/test_helper.bash b/tests/unit/test_helper.bash index 93e63b70d..6f86edeea 100644 --- a/tests/unit/test_helper.bash +++ b/tests/unit/test_helper.bash @@ -532,12 +532,6 @@ add_requirements_txt() { echo "flask" >>"$APP_REPO_DIR/requirements.txt" } -build_nginx_config() { - # simulate nginx post-deploy - dokku domains:setup "$TEST_APP" - dokku proxy:build-config "$TEST_APP" -} - create_network() { local NETWORK_NAME="$1:=$TEST_NETWORK" From f4f0a2944671c09d5bd7d6b8d6b2eef55c3db3f2 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Thu, 1 Dec 2022 22:57:31 -0500 Subject: [PATCH 07/13] fix: correct domain wildcard tests for new domain initialization method --- tests/unit/domains.bats | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/unit/domains.bats b/tests/unit/domains.bats index 1fb49b522..82b22d2e9 100644 --- a/tests/unit/domains.bats +++ b/tests/unit/domains.bats @@ -139,21 +139,27 @@ teardown() { } @test "(domains) domains:remove (wildcard domain)" { - run /bin/bash -c "dokku domains:add $TEST_APP *.dokku.me" + run /bin/bash -c "dokku domains:add $TEST_APP '*.dokku.me'" echo "output: $output" echo "status: $status" assert_success - run /bin/bash -c "dokku domains:remove $TEST_APP *.dokku.me" + run /bin/bash -c "dokku domains:report $TEST_APP --domains-app-vhosts" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "$TEST_APP.dokku.me *.dokku.me" + + run /bin/bash -c "dokku domains:remove $TEST_APP '*.dokku.me'" echo "output: $output" echo "status: $status" assert_success - run /bin/bash -c "dokku domains:report $TEST_APP 2>/dev/null" + run /bin/bash -c "dokku domains:report $TEST_APP --domains-app-vhosts" echo "output: $output" echo "status: $status" assert_success - assert_output_contains *.dokku.me 0 + assert_output "$TEST_APP.dokku.me" } @test "(domains) domains:set" { From edd6e476b3742984f3f345c4a85ef1f287c67f3e Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 2 Dec 2022 02:19:59 -0500 Subject: [PATCH 08/13] refactor: simplify how url generation works The URLS file is no longer necessary as urls are now generated directly from the app VHOST file. This also moves all the url generation logic to the domains plugin. --- docs/appendices/0.29.0-migration-guide.md | 2 + docs/development/plugin-triggers.md | 30 +++++ plugins/00_dokku-standard/subcommands/urls | 6 +- .../caddy-vhosts/docker-args-process-deploy | 4 - plugins/certs/certs-exists | 18 +++ plugins/common/functions | 111 +----------------- plugins/domains/domains-urls | 35 ++++++ plugins/domains/functions | 5 +- plugins/domains/install | 1 + plugins/domains/internal-functions | 67 +++++++++++ plugins/domains/post-app-clone-setup | 2 +- plugins/domains/post-app-rename-setup | 4 +- plugins/nginx-vhosts/functions | 8 +- plugins/proxy/proxy-configure-ports | 3 +- .../traefik-vhosts/docker-args-process-deploy | 5 - tests/unit/apps_2.bats | 2 - tests/unit/core_2.bats | 69 ++++++++--- tests/unit/nginx-vhosts_2.bats | 14 +-- tests/unit/nginx-vhosts_4.bats | 4 +- tests/unit/nginx-vhosts_5.bats | 2 +- tests/unit/nginx-vhosts_7.bats | 8 +- tests/unit/nginx-vhosts_9.bats | 8 +- tests/unit/test_helper.bash | 18 +-- 23 files changed, 247 insertions(+), 179 deletions(-) create mode 100755 plugins/certs/certs-exists create mode 100755 plugins/domains/domains-urls diff --git a/docs/appendices/0.29.0-migration-guide.md b/docs/appendices/0.29.0-migration-guide.md index 0dc3d4ffe..3aced033b 100644 --- a/docs/appendices/0.29.0-migration-guide.md +++ b/docs/appendices/0.29.0-migration-guide.md @@ -13,3 +13,5 @@ - The `DOKKU_WAIT_TO_RETIRE` environment variable has been migrated to a `checks` property named `wait-to-retire` and will be ignored if set as an environment variable. - The `Procfile` is now extracted when source code is extracted for a build and not from the built image. Users can specify alternative paths via the `procfile-path` property of the `ps` plugin. See the [process management documentation](/docs/processes/process-management.md#changing-the-procfile-location) for more information on how to configure the `Procfile` path for your application. - The `domains-setup` trigger has been removed. Initial app domains will now be automatically setup during app creation. +- The `URLS` file containing generated urls for an app is no longer generated or referenced. Users should retrieve app urls via the new `domains-urls` plugin trigger. +- The common function `get_app_urls` has been removed. Users should retrieve app urls via the new `domains-urls` plugin trigger. diff --git a/docs/development/plugin-triggers.md b/docs/development/plugin-triggers.md index 743ffcc6a..81a14ae57 100644 --- a/docs/development/plugin-triggers.md +++ b/docs/development/plugin-triggers.md @@ -236,6 +236,21 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x # TODO ``` +### `certs-exists` + +- Description: Echos `true` if certs exists for the app, `false` otherwise +- Invoked by: +- Arguments: `$APP` +- Example: + +```shell +#!/usr/bin/env bash + +set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x + +# TODO +``` + ### `check-deploy` - Description: Allows you to run checks on a deploy before Dokku allows the container to handle requests. @@ -713,6 +728,21 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x # TODO ``` +### `domains-urls` + +- Description: Gets an app's url(s) +- Invoked by: +- Arguments: `$APP $URL_TYPE` +- Example: + +```shell +#!/usr/bin/env bash + +set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x + +# TODO +``` + ### `domains-vhost-enabled` - Description: Checks if a virtual hosts are enabled for an app diff --git a/plugins/00_dokku-standard/subcommands/urls b/plugins/00_dokku-standard/subcommands/urls index f71fed601..1649aba5e 100755 --- a/plugins/00_dokku-standard/subcommands/urls +++ b/plugins/00_dokku-standard/subcommands/urls @@ -1,15 +1,15 @@ #!/usr/bin/env bash +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" cmd-urls() { declare desc="reports dokku vitals for troubleshooting" declare cmd="url" - declare APP="$2" + declare URL_TYPE="$1" APP="$2" verify_app_name "$APP" - get_app_urls "$@" + plugn trigger domains-urls "$APP" "$URL_TYPE" } cmd-urls "$@" diff --git a/plugins/caddy-vhosts/docker-args-process-deploy b/plugins/caddy-vhosts/docker-args-process-deploy index 60a4c232e..a5273b709 100755 --- a/plugins/caddy-vhosts/docker-args-process-deploy +++ b/plugins/caddy-vhosts/docker-args-process-deploy @@ -11,7 +11,6 @@ trigger-caddy-vhosts-docker-args-process-deploy() { local app_domains caddy_domains is_app_listening letsencrypt_email output proxy_container_port proxy_host_port port_map proxy_port_map proxy_scheme proxy_schemes scheme tls_internal local proxy_container_http_port proxy_container_http_port_candidate proxy_host_http_port_candidate local proxy_container_https_port proxy_container_https_port_candidate proxy_host_https_port_candidate - local app_urls_path="$DOKKU_ROOT/$APP/URLS" local STDIN=$(cat) if [[ "$PROC_TYPE" != "web" ]]; then @@ -128,9 +127,6 @@ trigger-caddy-vhosts-docker-args-process-deploy() { output="$output --label \"caddy.reverse_proxy={{ upstreams $proxy_container_http_port }}\"" fi - - echo "# THIS FILE IS GENERATED BY DOKKU - DO NOT EDIT, YOUR CHANGES WILL BE OVERWRITTEN" >"$app_urls_path" - xargs -I{} echo "$scheme://{}" <<<"$(echo "${app_domains}" | tr ' ' '\n' | sort -u)" >>"$app_urls_path" fi echo -n "$STDIN$output" diff --git a/plugins/certs/certs-exists b/plugins/certs/certs-exists new file mode 100755 index 000000000..25311583e --- /dev/null +++ b/plugins/certs/certs-exists @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +source "$PLUGIN_AVAILABLE_PATH/certs/functions" +set -eo pipefail +[[ $DOKKU_TRACE ]] && set -x + +trigger-certs-certs-exists() { + declare desc="checks if certs exist" + declare trigger="certs-exists" + declare APP="$1" + + if is_ssl_enabled "$APP"; then + echo "true" + else + echo "false" + fi +} + +trigger-certs-certs-exists "$@" diff --git a/plugins/common/functions b/plugins/common/functions index 220527418..a7ef0324d 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -384,7 +384,7 @@ is_image_herokuish_based() { fi if [[ -n "$APP" ]]; then - DOKKU_APP_USER=$(config_get "$APP" DOKKU_APP_USER || true) + DOKKU_APP_USER=$(plugn trigger config-get "$APP" DOKKU_APP_USER || true) fi DOKKU_APP_USER=${DOKKU_APP_USER:="herokuishuser"} @@ -719,7 +719,7 @@ release_and_deploy() { dokku_log_info1 "Deploying $APP via the $DOKKU_SCHEDULER scheduler..." cmd-deploy "$APP" "$IMAGE_TAG" dokku_log_info2 "Application deployed:" - get_app_urls urls "$APP" | sed "s/^/ /" + plugn trigger domains-urls "$APP" urls | sed "s/^/ /" else dokku_log_info1 "Skipping deployment" fi @@ -904,113 +904,6 @@ get_container_ports() { echo "$container_ports" } -get_app_urls() { - declare desc="print an app's available urls" - declare URL_TYPE="$1" APP="$2" - local urls - - urls=$(plugn trigger app-urls "$APP" "$URL_TYPE") - if [[ -n "$urls" ]]; then - echo "$urls" | sort - else - internal_get_app_urls "$URL_TYPE" "$APP" | sort - fi -} - -internal_get_app_urls() { - declare desc="print an app's available urls" - source "$PLUGIN_AVAILABLE_PATH/certs/functions" - source "$PLUGIN_AVAILABLE_PATH/config/functions" - - local APP="$2" - local URLS_FILE="$DOKKU_ROOT/$APP/URLS" - local DOKKU_PROXY_PORT_MAP=$(config_get "$APP" DOKKU_PROXY_PORT_MAP || true) - - if [[ -s "$URLS_FILE" ]]; then - local app_urls="$(grep -v -E "^#" "$URLS_FILE")" - if [[ -n "$DOKKU_PROXY_PORT_MAP" ]]; then - local port_map app_vhost - local app_vhosts=$(plugn trigger domains-list "$APP") - for port_map in $DOKKU_PROXY_PORT_MAP; do - local scheme="$(awk -F ':' '{ print $1 }' <<<"$port_map")" - local listen_port="$(awk -F ':' '{ print $2 }' <<<"$port_map")" - for app_vhost in $app_vhosts; do - if [[ "$listen_port" != "80" ]] && [[ "$listen_port" != "443" ]]; then - port_urls+=" $scheme://$app_vhost:$listen_port " - else - port_urls+=" $scheme://$app_vhost " - fi - done - done - fi - local port_urls="$(echo "$port_urls" | xargs)" - local URLS="$(merge_dedupe_list "$port_urls $app_urls" " ")" - case "$1" in - url) - if is_ssl_enabled "$APP"; then - echo "$URLS" | tr ' ' '\n' | grep https | head -n1 - else - echo "$URLS" | tr ' ' '\n' | head -n1 - fi - ;; - urls) - echo "$URLS" | tr ' ' '\n' | sort - ;; - esac - else - if [[ -s "$DOKKU_ROOT/VHOST" ]]; then - while read -r VHOST || [[ -n "$VHOST" ]]; do - internal_get_app_url_with_vhost "$APP" "$VHOST" - done <"$DOKKU_ROOT/VHOST" - else - internal_get_app_url_with_vhost "$APP" "$(hostname -f)" - fi - fi -} - -internal_get_app_url_with_vhost() { - declare APP="$1" VHOST="$2" - - local RAW_TCP_PORTS="$(get_app_raw_tcp_ports "$APP")" - local DOKKU_PROXY_PORT_MAP=$(config_get "$APP" DOKKU_PROXY_PORT_MAP || true) - local SCHEME="http" - local SSL="$DOKKU_ROOT/$APP/tls" - if [[ -e "$SSL/server.crt" && -e "$SSL/server.key" ]]; then - local SCHEME="https" - fi - - if [[ "$(plugn trigger proxy-is-enabled "$APP")" == "false" ]]; then - if [[ -n "$RAW_TCP_PORTS" ]]; then - local APP_CONTAINER_PORTS="$(get_container_ports "$APP")" - local app_port - for app_port in $APP_CONTAINER_PORTS; do - echo "$VHOST:$app_port (container)" - done - else - local DOKKU_APP_WEB_LISTENERS PORT - DOKKU_APP_WEB_LISTENERS="$(plugn trigger network-get-listeners "$APP" "web" | xargs)" - for DOKKU_APP_WEB_LISTENER in $DOKKU_APP_WEB_LISTENERS; do - PORT="$(echo "$DOKKU_APP_WEB_LISTENER" | cut -d ':' -f2)" - echo "$SCHEME://$VHOST:$PORT (container)" - done - shopt -u nullglob - fi - elif [[ -n "$DOKKU_PROXY_PORT_MAP" ]]; then - local port_map - for port_map in $DOKKU_PROXY_PORT_MAP; do - local scheme="$(awk -F ':' '{ print $1 }' <<<"$port_map")" - local listen_port="$(awk -F ':' '{ print $2 }' <<<"$port_map")" - echo "$scheme://$VHOST:$listen_port" - done - elif [[ -n "$RAW_TCP_PORTS" ]]; then - for p in $RAW_TCP_PORTS; do - echo "http://$VHOST:$p" - done - else - echo "$SCHEME://$VHOST" - fi -} - get_json_value() { declare desc="return value of provided json key from a json stream on stdin" # JSON_NODE should be expresses as either a top-level object that has no children diff --git a/plugins/domains/domains-urls b/plugins/domains/domains-urls new file mode 100755 index 000000000..3e45c80d5 --- /dev/null +++ b/plugins/domains/domains-urls @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +source "$PLUGIN_AVAILABLE_PATH/domains/internal-functions" +set -eo pipefail +[[ $DOKKU_TRACE ]] && set -x + +trigger-domains-domains-urls() { + declare desc="gets an app's urls" + declare trigger="domains-urls" + declare APP="$1" URL_TYPE="$2" + local urls + + local SCHEME="http" + local DEFAULT_LISTEN_PORT="80" + if [[ "$(plugn trigger certs-exists "$APP")" == "true" ]]; then + SCHEME="https" + DEFAULT_LISTEN_PORT="443" + fi + + urls=$(plugn trigger app-urls "$APP" "$URL_TYPE") + if [[ -n "$urls" ]]; then + if [[ "$URL_TYPE" == "url" ]]; then + echo "$urls" | tr ' ' '\n' | grep "$SCHEME://" | head -n1 + else + echo "$urls" | tr ' ' '\n' | sort + fi + else + if [[ "$URL_TYPE" == "url" ]]; then + fn-domains-generate-urls "$APP" "$SCHEME" "$DEFAULT_LISTEN_PORT" | tr ' ' '\n' | grep "$SCHEME://" | head -n1 + else + fn-domains-generate-urls "$APP" "$SCHEME" "$DEFAULT_LISTEN_PORT" | tr ' ' '\n' | sort + fi + fi +} + +trigger-domains-domains-urls "$@" diff --git a/plugins/domains/functions b/plugins/domains/functions index e7fe0bd2d..1ebff92d7 100755 --- a/plugins/domains/functions +++ b/plugins/domains/functions @@ -8,12 +8,11 @@ disable_app_vhost() { declare desc="disable vhost support for given application" declare APP=$1 RESTART_APP="$2" local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST" - local APP_URLS_PATH="$DOKKU_ROOT/$APP/URLS" plugn trigger pre-disable-vhost "$APP" - if [[ -f "$APP_VHOST_PATH" ]] || [[ -f "$APP_URLS_PATH" ]]; then + if [[ -f "$APP_VHOST_PATH" ]]; then dokku_log_info1 "App virtual host support disabled" - rm -f "$APP_VHOST_PATH" "$APP_URLS_PATH" + rm -f "$APP_VHOST_PATH" fi [[ "$RESTART_APP" == "--no-restart" ]] && local CONFIG_SET_ARGS=$RESTART_APP diff --git a/plugins/domains/install b/plugins/domains/install index 9a3155659..cb83eb49f 100755 --- a/plugins/domains/install +++ b/plugins/domains/install @@ -10,6 +10,7 @@ trigger-domains-install() { shopt -s nullglob for app in $(dokku_apps "false" 2>/dev/null); do domains_setup "$app" + rm -f "$DOKKU_ROOT/$APP/URLS" done } diff --git a/plugins/domains/internal-functions b/plugins/domains/internal-functions index adb6225c0..921ac9885 100755 --- a/plugins/domains/internal-functions +++ b/plugins/domains/internal-functions @@ -114,3 +114,70 @@ fn-domains-global-vhosts() { get_global_vhosts | tr '\n' ' ' fi } + +fn-domains-generate-urls() { + declare APP="$1" SCHEME="$2" DEFAULT_LISTEN_PORT="$3" + + local app_vhosts="$(plugn trigger domains-list "$APP")" + if [[ -n "$app_vhosts" ]]; then + for app_vhost in $app_vhosts; do + fn-domains-generate-urls-from-config "$APP" "$SCHEME" "$app_vhost" "$DEFAULT_LISTEN_PORT" + done + else + if [[ -s "$DOKKU_ROOT/VHOST" ]]; then + while read -r VHOST || [[ -n "$VHOST" ]]; do + fn-domains-generate-urls-from-config "$APP" "$SCHEME" "$VHOST" "$DEFAULT_LISTEN_PORT" + done <"$DOKKU_ROOT/VHOST" + else + fn-domains-generate-urls-from-config "$APP" "$SCHEME" "$(hostname -f)" "$DEFAULT_LISTEN_PORT" + fi + fi +} + +fn-domains-generate-urls-from-config() { + declare APP="$1" SCHEME="$2" VHOST="$3" DEFAULT_LISTEN_PORT="$4" + local DOKKU_PROXY_PORT_MAP=$(plugn trigger config-get "$APP" DOKKU_PROXY_PORT_MAP || true) + local RAW_TCP_PORTS="$(get_app_raw_tcp_ports "$APP")" + + if [[ "$(plugn trigger proxy-is-enabled "$APP")" == "false" ]]; then + if [[ -n "$RAW_TCP_PORTS" ]]; then + local APP_CONTAINER_PORTS="$(get_container_ports "$APP")" + local app_port + for listen_port in $APP_CONTAINER_PORTS; do + fn-domains-generate-url "$SCHEME" "$VHOST" "$listen_port" + done + else + local DOKKU_APP_WEB_LISTENERS PORT + DOKKU_APP_WEB_LISTENERS="$(plugn trigger network-get-listeners "$APP" "web" | xargs)" + for DOKKU_APP_WEB_LISTENER in $DOKKU_APP_WEB_LISTENERS; do + listen_port="$(echo "$DOKKU_APP_WEB_LISTENER" | cut -d ':' -f2)" + fn-domains-generate-url "$SCHEME" "$VHOST" "$listen_port" + done + shopt -u nullglob + fi + elif [[ -n "$DOKKU_PROXY_PORT_MAP" ]]; then + local port_map + for port_map in $DOKKU_PROXY_PORT_MAP; do + local scheme="$(awk -F ':' '{ print $1 }' <<<"$port_map")" + local listen_port="$(awk -F ':' '{ print $2 }' <<<"$port_map")" + fn-domains-generate-url "$SCHEME" "$VHOST" "$listen_port" + done + elif [[ -n "$RAW_TCP_PORTS" ]]; then + for listen_port in $RAW_TCP_PORTS; do + fn-domains-generate-url "$SCHEME" "$VHOST" "$listen_port" + done + else + fn-domains-generate-url "$SCHEME" "$VHOST" "$DEFAULT_LISTEN_PORT" + fi +} + +fn-domains-generate-url() { + declare SCHEME="$1" VHOST="$2" PORT="$3" + if [[ "$PORT" == "80" ]]; then + echo "http://$VHOST" + elif [[ "$PORT" == "443" ]]; then + echo "https://$VHOST" + else + echo "$SCHEME://$VHOST:$PORT" + fi +} diff --git a/plugins/domains/post-app-clone-setup b/plugins/domains/post-app-clone-setup index 6b3968e21..5b136369a 100755 --- a/plugins/domains/post-app-clone-setup +++ b/plugins/domains/post-app-clone-setup @@ -8,7 +8,7 @@ trigger-domains-post-app-clone-setup() { declare OLD_APP="$1" NEW_APP="$2" local APP_ROOT="$DOKKU_ROOT/$NEW_APP" - rm -rf "$APP_ROOT/URLS" "$APP_ROOT/VHOST" + rm -rf "$APP_ROOT/VHOST" } trigger-domains-post-app-clone-setup "$@" diff --git a/plugins/domains/post-app-rename-setup b/plugins/domains/post-app-rename-setup index 9b710ac9a..7cbce6a11 100755 --- a/plugins/domains/post-app-rename-setup +++ b/plugins/domains/post-app-rename-setup @@ -3,12 +3,10 @@ set -eo pipefail [[ $DOKKU_TRACE ]] && set -x trigger-domains-post-app-rename-setup() { - declare desc="updates VHOST and URLS files during rename" + declare desc="updates VHOST files during rename" declare trigger="post-app-rename-setup" declare OLD_APP="$1" NEW_APP="$2" - rm -f "$DOKKU_ROOT/$NEW_APP/URLS" - if [[ -f "$DOKKU_ROOT/$NEW_APP/VHOST" ]]; then while read -r VHOST || [[ -n "$VHOST" ]]; do sed -i -e "s/$OLD_APP.$VHOST/$NEW_APP.$VHOST/g" "$DOKKU_ROOT/$NEW_APP/VHOST" diff --git a/plugins/nginx-vhosts/functions b/plugins/nginx-vhosts/functions index edb08da95..569de8b03 100755 --- a/plugins/nginx-vhosts/functions +++ b/plugins/nginx-vhosts/functions @@ -311,7 +311,6 @@ nginx_build_config() { declare desc="build nginx config to proxy app containers using sigil" declare APP="$1" DOKKU_APP_LISTEN_PORT="$2" DOKKU_APP_LISTEN_IP="$3" local VHOST_PATH="$DOKKU_ROOT/$APP/VHOST" - local APP_URLS_PATH="$DOKKU_ROOT/$APP/URLS" local NGINX_TEMPLATE_NAME="nginx.conf.sigil" local NGINX_TEMPLATE="$PLUGIN_AVAILABLE_PATH/nginx-vhosts/templates/$NGINX_TEMPLATE_NAME" local SCHEME=http @@ -329,7 +328,7 @@ nginx_build_config() { plugn trigger domains-vhost-enabled "$APP" 2>/dev/null || IS_APP_VHOST_ENABLED=false local IS_SSL_ENABLED=false - if is_ssl_enabled "$APP"; then + if [[ "$(plugn trigger certs-exists "$APP")" == "true" ]]; then IS_SSL_ENABLED=true fi @@ -516,11 +515,6 @@ nginx_build_config() { dokku_log_verbose "Reloading nginx" validate_nginx && restart_nginx >/dev/null fi - - if ([[ -n "$NONSSL_VHOSTS" ]] || [[ -n "$SSL_VHOSTS" ]]) && [[ "$IS_APP_VHOST_ENABLED" == "true" ]]; then - echo "# THIS FILE IS GENERATED BY DOKKU - DO NOT EDIT, YOUR CHANGES WILL BE OVERWRITTEN" >"$APP_URLS_PATH" - xargs -i echo "$SCHEME://{}" <<<"$(echo "${SSL_VHOSTS}" "${NONSSL_VHOSTS}" | tr ' ' '\n' | sort -u)" >>"$APP_URLS_PATH" - fi else # note because this clause is long. if the proxy is disabled: dokku_log_info1 "Nginx support is disabled for app ($APP)" diff --git a/plugins/proxy/proxy-configure-ports b/plugins/proxy/proxy-configure-ports index 67754a7c4..21c94a69e 100755 --- a/plugins/proxy/proxy-configure-ports +++ b/plugins/proxy/proxy-configure-ports @@ -1,6 +1,5 @@ #!/usr/bin/env bash source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" -source "$PLUGIN_AVAILABLE_PATH/certs/functions" source "$PLUGIN_AVAILABLE_PATH/config/functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x @@ -29,7 +28,7 @@ trigger-proxy-proxy-configure-ports() { DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" DOKKU_PROXY_PORT="$PROXY_PORT" fi if [[ -z "$DOKKU_PROXY_SSL_PORT" ]]; then - if (is_ssl_enabled "$APP"); then + if [[ "$(plugn trigger certs-exists "$APP")" == "true" ]]; then local PROXY_SSL_PORT=$(config_get --global DOKKU_PROXY_SSL_PORT) PROXY_SSL_PORT=${PROXY_SSL_PORT:=443} if [[ -z "$RAW_TCP_PORTS" ]] && [[ "$IS_APP_VHOST_ENABLED" == "false" ]]; then diff --git a/plugins/traefik-vhosts/docker-args-process-deploy b/plugins/traefik-vhosts/docker-args-process-deploy index 7eb3d2b47..c81248cea 100755 --- a/plugins/traefik-vhosts/docker-args-process-deploy +++ b/plugins/traefik-vhosts/docker-args-process-deploy @@ -11,7 +11,6 @@ trigger-traefik-vhosts-docker-args-process-deploy() { local app_domains is_app_listening letsencrypt_email output proxy_container_port proxy_host_port port_map proxy_port_map priority proxy_scheme proxy_schemes traefik_domains local proxy_container_http_port proxy_container_http_port_candidate proxy_host_http_port_candidate local proxy_container_https_port proxy_container_https_port_candidate proxy_host_https_port_candidate - local app_urls_path="$DOKKU_ROOT/$APP/URLS" local STDIN=$(cat) if [[ "$PROC_TYPE" != "web" ]]; then @@ -108,8 +107,6 @@ trigger-traefik-vhosts-docker-args-process-deploy() { 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=Host(\\\`$traefik_domains\\\`)\"" - echo "# THIS FILE IS GENERATED BY DOKKU - DO NOT EDIT, YOUR CHANGES WILL BE OVERWRITTEN" >"$app_urls_path" - xargs -I{} echo "http://{}" <<<"$(echo "${app_domains}" | tr ' ' '\n' | sort -u)" >>"$app_urls_path" fi fi @@ -127,8 +124,6 @@ trigger-traefik-vhosts-docker-args-process-deploy() { output="$output --label traefik.http.routers.$APP-$PROC_TYPE-https.tls.certresolver=leresolver" if [[ -n "$traefik_domains" ]]; then output="$output --label \"traefik.http.routers.$APP-$PROC_TYPE-https.rule=Host(\\\`$traefik_domains\\\`)\"" - echo "# THIS FILE IS GENERATED BY DOKKU - DO NOT EDIT, YOUR CHANGES WILL BE OVERWRITTEN" >"$app_urls_path" - xargs -I{} echo "https://{}" <<<"$(echo "${app_domains}" | tr ' ' '\n' | sort -u)" >>"$app_urls_path" fi fi fi diff --git a/tests/unit/apps_2.bats b/tests/unit/apps_2.bats index 2de337244..2afb61fa8 100644 --- a/tests/unit/apps_2.bats +++ b/tests/unit/apps_2.bats @@ -136,8 +136,6 @@ teardown() { assert_success run [ -d /home/dokku/great-test-name/tls ] assert_failure - run [ -f /home/dokku/great-test-name/URLS ] - assert_failure run [ -f /home/dokku/great-test-name/VHOST ] assert_failure run /bin/bash -c "curl --silent --write-out '%{http_code}\n' $(dokku url $TEST_APP) | grep 200" diff --git a/tests/unit/core_2.bats b/tests/unit/core_2.bats index 1a165098f..43c902616 100644 --- a/tests/unit/core_2.bats +++ b/tests/unit/core_2.bats @@ -39,33 +39,72 @@ teardown() { @test "(core) urls (non-ssl)" { assert_urls "http://${TEST_APP}.dokku.me" - add_domain "test.dokku.me" + dokku domains:add $TEST_APP "test.dokku.me" assert_urls "http://${TEST_APP}.dokku.me" "http://test.dokku.me" } @test "(core) urls (app ssl)" { assert_urls "http://${TEST_APP}.dokku.me" - setup_test_tls - dokku proxy:build-config "$TEST_APP" - assert_urls "http://${TEST_APP}.dokku.me" "https://${TEST_APP}.dokku.me" - add_domain "test.dokku.me" - assert_urls "http://${TEST_APP}.dokku.me" "http://test.dokku.me" "https://${TEST_APP}.dokku.me" "https://test.dokku.me" + + run setup_test_tls + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku proxy:build-config $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_success + + assert_urls "https://${TEST_APP}.dokku.me" + + run /bin/bash -c "dokku domains:add $TEST_APP test.dokku.me" + echo "output: $output" + echo "status: $status" + assert_success + + assert_urls "http://${TEST_APP}.dokku.me" "https://${TEST_APP}.dokku.me" "https://test.dokku.me" "http://test.dokku.me" } @test "(core) url (app ssl)" { - setup_test_tls - dokku proxy:build-config "$TEST_APP" + run setup_test_tls + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku proxy:build-config $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_success + assert_url "https://${TEST_APP}.dokku.me" } @test "(core) urls (wildcard ssl)" { - setup_test_tls wildcard - dokku proxy:build-config "$TEST_APP" - assert_urls "http://${TEST_APP}.dokku.me" "https://${TEST_APP}.dokku.me" - add_domain "test.dokku.me" - assert_urls "http://${TEST_APP}.dokku.me" "http://test.dokku.me" "https://${TEST_APP}.dokku.me" "https://test.dokku.me" - add_domain "dokku.example.com" - assert_urls "http://dokku.example.com" "http://${TEST_APP}.dokku.me" "http://test.dokku.me" "https://dokku.example.com" "https://${TEST_APP}.dokku.me" "https://test.dokku.me" + run setup_test_tls wildcard + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku proxy:build-config $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_success + + assert_urls "https://${TEST_APP}.dokku.me" + + run /bin/bash -c "dokku domains:add $TEST_APP test.dokku.me" + echo "output: $output" + echo "status: $status" + assert_success + + assert_urls "http://${TEST_APP}.dokku.me" "https://${TEST_APP}.dokku.me" "https://test.dokku.me" "http://test.dokku.me" + + run /bin/bash -c "dokku domains:add $TEST_APP dokku.example.com" + echo "output: $output" + echo "status: $status" + assert_success + assert_urls "http://dokku.example.com" "http://${TEST_APP}.dokku.me" "https://dokku.example.com" "https://${TEST_APP}.dokku.me" "https://test.dokku.me" "http://test.dokku.me" } @test "(core) git-remote (off-port)" { diff --git a/tests/unit/nginx-vhosts_2.bats b/tests/unit/nginx-vhosts_2.bats index f8f26ea5c..5f122c9d6 100644 --- a/tests/unit/nginx-vhosts_2.bats +++ b/tests/unit/nginx-vhosts_2.bats @@ -16,8 +16,8 @@ teardown() { @test "(nginx-vhosts) nginx:build-config (with SSL and unrelated domain)" { setup_test_tls - add_domain "node-js-app.dokku.me" - add_domain "test.dokku.me" + dokku domains:add $TEST_APP "node-js-app.dokku.me" + dokku domains:add $TEST_APP "test.dokku.me" deploy_app dokku nginx:show-config $TEST_APP assert_ssl_domain "node-js-app.dokku.me" @@ -26,8 +26,8 @@ teardown() { @test "(nginx-vhosts) nginx:build-config (wildcard SSL)" { setup_test_tls wildcard - add_domain "wildcard1.dokku.me" - add_domain "wildcard2.dokku.me" + dokku domains:add $TEST_APP "wildcard1.dokku.me" + dokku domains:add $TEST_APP "wildcard2.dokku.me" deploy_app dokku nginx:show-config $TEST_APP assert_ssl_domain "wildcard1.dokku.me" @@ -51,9 +51,9 @@ teardown() { @test "(nginx-vhosts) nginx:build-config (with SSL and Multiple SANs)" { setup_test_tls sans - add_domain "test.dokku.me" - add_domain "www.test.dokku.me" - add_domain "www.test.app.dokku.me" + dokku domains:add $TEST_APP "test.dokku.me" + dokku domains:add $TEST_APP "www.test.dokku.me" + dokku domains:add $TEST_APP "www.test.app.dokku.me" deploy_app assert_ssl_domain "test.dokku.me" assert_ssl_domain "www.test.dokku.me" diff --git a/tests/unit/nginx-vhosts_4.bats b/tests/unit/nginx-vhosts_4.bats index cb9e09837..f02bb570a 100644 --- a/tests/unit/nginx-vhosts_4.bats +++ b/tests/unit/nginx-vhosts_4.bats @@ -58,7 +58,7 @@ teardown() { @test "(nginx-vhosts) nginx:build-config (without global VHOST and domains:add pre deploy)" { rm "$DOKKU_ROOT/VHOST" create_app - add_domain "www.test.app.dokku.me" + dokku domains:add $TEST_APP "www.test.app.dokku.me" deploy_app assert_nonssl_domain "www.test.app.dokku.me" } @@ -66,7 +66,7 @@ teardown() { @test "(nginx-vhosts) nginx:build-config (without global VHOST and domains:add post deploy)" { rm "$DOKKU_ROOT/VHOST" deploy_app - add_domain "www.test.app.dokku.me" + dokku domains:add $TEST_APP "www.test.app.dokku.me" check_urls http://www.test.app.dokku.me assert_http_success http://www.test.app.dokku.me } diff --git a/tests/unit/nginx-vhosts_5.bats b/tests/unit/nginx-vhosts_5.bats index 0e65a35be..c171fa262 100644 --- a/tests/unit/nginx-vhosts_5.bats +++ b/tests/unit/nginx-vhosts_5.bats @@ -26,7 +26,7 @@ teardown() { @test "(nginx-vhosts) nginx:build-config (dockerfile expose)" { deploy_app dockerfile - add_domain "www.test.app.dokku.me" + dokku domains:add $TEST_APP "www.test.app.dokku.me" check_urls http://${TEST_APP}.dokku.me:3000 check_urls http://${TEST_APP}.dokku.me:3003 check_urls http://www.test.app.dokku.me:3000 diff --git a/tests/unit/nginx-vhosts_7.bats b/tests/unit/nginx-vhosts_7.bats index 52417e403..2812b4b18 100644 --- a/tests/unit/nginx-vhosts_7.bats +++ b/tests/unit/nginx-vhosts_7.bats @@ -16,8 +16,8 @@ teardown() { @test "(nginx-vhosts) nginx:build-config (wildcard SSL and custom nginx template)" { setup_test_tls wildcard - add_domain "wildcard1.dokku.me" - add_domain "wildcard2.dokku.me" + dokku domains:add $TEST_APP "wildcard1.dokku.me" + dokku domains:add $TEST_APP "wildcard2.dokku.me" deploy_app nodejs-express dokku@dokku.me:$TEST_APP custom_ssl_nginx_template assert_ssl_domain "wildcard1.dokku.me" @@ -27,7 +27,7 @@ teardown() { } @test "(nginx-vhosts) nginx:build-config (custom nginx template - no ssl)" { - add_domain "www.test.app.dokku.me" + dokku domains:add $TEST_APP "www.test.app.dokku.me" run deploy_app nodejs-express dokku@dokku.me:$TEST_APP custom_nginx_template echo "output: $output" echo "status: $status" @@ -53,7 +53,7 @@ teardown() { echo "status: $status" assert_success - add_domain "www.test.app.dokku.me" + dokku domains:add $TEST_APP "www.test.app.dokku.me" run deploy_app nodejs-express dokku@dokku.me:$TEST_APP custom_nginx_template echo "output: $output" echo "status: $status" diff --git a/tests/unit/nginx-vhosts_9.bats b/tests/unit/nginx-vhosts_9.bats index 552ba2785..45d7d66fc 100644 --- a/tests/unit/nginx-vhosts_9.bats +++ b/tests/unit/nginx-vhosts_9.bats @@ -154,8 +154,8 @@ teardown() { @test "(nginx-vhosts) nginx:build-config (with SSL and unrelated domain)" { setup_test_tls - add_domain "node-js-app.dokku.me" - add_domain "test.dokku.me" + dokku domains:add $TEST_APP "node-js-app.dokku.me" + dokku domains:add $TEST_APP "test.dokku.me" deploy_app dokku nginx:show-config $TEST_APP assert_ssl_domain "node-js-app.dokku.me" @@ -164,8 +164,8 @@ teardown() { @test "(nginx-vhosts) nginx:build-config (wildcard SSL)" { setup_test_tls wildcard - add_domain "wildcard1.dokku.me" - add_domain "wildcard2.dokku.me" + dokku domains:add $TEST_APP "wildcard1.dokku.me" + dokku domains:add $TEST_APP "wildcard2.dokku.me" deploy_app dokku nginx:show-config $TEST_APP assert_ssl_domain "wildcard1.dokku.me" diff --git a/tests/unit/test_helper.bash b/tests/unit/test_helper.bash index 6f86edeea..444280bdd 100644 --- a/tests/unit/test_helper.bash +++ b/tests/unit/test_helper.bash @@ -218,10 +218,6 @@ destroy_key() { rm -f /tmp/testkey* &>/dev/null || true } -add_domain() { - dokku domains:add "$TEST_APP" "$1" -} - # shellcheck disable=SC2119 check_urls() { local PATTERN="$1" @@ -288,10 +284,14 @@ assert_not_external_port() { assert_url() { url="$1" - run /bin/bash -c "dokku url $TEST_APP" + run /bin/bash -c "dokku url $TEST_APP | xargs" + echo "VHOST: $(cat $DOKKU_ROOT/$TEST_APP/VHOST | xargs)" + echo "tls: $(ls $DOKKU_ROOT/$TEST_APP/tls || true)" + echo "proxy-is-enabled: $(dokku plugin:trigger proxy-is-enabled "$TEST_APP")" + echo "port-map: $(dokku config:get "$TEST_APP" DOKKU_PROXY_PORT_MAP)" + echo "url: $(dokku urls $TEST_APP)" echo "output: $output" echo "status: $status" - echo "url: ${url}" assert_output "${url}" } @@ -299,9 +299,13 @@ assert_urls() { # shellcheck disable=SC2124 urls="$@" run /bin/bash -c "dokku urls $TEST_APP | xargs" + echo "VHOST: $(cat $DOKKU_ROOT/$TEST_APP/VHOST | xargs)" + echo "tls: $(ls $DOKKU_ROOT/$TEST_APP/tls || true)" + echo "proxy-is-enabled: $(dokku plugin:trigger proxy-is-enabled "$TEST_APP")" + echo "port-map: $(dokku config:get "$TEST_APP" DOKKU_PROXY_PORT_MAP)" + echo "urls: $(dokku urls $TEST_APP)" echo "output: $output" echo "status: $status" - echo "urls:" "$urls" assert_output "$urls" } From 1dda40276992ccc910776fbee62ef13006e26635 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 2 Dec 2022 02:33:54 -0500 Subject: [PATCH 09/13] fix: do not depend upon domains:setup in tests Since it is now called on app creation, it doesn't work as expected for 'resetting' already set state. --- tests/unit/domains.bats | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tests/unit/domains.bats b/tests/unit/domains.bats index 82b22d2e9..dc40acc44 100644 --- a/tests/unit/domains.bats +++ b/tests/unit/domains.bats @@ -29,7 +29,6 @@ teardown() { } @test "(domains) domains" { - dokku domains:setup $TEST_APP run /bin/bash -c "dokku domains:report $TEST_APP 2>/dev/null | grep ${TEST_APP}.dokku.me" echo "output: $output" echo "status: $status" @@ -282,7 +281,15 @@ teardown() { echo "status: $status" assert_success - dokku domains:setup $TEST_APP + run destroy_app + echo "output: $output" + echo "status: $status" + assert_success + + run create_app + echo "output: $output" + echo "status: $status" + assert_success run /bin/bash -c "dokku domains:report $TEST_APP 2>/dev/null" echo "output: $output" @@ -303,7 +310,15 @@ teardown() { echo "status: $status" assert_success - dokku domains:setup $TEST_APP + run destroy_app + echo "output: $output" + echo "status: $status" + assert_success + + run create_app + echo "output: $output" + echo "status: $status" + assert_success run /bin/bash -c "dokku domains:report $TEST_APP 2>/dev/null" echo "output: $output" From a2cc6b84d6498181e0f9889afc8c3a95d0a96034 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 2 Dec 2022 10:47:40 -0500 Subject: [PATCH 10/13] fix: use assert_output_contains so as not to worry about order --- tests/unit/test_helper.bash | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/unit/test_helper.bash b/tests/unit/test_helper.bash index 444280bdd..36e516c5b 100644 --- a/tests/unit/test_helper.bash +++ b/tests/unit/test_helper.bash @@ -306,7 +306,9 @@ assert_urls() { echo "urls: $(dokku urls $TEST_APP)" echo "output: $output" echo "status: $status" - assert_output "$urls" + for url in "$@"; do + assert_output_contains "$url" + done } deploy_app() { From c2ebf48524dfca9aef9ad344a88038836b1ac459 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 2 Dec 2022 15:54:48 -0500 Subject: [PATCH 11/13] refactor: use a single implementation for checking cnb/herokuish images Also use a plugin trigger for testing whether an image is herokuish or not rather than trying to mess around with sourced files. --- docs/development/plugin-triggers.md | 42 +++++++++++++++++--- plugins/20_events/builder-image-is-cnb | 1 + plugins/20_events/builder-image-is-herokuish | 1 + plugins/builder/.gitignore | 2 +- plugins/builder/Makefile | 2 +- plugins/builder/src/triggers/triggers.go | 8 ++++ plugins/builder/triggers.go | 22 ++++++++++ plugins/common/functions | 28 ++----------- plugins/common/src/common/common.go | 15 +++++++ tests/unit/core_1.bats | 37 +++++++++-------- 10 files changed, 108 insertions(+), 50 deletions(-) create mode 120000 plugins/20_events/builder-image-is-cnb create mode 120000 plugins/20_events/builder-image-is-herokuish diff --git a/docs/development/plugin-triggers.md b/docs/development/plugin-triggers.md index 81a14ae57..a001ab3fa 100644 --- a/docs/development/plugin-triggers.md +++ b/docs/development/plugin-triggers.md @@ -173,6 +173,21 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x # TODO ``` +### `builder-create-dokku-image` + +- Description: Allows modification of the configured dokku-image +- Invoked by: `dokku deploy` +- Arguments: `$BUILDER_TYPE` `$APP` `$SOURCECODE_WORK_DIR` `$DOKKU_IMAGE` +- Example: + +```shell +#!/usr/bin/env bash + +set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x + +# TODO +``` + ### `builder-detect` - Description: Allows overriding the auto-detected `herokuish` builder in favor of a custom one. Dockerfile gets lowest builder precedence. @@ -191,9 +206,9 @@ if [[ -f "$SOURCECODE_WORK_DIR/project.toml" ]]; then fi ``` -### `builder-create-dokku-image` +### `builder-dokku-image` -- Description: Allows modification of the configured dokku-image +- Description: Allows modification of the used dokku-image. - Invoked by: `dokku deploy` - Arguments: `$BUILDER_TYPE` `$APP` `$SOURCECODE_WORK_DIR` `$DOKKU_IMAGE` - Example: @@ -206,11 +221,26 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x # TODO ``` -### `builder-dokku-image` +### `builder-image-is-cnb` -- Description: Allows modification of the used dokku-image. -- Invoked by: `dokku deploy` -- Arguments: `$BUILDER_TYPE` `$APP` `$SOURCECODE_WORK_DIR` `$DOKKU_IMAGE` +- Description: Checks if an image is cnb-based +- Invoked by: unit tests +- Arguments: `$APP` `$IMAGE_TAG` +- Example: + +```shell +#!/usr/bin/env bash + +set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x + +# TODO +``` + +### `builder-image-is-herokuish` + +- Description: Checks if an image is herokuish-based +- Invoked by: unit tests +- Arguments: `$APP` `$IMAGE_TAG` - Example: ```shell diff --git a/plugins/20_events/builder-image-is-cnb b/plugins/20_events/builder-image-is-cnb new file mode 120000 index 000000000..5178a749f --- /dev/null +++ b/plugins/20_events/builder-image-is-cnb @@ -0,0 +1 @@ +hook \ No newline at end of file diff --git a/plugins/20_events/builder-image-is-herokuish b/plugins/20_events/builder-image-is-herokuish new file mode 120000 index 000000000..5178a749f --- /dev/null +++ b/plugins/20_events/builder-image-is-herokuish @@ -0,0 +1 @@ +hook \ No newline at end of file diff --git a/plugins/builder/.gitignore b/plugins/builder/.gitignore index 6f788ece8..1dd54d973 100644 --- a/plugins/builder/.gitignore +++ b/plugins/builder/.gitignore @@ -7,4 +7,4 @@ /install /post-* /report -/builder-detect +/builder-* diff --git a/plugins/builder/Makefile b/plugins/builder/Makefile index b8a598628..2b9139e04 100644 --- a/plugins/builder/Makefile +++ b/plugins/builder/Makefile @@ -1,5 +1,5 @@ SUBCOMMANDS = subcommands/report subcommands/set -TRIGGERS = triggers/builder-detect triggers/core-post-extract triggers/install triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-delete triggers/report +TRIGGERS = triggers/builder-detect triggers/builder-image-is-cnb triggers/builder-image-is-herokuish triggers/core-post-extract triggers/install triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-delete triggers/report BUILD = commands subcommands triggers PLUGIN_NAME = builder diff --git a/plugins/builder/src/triggers/triggers.go b/plugins/builder/src/triggers/triggers.go index 56c623a05..25fba8921 100644 --- a/plugins/builder/src/triggers/triggers.go +++ b/plugins/builder/src/triggers/triggers.go @@ -21,6 +21,14 @@ func main() { case "builder-detect": appName := flag.Arg(0) err = builder.TriggerBuilderDetect(appName) + case "builder-image-is-cnb": + appName := flag.Arg(0) + image := flag.Arg(1) + err = builder.TriggerBuilderImageIsCNB(appName, image) + case "builder-image-is-herokuish": + appName := flag.Arg(0) + image := flag.Arg(1) + err = builder.TriggerBuilderImageIsHerokuish(appName, image) case "core-post-extract": appName := flag.Arg(0) sourceWorkDir := flag.Arg(1) diff --git a/plugins/builder/triggers.go b/plugins/builder/triggers.go index 8a0b7f5af..0ce1e6454 100644 --- a/plugins/builder/triggers.go +++ b/plugins/builder/triggers.go @@ -26,6 +26,28 @@ func TriggerBuilderDetect(appName string) error { return nil } +// TriggerBuilderImageIsCNB prints true if an image is cnb based, false otherwise +func TriggerBuilderImageIsCNB(appName string, image string) error { + if common.IsImageCnbBased(image) { + fmt.Println("true") + } else { + fmt.Println("false") + } + + return nil +} + +// TriggerBuilderImageIsHerokuish prints true if an image is herokuish based, false otherwise +func TriggerBuilderImageIsHerokuish(appName string, image string) error { + if common.IsImageHerokuishBased(image, appName) { + fmt.Println("true") + } else { + fmt.Println("false") + } + + return nil +} + // TriggerCorePostExtract moves a configured build-dir to be in the app root dir func TriggerCorePostExtract(appName string, sourceWorkDir string) error { buildDir := strings.Trim(reportComputedBuildDir(appName), "/") diff --git a/plugins/common/functions b/plugins/common/functions index a7ef0324d..3e0b6daf0 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -357,41 +357,19 @@ is_image_cnb_based() { declare desc="returns true if app image is based on cnb" declare IMAGE="$1" - if [[ -z "$IMAGE" ]]; then + + if [[ "$("$PLUGIN_CORE_AVAILABLE_PATH/common/common" --quiet image-is-cnb-based "$IMAGE")" != "true" ]]; then return 1 fi - - CNB_STACK_ID="$("$DOCKER_BIN" image inspect --format '{{ index .Config.Labels "io.buildpacks.stack.id" }}' "$IMAGE")" - if [[ -n "$CNB_STACK_ID" ]]; then - return 0 - fi - - return 1 } is_image_herokuish_based() { declare desc="returns true if app image is based on herokuish or a buildpack-like env" declare IMAGE="$1" APP="$2" - local DOKKU_APP_USER - local USER_VALUE - if [[ -z "$IMAGE" ]]; then + if [[ "$("$PLUGIN_CORE_AVAILABLE_PATH/common/common" --quiet image-is-herokuish-based "$IMAGE" "$APP")" != "true" ]]; then return 1 fi - - if is_image_cnb_based "$IMAGE"; then - return 0 - fi - - if [[ -n "$APP" ]]; then - DOKKU_APP_USER=$(plugn trigger config-get "$APP" DOKKU_APP_USER || true) - fi - DOKKU_APP_USER=${DOKKU_APP_USER:="herokuishuser"} - - # due to how the build process works, all herokuish images have the Environment variable USER=$DOKKU_APP_USER - USER_VALUE="$("$DOCKER_BIN" image inspect --format '{{range .Config.Env}}{{if eq . "USER='"$DOKKU_APP_USER"'"}}{{println .}}{{end}}{{end}}' "$IMAGE")" - [[ "$USER_VALUE" == "" ]] && return 1 - return 0 } get_docker_version() { diff --git a/plugins/common/src/common/common.go b/plugins/common/src/common/common.go index 4b4c078dc..25095fde1 100644 --- a/plugins/common/src/common/common.go +++ b/plugins/common/src/common/common.go @@ -32,6 +32,21 @@ func main() { if !common.IsDeployed(appName) { err = fmt.Errorf("App %v not deployed", appName) } + case "image-is-cnb-based": + image := flag.Arg(1) + if common.IsImageCnbBased(image) { + fmt.Print("true") + } else { + fmt.Print("false") + } + case "image-is-herokuish-based": + image := flag.Arg(1) + appName := flag.Arg(2) + if common.IsImageHerokuishBased(image, appName) { + fmt.Print("true") + } else { + fmt.Print("false") + } case "scheduler-detect": appName := flag.Arg(1) if *global { diff --git a/tests/unit/core_1.bats b/tests/unit/core_1.bats index 9939e3fc6..9d2413484 100644 --- a/tests/unit/core_1.bats +++ b/tests/unit/core_1.bats @@ -70,40 +70,43 @@ EOF } @test "(core) image type detection (herokuish default user)" { - export DOKKU_ROOT - deploy_app - source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" - source "$PLUGIN_CORE_AVAILABLE_PATH/config/functions" - - run is_image_herokuish_based "dokku/$TEST_APP" "$TEST_APP" + run deploy_app echo "output: $output" echo "status: $status" assert_success + + run /bin/bash -c "dokku plugin:trigger builder-image-is-herokuish $TEST_APP dokku/$TEST_APP" + echo "output: $output" + echo "status: $status" + assert_output "true" } @test "(core) image type detection (herokuish custom user)" { - export DOKKU_ROOT - deploy_app + run deploy_app + echo "output: $output" + echo "status: $status" + assert_success + CID=$(<"$DOKKU_ROOT/$TEST_APP/CONTAINER.web.1") docker commit --change "ENV USER postgres" "$CID" "dokku/${TEST_APP}:latest" dokku config:set --no-restart "$TEST_APP" DOKKU_APP_USER=postgres source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/config/functions" - run is_image_herokuish_based "dokku/$TEST_APP" "$TEST_APP" + run /bin/bash -c "dokku plugin:trigger builder-image-is-herokuish $TEST_APP dokku/$TEST_APP" echo "output: $output" echo "status: $status" - assert_success + assert_output "true" } @test "(core) image type detection (dockerfile)" { - export DOKKU_ROOT - deploy_app dockerfile - source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" - source "$PLUGIN_CORE_AVAILABLE_PATH/config/functions" - - run is_image_herokuish_based "dokku/$TEST_APP" "$TEST_APP" + run deploy_app dockerfile echo "output: $output" echo "status: $status" - assert_failure + assert_success + + run /bin/bash -c "dokku plugin:trigger builder-image-is-herokuish $TEST_APP dokku/$TEST_APP" + echo "output: $output" + echo "status: $status" + assert_output "false" } From ecae13ba842de9e7230bc8209a80eb8656f52d94 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 2 Dec 2022 15:55:49 -0500 Subject: [PATCH 12/13] fix: update event hooks --- plugins/20_events/{domains-setup => certs-exists} | 0 plugins/20_events/domains-urls | 1 + 2 files changed, 1 insertion(+) rename plugins/20_events/{domains-setup => certs-exists} (100%) create mode 120000 plugins/20_events/domains-urls diff --git a/plugins/20_events/domains-setup b/plugins/20_events/certs-exists similarity index 100% rename from plugins/20_events/domains-setup rename to plugins/20_events/certs-exists diff --git a/plugins/20_events/domains-urls b/plugins/20_events/domains-urls new file mode 120000 index 000000000..5178a749f --- /dev/null +++ b/plugins/20_events/domains-urls @@ -0,0 +1 @@ +hook \ No newline at end of file From 80fd9bbd4b58e914b418a03450af787ae8781bd1 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 2 Dec 2022 16:00:32 -0500 Subject: [PATCH 13/13] fix: run linting --- plugins/common/functions | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/common/functions b/plugins/common/functions index 3e0b6daf0..fb1232b86 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -357,7 +357,6 @@ is_image_cnb_based() { declare desc="returns true if app image is based on cnb" declare IMAGE="$1" - if [[ "$("$PLUGIN_CORE_AVAILABLE_PATH/common/common" --quiet image-is-cnb-based "$IMAGE")" != "true" ]]; then return 1 fi