@@ -129,12 +129,13 @@ func (o *ImportImageOptions) Validate(cmd *cobra.Command) error {
129
129
130
130
// Run contains all the necessary functionality for the OpenShift cli import-image command.
131
131
func (o * ImportImageOptions ) Run () error {
132
+ // TODO: add dry-run
132
133
stream , isi , err := o .createImageImport ()
133
134
if err != nil {
134
135
return err
135
136
}
136
137
137
- // TODO: add dry-run
138
+ // Attempt the new, direct import path
138
139
result , err := o .isClient .Import (isi )
139
140
switch {
140
141
case err == client .ErrImageStreamImportUnsupported :
@@ -248,128 +249,172 @@ func (o *ImportImageOptions) waitForImport(resourceVersion string) (*imageapi.Im
248
249
}
249
250
250
251
func (o * ImportImageOptions ) createImageImport () (* imageapi.ImageStream , * imageapi.ImageStreamImport , error ) {
252
+ var isi * imageapi.ImageStreamImport
251
253
stream , err := o .isClient .Get (o .Name )
252
- from := o .From
253
- tag := o .Tag
254
+ // no stream, try creating one
254
255
if err != nil {
255
256
if ! errors .IsNotFound (err ) {
256
257
return nil , nil , err
257
258
}
258
-
259
- // the stream is new
260
259
if ! o .Confirm {
261
260
return nil , nil , fmt .Errorf ("no image stream named %q exists, pass --confirm to create and import" , o .Name )
262
261
}
263
- if len (from ) == 0 {
264
- from = o .Target
265
- }
266
- if o .All {
267
- stream = & imageapi.ImageStream {
268
- ObjectMeta : kapi.ObjectMeta {Name : o .Name },
269
- Spec : imageapi.ImageStreamSpec {DockerImageRepository : from },
270
- }
271
- } else {
272
- stream = & imageapi.ImageStream {
273
- ObjectMeta : kapi.ObjectMeta {Name : o .Name },
274
- Spec : imageapi.ImageStreamSpec {
275
- Tags : map [string ]imageapi.TagReference {
276
- tag : {
277
- From : & kapi.ObjectReference {
278
- Kind : "DockerImage" ,
279
- Name : from ,
280
- },
281
- },
282
- },
283
- },
284
- }
285
- }
262
+ stream , isi = o .newImageStream ()
263
+ return stream , isi , nil
264
+ }
286
265
266
+ // the stream already exists
267
+ if len (stream .Spec .DockerImageRepository ) == 0 && len (stream .Spec .Tags ) == 0 {
268
+ return nil , nil , fmt .Errorf ("image stream does not have valid docker images to be imported" )
269
+ }
270
+
271
+ if o .All {
272
+ // importing the entire repository
273
+ isi , err = o .importAll (stream )
274
+ if err != nil {
275
+ return nil , nil , err
276
+ }
287
277
} else {
288
- // the stream already exists
289
- if len (stream .Spec .DockerImageRepository ) == 0 && len (stream .Spec .Tags ) == 0 {
290
- return nil , nil , fmt .Errorf ("image stream has not defined anything to import" )
278
+ // importing a single tag
279
+ isi , err = o .importTag (stream )
280
+ if err != nil {
281
+ return nil , nil , err
291
282
}
283
+ }
292
284
293
- if o .All {
294
- // importing a whole repository
295
- // TODO soltysh: write tests to cover all the possible usecases!!!
296
- if len (from ) == 0 {
297
- if len (stream .Spec .DockerImageRepository ) == 0 {
298
- // FIXME soltysh:
299
- return nil , nil , fmt .Errorf ("flag --all is applicable only to images with spec.dockerImageRepository defined" )
285
+ return stream , isi , nil
286
+ }
287
+
288
+ func (o * ImportImageOptions ) importAll (stream * imageapi.ImageStream ) (* imageapi.ImageStreamImport , error ) {
289
+ from := o .From
290
+ // update ImageStream appropriately
291
+ if len (from ) == 0 {
292
+ if len (stream .Spec .DockerImageRepository ) != 0 {
293
+ from = stream .Spec .DockerImageRepository
294
+ } else {
295
+ tags := make (map [string ]string )
296
+ for name , tag := range stream .Spec .Tags {
297
+ if tag .From != nil && tag .From .Kind == "DockerImage" {
298
+ tags [name ] = tag .From .Name
300
299
}
301
- from = stream .Spec .DockerImageRepository
302
300
}
303
- if from != stream .Spec .DockerImageRepository {
304
- if ! o .Confirm {
305
- if len (stream .Spec .DockerImageRepository ) == 0 {
306
- return nil , nil , fmt .Errorf ("the image stream does not currently import an entire Docker repository, pass --confirm to update" )
307
- }
308
- return nil , nil , fmt .Errorf ("the image stream has a different import spec %q, pass --confirm to update" , stream .Spec .DockerImageRepository )
309
- }
310
- stream .Spec .DockerImageRepository = from
301
+ if len (tags ) == 0 {
302
+ return nil , fmt .Errorf ("image stream does not have tags pointing to external docker images" )
311
303
}
304
+ return o .newImageStreamImportTags (stream , tags ), nil
305
+ }
306
+ }
307
+ if from != stream .Spec .DockerImageRepository {
308
+ if ! o .Confirm {
309
+ if len (stream .Spec .DockerImageRepository ) == 0 {
310
+ return nil , fmt .Errorf ("the image stream does not currently import an entire Docker repository, pass --confirm to update" )
311
+ }
312
+ return nil , fmt .Errorf ("the image stream has a different import spec %q, pass --confirm to update" , stream .Spec .DockerImageRepository )
313
+ }
314
+ stream .Spec .DockerImageRepository = from
315
+ }
312
316
313
- } else {
314
- // importing a single tag
317
+ // and create accompanying ImageStreamImport
318
+ return o .newImageStreamImportAll (stream , from ), nil
319
+ }
315
320
316
- // follow any referential tags to the destination
317
- finalTag , existing , ok , multiple := imageapi .FollowTagReference (stream , tag )
318
- if ! ok && multiple {
319
- return nil , nil , fmt .Errorf ("tag %q on the image stream is a reference to %q, which does not exist" , tag , finalTag )
320
- }
321
+ func (o * ImportImageOptions ) importTag (stream * imageapi.ImageStream ) (* imageapi.ImageStreamImport , error ) {
322
+ from := o .From
323
+ tag := o .Tag
324
+ // follow any referential tags to the destination
325
+ finalTag , existing , ok , multiple := imageapi .FollowTagReference (stream , tag )
326
+ if ! ok && multiple {
327
+ return nil , fmt .Errorf ("tag %q on the image stream is a reference to %q, which does not exist" , tag , finalTag )
328
+ }
321
329
322
- if ok {
323
- // disallow changing an existing tag
324
- if existing .From == nil || existing .From .Kind != "DockerImage" {
325
- return nil , nil , fmt .Errorf ("tag %q already exists - you must use the 'tag' command if you want to change the source to %q" , tag , from )
326
- }
327
- if len (from ) != 0 && from != existing .From .Name {
328
- if multiple {
329
- return nil , nil , fmt .Errorf ("the tag %q points to the tag %q which points to %q - use the 'tag' command if you want to change the source to %q" , tag , finalTag , existing .From .Name , from )
330
- }
331
- return nil , nil , fmt .Errorf ("the tag %q points to %q - use the 'tag' command if you want to change the source to %q" , tag , existing .From .Name , from )
332
- }
330
+ // update ImageStream appropriately
331
+ if ok {
332
+ // disallow changing an existing tag
333
+ if existing .From == nil || existing .From .Kind != "DockerImage" {
334
+ return nil , fmt .Errorf ("tag %q already exists - you must use the 'tag' command if you want to change the source to %q" , tag , from )
335
+ }
336
+ if len (from ) != 0 && from != existing .From .Name {
337
+ if multiple {
338
+ return nil , fmt .Errorf ("the tag %q points to the tag %q which points to %q - use the 'tag' command if you want to change the source to %q" , tag , finalTag , existing .From .Name , from )
339
+ }
340
+ return nil , fmt .Errorf ("the tag %q points to %q - use the 'tag' command if you want to change the source to %q" , tag , existing .From .Name , from )
341
+ }
333
342
334
- // set the target item to import
335
- from = existing .From .Name
336
- if multiple {
337
- tag = finalTag
338
- }
343
+ // set the target item to import
344
+ from = existing .From .Name
345
+ if multiple {
346
+ tag = finalTag
347
+ }
339
348
340
- // clear the legacy annotation
341
- delete (existing .Annotations , imageapi .DockerImageRepositoryCheckAnnotation )
342
- // reset the generation
343
- zero := int64 (0 )
344
- existing .Generation = & zero
349
+ // clear the legacy annotation
350
+ delete (existing .Annotations , imageapi .DockerImageRepositoryCheckAnnotation )
351
+ // reset the generation
352
+ zero := int64 (0 )
353
+ existing .Generation = & zero
345
354
346
- } else {
347
- // create a new tag
348
- if len (from ) == 0 {
349
- from = stream .Spec .DockerImageRepository
350
- }
351
- // if the from is still empty this means there's no such tag defined
352
- // nor we can't create any from .spec.dockerImageRepository
353
- if len (from ) == 0 {
354
- return nil , nil , fmt .Errorf ("the tag %q does not exist on the image stream - choose an existing tag to import or use the 'tag' command to create a new tag" , tag )
355
- }
356
- existing = & imageapi.TagReference {
357
- From : & kapi.ObjectReference {
358
- Kind : "DockerImage" ,
359
- Name : from ,
360
- },
361
- }
362
- }
363
- stream .Spec .Tags [tag ] = * existing
355
+ } else {
356
+ // create a new tag
357
+ if len (from ) == 0 {
358
+ from = stream .Spec .DockerImageRepository
359
+ }
360
+ // if the from is still empty this means there's no such tag defined
361
+ // nor we can't create any from .spec.dockerImageRepository
362
+ if len (from ) == 0 {
363
+ return nil , fmt .Errorf ("the tag %q does not exist on the image stream - choose an existing tag to import or use the 'tag' command to create a new tag" , tag )
364
+ }
365
+ existing = & imageapi.TagReference {
366
+ From : & kapi.ObjectReference {
367
+ Kind : "DockerImage" ,
368
+ Name : from ,
369
+ },
364
370
}
365
371
}
372
+ stream .Spec .Tags [tag ] = * existing
366
373
374
+ // and create accompanying ImageStreamImport
375
+ return o .newImageStreamImportTags (stream , map [string ]string {tag : from }), nil
376
+ }
377
+
378
+ func (o * ImportImageOptions ) newImageStream () (* imageapi.ImageStream , * imageapi.ImageStreamImport ) {
379
+ from := o .From
380
+ tag := o .Tag
367
381
if len (from ) == 0 {
368
- // catch programmer error
369
- return nil , nil , fmt .Errorf ("unexpected error, from is empty" )
382
+ from = o .Target
383
+ }
384
+ var stream * imageapi.ImageStream
385
+ // create new ImageStream
386
+ if o .All {
387
+ stream = & imageapi.ImageStream {
388
+ ObjectMeta : kapi.ObjectMeta {Name : o .Name },
389
+ Spec : imageapi.ImageStreamSpec {DockerImageRepository : from },
390
+ }
391
+ } else {
392
+ stream = & imageapi.ImageStream {
393
+ ObjectMeta : kapi.ObjectMeta {Name : o .Name },
394
+ Spec : imageapi.ImageStreamSpec {
395
+ Tags : map [string ]imageapi.TagReference {
396
+ tag : {
397
+ From : & kapi.ObjectReference {
398
+ Kind : "DockerImage" ,
399
+ Name : from ,
400
+ },
401
+ },
402
+ },
403
+ },
404
+ }
405
+ }
406
+ // and accompanying ImageStreamImport
407
+ var isi * imageapi.ImageStreamImport
408
+ if o .All {
409
+ isi = o .newImageStreamImportAll (stream , from )
410
+ } else {
411
+ isi = o .newImageStreamImportTags (stream , map [string ]string {tag : from })
370
412
}
371
413
372
- // Attempt the new, direct import path
414
+ return stream , isi
415
+ }
416
+
417
+ func (o * ImportImageOptions ) newImageStreamImport (stream * imageapi.ImageStream ) (* imageapi.ImageStreamImport , bool ) {
373
418
isi := & imageapi.ImageStreamImport {
374
419
ObjectMeta : kapi.ObjectMeta {
375
420
Name : stream .Name ,
@@ -384,15 +429,26 @@ func (o *ImportImageOptions) createImageImport() (*imageapi.ImageStream, *imagea
384
429
if o .Insecure != nil {
385
430
insecure = * o .Insecure
386
431
}
387
- if o .All {
388
- isi .Spec .Repository = & imageapi.RepositoryImportSpec {
389
- From : kapi.ObjectReference {
390
- Kind : "DockerImage" ,
391
- Name : from ,
392
- },
393
- ImportPolicy : imageapi.TagImportPolicy {Insecure : insecure },
394
- }
395
- } else {
432
+
433
+ return isi , insecure
434
+ }
435
+
436
+ func (o * ImportImageOptions ) newImageStreamImportAll (stream * imageapi.ImageStream , from string ) * imageapi.ImageStreamImport {
437
+ isi , insecure := o .newImageStreamImport (stream )
438
+ isi .Spec .Repository = & imageapi.RepositoryImportSpec {
439
+ From : kapi.ObjectReference {
440
+ Kind : "DockerImage" ,
441
+ Name : from ,
442
+ },
443
+ ImportPolicy : imageapi.TagImportPolicy {Insecure : insecure },
444
+ }
445
+
446
+ return isi
447
+ }
448
+
449
+ func (o * ImportImageOptions ) newImageStreamImportTags (stream * imageapi.ImageStream , tags map [string ]string ) * imageapi.ImageStreamImport {
450
+ isi , insecure := o .newImageStreamImport (stream )
451
+ for tag , from := range tags {
396
452
isi .Spec .Images = append (isi .Spec .Images , imageapi.ImageImportSpec {
397
453
From : kapi.ObjectReference {
398
454
Kind : "DockerImage" ,
@@ -402,6 +458,5 @@ func (o *ImportImageOptions) createImageImport() (*imageapi.ImageStream, *imagea
402
458
ImportPolicy : imageapi.TagImportPolicy {Insecure : insecure },
403
459
})
404
460
}
405
-
406
- return stream , isi , nil
461
+ return isi
407
462
}
0 commit comments