From 5d36264dd273a99f3dd0a5e6e451767636ca2c96 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 May 2022 13:20:54 +0000 Subject: [PATCH 01/18] chore(deps-dev): bump heroku/heroku-buildpack-php in /tests/apps/php Bumps [heroku/heroku-buildpack-php](https://github.com/heroku/heroku-buildpack-php) from 216 to 217. - [Release notes](https://github.com/heroku/heroku-buildpack-php/releases) - [Changelog](https://github.com/heroku/heroku-buildpack-php/blob/main/CHANGELOG.md) - [Commits](https://github.com/heroku/heroku-buildpack-php/compare/v216...v217) --- updated-dependencies: - dependency-name: heroku/heroku-buildpack-php dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- tests/apps/php/composer.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/apps/php/composer.lock b/tests/apps/php/composer.lock index 73f880b7d..506a0e0e0 100644 --- a/tests/apps/php/composer.lock +++ b/tests/apps/php/composer.lock @@ -1000,16 +1000,16 @@ "packages-dev": [ { "name": "heroku/heroku-buildpack-php", - "version": "v216", + "version": "v217", "source": { "type": "git", "url": "https://github.com/heroku/heroku-buildpack-php.git", - "reference": "78a95ba0abdadf2546178d5a2f9ab8d9dcac092d" + "reference": "5e95230f28b8d2375b27cc54cf3d78ef885f5b78" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/heroku/heroku-buildpack-php/zipball/78a95ba0abdadf2546178d5a2f9ab8d9dcac092d", - "reference": "78a95ba0abdadf2546178d5a2f9ab8d9dcac092d", + "url": "https://api.github.com/repos/heroku/heroku-buildpack-php/zipball/5e95230f28b8d2375b27cc54cf3d78ef885f5b78", + "reference": "5e95230f28b8d2375b27cc54cf3d78ef885f5b78", "shasum": "" }, "bin": [ @@ -1037,7 +1037,7 @@ "nginx", "php" ], - "time": "2022-04-14T16:00:42+00:00" + "time": "2022-05-18T19:16:45+00:00" } ], "aliases": [], From a937e6de50d87ce8e0256e266475004354c9f318 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sat, 21 May 2022 02:47:06 -0400 Subject: [PATCH 02/18] fix: confirm installation of universe packages when installing on ubuntu This fixes installs stalling on Ubuntu 22.04 because of necessary confirmation of the addition. Closes #5191 --- bootstrap.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap.sh b/bootstrap.sh index f1780bd4f..dac9ee095 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -63,7 +63,7 @@ install-requirements() { apt-get -qq -y --no-install-recommends install software-properties-common fi - add-apt-repository universe >/dev/null + add-apt-repository -y universe >/dev/null apt-get update -qq >/dev/null ;; esac From 88c1abc608543f859da9bb454cb1c42bdc6ead33 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sat, 21 May 2022 03:43:32 -0400 Subject: [PATCH 03/18] fix: force-set correct permissions on env files If an env file is written as a root user - for example, during plugin install - the permissions on the file may change to root. This forces those permissions back to what they should be so that the dokku user can edit the files later on. Closes #5190 --- plugins/config/config.go | 3 +++ plugins/config/environment.go | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/plugins/config/config.go b/plugins/config/config.go index 17b478cc8..8c50e73ab 100644 --- a/plugins/config/config.go +++ b/plugins/config/config.go @@ -52,6 +52,7 @@ func SetMany(appName string, entries map[string]string, restart bool) (err error fmt.Println(prettyPrintEnvEntries(" ", entries)) } env.Write() + common.SetPermissions(env.Filename(), 0600) triggerUpdate(appName, "set", keys) } if !global && restart && env.GetBoolDefault("DOKKU_APP_RESTORE", true) { @@ -84,6 +85,7 @@ func UnsetMany(appName string, keys []string, restart bool) (err error) { } if changed { env.Write() + common.SetPermissions(env.Filename(), 0600) triggerUpdate(appName, "unset", keys) } if !global && restart && env.GetBoolDefault("DOKKU_APP_RESTORE", true) { @@ -107,6 +109,7 @@ func UnsetAll(appName string, restart bool) (err error) { } if changed { env.Write() + common.SetPermissions(env.Filename(), 0600) triggerUpdate(appName, "clear", []string{}) } if !global && restart && env.GetBoolDefault("DOKKU_APP_RESTORE", true) { diff --git a/plugins/config/environment.go b/plugins/config/environment.go index ffd0daf28..8e26f0a80 100644 --- a/plugins/config/environment.go +++ b/plugins/config/environment.go @@ -92,6 +92,11 @@ func LoadGlobalEnv() (*Env, error) { return loadFromFile("", getGlobalFile()) } +// Filename returns the full path on disk to the file holding the env vars +func (e *Env) Filename() string { + return e.filename +} + //Get an environment variable func (e *Env) Get(key string) (value string, ok bool) { value, ok = e.env[key] From 6f5f3fa908908c8a74833d51297f3005fdf51def Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sat, 21 May 2022 13:42:45 -0400 Subject: [PATCH 04/18] feat: upgrade base Dockerfile image to phusion/baseimage:focal-1.2.0 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 5fe94a8ae..748c4f34c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM phusion/baseimage:focal-1.1.0 +FROM phusion/baseimage:focal-1.2.0 CMD ["/sbin/my_init"] From 27769f54b0a641daa3708215e70c1b27a7972914 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 22 May 2022 17:12:52 -0400 Subject: [PATCH 05/18] feat: disable herokuish usage on both armhf and arm64 platforms We will not provide support for herokuish on either as herokuish is meant to be Heroku-compatible, and the Heroku stack does not support arm. Use 'pack' or Dockerfiles for app building instead. --- plugins/00_dokku-standard/subcommands/report | 5 +++-- plugins/builder-herokuish/builder-detect | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/00_dokku-standard/subcommands/report b/plugins/00_dokku-standard/subcommands/report index 63e769db5..8acd5ed8f 100755 --- a/plugins/00_dokku-standard/subcommands/report +++ b/plugins/00_dokku-standard/subcommands/report @@ -8,6 +8,7 @@ cmd-report() { declare cmd="report" [[ "$1" == "$cmd" ]] && shift 1 declare APP="$1" + local ARCHITECTURE="$(dpkg --print-architecture 2>/dev/null || true)" if [[ "$APP" == "--format" ]]; then dokku_log_fail "--format flag not supported on global report" @@ -23,8 +24,8 @@ cmd-report() { dokku_log_info1 "git version: $(git --version)" dokku_log_info1 "sigil version: $(sigil -v)" dokku_log_info1 "herokuish version: " - if [[ "$(dpkg --print-architecture 2>/dev/null || true)" == "armhf" ]]; then - dokku_log_warn "herokuish not supported on armhf architecture" + if [[ "$ARCHITECTURE" == "armhf" ]] || [[ "$ARCHITECTURE" == "arm64" ]]; then + dokku_log_warn "herokuish not supported on $ARCHITECTURE architecture" else "$DOCKER_BIN" container run $DOKKU_GLOBAL_RUN_ARGS --rm "$DOKKU_IMAGE" herokuish version | sed "s/^/ /" fi diff --git a/plugins/builder-herokuish/builder-detect b/plugins/builder-herokuish/builder-detect index 63d291499..fc6fee428 100755 --- a/plugins/builder-herokuish/builder-detect +++ b/plugins/builder-herokuish/builder-detect @@ -7,8 +7,9 @@ trigger-builder-herokuish-builder-detect() { declare desc="builder-herokuish builder-detect plugin trigger" declare trigger="builder-detect" declare APP="$1" SOURCECODE_WORK_DIR="$2" + local ARCHITECTURE="$(dpkg --print-architecture 2>/dev/null || true)" - if [[ "$(dpkg --print-architecture 2>/dev/null || true)" == "armhf" ]]; then + if [[ "$ARCHITECTURE" == "armhf" ]] || [[ "$ARCHITECTURE" == "arm64" ]]; then return fi From 0a895b2d1144e794ce7f3f87f6009e4e7ce445b7 Mon Sep 17 00:00:00 2001 From: Pablo Orellana Date: Wed, 25 May 2022 07:44:38 +0200 Subject: [PATCH 06/18] remove --watch-config argument on startVectorContainer --- plugins/logs/functions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/logs/functions.go b/plugins/logs/functions.go index 0682aec37..488590b9d 100644 --- a/plugins/logs/functions.go +++ b/plugins/logs/functions.go @@ -77,7 +77,7 @@ func startVectorContainer(vectorImage string) error { "--volume", common.MustGetEnv("DOKKU_LOGS_HOST_DIR") + ":/var/logs/dokku/apps", "--volume", common.MustGetEnv("DOKKU_LOGS_HOST_DIR") + "/apps:/var/log/dokku/apps", vectorImage, - "--config", "/etc/vector/vector.json", "--watch-config", "1"}, " ")) + "--config", "/etc/vector/vector.json", "--watch-config"}, " ")) cmd.ShowOutput = false if !cmd.Execute() { From 2ba5c9df508a5c3f742ce7bf307c903b3635948b Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Thu, 26 May 2022 10:22:32 -0400 Subject: [PATCH 07/18] Revert "fix: Vector fails to start container due to --watch-config flag" --- plugins/logs/functions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/logs/functions.go b/plugins/logs/functions.go index 488590b9d..0682aec37 100644 --- a/plugins/logs/functions.go +++ b/plugins/logs/functions.go @@ -77,7 +77,7 @@ func startVectorContainer(vectorImage string) error { "--volume", common.MustGetEnv("DOKKU_LOGS_HOST_DIR") + ":/var/logs/dokku/apps", "--volume", common.MustGetEnv("DOKKU_LOGS_HOST_DIR") + "/apps:/var/log/dokku/apps", vectorImage, - "--config", "/etc/vector/vector.json", "--watch-config"}, " ")) + "--config", "/etc/vector/vector.json", "--watch-config", "1"}, " ")) cmd.ShowOutput = false if !cmd.Execute() { From b3d7174a7aafa4e211f813e36463ce93fa16ef1c Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 16 May 2022 00:56:18 -0400 Subject: [PATCH 08/18] fix: filter apps when verifying app names This ensures folks can't interact with apps that are hidden from them via the filtering performed in app listing. --- plugins/common/common.go | 5 +++++ plugins/common/functions | 23 ++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/plugins/common/common.go b/plugins/common/common.go index 4039fe7d2..091f15451 100644 --- a/plugins/common/common.go +++ b/plugins/common/common.go @@ -581,6 +581,11 @@ func VerifyAppName(appName string) error { return &AppDoesNotExist{appName} } + apps, _ := filterApps([]string{appName}) + if len(apps) != 1 { + return &AppDoesNotExist{appName} + } + return nil } diff --git a/plugins/common/functions b/plugins/common/functions index 181fccb27..0b4b0c0d0 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -250,6 +250,9 @@ is_valid_app_name_old() { verify_app_name() { declare desc="verify app name format and app existence" declare APP="$1" + export SSH_USER=${SSH_USER:=$USER} + export SSH_NAME=${NAME:="default"} + local VALID_NEW=false local VALID_OLD=false if fn-is-valid-app-name "$APP" 2>/dev/null; then @@ -266,7 +269,25 @@ verify_app_name() { [[ ! -d "$DOKKU_ROOT/$APP" ]] && DOKKU_FAIL_EXIT_CODE=20 dokku_log_fail "App $APP does not exist" - return 0 + local user_auth_count=$(find "$PLUGIN_PATH"/enabled/*/user-auth-app 2>/dev/null | wc -l) + + # no plugin trigger exists + if [[ $user_auth_count == 0 ]]; then + return 0 + fi + + # this plugin trigger exists in the core `20_events` plugin + if [[ "$user_auth_count" == 1 ]] && [[ -f "$PLUGIN_PATH"/enabled/20_events/user-auth-app ]]; then + return 0 + fi + + if output="$(plugn trigger user-auth-app "$SSH_USER" "$SSH_NAME" "$@" "$APP")"; then + if [[ -n "$output" ]]; then + return 0 + fi + fi + + DOKKU_FAIL_EXIT_CODE=20 dokku_log_fail "App $APP does not exist" } verify_image() { From 5981ff8e9bed3c15a5bfbf1efb0d167cff925a7d Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sat, 21 May 2022 14:42:01 -0400 Subject: [PATCH 09/18] refactor: split out config logic to remove need to check app name for function-based usage This MR splits out the logic such that there is now a binary that handles function based calls without validating the app name. We should only every check the app name for the subcommands and not internally. Internal calls should have their arguments taken at face value. --- plugins/config/Makefile | 8 +- plugins/config/functions | 2 +- plugins/config/functions.go | 125 +++++++++++++++++++- plugins/config/src/config_sub/config_sub.go | 112 ++++++++++++++++++ plugins/config/subcommands.go | 119 ++++--------------- plugins/config/triggers.go | 8 +- 6 files changed, 269 insertions(+), 105 deletions(-) create mode 100644 plugins/config/src/config_sub/config_sub.go diff --git a/plugins/config/Makefile b/plugins/config/Makefile index 7be217943..6a4bef9ec 100644 --- a/plugins/config/Makefile +++ b/plugins/config/Makefile @@ -1,6 +1,12 @@ SUBCOMMANDS = subcommands/bundle subcommands/clear subcommands/export subcommands/get subcommands/keys subcommands/show subcommands/set subcommands/unset TRIGGERS = triggers/config-export triggers/config-get triggers/config-get-global -BUILD = commands subcommands triggers +BUILD = commands config_sub subcommands triggers PLUGIN_NAME = config +clean-config_sub: + rm -rf config_sub + +config_sub: clean-config_sub **/**/config_sub.go + go build -ldflags="-s -w" $(GO_ARGS) -o config_sub src/config_sub/config_sub.go + include ../../common.mk diff --git a/plugins/config/functions b/plugins/config/functions index 9cb3dccbf..fa3b4e0e3 100755 --- a/plugins/config/functions +++ b/plugins/config/functions @@ -7,7 +7,7 @@ config_sub() { declare desc="executes a config subcommand" local name="$1" shift - "$PLUGIN_AVAILABLE_PATH/config/subcommands/$name" "config:$name" "$@" + "$PLUGIN_AVAILABLE_PATH/config/config_sub" "$name" "$@" } config_export() { diff --git a/plugins/config/functions.go b/plugins/config/functions.go index 13407fbfb..28997d25a 100644 --- a/plugins/config/functions.go +++ b/plugins/config/functions.go @@ -1,13 +1,16 @@ package config -import "fmt" +import ( + "encoding/base64" + "errors" + "fmt" + "os" + "strings" -func export(appName string, global bool, merged bool, format string) error { - appName, err := getAppNameOrGlobal(appName, global) - if err != nil { - return err - } + "github.com/dokku/dokku/plugins/common" +) +func export(appName string, merged bool, format string) error { env := getEnvironment(appName, merged) exportType := ExportFormatExports suffix := "\n" @@ -37,3 +40,113 @@ func export(appName string, global bool, merged bool, format string) error { fmt.Print(exported + suffix) return nil } + +// SubBundle implements the logic for config:bundle without app name validation +func SubBundle(appName string, merged bool) error { + env := getEnvironment(appName, merged) + return env.ExportBundle(os.Stdout) +} + +// SubClear implements the logic for config:clear without app name validation +func SubClear(appName string, noRestart bool) error { + return UnsetAll(appName, !noRestart) +} + +// SubExport implements the logic for config:export without app name validation +func SubExport(appName string, merged bool, format string) error { + return export(appName, merged, format) +} + +// SubGet implements the logic for config:get without app name validation +func SubGet(appName string, keys []string, quoted bool) error { + if len(keys) == 0 { + return errors.New("Expected: key") + } + + if len(keys) != 1 { + return fmt.Errorf("Unexpected argument(s): %v", keys[1:]) + } + + value, ok := Get(appName, keys[0]) + if !ok { + os.Exit(1) + return nil + } + + if quoted { + fmt.Printf("'%s'\n", singleQuoteEscape(value)) + } else { + fmt.Printf("%s\n", value) + } + + return nil +} + +// SubKeys implements the logic for config:keys without app name validation +func SubKeys(appName string, merged bool) error { + env := getEnvironment(appName, merged) + for _, k := range env.Keys() { + fmt.Println(k) + } + return nil +} + +// SubSet implements the logic for config:set without app name validation +func SubSet(appName string, pairs []string, noRestart bool, encoded bool) error { + if len(pairs) == 0 { + return errors.New("At least one env pair must be given") + } + + updated := make(map[string]string) + for _, e := range pairs { + parts := strings.SplitN(e, "=", 2) + if len(parts) == 1 { + return fmt.Errorf("Invalid env pair: %v", e) + } + + key, value := parts[0], parts[1] + if encoded { + decoded, err := base64.StdEncoding.DecodeString(value) + if err != nil { + return fmt.Errorf("%s for key '%s'", err.Error(), key) + } + value = string(decoded) + } + updated[key] = value + } + + return SetMany(appName, updated, !noRestart) +} + +// SubShow implements the logic for config:show without app name validation +func SubShow(appName string, merged bool, shell bool, export bool) error { + env := getEnvironment(appName, merged) + if shell && export { + return errors.New("Only one of --shell and --export can be given") + } + if shell { + common.LogWarn("Deprecated: Use 'config:export --format shell' instead") + fmt.Print(env.Export(ExportFormatShell)) + } else if export { + common.LogWarn("Deprecated: Use 'config:export --format exports' instead") + fmt.Println(env.Export(ExportFormatExports)) + } else { + contextName := "global" + if appName != "" { + contextName = appName + } + common.LogInfo2Quiet(contextName + " env vars") + fmt.Println(env.Export(ExportFormatPretty)) + } + + return nil +} + +// SubUnset implements the logic for config:unset without app name validation +func SubUnset(appName string, keys []string, noRestart bool) error { + if len(keys) == 0 { + return fmt.Errorf("At least one key must be given") + } + + return UnsetMany(appName, keys, !noRestart) +} diff --git a/plugins/config/src/config_sub/config_sub.go b/plugins/config/src/config_sub/config_sub.go new file mode 100644 index 000000000..42dc7d70e --- /dev/null +++ b/plugins/config/src/config_sub/config_sub.go @@ -0,0 +1,112 @@ +package main + +import ( + "fmt" + "os" + + "github.com/dokku/dokku/plugins/common" + "github.com/dokku/dokku/plugins/config" + + flag "github.com/spf13/pflag" +) + +func getKeys(args []string, global bool) []string { + keys := args + if !global && len(keys) > 0 { + keys = keys[1:] + } + return keys +} + +// main entrypoint to all subcommands +func main() { + action := os.Args[1] + + var err error + appName := "--global" + switch action { + case "bundle": + args := flag.NewFlagSet("bundle", flag.ExitOnError) + global := args.Bool("global", false, "--global: use the global environment") + merged := args.Bool("merged", false, "--merged: merge app environment and global environment") + args.Parse(os.Args[2:]) + if !*global { + appName = args.Arg(0) + } + err = config.SubBundle(appName, *merged) + case "clear": + args := flag.NewFlagSet("clear", flag.ExitOnError) + global := args.Bool("global", false, "--global: use the global environment") + noRestart := args.Bool("no-restart", false, "--no-restart: no restart") + args.Parse(os.Args[2:]) + if !*global { + appName = args.Arg(0) + } + err = config.SubClear(appName, *noRestart) + case "export": + args := flag.NewFlagSet("export", flag.ExitOnError) + global := args.Bool("global", false, "--global: use the global environment") + merged := args.Bool("merged", false, "--merged: merge app environment and global environment") + format := args.String("format", "exports", "--format: [ docker-args | docker-args-keys | exports | envfile | json | json-list | pack-keys | pretty | shell ] which format to export as)") + args.Parse(os.Args[2:]) + if !*global { + appName = args.Arg(0) + } + err = config.SubExport(appName, *merged, *format) + case "get": + args := flag.NewFlagSet("get", flag.ExitOnError) + global := args.Bool("global", false, "--global: use the global environment") + quoted := args.Bool("quoted", false, "--quoted: get the value quoted") + args.Parse(os.Args[2:]) + if !*global { + appName = args.Arg(0) + } + keys := getKeys(args.Args(), *global) + err = config.SubGet(appName, keys, *quoted) + case "keys": + args := flag.NewFlagSet("keys", flag.ExitOnError) + global := args.Bool("global", false, "--global: use the global environment") + merged := args.Bool("merged", false, "--merged: merge app environment and global environment") + args.Parse(os.Args[2:]) + if !*global { + appName = args.Arg(0) + } + err = config.SubKeys(appName, *merged) + case "show": + args := flag.NewFlagSet("show", flag.ExitOnError) + global := args.Bool("global", false, "--global: use the global environment") + merged := args.Bool("merged", false, "--merged: display the app's environment merged with the global environment") + args.Parse(os.Args[2:]) + if !*global { + appName = args.Arg(0) + } + err = config.SubShow(appName, *merged, false, false) + case "set": + args := flag.NewFlagSet("set", flag.ExitOnError) + global := args.Bool("global", false, "--global: use the global environment") + encoded := args.Bool("encoded", false, "--encoded: interpret VALUEs as base64") + noRestart := args.Bool("no-restart", false, "--no-restart: no restart") + args.Parse(os.Args[2:]) + if !*global { + appName = args.Arg(0) + } + pairs := getKeys(args.Args(), *global) + err = config.SubSet(appName, pairs, *noRestart, *encoded) + case "unset": + args := flag.NewFlagSet("unset", flag.ExitOnError) + global := args.Bool("global", false, "--global: use the global environment") + noRestart := args.Bool("no-restart", false, "--no-restart: no restart") + args.Parse(os.Args[2:]) + if !*global { + appName = args.Arg(0) + } + keys := getKeys(args.Args(), *global) + err = config.SubUnset(appName, keys, *noRestart) + default: + err = fmt.Errorf("Invalid plugin config_sub call: %s", action) + } + + if err != nil { + common.LogFailWithError(err) + } +} diff --git a/plugins/config/subcommands.go b/plugins/config/subcommands.go index 033b45dd2..fe7e252d6 100644 --- a/plugins/config/subcommands.go +++ b/plugins/config/subcommands.go @@ -1,156 +1,83 @@ package config -import ( - "encoding/base64" - "errors" - "fmt" - "os" - "strings" - - "github.com/dokku/dokku/plugins/common" -) - -// CommandBundle implements config:bundle +// CommandBundle creates a tarball of a .env.d directory +// containing env vars for the app func CommandBundle(appName string, global bool, merged bool) error { appName, err := getAppNameOrGlobal(appName, global) if err != nil { return err } - env := getEnvironment(appName, merged) - return env.ExportBundle(os.Stdout) + return SubBundle(appName, merged) } -// CommandClear implements config:clear +// CommandClear unsets all environment variables in use func CommandClear(appName string, global bool, noRestart bool) error { appName, err := getAppNameOrGlobal(appName, global) if err != nil { return err } - return UnsetAll(appName, !noRestart) + return SubClear(appName, noRestart) } -// CommandExport implements config:export +// CommandExport outputs all env vars (merged or not, global or not) +// in the specified format for consumption by other tools func CommandExport(appName string, global bool, merged bool, format string) error { - return export(appName, global, merged, format) + appName, err := getAppNameOrGlobal(appName, global) + if err != nil { + return err + } + + return SubExport(appName, merged, format) } -// CommandGet implements config:get +// CommandGet gets the value for the specified environment variable func CommandGet(appName string, keys []string, global bool, quoted bool) error { appName, err := getAppNameOrGlobal(appName, global) if err != nil { return err } - if len(keys) == 0 { - return errors.New("Expected: key") - } - - if len(keys) != 1 { - return fmt.Errorf("Unexpected argument(s): %v", keys[1:]) - } - - value, ok := Get(appName, keys[0]) - if !ok { - os.Exit(1) - return nil - } - - if quoted { - fmt.Printf("'%s'\n", singleQuoteEscape(value)) - } else { - fmt.Printf("%s\n", value) - } - - return nil + return SubGet(appName, keys, quoted) } -// CommandKeys implements config:keys +// CommandKeys shows the keys set for the specified environment func CommandKeys(appName string, global bool, merged bool) error { appName, err := getAppNameOrGlobal(appName, global) if err != nil { return err } - env := getEnvironment(appName, merged) - for _, k := range env.Keys() { - fmt.Println(k) - } - return nil + return SubKeys(appName, merged) } -// CommandSet implements config:set +// CommandSet sets one or more environment variable pairs func CommandSet(appName string, pairs []string, global bool, noRestart bool, encoded bool) error { appName, err := getAppNameOrGlobal(appName, global) if err != nil { return err } - if len(pairs) == 0 { - return errors.New("At least one env pair must be given") - } - - updated := make(map[string]string) - for _, e := range pairs { - parts := strings.SplitN(e, "=", 2) - if len(parts) == 1 { - return fmt.Errorf("Invalid env pair: %v", e) - } - - key, value := parts[0], parts[1] - if encoded { - decoded, err := base64.StdEncoding.DecodeString(value) - if err != nil { - return fmt.Errorf("%s for key '%s'", err.Error(), key) - } - value = string(decoded) - } - updated[key] = value - } - - return SetMany(appName, updated, !noRestart) + return SubSet(appName, pairs, noRestart, encoded) } -// CommandShow implements config:show +// CommandShow pretty-prints the specified environment vaiables func CommandShow(appName string, global bool, merged bool, shell bool, export bool) error { appName, err := getAppNameOrGlobal(appName, global) if err != nil { return err } - env := getEnvironment(appName, merged) - if shell && export { - return errors.New("Only one of --shell and --export can be given") - } - if shell { - common.LogWarn("Deprecated: Use 'config:export --format shell' instead") - fmt.Print(env.Export(ExportFormatShell)) - } else if export { - common.LogWarn("Deprecated: Use 'config:export --format exports' instead") - fmt.Println(env.Export(ExportFormatExports)) - } else { - contextName := "global" - if appName != "" { - contextName = appName - } - common.LogInfo2Quiet(contextName + " env vars") - fmt.Println(env.Export(ExportFormatPretty)) - } - - return nil + return SubShow(appName, merged, shell, export) } -// CommandUnset implements config:unset +// CommandUnset unsets one or more keys in a specified environment func CommandUnset(appName string, keys []string, global bool, noRestart bool) error { appName, err := getAppNameOrGlobal(appName, global) if err != nil { return err } - if len(keys) == 0 { - return fmt.Errorf("At least one key must be given") - } - - return UnsetMany(appName, keys, !noRestart) + return SubUnset(appName, keys, noRestart) } diff --git a/plugins/config/triggers.go b/plugins/config/triggers.go index 7bcfbb50f..3014f6d26 100644 --- a/plugins/config/triggers.go +++ b/plugins/config/triggers.go @@ -16,7 +16,13 @@ func TriggerConfigExport(appName string, global string, merged string, format st if err != nil { return err } - return export(appName, g, m, format) + + appName, err = getAppNameOrGlobal(appName, g) + if err != nil { + return err + } + + return export(appName, m, format) } // TriggerConfigGet returns an app config value by key From d803dbb84a3fb757ebaa884ea00e8a72637eca91 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 27 May 2022 23:44:46 -0400 Subject: [PATCH 10/18] fix: drop extra unnecessary validation of app name The app name is already validated when calling subcommands, so no need to validate it yet again here. --- plugins/config/environment.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/plugins/config/environment.go b/plugins/config/environment.go index 8e26f0a80..2f6ddf071 100644 --- a/plugins/config/environment.go +++ b/plugins/config/environment.go @@ -60,10 +60,6 @@ func newEnvFromString(rep string) (env *Env, err error) { //LoadAppEnv loads an environment for the given app func LoadAppEnv(appName string) (env *Env, err error) { - err = common.VerifyAppName(appName) - if err != nil { - return - } appfile, err := getAppFile(appName) if err != nil { return @@ -357,10 +353,6 @@ func loadFromFile(name string, filename string) (env *Env, err error) { } func getAppFile(appName string) (string, error) { - err := common.VerifyAppName(appName) - if err != nil { - return "", err - } return filepath.Join(common.MustGetEnv("DOKKU_ROOT"), appName, "ENV"), nil } From 9473ac5f381f46f981908e7e36a789410b41f304 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 May 2022 03:59:34 +0000 Subject: [PATCH 11/18] chore(deps): bump grunt from 1.5.2 to 1.5.3 in /tests/apps/multi Bumps [grunt](https://github.com/gruntjs/grunt) from 1.5.2 to 1.5.3. - [Release notes](https://github.com/gruntjs/grunt/releases) - [Changelog](https://github.com/gruntjs/grunt/blob/main/CHANGELOG) - [Commits](https://github.com/gruntjs/grunt/compare/v1.5.2...v1.5.3) --- updated-dependencies: - dependency-name: grunt dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- tests/apps/multi/package-lock.json | 14 +++++++------- tests/apps/multi/package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/apps/multi/package-lock.json b/tests/apps/multi/package-lock.json index a860dea0a..09a943a3c 100644 --- a/tests/apps/multi/package-lock.json +++ b/tests/apps/multi/package-lock.json @@ -11,7 +11,7 @@ "license": "ISC", "dependencies": { "bower": "^1.8.0", - "grunt": "~1.5.2", + "grunt": "~1.5.3", "grunt-cli": "~1.4.3", "grunt-contrib-compass": "~1.1.1", "load-grunt-tasks": "~5.1.0", @@ -517,9 +517,9 @@ } }, "node_modules/grunt": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.5.2.tgz", - "integrity": "sha512-XCtfaIu72OyDqK24MjWiGC9SwlkuhkS1mrULr1xzuJ2XqAFhP3ZAchZGHJeSCY6mkaOXU4F7SbmmCF7xIVoC9w==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.5.3.tgz", + "integrity": "sha512-mKwmo4X2d8/4c/BmcOETHek675uOqw0RuA/zy12jaspWqvTp4+ZeQF1W+OTpcbncnaBsfbQJ6l0l4j+Sn/GmaQ==", "dependencies": { "dateformat": "~3.0.3", "eventemitter2": "~0.4.13", @@ -2110,9 +2110,9 @@ } }, "grunt": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.5.2.tgz", - "integrity": "sha512-XCtfaIu72OyDqK24MjWiGC9SwlkuhkS1mrULr1xzuJ2XqAFhP3ZAchZGHJeSCY6mkaOXU4F7SbmmCF7xIVoC9w==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.5.3.tgz", + "integrity": "sha512-mKwmo4X2d8/4c/BmcOETHek675uOqw0RuA/zy12jaspWqvTp4+ZeQF1W+OTpcbncnaBsfbQJ6l0l4j+Sn/GmaQ==", "requires": { "dateformat": "~3.0.3", "eventemitter2": "~0.4.13", diff --git a/tests/apps/multi/package.json b/tests/apps/multi/package.json index 948916e2b..57db9ba80 100644 --- a/tests/apps/multi/package.json +++ b/tests/apps/multi/package.json @@ -2,7 +2,7 @@ "author": "Al Johri", "dependencies": { "bower": "^1.8.0", - "grunt": "~1.5.2", + "grunt": "~1.5.3", "grunt-cli": "~1.4.3", "grunt-contrib-compass": "~1.1.1", "load-grunt-tasks": "~5.1.0", From 96a2ec01f526e8c62b734af2361cc2dd13fbf42d Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sat, 28 May 2022 12:22:11 -0400 Subject: [PATCH 12/18] fix: ensure go tests have PLUGIN_ENABLED_PATH set --- plugins/common/common_test.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/plugins/common/common_test.go b/plugins/common/common_test.go index 3e31967e1..6f30e385d 100644 --- a/plugins/common/common_test.go +++ b/plugins/common/common_test.go @@ -20,6 +20,10 @@ var ( testEnvLine2 = "export testKey=TESTING" ) +func setupTests() (err error) { + return os.Setenv("PLUGIN_ENABLED_PATH", "/var/lib/dokku/plugins/enabled") +} + func setupTestApp() (err error) { Expect(os.MkdirAll(testAppDir, 0644)).To(Succeed()) b := []byte(testEnvLine + "\n") @@ -48,32 +52,37 @@ func teardownTestApp2() { func TestCommonGetEnv(t *testing.T) { RegisterTestingT(t) + Expect(setupTests()).To(Succeed()) Expect(MustGetEnv("DOKKU_ROOT")).To(Equal("/home/dokku")) } func TestCommonGetAppImageRepo(t *testing.T) { RegisterTestingT(t) + Expect(setupTests()).To(Succeed()) Expect(GetAppImageRepo("testapp")).To(Equal("dokku/testapp")) } func TestCommonVerifyImageInvalid(t *testing.T) { RegisterTestingT(t) + Expect(setupTests()).To(Succeed()) Expect(VerifyImage("testapp")).To(Equal(false)) } func TestCommonVerifyAppNameInvalid(t *testing.T) { RegisterTestingT(t) - err := VerifyAppName("1994testApp") - Expect(err).To(HaveOccurred()) + Expect(setupTests()).To(Succeed()) + Expect(VerifyAppName("1994testApp")).To(HaveOccurred()) } func TestCommonVerifyAppName(t *testing.T) { RegisterTestingT(t) + Expect(setupTests()).To(Succeed()) Expect(setupTestApp()).To(Succeed()) Expect(VerifyAppName(testAppName)).To(Succeed()) teardownTestApp() RegisterTestingT(t) + Expect(setupTests()).To(Succeed()) Expect(setupTestApp2()).To(Succeed()) Expect(VerifyAppName(testAppName2)).To(Succeed()) teardownTestApp2() @@ -81,13 +90,14 @@ func TestCommonVerifyAppName(t *testing.T) { func TestCommonDokkuAppsError(t *testing.T) { RegisterTestingT(t) + Expect(setupTests()).To(Succeed()) _, err := DokkuApps() Expect(err).To(HaveOccurred()) } func TestCommonDokkuApps(t *testing.T) { RegisterTestingT(t) - os.Setenv("PLUGIN_ENABLED_PATH", "/var/lib/dokku/plugins/enabled") + Expect(setupTests()).To(Succeed()) Expect(setupTestApp()).To(Succeed()) apps, err := DokkuApps() Expect(err).NotTo(HaveOccurred()) @@ -98,6 +108,7 @@ func TestCommonDokkuApps(t *testing.T) { func TestCommonStripInlineComments(t *testing.T) { RegisterTestingT(t) + Expect(setupTests()).To(Succeed()) text := StripInlineComments(strings.Join([]string{testEnvLine, "# testing comment"}, " ")) Expect(text).To(Equal(testEnvLine)) } From 3a2e9973b6d6359e3b6e3aafa50c642b3b226c73 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 May 2022 16:22:59 +0000 Subject: [PATCH 13/18] chore(deps): bump rack from 2.2.3 to 2.2.3.1 in /tests/apps/ruby Bumps [rack](https://github.com/rack/rack) from 2.2.3 to 2.2.3.1. - [Release notes](https://github.com/rack/rack/releases) - [Changelog](https://github.com/rack/rack/blob/main/CHANGELOG.md) - [Commits](https://github.com/rack/rack/compare/2.2.3...2.2.3.1) --- updated-dependencies: - dependency-name: rack dependency-type: indirect ... Signed-off-by: dependabot[bot] --- tests/apps/ruby/Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/apps/ruby/Gemfile.lock b/tests/apps/ruby/Gemfile.lock index e01a3c1cd..7b0185fe6 100644 --- a/tests/apps/ruby/Gemfile.lock +++ b/tests/apps/ruby/Gemfile.lock @@ -5,7 +5,7 @@ GEM eventmachine (1.2.7) mustermann (1.1.1) ruby2_keywords (~> 0.0.1) - rack (2.2.3) + rack (2.2.3.1) rack-protection (2.2.0) rack ruby2_keywords (0.0.5) From a95e5d210d1be46e0f06c91f0b1a70f498b7ed29 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sat, 28 May 2022 18:23:34 -0400 Subject: [PATCH 14/18] tests: test the command funcs to exercise app validation --- plugins/config/config_test.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/config/config_test.go b/plugins/config/config_test.go index ff2502fd2..63763eb66 100644 --- a/plugins/config/config_test.go +++ b/plugins/config/config_test.go @@ -64,20 +64,20 @@ func TestConfigSetMany(t *testing.T) { expectValue(testAppName, "testKey", "TESTING") - vals := map[string]string{"testKey": "updated", "testKey2": "new"} - Expect(SetMany(testAppName, vals, false)).To(Succeed()) + vals := []string{"testKey=updated", "testKey2=new"} + Expect(CommandSet(testAppName, vals, false, true, false)).To(Succeed()) expectValue(testAppName, "testKey", "updated") expectValue(testAppName, "testKey2", "new") - vals = map[string]string{"testKey": "updated_global", "testKey2": "new_global"} - Expect(SetMany("", vals, false)).To(Succeed()) + vals = []string{"testKey=updated_global", "testKey2=new_global"} + Expect(CommandSet("", vals, false, true, false)).To(Succeed()) expectValue("", "testKey", "updated_global") expectValue("", "testKey2", "new_global") expectValue("", "globalKey", "GLOBAL_VALUE") expectValue(testAppName, "testKey", "updated") expectValue(testAppName, "testKey2", "new") - Expect(SetMany(testAppName+"does_not_exist", vals, false)).ToNot(Succeed()) + Expect(CommandSet(testAppName+"does_not_exist", vals, false, true, false)).ToNot(Succeed()) } func TestConfigUnsetAll(t *testing.T) { @@ -88,12 +88,12 @@ func TestConfigUnsetAll(t *testing.T) { expectValue(testAppName, "testKey", "TESTING") expectValue("", "testKey", "GLOBAL_TESTING") - Expect(UnsetAll(testAppName, false)).To(Succeed()) + Expect(CommandClear(testAppName, false, true)).To(Succeed()) expectNoValue(testAppName, "testKey") expectNoValue(testAppName, "noKey") expectNoValue(testAppName, "globalKey") - Expect(UnsetAll(testAppName+"does-not-exist", false)).ToNot(Succeed()) + Expect(CommandClear(testAppName+"does-not-exist", false, true)).ToNot(Succeed()) } func TestConfigUnsetMany(t *testing.T) { @@ -105,15 +105,15 @@ func TestConfigUnsetMany(t *testing.T) { expectValue("", "testKey", "GLOBAL_TESTING") keys := []string{"testKey", "noKey"} - Expect(UnsetMany(testAppName, keys, false)).To(Succeed()) + Expect(CommandUnset(testAppName, keys, false, true)).To(Succeed()) expectNoValue(testAppName, "testKey") expectValue("", "testKey", "GLOBAL_TESTING") - Expect(UnsetMany(testAppName, keys, false)).To(Succeed()) + Expect(CommandUnset(testAppName, keys, false, true)).To(Succeed()) expectNoValue(testAppName, "testKey") expectNoValue(testAppName, "globalKey") - Expect(UnsetMany(testAppName+"does-not-exist", keys, false)).ToNot(Succeed()) + Expect(CommandUnset(testAppName+"does-not-exist", keys, false, true)).ToNot(Succeed()) } func TestEnvironmentLoading(t *testing.T) { From 97bbded5bbd8ef0aa60ea5ff2b266d884a7df2f7 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sat, 28 May 2022 23:23:25 -0400 Subject: [PATCH 15/18] tests: set the PLUGIN_ENABLED_PATH for config tests --- plugins/config/config_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/plugins/config/config_test.go b/plugins/config/config_test.go index 63763eb66..6d335ac3a 100644 --- a/plugins/config/config_test.go +++ b/plugins/config/config_test.go @@ -18,6 +18,10 @@ var ( globalConfigFile = strings.Join([]string{dokkuRoot, "ENV"}, "/") ) +func setupTests() (err error) { + return os.Setenv("PLUGIN_ENABLED_PATH", "/var/lib/dokku/plugins/enabled") +} + func setupTestApp() (err error) { Expect(os.MkdirAll(testAppDir, 0766)).To(Succeed()) b := []byte("export testKey=TESTING\n") @@ -38,6 +42,7 @@ func teardownTestApp() { func TestConfigGetWithDefault(t *testing.T) { RegisterTestingT(t) + Expect(setupTests()).To(Succeed()) Expect(setupTestApp()).To(Succeed()) Expect(GetWithDefault(testAppName, "unknownKey", "UNKNOWN")).To(Equal("UNKNOWN")) Expect(GetWithDefault(testAppName, "testKey", "testKey")).To(Equal("TESTING")) @@ -47,6 +52,7 @@ func TestConfigGetWithDefault(t *testing.T) { func TestConfigGet(t *testing.T) { RegisterTestingT(t) + Expect(setupTests()).To(Succeed()) Expect(setupTestApp()).To(Succeed()) defer teardownTestApp() @@ -59,6 +65,7 @@ func TestConfigGet(t *testing.T) { func TestConfigSetMany(t *testing.T) { RegisterTestingT(t) + Expect(setupTests()).To(Succeed()) Expect(setupTestApp()).To(Succeed()) defer teardownTestApp() @@ -82,6 +89,7 @@ func TestConfigSetMany(t *testing.T) { func TestConfigUnsetAll(t *testing.T) { RegisterTestingT(t) + Expect(setupTests()).To(Succeed()) Expect(setupTestApp()).To(Succeed()) defer teardownTestApp() @@ -98,6 +106,7 @@ func TestConfigUnsetAll(t *testing.T) { func TestConfigUnsetMany(t *testing.T) { RegisterTestingT(t) + Expect(setupTests()).To(Succeed()) Expect(setupTestApp()).To(Succeed()) defer teardownTestApp() @@ -118,6 +127,7 @@ func TestConfigUnsetMany(t *testing.T) { func TestEnvironmentLoading(t *testing.T) { RegisterTestingT(t) + Expect(setupTests()).To(Succeed()) Expect(setupTestApp()).To(Succeed()) defer teardownTestApp() @@ -142,6 +152,7 @@ func TestEnvironmentLoading(t *testing.T) { func TestInvalidKeys(t *testing.T) { RegisterTestingT(t) + Expect(setupTests()).To(Succeed()) Expect(setupTestApp()).To(Succeed()) defer teardownTestApp() @@ -158,6 +169,7 @@ func TestInvalidKeys(t *testing.T) { func TestInvalidEnvOnDisk(t *testing.T) { RegisterTestingT(t) + Expect(setupTests()).To(Succeed()) Expect(setupTestApp()).To(Succeed()) defer teardownTestApp() From cc9d76aa117cb07da809342693e9f538cdb83d6d Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 29 May 2022 00:00:26 -0400 Subject: [PATCH 16/18] fix: set globally --- plugins/config/config_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/config/config_test.go b/plugins/config/config_test.go index 6d335ac3a..769132c80 100644 --- a/plugins/config/config_test.go +++ b/plugins/config/config_test.go @@ -77,7 +77,7 @@ func TestConfigSetMany(t *testing.T) { expectValue(testAppName, "testKey2", "new") vals = []string{"testKey=updated_global", "testKey2=new_global"} - Expect(CommandSet("", vals, false, true, false)).To(Succeed()) + Expect(CommandSet("", vals, true, true, false)).To(Succeed()) expectValue("", "testKey", "updated_global") expectValue("", "testKey2", "new_global") expectValue("", "globalKey", "GLOBAL_VALUE") From db4d8dba88b795d7bf263b2f3b1b702d2afa67ad Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 29 May 2022 11:28:34 -0400 Subject: [PATCH 17/18] refactor: consolidate app name verification into golang binary This change ensures we only have to change this logic once in order to get them to apply to both languages in the codebase. --- plugins/common/functions | 34 +---------------------------- plugins/common/log.go | 13 +++++++++++ plugins/common/src/common/common.go | 5 ++++- 3 files changed, 18 insertions(+), 34 deletions(-) diff --git a/plugins/common/functions b/plugins/common/functions index 0b4b0c0d0..98237caf5 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -250,43 +250,11 @@ is_valid_app_name_old() { verify_app_name() { declare desc="verify app name format and app existence" declare APP="$1" - export SSH_USER=${SSH_USER:=$USER} - export SSH_NAME=${NAME:="default"} - local VALID_NEW=false - local VALID_OLD=false - if fn-is-valid-app-name "$APP" 2>/dev/null; then - VALID_NEW=true - fi - - if fn-is-valid-app-name-old "$APP" 2>/dev/null; then - VALID_OLD=true - fi - - if [[ "$VALID_NEW" == "false" ]] && [[ "$VALID_OLD" == "false" ]]; then - dokku_log_fail "App name must begin with lowercase alphanumeric character, and cannot include uppercase characters, colons, or underscores" - fi - - [[ ! -d "$DOKKU_ROOT/$APP" ]] && DOKKU_FAIL_EXIT_CODE=20 dokku_log_fail "App $APP does not exist" - - local user_auth_count=$(find "$PLUGIN_PATH"/enabled/*/user-auth-app 2>/dev/null | wc -l) - - # no plugin trigger exists - if [[ $user_auth_count == 0 ]]; then + if "$PLUGIN_CORE_AVAILABLE_PATH/common/common" --quiet verify-app-name "$APP"; then return 0 fi - # this plugin trigger exists in the core `20_events` plugin - if [[ "$user_auth_count" == 1 ]] && [[ -f "$PLUGIN_PATH"/enabled/20_events/user-auth-app ]]; then - return 0 - fi - - if output="$(plugn trigger user-auth-app "$SSH_USER" "$SSH_NAME" "$@" "$APP")"; then - if [[ -n "$output" ]]; then - return 0 - fi - fi - DOKKU_FAIL_EXIT_CODE=20 dokku_log_fail "App $APP does not exist" } diff --git a/plugins/common/log.go b/plugins/common/log.go index d45f26e48..dec3791b1 100644 --- a/plugins/common/log.go +++ b/plugins/common/log.go @@ -61,6 +61,19 @@ func LogFailWithError(err error) { os.Exit(1) } +// LogFailWithErrorQuiet is the failure log formatter (with quiet option) +// prints text to stderr and exits with the specified exit code +// The error message is not printed if DOKKU_QUIET_OUTPUT has any value +func LogFailWithErrorQuiet(err error) { + if os.Getenv("DOKKU_QUIET_OUTPUT") == "" { + fmt.Fprintln(os.Stderr, fmt.Sprintf(" ! %s", err.Error())) + } + if errExit, ok := err.(ErrWithExitCode); ok { + os.Exit(errExit.ExitCode()) + } + os.Exit(1) +} + // LogFailQuiet is the failure log formatter (with quiet option) // prints text to stderr and exits with status 1 func LogFailQuiet(text string) { diff --git a/plugins/common/src/common/common.go b/plugins/common/src/common/common.go index 432aa00e8..4b4c078dc 100644 --- a/plugins/common/src/common/common.go +++ b/plugins/common/src/common/common.go @@ -38,11 +38,14 @@ func main() { appName = "--global" } fmt.Print(common.GetAppScheduler(appName)) + case "verify-app-name": + appName := flag.Arg(1) + err = common.VerifyAppName(appName) default: err = fmt.Errorf("Invalid common command call: %v", cmd) } if err != nil { - common.LogFailQuiet(err.Error()) + common.LogFailWithErrorQuiet(err) } } From 37036ec2fa587cf6b59e949a07f03cab521d1e5d Mon Sep 17 00:00:00 2001 From: Dokku Bot Date: Sun, 29 May 2022 19:12:03 +0000 Subject: [PATCH 18/18] Release 0.27.5 # History ## 0.27.5 Install/update via the bootstrap script: ```shell wget https://raw.githubusercontent.com/dokku/dokku/v0.27.5/bootstrap.sh sudo DOKKU_TAG=v0.27.5 bash bootstrap.sh ``` ### Bug Fixes - #5183: @josegonzalez Filter apps when verifying app names - #5199: @josegonzalez Revert "fix: Vector fails to start container due to --watch-config flag" - #5197: @holamendi fix: Vector fails to start container due to --watch-config flag - #5192: @josegonzalez Confirm installation of universe packages when installing on ubuntu - #5193: @josegonzalez Force-set correct permissions on env files - #5181: @josegonzalez Ensure we default SSH_NAME to NAME when filtering apps ### New Features - #5196: @josegonzalez Disable herokuish usage on both armhf and arm64 platforms - #5194: @josegonzalez Upgrade base Dockerfile image to phusion/baseimage:focal-1.2.0 ### Other - #5200: @dependabot[bot] chore(deps): bump rack from 2.2.3 to 2.2.3.1 in /tests/apps/ruby - #5198: @dependabot[bot] chore(deps): bump grunt from 1.5.2 to 1.5.3 in /tests/apps/multi - #5187: @dependabot[bot] chore(deps-dev): bump heroku/heroku-buildpack-php from 216 to 217 in /tests/apps/php --- HISTORY.md | 29 +++++++++++ README.md | 4 +- debian/control | 2 +- docs/advanced-usage/plugin-management.md | 58 +++++++++++----------- docs/assets/favicons/browserconfig.xml | 8 +-- docs/assets/favicons/manifest.json | 12 ++--- docs/assets/style.css | 4 +- docs/assets/versions.json | 2 +- docs/development/release-process.md | 2 +- docs/getting-started/install/docker.md | 4 +- docs/getting-started/installation.md | 4 +- docs/home.html | 40 +++++++-------- docs/template.html | 36 +++++++------- plugins/00_dokku-standard/plugin.toml | 2 +- plugins/20_events/plugin.toml | 2 +- plugins/app-json/plugin.toml | 2 +- plugins/apps/plugin.toml | 2 +- plugins/builder-dockerfile/plugin.toml | 2 +- plugins/builder-herokuish/plugin.toml | 2 +- plugins/builder-null/plugin.toml | 2 +- plugins/builder-pack/plugin.toml | 2 +- plugins/builder/plugin.toml | 2 +- plugins/buildpacks/plugin.toml | 2 +- plugins/certs/plugin.toml | 2 +- plugins/checks/plugin.toml | 2 +- plugins/common/plugin.toml | 2 +- plugins/config/plugin.toml | 2 +- plugins/cron/plugin.toml | 2 +- plugins/docker-options/plugin.toml | 2 +- plugins/domains/plugin.toml | 2 +- plugins/enter/plugin.toml | 2 +- plugins/git/plugin.toml | 2 +- plugins/logs/plugin.toml | 2 +- plugins/network/plugin.toml | 2 +- plugins/nginx-vhosts/plugin.toml | 2 +- plugins/plugin/plugin.toml | 2 +- plugins/proxy/plugin.toml | 2 +- plugins/ps/plugin.toml | 2 +- plugins/registry/plugin.toml | 2 +- plugins/repo/plugin.toml | 2 +- plugins/resource/plugin.toml | 2 +- plugins/run/plugin.toml | 2 +- plugins/scheduler-docker-local/plugin.toml | 2 +- plugins/scheduler-null/plugin.toml | 2 +- plugins/scheduler/plugin.toml | 2 +- plugins/shell/plugin.toml | 2 +- plugins/ssh-keys/plugin.toml | 2 +- plugins/storage/plugin.toml | 2 +- plugins/trace/plugin.toml | 2 +- 49 files changed, 153 insertions(+), 124 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index b9c8ff804..9e21898f4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,34 @@ # History +## 0.27.5 + +Install/update via the bootstrap script: + +```shell +wget https://raw.githubusercontent.com/dokku/dokku/v0.27.5/bootstrap.sh +sudo DOKKU_TAG=v0.27.5 bash bootstrap.sh +``` + +### Bug Fixes + +- #5183: @josegonzalez Filter apps when verifying app names +- #5199: @josegonzalez Revert "fix: Vector fails to start container due to --watch-config flag" +- #5197: @holamendi fix: Vector fails to start container due to --watch-config flag +- #5192: @josegonzalez Confirm installation of universe packages when installing on ubuntu +- #5193: @josegonzalez Force-set correct permissions on env files +- #5181: @josegonzalez Ensure we default SSH_NAME to NAME when filtering apps + +### New Features + +- #5196: @josegonzalez Disable herokuish usage on both armhf and arm64 platforms +- #5194: @josegonzalez Upgrade base Dockerfile image to phusion/baseimage:focal-1.2.0 + +### Other + +- #5200: @dependabot[bot] chore(deps): bump rack from 2.2.3 to 2.2.3.1 in /tests/apps/ruby +- #5198: @dependabot[bot] chore(deps): bump grunt from 1.5.2 to 1.5.3 in /tests/apps/multi +- #5187: @dependabot[bot] chore(deps-dev): bump heroku/heroku-buildpack-php from 216 to 217 in /tests/apps/php + ## 0.27.4 Install/update via the bootstrap script: diff --git a/README.md b/README.md index 7913e9591..003c835af 100644 --- a/README.md +++ b/README.md @@ -87,8 +87,8 @@ Otherwise, you will need to import the keypair manually after installation using To install the latest stable release, run the following commands as a user who has access to `sudo`: ```shell -wget https://raw.githubusercontent.com/dokku/dokku/v0.27.4/bootstrap.sh -sudo DOKKU_TAG=v0.27.4 bash bootstrap.sh +wget https://raw.githubusercontent.com/dokku/dokku/v0.27.5/bootstrap.sh +sudo DOKKU_TAG=v0.27.5 bash bootstrap.sh ``` You can then proceed to configure your server domain (via `dokku domains:set-global`) and user access (via `dokku ssh-keys:add`) to complete the installation. diff --git a/debian/control b/debian/control index e4505a38e..bace8b72d 100644 --- a/debian/control +++ b/debian/control @@ -1,5 +1,5 @@ Package: dokku -Version: 0.27.4 +Version: 0.27.5 Section: web Priority: optional Architecture: amd64 diff --git a/docs/advanced-usage/plugin-management.md b/docs/advanced-usage/plugin-management.md index 62b042906..3bb5d428e 100644 --- a/docs/advanced-usage/plugin-management.md +++ b/docs/advanced-usage/plugin-management.md @@ -35,35 +35,35 @@ dokku plugin:list ``` plugn: dev - 00_dokku-standard 0.27.4 enabled dokku core standard plugin - 20_events 0.27.4 enabled dokku core events logging plugin - app-json 0.27.4 enabled dokku core app-json plugin - apps 0.27.4 enabled dokku core apps plugin - build-env 0.27.4 enabled dokku core build-env plugin - buildpacks 0.27.4 enabled dokku core buildpacks plugin - certs 0.27.4 enabled dokku core certificate management plugin - checks 0.27.4 enabled dokku core checks plugin - common 0.27.4 enabled dokku core common plugin - config 0.27.4 enabled dokku core config plugin - docker-options 0.27.4 enabled dokku core docker-options plugin - domains 0.27.4 enabled dokku core domains plugin - enter 0.27.4 enabled dokku core enter plugin - git 0.27.4 enabled dokku core git plugin - logs 0.27.4 enabled dokku core logs plugin - network 0.27.4 enabled dokku core network plugin - nginx-vhosts 0.27.4 enabled dokku core nginx-vhosts plugin - plugin 0.27.4 enabled dokku core plugin plugin - proxy 0.27.4 enabled dokku core proxy plugin - ps 0.27.4 enabled dokku core ps plugin - repo 0.27.4 enabled dokku core repo plugin - resource 0.27.4 enabled dokku core resource plugin - scheduler-docker-local 0.27.4 enabled dokku core scheduler-docker-local plugin - shell 0.27.4 enabled dokku core shell plugin - ssh-keys 0.27.4 enabled dokku core ssh-keys plugin - storage 0.27.4 enabled dokku core storage plugin - tags 0.27.4 enabled dokku core tags plugin - tar 0.27.4 enabled dokku core tar plugin - trace 0.27.4 enabled dokku core trace plugin + 00_dokku-standard 0.27.5 enabled dokku core standard plugin + 20_events 0.27.5 enabled dokku core events logging plugin + app-json 0.27.5 enabled dokku core app-json plugin + apps 0.27.5 enabled dokku core apps plugin + build-env 0.27.5 enabled dokku core build-env plugin + buildpacks 0.27.5 enabled dokku core buildpacks plugin + certs 0.27.5 enabled dokku core certificate management plugin + checks 0.27.5 enabled dokku core checks plugin + common 0.27.5 enabled dokku core common plugin + config 0.27.5 enabled dokku core config plugin + docker-options 0.27.5 enabled dokku core docker-options plugin + domains 0.27.5 enabled dokku core domains plugin + enter 0.27.5 enabled dokku core enter plugin + git 0.27.5 enabled dokku core git plugin + logs 0.27.5 enabled dokku core logs plugin + network 0.27.5 enabled dokku core network plugin + nginx-vhosts 0.27.5 enabled dokku core nginx-vhosts plugin + plugin 0.27.5 enabled dokku core plugin plugin + proxy 0.27.5 enabled dokku core proxy plugin + ps 0.27.5 enabled dokku core ps plugin + repo 0.27.5 enabled dokku core repo plugin + resource 0.27.5 enabled dokku core resource plugin + scheduler-docker-local 0.27.5 enabled dokku core scheduler-docker-local plugin + shell 0.27.5 enabled dokku core shell plugin + ssh-keys 0.27.5 enabled dokku core ssh-keys plugin + storage 0.27.5 enabled dokku core storage plugin + tags 0.27.5 enabled dokku core tags plugin + tar 0.27.5 enabled dokku core tar plugin + trace 0.27.5 enabled dokku core trace plugin ``` > Warning: All plugin commands other than `plugin:list` and `plugin:help` require sudo access and must be run directly from the Dokku server. diff --git a/docs/assets/favicons/browserconfig.xml b/docs/assets/favicons/browserconfig.xml index 15aa0f995..506727caf 100644 --- a/docs/assets/favicons/browserconfig.xml +++ b/docs/assets/favicons/browserconfig.xml @@ -2,10 +2,10 @@ - - - - + + + + #da532c diff --git a/docs/assets/favicons/manifest.json b/docs/assets/favicons/manifest.json index 7eccf6639..d4cae553e 100644 --- a/docs/assets/favicons/manifest.json +++ b/docs/assets/favicons/manifest.json @@ -2,37 +2,37 @@ "name": "Dokku", "icons": [ { - "src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.27.4\/docs\/assets\/favicons\/android-chrome-36x36.png", + "src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.27.5\/docs\/assets\/favicons\/android-chrome-36x36.png", "sizes": "36x36", "type": "image\/png", "density": "0.75" }, { - "src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.27.4\/docs\/assets\/favicons\/android-chrome-48x48.png", + "src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.27.5\/docs\/assets\/favicons\/android-chrome-48x48.png", "sizes": "48x48", "type": "image\/png", "density": "1.0" }, { - "src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.27.4\/docs\/assets\/favicons\/android-chrome-72x72.png", + "src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.27.5\/docs\/assets\/favicons\/android-chrome-72x72.png", "sizes": "72x72", "type": "image\/png", "density": "1.5" }, { - "src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.27.4\/docs\/assets\/favicons\/android-chrome-96x96.png", + "src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.27.5\/docs\/assets\/favicons\/android-chrome-96x96.png", "sizes": "96x96", "type": "image\/png", "density": "2.0" }, { - "src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.27.4\/docs\/assets\/favicons\/android-chrome-144x144.png", + "src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.27.5\/docs\/assets\/favicons\/android-chrome-144x144.png", "sizes": "144x144", "type": "image\/png", "density": "3.0" }, { - "src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.27.4\/docs\/assets\/favicons\/android-chrome-192x192.png", + "src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.27.5\/docs\/assets\/favicons\/android-chrome-192x192.png", "sizes": "192x192", "type": "image\/png", "density": "4.0" diff --git a/docs/assets/style.css b/docs/assets/style.css index 995d611dd..14cc4822c 100644 --- a/docs/assets/style.css +++ b/docs/assets/style.css @@ -42,13 +42,13 @@ h1 { font-size: 1.6em; } .header .navbar-brand a { - background-image: url(https://cdn.jsdelivr.net/gh/dokku/dokku@v0.27.4/docs/assets/dokku.png); + background-image: url(https://cdn.jsdelivr.net/gh/dokku/dokku@v0.27.5/docs/assets/dokku.png); text-indent: 40px; } .blurb { color: #424242; background-color: #ededed; - background-image: url(https://cdn.jsdelivr.net/gh/dokku/dokku@v0.27.4/docs/assets/gplaypattern.png); + background-image: url(https://cdn.jsdelivr.net/gh/dokku/dokku@v0.27.5/docs/assets/gplaypattern.png); padding: 45px 0; text-align: center; } diff --git a/docs/assets/versions.json b/docs/assets/versions.json index 7784b165c..dd671dbd9 100644 --- a/docs/assets/versions.json +++ b/docs/assets/versions.json @@ -24,6 +24,6 @@ "0.24.10", "0.25.7", "0.26.8", - "0.27.4" + "0.27.5" ] } diff --git a/docs/development/release-process.md b/docs/development/release-process.md index dce979fee..a9a316814 100644 --- a/docs/development/release-process.md +++ b/docs/development/release-process.md @@ -29,7 +29,7 @@ The workflow looks like this: ```shell # having dokku-arch in ../dokku-arch vagrant up build-arch -# wait for "==> build-arch: ==> Finished making: dokku 0.27.4-2 (Mon Feb 22 23:20:37 CET 2016)" +# wait for "==> build-arch: ==> Finished making: dokku 0.27.5-2 (Mon Feb 22 23:20:37 CET 2016)" cd ../dokku-arch git add PKGBUILD .SRCINFO git commit -m 'Update to dokku 0.9.9' diff --git a/docs/getting-started/install/docker.md b/docs/getting-started/install/docker.md index fcfd6ea17..006f8c4b3 100644 --- a/docs/getting-started/install/docker.md +++ b/docs/getting-started/install/docker.md @@ -3,7 +3,7 @@ Pull the dokku/dokku image: ```shell -docker pull dokku/dokku:0.27.4 +docker pull dokku/dokku:0.27.5 ``` Next, run the image. @@ -18,7 +18,7 @@ docker container run \ --publish 8443:443 \ --volume /var/lib/dokku:/mnt/dokku \ --volume /var/run/docker.sock:/var/run/docker.sock \ - dokku/dokku:0.27.4 + dokku/dokku:0.27.5 ``` The above command will start a new docker container that is ready when a message similar to `Runit started as PID 12345` appears. diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md index c8c78a580..0d787a9ab 100644 --- a/docs/getting-started/installation.md +++ b/docs/getting-started/installation.md @@ -39,8 +39,8 @@ To install the latest stable version of Dokku, you can run the following shell c ```shell # for debian systems, installs Dokku via apt-get -wget https://raw.githubusercontent.com/dokku/dokku/v0.27.4/bootstrap.sh; -sudo DOKKU_TAG=v0.27.4 bash bootstrap.sh +wget https://raw.githubusercontent.com/dokku/dokku/v0.27.5/bootstrap.sh; +sudo DOKKU_TAG=v0.27.5 bash bootstrap.sh ``` The installation process takes about 5-10 minutes, depending upon internet connection speed. diff --git a/docs/home.html b/docs/home.html index b56e8fe49..f8d2a33eb 100644 --- a/docs/home.html +++ b/docs/home.html @@ -10,30 +10,30 @@ Dokku - The smallest PaaS implementation you've ever seen - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - + + - + @@ -98,12 +98,12 @@

$ - wget https://raw.githubusercontent.com/dokku/dokku/v0.27.4/bootstrap.sh + wget https://raw.githubusercontent.com/dokku/dokku/v0.27.5/bootstrap.sh

$ - sudo DOKKU_TAG=v0.27.4 bash bootstrap.sh + sudo DOKKU_TAG=v0.27.5 bash bootstrap.sh

 # Configure your server domain via `dokku domains:set-global` diff --git a/docs/template.html b/docs/template.html index 5fa7f1b17..1eace7df0 100644 --- a/docs/template.html +++ b/docs/template.html @@ -9,26 +9,26 @@ Dokku - {{DOC_TITLE}} - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - + + - +