|
@@ -2,14 +2,11 @@ package registry
|
|
|
|
|
|
import (
|
|
import (
|
|
"crypto/tls"
|
|
"crypto/tls"
|
|
- "fmt"
|
|
|
|
"net/http"
|
|
"net/http"
|
|
"net/url"
|
|
"net/url"
|
|
- "strings"
|
|
|
|
|
|
|
|
"github.com/docker/distribution/registry/client/auth"
|
|
"github.com/docker/distribution/registry/client/auth"
|
|
"github.com/docker/docker/cliconfig"
|
|
"github.com/docker/docker/cliconfig"
|
|
- "github.com/docker/docker/pkg/tlsconfig"
|
|
|
|
)
|
|
)
|
|
|
|
|
|
// Service is a registry service. It tracks configuration data such as a list
|
|
// Service is a registry service. It tracks configuration data such as a list
|
|
@@ -39,7 +36,14 @@ func (s *Service) Auth(authConfig *cliconfig.AuthConfig) (string, error) {
|
|
if err != nil {
|
|
if err != nil {
|
|
return "", err
|
|
return "", err
|
|
}
|
|
}
|
|
- endpoint, err := NewEndpoint(index, nil)
|
|
|
|
|
|
+
|
|
|
|
+ endpointVersion := APIVersion(APIVersionUnknown)
|
|
|
|
+ if V2Only {
|
|
|
|
+ // Override the endpoint to only attempt a v2 ping
|
|
|
|
+ endpointVersion = APIVersion2
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ endpoint, err := NewEndpoint(index, nil, endpointVersion)
|
|
if err != nil {
|
|
if err != nil {
|
|
return "", err
|
|
return "", err
|
|
}
|
|
}
|
|
@@ -56,10 +60,11 @@ func (s *Service) Search(term string, authConfig *cliconfig.AuthConfig, headers
|
|
}
|
|
}
|
|
|
|
|
|
// *TODO: Search multiple indexes.
|
|
// *TODO: Search multiple indexes.
|
|
- endpoint, err := repoInfo.GetEndpoint(http.Header(headers))
|
|
|
|
|
|
+ endpoint, err := NewEndpoint(repoInfo.Index, http.Header(headers), APIVersionUnknown)
|
|
if err != nil {
|
|
if err != nil {
|
|
return nil, err
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
+
|
|
r, err := NewSession(endpoint.client, authConfig, endpoint)
|
|
r, err := NewSession(endpoint.client, authConfig, endpoint)
|
|
if err != nil {
|
|
if err != nil {
|
|
return nil, err
|
|
return nil, err
|
|
@@ -112,108 +117,32 @@ func (s *Service) tlsConfigForMirror(mirror string) (*tls.Config, error) {
|
|
// It gives preference to v2 endpoints over v1, mirrors over the actual
|
|
// It gives preference to v2 endpoints over v1, mirrors over the actual
|
|
// registry, and HTTPS over plain HTTP.
|
|
// registry, and HTTPS over plain HTTP.
|
|
func (s *Service) LookupPullEndpoints(repoName string) (endpoints []APIEndpoint, err error) {
|
|
func (s *Service) LookupPullEndpoints(repoName string) (endpoints []APIEndpoint, err error) {
|
|
- return s.lookupEndpoints(repoName, false)
|
|
|
|
|
|
+ return s.lookupEndpoints(repoName)
|
|
}
|
|
}
|
|
|
|
|
|
// LookupPushEndpoints creates an list of endpoints to try to push to, in order of preference.
|
|
// LookupPushEndpoints creates an list of endpoints to try to push to, in order of preference.
|
|
// It gives preference to v2 endpoints over v1, and HTTPS over plain HTTP.
|
|
// It gives preference to v2 endpoints over v1, and HTTPS over plain HTTP.
|
|
// Mirrors are not included.
|
|
// Mirrors are not included.
|
|
func (s *Service) LookupPushEndpoints(repoName string) (endpoints []APIEndpoint, err error) {
|
|
func (s *Service) LookupPushEndpoints(repoName string) (endpoints []APIEndpoint, err error) {
|
|
- return s.lookupEndpoints(repoName, true)
|
|
|
|
|
|
+ return s.lookupEndpoints(repoName)
|
|
}
|
|
}
|
|
|
|
|
|
-func (s *Service) lookupEndpoints(repoName string, isPush bool) (endpoints []APIEndpoint, err error) {
|
|
|
|
- var cfg = tlsconfig.ServerDefault
|
|
|
|
- tlsConfig := &cfg
|
|
|
|
- if strings.HasPrefix(repoName, DefaultNamespace+"/") {
|
|
|
|
- if !isPush {
|
|
|
|
- // v2 mirrors for pull only
|
|
|
|
- for _, mirror := range s.Config.Mirrors {
|
|
|
|
- mirrorTLSConfig, err := s.tlsConfigForMirror(mirror)
|
|
|
|
- if err != nil {
|
|
|
|
- return nil, err
|
|
|
|
- }
|
|
|
|
- endpoints = append(endpoints, APIEndpoint{
|
|
|
|
- URL: mirror,
|
|
|
|
- // guess mirrors are v2
|
|
|
|
- Version: APIVersion2,
|
|
|
|
- Mirror: true,
|
|
|
|
- TrimHostname: true,
|
|
|
|
- TLSConfig: mirrorTLSConfig,
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- // v2 registry
|
|
|
|
- endpoints = append(endpoints, APIEndpoint{
|
|
|
|
- URL: DefaultV2Registry,
|
|
|
|
- Version: APIVersion2,
|
|
|
|
- Official: true,
|
|
|
|
- TrimHostname: true,
|
|
|
|
- TLSConfig: tlsConfig,
|
|
|
|
- })
|
|
|
|
- // v1 registry
|
|
|
|
- endpoints = append(endpoints, APIEndpoint{
|
|
|
|
- URL: DefaultV1Registry,
|
|
|
|
- Version: APIVersion1,
|
|
|
|
- Official: true,
|
|
|
|
- TrimHostname: true,
|
|
|
|
- TLSConfig: tlsConfig,
|
|
|
|
- })
|
|
|
|
- return endpoints, nil
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- slashIndex := strings.IndexRune(repoName, '/')
|
|
|
|
- if slashIndex <= 0 {
|
|
|
|
- return nil, fmt.Errorf("invalid repo name: missing '/': %s", repoName)
|
|
|
|
- }
|
|
|
|
- hostname := repoName[:slashIndex]
|
|
|
|
|
|
+func (s *Service) lookupEndpoints(repoName string) (endpoints []APIEndpoint, err error) {
|
|
|
|
+ endpoints, err = s.lookupV2Endpoints(repoName)
|
|
|
|
|
|
- tlsConfig, err = s.TLSConfig(hostname)
|
|
|
|
if err != nil {
|
|
if err != nil {
|
|
return nil, err
|
|
return nil, err
|
|
}
|
|
}
|
|
- isSecure := !tlsConfig.InsecureSkipVerify
|
|
|
|
|
|
|
|
- v2Versions := []auth.APIVersion{
|
|
|
|
- {
|
|
|
|
- Type: "registry",
|
|
|
|
- Version: "2.0",
|
|
|
|
- },
|
|
|
|
- }
|
|
|
|
- endpoints = []APIEndpoint{
|
|
|
|
- {
|
|
|
|
- URL: "https://" + hostname,
|
|
|
|
- Version: APIVersion2,
|
|
|
|
- TrimHostname: true,
|
|
|
|
- TLSConfig: tlsConfig,
|
|
|
|
- VersionHeader: DefaultRegistryVersionHeader,
|
|
|
|
- Versions: v2Versions,
|
|
|
|
- },
|
|
|
|
- {
|
|
|
|
- URL: "https://" + hostname,
|
|
|
|
- Version: APIVersion1,
|
|
|
|
- TrimHostname: true,
|
|
|
|
- TLSConfig: tlsConfig,
|
|
|
|
- },
|
|
|
|
|
|
+ if V2Only {
|
|
|
|
+ return endpoints, nil
|
|
}
|
|
}
|
|
|
|
|
|
- if !isSecure {
|
|
|
|
- endpoints = append(endpoints, APIEndpoint{
|
|
|
|
- URL: "http://" + hostname,
|
|
|
|
- Version: APIVersion2,
|
|
|
|
- TrimHostname: true,
|
|
|
|
- // used to check if supposed to be secure via InsecureSkipVerify
|
|
|
|
- TLSConfig: tlsConfig,
|
|
|
|
- VersionHeader: DefaultRegistryVersionHeader,
|
|
|
|
- Versions: v2Versions,
|
|
|
|
- }, APIEndpoint{
|
|
|
|
- URL: "http://" + hostname,
|
|
|
|
- Version: APIVersion1,
|
|
|
|
- TrimHostname: true,
|
|
|
|
- // used to check if supposed to be secure via InsecureSkipVerify
|
|
|
|
- TLSConfig: tlsConfig,
|
|
|
|
- })
|
|
|
|
|
|
+ legacyEndpoints, err := s.lookupV1Endpoints(repoName)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return nil, err
|
|
}
|
|
}
|
|
|
|
+ endpoints = append(endpoints, legacyEndpoints...)
|
|
|
|
|
|
return endpoints, nil
|
|
return endpoints, nil
|
|
}
|
|
}
|