diff --git a/contrib/completion/fish/docker.fish b/contrib/completion/fish/docker.fish index 41c4a33008be6..0af1169204093 100644 --- a/contrib/completion/fish/docker.fish +++ b/contrib/completion/fish/docker.fish @@ -63,7 +63,9 @@ complete -c docker -f -n '__fish_docker_no_subcommand' -l ip-masq -d "Enable IP complete -c docker -f -n '__fish_docker_no_subcommand' -l iptables -d "Enable Docker's addition of iptables rules" complete -c docker -f -n '__fish_docker_no_subcommand' -l mtu -d 'Set the containers network MTU' complete -c docker -f -n '__fish_docker_no_subcommand' -s p -l pidfile -d 'Path to use for daemon PID file' -complete -c docker -f -n '__fish_docker_no_subcommand' -l registry-mirror -d 'Specify a preferred Docker registry mirror' +complete -c docker -f -n '__fish_docker_no_subcommand' -l registry-mirror -d "Specify a preferred Docker registry mirror for pulls from official registry" +complete -c docker -f -n '__fish_docker_no_subcommand' -l registry-replace -d "Registry that shall replace official registry and index. Registry is expected to be insecure." +complete -c docker -f -n '__fish_docker_no_subcommand' -l registry-prepend -d "Each given registry will be prepended to a list of registries queried during image pulls or searches. The last registry given will be queried first. They will be treated as insecure." complete -c docker -f -n '__fish_docker_no_subcommand' -s s -l storage-driver -d 'Force the Docker runtime to use a specific storage driver' complete -c docker -f -n '__fish_docker_no_subcommand' -l selinux-enabled -d 'Enable selinux support. SELinux does not presently support the BTRFS storage driver' complete -c docker -f -n '__fish_docker_no_subcommand' -l storage-opt -d 'Set storage driver options' diff --git a/docker/daemon.go b/docker/daemon.go index 0923997375688..f4f15e7aed1ee 100644 --- a/docker/daemon.go +++ b/docker/daemon.go @@ -79,6 +79,21 @@ func mainDaemon() { flag.Usage() return } + + if *registryCfg.DefaultRegistry != "" { + defaultRegistry, err := registry.ValidateIndexName(*registryCfg.DefaultRegistry) + if err != nil { + log.Fatal("Given invalid default registry \"%s\": %s", *registryCfg.DefaultRegistry, err.Error()) + } + registry.RegistryList[0] = defaultRegistry + } + + for _, r := range registryCfg.AdditionalRegistries.GetAll() { + if r != "" { + registry.RegistryList = append([]string{r}, registry.RegistryList...) + } + } + eng := engine.New() signal.Trap(eng.Shutdown) diff --git a/docker/docker.go b/docker/docker.go index 7a10e6cdca4e1..6410171fab1ee 100644 --- a/docker/docker.go +++ b/docker/docker.go @@ -14,7 +14,6 @@ import ( "github.com/docker/docker/dockerversion" flag "github.com/docker/docker/pkg/mflag" "github.com/docker/docker/pkg/reexec" - "github.com/docker/docker/registry" "github.com/docker/docker/utils" ) @@ -38,19 +37,6 @@ func main() { return } - if *flDefaultRegistry != "" { - registry.RegistryList = strings.Split(*flDefaultRegistry, ",") - } - - if *flPrependRegistry != "" { - regs := strings.Split(*flPrependRegistry, ",") - for r := range regs { - // TODO: we actually prepend here - reflect this in the option name - // (--registry-prepend) - registry.RegistryList = append([]string{regs[r]}, registry.RegistryList...) - } - } - if *flLogLevel != "" { lvl, err := log.ParseLevel(*flLogLevel) if err != nil { diff --git a/docker/flags.go b/docker/flags.go index 59eaacbad2320..3b54612e89d0a 100644 --- a/docker/flags.go +++ b/docker/flags.go @@ -37,17 +37,15 @@ func getDaemonConfDir() string { } var ( - flPrependRegistry = flag.String([]string{"#registry-prepend", "-registry-prepend"}, "", "Comma separated list of registries to prepend to default registry. Registries will be searched in reverse order") - flDefaultRegistry = flag.String([]string{"#registry-replace", "-registry-replace"}, "", "Comma separated list of registries to replace the default registry. Registries will be searched in reverse order") - flVersion = flag.Bool([]string{"v", "-version"}, false, "Print version information and quit") - flDaemon = flag.Bool([]string{"d", "-daemon"}, false, "Enable daemon mode") - flDebug = flag.Bool([]string{"D", "-debug"}, false, "Enable debug mode") - flSocketGroup = flag.String([]string{"G", "-group"}, "docker", "Group to assign the unix socket specified by -H when running in daemon mode\nuse '' (the empty string) to disable setting of a group") - flLogLevel = flag.String([]string{"l", "-log-level"}, "info", "Set the logging level (debug, info, warn, error, fatal)") - flEnableCors = flag.Bool([]string{"#api-enable-cors", "-api-enable-cors"}, false, "Enable CORS headers in the remote API") - flTls = flag.Bool([]string{"-tls"}, false, "Use TLS; implied by --tlsverify flag") - flHelp = flag.Bool([]string{"h", "-help"}, false, "Print usage") - flTlsVerify = flag.Bool([]string{"-tlsverify"}, dockerTlsVerify, "Use TLS and verify the remote (daemon: verify client, client: verify daemon)") + flVersion = flag.Bool([]string{"v", "-version"}, false, "Print version information and quit") + flDaemon = flag.Bool([]string{"d", "-daemon"}, false, "Enable daemon mode") + flDebug = flag.Bool([]string{"D", "-debug"}, false, "Enable debug mode") + flSocketGroup = flag.String([]string{"G", "-group"}, "docker", "Group to assign the unix socket specified by -H when running in daemon mode\nuse '' (the empty string) to disable setting of a group") + flLogLevel = flag.String([]string{"l", "-log-level"}, "info", "Set the logging level (debug, info, warn, error, fatal)") + flEnableCors = flag.Bool([]string{"#api-enable-cors", "-api-enable-cors"}, false, "Enable CORS headers in the remote API") + flTls = flag.Bool([]string{"-tls"}, false, "Use TLS; implied by --tlsverify flag") + flHelp = flag.Bool([]string{"h", "-help"}, false, "Print usage") + flTlsVerify = flag.Bool([]string{"-tlsverify"}, dockerTlsVerify, "Use TLS and verify the remote (daemon: verify client, client: verify daemon)") // these are initialized in init() below since their default values depend on dockerCertPath which isn't fully initialized until init() runs flTrustKey *string diff --git a/docs/man/docker.1.md b/docs/man/docker.1.md index 48d53a3af3ef0..ec6d32d5e5913 100644 --- a/docs/man/docker.1.md +++ b/docs/man/docker.1.md @@ -89,7 +89,13 @@ unix://[/path/to/socket] to use. Path to use for daemon PID file. Default is `/var/run/docker.pid` **--registry-mirror**=:// - Prepend a registry mirror to be used for image pulls. May be specified multiple times. + Prepend a registry mirror to be used for image pulls from public Docker registry. May be specified multiple times. + +**--registry-prepend**=[] + Each given registry will be prepended to a list of registries queried during image pulls or searches. The last registry given will be queried first. They will be treated as insecure. Registry mirrors won't apply to them. + +**--registry-replace**="" + Registry that shall replace official Docker registry and index (e.g. 10.172.10.2:5000, private-registry.foo.bar). Additional registries added with --registry-prepend will be queried before this one. Use this option if you do not want to query official registry at all. It will be treated as insecure. Registry mirrors won't apply to given registry. **-s**="" Force the Docker runtime to use a specific storage driver. @@ -100,12 +106,6 @@ unix://[/path/to/socket] to use. **-v**=*true*|*false* Print version information and quit. Default is false. -**--registry-prepend**="" - Comma separated list of registries to prepend to default registry. Registries will be searched in reverse order. - -**--registry-replace**="" -Comma separated list of registries to replace the default registry. Registries will be searched in reverse order - **--selinux-enabled**=*true*|*false* Enable selinux support. Default is false. SELinux does not presently support the BTRFS storage driver. diff --git a/registry/config.go b/registry/config.go index 3457d15ebe868..dba3a51c129c8 100644 --- a/registry/config.go +++ b/registry/config.go @@ -16,8 +16,10 @@ import ( // Options holds command line options. type Options struct { - Mirrors opts.ListOpts - InsecureRegistries opts.ListOpts + Mirrors opts.ListOpts + InsecureRegistries opts.ListOpts + DefaultRegistry *string + AdditionalRegistries opts.ListOpts } const ( @@ -31,6 +33,8 @@ const ( ) var ( + // List of registries to query. + RegistryList = []string{INDEXNAME} ErrInvalidRepositoryName = errors.New("Invalid repository name (ex: \"registry.domain.tld/myrepos\")") emptyServiceConfig = NewServiceConfig(nil) validNamespaceChars = regexp.MustCompile(`^([a-z0-9-_]*)$`) @@ -45,24 +49,24 @@ func IndexServerName() string { // IndexServerAddress returns an index uri for given name. Empty string is // treated the same as a result of IndexServerName(). func IndexServerAddress(indexName string) string { - if (indexName == "" && RegistryList[0] == INDEXNAME) || indexName == INDEXNAME || indexName == INDEXSERVER { + if (indexName == "" && IndexServerName() == INDEXNAME) || indexName == INDEXNAME || indexName == INDEXSERVER { return INDEXSERVER } else if indexName != "" { return fmt.Sprintf("http://%s/v1/", indexName) } else { - return fmt.Sprintf("http://%s/v1/", RegistryList[0]) + return fmt.Sprintf("http://%s/v1/", IndexServerName()) } } // RegistryServerAddress returns a registry uri for given index name. Empty string // is treated the same as a result of IndexServerName(). func RegistryServerAddress(indexName string) string { - if (indexName == "" && RegistryList[0] == INDEXNAME) || indexName == INDEXNAME { + if (indexName == "" && IndexServerName() == INDEXNAME) || indexName == INDEXNAME { return REGISTRYSERVER } else if indexName != "" { return fmt.Sprintf("http://%s/v2/", indexName) } else { - return fmt.Sprintf("http://%s/v2/", RegistryList[0]) + return fmt.Sprintf("http://%s/v2/", IndexServerName()) } } @@ -70,9 +74,12 @@ func RegistryServerAddress(indexName string) string { // the current process. func (options *Options) InstallFlags() { options.Mirrors = opts.NewListOpts(ValidateMirror) - flag.Var(&options.Mirrors, []string{"-registry-mirror"}, "Specify a preferred Docker registry mirror") + flag.Var(&options.Mirrors, []string{"-registry-mirror"}, "Specify a preferred Docker registry mirror for pulls from official registry") options.InsecureRegistries = opts.NewListOpts(ValidateIndexName) flag.Var(&options.InsecureRegistries, []string{"-insecure-registry"}, "Enable insecure communication with specified registries (no certificate verification for HTTPS and enable HTTP fallback) (e.g., localhost:5000 or 10.20.0.0/16)") + options.DefaultRegistry = flag.String([]string{"-registry-replace"}, "", "Registry that shall replace official registry and index. It will be treated as insecure.") + options.AdditionalRegistries = opts.NewListOpts(ValidateIndexName) + flag.Var(&options.AdditionalRegistries, []string{"-registry-prepend"}, "Each given registry will be prepended to a list of registries queried during image pulls or searches. The last registry given will be queried first. They will be treated as insecure.") } type netIPNet net.IPNet @@ -136,13 +143,21 @@ func NewServiceConfig(options *Options) *ServiceConfig { } } - if config.IndexConfigs[IndexServerName()] == nil { - // Configure public registry. - config.IndexConfigs[IndexServerName()] = &IndexInfo{ - Name: IndexServerName(), - Mirrors: options.Mirrors.GetAll(), - Secure: IndexServerName() == INDEXNAME, - Official: IndexServerName() == INDEXNAME, + for _, r := range RegistryList { + var mirrors []string + if config.IndexConfigs[r] == nil { + // Use mirrors only with official index + if r == INDEXNAME { + mirrors = options.Mirrors.GetAll() + } else { + mirrors = make([]string, 0) + } + config.IndexConfigs[r] = &IndexInfo{ + Name: r, + Mirrors: mirrors, + Secure: r == INDEXNAME, + Official: r == INDEXNAME, + } } } diff --git a/registry/service.go b/registry/service.go index 3af88ea13e48a..88609d772ccc4 100644 --- a/registry/service.go +++ b/registry/service.go @@ -6,10 +6,6 @@ import ( "github.com/docker/docker/engine" ) -// List of indexes to query. -// The lower the index, the higher the priority. -var RegistryList = []string{INDEXNAME} - // Service exposes registry capabilities in the standard Engine // interface. Once installed, it extends the engine with the // following calls: @@ -117,7 +113,6 @@ func (s *Service) Search(job *engine.Job) engine.Status { if err != nil { return err } - // *TODO: Search multiple indexes. endpoint, err := repoInfo.GetEndpoint() if err != nil { return err