From efdf008933cab0e767b5eea5741d37d06d7613d8 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 (cherry picked from commit 21e8bbc8a28c8ca1c1ec139c4397f7b45462d064) 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 da036af8ee..cd79ff9289 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 e0288b9cba..00268e7592 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/docker/docker/api/types/image" registrytypes "github.com/docker/docker/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 9626d3c647..33a7179edd 100644 --- a/cli/command/plugin/install.go +++ b/cli/command/plugin/install.go @@ -65,7 +65,7 @@ func buildPullConfig(ctx context.Context, dockerCli command.Cli, opts pluginOpti return types.PluginInstallOptions{}, err } - repoInfo := registry.ParseRepositoryInfo(ref) + indexInfo := registry.NewIndexInfo(ref) remote := ref.String() _, isCanonical := ref.(reference.Canonical) @@ -83,7 +83,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 types.PluginInstallOptions{}, err diff --git a/cli/command/plugin/push.go b/cli/command/plugin/push.go index 36fcb79644..573ae3d0ae 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 @@ -63,6 +63,10 @@ func runPush(ctx context.Context, dockerCli command.Cli, opts pushOptions) error defer responseBody.Close() 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 4b66912349..ea79161ad5 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 4a1e8b5247..ce6e774969 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 647c3243a5..eeddc912b3 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 047990c453..87a33e7ca2 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/docker/docker/api/types" registrytypes "github.com/docker/docker/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 f2f026c5b9..04414cc88b 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 e7cbef3a0b..f1747aa86b 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 c35eb9fad2..0000000000 --- a/internal/registry/types.go +++ /dev/null @@ -1,13 +0,0 @@ -package registry - -import ( - "github.com/distribution/reference" - "github.com/docker/docker/api/types/registry" -) - -// RepositoryInfo describes a repository -type RepositoryInfo struct { - Name reference.Named - // Index points to registry information - Index *registry.IndexInfo -}