Merge pull request #50557 from thaJeztah/registry_deadcode

daemon/pkg/registry: remove unused code
This commit is contained in:
Sebastiaan van Stijn
2025-07-29 13:38:00 +02:00
committed by GitHub
7 changed files with 11 additions and 430 deletions

View File

@@ -9,6 +9,5 @@ import (
// AuthenticateToRegistry checks the validity of credentials in authConfig
func (daemon *Daemon) AuthenticateToRegistry(ctx context.Context, authConfig *registry.AuthConfig) (string, error) {
_, token, err := daemon.registryService.Auth(ctx, authConfig, dockerversion.DockerUserAgent(ctx))
return token, err
return daemon.registryService.Auth(ctx, authConfig, dockerversion.DockerUserAgent(ctx))
}

View File

@@ -17,6 +17,7 @@ import (
"github.com/containerd/log"
"github.com/distribution/reference"
"github.com/docker/docker/daemon/internal/rootless"
"github.com/moby/moby/api/types/registry"
)
@@ -66,14 +67,6 @@ var (
})
)
// runningWithRootlessKit is a fork of [rootless.RunningWithRootlessKit],
// but inlining it to prevent adding that as a dependency for docker/cli.
//
// [rootless.RunningWithRootlessKit]: https://github.com/moby/moby/blob/b4bdf12daec84caaf809a639f923f7370d4926ad/pkg/rootless/rootless.go#L5-L8
func runningWithRootlessKit() bool {
return runtime.GOOS == "linux" && os.Getenv("ROOTLESSKIT_STATE_DIR") != ""
}
// CertsDir is the directory where certificates are stored.
//
// - Linux: "/etc/docker/certs.d/"
@@ -83,7 +76,7 @@ func runningWithRootlessKit() bool {
// TODO(thaJeztah): certsDir but stored in our config, and passed when needed. For the CLI, we should also default to same path as rootless.
func CertsDir() string {
certsDir := "/etc/docker/certs.d"
if runningWithRootlessKit() {
if runtime.GOOS == "linux" && rootless.RunningWithRootlessKit() {
if configHome, _ := os.UserConfigDir(); configHome != "" {
certsDir = filepath.Join(configHome, "docker", "certs.d")
}
@@ -328,10 +321,6 @@ func normalizeIndexName(val string) string {
return val
}
func hasScheme(reposName string) bool {
return strings.Contains(reposName, "://")
}
func validateHostPort(s string) error {
// Split host and port, and in case s can not be split, assume host only
host, port, err := net.SplitHostPort(s)
@@ -381,69 +370,3 @@ func GetAuthConfigKey(index *registry.IndexInfo) string {
}
return index.Name
}
// ParseRepositoryInfo performs the breakdown of a repository name into a
// [RepositoryInfo], but lacks registry configuration.
//
// It is used by the Docker cli to interact with registry-related endpoints.
func ParseRepositoryInfo(reposName reference.Named) (*RepositoryInfo, error) {
indexName := normalizeIndexName(reference.Domain(reposName))
if indexName == IndexName {
return &RepositoryInfo{
Name: reference.TrimNamed(reposName),
Index: &registry.IndexInfo{
Name: IndexName,
Mirrors: []string{},
Secure: true,
Official: true,
},
}, nil
}
return &RepositoryInfo{
Name: reference.TrimNamed(reposName),
Index: &registry.IndexInfo{
Name: indexName,
Mirrors: []string{},
Secure: !isInsecure(indexName),
},
}, nil
}
// isInsecure is used to detect whether a registry domain or IP-address is allowed
// to use an insecure (non-TLS, or self-signed cert) connection according to the
// defaults, which allows for insecure connections with registries running on a
// loopback address ("localhost", "::1/128", "127.0.0.0/8").
//
// It is used in situations where we don't have access to the daemon's configuration,
// for example, when used from the client / CLI.
func isInsecure(hostNameOrIP string) bool {
// Attempt to strip port if present; this also strips brackets for
// IPv6 addresses with a port (e.g. "[::1]:5000").
//
// This is best-effort; we'll continue using the address as-is if it fails.
if host, _, err := net.SplitHostPort(hostNameOrIP); err == nil {
hostNameOrIP = host
}
if hostNameOrIP == "127.0.0.1" || hostNameOrIP == "::1" || strings.EqualFold(hostNameOrIP, "localhost") {
// Fast path; no need to resolve these, assuming nobody overrides
// "localhost" for anything else than a loopback address (sorry, not sorry).
return true
}
var addresses []net.IP
if ip := net.ParseIP(hostNameOrIP); ip != nil {
addresses = append(addresses, ip)
} else {
// Try to resolve the host's IP-addresses.
addrs, _ := lookupIP(hostNameOrIP)
addresses = append(addresses, addrs...)
}
for _, addr := range addresses {
if addr.IsLoopback() {
return true
}
}
return false
}

View File

@@ -55,13 +55,6 @@ func hasFile(files []os.DirEntry, name string) bool {
return false
}
// ReadCertsDirectory reads the directory for TLS certificates
// including roots and certificate pairs and updates the
// provided TLS configuration.
func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error {
return loadTLSConfig(context.TODO(), directory, tlsConfig)
}
// loadTLSConfig reads the directory for TLS certificates including roots and
// certificate pairs, and updates the provided TLS configuration.
func loadTLSConfig(ctx context.Context, directory string, tlsConfig *tls.Config) error {

View File

@@ -34,301 +34,6 @@ func overrideLookupIP(t *testing.T) {
})
}
func TestParseRepositoryInfo(t *testing.T) {
type staticRepositoryInfo struct {
Index *registry.IndexInfo
RemoteName string
CanonicalName string
LocalName string
}
tests := map[string]staticRepositoryInfo{
"fooo/bar": {
Index: &registry.IndexInfo{
Name: IndexName,
Mirrors: []string{},
Official: true,
Secure: true,
},
RemoteName: "fooo/bar",
LocalName: "fooo/bar",
CanonicalName: "docker.io/fooo/bar",
},
"library/ubuntu": {
Index: &registry.IndexInfo{
Name: IndexName,
Mirrors: []string{},
Official: true,
Secure: true,
},
RemoteName: "library/ubuntu",
LocalName: "ubuntu",
CanonicalName: "docker.io/library/ubuntu",
},
"nonlibrary/ubuntu": {
Index: &registry.IndexInfo{
Name: IndexName,
Mirrors: []string{},
Official: true,
Secure: true,
},
RemoteName: "nonlibrary/ubuntu",
LocalName: "nonlibrary/ubuntu",
CanonicalName: "docker.io/nonlibrary/ubuntu",
},
"ubuntu": {
Index: &registry.IndexInfo{
Name: IndexName,
Mirrors: []string{},
Official: true,
Secure: true,
},
RemoteName: "library/ubuntu",
LocalName: "ubuntu",
CanonicalName: "docker.io/library/ubuntu",
},
"other/library": {
Index: &registry.IndexInfo{
Name: IndexName,
Mirrors: []string{},
Official: true,
Secure: true,
},
RemoteName: "other/library",
LocalName: "other/library",
CanonicalName: "docker.io/other/library",
},
"127.0.0.1:8000/private/moonbase": {
Index: &registry.IndexInfo{
Name: "127.0.0.1:8000",
Mirrors: []string{},
Official: false,
Secure: false,
},
RemoteName: "private/moonbase",
LocalName: "127.0.0.1:8000/private/moonbase",
CanonicalName: "127.0.0.1:8000/private/moonbase",
},
"127.0.0.1:8000/privatebase": {
Index: &registry.IndexInfo{
Name: "127.0.0.1:8000",
Mirrors: []string{},
Official: false,
Secure: false,
},
RemoteName: "privatebase",
LocalName: "127.0.0.1:8000/privatebase",
CanonicalName: "127.0.0.1:8000/privatebase",
},
"[::1]:8000/private/moonbase": {
Index: &registry.IndexInfo{
Name: "[::1]:8000",
Mirrors: []string{},
Official: false,
Secure: false,
},
RemoteName: "private/moonbase",
LocalName: "[::1]:8000/private/moonbase",
CanonicalName: "[::1]:8000/private/moonbase",
},
"[::1]:8000/privatebase": {
Index: &registry.IndexInfo{
Name: "[::1]:8000",
Mirrors: []string{},
Official: false,
Secure: false,
},
RemoteName: "privatebase",
LocalName: "[::1]:8000/privatebase",
CanonicalName: "[::1]:8000/privatebase",
},
// IPv6 only has a single loopback address, so ::2 is not a loopback,
// hence not marked "insecure".
"[::2]:8000/private/moonbase": {
Index: &registry.IndexInfo{
Name: "[::2]:8000",
Mirrors: []string{},
Official: false,
Secure: true,
},
RemoteName: "private/moonbase",
LocalName: "[::2]:8000/private/moonbase",
CanonicalName: "[::2]:8000/private/moonbase",
},
// IPv6 only has a single loopback address, so ::2 is not a loopback,
// hence not marked "insecure".
"[::2]:8000/privatebase": {
Index: &registry.IndexInfo{
Name: "[::2]:8000",
Mirrors: []string{},
Official: false,
Secure: true,
},
RemoteName: "privatebase",
LocalName: "[::2]:8000/privatebase",
CanonicalName: "[::2]:8000/privatebase",
},
"localhost:8000/private/moonbase": {
Index: &registry.IndexInfo{
Name: "localhost:8000",
Mirrors: []string{},
Official: false,
Secure: false,
},
RemoteName: "private/moonbase",
LocalName: "localhost:8000/private/moonbase",
CanonicalName: "localhost:8000/private/moonbase",
},
"localhost:8000/privatebase": {
Index: &registry.IndexInfo{
Name: "localhost:8000",
Mirrors: []string{},
Official: false,
Secure: false,
},
RemoteName: "privatebase",
LocalName: "localhost:8000/privatebase",
CanonicalName: "localhost:8000/privatebase",
},
"example.com/private/moonbase": {
Index: &registry.IndexInfo{
Name: "example.com",
Mirrors: []string{},
Official: false,
Secure: true,
},
RemoteName: "private/moonbase",
LocalName: "example.com/private/moonbase",
CanonicalName: "example.com/private/moonbase",
},
"example.com/privatebase": {
Index: &registry.IndexInfo{
Name: "example.com",
Mirrors: []string{},
Official: false,
Secure: true,
},
RemoteName: "privatebase",
LocalName: "example.com/privatebase",
CanonicalName: "example.com/privatebase",
},
"example.com:8000/private/moonbase": {
Index: &registry.IndexInfo{
Name: "example.com:8000",
Mirrors: []string{},
Official: false,
Secure: true,
},
RemoteName: "private/moonbase",
LocalName: "example.com:8000/private/moonbase",
CanonicalName: "example.com:8000/private/moonbase",
},
"example.com:8000/privatebase": {
Index: &registry.IndexInfo{
Name: "example.com:8000",
Mirrors: []string{},
Official: false,
Secure: true,
},
RemoteName: "privatebase",
LocalName: "example.com:8000/privatebase",
CanonicalName: "example.com:8000/privatebase",
},
"localhost/private/moonbase": {
Index: &registry.IndexInfo{
Name: "localhost",
Mirrors: []string{},
Official: false,
Secure: false,
},
RemoteName: "private/moonbase",
LocalName: "localhost/private/moonbase",
CanonicalName: "localhost/private/moonbase",
},
"localhost/privatebase": {
Index: &registry.IndexInfo{
Name: "localhost",
Mirrors: []string{},
Official: false,
Secure: false,
},
RemoteName: "privatebase",
LocalName: "localhost/privatebase",
CanonicalName: "localhost/privatebase",
},
IndexName + "/public/moonbase": {
Index: &registry.IndexInfo{
Name: IndexName,
Mirrors: []string{},
Official: true,
Secure: true,
},
RemoteName: "public/moonbase",
LocalName: "public/moonbase",
CanonicalName: "docker.io/public/moonbase",
},
"index." + IndexName + "/public/moonbase": {
Index: &registry.IndexInfo{
Name: IndexName,
Mirrors: []string{},
Official: true,
Secure: true,
},
RemoteName: "public/moonbase",
LocalName: "public/moonbase",
CanonicalName: "docker.io/public/moonbase",
},
"ubuntu-12.04-base": {
Index: &registry.IndexInfo{
Name: IndexName,
Mirrors: []string{},
Official: true,
Secure: true,
},
RemoteName: "library/ubuntu-12.04-base",
LocalName: "ubuntu-12.04-base",
CanonicalName: "docker.io/library/ubuntu-12.04-base",
},
IndexName + "/ubuntu-12.04-base": {
Index: &registry.IndexInfo{
Name: IndexName,
Mirrors: []string{},
Official: true,
Secure: true,
},
RemoteName: "library/ubuntu-12.04-base",
LocalName: "ubuntu-12.04-base",
CanonicalName: "docker.io/library/ubuntu-12.04-base",
},
"index." + IndexName + "/ubuntu-12.04-base": {
Index: &registry.IndexInfo{
Name: IndexName,
Mirrors: []string{},
Official: true,
Secure: true,
},
RemoteName: "library/ubuntu-12.04-base",
LocalName: "ubuntu-12.04-base",
CanonicalName: "docker.io/library/ubuntu-12.04-base",
},
}
for reposName, expected := range tests {
t.Run(reposName, func(t *testing.T) {
named, err := reference.ParseNormalizedNamed(reposName)
assert.NilError(t, err)
repoInfo, err := ParseRepositoryInfo(named)
assert.NilError(t, err)
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))
})
}
}
func TestNewIndexInfo(t *testing.T) {
overrideLookupIP(t)

View File

@@ -83,7 +83,7 @@ func (s *Service) Search(ctx context.Context, searchFilters filters.Args, term s
}
func (s *Service) searchUnfiltered(ctx context.Context, term string, limit int, authConfig *registry.AuthConfig, headers http.Header) (*registry.SearchResults, error) {
if hasScheme(term) {
if strings.Contains(term, "://") {
return nil, invalidParamf("invalid repository name: repository name (%s) should not have a scheme", term)
}
@@ -143,28 +143,3 @@ func splitReposSearchTerm(reposName string) (string, string) {
}
return nameParts[0], nameParts[1]
}
// ParseSearchIndexInfo will use repository name to get back an indexInfo.
//
// TODO(thaJeztah) this function is only used by the CLI, and used to get
// information of the registry (to provide credentials if needed). We should
// move this function (or equivalent) to the CLI, as it's doing too much just
// for that.
func ParseSearchIndexInfo(reposName string) (*registry.IndexInfo, error) {
indexName, _ := splitReposSearchTerm(reposName)
indexName = normalizeIndexName(indexName)
if indexName == IndexName {
return &registry.IndexInfo{
Name: IndexName,
Mirrors: []string{},
Secure: true,
Official: true,
}, nil
}
return &registry.IndexInfo{
Name: indexName,
Mirrors: []string{},
Secure: !isInsecure(indexName),
}, nil
}

View File

@@ -56,7 +56,7 @@ func (s *Service) ReplaceConfig(options ServiceOptions) (commit func(), _ error)
// Auth contacts the public registry with the provided credentials,
// and returns OK if authentication was successful.
// It can be used to verify the validity of a client's credentials.
func (s *Service) Auth(ctx context.Context, authConfig *registry.AuthConfig, userAgent string) (statusMessage, token string, _ error) {
func (s *Service) Auth(ctx context.Context, authConfig *registry.AuthConfig, userAgent string) (token string, _ error) {
// TODO Use ctx when searching for repositories
registryHostName := IndexHostname
@@ -67,7 +67,7 @@ func (s *Service) Auth(ctx context.Context, authConfig *registry.AuthConfig, use
}
u, err := url.Parse(serverAddress)
if err != nil {
return "", "", invalidParamWrapf(err, "unable to parse server address")
return "", invalidParamWrapf(err, "unable to parse server address")
}
registryHostName = u.Host
}
@@ -79,9 +79,9 @@ func (s *Service) Auth(ctx context.Context, authConfig *registry.AuthConfig, use
s.mu.RUnlock()
if err != nil {
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
return "", "", err
return "", err
}
return "", "", invalidParam(err)
return "", invalidParam(err)
}
var lastErr error
@@ -90,7 +90,7 @@ func (s *Service) Auth(ctx context.Context, authConfig *registry.AuthConfig, use
if err != nil {
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) || cerrdefs.IsUnauthorized(err) {
// Failed to authenticate; don't continue with (non-TLS) endpoints.
return "", "", err
return "", err
}
// Try next endpoint
log.G(ctx).WithFields(log.Fields{
@@ -101,11 +101,10 @@ func (s *Service) Auth(ctx context.Context, authConfig *registry.AuthConfig, use
continue
}
// TODO(thaJeztah): move the statusMessage to the API endpoint; we don't need to produce that here?
return "Login Succeeded", authToken, nil
return authToken, nil
}
return "", "", lastErr
return "", lastErr
}
// ResolveAuthConfig looks up authentication for the given reference from the

View File

@@ -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
}