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:
commit
e60bddcc60
66 changed files with 462 additions and 345 deletions
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 == "" {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
99
api/types/registry/authconfig.go
Normal file
99
api/types/registry/authconfig.go
Normal 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 }
|
59
api/types/registry/authconfig_test.go
Normal file
59
api/types/registry/authconfig_test.go
Normal 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)
|
||||
}
|
|
@ -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},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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=",
|
||||
},
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 != "" {
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 := ®istry.AuthConfig{}
|
||||
if encodedAuthConfig != "" {
|
||||
if err := json.NewDecoder(base64.NewDecoder(base64.URLEncoding, strings.NewReader(encodedAuthConfig))).Decode(authConfig); err != nil {
|
||||
logrus.Warnf("invalid authconfig: %v", err)
|
||||
|
|
|
@ -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 := ®istry.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 := ®istry.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
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 := ®istry.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
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 ®istrytypes.SearchResults{
|
||||
return ®istry.SearchResults{
|
||||
Query: unfilteredResult.Query,
|
||||
NumResults: len(filteredResults),
|
||||
Results: filteredResults,
|
||||
|
|
|
@ -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 ®istrytypes.SearchResults{
|
||||
return ®istry.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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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: ®istrytypes.AuthConfig{
|
||||
RegistryToken: secretRegistryToken,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -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 = ®istry.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: ®istry.RepositoryInfo{
|
||||
repoInfo: ®istrypkg.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,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 := ®istry.RepositoryInfo{
|
||||
repoInfo := ®istrypkg.RepositoryInfo{
|
||||
Name: n,
|
||||
Index: ®istrytypes.IndexInfo{
|
||||
Index: ®istry.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: ®istry.AuthConfig{
|
||||
RegistryToken: secretRegistryToken,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -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 := ®istrytypes.AuthConfig{ServerAddress: registry.DefaultURL, Username: "testuser", Password: "testpassword"}
|
||||
assert.NilError(t, plugin.CreateInRegistry(ctx, repo, auth))
|
||||
|
||||
authEncoded, err := json.Marshal(auth)
|
||||
|
|
|
@ -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)))
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 := ®istry.AuthConfig{}
|
||||
endpoint, err := newV1Endpoint(makeIndex("/v1/"), "", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = ®istry.AuthConfig{}
|
||||
}
|
||||
err = manager.Push(ctx, repo, nil, auth, io.Discard)
|
||||
return errors.Wrap(err, "error pushing plugin")
|
||||
|
|
Loading…
Reference in a new issue