Added support for multiple endpoints in X-Docker-Endpoints header
Docker-DCO-1.1-Signed-off-by: Joffrey F <joffrey@docker.com> (github: shin-)master
							parent
							
								
									c7c51058ce
								
							
						
					
					
						commit
						52893cae73
					
				|  | @ -297,6 +297,25 @@ func (r *Registry) GetRemoteTags(registries []string, repository string, token [ | |||
| 	return nil, fmt.Errorf("Could not reach any registry endpoint") | ||||
| } | ||||
| 
 | ||||
| func buildEndpointsList(headers []string, indexEp string) ([]string, error) { | ||||
| 	var endpoints []string | ||||
| 	parsedUrl, err := url.Parse(indexEp) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	var urlScheme = parsedUrl.Scheme | ||||
| 	// The Registry's URL scheme has to match the Index'
 | ||||
| 	for _, ep := range headers { | ||||
| 		epList := strings.Split(ep, ",") | ||||
| 		for _, epListElement := range epList { | ||||
| 			endpoints = append( | ||||
| 				endpoints, | ||||
| 				fmt.Sprintf("%s://%s/v1/", urlScheme, strings.TrimSpace(epListElement))) | ||||
| 		} | ||||
| 	} | ||||
| 	return endpoints, nil | ||||
| } | ||||
| 
 | ||||
| func (r *Registry) GetRepositoryData(remote string) (*RepositoryData, error) { | ||||
| 	indexEp := r.indexEndpoint | ||||
| 	repositoryTarget := fmt.Sprintf("%srepositories/%s/images", indexEp, remote) | ||||
|  | @ -332,11 +351,10 @@ func (r *Registry) GetRepositoryData(remote string) (*RepositoryData, error) { | |||
| 	} | ||||
| 
 | ||||
| 	var endpoints []string | ||||
| 	var urlScheme = indexEp[:strings.Index(indexEp, ":")] | ||||
| 	if res.Header.Get("X-Docker-Endpoints") != "" { | ||||
| 		// The Registry's URL scheme has to match the Index'
 | ||||
| 		for _, ep := range res.Header["X-Docker-Endpoints"] { | ||||
| 			endpoints = append(endpoints, fmt.Sprintf("%s://%s/v1/", urlScheme, ep)) | ||||
| 		endpoints, err = buildEndpointsList(res.Header["X-Docker-Endpoints"], indexEp) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} else { | ||||
| 		return nil, fmt.Errorf("Index response didn't contain any endpoints") | ||||
|  | @ -565,7 +583,6 @@ func (r *Registry) PushImageJSONIndex(remote string, imgList []*ImgData, validat | |||
| 	} | ||||
| 
 | ||||
| 	var tokens, endpoints []string | ||||
| 	var urlScheme = indexEp[:strings.Index(indexEp, ":")] | ||||
| 	if !validate { | ||||
| 		if res.StatusCode != 200 && res.StatusCode != 201 { | ||||
| 			errBody, err := ioutil.ReadAll(res.Body) | ||||
|  | @ -582,9 +599,9 @@ func (r *Registry) PushImageJSONIndex(remote string, imgList []*ImgData, validat | |||
| 		} | ||||
| 
 | ||||
| 		if res.Header.Get("X-Docker-Endpoints") != "" { | ||||
| 			// The Registry's URL scheme has to match the Index'
 | ||||
| 			for _, ep := range res.Header["X-Docker-Endpoints"] { | ||||
| 				endpoints = append(endpoints, fmt.Sprintf("%s://%s/v1/", urlScheme, ep)) | ||||
| 			endpoints, err = buildEndpointsList(res.Header["X-Docker-Endpoints"], indexEp) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 		} else { | ||||
| 			return nil, fmt.Errorf("Index response didn't contain any endpoints") | ||||
|  |  | |||
|  | @ -291,7 +291,7 @@ func handlerUsers(w http.ResponseWriter, r *http.Request) { | |||
| 
 | ||||
| func handlerImages(w http.ResponseWriter, r *http.Request) { | ||||
| 	u, _ := url.Parse(testHttpServer.URL) | ||||
| 	w.Header().Add("X-Docker-Endpoints", u.Host) | ||||
| 	w.Header().Add("X-Docker-Endpoints", fmt.Sprintf("%s 	,  %s ", u.Host, "test.example.com")) | ||||
| 	w.Header().Add("X-Docker-Token", fmt.Sprintf("FAKE-SESSION-%d", time.Now().UnixNano())) | ||||
| 	if r.Method == "PUT" { | ||||
| 		if strings.HasSuffix(r.URL.Path, "images") { | ||||
|  |  | |||
|  | @ -1,7 +1,9 @@ | |||
| package registry | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/dotcloud/docker/utils" | ||||
| 	"net/url" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| ) | ||||
|  | @ -99,12 +101,23 @@ func TestGetRemoteTags(t *testing.T) { | |||
| 
 | ||||
| func TestGetRepositoryData(t *testing.T) { | ||||
| 	r := spawnTestRegistry(t) | ||||
| 	parsedUrl, err := url.Parse(makeURL("/v1/")) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	host := "http://" + parsedUrl.Host + "/v1/" | ||||
| 	data, err := r.GetRepositoryData("foo42/bar") | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	assertEqual(t, len(data.ImgList), 2, "Expected 2 images in ImgList") | ||||
| 	assertEqual(t, len(data.Endpoints), 1, "Expected one endpoint in Endpoints") | ||||
| 	assertEqual(t, len(data.Endpoints), 2, | ||||
| 		fmt.Sprintf("Expected 2 endpoints in Endpoints, found %d instead", len(data.Endpoints))) | ||||
| 	assertEqual(t, data.Endpoints[0], host, | ||||
| 		fmt.Sprintf("Expected first endpoint to be %s but found %s instead", host, data.Endpoints[0])) | ||||
| 	assertEqual(t, data.Endpoints[1], "http://test.example.com/v1/", | ||||
| 		fmt.Sprintf("Expected first endpoint to be http://test.example.com/v1/ but found %s instead", data.Endpoints[1])) | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| func TestPushImageJSONRegistry(t *testing.T) { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue