Browse code

Added support for multiple endpoints in X-Docker-Endpoints header Docker-DCO-1.1-Signed-off-by: Joffrey F <joffrey@docker.com> (github: shin-)

shin- authored on 2014/04/15 03:32:47
Showing 3 changed files
... ...
@@ -297,6 +297,25 @@ func (r *Registry) GetRemoteTags(registries []string, repository string, token [
297 297
 	return nil, fmt.Errorf("Could not reach any registry endpoint")
298 298
 }
299 299
 
300
+func buildEndpointsList(headers []string, indexEp string) ([]string, error) {
301
+	var endpoints []string
302
+	parsedUrl, err := url.Parse(indexEp)
303
+	if err != nil {
304
+		return nil, err
305
+	}
306
+	var urlScheme = parsedUrl.Scheme
307
+	// The Registry's URL scheme has to match the Index'
308
+	for _, ep := range headers {
309
+		epList := strings.Split(ep, ",")
310
+		for _, epListElement := range epList {
311
+			endpoints = append(
312
+				endpoints,
313
+				fmt.Sprintf("%s://%s/v1/", urlScheme, strings.TrimSpace(epListElement)))
314
+		}
315
+	}
316
+	return endpoints, nil
317
+}
318
+
300 319
 func (r *Registry) GetRepositoryData(remote string) (*RepositoryData, error) {
301 320
 	indexEp := r.indexEndpoint
302 321
 	repositoryTarget := fmt.Sprintf("%srepositories/%s/images", indexEp, remote)
... ...
@@ -332,11 +351,10 @@ func (r *Registry) GetRepositoryData(remote string) (*RepositoryData, error) {
332 332
 	}
333 333
 
334 334
 	var endpoints []string
335
-	var urlScheme = indexEp[:strings.Index(indexEp, ":")]
336 335
 	if res.Header.Get("X-Docker-Endpoints") != "" {
337
-		// The Registry's URL scheme has to match the Index'
338
-		for _, ep := range res.Header["X-Docker-Endpoints"] {
339
-			endpoints = append(endpoints, fmt.Sprintf("%s://%s/v1/", urlScheme, ep))
336
+		endpoints, err = buildEndpointsList(res.Header["X-Docker-Endpoints"], indexEp)
337
+		if err != nil {
338
+			return nil, err
340 339
 		}
341 340
 	} else {
342 341
 		return nil, fmt.Errorf("Index response didn't contain any endpoints")
... ...
@@ -565,7 +583,6 @@ func (r *Registry) PushImageJSONIndex(remote string, imgList []*ImgData, validat
565 565
 	}
566 566
 
567 567
 	var tokens, endpoints []string
568
-	var urlScheme = indexEp[:strings.Index(indexEp, ":")]
569 568
 	if !validate {
570 569
 		if res.StatusCode != 200 && res.StatusCode != 201 {
571 570
 			errBody, err := ioutil.ReadAll(res.Body)
... ...
@@ -582,9 +599,9 @@ func (r *Registry) PushImageJSONIndex(remote string, imgList []*ImgData, validat
582 582
 		}
583 583
 
584 584
 		if res.Header.Get("X-Docker-Endpoints") != "" {
585
-			// The Registry's URL scheme has to match the Index'
586
-			for _, ep := range res.Header["X-Docker-Endpoints"] {
587
-				endpoints = append(endpoints, fmt.Sprintf("%s://%s/v1/", urlScheme, ep))
585
+			endpoints, err = buildEndpointsList(res.Header["X-Docker-Endpoints"], indexEp)
586
+			if err != nil {
587
+				return nil, err
588 588
 			}
589 589
 		} else {
590 590
 			return nil, fmt.Errorf("Index response didn't contain any endpoints")
... ...
@@ -291,7 +291,7 @@ func handlerUsers(w http.ResponseWriter, r *http.Request) {
291 291
 
292 292
 func handlerImages(w http.ResponseWriter, r *http.Request) {
293 293
 	u, _ := url.Parse(testHttpServer.URL)
294
-	w.Header().Add("X-Docker-Endpoints", u.Host)
294
+	w.Header().Add("X-Docker-Endpoints", fmt.Sprintf("%s 	,  %s ", u.Host, "test.example.com"))
295 295
 	w.Header().Add("X-Docker-Token", fmt.Sprintf("FAKE-SESSION-%d", time.Now().UnixNano()))
296 296
 	if r.Method == "PUT" {
297 297
 		if strings.HasSuffix(r.URL.Path, "images") {
... ...
@@ -1,7 +1,9 @@
1 1
 package registry
2 2
 
3 3
 import (
4
+	"fmt"
4 5
 	"github.com/dotcloud/docker/utils"
6
+	"net/url"
5 7
 	"strings"
6 8
 	"testing"
7 9
 )
... ...
@@ -99,12 +101,23 @@ func TestGetRemoteTags(t *testing.T) {
99 99
 
100 100
 func TestGetRepositoryData(t *testing.T) {
101 101
 	r := spawnTestRegistry(t)
102
+	parsedUrl, err := url.Parse(makeURL("/v1/"))
103
+	if err != nil {
104
+		t.Fatal(err)
105
+	}
106
+	host := "http://" + parsedUrl.Host + "/v1/"
102 107
 	data, err := r.GetRepositoryData("foo42/bar")
103 108
 	if err != nil {
104 109
 		t.Fatal(err)
105 110
 	}
106 111
 	assertEqual(t, len(data.ImgList), 2, "Expected 2 images in ImgList")
107
-	assertEqual(t, len(data.Endpoints), 1, "Expected one endpoint in Endpoints")
112
+	assertEqual(t, len(data.Endpoints), 2,
113
+		fmt.Sprintf("Expected 2 endpoints in Endpoints, found %d instead", len(data.Endpoints)))
114
+	assertEqual(t, data.Endpoints[0], host,
115
+		fmt.Sprintf("Expected first endpoint to be %s but found %s instead", host, data.Endpoints[0]))
116
+	assertEqual(t, data.Endpoints[1], "http://test.example.com/v1/",
117
+		fmt.Sprintf("Expected first endpoint to be http://test.example.com/v1/ but found %s instead", data.Endpoints[1]))
118
+
108 119
 }
109 120
 
110 121
 func TestPushImageJSONRegistry(t *testing.T) {