Browse code

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 authored on 2014/08/16 19:27:04
Showing 8 changed files
... ...
@@ -31,6 +31,7 @@ type Config struct {
31 31
 	BridgeIface                 string
32 32
 	BridgeIP                    string
33 33
 	FixedCIDR                   string
34
+	InsecureRegistries          []string
34 35
 	InterContainerCommunication bool
35 36
 	GraphDriver                 string
36 37
 	GraphOptions                []string
... ...
@@ -55,6 +56,7 @@ func (config *Config) InstallFlags() {
55 55
 	flag.StringVar(&config.BridgeIP, []string{"#bip", "-bip"}, "", "Use this CIDR notation address for the network bridge's IP, not compatible with -b")
56 56
 	flag.StringVar(&config.BridgeIface, []string{"b", "-bridge"}, "", "Attach containers to a pre-existing network bridge\nuse 'none' to disable container networking")
57 57
 	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)")
58
+	opts.ListVar(&config.InsecureRegistries, []string{"-insecure-registry"}, "Make these registries use http")
58 59
 	flag.BoolVar(&config.InterContainerCommunication, []string{"#icc", "-icc"}, true, "Enable inter-container communication")
59 60
 	flag.StringVar(&config.GraphDriver, []string{"s", "-storage-driver"}, "", "Force the Docker runtime to use a specific storage driver")
60 61
 	flag.StringVar(&config.ExecDriver, []string{"e", "-exec-driver"}, "native", "Force the Docker runtime to use a specific exec driver")
... ...
@@ -832,7 +832,7 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine) (*Daemon, error)
832 832
 	}
833 833
 
834 834
 	log.Debugf("Creating repository list")
835
-	repositories, err := graph.NewTagStore(path.Join(config.Root, "repositories-"+driver.String()), g, config.Mirrors)
835
+	repositories, err := graph.NewTagStore(path.Join(config.Root, "repositories-"+driver.String()), g, config.Mirrors, config.InsecureRegistries)
836 836
 	if err != nil {
837 837
 		return nil, fmt.Errorf("Couldn't create Tag store: %s", err)
838 838
 	}
... ...
@@ -70,7 +70,8 @@ expect an integer, and they can only be specified once.
70 70
       -g, --graph="/var/lib/docker"              Path to use as the root of the Docker runtime
71 71
       -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.
72 72
       --icc=true                                 Enable inter-container communication
73
-      --ip=0.0.0.0                               Default IP address to use when binding container ports
73
+      --insecure-registry=[]                     Make these registries use http
74
+      --ip=0.0.0.0                             Default IP address to use when binding container ports
74 75
       --ip-forward=true                          Enable net.ipv4.ip_forward
75 76
       --ip-masq=true                             Enable IP masquerading for bridge's IP range
76 77
       --iptables=true                            Enable Docker's addition of iptables rules
... ...
@@ -113,7 +113,9 @@ func (s *TagStore) CmdPull(job *engine.Job) engine.Status {
113 113
 		return job.Error(err)
114 114
 	}
115 115
 
116
-	endpoint, err := registry.NewEndpoint(hostname)
116
+	secure := registry.IsSecure(hostname, s.InsecureRegistries)
117
+
118
+	endpoint, err := registry.NewEndpoint(hostname, secure)
117 119
 	if err != nil {
118 120
 		return job.Error(err)
119 121
 	}
... ...
@@ -214,7 +214,9 @@ func (s *TagStore) CmdPush(job *engine.Job) engine.Status {
214 214
 		return job.Error(err)
215 215
 	}
216 216
 
217
-	endpoint, err := registry.NewEndpoint(hostname)
217
+	secure := registry.IsSecure(hostname, s.InsecureRegistries)
218
+
219
+	endpoint, err := registry.NewEndpoint(hostname, secure)
218 220
 	if err != nil {
219 221
 		return job.Error(err)
220 222
 	}
... ...
@@ -23,10 +23,11 @@ var (
23 23
 )
24 24
 
25 25
 type TagStore struct {
26
-	path         string
27
-	graph        *Graph
28
-	mirrors      []string
29
-	Repositories map[string]Repository
26
+	path               string
27
+	graph              *Graph
28
+	mirrors            []string
29
+	InsecureRegistries []string
30
+	Repositories       map[string]Repository
30 31
 	sync.Mutex
31 32
 	// FIXME: move push/pull-related fields
32 33
 	// to a helper type
... ...
@@ -54,18 +55,19 @@ func (r Repository) Contains(u Repository) bool {
54 54
 	return true
55 55
 }
56 56
 
57
-func NewTagStore(path string, graph *Graph, mirrors []string) (*TagStore, error) {
57
+func NewTagStore(path string, graph *Graph, mirrors []string, insecureRegistries []string) (*TagStore, error) {
58 58
 	abspath, err := filepath.Abs(path)
59 59
 	if err != nil {
60 60
 		return nil, err
61 61
 	}
62 62
 	store := &TagStore{
63
-		path:         abspath,
64
-		graph:        graph,
65
-		mirrors:      mirrors,
66
-		Repositories: make(map[string]Repository),
67
-		pullingPool:  make(map[string]chan struct{}),
68
-		pushingPool:  make(map[string]chan struct{}),
63
+		path:               abspath,
64
+		graph:              graph,
65
+		mirrors:            mirrors,
66
+		InsecureRegistries: insecureRegistries,
67
+		Repositories:       make(map[string]Repository),
68
+		pullingPool:        make(map[string]chan struct{}),
69
+		pushingPool:        make(map[string]chan struct{}),
69 70
 	}
70 71
 	// Load the json file if it exists, otherwise create it.
71 72
 	if err := store.reload(); os.IsNotExist(err) {
... ...
@@ -213,6 +213,55 @@ func ResolveRepositoryName(reposName string) (string, string, error) {
213 213
 	return hostname, reposName, nil
214 214
 }
215 215
 
216
+// this method expands the registry name as used in the prefix of a repo
217
+// to a full url. if it already is a url, there will be no change.
218
+func ExpandAndVerifyRegistryUrl(hostname string, secure bool) (endpoint string, err error) {
219
+	if strings.HasPrefix(hostname, "http:") || strings.HasPrefix(hostname, "https:") {
220
+		// if there is no slash after https:// (8 characters) then we have no path in the url
221
+		if strings.LastIndex(hostname, "/") < 9 {
222
+			// there is no path given. Expand with default path
223
+			hostname = hostname + "/v1/"
224
+		}
225
+		if _, err := pingRegistryEndpoint(hostname); err != nil {
226
+			return "", errors.New("Invalid Registry endpoint: " + err.Error())
227
+		}
228
+		return hostname, nil
229
+	}
230
+
231
+	// use HTTPS if secure, otherwise use HTTP
232
+	if secure {
233
+		endpoint = fmt.Sprintf("https://%s/v1/", hostname)
234
+	} else {
235
+		endpoint = fmt.Sprintf("http://%s/v1/", hostname)
236
+	}
237
+	_, err = pingRegistryEndpoint(endpoint)
238
+	if err != nil {
239
+		//TODO: triggering highland build can be done there without "failing"
240
+		err = fmt.Errorf("Invalid registry endpoint '%s': %s ", endpoint, err)
241
+		if secure {
242
+			err = fmt.Errorf("%s. If this private registry supports only HTTP, please add `--insecure-registry %s` to the daemon's arguments.", err, hostname)
243
+		}
244
+		return "", err
245
+	}
246
+	return endpoint, nil
247
+}
248
+
249
+// this method verifies if the provided hostname is part of the list of
250
+// insecure registries and returns false if HTTP should be used
251
+func IsSecure(hostname string, insecureRegistries []string) (secure bool) {
252
+	secure = true
253
+	for _, h := range insecureRegistries {
254
+		if hostname == h {
255
+			secure = false
256
+			break
257
+		}
258
+	}
259
+	if hostname == IndexServerAddress() {
260
+		secure = true
261
+	}
262
+	return
263
+}
264
+
216 265
 func trustedLocation(req *http.Request) bool {
217 266
 	var (
218 267
 		trusteds = []string{"docker.com", "docker.io"}
... ...
@@ -40,7 +40,7 @@ func (s *Service) Auth(job *engine.Job) engine.Status {
40 40
 	job.GetenvJson("authConfig", authConfig)
41 41
 	// TODO: this is only done here because auth and registry need to be merged into one pkg
42 42
 	if addr := authConfig.ServerAddress; addr != "" && addr != IndexServerAddress() {
43
-		endpoint, err := NewEndpoint(addr)
43
+		endpoint, err := NewEndpoint(addr, true)
44 44
 		if err != nil {
45 45
 			return job.Error(err)
46 46
 		}