Browse Source

make http usage for registry explicit

Docker-DCO-1.1-Signed-off-by: Cristian Staretu <cristian.staretu@gmail.com> (github: unclejack)

Conflicts:
	daemon/config.go
	daemon/daemon.go
	graph/pull.go
	graph/push.go
	graph/tags.go
	registry/registry.go
	registry/service.go
unclejack 11 years ago
parent
commit
f9b4bfa59b
8 changed files with 74 additions and 16 deletions
  1. 2 0
      daemon/config.go
  2. 1 1
      daemon/daemon.go
  3. 2 1
      docs/sources/reference/commandline/cli.md
  4. 3 1
      graph/pull.go
  5. 3 1
      graph/push.go
  6. 13 11
      graph/tags.go
  7. 49 0
      registry/registry.go
  8. 1 1
      registry/service.go

+ 2 - 0
daemon/config.go

@@ -31,6 +31,7 @@ type Config struct {
 	BridgeIface                 string
 	BridgeIP                    string
 	FixedCIDR                   string
+	InsecureRegistries          []string
 	InterContainerCommunication bool
 	GraphDriver                 string
 	GraphOptions                []string
@@ -55,6 +56,7 @@ func (config *Config) InstallFlags() {
 	flag.StringVar(&config.BridgeIP, []string{"#bip", "-bip"}, "", "Use this CIDR notation address for the network bridge's IP, not compatible with -b")
 	flag.StringVar(&config.BridgeIface, []string{"b", "-bridge"}, "", "Attach containers to a pre-existing network bridge\nuse 'none' to disable container networking")
 	flag.StringVar(&config.FixedCIDR, []string{"-fixed-cidr"}, "", "IPv4 subnet for fixed IPs (ex: 10.20.0.0/16)\nthis subnet must be nested in the bridge subnet (which is defined by -b or --bip)")
+	opts.ListVar(&config.InsecureRegistries, []string{"-insecure-registry"}, "Make these registries use http")
 	flag.BoolVar(&config.InterContainerCommunication, []string{"#icc", "-icc"}, true, "Enable inter-container communication")
 	flag.StringVar(&config.GraphDriver, []string{"s", "-storage-driver"}, "", "Force the Docker runtime to use a specific storage driver")
 	flag.StringVar(&config.ExecDriver, []string{"e", "-exec-driver"}, "native", "Force the Docker runtime to use a specific exec driver")

+ 1 - 1
daemon/daemon.go

@@ -831,7 +831,7 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine) (*Daemon, error)
 	}
 
 	log.Debugf("Creating repository list")
-	repositories, err := graph.NewTagStore(path.Join(config.Root, "repositories-"+driver.String()), g, config.Mirrors)
+	repositories, err := graph.NewTagStore(path.Join(config.Root, "repositories-"+driver.String()), g, config.Mirrors, config.InsecureRegistries)
 	if err != nil {
 		return nil, fmt.Errorf("Couldn't create Tag store: %s", err)
 	}

+ 2 - 1
docs/sources/reference/commandline/cli.md

@@ -70,7 +70,8 @@ expect an integer, and they can only be specified once.
       -g, --graph="/var/lib/docker"              Path to use as the root of the Docker runtime
       -H, --host=[]                              The socket(s) to bind to in daemon mode or connect to in client mode, specified using one or more tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd.
       --icc=true                                 Enable inter-container communication
-      --ip=0.0.0.0                               Default IP address to use when binding container ports
+      --insecure-registry=[]                     Make these registries use http
+      --ip=0.0.0.0                             Default IP address to use when binding container ports
       --ip-forward=true                          Enable net.ipv4.ip_forward
       --ip-masq=true                             Enable IP masquerading for bridge's IP range
       --iptables=true                            Enable Docker's addition of iptables rules

+ 3 - 1
graph/pull.go

@@ -113,7 +113,9 @@ func (s *TagStore) CmdPull(job *engine.Job) engine.Status {
 		return job.Error(err)
 	}
 
-	endpoint, err := registry.NewEndpoint(hostname)
+	secure := registry.IsSecure(hostname, s.InsecureRegistries)
+
+	endpoint, err := registry.NewEndpoint(hostname, secure)
 	if err != nil {
 		return job.Error(err)
 	}

+ 3 - 1
graph/push.go

@@ -214,7 +214,9 @@ func (s *TagStore) CmdPush(job *engine.Job) engine.Status {
 		return job.Error(err)
 	}
 
-	endpoint, err := registry.NewEndpoint(hostname)
+	secure := registry.IsSecure(hostname, s.InsecureRegistries)
+
+	endpoint, err := registry.NewEndpoint(hostname, secure)
 	if err != nil {
 		return job.Error(err)
 	}

+ 13 - 11
graph/tags.go

@@ -23,10 +23,11 @@ var (
 )
 
 type TagStore struct {
-	path         string
-	graph        *Graph
-	mirrors      []string
-	Repositories map[string]Repository
+	path               string
+	graph              *Graph
+	mirrors            []string
+	InsecureRegistries []string
+	Repositories       map[string]Repository
 	sync.Mutex
 	// FIXME: move push/pull-related fields
 	// to a helper type
@@ -54,18 +55,19 @@ func (r Repository) Contains(u Repository) bool {
 	return true
 }
 
-func NewTagStore(path string, graph *Graph, mirrors []string) (*TagStore, error) {
+func NewTagStore(path string, graph *Graph, mirrors []string, insecureRegistries []string) (*TagStore, error) {
 	abspath, err := filepath.Abs(path)
 	if err != nil {
 		return nil, err
 	}
 	store := &TagStore{
-		path:         abspath,
-		graph:        graph,
-		mirrors:      mirrors,
-		Repositories: make(map[string]Repository),
-		pullingPool:  make(map[string]chan struct{}),
-		pushingPool:  make(map[string]chan struct{}),
+		path:               abspath,
+		graph:              graph,
+		mirrors:            mirrors,
+		InsecureRegistries: insecureRegistries,
+		Repositories:       make(map[string]Repository),
+		pullingPool:        make(map[string]chan struct{}),
+		pushingPool:        make(map[string]chan struct{}),
 	}
 	// Load the json file if it exists, otherwise create it.
 	if err := store.reload(); os.IsNotExist(err) {

+ 49 - 0
registry/registry.go

@@ -202,6 +202,55 @@ func ResolveRepositoryName(reposName string) (string, string, error) {
 	return hostname, reposName, nil
 }
 
+// this method expands the registry name as used in the prefix of a repo
+// to a full url. if it already is a url, there will be no change.
+func ExpandAndVerifyRegistryUrl(hostname string, secure bool) (endpoint string, err error) {
+	if strings.HasPrefix(hostname, "http:") || strings.HasPrefix(hostname, "https:") {
+		// if there is no slash after https:// (8 characters) then we have no path in the url
+		if strings.LastIndex(hostname, "/") < 9 {
+			// there is no path given. Expand with default path
+			hostname = hostname + "/v1/"
+		}
+		if _, err := pingRegistryEndpoint(hostname); err != nil {
+			return "", errors.New("Invalid Registry endpoint: " + err.Error())
+		}
+		return hostname, nil
+	}
+
+	// use HTTPS if secure, otherwise use HTTP
+	if secure {
+		endpoint = fmt.Sprintf("https://%s/v1/", hostname)
+	} else {
+		endpoint = fmt.Sprintf("http://%s/v1/", hostname)
+	}
+	_, err = pingRegistryEndpoint(endpoint)
+	if err != nil {
+		//TODO: triggering highland build can be done there without "failing"
+		err = fmt.Errorf("Invalid registry endpoint '%s': %s ", endpoint, err)
+		if secure {
+			err = fmt.Errorf("%s. If this private registry supports only HTTP, please add `--insecure-registry %s` to the daemon's arguments.", err, hostname)
+		}
+		return "", err
+	}
+	return endpoint, nil
+}
+
+// this method verifies if the provided hostname is part of the list of
+// insecure registries and returns false if HTTP should be used
+func IsSecure(hostname string, insecureRegistries []string) (secure bool) {
+	secure = true
+	for _, h := range insecureRegistries {
+		if hostname == h {
+			secure = false
+			break
+		}
+	}
+	if hostname == IndexServerAddress() {
+		secure = true
+	}
+	return
+}
+
 func trustedLocation(req *http.Request) bool {
 	var (
 		trusteds = []string{"docker.com", "docker.io"}

+ 1 - 1
registry/service.go

@@ -40,7 +40,7 @@ func (s *Service) Auth(job *engine.Job) engine.Status {
 	job.GetenvJson("authConfig", authConfig)
 	// TODO: this is only done here because auth and registry need to be merged into one pkg
 	if addr := authConfig.ServerAddress; addr != "" && addr != IndexServerAddress() {
-		endpoint, err := NewEndpoint(addr)
+		endpoint, err := NewEndpoint(addr, true)
 		if err != nil {
 			return job.Error(err)
 		}