mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	Add class to repository scope
Expose registry error translation for plugin distribution
Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
(cherry picked from commit a12b466183)
Signed-off-by: Victor Vieux <vieux@docker.com>
			
			
This commit is contained in:
		
							parent
							
								
									9ecbaa77ae
								
							
						
					
					
						commit
						cca0132fcf
					
				
					 8 changed files with 34 additions and 17 deletions
				
			
		| 
						 | 
				
			
			@ -60,21 +60,25 @@ func shouldV2Fallback(err errcode.Error) bool {
 | 
			
		|||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func translatePullError(err error, ref reference.Named) error {
 | 
			
		||||
// TranslatePullError is used to convert an error from a registry pull
 | 
			
		||||
// operation to an error representing the entire pull operation. Any error
 | 
			
		||||
// information which is not used by the returned error gets output to
 | 
			
		||||
// log at info level.
 | 
			
		||||
func TranslatePullError(err error, ref reference.Named) error {
 | 
			
		||||
	switch v := err.(type) {
 | 
			
		||||
	case errcode.Errors:
 | 
			
		||||
		if len(v) != 0 {
 | 
			
		||||
			for _, extra := range v[1:] {
 | 
			
		||||
				logrus.Infof("Ignoring extra error returned from registry: %v", extra)
 | 
			
		||||
			}
 | 
			
		||||
			return translatePullError(v[0], ref)
 | 
			
		||||
			return TranslatePullError(v[0], ref)
 | 
			
		||||
		}
 | 
			
		||||
	case errcode.Error:
 | 
			
		||||
		var newErr error
 | 
			
		||||
		switch v.Code {
 | 
			
		||||
		case errcode.ErrorCodeDenied:
 | 
			
		||||
			// ErrorCodeDenied is used when access to the repository was denied
 | 
			
		||||
			newErr = errors.Errorf("repository %s not found: does not exist or no read access", ref.Name())
 | 
			
		||||
			newErr = errors.Errorf("repository %s not found: does not exist or no pull access", ref.Name())
 | 
			
		||||
		case v2.ErrorCodeManifestUnknown:
 | 
			
		||||
			newErr = errors.Errorf("manifest for %s not found", ref.String())
 | 
			
		||||
		case v2.ErrorCodeNameUnknown:
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +89,7 @@ func translatePullError(err error, ref reference.Named) error {
 | 
			
		|||
			return newErr
 | 
			
		||||
		}
 | 
			
		||||
	case xfer.DoNotRetry:
 | 
			
		||||
		return translatePullError(v.Err, ref)
 | 
			
		||||
		return TranslatePullError(v.Err, ref)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return err
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -168,7 +168,7 @@ func Pull(ctx context.Context, ref reference.Named, imagePullConfig *ImagePullCo
 | 
			
		|||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			logrus.Errorf("Not continuing with pull after error: %v", err)
 | 
			
		||||
			return translatePullError(err, ref)
 | 
			
		||||
			return TranslatePullError(err, ref)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		imagePullConfig.ImageEventLogger(ref.String(), repoInfo.Name(), "pull")
 | 
			
		||||
| 
						 | 
				
			
			@ -179,7 +179,7 @@ func Pull(ctx context.Context, ref reference.Named, imagePullConfig *ImagePullCo
 | 
			
		|||
		lastErr = fmt.Errorf("no endpoints found for %s", ref.String())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return translatePullError(lastErr, ref)
 | 
			
		||||
	return TranslatePullError(lastErr, ref)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// writeStatus writes a status message to out. If layersDownloaded is true, the
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -70,17 +70,22 @@ func NewV2Repository(ctx context.Context, repoInfo *registry.RepositoryInfo, end
 | 
			
		|||
		passThruTokenHandler := &existingTokenHandler{token: authConfig.RegistryToken}
 | 
			
		||||
		modifiers = append(modifiers, auth.NewAuthorizer(challengeManager, passThruTokenHandler))
 | 
			
		||||
	} else {
 | 
			
		||||
		scope := auth.RepositoryScope{
 | 
			
		||||
			Repository: repoName,
 | 
			
		||||
			Actions:    actions,
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Keep image repositories blank for scope compatibility
 | 
			
		||||
		if repoInfo.Class != "image" {
 | 
			
		||||
			scope.Class = repoInfo.Class
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		creds := registry.NewStaticCredentialStore(authConfig)
 | 
			
		||||
		tokenHandlerOptions := auth.TokenHandlerOptions{
 | 
			
		||||
			Transport:   authTransport,
 | 
			
		||||
			Credentials: creds,
 | 
			
		||||
			Scopes: []auth.Scope{
 | 
			
		||||
				auth.RepositoryScope{
 | 
			
		||||
					Repository: repoName,
 | 
			
		||||
					Actions:    actions,
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			ClientID: registry.AuthClientID,
 | 
			
		||||
			Scopes:      []auth.Scope{scope},
 | 
			
		||||
			ClientID:    registry.AuthClientID,
 | 
			
		||||
		}
 | 
			
		||||
		tokenHandler := auth.NewTokenHandlerWithOptions(tokenHandlerOptions)
 | 
			
		||||
		basicHandler := auth.NewBasicHandler(creds)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -98,7 +98,7 @@ func (s *DockerHubPullSuite) TestPullNonExistingImage(c *check.C) {
 | 
			
		|||
	for record := range recordChan {
 | 
			
		||||
		if len(record.option) == 0 {
 | 
			
		||||
			c.Assert(record.err, checker.NotNil, check.Commentf("expected non-zero exit status when pulling non-existing image: %s", record.out))
 | 
			
		||||
			c.Assert(record.out, checker.Contains, fmt.Sprintf("repository %s not found: does not exist or no read access", record.e.repo), check.Commentf("expected image not found error messages"))
 | 
			
		||||
			c.Assert(record.out, checker.Contains, fmt.Sprintf("repository %s not found: does not exist or no pull access", record.e.repo), check.Commentf("expected image not found error messages"))
 | 
			
		||||
		} else {
 | 
			
		||||
			// pull -a on a nonexistent registry should fall back as well
 | 
			
		||||
			c.Assert(record.err, checker.NotNil, check.Commentf("expected non-zero exit status when pulling non-existing image: %s", record.out))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -85,6 +85,7 @@ func Pull(ref reference.Named, rs registry.Service, metaheader http.Header, auth
 | 
			
		|||
		logrus.Debugf("pull.go: error in ResolveRepository: %v", err)
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	repoInfo.Class = "plugin"
 | 
			
		||||
 | 
			
		||||
	if err := dockerdist.ValidateRepoName(repoInfo.Name()); err != nil {
 | 
			
		||||
		logrus.Debugf("pull.go: error in ValidateRepoName: %v", err)
 | 
			
		||||
| 
						 | 
				
			
			@ -138,9 +139,8 @@ func Pull(ref reference.Named, rs registry.Service, metaheader http.Header, auth
 | 
			
		|||
	}
 | 
			
		||||
	manifest, err := msv.Get(context.Background(), "", distribution.WithTag(tag))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		// TODO: change 401 to 404
 | 
			
		||||
		logrus.Debugf("pull.go: error in msv.Get(): %v", err)
 | 
			
		||||
		return nil, err
 | 
			
		||||
		return nil, dockerdist.TranslatePullError(err, repoInfo)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, pl, err := manifest.Payload()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,7 @@ func Push(name string, rs registry.Service, metaHeader http.Header, authConfig *
 | 
			
		|||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	repoInfo.Class = "plugin"
 | 
			
		||||
 | 
			
		||||
	if err := dockerdist.ValidateRepoName(repoInfo.Name()); err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -280,7 +280,11 @@ func newRepositoryInfo(config *serviceConfig, name reference.Named) (*Repository
 | 
			
		|||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	official := !strings.ContainsRune(name.Name(), '/')
 | 
			
		||||
	return &RepositoryInfo{name, index, official}, nil
 | 
			
		||||
	return &RepositoryInfo{
 | 
			
		||||
		Named:    name,
 | 
			
		||||
		Index:    index,
 | 
			
		||||
		Official: official,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ParseRepositoryInfo performs the breakdown of a repository name into a RepositoryInfo, but
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -67,4 +67,7 @@ type RepositoryInfo struct {
 | 
			
		|||
	// If the registry is official, and the normalized name does not
 | 
			
		||||
	// contain a '/' (e.g. "foo"), then it is considered an official repo.
 | 
			
		||||
	Official bool
 | 
			
		||||
	// Class represents the class of the repository, such as "plugin"
 | 
			
		||||
	// or "image".
 | 
			
		||||
	Class string
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue