Make the v2 logic fallback on v1 when v2 requests cannot be authorized.
Signed-off-by: Matt Moore <mattmoor@google.com>
This commit is contained in:
parent
7f6a7973cd
commit
bd2575cc4f
3 changed files with 31 additions and 5 deletions
|
@ -482,6 +482,10 @@ func (s *TagStore) pullV2Repository(r *registry.Session, out io.Writer, repoInfo
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error getting authorization: %s", err)
|
return fmt.Errorf("error getting authorization: %s", err)
|
||||||
}
|
}
|
||||||
|
if !auth.CanAuthorizeV2() {
|
||||||
|
return ErrV2RegistryUnavailable
|
||||||
|
}
|
||||||
|
|
||||||
var layersDownloaded bool
|
var layersDownloaded bool
|
||||||
if tag == "" {
|
if tag == "" {
|
||||||
logrus.Debugf("Pulling tag list from V2 registry for %s", repoInfo.CanonicalName)
|
logrus.Debugf("Pulling tag list from V2 registry for %s", repoInfo.CanonicalName)
|
||||||
|
|
|
@ -322,6 +322,9 @@ func (s *TagStore) pushV2Repository(r *registry.Session, localRepo Repository, o
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error getting authorization: %s", err)
|
return fmt.Errorf("error getting authorization: %s", err)
|
||||||
}
|
}
|
||||||
|
if !auth.CanAuthorizeV2() {
|
||||||
|
return ErrV2RegistryUnavailable
|
||||||
|
}
|
||||||
|
|
||||||
for _, tag := range tags {
|
for _, tag := range tags {
|
||||||
logrus.Debugf("Pushing repository: %s:%s", repoInfo.CanonicalName, tag)
|
logrus.Debugf("Pushing repository: %s:%s", repoInfo.CanonicalName, tag)
|
||||||
|
@ -549,6 +552,7 @@ func (s *TagStore) Push(localName string, imagePushConfig *ImagePushConfig) erro
|
||||||
if err != ErrV2RegistryUnavailable {
|
if err != ErrV2RegistryUnavailable {
|
||||||
return fmt.Errorf("Error pushing to registry: %s", err)
|
return fmt.Errorf("Error pushing to registry: %s", err)
|
||||||
}
|
}
|
||||||
|
logrus.Debug("V2 registry is unavailable, falling back on V1")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.pushRepository(r, imagePushConfig.OutStream, repoInfo, localRepo, imagePushConfig.Tag, sf); err != nil {
|
if err := s.pushRepository(r, imagePushConfig.OutStream, repoInfo, localRepo, imagePushConfig.Tag, sf); err != nil {
|
||||||
|
|
|
@ -74,6 +74,19 @@ func (auth *RequestAuthorization) getToken() (string, error) {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks that requests to the v2 registry can be authorized.
|
||||||
|
func (auth *RequestAuthorization) CanAuthorizeV2() bool {
|
||||||
|
if len(auth.registryEndpoint.AuthChallenges) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
scope := fmt.Sprintf("%s:%s:%s", auth.resource, auth.scope, strings.Join(auth.actions, ","))
|
||||||
|
if _, err := loginV2(auth.authConfig, auth.registryEndpoint, scope); err != nil {
|
||||||
|
logrus.Debugf("Cannot authorize against V2 endpoint: %s", auth.registryEndpoint)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func (auth *RequestAuthorization) Authorize(req *http.Request) error {
|
func (auth *RequestAuthorization) Authorize(req *http.Request) error {
|
||||||
token, err := auth.getToken()
|
token, err := auth.getToken()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -91,7 +104,7 @@ func (auth *RequestAuthorization) Authorize(req *http.Request) error {
|
||||||
func Login(authConfig *cliconfig.AuthConfig, registryEndpoint *Endpoint) (string, error) {
|
func Login(authConfig *cliconfig.AuthConfig, registryEndpoint *Endpoint) (string, error) {
|
||||||
// Separates the v2 registry login logic from the v1 logic.
|
// Separates the v2 registry login logic from the v1 logic.
|
||||||
if registryEndpoint.Version == APIVersion2 {
|
if registryEndpoint.Version == APIVersion2 {
|
||||||
return loginV2(authConfig, registryEndpoint)
|
return loginV2(authConfig, registryEndpoint, "" /* scope */)
|
||||||
}
|
}
|
||||||
return loginV1(authConfig, registryEndpoint)
|
return loginV1(authConfig, registryEndpoint)
|
||||||
}
|
}
|
||||||
|
@ -209,7 +222,7 @@ func loginV1(authConfig *cliconfig.AuthConfig, registryEndpoint *Endpoint) (stri
|
||||||
// now, users should create their account through other means like directly from a web page
|
// now, users should create their account through other means like directly from a web page
|
||||||
// served by the v2 registry service provider. Whether this will be supported in the future
|
// served by the v2 registry service provider. Whether this will be supported in the future
|
||||||
// is to be determined.
|
// is to be determined.
|
||||||
func loginV2(authConfig *cliconfig.AuthConfig, registryEndpoint *Endpoint) (string, error) {
|
func loginV2(authConfig *cliconfig.AuthConfig, registryEndpoint *Endpoint, scope string) (string, error) {
|
||||||
logrus.Debugf("attempting v2 login to registry endpoint %s", registryEndpoint)
|
logrus.Debugf("attempting v2 login to registry endpoint %s", registryEndpoint)
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
|
@ -217,13 +230,18 @@ func loginV2(authConfig *cliconfig.AuthConfig, registryEndpoint *Endpoint) (stri
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, challenge := range registryEndpoint.AuthChallenges {
|
for _, challenge := range registryEndpoint.AuthChallenges {
|
||||||
logrus.Debugf("trying %q auth challenge with params %s", challenge.Scheme, challenge.Parameters)
|
params := make(map[string]string, len(challenge.Parameters)+1)
|
||||||
|
for k, v := range challenge.Parameters {
|
||||||
|
params[k] = v
|
||||||
|
}
|
||||||
|
params["scope"] = scope
|
||||||
|
logrus.Debugf("trying %q auth challenge with params %v", challenge.Scheme, params)
|
||||||
|
|
||||||
switch strings.ToLower(challenge.Scheme) {
|
switch strings.ToLower(challenge.Scheme) {
|
||||||
case "basic":
|
case "basic":
|
||||||
err = tryV2BasicAuthLogin(authConfig, challenge.Parameters, registryEndpoint)
|
err = tryV2BasicAuthLogin(authConfig, params, registryEndpoint)
|
||||||
case "bearer":
|
case "bearer":
|
||||||
err = tryV2TokenAuthLogin(authConfig, challenge.Parameters, registryEndpoint)
|
err = tryV2TokenAuthLogin(authConfig, params, registryEndpoint)
|
||||||
default:
|
default:
|
||||||
// Unsupported challenge types are explicitly skipped.
|
// Unsupported challenge types are explicitly skipped.
|
||||||
err = fmt.Errorf("unsupported auth scheme: %q", challenge.Scheme)
|
err = fmt.Errorf("unsupported auth scheme: %q", challenge.Scheme)
|
||||||
|
|
Loading…
Reference in a new issue