| ... | ... |
@@ -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) {
|