Merge pull request #43885 from thaJeztah/auth_header_refactor

Move AuthConfig to types/registry, and implement utilities for encoding/decoding
This commit is contained in:
Tianon Gravi 2022-08-03 11:31:26 -07:00 committed by GitHub
commit e60bddcc60
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
66 changed files with 462 additions and 345 deletions

View file

@ -4,6 +4,7 @@ import (
"context"
"net/http"
"github.com/docker/docker/api/types/registry"
"github.com/sirupsen/logrus"
)
@ -30,7 +31,7 @@ func (c CORSMiddleware) WrapHandler(handler func(ctx context.Context, w http.Res
logrus.Debugf("CORS header is enabled and set to: %s", corsHeaders)
w.Header().Add("Access-Control-Allow-Origin", corsHeaders)
w.Header().Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Registry-Auth")
w.Header().Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, "+registry.AuthHeader)
w.Header().Add("Access-Control-Allow-Methods", "HEAD, GET, POST, DELETE, PUT, OPTIONS")
return handler(ctx, w, r, vars)
}

View file

@ -19,6 +19,7 @@ import (
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/ioutils"
@ -296,8 +297,8 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
return nil
}
func getAuthConfigs(header http.Header) map[string]types.AuthConfig {
authConfigs := map[string]types.AuthConfig{}
func getAuthConfigs(header http.Header) map[string]registry.AuthConfig {
authConfigs := map[string]registry.AuthConfig{}
authConfigsEncoded := header.Get("X-Registry-Config")
if authConfigsEncoded == "" {

View file

@ -5,11 +5,11 @@ import (
"github.com/docker/distribution"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
)
// Backend is all the methods that need to be implemented
// to provide image specific functionality.
type Backend interface {
GetRepository(context.Context, reference.Named, *types.AuthConfig) (distribution.Repository, error)
GetRepository(context.Context, reference.Named, *registry.AuthConfig) (distribution.Repository, error)
}

View file

@ -2,18 +2,15 @@ package distribution // import "github.com/docker/docker/api/server/router/distr
import (
"context"
"encoding/base64"
"encoding/json"
"net/http"
"strings"
"github.com/docker/distribution/manifest/manifestlist"
"github.com/docker/distribution/manifest/schema1"
"github.com/docker/distribution/manifest/schema2"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
@ -26,21 +23,6 @@ func (s *distributionRouter) getDistributionInfo(ctx context.Context, w http.Res
w.Header().Set("Content-Type", "application/json")
var (
config = &types.AuthConfig{}
authEncoded = r.Header.Get("X-Registry-Auth")
distributionInspect registrytypes.DistributionInspect
)
if authEncoded != "" {
authJSON := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded))
if err := json.NewDecoder(authJSON).Decode(&config); err != nil {
// for a search it is not an error if no auth was given
// to increase compatibility with the existing api it is defaulting to be empty
config = &types.AuthConfig{}
}
}
image := vars["name"]
// TODO why is reference.ParseAnyReference() / reference.ParseNormalizedNamed() not using the reference.ErrTagInvalidFormat (and so on) errors?
@ -57,12 +39,16 @@ func (s *distributionRouter) getDistributionInfo(ctx context.Context, w http.Res
return errdefs.InvalidParameter(errors.Errorf("unknown image reference format: %s", image))
}
distrepo, err := s.backend.GetRepository(ctx, namedRef, config)
// For a search it is not an error if no auth was given. Ignore invalid
// AuthConfig to increase compatibility with the existing API.
authConfig, _ := registry.DecodeAuthConfig(r.Header.Get(registry.AuthHeader))
distrepo, err := s.backend.GetRepository(ctx, namedRef, authConfig)
if err != nil {
return err
}
blobsrvc := distrepo.Blobs(ctx)
var distributionInspect registry.DistributionInspect
if canonicalRef, ok := namedRef.(reference.Canonical); !ok {
namedRef = reference.TagNameOnly(namedRef)

View file

@ -36,7 +36,7 @@ type importExportBackend interface {
}
type registryBackend interface {
PullImage(ctx context.Context, image, tag string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error
PushImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error
SearchRegistryForImages(ctx context.Context, searchFilters filters.Args, term string, limit int, authConfig *types.AuthConfig, metaHeaders map[string][]string) (*registry.SearchResults, error)
PullImage(ctx context.Context, image, tag string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error
PushImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error
SearchRegistryForImages(ctx context.Context, searchFilters filters.Args, term string, limit int, authConfig *registry.AuthConfig, metaHeaders map[string][]string) (*registry.SearchResults, error)
}

View file

@ -2,8 +2,6 @@ package image // import "github.com/docker/docker/api/server/router/image"
import (
"context"
"encoding/base64"
"encoding/json"
"net/http"
"strconv"
"strings"
@ -14,6 +12,7 @@ import (
"github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/image"
@ -63,16 +62,9 @@ func (s *imageRouter) postImagesCreate(ctx context.Context, w http.ResponseWrite
}
}
authEncoded := r.Header.Get("X-Registry-Auth")
authConfig := &types.AuthConfig{}
if authEncoded != "" {
authJSON := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded))
if err := json.NewDecoder(authJSON).Decode(authConfig); err != nil {
// for a pull it is not an error if no auth was given
// to increase compatibility with the existing api it is defaulting to be empty
authConfig = &types.AuthConfig{}
}
}
// For a pull it is not an error if no auth was given. Ignore invalid
// AuthConfig to increase compatibility with the existing API.
authConfig, _ := registry.DecodeAuthConfig(r.Header.Get(registry.AuthHeader))
progressErr = s.backend.PullImage(ctx, image, tag, platform, metaHeaders, authConfig, output)
} else { // import
src := r.Form.Get("fromSrc")
@ -98,32 +90,29 @@ func (s *imageRouter) postImagesPush(ctx context.Context, w http.ResponseWriter,
if err := httputils.ParseForm(r); err != nil {
return err
}
authConfig := &types.AuthConfig{}
authEncoded := r.Header.Get("X-Registry-Auth")
if authEncoded != "" {
// the new format is to handle the authConfig as a header
authJSON := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded))
if err := json.NewDecoder(authJSON).Decode(authConfig); err != nil {
// to increase compatibility to existing api it is defaulting to be empty
authConfig = &types.AuthConfig{}
}
var authConfig *registry.AuthConfig
if authEncoded := r.Header.Get(registry.AuthHeader); authEncoded != "" {
// the new format is to handle the authConfig as a header. Ignore invalid
// AuthConfig to increase compatibility with the existing API.
authConfig, _ = registry.DecodeAuthConfig(authEncoded)
} else {
// the old format is supported for compatibility if there was no authConfig header
if err := json.NewDecoder(r.Body).Decode(authConfig); err != nil {
return errors.Wrap(errdefs.InvalidParameter(err), "Bad parameters and missing X-Registry-Auth")
var err error
authConfig, err = registry.DecodeAuthConfigBody(r.Body)
if err != nil {
return errors.Wrap(err, "bad parameters and missing X-Registry-Auth")
}
}
image := vars["name"]
tag := r.Form.Get("tag")
output := ioutils.NewWriteFlusher(w)
defer output.Close()
w.Header().Set("Content-Type", "application/json")
if err := s.backend.PushImage(ctx, image, tag, metaHeaders, authConfig, output); err != nil {
img := vars["name"]
tag := r.Form.Get("tag")
if err := s.backend.PushImage(ctx, img, tag, metaHeaders, authConfig, output); err != nil {
if !output.Flushed() {
return err
}
@ -358,20 +347,8 @@ func (s *imageRouter) getImagesSearch(ctx context.Context, w http.ResponseWriter
if err := httputils.ParseForm(r); err != nil {
return err
}
var (
config *types.AuthConfig
authEncoded = r.Header.Get("X-Registry-Auth")
headers = map[string][]string{}
)
if authEncoded != "" {
authJSON := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded))
if err := json.NewDecoder(authJSON).Decode(&config); err != nil {
// for a search it is not an error if no auth was given
// to increase compatibility with the existing api it is defaulting to be empty
config = &types.AuthConfig{}
}
}
var headers = map[string][]string{}
for k, v := range r.Header {
if strings.HasPrefix(k, "X-Meta-") {
headers[k] = v
@ -391,7 +368,10 @@ func (s *imageRouter) getImagesSearch(ctx context.Context, w http.ResponseWriter
return err
}
query, err := s.backend.SearchRegistryForImages(ctx, searchFilters, r.Form.Get("term"), limit, config, headers)
// For a search it is not an error if no auth was given. Ignore invalid
// AuthConfig to increase compatibility with the existing API.
authConfig, _ := registry.DecodeAuthConfig(r.Header.Get(registry.AuthHeader))
query, err := s.backend.SearchRegistryForImages(ctx, searchFilters, r.Form.Get("term"), limit, authConfig, headers)
if err != nil {
return err
}

View file

@ -6,22 +6,23 @@ import (
"net/http"
"github.com/docker/distribution/reference"
enginetypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/plugin"
)
// Backend for Plugin
type Backend interface {
Disable(name string, config *enginetypes.PluginDisableConfig) error
Enable(name string, config *enginetypes.PluginEnableConfig) error
List(filters.Args) ([]enginetypes.Plugin, error)
Inspect(name string) (*enginetypes.Plugin, error)
Remove(name string, config *enginetypes.PluginRmConfig) error
Disable(name string, config *types.PluginDisableConfig) error
Enable(name string, config *types.PluginEnableConfig) error
List(filters.Args) ([]types.Plugin, error)
Inspect(name string) (*types.Plugin, error)
Remove(name string, config *types.PluginRmConfig) error
Set(name string, args []string) error
Privileges(ctx context.Context, ref reference.Named, metaHeaders http.Header, authConfig *enginetypes.AuthConfig) (enginetypes.PluginPrivileges, error)
Pull(ctx context.Context, ref reference.Named, name string, metaHeaders http.Header, authConfig *enginetypes.AuthConfig, privileges enginetypes.PluginPrivileges, outStream io.Writer, opts ...plugin.CreateOpt) error
Push(ctx context.Context, name string, metaHeaders http.Header, authConfig *enginetypes.AuthConfig, outStream io.Writer) error
Upgrade(ctx context.Context, ref reference.Named, name string, metaHeaders http.Header, authConfig *enginetypes.AuthConfig, privileges enginetypes.PluginPrivileges, outStream io.Writer) error
CreateFromContext(ctx context.Context, tarCtx io.ReadCloser, options *enginetypes.PluginCreateOptions) error
Privileges(ctx context.Context, ref reference.Named, metaHeaders http.Header, authConfig *registry.AuthConfig) (types.PluginPrivileges, error)
Pull(ctx context.Context, ref reference.Named, name string, metaHeaders http.Header, authConfig *registry.AuthConfig, privileges types.PluginPrivileges, outStream io.Writer, opts ...plugin.CreateOpt) error
Push(ctx context.Context, name string, metaHeaders http.Header, authConfig *registry.AuthConfig, outStream io.Writer) error
Upgrade(ctx context.Context, ref reference.Named, name string, metaHeaders http.Header, authConfig *registry.AuthConfig, privileges types.PluginPrivileges, outStream io.Writer) error
CreateFromContext(ctx context.Context, tarCtx io.ReadCloser, options *types.PluginCreateOptions) error
}

View file

@ -2,8 +2,6 @@ package plugin // import "github.com/docker/docker/api/server/router/plugin"
import (
"context"
"encoding/base64"
"encoding/json"
"net/http"
"strconv"
"strings"
@ -12,13 +10,13 @@ import (
"github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/streamformatter"
"github.com/pkg/errors"
)
func parseHeaders(headers http.Header) (map[string][]string, *types.AuthConfig) {
func parseHeaders(headers http.Header) (map[string][]string, *registry.AuthConfig) {
metaHeaders := map[string][]string{}
for k, v := range headers {
if strings.HasPrefix(k, "X-Meta-") {
@ -26,16 +24,8 @@ func parseHeaders(headers http.Header) (map[string][]string, *types.AuthConfig)
}
}
// Get X-Registry-Auth
authEncoded := headers.Get("X-Registry-Auth")
authConfig := &types.AuthConfig{}
if authEncoded != "" {
authJSON := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded))
if err := json.NewDecoder(authJSON).Decode(authConfig); err != nil {
authConfig = &types.AuthConfig{}
}
}
// Ignore invalid AuthConfig to increase compatibility with the existing API.
authConfig, _ := registry.DecodeAuthConfig(headers.Get(registry.AuthHeader))
return metaHeaders, authConfig
}

View file

@ -10,6 +10,7 @@ import (
basictypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/registry"
types "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/errdefs"
@ -207,7 +208,7 @@ func (sr *swarmRouter) createService(ctx context.Context, w http.ResponseWriter,
}
// Get returns "" if the header does not exist
encodedAuth := r.Header.Get("X-Registry-Auth")
encodedAuth := r.Header.Get(registry.AuthHeader)
queryRegistry := false
if v := httputils.VersionFromContext(ctx); v != "" {
if versions.LessThan(v, "1.30") {
@ -240,7 +241,7 @@ func (sr *swarmRouter) updateService(ctx context.Context, w http.ResponseWriter,
var flags basictypes.ServiceUpdateOptions
// Get returns "" if the header does not exist
flags.EncodedRegistryAuth = r.Header.Get("X-Registry-Auth")
flags.EncodedRegistryAuth = r.Header.Get(registry.AuthHeader)
flags.RegistryAuthFrom = r.URL.Query().Get("registryAuthFrom")
flags.Rollback = r.URL.Query().Get("rollback")
queryRegistry := false

View file

@ -7,6 +7,7 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm"
)
@ -30,7 +31,7 @@ type Backend interface {
SystemDiskUsage(ctx context.Context, opts DiskUsageOptions) (*types.DiskUsage, error)
SubscribeToEvents(since, until time.Time, ef filters.Args) ([]events.Message, chan interface{})
UnsubscribeFromEvents(chan interface{})
AuthenticateToRegistry(ctx context.Context, authConfig *types.AuthConfig) (string, string, error)
AuthenticateToRegistry(ctx context.Context, authConfig *registry.AuthConfig) (string, string, error)
}
// ClusterBackend is all the methods that need to be implemented

View file

@ -281,7 +281,7 @@ func (s *systemRouter) getEvents(ctx context.Context, w http.ResponseWriter, r *
}
func (s *systemRouter) postAuth(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var config *types.AuthConfig
var config *registry.AuthConfig
err := json.NewDecoder(r.Body).Decode(&config)
r.Body.Close()
if err != nil {

View file

@ -1,22 +1,7 @@
package types // import "github.com/docker/docker/api/types"
import "github.com/docker/docker/api/types/registry"
// AuthConfig contains authorization information for connecting to a Registry
type AuthConfig struct {
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
Auth string `json:"auth,omitempty"`
// Email is an optional value associated with the username.
// This field is deprecated and will be removed in a later
// version of docker.
Email string `json:"email,omitempty"`
ServerAddress string `json:"serveraddress,omitempty"`
// IdentityToken is used to authenticate the user and get
// an access token for the registry.
IdentityToken string `json:"identitytoken,omitempty"`
// RegistryToken is a bearer token to be sent to a registry
RegistryToken string `json:"registrytoken,omitempty"`
}
// AuthConfig contains authorization information for connecting to a Registry.
//
// Deprecated: use github.com/docker/docker/api/types/registry.AuthConfig
type AuthConfig = registry.AuthConfig

View file

@ -4,6 +4,7 @@ import (
"io"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/pkg/streamformatter"
specs "github.com/opencontainers/image-spec/specs-go/v1"
)
@ -39,7 +40,7 @@ type BuildConfig struct {
// GetImageAndLayerOptions are the options supported by GetImageAndReleasableLayer
type GetImageAndLayerOptions struct {
PullOption PullOption
AuthConfig map[string]types.AuthConfig
AuthConfig map[string]registry.AuthConfig
Output io.Writer
Platform *specs.Platform
}

View file

@ -7,6 +7,7 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/registry"
units "github.com/docker/go-units"
)
@ -180,7 +181,7 @@ type ImageBuildOptions struct {
// at all (nil). See the parsing of buildArgs in
// api/server/router/build/build_routes.go for even more info.
BuildArgs map[string]*string
AuthConfigs map[string]AuthConfig
AuthConfigs map[string]registry.AuthConfig
Context io.Reader
Labels map[string]string
// squash the resulting image's layers to the parent

View file

@ -0,0 +1,99 @@
package registry // import "github.com/docker/docker/api/types/registry"
import (
"encoding/base64"
"encoding/json"
"io"
"strings"
"github.com/pkg/errors"
)
// AuthHeader is the name of the header used to send encoded registry
// authorization credentials for registry operations (push/pull).
const AuthHeader = "X-Registry-Auth"
// AuthConfig contains authorization information for connecting to a Registry.
type AuthConfig struct {
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
Auth string `json:"auth,omitempty"`
// Email is an optional value associated with the username.
// This field is deprecated and will be removed in a later
// version of docker.
Email string `json:"email,omitempty"`
ServerAddress string `json:"serveraddress,omitempty"`
// IdentityToken is used to authenticate the user and get
// an access token for the registry.
IdentityToken string `json:"identitytoken,omitempty"`
// RegistryToken is a bearer token to be sent to a registry
RegistryToken string `json:"registrytoken,omitempty"`
}
// EncodeAuthConfig serializes the auth configuration as a base64url encoded
// RFC4648, section 5) JSON string for sending through the X-Registry-Auth header.
//
// For details on base64url encoding, see:
// - RFC4648, section 5: https://tools.ietf.org/html/rfc4648#section-5
func EncodeAuthConfig(authConfig AuthConfig) (string, error) {
buf, err := json.Marshal(authConfig)
if err != nil {
return "", errInvalidParameter{err}
}
return base64.URLEncoding.EncodeToString(buf), nil
}
// DecodeAuthConfig decodes base64url encoded (RFC4648, section 5) JSON
// authentication information as sent through the X-Registry-Auth header.
//
// This function always returns an AuthConfig, even if an error occurs. It is up
// to the caller to decide if authentication is required, and if the error can
// be ignored.
//
// For details on base64url encoding, see:
// - RFC4648, section 5: https://tools.ietf.org/html/rfc4648#section-5
func DecodeAuthConfig(authEncoded string) (*AuthConfig, error) {
if authEncoded == "" {
return &AuthConfig{}, nil
}
authJSON := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded))
return decodeAuthConfigFromReader(authJSON)
}
// DecodeAuthConfigBody decodes authentication information as sent as JSON in the
// body of a request. This function is to provide backward compatibility with old
// clients and API versions. Current clients and API versions expect authentication
// to be provided through the X-Registry-Auth header.
//
// Like DecodeAuthConfig, this function always returns an AuthConfig, even if an
// error occurs. It is up to the caller to decide if authentication is required,
// and if the error can be ignored.
func DecodeAuthConfigBody(rdr io.ReadCloser) (*AuthConfig, error) {
return decodeAuthConfigFromReader(rdr)
}
func decodeAuthConfigFromReader(rdr io.Reader) (*AuthConfig, error) {
authConfig := &AuthConfig{}
if err := json.NewDecoder(rdr).Decode(authConfig); err != nil {
// always return an (empty) AuthConfig to increase compatibility with
// the existing API.
return &AuthConfig{}, invalid(err)
}
return authConfig, nil
}
func invalid(err error) error {
return errInvalidParameter{errors.Wrap(err, "invalid X-Registry-Auth header")}
}
type errInvalidParameter struct{ error }
func (errInvalidParameter) InvalidParameter() {}
func (e errInvalidParameter) Cause() error { return e.error }
func (e errInvalidParameter) Unwrap() error { return e.error }

View file

@ -0,0 +1,59 @@
package registry // import "github.com/docker/docker/api/types/registry"
import (
"io"
"strings"
"testing"
"gotest.tools/v3/assert"
)
const (
unencoded = `{"username":"testuser","password":"testpassword","serveraddress":"example.com"}`
encoded = `eyJ1c2VybmFtZSI6InRlc3R1c2VyIiwicGFzc3dvcmQiOiJ0ZXN0cGFzc3dvcmQiLCJzZXJ2ZXJhZGRyZXNzIjoiZXhhbXBsZS5jb20ifQ==`
encodedNoPadding = `eyJ1c2VybmFtZSI6InRlc3R1c2VyIiwicGFzc3dvcmQiOiJ0ZXN0cGFzc3dvcmQiLCJzZXJ2ZXJhZGRyZXNzIjoiZXhhbXBsZS5jb20ifQ`
)
var expected = AuthConfig{
Username: "testuser",
Password: "testpassword",
ServerAddress: "example.com",
}
func TestDecodeAuthConfig(t *testing.T) {
t.Run("valid", func(t *testing.T) {
token, err := DecodeAuthConfig(encoded)
assert.NilError(t, err)
assert.Equal(t, *token, expected)
})
t.Run("empty", func(t *testing.T) {
token, err := DecodeAuthConfig("")
assert.NilError(t, err)
assert.Equal(t, *token, AuthConfig{})
})
// We currently only support base64url encoding with padding, so
// un-padded should produce an error.
//
// RFC4648, section 5: https://tools.ietf.org/html/rfc4648#section-5
// RFC4648, section 3.2: https://tools.ietf.org/html/rfc4648#section-3.2
t.Run("invalid encoding", func(t *testing.T) {
token, err := DecodeAuthConfig(encodedNoPadding)
assert.ErrorType(t, err, errInvalidParameter{})
assert.ErrorContains(t, err, "invalid X-Registry-Auth header: unexpected EOF")
assert.Equal(t, *token, AuthConfig{})
})
}
func TestDecodeAuthConfigBody(t *testing.T) {
token, err := DecodeAuthConfigBody(io.NopCloser(strings.NewReader(unencoded)))
assert.NilError(t, err)
assert.Equal(t, *token, expected)
}
func TestEncodeAuthConfig(t *testing.T) {
token, err := EncodeAuthConfig(expected)
assert.NilError(t, err)
assert.Equal(t, token, encoded)
}

View file

@ -5,13 +5,13 @@ import (
"encoding/json"
"net/url"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/registry"
)
// DistributionInspect returns the image digest with the full manifest.
func (cli *Client) DistributionInspect(ctx context.Context, image, encodedRegistryAuth string) (registrytypes.DistributionInspect, error) {
func (cli *Client) DistributionInspect(ctx context.Context, image, encodedRegistryAuth string) (registry.DistributionInspect, error) {
// Contact the registry to retrieve digest and platform information
var distributionInspect registrytypes.DistributionInspect
var distributionInspect registry.DistributionInspect
if image == "" {
return distributionInspect, objectNotFoundError{object: "distribution", id: image}
}
@ -23,7 +23,7 @@ func (cli *Client) DistributionInspect(ctx context.Context, image, encodedRegist
if encodedRegistryAuth != "" {
headers = map[string][]string{
"X-Registry-Auth": {encodedRegistryAuth},
registry.AuthHeader: {encodedRegistryAuth},
}
}

View file

@ -12,6 +12,7 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs"
units "github.com/docker/go-units"
)
@ -144,7 +145,7 @@ func TestImageBuild(t *testing.T) {
},
{
buildOptions: types.ImageBuildOptions{
AuthConfigs: map[string]types.AuthConfig{
AuthConfigs: map[string]registry.AuthConfig{
"https://index.docker.io/v1/": {
Auth: "dG90bwo=",
},

View file

@ -8,6 +8,7 @@ import (
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
)
// ImageCreate creates a new image based on the parent options.
@ -32,6 +33,6 @@ func (cli *Client) ImageCreate(ctx context.Context, parentReference string, opti
}
func (cli *Client) tryImageCreate(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {
headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
headers := map[string][]string{registry.AuthHeader: {registryAuth}}
return cli.post(ctx, "/images/create", query, nil, headers)
}

View file

@ -10,6 +10,7 @@ import (
"testing"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs"
)
@ -34,9 +35,9 @@ func TestImageCreate(t *testing.T) {
if !strings.HasPrefix(r.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL)
}
registryAuth := r.Header.Get("X-Registry-Auth")
registryAuth := r.Header.Get(registry.AuthHeader)
if registryAuth != expectedRegistryAuth {
return nil, fmt.Errorf("X-Registry-Auth header not properly set in the request. Expected '%s', got %s", expectedRegistryAuth, registryAuth)
return nil, fmt.Errorf("%s header not properly set in the request. Expected '%s', got %s", registry.AuthHeader, expectedRegistryAuth, registryAuth)
}
query := r.URL.Query()

View file

@ -10,6 +10,7 @@ import (
"testing"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs"
)
@ -81,9 +82,9 @@ func TestImagePullWithPrivilegedFuncNoError(t *testing.T) {
client := &Client{
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
return nil, fmt.Errorf("expected URL '%s', got '%s'", expectedURL, req.URL)
}
auth := req.Header.Get("X-Registry-Auth")
auth := req.Header.Get(registry.AuthHeader)
if auth == "NotValid" {
return &http.Response{
StatusCode: http.StatusUnauthorized,
@ -91,7 +92,7 @@ func TestImagePullWithPrivilegedFuncNoError(t *testing.T) {
}, nil
}
if auth != "IAmValid" {
return nil, fmt.Errorf("Invalid auth header : expected %s, got %s", "IAmValid", auth)
return nil, fmt.Errorf("invalid auth header: expected %s, got %s", "IAmValid", auth)
}
query := req.URL.Query()
fromImage := query.Get("fromImage")

View file

@ -8,6 +8,7 @@ import (
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs"
)
@ -49,6 +50,6 @@ func (cli *Client) ImagePush(ctx context.Context, image string, options types.Im
}
func (cli *Client) tryImagePush(ctx context.Context, imageID string, query url.Values, registryAuth string) (serverResponse, error) {
headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
headers := map[string][]string{registry.AuthHeader: {registryAuth}}
return cli.post(ctx, "/images/"+imageID+"/push", query, nil, headers)
}

View file

@ -10,6 +10,7 @@ import (
"testing"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs"
)
@ -88,7 +89,7 @@ func TestImagePushWithPrivilegedFuncNoError(t *testing.T) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}
auth := req.Header.Get("X-Registry-Auth")
auth := req.Header.Get(registry.AuthHeader)
if auth == "NotValid" {
return &http.Response{
StatusCode: http.StatusUnauthorized,
@ -96,7 +97,7 @@ func TestImagePushWithPrivilegedFuncNoError(t *testing.T) {
}, nil
}
if auth != "IAmValid" {
return nil, fmt.Errorf("Invalid auth header : expected %s, got %s", "IAmValid", auth)
return nil, fmt.Errorf("invalid auth header: expected %s, got %s", "IAmValid", auth)
}
query := req.URL.Query()
tag := query.Get("tag")

View file

@ -48,6 +48,6 @@ func (cli *Client) ImageSearch(ctx context.Context, term string, options types.I
}
func (cli *Client) tryImageSearch(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {
headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
headers := map[string][]string{registry.AuthHeader: {registryAuth}}
return cli.get(ctx, "/images/search", query, headers)
}

View file

@ -73,7 +73,7 @@ func TestImageSearchWithPrivilegedFuncNoError(t *testing.T) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}
auth := req.Header.Get("X-Registry-Auth")
auth := req.Header.Get(registry.AuthHeader)
if auth == "NotValid" {
return &http.Response{
StatusCode: http.StatusUnauthorized,
@ -81,7 +81,7 @@ func TestImageSearchWithPrivilegedFuncNoError(t *testing.T) {
}, nil
}
if auth != "IAmValid" {
return nil, fmt.Errorf("Invalid auth header : expected 'IAmValid', got %s", auth)
return nil, fmt.Errorf("invalid auth header: expected 'IAmValid', got %s", auth)
}
query := req.URL.Query()
term := query.Get("term")

View file

@ -166,7 +166,7 @@ type SwarmAPIClient interface {
type SystemAPIClient interface {
Events(ctx context.Context, options types.EventsOptions) (<-chan events.Message, <-chan error)
Info(ctx context.Context) (types.Info, error)
RegistryLogin(ctx context.Context, auth types.AuthConfig) (registry.AuthenticateOKBody, error)
RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error)
DiskUsage(ctx context.Context, options types.DiskUsageOptions) (types.DiskUsage, error)
Ping(ctx context.Context) (types.Ping, error)
}

View file

@ -5,13 +5,12 @@ import (
"encoding/json"
"net/url"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
)
// RegistryLogin authenticates the docker server with a given docker registry.
// It returns unauthorizedError when the authentication fails.
func (cli *Client) RegistryLogin(ctx context.Context, auth types.AuthConfig) (registry.AuthenticateOKBody, error) {
func (cli *Client) RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error) {
resp, err := cli.post(ctx, "/auth", url.Values{}, auth, nil)
defer ensureReaderClosed(resp)

View file

@ -8,6 +8,7 @@ import (
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs"
"github.com/pkg/errors"
)
@ -67,12 +68,12 @@ func (cli *Client) PluginInstall(ctx context.Context, name string, options types
}
func (cli *Client) tryPluginPrivileges(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {
headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
headers := map[string][]string{registry.AuthHeader: {registryAuth}}
return cli.get(ctx, "/plugins/privileges", query, headers)
}
func (cli *Client) tryPluginPull(ctx context.Context, query url.Values, privileges types.PluginPrivileges, registryAuth string) (serverResponse, error) {
headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
headers := map[string][]string{registry.AuthHeader: {registryAuth}}
return cli.post(ctx, "/plugins/pull", query, privileges, headers)
}

View file

@ -3,11 +3,13 @@ package client // import "github.com/docker/docker/client"
import (
"context"
"io"
"github.com/docker/docker/api/types/registry"
)
// PluginPush pushes a plugin to a registry
func (cli *Client) PluginPush(ctx context.Context, name string, registryAuth string) (io.ReadCloser, error) {
headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
headers := map[string][]string{registry.AuthHeader: {registryAuth}}
resp, err := cli.post(ctx, "/plugins/"+name+"/push", nil, nil, headers)
if err != nil {
return nil, err

View file

@ -9,6 +9,7 @@ import (
"strings"
"testing"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs"
)
@ -34,9 +35,9 @@ func TestPluginPush(t *testing.T) {
if req.Method != http.MethodPost {
return nil, fmt.Errorf("expected POST method, got %s", req.Method)
}
auth := req.Header.Get("X-Registry-Auth")
auth := req.Header.Get(registry.AuthHeader)
if auth != "authtoken" {
return nil, fmt.Errorf("Invalid auth header : expected 'authtoken', got %s", auth)
return nil, fmt.Errorf("invalid auth header: expected 'authtoken', got %s", auth)
}
return &http.Response{
StatusCode: http.StatusOK,

View file

@ -7,6 +7,7 @@ import (
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/pkg/errors"
)
@ -34,6 +35,6 @@ func (cli *Client) PluginUpgrade(ctx context.Context, name string, options types
}
func (cli *Client) tryPluginUpgrade(ctx context.Context, query url.Values, privileges types.PluginPrivileges, name, registryAuth string) (serverResponse, error) {
headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
headers := map[string][]string{registry.AuthHeader: {registryAuth}}
return cli.post(ctx, "/plugins/"+name+"/upgrade", query, privileges, headers)
}

View file

@ -8,6 +8,7 @@ import (
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
@ -21,7 +22,7 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec,
}
if options.EncodedRegistryAuth != "" {
headers["X-Registry-Auth"] = []string{options.EncodedRegistryAuth}
headers[registry.AuthHeader] = []string{options.EncodedRegistryAuth}
}
// Make sure containerSpec is not nil when no runtime is set or the runtime is set to container

View file

@ -6,6 +6,7 @@ import (
"net/url"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm"
)
@ -23,7 +24,7 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version
}
if options.EncodedRegistryAuth != "" {
headers["X-Registry-Auth"] = []string{options.EncodedRegistryAuth}
headers[registry.AuthHeader] = []string{options.EncodedRegistryAuth}
}
if options.RegistryAuthFrom != "" {

View file

@ -3,11 +3,11 @@ package daemon // import "github.com/docker/docker/daemon"
import (
"context"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/dockerversion"
)
// AuthenticateToRegistry checks the validity of credentials in authConfig
func (daemon *Daemon) AuthenticateToRegistry(ctx context.Context, authConfig *types.AuthConfig) (string, string, error) {
func (daemon *Daemon) AuthenticateToRegistry(ctx context.Context, authConfig *registry.AuthConfig) (string, string, error) {
return daemon.registryService.Auth(ctx, authConfig, dockerversion.DockerUserAgent(ctx))
}

View file

@ -6,7 +6,8 @@ import (
"net/http"
"github.com/docker/distribution/reference"
enginetypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm/runtime"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/plugin"
@ -41,11 +42,11 @@ type Controller struct {
// Backend is the interface for interacting with the plugin manager
// Controller actions are passed to the configured backend to do the real work.
type Backend interface {
Disable(name string, config *enginetypes.PluginDisableConfig) error
Enable(name string, config *enginetypes.PluginEnableConfig) error
Remove(name string, config *enginetypes.PluginRmConfig) error
Pull(ctx context.Context, ref reference.Named, name string, metaHeaders http.Header, authConfig *enginetypes.AuthConfig, privileges enginetypes.PluginPrivileges, outStream io.Writer, opts ...plugin.CreateOpt) error
Upgrade(ctx context.Context, ref reference.Named, name string, metaHeaders http.Header, authConfig *enginetypes.AuthConfig, privileges enginetypes.PluginPrivileges, outStream io.Writer) error
Disable(name string, config *types.PluginDisableConfig) error
Enable(name string, config *types.PluginEnableConfig) error
Remove(name string, config *types.PluginRmConfig) error
Pull(ctx context.Context, ref reference.Named, name string, metaHeaders http.Header, authConfig *registry.AuthConfig, privileges types.PluginPrivileges, outStream io.Writer, opts ...plugin.CreateOpt) error
Upgrade(ctx context.Context, ref reference.Named, name string, metaHeaders http.Header, authConfig *registry.AuthConfig, privileges types.PluginPrivileges, outStream io.Writer) error
Get(name string) (*v2.Plugin, error)
SubscribeEvents(buffer int, events ...plugin.Event) (eventCh <-chan interface{}, cancel func())
}
@ -96,7 +97,7 @@ func (p *Controller) Prepare(ctx context.Context) (err error) {
p.spec.Name = remote.String()
}
var authConfig enginetypes.AuthConfig
var authConfig registry.AuthConfig
privs := convertPrivileges(p.spec.Privileges)
pl, err := p.backend.Get(p.spec.Name)
@ -112,7 +113,7 @@ func (p *Controller) Prepare(ctx context.Context) (err error) {
return errors.Errorf("plugin already exists: %s", p.spec.Name)
}
if pl.IsEnabled() {
if err := p.backend.Disable(pl.GetID(), &enginetypes.PluginDisableConfig{ForceDisable: true}); err != nil {
if err := p.backend.Disable(pl.GetID(), &types.PluginDisableConfig{ForceDisable: true}); err != nil {
p.logger.WithError(err).Debug("could not disable plugin before running upgrade")
}
}
@ -143,12 +144,12 @@ func (p *Controller) Start(ctx context.Context) error {
if p.spec.Disabled {
if pl.IsEnabled() {
return p.backend.Disable(p.pluginID, &enginetypes.PluginDisableConfig{ForceDisable: false})
return p.backend.Disable(p.pluginID, &types.PluginDisableConfig{ForceDisable: false})
}
return nil
}
if !pl.IsEnabled() {
return p.backend.Enable(p.pluginID, &enginetypes.PluginEnableConfig{Timeout: 30})
return p.backend.Enable(p.pluginID, &types.PluginEnableConfig{Timeout: 30})
}
return nil
}
@ -232,7 +233,7 @@ func (p *Controller) Remove(ctx context.Context) error {
// This may error because we have exactly 1 plugin, but potentially multiple
// tasks which are calling remove.
err = p.backend.Remove(p.pluginID, &enginetypes.PluginRmConfig{ForceRemove: true})
err = p.backend.Remove(p.pluginID, &types.PluginRmConfig{ForceRemove: true})
if isNotFound(err) {
return nil
}
@ -245,10 +246,10 @@ func (p *Controller) Close() error {
return nil
}
func convertPrivileges(ls []*runtime.PluginPrivilege) enginetypes.PluginPrivileges {
var out enginetypes.PluginPrivileges
func convertPrivileges(ls []*runtime.PluginPrivilege) types.PluginPrivileges {
var out types.PluginPrivileges
for _, p := range ls {
pp := enginetypes.PluginPrivilege{
pp := types.PluginPrivilege{
Name: p.Name,
Description: p.Description,
Value: p.Value,

View file

@ -10,7 +10,8 @@ import (
"time"
"github.com/docker/distribution/reference"
enginetypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm/runtime"
"github.com/docker/docker/pkg/pubsub"
"github.com/docker/docker/plugin"
@ -341,27 +342,27 @@ type mockBackend struct {
pub *pubsub.Publisher
}
func (m *mockBackend) Disable(name string, config *enginetypes.PluginDisableConfig) error {
func (m *mockBackend) Disable(name string, config *types.PluginDisableConfig) error {
m.p.PluginObj.Enabled = false
m.pub.Publish(plugin.EventDisable{})
return nil
}
func (m *mockBackend) Enable(name string, config *enginetypes.PluginEnableConfig) error {
func (m *mockBackend) Enable(name string, config *types.PluginEnableConfig) error {
m.p.PluginObj.Enabled = true
m.pub.Publish(plugin.EventEnable{})
return nil
}
func (m *mockBackend) Remove(name string, config *enginetypes.PluginRmConfig) error {
func (m *mockBackend) Remove(name string, config *types.PluginRmConfig) error {
m.p = nil
m.pub.Publish(plugin.EventRemove{})
return nil
}
func (m *mockBackend) Pull(ctx context.Context, ref reference.Named, name string, metaHeaders http.Header, authConfig *enginetypes.AuthConfig, privileges enginetypes.PluginPrivileges, outStream io.Writer, opts ...plugin.CreateOpt) error {
func (m *mockBackend) Pull(ctx context.Context, ref reference.Named, name string, metaHeaders http.Header, authConfig *registry.AuthConfig, privileges types.PluginPrivileges, outStream io.Writer, opts ...plugin.CreateOpt) error {
m.p = &v2.Plugin{
PluginObj: enginetypes.Plugin{
PluginObj: types.Plugin{
ID: "1234",
Name: name,
PluginReference: ref.String(),
@ -370,7 +371,7 @@ func (m *mockBackend) Pull(ctx context.Context, ref reference.Named, name string
return nil
}
func (m *mockBackend) Upgrade(ctx context.Context, ref reference.Named, name string, metaHeaders http.Header, authConfig *enginetypes.AuthConfig, privileges enginetypes.PluginPrivileges, outStream io.Writer) error {
func (m *mockBackend) Upgrade(ctx context.Context, ref reference.Named, name string, metaHeaders http.Header, authConfig *registry.AuthConfig, privileges types.PluginPrivileges, outStream io.Writer) error {
m.p.PluginObj.PluginReference = pluginTestRemoteUpgrade
return nil
}

View file

@ -13,7 +13,8 @@ import (
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/network"
swarmtypes "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/volume"
containerpkg "github.com/docker/docker/container"
clustertypes "github.com/docker/docker/daemon/cluster/provider"
@ -48,8 +49,8 @@ type Backend interface {
ContainerRm(name string, config *types.ContainerRmConfig) error
ContainerKill(name string, sig string) error
SetContainerDependencyStore(name string, store exec.DependencyGetter) error
SetContainerSecretReferences(name string, refs []*swarmtypes.SecretReference) error
SetContainerConfigReferences(name string, refs []*swarmtypes.ConfigReference) error
SetContainerSecretReferences(name string, refs []*swarm.SecretReference) error
SetContainerConfigReferences(name string, refs []*swarm.ConfigReference) error
SystemInfo() *types.Info
Containers(config *types.ContainerListOptions) ([]*types.Container, error)
SetNetworkBootstrapKeys([]*networktypes.EncryptionKey) error
@ -73,7 +74,7 @@ type VolumeBackend interface {
// ImageBackend is used by an executor to perform image operations
type ImageBackend interface {
PullImage(ctx context.Context, image, tag string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error
GetRepository(context.Context, reference.Named, *types.AuthConfig) (distribution.Repository, error)
PullImage(ctx context.Context, image, tag string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error
GetRepository(context.Context, reference.Named, *registry.AuthConfig) (distribution.Repository, error)
GetImage(refOrID string, platform *specs.Platform) (retImg *image.Image, retErr error)
}

View file

@ -16,6 +16,7 @@ import (
"github.com/docker/docker/api/types/backend"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/registry"
containerpkg "github.com/docker/docker/container"
"github.com/docker/docker/daemon"
"github.com/docker/docker/daemon/cluster/convert"
@ -87,7 +88,7 @@ func (c *containerAdapter) pullImage(ctx context.Context) error {
encodedAuthConfig = spec.PullOptions.RegistryAuth
}
authConfig := &types.AuthConfig{}
authConfig := &registry.AuthConfig{}
if encodedAuthConfig != "" {
if err := json.NewDecoder(base64.NewDecoder(base64.URLEncoding, strings.NewReader(encodedAuthConfig))).Decode(authConfig); err != nil {
logrus.Warnf("invalid authconfig: %v", err)

View file

@ -12,9 +12,10 @@ import (
"time"
"github.com/docker/distribution/reference"
apitypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
types "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm"
timetypes "github.com/docker/docker/api/types/time"
"github.com/docker/docker/daemon/cluster/convert"
"github.com/docker/docker/errdefs"
@ -27,7 +28,7 @@ import (
)
// GetServices returns all services of a managed swarm cluster.
func (c *Cluster) GetServices(options apitypes.ServiceListOptions) ([]types.Service, error) {
func (c *Cluster) GetServices(options types.ServiceListOptions) ([]swarm.Service, error) {
c.mu.RLock()
defer c.mu.RUnlock()
@ -53,7 +54,7 @@ func (c *Cluster) GetServices(options apitypes.ServiceListOptions) ([]types.Serv
if len(options.Filters.Get("runtime")) == 0 {
// Default to using the container runtime filter
options.Filters.Add("runtime", string(types.RuntimeContainer))
options.Filters.Add("runtime", string(swarm.RuntimeContainer))
}
filters := &swarmapi.ListServicesRequest_Filters{
@ -75,7 +76,7 @@ func (c *Cluster) GetServices(options apitypes.ServiceListOptions) ([]types.Serv
return nil, err
}
services := make([]types.Service, 0, len(r.Services))
services := make([]swarm.Service, 0, len(r.Services))
// if the user requests the service statuses, we'll store the IDs needed
// in this slice
@ -132,9 +133,9 @@ func (c *Cluster) GetServices(options apitypes.ServiceListOptions) ([]types.Serv
// result would be quadratic. instead, make a mapping of service IDs to
// service statuses so that this is roughly linear. additionally,
// convert the status response to an engine api service status here.
serviceMap := map[string]*types.ServiceStatus{}
serviceMap := map[string]*swarm.ServiceStatus{}
for _, status := range resp.Statuses {
serviceMap[status.ServiceID] = &types.ServiceStatus{
serviceMap[status.ServiceID] = &swarm.ServiceStatus{
RunningTasks: status.RunningTasks,
DesiredTasks: status.DesiredTasks,
CompletedTasks: status.CompletedTasks,
@ -159,7 +160,7 @@ func (c *Cluster) GetServices(options apitypes.ServiceListOptions) ([]types.Serv
}
// GetService returns a service based on an ID or name.
func (c *Cluster) GetService(input string, insertDefaults bool) (types.Service, error) {
func (c *Cluster) GetService(input string, insertDefaults bool) (swarm.Service, error) {
var service *swarmapi.Service
if err := c.lockedManagerAction(func(ctx context.Context, state nodeState) error {
s, err := getService(ctx, state.controlClient, input, insertDefaults)
@ -169,18 +170,18 @@ func (c *Cluster) GetService(input string, insertDefaults bool) (types.Service,
service = s
return nil
}); err != nil {
return types.Service{}, err
return swarm.Service{}, err
}
svc, err := convert.ServiceFromGRPC(*service)
if err != nil {
return types.Service{}, err
return swarm.Service{}, err
}
return svc, nil
}
// CreateService creates a new service in a managed swarm cluster.
func (c *Cluster) CreateService(s types.ServiceSpec, encodedAuth string, queryRegistry bool) (*apitypes.ServiceCreateResponse, error) {
var resp *apitypes.ServiceCreateResponse
func (c *Cluster) CreateService(s swarm.ServiceSpec, encodedAuth string, queryRegistry bool) (*types.ServiceCreateResponse, error) {
var resp *types.ServiceCreateResponse
err := c.lockedManagerAction(func(ctx context.Context, state nodeState) error {
err := c.populateNetworkID(ctx, state.controlClient, &s)
if err != nil {
@ -192,17 +193,17 @@ func (c *Cluster) CreateService(s types.ServiceSpec, encodedAuth string, queryRe
return errdefs.InvalidParameter(err)
}
resp = &apitypes.ServiceCreateResponse{}
resp = &types.ServiceCreateResponse{}
switch serviceSpec.Task.Runtime.(type) {
case *swarmapi.TaskSpec_Attachment:
return fmt.Errorf("invalid task spec: spec type %q not supported", types.RuntimeNetworkAttachment)
return fmt.Errorf("invalid task spec: spec type %q not supported", swarm.RuntimeNetworkAttachment)
// handle other runtimes here
case *swarmapi.TaskSpec_Generic:
switch serviceSpec.Task.GetGeneric().Kind {
case string(types.RuntimePlugin):
case string(swarm.RuntimePlugin):
if !c.config.Backend.HasExperimental() {
return fmt.Errorf("runtime type %q only supported in experimental", types.RuntimePlugin)
return fmt.Errorf("runtime type %q only supported in experimental", swarm.RuntimePlugin)
}
if s.TaskTemplate.PluginSpec == nil {
return errors.New("plugin spec must be set")
@ -228,7 +229,7 @@ func (c *Cluster) CreateService(s types.ServiceSpec, encodedAuth string, queryRe
}
// retrieve auth config from encoded auth
authConfig := &apitypes.AuthConfig{}
authConfig := &registry.AuthConfig{}
if encodedAuth != "" {
authReader := strings.NewReader(encodedAuth)
dec := json.NewDecoder(base64.NewDecoder(base64.URLEncoding, authReader))
@ -282,8 +283,8 @@ func (c *Cluster) CreateService(s types.ServiceSpec, encodedAuth string, queryRe
}
// UpdateService updates existing service to match new properties.
func (c *Cluster) UpdateService(serviceIDOrName string, version uint64, spec types.ServiceSpec, flags apitypes.ServiceUpdateOptions, queryRegistry bool) (*apitypes.ServiceUpdateResponse, error) {
var resp *apitypes.ServiceUpdateResponse
func (c *Cluster) UpdateService(serviceIDOrName string, version uint64, spec swarm.ServiceSpec, flags types.ServiceUpdateOptions, queryRegistry bool) (*types.ServiceUpdateResponse, error) {
var resp *types.ServiceUpdateResponse
err := c.lockedManagerAction(func(ctx context.Context, state nodeState) error {
@ -302,14 +303,14 @@ func (c *Cluster) UpdateService(serviceIDOrName string, version uint64, spec typ
return err
}
resp = &apitypes.ServiceUpdateResponse{}
resp = &types.ServiceUpdateResponse{}
switch serviceSpec.Task.Runtime.(type) {
case *swarmapi.TaskSpec_Attachment:
return fmt.Errorf("invalid task spec: spec type %q not supported", types.RuntimeNetworkAttachment)
return fmt.Errorf("invalid task spec: spec type %q not supported", swarm.RuntimeNetworkAttachment)
case *swarmapi.TaskSpec_Generic:
switch serviceSpec.Task.GetGeneric().Kind {
case string(types.RuntimePlugin):
case string(swarm.RuntimePlugin):
if spec.TaskTemplate.PluginSpec == nil {
return errors.New("plugin spec must be set")
}
@ -328,9 +329,9 @@ func (c *Cluster) UpdateService(serviceIDOrName string, version uint64, spec typ
// shouldn't lose it, and continue to use the one that was already present
var ctnr *swarmapi.ContainerSpec
switch flags.RegistryAuthFrom {
case apitypes.RegistryAuthFromSpec, "":
case types.RegistryAuthFromSpec, "":
ctnr = currentService.Spec.Task.GetContainer()
case apitypes.RegistryAuthFromPreviousSpec:
case types.RegistryAuthFromPreviousSpec:
if currentService.PreviousSpec == nil {
return errors.New("service does not have a previous spec")
}
@ -349,7 +350,7 @@ func (c *Cluster) UpdateService(serviceIDOrName string, version uint64, spec typ
}
// retrieve auth config from encoded auth
authConfig := &apitypes.AuthConfig{}
authConfig := &registry.AuthConfig{}
if encodedAuth != "" {
if err := json.NewDecoder(base64.NewDecoder(base64.URLEncoding, strings.NewReader(encodedAuth))).Decode(authConfig); err != nil {
logrus.Warnf("invalid authconfig: %v", err)
@ -425,7 +426,7 @@ func (c *Cluster) RemoveService(input string) error {
}
// ServiceLogs collects service logs and writes them back to `config.OutStream`
func (c *Cluster) ServiceLogs(ctx context.Context, selector *backend.LogSelector, config *apitypes.ContainerLogsOptions) (<-chan *backend.LogMessage, error) {
func (c *Cluster) ServiceLogs(ctx context.Context, selector *backend.LogSelector, config *types.ContainerLogsOptions) (<-chan *backend.LogMessage, error) {
c.mu.RLock()
defer c.mu.RUnlock()
@ -612,7 +613,7 @@ func convertSelector(ctx context.Context, cc swarmapi.ControlClient, selector *b
// imageWithDigestString takes an image such as name or name:tag
// and returns the image pinned to a digest, such as name@sha256:34234
func (c *Cluster) imageWithDigestString(ctx context.Context, image string, authConfig *apitypes.AuthConfig) (string, error) {
func (c *Cluster) imageWithDigestString(ctx context.Context, image string, authConfig *registry.AuthConfig) (string, error) {
ref, err := reference.ParseAnyReference(image)
if err != nil {
return "", err

View file

@ -8,7 +8,7 @@ import (
"github.com/containerd/containerd/platforms"
"github.com/docker/distribution"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs"
"github.com/opencontainers/go-digest"
specs "github.com/opencontainers/image-spec/specs-go/v1"
@ -16,7 +16,7 @@ import (
// PullImage initiates a pull operation. image is the repository name to pull, and
// tagOrDigest may be either empty, or indicate a specific tag or digest to pull.
func (i *ImageService) PullImage(ctx context.Context, image, tagOrDigest string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error {
func (i *ImageService) PullImage(ctx context.Context, image, tagOrDigest string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error {
var opts []containerd.RemoteOpt
if platform != nil {
opts = append(opts, containerd.WithPlatform(platforms.Format(*platform)))
@ -46,6 +46,6 @@ func (i *ImageService) PullImage(ctx context.Context, image, tagOrDigest string,
}
// GetRepository returns a repository from the registry.
func (i *ImageService) GetRepository(ctx context.Context, ref reference.Named, authConfig *types.AuthConfig) (distribution.Repository, error) {
func (i *ImageService) GetRepository(ctx context.Context, ref reference.Named, authConfig *registry.AuthConfig) (distribution.Repository, error) {
panic("not implemented")
}

View file

@ -4,10 +4,10 @@ import (
"context"
"io"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
)
// PushImage initiates a push operation on the repository named localName.
func (i *ImageService) PushImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error {
func (i *ImageService) PushImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error {
panic("not implemented")
}

View file

@ -3,9 +3,8 @@ package containerd
import (
"context"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/registry"
)
// SearchRegistryForImages queries the registry for images matching
@ -13,6 +12,6 @@ import (
//
// TODO: this could be implemented in a registry service instead of the image
// service.
func (i *ImageService) SearchRegistryForImages(ctx context.Context, searchFilters filters.Args, term string, limit int, authConfig *types.AuthConfig, metaHeaders map[string][]string) (*registrytypes.SearchResults, error) {
func (i *ImageService) SearchRegistryForImages(ctx context.Context, searchFilters filters.Args, term string, limit int, authConfig *registry.AuthConfig, metaHeaders map[string][]string) (*registry.SearchResults, error) {
panic("not implemented")
}

View file

@ -25,8 +25,8 @@ import (
type ImageService interface {
// Images
PullImage(ctx context.Context, image, tag string, platform *v1.Platform, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error
PushImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error
PullImage(ctx context.Context, image, tag string, platform *v1.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error
PushImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error
CreateImage(config []byte, parent string) (builder.Image, error)
ImageDelete(imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error)
ExportImage(names []string, outStream io.Writer) error
@ -67,8 +67,8 @@ type ImageService interface {
// Other
GetRepository(ctx context.Context, ref reference.Named, authConfig *types.AuthConfig) (distribution.Repository, error)
SearchRegistryForImages(ctx context.Context, searchFilters filters.Args, term string, limit int, authConfig *types.AuthConfig, headers map[string][]string) (*registry.SearchResults, error)
GetRepository(ctx context.Context, ref reference.Named, authConfig *registry.AuthConfig) (distribution.Repository, error)
SearchRegistryForImages(ctx context.Context, searchFilters filters.Args, term string, limit int, authConfig *registry.AuthConfig, headers map[string][]string) (*registry.SearchResults, error)
DistributionServices() images.DistributionServices
Children(id image.ID) []image.ID
Cleanup() error

View file

@ -7,8 +7,8 @@ import (
"github.com/containerd/containerd/platforms"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/builder"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/image"
@ -18,7 +18,7 @@ import (
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/registry"
registrypkg "github.com/docker/docker/registry"
specs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@ -144,14 +144,14 @@ func newROLayerForImage(img *image.Image, layerStore layer.Store) (builder.ROLay
}
// TODO: could this use the regular daemon PullImage ?
func (i *ImageService) pullForBuilder(ctx context.Context, name string, authConfigs map[string]types.AuthConfig, output io.Writer, platform *specs.Platform) (*image.Image, error) {
func (i *ImageService) pullForBuilder(ctx context.Context, name string, authConfigs map[string]registry.AuthConfig, output io.Writer, platform *specs.Platform) (*image.Image, error) {
ref, err := reference.ParseNormalizedNamed(name)
if err != nil {
return nil, err
}
ref = reference.TagNameOnly(ref)
pullRegistryAuth := &types.AuthConfig{}
pullRegistryAuth := &registry.AuthConfig{}
if len(authConfigs) > 0 {
// The request came with a full auth config, use it
repoInfo, err := i.registryService.ResolveRepository(ref)
@ -159,7 +159,7 @@ func (i *ImageService) pullForBuilder(ctx context.Context, name string, authConf
return nil, err
}
resolvedConfig := registry.ResolveAuthConfig(authConfigs, repoInfo.Index)
resolvedConfig := registrypkg.ResolveAuthConfig(authConfigs, repoInfo.Index)
pullRegistryAuth = &resolvedConfig
}

View file

@ -10,7 +10,7 @@ import (
"github.com/containerd/containerd/namespaces"
dist "github.com/docker/distribution"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/distribution"
progressutils "github.com/docker/docker/distribution/utils"
"github.com/docker/docker/errdefs"
@ -24,7 +24,7 @@ import (
// PullImage initiates a pull operation. image is the repository name to pull, and
// tag may be either empty, or indicate a specific tag to pull.
func (i *ImageService) PullImage(ctx context.Context, image, tag string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error {
func (i *ImageService) PullImage(ctx context.Context, image, tag string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error {
start := time.Now()
// Special case: "pull -a" may send an image name with a
// trailing :. This is ugly, but let's not break API
@ -77,7 +77,7 @@ func (i *ImageService) PullImage(ctx context.Context, image, tag string, platfor
return nil
}
func (i *ImageService) pullImageWithReference(ctx context.Context, ref reference.Named, platform *specs.Platform, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error {
func (i *ImageService) pullImageWithReference(ctx context.Context, ref reference.Named, platform *specs.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error {
// Include a buffer so that slow client connections don't affect
// transfer performance.
progressChan := make(chan progress.Progress, 100)
@ -132,7 +132,7 @@ func (i *ImageService) pullImageWithReference(ctx context.Context, ref reference
}
// GetRepository returns a repository from the registry.
func (i *ImageService) GetRepository(ctx context.Context, ref reference.Named, authConfig *types.AuthConfig) (dist.Repository, error) {
func (i *ImageService) GetRepository(ctx context.Context, ref reference.Named, authConfig *registry.AuthConfig) (dist.Repository, error) {
return distribution.GetRepository(ctx, ref, &distribution.ImagePullConfig{
Config: distribution.Config{
AuthConfig: authConfig,

View file

@ -7,14 +7,14 @@ import (
"github.com/docker/distribution/manifest/schema2"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/distribution"
progressutils "github.com/docker/docker/distribution/utils"
"github.com/docker/docker/pkg/progress"
)
// PushImage initiates a push operation on the repository named localName.
func (i *ImageService) PushImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error {
func (i *ImageService) PushImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error {
start := time.Now()
ref, err := reference.ParseNormalizedNamed(image)
if err != nil {

View file

@ -4,9 +4,8 @@ import (
"context"
"strconv"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/dockerversion"
)
@ -22,8 +21,8 @@ var acceptedSearchFilterTags = map[string]bool{
// TODO: this could be implemented in a registry service instead of the image
// service.
func (i *ImageService) SearchRegistryForImages(ctx context.Context, searchFilters filters.Args, term string, limit int,
authConfig *types.AuthConfig,
headers map[string][]string) (*registrytypes.SearchResults, error) {
authConfig *registry.AuthConfig,
headers map[string][]string) (*registry.SearchResults, error) {
if err := searchFilters.Validate(acceptedSearchFilterTags); err != nil {
return nil, err
@ -63,7 +62,7 @@ func (i *ImageService) SearchRegistryForImages(ctx context.Context, searchFilter
return nil, err
}
filteredResults := []registrytypes.SearchResult{}
filteredResults := []registry.SearchResult{}
for _, result := range unfilteredResult.Results {
if searchFilters.Contains("is-automated") {
if isAutomated != result.IsAutomated {
@ -83,7 +82,7 @@ func (i *ImageService) SearchRegistryForImages(ctx context.Context, searchFilter
filteredResults = append(filteredResults, result)
}
return &registrytypes.SearchResults{
return &registry.SearchResults{
Query: unfilteredResult.Query,
NumResults: len(filteredResults),
Results: filteredResults,

View file

@ -5,27 +5,26 @@ import (
"errors"
"testing"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/registry"
registrypkg "github.com/docker/docker/registry"
"gotest.tools/v3/assert"
)
type fakeService struct {
registry.Service
registrypkg.Service
shouldReturnError bool
term string
results []registrytypes.SearchResult
results []registry.SearchResult
}
func (s *fakeService) Search(ctx context.Context, term string, limit int, authConfig *types.AuthConfig, userAgent string, headers map[string][]string) (*registrytypes.SearchResults, error) {
func (s *fakeService) Search(ctx context.Context, term string, limit int, authConfig *registry.AuthConfig, userAgent string, headers map[string][]string) (*registry.SearchResults, error) {
if s.shouldReturnError {
return nil, errdefs.Unknown(errors.New("search unknown error"))
}
return &registrytypes.SearchResults{
return &registry.SearchResults{
Query: s.term,
NumResults: len(s.results),
Results: s.results,
@ -104,23 +103,23 @@ func TestSearchRegistryForImages(t *testing.T) {
successCases := []struct {
name string
filtersArgs filters.Args
registryResults []registrytypes.SearchResult
expectedResults []registrytypes.SearchResult
registryResults []registry.SearchResult
expectedResults []registry.SearchResult
}{
{
name: "empty results",
registryResults: []registrytypes.SearchResult{},
expectedResults: []registrytypes.SearchResult{},
registryResults: []registry.SearchResult{},
expectedResults: []registry.SearchResult{},
},
{
name: "no filter",
registryResults: []registrytypes.SearchResult{
registryResults: []registry.SearchResult{
{
Name: "name",
Description: "description",
},
},
expectedResults: []registrytypes.SearchResult{
expectedResults: []registry.SearchResult{
{
Name: "name",
Description: "description",
@ -130,25 +129,25 @@ func TestSearchRegistryForImages(t *testing.T) {
{
name: "is-automated=true, no results",
filtersArgs: filters.NewArgs(filters.Arg("is-automated", "true")),
registryResults: []registrytypes.SearchResult{
registryResults: []registry.SearchResult{
{
Name: "name",
Description: "description",
},
},
expectedResults: []registrytypes.SearchResult{},
expectedResults: []registry.SearchResult{},
},
{
name: "is-automated=true",
filtersArgs: filters.NewArgs(filters.Arg("is-automated", "true")),
registryResults: []registrytypes.SearchResult{
registryResults: []registry.SearchResult{
{
Name: "name",
Description: "description",
IsAutomated: true,
},
},
expectedResults: []registrytypes.SearchResult{
expectedResults: []registry.SearchResult{
{
Name: "name",
Description: "description",
@ -159,26 +158,26 @@ func TestSearchRegistryForImages(t *testing.T) {
{
name: "is-automated=false, no results",
filtersArgs: filters.NewArgs(filters.Arg("is-automated", "false")),
registryResults: []registrytypes.SearchResult{
registryResults: []registry.SearchResult{
{
Name: "name",
Description: "description",
IsAutomated: true,
},
},
expectedResults: []registrytypes.SearchResult{},
expectedResults: []registry.SearchResult{},
},
{
name: "is-automated=false",
filtersArgs: filters.NewArgs(filters.Arg("is-automated", "false")),
registryResults: []registrytypes.SearchResult{
registryResults: []registry.SearchResult{
{
Name: "name",
Description: "description",
IsAutomated: false,
},
},
expectedResults: []registrytypes.SearchResult{
expectedResults: []registry.SearchResult{
{
Name: "name",
Description: "description",
@ -189,25 +188,25 @@ func TestSearchRegistryForImages(t *testing.T) {
{
name: "is-official=true, no results",
filtersArgs: filters.NewArgs(filters.Arg("is-official", "true")),
registryResults: []registrytypes.SearchResult{
registryResults: []registry.SearchResult{
{
Name: "name",
Description: "description",
},
},
expectedResults: []registrytypes.SearchResult{},
expectedResults: []registry.SearchResult{},
},
{
name: "is-official=true",
filtersArgs: filters.NewArgs(filters.Arg("is-official", "true")),
registryResults: []registrytypes.SearchResult{
registryResults: []registry.SearchResult{
{
Name: "name",
Description: "description",
IsOfficial: true,
},
},
expectedResults: []registrytypes.SearchResult{
expectedResults: []registry.SearchResult{
{
Name: "name",
Description: "description",
@ -218,26 +217,26 @@ func TestSearchRegistryForImages(t *testing.T) {
{
name: "is-official=false, no results",
filtersArgs: filters.NewArgs(filters.Arg("is-official", "false")),
registryResults: []registrytypes.SearchResult{
registryResults: []registry.SearchResult{
{
Name: "name",
Description: "description",
IsOfficial: true,
},
},
expectedResults: []registrytypes.SearchResult{},
expectedResults: []registry.SearchResult{},
},
{
name: "is-official=false",
filtersArgs: filters.NewArgs(filters.Arg("is-official", "false")),
registryResults: []registrytypes.SearchResult{
registryResults: []registry.SearchResult{
{
Name: "name",
Description: "description",
IsOfficial: false,
},
},
expectedResults: []registrytypes.SearchResult{
expectedResults: []registry.SearchResult{
{
Name: "name",
Description: "description",
@ -248,14 +247,14 @@ func TestSearchRegistryForImages(t *testing.T) {
{
name: "stars=0",
filtersArgs: filters.NewArgs(filters.Arg("stars", "0")),
registryResults: []registrytypes.SearchResult{
registryResults: []registry.SearchResult{
{
Name: "name",
Description: "description",
StarCount: 0,
},
},
expectedResults: []registrytypes.SearchResult{
expectedResults: []registry.SearchResult{
{
Name: "name",
Description: "description",
@ -266,19 +265,19 @@ func TestSearchRegistryForImages(t *testing.T) {
{
name: "stars=0, no results",
filtersArgs: filters.NewArgs(filters.Arg("stars", "1")),
registryResults: []registrytypes.SearchResult{
registryResults: []registry.SearchResult{
{
Name: "name",
Description: "description",
StarCount: 0,
},
},
expectedResults: []registrytypes.SearchResult{},
expectedResults: []registry.SearchResult{},
},
{
name: "stars=1",
filtersArgs: filters.NewArgs(filters.Arg("stars", "1")),
registryResults: []registrytypes.SearchResult{
registryResults: []registry.SearchResult{
{
Name: "name0",
Description: "description0",
@ -290,7 +289,7 @@ func TestSearchRegistryForImages(t *testing.T) {
StarCount: 1,
},
},
expectedResults: []registrytypes.SearchResult{
expectedResults: []registry.SearchResult{
{
Name: "name1",
Description: "description1",
@ -305,7 +304,7 @@ func TestSearchRegistryForImages(t *testing.T) {
filters.Arg("is-official", "true"),
filters.Arg("is-automated", "true"),
),
registryResults: []registrytypes.SearchResult{
registryResults: []registry.SearchResult{
{
Name: "name0",
Description: "description0",
@ -335,7 +334,7 @@ func TestSearchRegistryForImages(t *testing.T) {
IsAutomated: true,
},
},
expectedResults: []registrytypes.SearchResult{
expectedResults: []registry.SearchResult{
{
Name: "name3",
Description: "description3",

View file

@ -8,7 +8,7 @@ import (
"github.com/docker/distribution"
"github.com/docker/distribution/manifest/schema2"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/distribution/metadata"
"github.com/docker/docker/distribution/xfer"
"github.com/docker/docker/image"
@ -16,7 +16,7 @@ import (
"github.com/docker/docker/pkg/progress"
"github.com/docker/docker/pkg/system"
refstore "github.com/docker/docker/reference"
"github.com/docker/docker/registry"
registrypkg "github.com/docker/docker/registry"
"github.com/docker/libtrust"
"github.com/opencontainers/go-digest"
specs "github.com/opencontainers/image-spec/specs-go/v1"
@ -30,13 +30,13 @@ type Config struct {
MetaHeaders map[string][]string
// AuthConfig holds authentication credentials for authenticating with
// the registry.
AuthConfig *types.AuthConfig
AuthConfig *registry.AuthConfig
// ProgressOutput is the interface for showing the status of the pull
// operation.
ProgressOutput progress.Output
// RegistryService is the registry service to use for TLS configuration
// and endpoint lookup.
RegistryService registry.Service
RegistryService registrypkg.Service
// ImageEventLogger notifies events for a given image
ImageEventLogger func(id, name, action string)
// MetadataStore is the storage backend for distribution-specific

View file

@ -7,7 +7,7 @@ import (
"encoding/json"
"errors"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/layer"
"github.com/opencontainers/go-digest"
)
@ -69,7 +69,7 @@ func ComputeV2MetadataHMAC(key []byte, meta *V2Metadata) string {
// ComputeV2MetadataHMACKey returns a key for the given "authConfig" that can be used to hash v2 metadata
// entries.
func ComputeV2MetadataHMACKey(authConfig *types.AuthConfig) ([]byte, error) {
func ComputeV2MetadataHMACKey(authConfig *registry.AuthConfig) ([]byte, error) {
if authConfig == nil {
return nil, nil
}

View file

@ -16,7 +16,6 @@ import (
"github.com/docker/distribution/manifest/schema1"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/image"
"github.com/docker/docker/registry"
@ -351,7 +350,7 @@ func testNewPuller(t *testing.T, rawurl string) *puller {
imagePullConfig := &ImagePullConfig{
Config: Config{
MetaHeaders: http.Header{},
AuthConfig: &types.AuthConfig{
AuthConfig: &registrytypes.AuthConfig{
RegistryToken: secretRegistryToken,
},
},

View file

@ -11,12 +11,12 @@ import (
"github.com/docker/distribution/manifest/schema2"
"github.com/docker/distribution/reference"
"github.com/docker/distribution/registry/api/errcode"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/distribution/metadata"
"github.com/docker/docker/layer"
"github.com/docker/docker/pkg/progress"
refstore "github.com/docker/docker/reference"
"github.com/docker/docker/registry"
registrypkg "github.com/docker/docker/registry"
"github.com/opencontainers/go-digest"
)
@ -515,7 +515,7 @@ func TestWhenEmptyAuthConfig(t *testing.T) {
},
} {
imagePushConfig := &ImagePushConfig{}
imagePushConfig.AuthConfig = &types.AuthConfig{
imagePushConfig.AuthConfig = &registry.AuthConfig{
Username: authInfo.username,
Password: authInfo.password,
RegistryToken: authInfo.registryToken,
@ -524,15 +524,15 @@ func TestWhenEmptyAuthConfig(t *testing.T) {
repoInfo, _ := reference.ParseNormalizedNamed("xujihui1985/test.img")
pusher := &pusher{
config: imagePushConfig,
repoInfo: &registry.RepositoryInfo{
repoInfo: &registrypkg.RepositoryInfo{
Name: repoInfo,
},
endpoint: registry.APIEndpoint{
endpoint: registrypkg.APIEndpoint{
URL: &url.URL{
Scheme: "https",
Host: "index.docker.io",
},
Version: registry.APIVersion2,
Version: registrypkg.APIVersion2,
TrimHostname: true,
},
}

View file

@ -13,7 +13,7 @@ import (
"github.com/docker/distribution/registry/client"
"github.com/docker/distribution/registry/client/auth"
"github.com/docker/distribution/registry/client/transport"
"github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/dockerversion"
"github.com/docker/docker/registry"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@ -58,7 +58,7 @@ func init() {
// remote API version.
func newRepository(
ctx context.Context, repoInfo *registry.RepositoryInfo, endpoint registry.APIEndpoint,
metaHeaders http.Header, authConfig *types.AuthConfig, actions ...string,
metaHeaders http.Header, authConfig *registrytypes.AuthConfig, actions ...string,
) (repo distribution.Repository, err error) {
repoName := repoInfo.Name.Name()
// If endpoint does not support CanonicalName, use the RemoteName instead

View file

@ -9,9 +9,8 @@ import (
"testing"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/registry"
"github.com/docker/docker/api/types/registry"
registrypkg "github.com/docker/docker/registry"
"github.com/sirupsen/logrus"
)
@ -41,7 +40,7 @@ func testTokenPassThru(t *testing.T, ts *httptest.Server) {
t.Fatalf("could not parse url from test server: %v", err)
}
endpoint := registry.APIEndpoint{
endpoint := registrypkg.APIEndpoint{
Mirror: false,
URL: uri,
Version: 2,
@ -50,9 +49,9 @@ func testTokenPassThru(t *testing.T, ts *httptest.Server) {
TLSConfig: nil,
}
n, _ := reference.ParseNormalizedNamed("testremotename")
repoInfo := &registry.RepositoryInfo{
repoInfo := &registrypkg.RepositoryInfo{
Name: n,
Index: &registrytypes.IndexInfo{
Index: &registry.IndexInfo{
Name: "testrepo",
Mirrors: nil,
Secure: false,
@ -63,7 +62,7 @@ func testTokenPassThru(t *testing.T, ts *httptest.Server) {
imagePullConfig := &ImagePullConfig{
Config: Config{
MetaHeaders: http.Header{},
AuthConfig: &types.AuthConfig{
AuthConfig: &registry.AuthConfig{
RegistryToken: secretRegistryToken,
},
},

View file

@ -17,6 +17,7 @@ import (
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/remotes/docker"
"github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/pkg/jsonmessage"
"github.com/docker/docker/testutil/daemon"
"github.com/docker/docker/testutil/fixtures/plugin"
@ -125,7 +126,7 @@ func TestPluginInstall(t *testing.T) {
name := "test-" + strings.ToLower(t.Name())
repo := path.Join(registry.DefaultURL, name+":latest")
auth := &types.AuthConfig{ServerAddress: registry.DefaultURL, Username: "testuser", Password: "testpassword"}
auth := &registrytypes.AuthConfig{ServerAddress: registry.DefaultURL, Username: "testuser", Password: "testpassword"}
assert.NilError(t, plugin.CreateInRegistry(ctx, repo, auth))
authEncoded, err := json.Marshal(auth)

View file

@ -5,9 +5,9 @@ import (
"fmt"
"testing"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/integration/internal/requirement"
"github.com/docker/docker/registry"
registrypkg "github.com/docker/docker/registry"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/skip"
@ -20,12 +20,12 @@ func TestLoginFailsWithBadCredentials(t *testing.T) {
defer setupTest(t)()
client := testEnv.APIClient()
config := types.AuthConfig{
config := registry.AuthConfig{
Username: "no-user",
Password: "no-password",
}
_, err := client.RegistryLogin(context.Background(), config)
assert.Assert(t, err != nil)
assert.Check(t, is.ErrorContains(err, "unauthorized: incorrect username or password"))
assert.Check(t, is.ErrorContains(err, fmt.Sprintf("https://%s/v2/", registry.DefaultRegistryHost)))
assert.Check(t, is.ErrorContains(err, fmt.Sprintf("https://%s/v2/", registrypkg.DefaultRegistryHost)))
}

View file

@ -23,6 +23,7 @@ import (
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/dockerversion"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/authorization"
@ -121,12 +122,12 @@ func computePrivileges(c types.PluginConfig) types.PluginPrivileges {
Value: []string{"true"},
})
}
for _, mount := range c.Mounts {
if mount.Source != nil {
for _, mnt := range c.Mounts {
if mnt.Source != nil {
privileges = append(privileges, types.PluginPrivilege{
Name: "mount",
Description: "host path to mount",
Value: []string{*mount.Source},
Value: []string{*mnt.Source},
})
}
}
@ -158,7 +159,7 @@ func computePrivileges(c types.PluginConfig) types.PluginPrivileges {
}
// Privileges pulls a plugin config and computes the privileges required to install it.
func (pm *Manager) Privileges(ctx context.Context, ref reference.Named, metaHeader http.Header, authConfig *types.AuthConfig) (types.PluginPrivileges, error) {
func (pm *Manager) Privileges(ctx context.Context, ref reference.Named, metaHeader http.Header, authConfig *registry.AuthConfig) (types.PluginPrivileges, error) {
var (
config types.PluginConfig
configSeen bool
@ -206,7 +207,7 @@ func (pm *Manager) Privileges(ctx context.Context, ref reference.Named, metaHead
// Upgrade upgrades a plugin
//
// TODO: replace reference package usage with simpler url.Parse semantics
func (pm *Manager) Upgrade(ctx context.Context, ref reference.Named, name string, metaHeader http.Header, authConfig *types.AuthConfig, privileges types.PluginPrivileges, outStream io.Writer) (err error) {
func (pm *Manager) Upgrade(ctx context.Context, ref reference.Named, name string, metaHeader http.Header, authConfig *registry.AuthConfig, privileges types.PluginPrivileges, outStream io.Writer) (err error) {
p, err := pm.config.Store.GetV2Plugin(name)
if err != nil {
return err
@ -254,7 +255,7 @@ func (pm *Manager) Upgrade(ctx context.Context, ref reference.Named, name string
// Pull pulls a plugin, check if the correct privileges are provided and install the plugin.
//
// TODO: replace reference package usage with simpler url.Parse semantics
func (pm *Manager) Pull(ctx context.Context, ref reference.Named, name string, metaHeader http.Header, authConfig *types.AuthConfig, privileges types.PluginPrivileges, outStream io.Writer, opts ...CreateOpt) (err error) {
func (pm *Manager) Pull(ctx context.Context, ref reference.Named, name string, metaHeader http.Header, authConfig *registry.AuthConfig, privileges types.PluginPrivileges, outStream io.Writer, opts ...CreateOpt) (err error) {
pm.muGC.RLock()
defer pm.muGC.RUnlock()
@ -350,7 +351,7 @@ next:
}
// Push pushes a plugin to the registry.
func (pm *Manager) Push(ctx context.Context, name string, metaHeader http.Header, authConfig *types.AuthConfig, outStream io.Writer) error {
func (pm *Manager) Push(ctx context.Context, name string, metaHeader http.Header, authConfig *registry.AuthConfig, outStream io.Writer) error {
p, err := pm.config.Store.GetV2Plugin(name)
if err != nil {
return err

View file

@ -12,6 +12,7 @@ import (
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/registry"
)
var errNotSupported = errors.New("plugins are not supported on this platform")
@ -32,17 +33,17 @@ func (pm *Manager) Inspect(refOrID string) (tp *types.Plugin, err error) {
}
// Privileges pulls a plugin config and computes the privileges required to install it.
func (pm *Manager) Privileges(ctx context.Context, ref reference.Named, metaHeader http.Header, authConfig *types.AuthConfig) (types.PluginPrivileges, error) {
func (pm *Manager) Privileges(ctx context.Context, ref reference.Named, metaHeader http.Header, authConfig *registry.AuthConfig) (types.PluginPrivileges, error) {
return nil, errNotSupported
}
// Pull pulls a plugin, check if the correct privileges are provided and install the plugin.
func (pm *Manager) Pull(ctx context.Context, ref reference.Named, name string, metaHeader http.Header, authConfig *types.AuthConfig, privileges types.PluginPrivileges, out io.Writer, opts ...CreateOpt) error {
func (pm *Manager) Pull(ctx context.Context, ref reference.Named, name string, metaHeader http.Header, authConfig *registry.AuthConfig, privileges types.PluginPrivileges, out io.Writer, opts ...CreateOpt) error {
return errNotSupported
}
// Upgrade pulls a plugin, check if the correct privileges are provided and install the plugin.
func (pm *Manager) Upgrade(ctx context.Context, ref reference.Named, name string, metaHeader http.Header, authConfig *types.AuthConfig, privileges types.PluginPrivileges, outStream io.Writer) error {
func (pm *Manager) Upgrade(ctx context.Context, ref reference.Named, name string, metaHeader http.Header, authConfig *registry.AuthConfig, privileges types.PluginPrivileges, outStream io.Writer) error {
return errNotSupported
}
@ -52,7 +53,7 @@ func (pm *Manager) List(pluginFilters filters.Args) ([]types.Plugin, error) {
}
// Push pushes a plugin to the store.
func (pm *Manager) Push(ctx context.Context, name string, metaHeader http.Header, authConfig *types.AuthConfig, out io.Writer) error {
func (pm *Manager) Push(ctx context.Context, name string, metaHeader http.Header, authConfig *registry.AuthConfig, out io.Writer) error {
return errNotSupported
}

View file

@ -12,7 +12,7 @@ import (
"github.com/containerd/containerd/remotes"
"github.com/containerd/containerd/remotes/docker"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
progressutils "github.com/docker/docker/distribution/utils"
"github.com/docker/docker/pkg/chrootarchive"
"github.com/docker/docker/pkg/ioutils"
@ -59,7 +59,7 @@ func setupProgressOutput(outStream io.Writer, cancel func()) (progress.Output, f
// fetch the content related to the passed in reference into the blob store and appends the provided images.Handlers
// There is no need to use remotes.FetchHandler since it already gets set
func (pm *Manager) fetch(ctx context.Context, ref reference.Named, auth *types.AuthConfig, out progress.Output, metaHeader http.Header, handlers ...images.Handler) (err error) {
func (pm *Manager) fetch(ctx context.Context, ref reference.Named, auth *registry.AuthConfig, out progress.Output, metaHeader http.Header, handlers ...images.Handler) (err error) {
// We need to make sure we have a domain on the reference
withDomain, err := reference.ParseNormalizedNamed(ref.String())
if err != nil {

View file

@ -10,7 +10,7 @@ import (
"github.com/containerd/containerd/remotes"
"github.com/containerd/containerd/remotes/docker"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/dockerversion"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@ -27,7 +27,7 @@ func scope(ref reference.Named, push bool) string {
return scope
}
func (pm *Manager) newResolver(ctx context.Context, tracker docker.StatusTracker, auth *types.AuthConfig, headers http.Header, httpFallback bool) (remotes.Resolver, error) {
func (pm *Manager) newResolver(ctx context.Context, tracker docker.StatusTracker, auth *registry.AuthConfig, headers http.Header, httpFallback bool) (remotes.Resolver, error) {
if headers == nil {
headers = http.Header{}
}
@ -55,7 +55,7 @@ func registryHTTPClient(config *tls.Config) *http.Client {
}
}
func (pm *Manager) registryHostsFn(auth *types.AuthConfig, httpFallback bool) docker.RegistryHosts {
func (pm *Manager) registryHostsFn(auth *registry.AuthConfig, httpFallback bool) docker.RegistryHosts {
return func(hostname string) ([]docker.RegistryHost, error) {
eps, err := pm.config.RegistryService.LookupPullEndpoints(hostname)
if err != nil {

View file

@ -9,7 +9,6 @@ import (
"github.com/docker/distribution/registry/client/auth"
"github.com/docker/distribution/registry/client/auth/challenge"
"github.com/docker/distribution/registry/client/transport"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@ -19,7 +18,7 @@ import (
const AuthClientID = "docker"
type loginCredentialStore struct {
authConfig *types.AuthConfig
authConfig *registry.AuthConfig
}
func (lcs loginCredentialStore) Basic(*url.URL) (string, string) {
@ -35,12 +34,12 @@ func (lcs loginCredentialStore) SetRefreshToken(u *url.URL, service, token strin
}
type staticCredentialStore struct {
auth *types.AuthConfig
auth *registry.AuthConfig
}
// NewStaticCredentialStore returns a credential store
// which always returns the same credential values.
func NewStaticCredentialStore(auth *types.AuthConfig) auth.CredentialStore {
func NewStaticCredentialStore(auth *registry.AuthConfig) auth.CredentialStore {
return staticCredentialStore{
auth: auth,
}
@ -66,7 +65,7 @@ func (scs staticCredentialStore) SetRefreshToken(*url.URL, string, string) {
// loginV2 tries to login to the v2 registry server. The given registry
// endpoint will be pinged to get authorization challenges. These challenges
// will be used to authenticate against the registry to validate credentials.
func loginV2(authConfig *types.AuthConfig, endpoint APIEndpoint, userAgent string) (string, string, error) {
func loginV2(authConfig *registry.AuthConfig, endpoint APIEndpoint, userAgent string) (string, string, error) {
var (
endpointStr = strings.TrimRight(endpoint.URL.String(), "/") + "/v2/"
modifiers = Headers(userAgent, nil)
@ -138,7 +137,7 @@ func ConvertToHostname(url string) string {
}
// ResolveAuthConfig matches an auth configuration to a server address or a URL
func ResolveAuthConfig(authConfigs map[string]types.AuthConfig, index *registry.IndexInfo) types.AuthConfig {
func ResolveAuthConfig(authConfigs map[string]registry.AuthConfig, index *registry.IndexInfo) registry.AuthConfig {
configKey := GetAuthConfigKey(index)
// First try the happy case
if c, found := authConfigs[configKey]; found || index.Official {
@ -154,7 +153,7 @@ func ResolveAuthConfig(authConfigs map[string]types.AuthConfig, index *registry.
}
// When all else fails, return an empty auth config
return types.AuthConfig{}
return registry.AuthConfig{}
}
// PingResponseError is used when the response from a ping

View file

@ -3,16 +3,15 @@ package registry // import "github.com/docker/docker/registry"
import (
"testing"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"gotest.tools/v3/assert"
)
func buildAuthConfigs() map[string]types.AuthConfig {
authConfigs := map[string]types.AuthConfig{}
func buildAuthConfigs() map[string]registry.AuthConfig {
authConfigs := map[string]registry.AuthConfig{}
for _, reg := range []string{"testIndex", IndexServer} {
authConfigs[reg] = types.AuthConfig{
authConfigs[reg] = registry.AuthConfig{
Username: "docker-user",
Password: "docker-pass",
}
@ -42,21 +41,21 @@ func TestResolveAuthConfigIndexServer(t *testing.T) {
func TestResolveAuthConfigFullURL(t *testing.T) {
authConfigs := buildAuthConfigs()
registryAuth := types.AuthConfig{
registryAuth := registry.AuthConfig{
Username: "foo-user",
Password: "foo-pass",
}
localAuth := types.AuthConfig{
localAuth := registry.AuthConfig{
Username: "bar-user",
Password: "bar-pass",
}
officialAuth := types.AuthConfig{
officialAuth := registry.AuthConfig{
Username: "baz-user",
Password: "baz-pass",
}
authConfigs[IndexServer] = officialAuth
expectedAuths := map[string]types.AuthConfig{
expectedAuths := map[string]registry.AuthConfig{
"registry.example.com": registryAuth,
"localhost:8000": localAuth,
"example.com": localAuth,

View file

@ -9,7 +9,6 @@ import (
"github.com/docker/distribution/reference"
"github.com/docker/distribution/registry/client/transport"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@ -17,7 +16,7 @@ import (
)
func spawnTestRegistrySession(t *testing.T) *session {
authConfig := &types.AuthConfig{}
authConfig := &registry.AuthConfig{}
endpoint, err := newV1Endpoint(makeIndex("/v1/"), "", nil)
if err != nil {
t.Fatal(err)

View file

@ -10,7 +10,6 @@ import (
"github.com/docker/distribution/reference"
"github.com/docker/distribution/registry/client/auth"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs"
"github.com/sirupsen/logrus"
@ -18,11 +17,11 @@ import (
// Service is the interface defining what a registry service should implement.
type Service interface {
Auth(ctx context.Context, authConfig *types.AuthConfig, userAgent string) (status, token string, err error)
Auth(ctx context.Context, authConfig *registry.AuthConfig, userAgent string) (status, token string, err error)
LookupPullEndpoints(hostname string) (endpoints []APIEndpoint, err error)
LookupPushEndpoints(hostname string) (endpoints []APIEndpoint, err error)
ResolveRepository(name reference.Named) (*RepositoryInfo, error)
Search(ctx context.Context, term string, limit int, authConfig *types.AuthConfig, userAgent string, headers map[string][]string) (*registry.SearchResults, error)
Search(ctx context.Context, term string, limit int, authConfig *registry.AuthConfig, userAgent string, headers map[string][]string) (*registry.SearchResults, error)
ServiceConfig() *registry.ServiceConfig
LoadAllowNondistributableArtifacts([]string) error
LoadMirrors([]string) error
@ -78,7 +77,7 @@ func (s *defaultService) LoadInsecureRegistries(registries []string) error {
// Auth contacts the public registry with the provided credentials,
// and returns OK if authentication was successful.
// It can be used to verify the validity of a client's credentials.
func (s *defaultService) Auth(ctx context.Context, authConfig *types.AuthConfig, userAgent string) (status, token string, err error) {
func (s *defaultService) Auth(ctx context.Context, authConfig *registry.AuthConfig, userAgent string) (status, token string, err error) {
// TODO Use ctx when searching for repositories
var registryHostName = IndexHostname
@ -131,7 +130,7 @@ func splitReposSearchTerm(reposName string) (string, string) {
// Search queries the public registry for images matching the specified
// search terms, and returns the results.
func (s *defaultService) Search(ctx context.Context, term string, limit int, authConfig *types.AuthConfig, userAgent string, headers map[string][]string) (*registry.SearchResults, error) {
func (s *defaultService) Search(ctx context.Context, term string, limit int, authConfig *registry.AuthConfig, userAgent string, headers map[string][]string) (*registry.SearchResults, error) {
// TODO Use ctx when searching for repositories
if hasScheme(term) {
return nil, invalidParamf("invalid repository name: repository name (%s) should not have a scheme", term)

View file

@ -11,7 +11,6 @@ import (
"strings"
"sync"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/ioutils"
@ -30,7 +29,7 @@ type session struct {
type authTransport struct {
http.RoundTripper
*types.AuthConfig
*registry.AuthConfig
alwaysSetBasicAuth bool
token []string
@ -52,7 +51,7 @@ type authTransport struct {
// If the server sends a token without the client having requested it, it is ignored.
//
// This RoundTripper also has a CancelRequest method important for correct timeout handling.
func newAuthTransport(base http.RoundTripper, authConfig *types.AuthConfig, alwaysSetBasicAuth bool) *authTransport {
func newAuthTransport(base http.RoundTripper, authConfig *registry.AuthConfig, alwaysSetBasicAuth bool) *authTransport {
if base == nil {
base = http.DefaultTransport
}
@ -147,7 +146,7 @@ func (tr *authTransport) CancelRequest(req *http.Request) {
}
}
func authorizeClient(client *http.Client, authConfig *types.AuthConfig, endpoint *v1Endpoint) error {
func authorizeClient(client *http.Client, authConfig *registry.AuthConfig, endpoint *v1Endpoint) error {
var alwaysSetBasicAuth bool
// If we're working with a standalone private registry over HTTPS, send Basic Auth headers

View file

@ -10,9 +10,10 @@ import (
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/plugin"
"github.com/docker/docker/registry"
registrypkg "github.com/docker/docker/registry"
"github.com/pkg/errors"
)
@ -26,7 +27,7 @@ type CreateOpt func(*Config)
type Config struct {
*types.PluginConfig
binPath string
RegistryConfig registry.ServiceOptions
RegistryConfig registrypkg.ServiceOptions
}
// WithInsecureRegistry specifies that the given registry can skip host-key checking as well as fall back to plain http
@ -77,7 +78,7 @@ func Create(ctx context.Context, c CreateClient, name string, opts ...CreateOpt)
// This can be useful when testing plugins on swarm where you don't really want
// the plugin to exist on any of the daemons (immediately) and there needs to be
// some way to distribute the plugin.
func CreateInRegistry(ctx context.Context, repo string, auth *types.AuthConfig, opts ...CreateOpt) error {
func CreateInRegistry(ctx context.Context, repo string, auth *registry.AuthConfig, opts ...CreateOpt) error {
tmpDir, err := os.MkdirTemp("", "create-test-plugin-local")
if err != nil {
return err
@ -105,7 +106,7 @@ func CreateInRegistry(ctx context.Context, repo string, auth *types.AuthConfig,
return nil, nil
}
regService, err := registry.NewService(cfg.RegistryConfig)
regService, err := registrypkg.NewService(cfg.RegistryConfig)
if err != nil {
return err
}
@ -130,7 +131,7 @@ func CreateInRegistry(ctx context.Context, repo string, auth *types.AuthConfig,
}
if auth == nil {
auth = &types.AuthConfig{}
auth = &registry.AuthConfig{}
}
err = manager.Push(ctx, repo, nil, auth, io.Discard)
return errors.Wrap(err, "error pushing plugin")