github.com/rawahars/moby@v24.0.4+incompatible/daemon/containerd/resolver.go (about) 1 package containerd 2 3 import ( 4 "context" 5 "crypto/tls" 6 "errors" 7 "net/http" 8 9 "github.com/containerd/containerd/remotes" 10 "github.com/containerd/containerd/remotes/docker" 11 "github.com/containerd/containerd/version" 12 registrytypes "github.com/docker/docker/api/types/registry" 13 "github.com/docker/docker/dockerversion" 14 "github.com/docker/docker/pkg/useragent" 15 "github.com/docker/docker/registry" 16 "github.com/sirupsen/logrus" 17 ) 18 19 func (i *ImageService) newResolverFromAuthConfig(ctx context.Context, authConfig *registrytypes.AuthConfig) (remotes.Resolver, docker.StatusTracker) { 20 tracker := docker.NewInMemoryTracker() 21 hostsFn := i.registryHosts.RegistryHosts() 22 23 hosts := hostsWrapper(hostsFn, authConfig, i.registryService) 24 headers := http.Header{} 25 headers.Set("User-Agent", dockerversion.DockerUserAgent(ctx, useragent.VersionInfo{Name: "containerd-client", Version: version.Version}, useragent.VersionInfo{Name: "storage-driver", Version: i.snapshotter})) 26 27 return docker.NewResolver(docker.ResolverOptions{ 28 Hosts: hosts, 29 Tracker: tracker, 30 Headers: headers, 31 }), tracker 32 } 33 34 func hostsWrapper(hostsFn docker.RegistryHosts, optAuthConfig *registrytypes.AuthConfig, regService RegistryConfigProvider) docker.RegistryHosts { 35 var authorizer docker.Authorizer 36 if optAuthConfig != nil { 37 authorizer = docker.NewDockerAuthorizer(authorizationCredsFromAuthConfig(*optAuthConfig)) 38 } 39 40 return func(n string) ([]docker.RegistryHost, error) { 41 hosts, err := hostsFn(n) 42 if err != nil { 43 return nil, err 44 } 45 46 for i := range hosts { 47 if hosts[i].Authorizer == nil { 48 hosts[i].Authorizer = authorizer 49 isInsecure := regService.IsInsecureRegistry(hosts[i].Host) 50 if hosts[i].Client.Transport != nil && isInsecure { 51 hosts[i].Client.Transport = httpFallback{super: hosts[i].Client.Transport} 52 } 53 } 54 } 55 return hosts, nil 56 } 57 } 58 59 func authorizationCredsFromAuthConfig(authConfig registrytypes.AuthConfig) docker.AuthorizerOpt { 60 cfgHost := registry.ConvertToHostname(authConfig.ServerAddress) 61 if cfgHost == "" || cfgHost == registry.IndexHostname { 62 cfgHost = registry.DefaultRegistryHost 63 } 64 65 return docker.WithAuthCreds(func(host string) (string, string, error) { 66 if cfgHost != host { 67 logrus.WithFields(logrus.Fields{ 68 "host": host, 69 "cfgHost": cfgHost, 70 }).Warn("Host doesn't match") 71 return "", "", nil 72 } 73 if authConfig.IdentityToken != "" { 74 return "", authConfig.IdentityToken, nil 75 } 76 return authConfig.Username, authConfig.Password, nil 77 }) 78 } 79 80 type httpFallback struct { 81 super http.RoundTripper 82 } 83 84 func (f httpFallback) RoundTrip(r *http.Request) (*http.Response, error) { 85 resp, err := f.super.RoundTrip(r) 86 var tlsErr tls.RecordHeaderError 87 if errors.As(err, &tlsErr) && string(tlsErr.RecordHeader[:]) == "HTTP/" { 88 // server gave HTTP response to HTTPS client 89 plainHttpUrl := *r.URL 90 plainHttpUrl.Scheme = "http" 91 92 plainHttpRequest := *r 93 plainHttpRequest.URL = &plainHttpUrl 94 95 return http.DefaultTransport.RoundTrip(&plainHttpRequest) 96 } 97 98 return resp, err 99 }