From 3262107821280a4d27862858a5d65390ad08cf23 Mon Sep 17 00:00:00 2001 From: Alano Terblanche <18033717+Benehiko@users.noreply.github.com> Date: Fri, 4 Jul 2025 14:04:38 +0200 Subject: [PATCH 1/3] cli/config: export const dockerEnvConfig Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com> --- cli/config/configfile/file.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/config/configfile/file.go b/cli/config/configfile/file.go index 396f900345..530c522856 100644 --- a/cli/config/configfile/file.go +++ b/cli/config/configfile/file.go @@ -56,7 +56,7 @@ type configEnv struct { AuthConfigs map[string]configEnvAuth `json:"auths"` } -// dockerEnvConfig is an environment variable that contains a JSON encoded +// DockerEnvConfigKey is an environment variable that contains a JSON encoded // credential config. It only supports storing the credentials as a base64 // encoded string in the format base64("username:pat"). // @@ -71,7 +71,7 @@ type configEnv struct { // } // } // } -const dockerEnvConfig = "DOCKER_AUTH_CONFIG" +const DockerEnvConfigKey = "DOCKER_AUTH_CONFIG" // ProxyConfig contains proxy configuration settings type ProxyConfig struct { @@ -296,7 +296,7 @@ func (configFile *ConfigFile) GetCredentialsStore(registryHostname string) crede store = newNativeStore(configFile, helper) } - envConfig := os.Getenv(dockerEnvConfig) + envConfig := os.Getenv(DockerEnvConfigKey) if envConfig == "" { return store } From dec07e6fdfb6cbff06f6572a28318c9c842c69a1 Mon Sep 17 00:00:00 2001 From: Alano Terblanche <18033717+Benehiko@users.noreply.github.com> Date: Mon, 7 Jul 2025 11:22:28 +0200 Subject: [PATCH 2/3] tui/note: add warning note type Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com> --- internal/tui/note.go | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/internal/tui/note.go b/internal/tui/note.go index 664ba9e8df..d2bc0b9af8 100644 --- a/internal/tui/note.go +++ b/internal/tui/note.go @@ -15,19 +15,39 @@ var InfoHeader = Str{ Fancy: aec.Bold.Apply(aec.LightCyanB.Apply(aec.BlackF.Apply("i")) + " " + aec.LightCyanF.Apply("Info → ")), } -func (o Output) PrintNote(format string, args ...any) { +type options struct { + header Str +} + +type noteOptions func(o *options) + +func withHeader(header Str) noteOptions { + return func(o *options) { + o.header = header + } +} + +func (o Output) printNoteWithOptions(format string, args []any, opts ...noteOptions) { if o.isTerminal { // TODO: Handle all flags format = strings.ReplaceAll(format, "--platform", ColorFlag.Apply("--platform")) } - header := o.Sprint(InfoHeader) + opt := &options{ + header: InfoHeader, + } - _, _ = fmt.Fprint(o, "\n", header) + for _, override := range opts { + override(opt) + } + + h := o.Sprint(opt.header) + + _, _ = fmt.Fprint(o, "\n", h) s := fmt.Sprintf(format, args...) for idx, line := range strings.Split(s, "\n") { if idx > 0 { - _, _ = fmt.Fprint(o, strings.Repeat(" ", Width(header))) + _, _ = fmt.Fprint(o, strings.Repeat(" ", Width(h))) } l := line @@ -37,3 +57,16 @@ func (o Output) PrintNote(format string, args ...any) { _, _ = fmt.Fprintln(o, l) } } + +func (o Output) PrintNote(format string, args ...any) { + o.printNoteWithOptions(format, args, withHeader(InfoHeader)) +} + +var warningHeader = Str{ + Plain: " Warn -> ", + Fancy: aec.Bold.Apply(aec.LightYellowB.Apply(aec.BlackF.Apply("w")) + " " + ColorWarning.Apply("Warn → ")), +} + +func (o Output) PrintWarning(format string, args ...any) { + o.printNoteWithOptions(format, args, withHeader(warningHeader)) +} From ccd5bd8d5754d8924905b05a67dc8ca11c280baf Mon Sep 17 00:00:00 2001 From: Alano Terblanche <18033717+Benehiko@users.noreply.github.com> Date: Fri, 4 Jul 2025 14:05:11 +0200 Subject: [PATCH 3/3] registry: warn of DOCKER_AUTH_CONFIG usage in login and logout Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com> --- cli/command/registry/login.go | 3 +++ cli/command/registry/logout.go | 2 ++ cli/command/registry/warning.go | 18 ++++++++++++++++++ 3 files changed, 23 insertions(+) create mode 100644 cli/command/registry/warning.go diff --git a/cli/command/registry/login.go b/cli/command/registry/login.go index ce5e584859..3679e51edd 100644 --- a/cli/command/registry/login.go +++ b/cli/command/registry/login.go @@ -110,6 +110,9 @@ func runLogin(ctx context.Context, dockerCLI command.Cli, opts loginOptions) err if err := verifyLoginOptions(dockerCLI, &opts); err != nil { return err } + + maybePrintEnvAuthWarning(dockerCLI) + var ( serverAddress string msg string diff --git a/cli/command/registry/logout.go b/cli/command/registry/logout.go index 6dc75dc585..2af2cdad3f 100644 --- a/cli/command/registry/logout.go +++ b/cli/command/registry/logout.go @@ -36,6 +36,8 @@ func NewLogoutCommand(dockerCli command.Cli) *cobra.Command { } func runLogout(ctx context.Context, dockerCLI command.Cli, serverAddress string) error { + maybePrintEnvAuthWarning(dockerCLI) + var isDefaultRegistry bool if serverAddress == "" { diff --git a/cli/command/registry/warning.go b/cli/command/registry/warning.go new file mode 100644 index 0000000000..22a8c8655b --- /dev/null +++ b/cli/command/registry/warning.go @@ -0,0 +1,18 @@ +package registry + +import ( + "os" + + "github.com/docker/cli/cli/command" + "github.com/docker/cli/cli/config/configfile" + "github.com/docker/cli/internal/tui" +) + +// maybePrintEnvAuthWarning if the `DOCKER_AUTH_CONFIG` environment variable is +// set this function will output a warning to stdErr +func maybePrintEnvAuthWarning(out command.Streams) { + if os.Getenv(configfile.DockerEnvConfigKey) != "" { + tui.NewOutput(out.Err()). + PrintWarning("%[1]s is set and takes precedence.\nUnset %[1]s to restore the CLI auth behaviour.\n", configfile.DockerEnvConfigKey) + } +}