Remove the use of dockerversion from the registry package

Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
Daniel Nephin 2016-01-04 13:36:01 -05:00
parent 012a3b6e74
commit 61a49bb6ba
13 changed files with 63 additions and 53 deletions

View File

@ -21,6 +21,7 @@ import (
"github.com/docker/distribution/registry/client/transport" "github.com/docker/distribution/registry/client/transport"
"github.com/docker/docker/cliconfig" "github.com/docker/docker/cliconfig"
"github.com/docker/docker/distribution" "github.com/docker/docker/distribution"
"github.com/docker/docker/dockerversion"
"github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/pkg/jsonmessage"
flag "github.com/docker/docker/pkg/mflag" flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/reference" "github.com/docker/docker/reference"
@ -139,7 +140,7 @@ func (cli *DockerCli) getNotaryRepository(repoInfo *registry.RepositoryInfo, aut
} }
// Skip configuration headers since request is not going to Docker daemon // Skip configuration headers since request is not going to Docker daemon
modifiers := registry.DockerHeaders(http.Header{}) modifiers := registry.DockerHeaders(dockerversion.DockerUserAgent(), http.Header{})
authTransport := transport.NewTransport(base, modifiers...) authTransport := transport.NewTransport(base, modifiers...)
pingClient := &http.Client{ pingClient := &http.Client{
Transport: authTransport, Transport: authTransport,

View File

@ -40,6 +40,7 @@ import (
"github.com/docker/docker/distribution" "github.com/docker/docker/distribution"
dmetadata "github.com/docker/docker/distribution/metadata" dmetadata "github.com/docker/docker/distribution/metadata"
"github.com/docker/docker/distribution/xfer" "github.com/docker/docker/distribution/xfer"
"github.com/docker/docker/dockerversion"
derr "github.com/docker/docker/errors" derr "github.com/docker/docker/errors"
"github.com/docker/docker/image" "github.com/docker/docker/image"
"github.com/docker/docker/image/tarexport" "github.com/docker/docker/image/tarexport"
@ -1452,7 +1453,7 @@ func configureVolumes(config *Config, rootUID, rootGID int) (*store.VolumeStore,
// AuthenticateToRegistry checks the validity of credentials in authConfig // AuthenticateToRegistry checks the validity of credentials in authConfig
func (daemon *Daemon) AuthenticateToRegistry(authConfig *types.AuthConfig) (string, error) { func (daemon *Daemon) AuthenticateToRegistry(authConfig *types.AuthConfig) (string, error) {
return daemon.RegistryService.Auth(authConfig) return daemon.RegistryService.Auth(authConfig, dockerversion.DockerUserAgent())
} }
// SearchRegistryForImages queries the registry for images matching // SearchRegistryForImages queries the registry for images matching
@ -1460,7 +1461,7 @@ func (daemon *Daemon) AuthenticateToRegistry(authConfig *types.AuthConfig) (stri
func (daemon *Daemon) SearchRegistryForImages(term string, func (daemon *Daemon) SearchRegistryForImages(term string,
authConfig *types.AuthConfig, authConfig *types.AuthConfig,
headers map[string][]string) (*registrytypes.SearchResults, error) { headers map[string][]string) (*registrytypes.SearchResults, error) {
return daemon.RegistryService.Search(term, authConfig, headers) return daemon.RegistryService.Search(term, authConfig, dockerversion.DockerUserAgent(), headers)
} }
// IsShuttingDown tells whether the daemon is shutting down or not // IsShuttingDown tells whether the daemon is shutting down or not

View File

@ -20,7 +20,6 @@ import (
// ImagePullConfig stores pull configuration. // ImagePullConfig stores pull configuration.
type ImagePullConfig struct { type ImagePullConfig struct {
// MetaHeaders stores HTTP headers with metadata about the image // MetaHeaders stores HTTP headers with metadata about the image
// (DockerHeaders with prefix X-Meta- in the request).
MetaHeaders map[string][]string MetaHeaders map[string][]string
// AuthConfig holds authentication credentials for authenticating with // AuthConfig holds authentication credentials for authenticating with
// the registry. // the registry.

View File

@ -14,6 +14,7 @@ import (
"github.com/docker/distribution/registry/client/transport" "github.com/docker/distribution/registry/client/transport"
"github.com/docker/docker/distribution/metadata" "github.com/docker/docker/distribution/metadata"
"github.com/docker/docker/distribution/xfer" "github.com/docker/docker/distribution/xfer"
"github.com/docker/docker/dockerversion"
"github.com/docker/docker/image" "github.com/docker/docker/image"
"github.com/docker/docker/image/v1" "github.com/docker/docker/image/v1"
"github.com/docker/docker/layer" "github.com/docker/docker/layer"
@ -47,10 +48,10 @@ func (p *v1Puller) Pull(ctx context.Context, ref reference.Named) error {
tr := transport.NewTransport( tr := transport.NewTransport(
// TODO(tiborvass): was ReceiveTimeout // TODO(tiborvass): was ReceiveTimeout
registry.NewTransport(tlsConfig), registry.NewTransport(tlsConfig),
registry.DockerHeaders(p.config.MetaHeaders)..., registry.DockerHeaders(dockerversion.DockerUserAgent(), p.config.MetaHeaders)...,
) )
client := registry.HTTPClient(tr) client := registry.HTTPClient(tr)
v1Endpoint, err := p.endpoint.ToV1Endpoint(p.config.MetaHeaders) v1Endpoint, err := p.endpoint.ToV1Endpoint(dockerversion.DockerUserAgent(), p.config.MetaHeaders)
if err != nil { if err != nil {
logrus.Debugf("Could not get v1 endpoint: %v", err) logrus.Debugf("Could not get v1 endpoint: %v", err)
return fallbackError{err: err} return fallbackError{err: err}

View File

@ -22,7 +22,6 @@ import (
// ImagePushConfig stores push configuration. // ImagePushConfig stores push configuration.
type ImagePushConfig struct { type ImagePushConfig struct {
// MetaHeaders store HTTP headers with metadata about the image // MetaHeaders store HTTP headers with metadata about the image
// (DockerHeaders with prefix X-Meta- in the request).
MetaHeaders map[string][]string MetaHeaders map[string][]string
// AuthConfig holds authentication credentials for authenticating with // AuthConfig holds authentication credentials for authenticating with
// the registry. // the registry.

View File

@ -8,6 +8,7 @@ import (
"github.com/docker/distribution/digest" "github.com/docker/distribution/digest"
"github.com/docker/distribution/registry/client/transport" "github.com/docker/distribution/registry/client/transport"
"github.com/docker/docker/distribution/metadata" "github.com/docker/docker/distribution/metadata"
"github.com/docker/docker/dockerversion"
"github.com/docker/docker/image" "github.com/docker/docker/image"
"github.com/docker/docker/image/v1" "github.com/docker/docker/image/v1"
"github.com/docker/docker/layer" "github.com/docker/docker/layer"
@ -38,10 +39,10 @@ func (p *v1Pusher) Push(ctx context.Context) error {
tr := transport.NewTransport( tr := transport.NewTransport(
// TODO(tiborvass): was NoTimeout // TODO(tiborvass): was NoTimeout
registry.NewTransport(tlsConfig), registry.NewTransport(tlsConfig),
registry.DockerHeaders(p.config.MetaHeaders)..., registry.DockerHeaders(dockerversion.DockerUserAgent(), p.config.MetaHeaders)...,
) )
client := registry.HTTPClient(tr) client := registry.HTTPClient(tr)
v1Endpoint, err := p.endpoint.ToV1Endpoint(p.config.MetaHeaders) v1Endpoint, err := p.endpoint.ToV1Endpoint(dockerversion.DockerUserAgent(), p.config.MetaHeaders)
if err != nil { if err != nil {
logrus.Debugf("Could not get v1 endpoint: %v", err) logrus.Debugf("Could not get v1 endpoint: %v", err)
return fallbackError{err: err} return fallbackError{err: err}

View File

@ -14,6 +14,7 @@ import (
"github.com/docker/distribution/registry/client/auth" "github.com/docker/distribution/registry/client/auth"
"github.com/docker/distribution/registry/client/transport" "github.com/docker/distribution/registry/client/transport"
"github.com/docker/docker/distribution/xfer" "github.com/docker/docker/distribution/xfer"
"github.com/docker/docker/dockerversion"
"github.com/docker/docker/registry" "github.com/docker/docker/registry"
"github.com/docker/engine-api/types" "github.com/docker/engine-api/types"
"golang.org/x/net/context" "golang.org/x/net/context"
@ -67,7 +68,7 @@ func NewV2Repository(ctx context.Context, repoInfo *registry.RepositoryInfo, end
DisableKeepAlives: true, DisableKeepAlives: true,
} }
modifiers := registry.DockerHeaders(metaHeaders) modifiers := registry.DockerHeaders(dockerversion.DockerUserAgent(), metaHeaders)
authTransport := transport.NewTransport(base, modifiers...) authTransport := transport.NewTransport(base, modifiers...)
pingClient := &http.Client{ pingClient := &http.Client{
Transport: authTransport, Transport: authTransport,

View File

@ -0,0 +1,24 @@
package dockerversion
import (
"runtime"
"github.com/docker/docker/pkg/parsers/kernel"
"github.com/docker/docker/pkg/useragent"
)
// DockerUserAgent is the User-Agent the Docker client uses to identify itself.
// It is populated from version information of different components.
func DockerUserAgent() string {
httpVersion := make([]useragent.VersionInfo, 0, 6)
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "docker", Version: Version})
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "go", Version: runtime.Version()})
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "git-commit", Version: GitCommit})
if kernelVersion, err := kernel.GetKernelVersion(); err == nil {
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "kernel", Version: kernelVersion.String()})
}
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "os", Version: runtime.GOOS})
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "arch", Version: runtime.GOARCH})
return useragent.AppendVersions("", httpVersion...)
}

View File

@ -45,12 +45,12 @@ func scanForAPIVersion(address string) (string, APIVersion) {
// NewEndpoint parses the given address to return a registry endpoint. v can be used to // NewEndpoint parses the given address to return a registry endpoint. v can be used to
// specify a specific endpoint version // specify a specific endpoint version
func NewEndpoint(index *registrytypes.IndexInfo, metaHeaders http.Header, v APIVersion) (*Endpoint, error) { func NewEndpoint(index *registrytypes.IndexInfo, userAgent string, metaHeaders http.Header, v APIVersion) (*Endpoint, error) {
tlsConfig, err := newTLSConfig(index.Name, index.Secure) tlsConfig, err := newTLSConfig(index.Name, index.Secure)
if err != nil { if err != nil {
return nil, err return nil, err
} }
endpoint, err := newEndpoint(GetAuthConfigKey(index), tlsConfig, metaHeaders) endpoint, err := newEndpoint(GetAuthConfigKey(index), tlsConfig, userAgent, metaHeaders)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -91,7 +91,7 @@ func validateEndpoint(endpoint *Endpoint) error {
return nil return nil
} }
func newEndpoint(address string, tlsConfig *tls.Config, metaHeaders http.Header) (*Endpoint, error) { func newEndpoint(address string, tlsConfig *tls.Config, userAgent string, metaHeaders http.Header) (*Endpoint, error) {
var ( var (
endpoint = new(Endpoint) endpoint = new(Endpoint)
trimmedAddress string trimmedAddress string
@ -112,7 +112,7 @@ func newEndpoint(address string, tlsConfig *tls.Config, metaHeaders http.Header)
// TODO(tiborvass): make sure a ConnectTimeout transport is used // TODO(tiborvass): make sure a ConnectTimeout transport is used
tr := NewTransport(tlsConfig) tr := NewTransport(tlsConfig)
endpoint.client = HTTPClient(transport.NewTransport(tr, DockerHeaders(metaHeaders)...)) endpoint.client = HTTPClient(transport.NewTransport(tr, DockerHeaders(userAgent, metaHeaders)...))
return endpoint, nil return endpoint, nil
} }

View File

@ -19,7 +19,7 @@ func TestEndpointParse(t *testing.T) {
{"0.0.0.0:5000", "https://0.0.0.0:5000/v0/"}, {"0.0.0.0:5000", "https://0.0.0.0:5000/v0/"},
} }
for _, td := range testData { for _, td := range testData {
e, err := newEndpoint(td.str, nil, nil) e, err := newEndpoint(td.str, nil, "", nil)
if err != nil { if err != nil {
t.Errorf("%q: %s", td.str, err) t.Errorf("%q: %s", td.str, err)
} }

View File

@ -21,9 +21,6 @@ import (
"github.com/docker/distribution/registry/api/v2" "github.com/docker/distribution/registry/api/v2"
"github.com/docker/distribution/registry/client" "github.com/docker/distribution/registry/client"
"github.com/docker/distribution/registry/client/transport" "github.com/docker/distribution/registry/client/transport"
"github.com/docker/docker/dockerversion"
"github.com/docker/docker/pkg/parsers/kernel"
"github.com/docker/docker/pkg/useragent"
"github.com/docker/go-connections/tlsconfig" "github.com/docker/go-connections/tlsconfig"
) )
@ -34,23 +31,7 @@ var (
errLoginRequired = errors.New("Authentication is required.") errLoginRequired = errors.New("Authentication is required.")
) )
// dockerUserAgent is the User-Agent the Docker client uses to identify itself.
// It is populated on init(), comprising version information of different components.
var dockerUserAgent string
func init() { func init() {
httpVersion := make([]useragent.VersionInfo, 0, 6)
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "docker", Version: dockerversion.Version})
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "go", Version: runtime.Version()})
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "git-commit", Version: dockerversion.GitCommit})
if kernelVersion, err := kernel.GetKernelVersion(); err == nil {
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "kernel", Version: kernelVersion.String()})
}
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "os", Version: runtime.GOOS})
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "arch", Version: runtime.GOARCH})
dockerUserAgent = useragent.AppendVersions("", httpVersion...)
if runtime.GOOS != "linux" { if runtime.GOOS != "linux" {
V2Only = true V2Only = true
} }
@ -130,12 +111,13 @@ func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error {
return nil return nil
} }
// DockerHeaders returns request modifiers that ensure requests have // DockerHeaders returns request modifiers with a User-Agent and metaHeaders
// the User-Agent header set to dockerUserAgent and that metaHeaders func DockerHeaders(userAgent string, metaHeaders http.Header) []transport.RequestModifier {
// are added. modifiers := []transport.RequestModifier{}
func DockerHeaders(metaHeaders http.Header) []transport.RequestModifier { if userAgent != "" {
modifiers := []transport.RequestModifier{ modifiers = append(modifiers, transport.NewHeaderRequestModifier(http.Header{
transport.NewHeaderRequestModifier(http.Header{"User-Agent": []string{dockerUserAgent}}), "User-Agent": []string{userAgent},
}))
} }
if metaHeaders != nil { if metaHeaders != nil {
modifiers = append(modifiers, transport.NewHeaderRequestModifier(metaHeaders)) modifiers = append(modifiers, transport.NewHeaderRequestModifier(metaHeaders))

View File

@ -25,12 +25,13 @@ const (
func spawnTestRegistrySession(t *testing.T) *Session { func spawnTestRegistrySession(t *testing.T) *Session {
authConfig := &types.AuthConfig{} authConfig := &types.AuthConfig{}
endpoint, err := NewEndpoint(makeIndex("/v1/"), nil, APIVersionUnknown) endpoint, err := NewEndpoint(makeIndex("/v1/"), "", nil, APIVersionUnknown)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
userAgent := "docker test client"
var tr http.RoundTripper = debugTransport{NewTransport(nil), t.Log} var tr http.RoundTripper = debugTransport{NewTransport(nil), t.Log}
tr = transport.NewTransport(AuthTransport(tr, authConfig, false), DockerHeaders(nil)...) tr = transport.NewTransport(AuthTransport(tr, authConfig, false), DockerHeaders(userAgent, nil)...)
client := HTTPClient(tr) client := HTTPClient(tr)
r, err := NewSession(client, authConfig, endpoint) r, err := NewSession(client, authConfig, endpoint)
if err != nil { if err != nil {
@ -52,7 +53,7 @@ func spawnTestRegistrySession(t *testing.T) *Session {
func TestPingRegistryEndpoint(t *testing.T) { func TestPingRegistryEndpoint(t *testing.T) {
testPing := func(index *registrytypes.IndexInfo, expectedStandalone bool, assertMessage string) { testPing := func(index *registrytypes.IndexInfo, expectedStandalone bool, assertMessage string) {
ep, err := NewEndpoint(index, nil, APIVersionUnknown) ep, err := NewEndpoint(index, "", nil, APIVersionUnknown)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -72,7 +73,7 @@ func TestPingRegistryEndpoint(t *testing.T) {
func TestEndpoint(t *testing.T) { func TestEndpoint(t *testing.T) {
// Simple wrapper to fail test if err != nil // Simple wrapper to fail test if err != nil
expandEndpoint := func(index *registrytypes.IndexInfo) *Endpoint { expandEndpoint := func(index *registrytypes.IndexInfo) *Endpoint {
endpoint, err := NewEndpoint(index, nil, APIVersionUnknown) endpoint, err := NewEndpoint(index, "", nil, APIVersionUnknown)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -81,7 +82,7 @@ func TestEndpoint(t *testing.T) {
assertInsecureIndex := func(index *registrytypes.IndexInfo) { assertInsecureIndex := func(index *registrytypes.IndexInfo) {
index.Secure = true index.Secure = true
_, err := NewEndpoint(index, nil, APIVersionUnknown) _, err := NewEndpoint(index, "", nil, APIVersionUnknown)
assertNotEqual(t, err, nil, index.Name+": Expected error for insecure index") assertNotEqual(t, err, nil, index.Name+": Expected error for insecure index")
assertEqual(t, strings.Contains(err.Error(), "insecure-registry"), true, index.Name+": Expected insecure-registry error for insecure index") assertEqual(t, strings.Contains(err.Error(), "insecure-registry"), true, index.Name+": Expected insecure-registry error for insecure index")
index.Secure = false index.Secure = false
@ -89,7 +90,7 @@ func TestEndpoint(t *testing.T) {
assertSecureIndex := func(index *registrytypes.IndexInfo) { assertSecureIndex := func(index *registrytypes.IndexInfo) {
index.Secure = true index.Secure = true
_, err := NewEndpoint(index, nil, APIVersionUnknown) _, err := NewEndpoint(index, "", nil, APIVersionUnknown)
assertNotEqual(t, err, nil, index.Name+": Expected cert error for secure index") assertNotEqual(t, err, nil, index.Name+": Expected cert error for secure index")
assertEqual(t, strings.Contains(err.Error(), "certificate signed by unknown authority"), true, index.Name+": Expected cert error for secure index") assertEqual(t, strings.Contains(err.Error(), "certificate signed by unknown authority"), true, index.Name+": Expected cert error for secure index")
index.Secure = false index.Secure = false
@ -155,7 +156,7 @@ func TestEndpoint(t *testing.T) {
} }
for _, address := range badEndpoints { for _, address := range badEndpoints {
index.Name = address index.Name = address
_, err := NewEndpoint(index, nil, APIVersionUnknown) _, err := NewEndpoint(index, "", nil, APIVersionUnknown)
checkNotEqual(t, err, nil, "Expected error while expanding bad endpoint") checkNotEqual(t, err, nil, "Expected error while expanding bad endpoint")
} }
} }

View File

@ -28,7 +28,7 @@ func NewService(options *Options) *Service {
// Auth contacts the public registry with the provided credentials, // Auth contacts the public registry with the provided credentials,
// and returns OK if authentication was successful. // and returns OK if authentication was successful.
// It can be used to verify the validity of a client's credentials. // It can be used to verify the validity of a client's credentials.
func (s *Service) Auth(authConfig *types.AuthConfig) (string, error) { func (s *Service) Auth(authConfig *types.AuthConfig, userAgent string) (string, error) {
addr := authConfig.ServerAddress addr := authConfig.ServerAddress
if addr == "" { if addr == "" {
// Use the official registry address if not specified. // Use the official registry address if not specified.
@ -45,7 +45,7 @@ func (s *Service) Auth(authConfig *types.AuthConfig) (string, error) {
endpointVersion = APIVersion2 endpointVersion = APIVersion2
} }
endpoint, err := NewEndpoint(index, nil, endpointVersion) endpoint, err := NewEndpoint(index, userAgent, nil, endpointVersion)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -72,7 +72,7 @@ func splitReposSearchTerm(reposName string) (string, string) {
// Search queries the public registry for images matching the specified // Search queries the public registry for images matching the specified
// search terms, and returns the results. // search terms, and returns the results.
func (s *Service) Search(term string, authConfig *types.AuthConfig, headers map[string][]string) (*registrytypes.SearchResults, error) { func (s *Service) Search(term string, authConfig *types.AuthConfig, userAgent string, headers map[string][]string) (*registrytypes.SearchResults, error) {
if err := validateNoSchema(term); err != nil { if err := validateNoSchema(term); err != nil {
return nil, err return nil, err
} }
@ -85,7 +85,7 @@ func (s *Service) Search(term string, authConfig *types.AuthConfig, headers map[
} }
// *TODO: Search multiple indexes. // *TODO: Search multiple indexes.
endpoint, err := NewEndpoint(index, http.Header(headers), APIVersionUnknown) endpoint, err := NewEndpoint(index, userAgent, http.Header(headers), APIVersionUnknown)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -129,8 +129,8 @@ type APIEndpoint struct {
} }
// ToV1Endpoint returns a V1 API endpoint based on the APIEndpoint // ToV1Endpoint returns a V1 API endpoint based on the APIEndpoint
func (e APIEndpoint) ToV1Endpoint(metaHeaders http.Header) (*Endpoint, error) { func (e APIEndpoint) ToV1Endpoint(userAgent string, metaHeaders http.Header) (*Endpoint, error) {
return newEndpoint(e.URL, e.TLSConfig, metaHeaders) return newEndpoint(e.URL, e.TLSConfig, userAgent, metaHeaders)
} }
// TLSConfig constructs a client TLS configuration based on server defaults // TLSConfig constructs a client TLS configuration based on server defaults