@@ -13,6 +13,7 @@ import (
13
13
"testing"
14
14
"time"
15
15
16
+ "github.com/docker/distribution/registry/api/errcode"
16
17
gocontext "golang.org/x/net/context"
17
18
18
19
kapi "k8s.io/kubernetes/pkg/api"
@@ -135,16 +136,18 @@ func TestImageStreamImport(t *testing.T) {
135
136
}
136
137
}
137
138
138
- func mockRegistryHandler (t * testing.T , count * int ) http.Handler {
139
+ func mockRegistryHandler (t * testing.T , requireAuth bool , count * int ) http.Handler {
139
140
return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
140
141
(* count )++
141
142
t .Logf ("%d got %s %s" , * count , r .Method , r .URL .Path )
142
143
143
144
w .Header ().Set ("Docker-Distribution-API-Version" , "registry/2.0" )
144
- if len (r .Header .Get ("Authorization" )) == 0 {
145
- w .Header ().Set ("WWW-Authenticate" , "BASIC" )
146
- w .WriteHeader (http .StatusUnauthorized )
147
- return
145
+ if requireAuth {
146
+ if len (r .Header .Get ("Authorization" )) == 0 {
147
+ w .Header ().Set ("WWW-Authenticate" , "BASIC" )
148
+ w .WriteHeader (http .StatusUnauthorized )
149
+ return
150
+ }
148
151
}
149
152
150
153
switch r .URL .Path {
@@ -154,6 +157,12 @@ func mockRegistryHandler(t *testing.T, count *int) http.Handler {
154
157
w .Write ([]byte (phpManifest ))
155
158
case "/v2/test/image2/manifests/" + etcdDigest :
156
159
w .Write ([]byte (etcdManifest ))
160
+ case "/v2/test/image3/tags/list" :
161
+ w .Write ([]byte ("{\" name\" : \" test/image3\" , \" tags\" : [\" latest\" , \" v1\" , \" v2\" ]}" ))
162
+ case "/v2/test/image3/manifests/latest" , "/v2/test/image3/manifests/v2" , "/v2/test/image3/manifests/" + forbiddenDigest :
163
+ errcode .ServeJSON (w , errcode .ErrorCodeUnknown )
164
+ case "/v2/test/image3/manifests/v1" , "/v2/test/image3/manifests/" + etcdDigest :
165
+ w .Write ([]byte (etcdManifest ))
157
166
default :
158
167
t .Fatalf ("unexpected request %s: %#v" , r .URL .Path , r )
159
168
}
@@ -164,7 +173,7 @@ func TestImageStreamImportAuthenticated(t *testing.T) {
164
173
testutil .RequireEtcd (t )
165
174
// start regular HTTP servers
166
175
count := 0
167
- server := httptest .NewServer (mockRegistryHandler (t , & count ))
176
+ server := httptest .NewServer (mockRegistryHandler (t , true , & count ))
168
177
server2 := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
169
178
w .Header ().Set ("Docker-Distribution-API-Version" , "registry/2.0" )
170
179
if len (r .Header .Get ("Authorization" )) == 0 {
@@ -177,7 +186,7 @@ func TestImageStreamImportAuthenticated(t *testing.T) {
177
186
178
187
// start a TLS server
179
188
count2 := 0
180
- server3 := httptest .NewTLSServer (mockRegistryHandler (t , & count2 ))
189
+ server3 := httptest .NewTLSServer (mockRegistryHandler (t , true , & count2 ))
181
190
182
191
url1 , _ := url .Parse (server .URL )
183
192
url2 , _ := url .Parse (server2 .URL )
@@ -324,6 +333,105 @@ func TestImageStreamImportAuthenticated(t *testing.T) {
324
333
}
325
334
}
326
335
336
+ // Verifies that individual errors for particular tags are handled properly when pulling all tags from a
337
+ // repository.
338
+ func TestImageStreamImportTagsFromRepository (t * testing.T ) {
339
+ testutil .RequireEtcd (t )
340
+ // start regular HTTP servers
341
+ count := 0
342
+ server := httptest .NewServer (mockRegistryHandler (t , false , & count ))
343
+
344
+ url , _ := url .Parse (server .URL )
345
+
346
+ // start a master
347
+ _ , clusterAdminKubeConfig , err := testserver .StartTestMaster ()
348
+ if err != nil {
349
+ t .Fatalf ("unexpected error: %v" , err )
350
+ }
351
+ /*
352
+ _, err := testutil.GetClusterAdminKubeClient(clusterAdminKubeConfig)
353
+ if err != nil {
354
+ t.Fatalf("unexpected error: %v", err)
355
+ }
356
+ */
357
+ c , err := testutil .GetClusterAdminClient (clusterAdminKubeConfig )
358
+ if err != nil {
359
+ t .Fatalf ("unexpected error: %v" , err )
360
+ }
361
+ err = testutil .CreateNamespace (clusterAdminKubeConfig , testutil .Namespace ())
362
+ if err != nil {
363
+ t .Fatalf ("unexpected error: %v" , err )
364
+ }
365
+
366
+ importSpec := & api.ImageStreamImport {
367
+ ObjectMeta : kapi.ObjectMeta {Name : "test" },
368
+ Spec : api.ImageStreamImportSpec {
369
+ Import : true ,
370
+ Repository : & api.RepositoryImportSpec {
371
+ From : kapi.ObjectReference {Kind : "DockerImage" , Name : url .Host + "/test/image3" },
372
+ ImportPolicy : api.TagImportPolicy {Insecure : true },
373
+ IncludeManifest : true ,
374
+ },
375
+ },
376
+ }
377
+
378
+ // import expecting regular image to pass
379
+ isi , err := c .ImageStreams (testutil .Namespace ()).Import (importSpec )
380
+ if err != nil {
381
+ t .Fatal (err )
382
+ }
383
+ if len (isi .Status .Images ) != 0 {
384
+ t .Errorf ("imported unexpected number of images (%d != 0)" , len (isi .Status .Images ))
385
+ }
386
+ if isi .Status .Repository == nil {
387
+ t .Fatalf ("exported non-nil repository status" )
388
+ }
389
+ if len (isi .Status .Repository .Images ) != 3 {
390
+ t .Fatalf ("imported unexpected number of tags (%d != 3)" , len (isi .Status .Repository .Images ))
391
+ }
392
+ for i , image := range isi .Status .Repository .Images {
393
+ switch i {
394
+ case 2 :
395
+ if image .Status .Status != unversioned .StatusSuccess {
396
+ t .Errorf ("import of image %d did not succeed: %#v" , i , image .Status )
397
+ }
398
+ if image .Tag != "v1" {
399
+ t .Errorf ("unexpected tag at position %d (%s != v1)" , i , image .Tag )
400
+ }
401
+ if image .Image == nil {
402
+ t .Fatalf ("expected image to be set" )
403
+ }
404
+ if image .Image .DockerImageReference != url .Host + "/test/image3@" + etcdDigest {
405
+ t .Errorf ("unexpected DockerImageReference (%s != %s)" , image .Image .DockerImageReference , url .Host + "/test/image3@" + etcdDigest )
406
+ }
407
+ if image .Image .Name != etcdDigest {
408
+ t .Errorf ("expected etcd digest as a name of the image (%s != %s)" , image .Image .Name , etcdDigest )
409
+ }
410
+ default :
411
+ if image .Status .Status != unversioned .StatusFailure || image .Status .Reason != unversioned .StatusReasonInternalError {
412
+ t .Fatalf ("import of image %d did not report internal server error: %#v" , i , image .Status )
413
+ }
414
+ expectedTags := []string {"latest" , "v2" }[i ]
415
+ if image .Tag != expectedTags {
416
+ t .Errorf ("unexpected tag at position %d (%s != %s)" , i , image .Tag , expectedTags [i ])
417
+ }
418
+ }
419
+ }
420
+
421
+ is , err := c .ImageStreams (testutil .Namespace ()).Get ("test" )
422
+ if err != nil {
423
+ t .Fatal (err )
424
+ }
425
+ tagEvent := api .LatestTaggedImage (is , "v1" )
426
+ if tagEvent == nil {
427
+ t .Fatalf ("no image tagged for v1: %#v" , is )
428
+ }
429
+
430
+ if tagEvent == nil || tagEvent .Image != etcdDigest || tagEvent .DockerImageReference != url .Host + "/test/image3@" + etcdDigest {
431
+ t .Fatalf ("expected the etcd image to be tagged: %#v" , tagEvent )
432
+ }
433
+ }
434
+
327
435
// Verifies that the import scheduler fetches an image repeatedly (every 1s as per the default
328
436
// test controller interval), updates the image stream only when there are changes, and if an
329
437
// error occurs writes the error only once (instead of every interval)
@@ -861,3 +969,5 @@ const phpManifest = `{
861
969
}
862
970
]
863
971
}`
972
+
973
+ const forbiddenDigest = `sha256:f374c0d9b59e6fdf9f8922d59e946b05fbeabaed70b0639d7b6b524f3299e87b`
0 commit comments