Skip to content

Commit

Permalink
Add support for registry token in containerd pull logic
Browse files Browse the repository at this point in the history
When registry token is provided, the authorization header can be
directly applied to the registry request. No other type of
authorization will be attempted when the registry token is provided.

Signed-off-by: Derek McGowan <[email protected]>
  • Loading branch information
dmcgowan committed Sep 14, 2023
1 parent 982e5af commit 62e55fd
Showing 1 changed file with 36 additions and 4 deletions.
40 changes: 36 additions & 4 deletions daemon/containerd/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"net/http"

cerrdefs "github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/remotes"
"github.com/containerd/containerd/remotes/docker"
Expand Down Expand Up @@ -33,7 +34,7 @@ func (i *ImageService) newResolverFromAuthConfig(ctx context.Context, authConfig
func hostsWrapper(hostsFn docker.RegistryHosts, optAuthConfig *registrytypes.AuthConfig, regService RegistryConfigProvider) docker.RegistryHosts {
var authorizer docker.Authorizer
if optAuthConfig != nil {
authorizer = docker.NewDockerAuthorizer(authorizationCredsFromAuthConfig(*optAuthConfig))
authorizer = authorizerFromAuthConfig(*optAuthConfig)
}

return func(n string) ([]docker.RegistryHost, error) {
Expand All @@ -55,13 +56,20 @@ func hostsWrapper(hostsFn docker.RegistryHosts, optAuthConfig *registrytypes.Aut
}
}

func authorizationCredsFromAuthConfig(authConfig registrytypes.AuthConfig) docker.AuthorizerOpt {
func authorizerFromAuthConfig(authConfig registrytypes.AuthConfig) docker.Authorizer {
cfgHost := registry.ConvertToHostname(authConfig.ServerAddress)
if cfgHost == "" || cfgHost == registry.IndexHostname {
cfgHost = registry.DefaultRegistryHost
}

return docker.WithAuthCreds(func(host string) (string, string, error) {
if authConfig.RegistryToken != "" {
return &bearerAuthorizer{
host: cfgHost,
bearer: authConfig.RegistryToken,
}
}

return docker.NewDockerAuthorizer(docker.WithAuthCreds(func(host string) (string, string, error) {
if cfgHost != host {
log.G(context.TODO()).WithFields(log.Fields{
"host": host,
Expand All @@ -73,7 +81,31 @@ func authorizationCredsFromAuthConfig(authConfig registrytypes.AuthConfig) docke
return "", authConfig.IdentityToken, nil
}
return authConfig.Username, authConfig.Password, nil
})
}))
}

type bearerAuthorizer struct {
host string
bearer string
}

func (a *bearerAuthorizer) Authorize(ctx context.Context, req *http.Request) error {
if req.Host != a.host {
log.G(ctx).WithFields(log.Fields{
"host": req.Host,
"cfgHost": a.host,
}).Warn("Host doesn't match for bearer token")
return nil
}

req.Header.Set("Authorization", "Bearer "+a.bearer)

return nil
}

func (a *bearerAuthorizer) AddResponses(context.Context, []*http.Response) error {
// Return not implemented to prevent retry of the request when bearer did not succeed
return cerrdefs.ErrNotImplemented
}

type httpFallback struct {
Expand Down

0 comments on commit 62e55fd

Please sign in to comment.