Bläddra i källkod

Move registry service options to the daemon configuration.

Allowing to set their values in the daemon configuration file.

Signed-off-by: David Calavera <david.calavera@gmail.com>
David Calavera 9 år sedan
förälder
incheckning
59586d02b1

+ 4 - 0
daemon/config.go

@@ -13,6 +13,7 @@ import (
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/pkg/discovery"
 	flag "github.com/docker/docker/pkg/mflag"
+	"github.com/docker/docker/registry"
 	"github.com/imdario/mergo"
 )
 
@@ -96,6 +97,7 @@ type CommonConfig struct {
 	CommonTLSOptions
 	LogConfig
 	bridgeConfig // bridgeConfig holds bridge network specific configuration.
+	registry.ServiceOptions
 
 	reloadLock sync.Mutex
 	valuesSet  map[string]interface{}
@@ -106,6 +108,8 @@ type CommonConfig struct {
 // Subsequent calls to `flag.Parse` will populate config with values parsed
 // from the command-line.
 func (config *Config) InstallCommonFlags(cmd *flag.FlagSet, usageFn func(string) string) {
+	config.ServiceOptions.InstallCliFlags(cmd, usageFn)
+
 	cmd.Var(opts.NewNamedListOptsRef("storage-opts", &config.GraphOptions, nil), []string{"-storage-opt"}, usageFn("Set storage driver options"))
 	cmd.Var(opts.NewNamedListOptsRef("authorization-plugins", &config.AuthorizationPlugins, nil), []string{"-authorization-plugin"}, usageFn("List authorization plugins in order from first evaluator to last"))
 	cmd.Var(opts.NewNamedListOptsRef("exec-opts", &config.ExecOptions, nil), []string{"-exec-opt"}, usageFn("Set exec driver options"))

+ 1 - 1
daemon/info.go

@@ -90,7 +90,7 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) {
 		IndexServerAddress: registry.IndexServer,
 		OSType:             platform.OSType,
 		Architecture:       platform.Architecture,
-		RegistryConfig:     daemon.RegistryService.Config,
+		RegistryConfig:     daemon.RegistryService.ServiceConfig(),
 		NCPU:               runtime.NumCPU(),
 		MemTotal:           meminfo.MemTotal,
 		DockerRootDir:      daemon.configStore.Root,

+ 9 - 9
docker/daemon.go

@@ -8,6 +8,7 @@ import (
 	"io"
 	"os"
 	"path/filepath"
+	"runtime"
 	"strings"
 	"time"
 
@@ -51,8 +52,7 @@ var (
 // DaemonCli represents the daemon CLI.
 type DaemonCli struct {
 	*daemon.Config
-	registryOptions *registry.Options
-	flags           *flag.FlagSet
+	flags *flag.FlagSet
 }
 
 func presentInHelp(usage string) string { return usage }
@@ -67,17 +67,17 @@ func NewDaemonCli() *DaemonCli {
 	daemonConfig.LogConfig.Config = make(map[string]string)
 	daemonConfig.ClusterOpts = make(map[string]string)
 
+	if runtime.GOOS != "linux" {
+		daemonConfig.V2Only = true
+	}
+
 	daemonConfig.InstallFlags(daemonFlags, presentInHelp)
 	daemonConfig.InstallFlags(flag.CommandLine, absentFromHelp)
-	registryOptions := new(registry.Options)
-	registryOptions.InstallFlags(daemonFlags, presentInHelp)
-	registryOptions.InstallFlags(flag.CommandLine, absentFromHelp)
 	daemonFlags.Require(flag.Exact, 0)
 
 	return &DaemonCli{
-		Config:          daemonConfig,
-		registryOptions: registryOptions,
-		flags:           daemonFlags,
+		Config: daemonConfig,
+		flags:  daemonFlags,
 	}
 }
 
@@ -263,7 +263,7 @@ func (cli *DaemonCli) CmdDaemon(args ...string) error {
 	}
 	cli.TrustKeyPath = commonFlags.TrustKey
 
-	registryService := registry.NewService(cli.registryOptions)
+	registryService := registry.NewService(cli.Config.ServiceOptions)
 	d, err := daemon.NewDaemon(cli.Config, registryService)
 	if err != nil {
 		if pfile != nil {

+ 53 - 6
docker/daemon_test.go

@@ -4,6 +4,7 @@ package main
 
 import (
 	"io/ioutil"
+	"os"
 	"strings"
 	"testing"
 
@@ -63,8 +64,9 @@ func TestLoadDaemonCliConfigWithConflicts(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-
 	configFile := f.Name()
+	defer os.Remove(configFile)
+
 	f.Write([]byte(`{"labels": ["l3=foo"]}`))
 	f.Close()
 
@@ -103,8 +105,9 @@ func TestLoadDaemonCliConfigWithTLSVerify(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-
 	configFile := f.Name()
+	defer os.Remove(configFile)
+
 	f.Write([]byte(`{"tlsverify": true}`))
 	f.Close()
 
@@ -135,8 +138,9 @@ func TestLoadDaemonCliConfigWithExplicitTLSVerifyFalse(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-
 	configFile := f.Name()
+	defer os.Remove(configFile)
+
 	f.Write([]byte(`{"tlsverify": false}`))
 	f.Close()
 
@@ -167,8 +171,9 @@ func TestLoadDaemonCliConfigWithoutTLSVerify(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-
 	configFile := f.Name()
+	defer os.Remove(configFile)
+
 	f.Write([]byte(`{}`))
 	f.Close()
 
@@ -194,8 +199,9 @@ func TestLoadDaemonCliConfigWithLogLevel(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-
 	configFile := f.Name()
+	defer os.Remove(configFile)
+
 	f.Write([]byte(`{"log-level": "warn"}`))
 	f.Close()
 
@@ -220,6 +226,7 @@ func TestLoadDaemonCliConfigWithLogLevel(t *testing.T) {
 func TestLoadDaemonConfigWithEmbeddedOptions(t *testing.T) {
 	c := &daemon.Config{}
 	common := &cli.CommonFlags{}
+
 	flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
 	flags.String([]string{"-tlscacert"}, "", "")
 	flags.String([]string{"-log-driver"}, "", "")
@@ -228,8 +235,9 @@ func TestLoadDaemonConfigWithEmbeddedOptions(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-
 	configFile := f.Name()
+	defer os.Remove(configFile)
+
 	f.Write([]byte(`{"tlscacert": "/etc/certs/ca.pem", "log-driver": "syslog"}`))
 	f.Close()
 
@@ -247,3 +255,42 @@ func TestLoadDaemonConfigWithEmbeddedOptions(t *testing.T) {
 		t.Fatalf("expected LogConfig type syslog, got %v", loadedConfig.LogConfig.Type)
 	}
 }
+
+func TestLoadDaemonConfigWithRegistryOptions(t *testing.T) {
+	c := &daemon.Config{}
+	common := &cli.CommonFlags{}
+	flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
+	c.ServiceOptions.InstallCliFlags(flags, absentFromHelp)
+
+	f, err := ioutil.TempFile("", "docker-config-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	configFile := f.Name()
+	defer os.Remove(configFile)
+
+	f.Write([]byte(`{"registry-mirrors": ["https://mirrors.docker.com"], "insecure-registries": ["https://insecure.docker.com"], "disable-legacy-registry": true}`))
+	f.Close()
+
+	loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if loadedConfig == nil {
+		t.Fatal("expected configuration, got nil")
+	}
+
+	m := loadedConfig.Mirrors
+	if len(m) != 1 {
+		t.Fatalf("expected 1 mirror, got %d", len(m))
+	}
+
+	r := loadedConfig.InsecureRegistries
+	if len(r) != 1 {
+		t.Fatalf("expected 1 insecure registries, got %d", len(r))
+	}
+
+	if !loadedConfig.V2Only {
+		t.Fatal("expected disable-legacy-registry to be true, got false")
+	}
+}

+ 4 - 1
docs/reference/commandline/daemon.md

@@ -883,7 +883,10 @@ This is a full example of the allowed configuration options in the file:
 	"default-gateway": "",
 	"default-gateway-v6": "",
 	"icc": false,
-	"raw-logs": false
+	"raw-logs": false,
+	"registry-mirrors": [],
+	"insecure-registries": [],
+	"disable-legacy-registry": false
 }
 ```
 

+ 41 - 37
registry/config.go

@@ -13,10 +13,20 @@ import (
 	registrytypes "github.com/docker/engine-api/types/registry"
 )
 
-// Options holds command line options.
-type Options struct {
-	Mirrors            opts.ListOpts
-	InsecureRegistries opts.ListOpts
+// ServiceOptions holds command line options.
+type ServiceOptions struct {
+	Mirrors            []string `json:"registry-mirrors,omitempty"`
+	InsecureRegistries []string `json:"insecure-registries,omitempty"`
+
+	// V2Only controls access to legacy registries.  If it is set to true via the
+	// command line flag the daemon will not attempt to contact v1 legacy registries
+	V2Only bool `json:"disable-legacy-registry,omitempty"`
+}
+
+// serviceConfig holds daemon configuration for the registry service.
+type serviceConfig struct {
+	registrytypes.ServiceConfig
+	V2Only bool
 }
 
 var (
@@ -42,51 +52,45 @@ var (
 	// not have the correct form
 	ErrInvalidRepositoryName = errors.New("Invalid repository name (ex: \"registry.domain.tld/myrepos\")")
 
-	emptyServiceConfig = NewServiceConfig(nil)
-
-	// V2Only controls access to legacy registries.  If it is set to true via the
-	// command line flag the daemon will not attempt to contact v1 legacy registries
-	V2Only = false
+	emptyServiceConfig = newServiceConfig(ServiceOptions{})
 )
 
 // for mocking in unit tests
 var lookupIP = net.LookupIP
 
-// InstallFlags adds command-line options to the top-level flag parser for
+// InstallCliFlags adds command-line options to the top-level flag parser for
 // the current process.
-func (options *Options) InstallFlags(cmd *flag.FlagSet, usageFn func(string) string) {
-	options.Mirrors = opts.NewListOpts(ValidateMirror)
-	cmd.Var(&options.Mirrors, []string{"-registry-mirror"}, usageFn("Preferred Docker registry mirror"))
-	options.InsecureRegistries = opts.NewListOpts(ValidateIndexName)
-	cmd.Var(&options.InsecureRegistries, []string{"-insecure-registry"}, usageFn("Enable insecure registry communication"))
-	cmd.BoolVar(&V2Only, []string{"-disable-legacy-registry"}, false, usageFn("Do not contact legacy registries"))
-}
+func (options *ServiceOptions) InstallCliFlags(cmd *flag.FlagSet, usageFn func(string) string) {
+	mirrors := opts.NewNamedListOptsRef("registry-mirrors", &options.Mirrors, ValidateMirror)
+	cmd.Var(mirrors, []string{"-registry-mirror"}, usageFn("Preferred Docker registry mirror"))
 
-// NewServiceConfig returns a new instance of ServiceConfig
-func NewServiceConfig(options *Options) *registrytypes.ServiceConfig {
-	if options == nil {
-		options = &Options{
-			Mirrors:            opts.NewListOpts(nil),
-			InsecureRegistries: opts.NewListOpts(nil),
-		}
-	}
+	insecureRegistries := opts.NewNamedListOptsRef("insecure-registries", &options.InsecureRegistries, ValidateIndexName)
+	cmd.Var(insecureRegistries, []string{"-insecure-registry"}, usageFn("Enable insecure registry communication"))
+
+	cmd.BoolVar(&options.V2Only, []string{"-disable-legacy-registry"}, false, usageFn("Do not contact legacy registries"))
+}
 
+// newServiceConfig returns a new instance of ServiceConfig
+func newServiceConfig(options ServiceOptions) *serviceConfig {
 	// Localhost is by default considered as an insecure registry
 	// This is a stop-gap for people who are running a private registry on localhost (especially on Boot2docker).
 	//
 	// TODO: should we deprecate this once it is easier for people to set up a TLS registry or change
 	// daemon flags on boot2docker?
-	options.InsecureRegistries.Set("127.0.0.0/8")
-
-	config := &registrytypes.ServiceConfig{
-		InsecureRegistryCIDRs: make([]*registrytypes.NetIPNet, 0),
-		IndexConfigs:          make(map[string]*registrytypes.IndexInfo, 0),
-		// Hack: Bypass setting the mirrors to IndexConfigs since they are going away
-		// and Mirrors are only for the official registry anyways.
-		Mirrors: options.Mirrors.GetAll(),
+	options.InsecureRegistries = append(options.InsecureRegistries, "127.0.0.0/8")
+
+	config := &serviceConfig{
+		ServiceConfig: registrytypes.ServiceConfig{
+			InsecureRegistryCIDRs: make([]*registrytypes.NetIPNet, 0),
+			IndexConfigs:          make(map[string]*registrytypes.IndexInfo, 0),
+			// Hack: Bypass setting the mirrors to IndexConfigs since they are going away
+			// and Mirrors are only for the official registry anyways.
+			Mirrors: options.Mirrors,
+		},
+		V2Only: options.V2Only,
 	}
 	// Split --insecure-registry into CIDR and registry-specific settings.
-	for _, r := range options.InsecureRegistries.GetAll() {
+	for _, r := range options.InsecureRegistries {
 		// Check if CIDR was passed to --insecure-registry
 		_, ipnet, err := net.ParseCIDR(r)
 		if err == nil {
@@ -125,7 +129,7 @@ func NewServiceConfig(options *Options) *registrytypes.ServiceConfig {
 // or an IP address. If it is a domain name, then it will be resolved in order to check if the IP is contained
 // in a subnet. If the resolving is not successful, isSecureIndex will only try to match hostname to any element
 // of insecureRegistries.
-func isSecureIndex(config *registrytypes.ServiceConfig, indexName string) bool {
+func isSecureIndex(config *serviceConfig, indexName string) bool {
 	// Check for configured index, first.  This is needed in case isSecureIndex
 	// is called from anything besides newIndexInfo, in order to honor per-index configurations.
 	if index, ok := config.IndexConfigs[indexName]; ok {
@@ -201,7 +205,7 @@ func validateNoSchema(reposName string) error {
 }
 
 // newIndexInfo returns IndexInfo configuration from indexName
-func newIndexInfo(config *registrytypes.ServiceConfig, indexName string) (*registrytypes.IndexInfo, error) {
+func newIndexInfo(config *serviceConfig, indexName string) (*registrytypes.IndexInfo, error) {
 	var err error
 	indexName, err = ValidateIndexName(indexName)
 	if err != nil {
@@ -233,7 +237,7 @@ func GetAuthConfigKey(index *registrytypes.IndexInfo) string {
 }
 
 // newRepositoryInfo validates and breaks down a repository name into a RepositoryInfo
-func newRepositoryInfo(config *registrytypes.ServiceConfig, name reference.Named) (*RepositoryInfo, error) {
+func newRepositoryInfo(config *serviceConfig, name reference.Named) (*RepositoryInfo, error) {
 	index, err := newIndexInfo(config, name.Hostname())
 	if err != nil {
 		return nil, err

+ 0 - 7
registry/registry.go

@@ -11,7 +11,6 @@ import (
 	"net/http"
 	"os"
 	"path/filepath"
-	"runtime"
 	"strings"
 	"time"
 
@@ -26,12 +25,6 @@ var (
 	ErrAlreadyExists = errors.New("Image already exists")
 )
 
-func init() {
-	if runtime.GOOS != "linux" {
-		V2Only = true
-	}
-}
-
 func newTLSConfig(hostname string, isSecure bool) (*tls.Config, error) {
 	// PreferredServerCipherSuites should have no effect
 	tlsConfig := tlsconfig.ServerDefault

+ 5 - 16
registry/registry_mock_test.go

@@ -15,7 +15,6 @@ import (
 	"testing"
 	"time"
 
-	"github.com/docker/docker/opts"
 	"github.com/docker/docker/reference"
 	registrytypes "github.com/docker/engine-api/types/registry"
 	"github.com/gorilla/mux"
@@ -174,23 +173,13 @@ func makePublicIndex() *registrytypes.IndexInfo {
 	return index
 }
 
-func makeServiceConfig(mirrors []string, insecureRegistries []string) *registrytypes.ServiceConfig {
-	options := &Options{
-		Mirrors:            opts.NewListOpts(nil),
-		InsecureRegistries: opts.NewListOpts(nil),
-	}
-	if mirrors != nil {
-		for _, mirror := range mirrors {
-			options.Mirrors.Set(mirror)
-		}
-	}
-	if insecureRegistries != nil {
-		for _, insecureRegistries := range insecureRegistries {
-			options.InsecureRegistries.Set(insecureRegistries)
-		}
+func makeServiceConfig(mirrors []string, insecureRegistries []string) *serviceConfig {
+	options := ServiceOptions{
+		Mirrors:            mirrors,
+		InsecureRegistries: insecureRegistries,
 	}
 
-	return NewServiceConfig(options)
+	return newServiceConfig(options)
 }
 
 func writeHeaders(w http.ResponseWriter) {

+ 3 - 3
registry/registry_test.go

@@ -523,7 +523,7 @@ func TestParseRepositoryInfo(t *testing.T) {
 }
 
 func TestNewIndexInfo(t *testing.T) {
-	testIndexInfo := func(config *registrytypes.ServiceConfig, expectedIndexInfos map[string]*registrytypes.IndexInfo) {
+	testIndexInfo := func(config *serviceConfig, expectedIndexInfos map[string]*registrytypes.IndexInfo) {
 		for indexName, expectedIndexInfo := range expectedIndexInfos {
 			index, err := newIndexInfo(config, indexName)
 			if err != nil {
@@ -537,7 +537,7 @@ func TestNewIndexInfo(t *testing.T) {
 		}
 	}
 
-	config := NewServiceConfig(nil)
+	config := newServiceConfig(ServiceOptions{})
 	noMirrors := []string{}
 	expectedIndexInfos := map[string]*registrytypes.IndexInfo{
 		IndexName: {
@@ -661,7 +661,7 @@ func TestMirrorEndpointLookup(t *testing.T) {
 		}
 		return false
 	}
-	s := Service{Config: makeServiceConfig([]string{"my.mirror"}, nil)}
+	s := Service{config: makeServiceConfig([]string{"my.mirror"}, nil)}
 
 	imageName, err := reference.WithName(IndexName + "/test/image")
 	if err != nil {

+ 13 - 8
registry/service.go

@@ -15,17 +15,22 @@ import (
 // Service is a registry service. It tracks configuration data such as a list
 // of mirrors.
 type Service struct {
-	Config *registrytypes.ServiceConfig
+	config *serviceConfig
 }
 
 // NewService returns a new instance of Service ready to be
 // installed into an engine.
-func NewService(options *Options) *Service {
+func NewService(options ServiceOptions) *Service {
 	return &Service{
-		Config: NewServiceConfig(options),
+		config: newServiceConfig(options),
 	}
 }
 
+// ServiceConfig returns the public registry service configuration.
+func (s *Service) ServiceConfig() *registrytypes.ServiceConfig {
+	return &s.config.ServiceConfig
+}
+
 // 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.
@@ -82,7 +87,7 @@ func (s *Service) Search(term string, authConfig *types.AuthConfig, userAgent st
 
 	indexName, remoteName := splitReposSearchTerm(term)
 
-	index, err := newIndexInfo(s.Config, indexName)
+	index, err := newIndexInfo(s.config, indexName)
 	if err != nil {
 		return nil, err
 	}
@@ -113,12 +118,12 @@ func (s *Service) Search(term string, authConfig *types.AuthConfig, userAgent st
 // ResolveRepository splits a repository name into its components
 // and configuration of the associated registry.
 func (s *Service) ResolveRepository(name reference.Named) (*RepositoryInfo, error) {
-	return newRepositoryInfo(s.Config, name)
+	return newRepositoryInfo(s.config, name)
 }
 
 // ResolveIndex takes indexName and returns index info
 func (s *Service) ResolveIndex(name string) (*registrytypes.IndexInfo, error) {
-	return newIndexInfo(s.Config, name)
+	return newIndexInfo(s.config, name)
 }
 
 // APIEndpoint represents a remote API endpoint
@@ -138,7 +143,7 @@ func (e APIEndpoint) ToV1Endpoint(userAgent string, metaHeaders http.Header) (*V
 
 // TLSConfig constructs a client TLS configuration based on server defaults
 func (s *Service) TLSConfig(hostname string) (*tls.Config, error) {
-	return newTLSConfig(hostname, isSecureIndex(s.Config, hostname))
+	return newTLSConfig(hostname, isSecureIndex(s.config, hostname))
 }
 
 func (s *Service) tlsConfigForMirror(mirrorURL *url.URL) (*tls.Config, error) {
@@ -173,7 +178,7 @@ func (s *Service) lookupEndpoints(hostname string) (endpoints []APIEndpoint, err
 		return nil, err
 	}
 
-	if V2Only {
+	if s.config.V2Only {
 		return endpoints, nil
 	}
 

+ 1 - 1
registry/service_v2.go

@@ -12,7 +12,7 @@ func (s *Service) lookupV2Endpoints(hostname string) (endpoints []APIEndpoint, e
 	tlsConfig := &cfg
 	if hostname == DefaultNamespace {
 		// v2 mirrors
-		for _, mirror := range s.Config.Mirrors {
+		for _, mirror := range s.config.Mirrors {
 			if !strings.HasPrefix(mirror, "http://") && !strings.HasPrefix(mirror, "https://") {
 				mirror = "https://" + mirror
 			}