Prevent push and pull to v1 registries by filtering the available endpoints.
Add a daemon flag to control this behaviour. Add a warning message when pulling an image from a v1 registry. The default order of pull is slightly altered with this changset. Previously it was: https v2, https v1, http v2, http v1 now it is: https v2, http v2, https v1, http v1 Prevent login to v1 registries by explicitly setting the version before ping to prevent fallback to v1. Add unit tests for v2 only mode. Create a mock server that can register handlers for various endpoints. Assert no v1 endpoints are hit with legacy registries disabled for the following commands: pull, push, build, run and login. Assert the opposite when legacy registries are not disabled. Signed-off-by: Richard Scothern <richard.scothern@gmail.com>
This commit is contained in:
parent
2b658054bb
commit
ebaa771c3b
7 changed files with 175 additions and 103 deletions
107
docs/service.go
107
docs/service.go
|
@ -2,15 +2,11 @@ package registry
|
|||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/distribution/registry/client/auth"
|
||||
"github.com/docker/docker/cliconfig"
|
||||
"github.com/docker/docker/pkg/tlsconfig"
|
||||
)
|
||||
|
||||
// Service is a registry service. It tracks configuration data such as a list
|
||||
|
@ -40,7 +36,14 @@ func (s *Service) Auth(authConfig *cliconfig.AuthConfig) (string, error) {
|
|||
if err != nil {
|
||||
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 {
|
||||
return "", err
|
||||
}
|
||||
|
@ -57,10 +60,11 @@ func (s *Service) Search(term string, authConfig *cliconfig.AuthConfig, headers
|
|||
}
|
||||
|
||||
// *TODO: Search multiple indexes.
|
||||
endpoint, err := repoInfo.GetEndpoint(http.Header(headers))
|
||||
endpoint, err := NewEndpoint(repoInfo.Index, http.Header(headers), APIVersionUnknown)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r, err := NewSession(endpoint.client, authConfig, endpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -132,97 +136,20 @@ func (s *Service) LookupPushEndpoints(repoName string) (endpoints []APIEndpoint,
|
|||
}
|
||||
|
||||
func (s *Service) lookupEndpoints(repoName string) (endpoints []APIEndpoint, err error) {
|
||||
var cfg = tlsconfig.ServerDefault
|
||||
tlsConfig := &cfg
|
||||
if strings.HasPrefix(repoName, DefaultNamespace+"/") {
|
||||
// v2 mirrors
|
||||
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,
|
||||
})
|
||||
if runtime.GOOS == "linux" { // do not inherit legacy API for OSes supported in the future
|
||||
// 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]
|
||||
|
||||
tlsConfig, err = s.TLSConfig(hostname)
|
||||
endpoints, err = s.lookupV2Endpoints(repoName)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue