Skip to content

Commit 98ad752

Browse files
author
OpenShift Bot
authored
Merge pull request #12585 from jim-minter/issue12559-fix
Merged by openshift-bot
2 parents 7412065 + d9e63e0 commit 98ad752

File tree

4 files changed

+189
-36
lines changed

4 files changed

+189
-36
lines changed

pkg/cmd/cli/cmd/debug.go

+102-12
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/openshift/origin/pkg/cmd/templates"
3030
cmdutil "github.com/openshift/origin/pkg/cmd/util"
3131
"github.com/openshift/origin/pkg/cmd/util/clientcmd"
32+
deployapi "github.com/openshift/origin/pkg/deploy/api"
3233
generateapp "github.com/openshift/origin/pkg/generate/app"
3334
imageapi "github.com/openshift/origin/pkg/image/api"
3435
)
@@ -394,18 +395,107 @@ func (o *DebugOptions) Debug() error {
394395
})
395396
}
396397

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+
},
402470
}
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)
404473
if err != nil {
405474
return nil, err
406475
}
407476

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
409499
return append(config.Entrypoint, config.Cmd...), nil
410500
}
411501

@@ -421,13 +511,13 @@ func (o *DebugOptions) transformPodForDebug(annotations map[string]string) (*kap
421511
container := containerForName(pod, o.Attach.ContainerName)
422512

423513
// 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...)
428517
}
429-
container.Args = nil
430518

519+
container.Command = o.Command
520+
container.Args = nil
431521
container.TTY = o.Attach.Stdin && o.Attach.TTY
432522
container.Stdin = o.Attach.Stdin
433523
container.StdinOnce = o.Attach.Stdin

test/extended/builds/new_app.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import (
1010
var _ = g.Describe("[builds][Conformance] oc new-app", func() {
1111
// Previously, the maximum length of app names creatable by new-app has
1212
// inadvertently been decreased, e.g. by creating an annotation somewhere
13-
// whose name itself includes the app name. Ensure we can create and deploy
14-
// an app with a 58 character name [63 maximum - len('-9999' suffix)].
13+
// whose name itself includes the app name. Ensure we can create and fully
14+
// deploy an app with a 58 character name [63 maximum - len('-9999' suffix)].
1515

1616
oc := exutil.NewCLI("new-app", exutil.KubeConfigPath())
1717

test/extended/cli/debug.go

+16-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
exutil "github.com/openshift/origin/test/extended/util"
88
)
99

10-
var _ = g.Describe("[cli] oc debug", func() {
10+
var _ = g.Describe("[cli][Slow] oc debug", func() {
1111
oc := exutil.NewCLI("oc-debug", exutil.KubeConfigPath())
1212
templatePath := exutil.FixturePath("testdata", "test-cli-debug.yaml")
1313

@@ -20,17 +20,29 @@ var _ = g.Describe("[cli] oc debug", func() {
2020
err = oc.Run("create").Args("-f", templatePath).Execute()
2121
o.Expect(err).NotTo(o.HaveOccurred())
2222

23-
exutil.WaitForAnImageStreamTag(oc, oc.Namespace(), "busybox", "latest")
23+
exutil.WaitForAnImageStreamTag(oc, oc.Namespace(), "local-busybox", "latest")
2424
o.Expect(err).NotTo(o.HaveOccurred())
2525
})
2626

27-
g.It("should print the container entrypoint/command", func() {
27+
g.It("should print the imagestream-based container entrypoint/command", func() {
28+
out, err := oc.Run("debug").Args("dc/local-busybox1").Output()
29+
o.Expect(err).NotTo(o.HaveOccurred())
30+
o.Expect(out).To(o.ContainSubstring("Debugging with pod/local-busybox1-debug, original command: sh\n"))
31+
})
32+
33+
g.It("should print the overridden imagestream-based container entrypoint/command", func() {
34+
out, err := oc.Run("debug").Args("dc/local-busybox2").Output()
35+
o.Expect(err).NotTo(o.HaveOccurred())
36+
o.Expect(out).To(o.ContainSubstring("Debugging with pod/local-busybox2-debug, original command: foo bar baz qux\n"))
37+
})
38+
39+
g.It("should print the docker image-based container entrypoint/command", func() {
2840
out, err := oc.Run("debug").Args("dc/busybox1").Output()
2941
o.Expect(err).NotTo(o.HaveOccurred())
3042
o.Expect(out).To(o.ContainSubstring("Debugging with pod/busybox1-debug, original command: sh\n"))
3143
})
3244

33-
g.It("should print the overridden container entrypoint/command", func() {
45+
g.It("should print the overridden docker image-based container entrypoint/command", func() {
3446
out, err := oc.Run("debug").Args("dc/busybox2").Output()
3547
o.Expect(err).NotTo(o.HaveOccurred())
3648
o.Expect(out).To(o.ContainSubstring("Debugging with pod/busybox2-debug, original command: foo bar baz qux\n"))

test/extended/testdata/test-cli-debug.yaml

+69-18
Original file line numberDiff line numberDiff line change
@@ -4,54 +4,65 @@ items:
44
- kind: ImageStream
55
apiVersion: v1
66
metadata:
7-
name: busybox
7+
name: local-busybox
8+
9+
- kind: BuildConfig
10+
apiVersion: v1
11+
metadata:
12+
name: local-busybox
813
spec:
9-
tags:
10-
- name: latest
11-
from:
12-
name: busybox
13-
kind: DockerImage
14+
strategy:
15+
type: Docker
16+
source:
17+
type: Git
18+
dockerfile: "FROM busybox:latest\n"
19+
output:
20+
to:
21+
kind: ImageStreamTag
22+
name: local-busybox:latest
23+
triggers:
24+
- type: ConfigChange
1425

1526
- kind: DeploymentConfig
1627
apiVersion: v1
1728
metadata:
18-
name: busybox1
29+
name: local-busybox1
1930
spec:
2031
replicas: 0
2132
selector:
22-
deploymentconfig: busybox1
33+
deploymentconfig: local-busybox1
2334
template:
2435
metadata:
2536
labels:
26-
deploymentconfig: busybox1
37+
deploymentconfig: local-busybox1
2738
spec:
2839
containers:
29-
- name: busybox
40+
- name: local-busybox
3041
triggers:
3142
- type: ImageChange
3243
imageChangeParams:
3344
automatic: true
3445
containerNames:
35-
- busybox
46+
- local-busybox
3647
from:
37-
name: busybox:latest
3848
kind: ImageStreamTag
49+
name: local-busybox:latest
3950

4051
- kind: DeploymentConfig
4152
apiVersion: v1
4253
metadata:
43-
name: busybox2
54+
name: local-busybox2
4455
spec:
4556
replicas: 0
4657
selector:
47-
deploymentconfig: busybox2
58+
deploymentconfig: local-busybox2
4859
template:
4960
metadata:
5061
labels:
51-
deploymentconfig: busybox2
62+
deploymentconfig: local-busybox2
5263
spec:
5364
containers:
54-
- name: busybox
65+
- name: local-busybox
5566
command:
5667
- foo
5768
- bar
@@ -63,7 +74,47 @@ items:
6374
imageChangeParams:
6475
automatic: true
6576
containerNames:
66-
- busybox
77+
- local-busybox
6778
from:
68-
name: busybox:latest
6979
kind: ImageStreamTag
80+
name: local-busybox:latest
81+
82+
- kind: DeploymentConfig
83+
apiVersion: v1
84+
metadata:
85+
name: busybox1
86+
spec:
87+
replicas: 0
88+
selector:
89+
deploymentconfig: busybox1
90+
template:
91+
metadata:
92+
labels:
93+
deploymentconfig: busybox1
94+
spec:
95+
containers:
96+
- name: busybox
97+
image: busybox
98+
99+
- kind: DeploymentConfig
100+
apiVersion: v1
101+
metadata:
102+
name: busybox2
103+
spec:
104+
replicas: 0
105+
selector:
106+
deploymentconfig: busybox2
107+
template:
108+
metadata:
109+
labels:
110+
deploymentconfig: busybox2
111+
spec:
112+
containers:
113+
- name: busybox
114+
image: busybox
115+
command:
116+
- foo
117+
- bar
118+
args:
119+
- baz
120+
- qux

0 commit comments

Comments
 (0)