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) + } +} 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 } 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)) +}