From e504faf6dae1414ff281686d7830848b31eb86c2 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 22 Jul 2025 22:07:51 +0200 Subject: [PATCH] cli/command/registry: remove uses of registry.ParseSearchIndexInfo This utility was only used in the CLI, but the implementation was based on it being used on the daemon side, so included resolving the host's IP-address, mirrors, etc. The only reason it's used in the CLI is to provide credentials for the registry that's being searched, so reduce it to just that. There's more cleaning up to do in this area, so to make our lives easier, it's implemented locally as non-exported functions; likely to be replaced with something else. Signed-off-by: Sebastiaan van Stijn --- cli/command/registry/search.go | 44 +++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/cli/command/registry/search.go b/cli/command/registry/search.go index fdd3a99dc2..150cbe3eb5 100644 --- a/cli/command/registry/search.go +++ b/cli/command/registry/search.go @@ -3,12 +3,12 @@ package registry import ( "context" "fmt" + "strings" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command/formatter" "github.com/docker/cli/opts" - "github.com/docker/docker/registry" registrytypes "github.com/moby/moby/api/types/registry" "github.com/spf13/cobra" ) @@ -52,13 +52,7 @@ func runSearch(ctx context.Context, dockerCli command.Cli, options searchOptions if options.filter.Value().Contains("is-automated") { _, _ = fmt.Fprintln(dockerCli.Err(), `WARNING: the "is-automated" filter is deprecated, and searching for "is-automated=true" will not yield any results in future.`) } - indexInfo, err := registry.ParseSearchIndexInfo(options.term) - if err != nil { - return err - } - - authConfig := command.ResolveAuthConfig(dockerCli.ConfigFile(), indexInfo) - encodedAuth, err := registrytypes.EncodeAuthConfig(authConfig) + encodedAuth, err := getAuth(dockerCli, options.term) if err != nil { return err } @@ -80,3 +74,37 @@ func runSearch(ctx context.Context, dockerCli command.Cli, options searchOptions } return SearchWrite(searchCtx, results) } + +// authConfigKey is the key used to store credentials for Docker Hub. It is +// a copy of [registry.IndexServer]. +// +// [registry.IndexServer]: https://pkg.go.dev/github.com/docker/docker/registry#IndexServer +const authConfigKey = "https://index.docker.io/v1/" + +// getAuth will use fetch auth based on the given search-term. If the search +// does not contain a hostname for the registry, it assumes Docker Hub is used, +// and resolves authentication for Docker Hub, otherwise it resolves authentication +// for the given registry. +func getAuth(dockerCLI command.Cli, reposName string) (encodedAuth string, err error) { + authCfgKey := splitReposSearchTerm(reposName) + if authCfgKey == "docker.io" || authCfgKey == "index.docker.io" { + authCfgKey = authConfigKey + } + + // Ignoring errors here, which was the existing behavior (likely + // "no credentials found"). We'll get an error when search failed, + // so fine to ignore in most situations. + authConfig, _ := dockerCLI.ConfigFile().GetAuthConfig(authCfgKey) + return registrytypes.EncodeAuthConfig(registrytypes.AuthConfig(authConfig)) +} + +// splitReposSearchTerm breaks a search term into an index name and remote name +func splitReposSearchTerm(reposName string) string { + nameParts := strings.SplitN(reposName, "/", 2) + if len(nameParts) == 1 || (!strings.Contains(nameParts[0], ".") && !strings.Contains(nameParts[0], ":") && nameParts[0] != "localhost") { + // This is a Docker Hub repository (ex: samalba/hipache or ubuntu), + // use the default Docker Hub registry (docker.io) + return "docker.io" + } + return nameParts[0] +}