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 4a0f8c8ae..a27629256 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 5381c1b55..460bac721 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 573a2e0e7..9ec11a410 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 aec5ef7a5..5962ea2f3 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 9bd0aa840..20377bc24 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 28223d273..05a0535d7 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 28fa4f89e..852bc86e1 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 fa4ee9069..bf7896638 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 b7b7b5ec8..65aee25d2 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 ddc811838..368604a5c 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 9edd68267..676076fc9 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 346db9af1..000000000 --- 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 -}