@@ -29,6 +29,7 @@ import (
29
29
"github.com/openshift/origin/pkg/cmd/templates"
30
30
cmdutil "github.com/openshift/origin/pkg/cmd/util"
31
31
"github.com/openshift/origin/pkg/cmd/util/clientcmd"
32
+ deployapi "github.com/openshift/origin/pkg/deploy/api"
32
33
generateapp "github.com/openshift/origin/pkg/generate/app"
33
34
imageapi "github.com/openshift/origin/pkg/image/api"
34
35
)
@@ -394,18 +395,107 @@ func (o *DebugOptions) Debug() error {
394
395
})
395
396
}
396
397
397
- func (o * DebugOptions ) getContainerImageCommand (container * kapi.Container ) ([]string , error ) {
398
- image := container .Image [strings .LastIndex (container .Image , "/" )+ 1 :]
399
- name , id , ok := imageapi .SplitImageStreamImage (image )
400
- if ! ok {
401
- return nil , errors .New ("container image did not contain an id" )
398
+ // getContainerImageViaDeploymentConfig attempts to return an Image for a given
399
+ // Container. It tries to walk from the Container's Pod to its DeploymentConfig
400
+ // (via the "openshift.io/deployment-config.name" annotation), then tries to
401
+ // find the ImageStream from which the DeploymentConfig is deploying, then tries
402
+ // to find a match for the Container's image in the ImageStream's Images.
403
+ func (o * DebugOptions ) getContainerImageViaDeploymentConfig (pod * kapi.Pod , container * kapi.Container ) (* imageapi.Image , error ) {
404
+ ref , err := imageapi .ParseDockerImageReference (container .Image )
405
+ if err != nil {
406
+ return nil , err
407
+ }
408
+
409
+ if ref .ID == "" {
410
+ return nil , nil // ID is needed for later lookup
411
+ }
412
+
413
+ dcname := pod .Annotations [deployapi .DeploymentConfigAnnotation ]
414
+ if dcname == "" {
415
+ return nil , nil // Pod doesn't appear to have been created by a DeploymentConfig
416
+ }
417
+
418
+ dc , err := o .Client .DeploymentConfigs (o .Attach .Pod .Namespace ).Get (dcname )
419
+ if err != nil {
420
+ return nil , err
421
+ }
422
+
423
+ for _ , trigger := range dc .Spec .Triggers {
424
+ if trigger .Type == deployapi .DeploymentTriggerOnImageChange &&
425
+ trigger .ImageChangeParams != nil &&
426
+ trigger .ImageChangeParams .From .Kind == "ImageStreamTag" {
427
+
428
+ isname , _ , err := imageapi .ParseImageStreamTagName (trigger .ImageChangeParams .From .Name )
429
+ if err != nil {
430
+ return nil , err
431
+ }
432
+
433
+ namespace := trigger .ImageChangeParams .From .Namespace
434
+ if len (namespace ) == 0 {
435
+ namespace = o .Attach .Pod .Namespace
436
+ }
437
+
438
+ isi , err := o .Client .ImageStreamImages (namespace ).Get (isname , ref .ID )
439
+ if err != nil {
440
+ return nil , err
441
+ }
442
+
443
+ return & isi .Image , nil
444
+ }
445
+ }
446
+
447
+ return nil , nil // DeploymentConfig doesn't have an ImageChange Trigger
448
+ }
449
+
450
+ // getContainerImageViaImageStreamImport attempts to return an Image for a given
451
+ // Container. It does this by submiting a ImageStreamImport request with Import
452
+ // set to false. The request will not succeed if the backing repository
453
+ // requires Insecure to be set to true, which cannot be hard-coded for security
454
+ // reasons.
455
+ func (o * DebugOptions ) getContainerImageViaImageStreamImport (container * kapi.Container ) (* imageapi.Image , error ) {
456
+ isi := & imageapi.ImageStreamImport {
457
+ ObjectMeta : kapi.ObjectMeta {
458
+ Name : "oc-debug" ,
459
+ },
460
+ Spec : imageapi.ImageStreamImportSpec {
461
+ Images : []imageapi.ImageImportSpec {
462
+ {
463
+ From : kapi.ObjectReference {
464
+ Kind : "DockerImage" ,
465
+ Name : container .Image ,
466
+ },
467
+ },
468
+ },
469
+ },
402
470
}
403
- isimage , err := o .Client .ImageStreamImages (o .Attach .Pod .Namespace ).Get (name , id )
471
+
472
+ isi , err := o .Client .ImageStreams (o .Attach .Pod .Namespace ).Import (isi )
404
473
if err != nil {
405
474
return nil , err
406
475
}
407
476
408
- config := isimage .Image .DockerImageMetadata .Config
477
+ if len (isi .Status .Images ) > 0 {
478
+ return isi .Status .Images [0 ].Image , nil
479
+ }
480
+
481
+ return nil , nil
482
+ }
483
+
484
+ func (o * DebugOptions ) getContainerImageCommand (pod * kapi.Pod , container * kapi.Container ) ([]string , error ) {
485
+ if len (container .Command ) > 0 {
486
+ return container .Command , nil
487
+ }
488
+
489
+ image , _ := o .getContainerImageViaDeploymentConfig (pod , container )
490
+ if image == nil {
491
+ image , _ = o .getContainerImageViaImageStreamImport (container )
492
+ }
493
+
494
+ if image == nil || image .DockerImageMetadata .Config == nil {
495
+ return nil , errors .New ("error: no usable image found" )
496
+ }
497
+
498
+ config := image .DockerImageMetadata .Config
409
499
return append (config .Entrypoint , config .Cmd ... ), nil
410
500
}
411
501
@@ -421,13 +511,13 @@ func (o *DebugOptions) transformPodForDebug(annotations map[string]string) (*kap
421
511
container := containerForName (pod , o .Attach .ContainerName )
422
512
423
513
// identify the command to be run
424
- originalCommand := append (container .Command , container .Args ... )
425
- container .Command = o .Command
426
- if len (originalCommand ) == 0 {
427
- originalCommand , _ = o .getContainerImageCommand (container )
514
+ originalCommand , _ := o .getContainerImageCommand (pod , container )
515
+ if len (originalCommand ) > 0 {
516
+ originalCommand = append (originalCommand , container .Args ... )
428
517
}
429
- container .Args = nil
430
518
519
+ container .Command = o .Command
520
+ container .Args = nil
431
521
container .TTY = o .Attach .Stdin && o .Attach .TTY
432
522
container .Stdin = o .Attach .Stdin
433
523
container .StdinOnce = o .Attach .Stdin
0 commit comments