From 21e8bbc8a28c8ca1c1ec139c4397f7b45462d064 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sun, 3 Aug 2025 14:39:30 +0200 Subject: [PATCH] internal/registry: remove RepositoryInfo, add NewIndexInfo Most places only use IndexInfo (and may not even need that), so replace the use of ParseRepositoryInfo for NewIndexInfo, and move the RepositoryInfo type to the trust package, which uses it as part of its ImageRefAndAuth struct. Signed-off-by: Sebastiaan van Stijn --- cli/command/image/push.go | 6 +++--- cli/command/image/trust.go | 7 +++++-- cli/command/plugin/install.go | 4 ++-- cli/command/plugin/push.go | 8 ++++++-- cli/command/service/trust.go | 9 ++++++--- cli/registry/client/endpoint.go | 3 +-- cli/registry/client/fetcher.go | 6 ++---- cli/trust/trust.go | 26 ++++++++++++++++++-------- cli/trust/trust_push.go | 3 +-- internal/registry/config.go | 27 +++++++++++---------------- internal/registry/registry_test.go | 13 +++++++------ internal/registry/types.go | 13 ------------- 12 files changed, 62 insertions(+), 63 deletions(-) delete mode 100644 internal/registry/types.go diff --git a/cli/command/image/push.go b/cli/command/image/push.go index 4a0f8c8ae2..a27629256a 100644 --- a/cli/command/image/push.go +++ b/cli/command/image/push.go @@ -105,10 +105,10 @@ To push the complete multi-platform image, remove the --platform flag. } // Resolve the Repository name from fqn to RepositoryInfo - repoInfo := registry.ParseRepositoryInfo(ref) + indexInfo := registry.NewIndexInfo(ref) // Resolve the Auth config relevant for this server - authConfig := command.ResolveAuthConfig(dockerCli.ConfigFile(), repoInfo.Index) + authConfig := command.ResolveAuthConfig(dockerCli.ConfigFile(), indexInfo) encodedAuth, err := registrytypes.EncodeAuthConfig(authConfig) if err != nil { return err @@ -134,7 +134,7 @@ To push the complete multi-platform image, remove the --platform flag. defer responseBody.Close() if !opts.untrusted { // TODO pushTrustedReference currently doesn't respect `--quiet` - return pushTrustedReference(ctx, dockerCli, repoInfo, ref, authConfig, responseBody) + return pushTrustedReference(ctx, dockerCli, indexInfo, ref, authConfig, responseBody) } if opts.quiet { diff --git a/cli/command/image/trust.go b/cli/command/image/trust.go index 5381c1b55b..460bac7214 100644 --- a/cli/command/image/trust.go +++ b/cli/command/image/trust.go @@ -11,7 +11,6 @@ import ( "github.com/docker/cli/cli/streams" "github.com/docker/cli/cli/trust" "github.com/docker/cli/internal/jsonstream" - "github.com/docker/cli/internal/registry" "github.com/moby/moby/api/types/image" registrytypes "github.com/moby/moby/api/types/registry" "github.com/opencontainers/go-digest" @@ -42,7 +41,11 @@ func newNotaryClient(cli command.Streams, imgRefAndAuth trust.ImageRefAndAuth) ( } // pushTrustedReference pushes a canonical reference to the trust server. -func pushTrustedReference(ctx context.Context, ioStreams command.Streams, repoInfo *registry.RepositoryInfo, ref reference.Named, authConfig registrytypes.AuthConfig, in io.Reader) error { +func pushTrustedReference(ctx context.Context, ioStreams command.Streams, indexInfo *registrytypes.IndexInfo, ref reference.Named, authConfig registrytypes.AuthConfig, in io.Reader) error { + repoInfo := &trust.RepositoryInfo{ + Name: reference.TrimNamed(ref), + Index: indexInfo, + } return trust.PushTrustedReference(ctx, ioStreams, repoInfo, ref, authConfig, in, command.UserAgent()) } diff --git a/cli/command/plugin/install.go b/cli/command/plugin/install.go index 573a2e0e78..9ec11a4104 100644 --- a/cli/command/plugin/install.go +++ b/cli/command/plugin/install.go @@ -66,7 +66,7 @@ func buildPullConfig(ctx context.Context, dockerCli command.Cli, opts pluginOpti return client.PluginInstallOptions{}, err } - repoInfo := registry.ParseRepositoryInfo(ref) + indexInfo := registry.NewIndexInfo(ref) remote := ref.String() _, isCanonical := ref.(reference.Canonical) @@ -84,7 +84,7 @@ func buildPullConfig(ctx context.Context, dockerCli command.Cli, opts pluginOpti remote = reference.FamiliarString(trusted) } - authConfig := command.ResolveAuthConfig(dockerCli.ConfigFile(), repoInfo.Index) + authConfig := command.ResolveAuthConfig(dockerCli.ConfigFile(), indexInfo) encodedAuth, err := registrytypes.EncodeAuthConfig(authConfig) if err != nil { return client.PluginInstallOptions{}, err diff --git a/cli/command/plugin/push.go b/cli/command/plugin/push.go index aec5ef7a51..5962ea2f38 100644 --- a/cli/command/plugin/push.go +++ b/cli/command/plugin/push.go @@ -49,8 +49,8 @@ func runPush(ctx context.Context, dockerCli command.Cli, opts pushOptions) error named = reference.TagNameOnly(named) - repoInfo := registry.ParseRepositoryInfo(named) - authConfig := command.ResolveAuthConfig(dockerCli.ConfigFile(), repoInfo.Index) + indexInfo := registry.NewIndexInfo(named) + authConfig := command.ResolveAuthConfig(dockerCli.ConfigFile(), indexInfo) encodedAuth, err := registrytypes.EncodeAuthConfig(authConfig) if err != nil { return err @@ -65,6 +65,10 @@ func runPush(ctx context.Context, dockerCli command.Cli, opts pushOptions) error }() if !opts.untrusted { + repoInfo := &trust.RepositoryInfo{ + Name: reference.TrimNamed(named), + Index: indexInfo, + } return trust.PushTrustedReference(ctx, dockerCli, repoInfo, named, authConfig, responseBody, command.UserAgent()) } diff --git a/cli/command/service/trust.go b/cli/command/service/trust.go index 9bd0aa840e..20377bc24f 100644 --- a/cli/command/service/trust.go +++ b/cli/command/service/trust.go @@ -51,9 +51,12 @@ func resolveServiceImageDigestContentTrust(dockerCli command.Cli, service *swarm } func trustedResolveDigest(cli command.Cli, ref reference.NamedTagged) (reference.Canonical, error) { - repoInfo := registry.ParseRepositoryInfo(ref) - authConfig := command.ResolveAuthConfig(cli.ConfigFile(), repoInfo.Index) - + indexInfo := registry.NewIndexInfo(ref) + authConfig := command.ResolveAuthConfig(cli.ConfigFile(), indexInfo) + repoInfo := &trust.RepositoryInfo{ + Name: reference.TrimNamed(ref), + Index: indexInfo, + } notaryRepo, err := trust.GetNotaryRepository(cli.In(), cli.Out(), command.UserAgent(), repoInfo, &authConfig, "pull") if err != nil { return nil, errors.Wrap(err, "error establishing connection to trust repository") diff --git a/cli/registry/client/endpoint.go b/cli/registry/client/endpoint.go index 28223d2733..05a0535d75 100644 --- a/cli/registry/client/endpoint.go +++ b/cli/registry/client/endpoint.go @@ -34,8 +34,7 @@ func (r repositoryEndpoint) BaseURL() string { func newDefaultRepositoryEndpoint(ref reference.Named, insecure bool) (repositoryEndpoint, error) { repoName := reference.TrimNamed(ref) - repoInfo := registry.ParseRepositoryInfo(ref) - indexInfo := repoInfo.Index + indexInfo := registry.NewIndexInfo(ref) endpoint, err := getDefaultEndpoint(ref, !indexInfo.Secure) if err != nil { diff --git a/cli/registry/client/fetcher.go b/cli/registry/client/fetcher.go index 28fa4f89ec..852bc86e1e 100644 --- a/cli/registry/client/fetcher.go +++ b/cli/registry/client/fetcher.go @@ -221,8 +221,7 @@ func (c *client) iterateEndpoints(ctx context.Context, namedRef reference.Named, } repoName := reference.TrimNamed(namedRef) - repoInfo := registry.ParseRepositoryInfo(namedRef) - indexInfo := repoInfo.Index + indexInfo := registry.NewIndexInfo(namedRef) confirmedTLSRegistries := make(map[string]bool) for _, endpoint := range endpoints { @@ -285,8 +284,7 @@ func allEndpoints(namedRef reference.Named, insecure bool) ([]registry.APIEndpoi if err != nil { return nil, err } - repoInfo := registry.ParseRepositoryInfo(namedRef) - endpoints, err := registryService.Endpoints(context.TODO(), reference.Domain(repoInfo.Name)) + endpoints, err := registryService.Endpoints(context.TODO(), reference.Domain(namedRef)) logrus.Debugf("endpoints for %s: %v", namedRef, endpoints) return endpoints, err } diff --git a/cli/trust/trust.go b/cli/trust/trust.go index fa4ee9069a..bf78966385 100644 --- a/cli/trust/trust.go +++ b/cli/trust/trust.go @@ -95,7 +95,7 @@ func (simpleCredentialStore) SetRefreshToken(*url.URL, string, string) {} // GetNotaryRepository returns a NotaryRepository which stores all the // information needed to operate on a notary repository. // It creates an HTTP transport providing authentication support. -func GetNotaryRepository(in io.Reader, out io.Writer, userAgent string, repoInfo *registry.RepositoryInfo, authConfig *registrytypes.AuthConfig, actions ...string) (client.Repository, error) { +func GetNotaryRepository(in io.Reader, out io.Writer, userAgent string, repoInfo *RepositoryInfo, authConfig *registrytypes.AuthConfig, actions ...string) (client.Repository, error) { server, err := Server(repoInfo.Index) if err != nil { return nil, err @@ -304,11 +304,18 @@ type ImageRefAndAuth struct { original string authConfig *registrytypes.AuthConfig reference reference.Named - repoInfo *registry.RepositoryInfo + repoInfo *RepositoryInfo tag string digest digest.Digest } +// RepositoryInfo describes a repository +type RepositoryInfo struct { + Name reference.Named + // Index points to registry information + Index *registrytypes.IndexInfo +} + // GetImageReferencesAndAuth retrieves the necessary reference and auth information for an image name // as an ImageRefAndAuth struct func GetImageReferencesAndAuth(ctx context.Context, @@ -321,15 +328,18 @@ func GetImageReferencesAndAuth(ctx context.Context, } // Resolve the Repository name from fqn to RepositoryInfo - repoInfo := registry.ParseRepositoryInfo(ref) - authConfig := authResolver(ctx, repoInfo.Index) + indexInfo := registry.NewIndexInfo(ref) + authConfig := authResolver(ctx, indexInfo) return ImageRefAndAuth{ original: imgName, authConfig: &authConfig, reference: ref, - repoInfo: repoInfo, - tag: getTag(ref), - digest: getDigest(ref), + repoInfo: &RepositoryInfo{ + Name: reference.TrimNamed(ref), + Index: indexInfo, + }, + tag: getTag(ref), + digest: getDigest(ref), }, nil } @@ -366,7 +376,7 @@ func (imgRefAuth *ImageRefAndAuth) Reference() reference.Named { } // RepoInfo returns the repository information for a given ImageRefAndAuth -func (imgRefAuth *ImageRefAndAuth) RepoInfo() *registry.RepositoryInfo { +func (imgRefAuth *ImageRefAndAuth) RepoInfo() *RepositoryInfo { return imgRefAuth.repoInfo } diff --git a/cli/trust/trust_push.go b/cli/trust/trust_push.go index b7b7b5ec89..65aee25d20 100644 --- a/cli/trust/trust_push.go +++ b/cli/trust/trust_push.go @@ -11,7 +11,6 @@ import ( "github.com/distribution/reference" "github.com/docker/cli/cli/streams" "github.com/docker/cli/internal/jsonstream" - "github.com/docker/cli/internal/registry" "github.com/moby/moby/api/types" registrytypes "github.com/moby/moby/api/types/registry" "github.com/opencontainers/go-digest" @@ -32,7 +31,7 @@ type Streams interface { // PushTrustedReference pushes a canonical reference to the trust server. // //nolint:gocyclo -func PushTrustedReference(ctx context.Context, ioStreams Streams, repoInfo *registry.RepositoryInfo, ref reference.Named, authConfig registrytypes.AuthConfig, in io.Reader, userAgent string) error { +func PushTrustedReference(ctx context.Context, ioStreams Streams, repoInfo *RepositoryInfo, ref reference.Named, authConfig registrytypes.AuthConfig, in io.Reader, userAgent string) error { // If it is a trusted push we would like to find the target entry which match the // tag provided in the function and then do an AddTarget later. notaryTarget := &client.Target{} diff --git a/internal/registry/config.go b/internal/registry/config.go index ddc8118389..368604a5c7 100644 --- a/internal/registry/config.go +++ b/internal/registry/config.go @@ -252,27 +252,22 @@ func validateHostPort(s string) error { return nil } -// ParseRepositoryInfo performs the breakdown of a repository name into a -// [RepositoryInfo], but lacks registry configuration. -func ParseRepositoryInfo(reposName reference.Named) *RepositoryInfo { +// NewIndexInfo creates a new [registry.IndexInfo] or the given +// repository-name, and detects whether the registry is considered +// "secure" (non-localhost). +func NewIndexInfo(reposName reference.Named) *registry.IndexInfo { indexName := normalizeIndexName(reference.Domain(reposName)) if indexName == IndexName { - return &RepositoryInfo{ - Name: reference.TrimNamed(reposName), - Index: ®istry.IndexInfo{ - Name: IndexName, - Secure: true, - Official: true, - }, + return ®istry.IndexInfo{ + Name: IndexName, + Secure: true, + Official: true, } } - return &RepositoryInfo{ - Name: reference.TrimNamed(reposName), - Index: ®istry.IndexInfo{ - Name: indexName, - Secure: !isInsecure(indexName), - }, + return ®istry.IndexInfo{ + Name: indexName, + Secure: !isInsecure(indexName), } } diff --git a/internal/registry/registry_test.go b/internal/registry/registry_test.go index 9edd682675..676076fc93 100644 --- a/internal/registry/registry_test.go +++ b/internal/registry/registry_test.go @@ -9,7 +9,7 @@ import ( is "gotest.tools/v3/assert/cmp" ) -func TestParseRepositoryInfo(t *testing.T) { +func TestNewIndexInfo(t *testing.T) { type staticRepositoryInfo struct { Index *registry.IndexInfo RemoteName string @@ -269,12 +269,13 @@ func TestParseRepositoryInfo(t *testing.T) { named, err := reference.ParseNormalizedNamed(reposName) assert.NilError(t, err) - repoInfo := ParseRepositoryInfo(named) + indexInfo := NewIndexInfo(named) + repoInfoName := reference.TrimNamed(named) - assert.Check(t, is.DeepEqual(repoInfo.Index, expected.Index)) - assert.Check(t, is.Equal(reference.Path(repoInfo.Name), expected.RemoteName)) - assert.Check(t, is.Equal(reference.FamiliarName(repoInfo.Name), expected.LocalName)) - assert.Check(t, is.Equal(repoInfo.Name.Name(), expected.CanonicalName)) + assert.Check(t, is.DeepEqual(indexInfo, expected.Index)) + assert.Check(t, is.Equal(reference.Path(repoInfoName), expected.RemoteName)) + assert.Check(t, is.Equal(reference.FamiliarName(repoInfoName), expected.LocalName)) + assert.Check(t, is.Equal(repoInfoName.Name(), expected.CanonicalName)) }) } } diff --git a/internal/registry/types.go b/internal/registry/types.go deleted file mode 100644 index 346db9af1c..0000000000 --- a/internal/registry/types.go +++ /dev/null @@ -1,13 +0,0 @@ -package registry - -import ( - "github.com/distribution/reference" - "github.com/moby/moby/api/types/registry" -) - -// RepositoryInfo describes a repository -type RepositoryInfo struct { - Name reference.Named - // Index points to registry information - Index *registry.IndexInfo -}