mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #21045 from calavera/registry_config_options
Move registry service options to the daemon configuration.
This commit is contained in:
commit
1d094255d5
11 changed files with 133 additions and 88 deletions
|
@ -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"))
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -51,7 +52,6 @@ var (
|
|||
// DaemonCli represents the daemon CLI.
|
||||
type DaemonCli struct {
|
||||
*daemon.Config
|
||||
registryOptions *registry.Options
|
||||
flags *flag.FlagSet
|
||||
}
|
||||
|
||||
|
@ -67,16 +67,16 @@ 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,
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -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"))
|
||||
|
||||
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 *Options) *registrytypes.ServiceConfig {
|
||||
if options == nil {
|
||||
options = &Options{
|
||||
Mirrors: opts.NewListOpts(nil),
|
||||
InsecureRegistries: opts.NewListOpts(nil),
|
||||
}
|
||||
}
|
||||
|
||||
// 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")
|
||||
options.InsecureRegistries = append(options.InsecureRegistries, "127.0.0.0/8")
|
||||
|
||||
config := ®istrytypes.ServiceConfig{
|
||||
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.GetAll(),
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue