Skip to content

Commit 629cebb

Browse files
authored
bugfix(k8s): avoid InspectContainer panic where container is not Terminated (#308)
1 parent 859dd37 commit 629cebb

File tree

3 files changed

+68
-18
lines changed

3 files changed

+68
-18
lines changed

runtime/kubernetes/container.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,24 @@ func (c *client) InspectContainer(ctx context.Context, ctn *pipeline.Container)
5454
continue
5555
}
5656

57+
// avoid a panic if the build ends without terminating all containers
58+
if cst.State.Terminated == nil {
59+
for _, container := range pod.Spec.Containers {
60+
if cst.Name != container.Name {
61+
continue
62+
}
63+
64+
// steps that were not executed will still be "running" the pause image as expected.
65+
if container.Image == pauseImage {
66+
return nil
67+
}
68+
69+
break
70+
}
71+
72+
return fmt.Errorf("expected container %s to be terminated, got %v", ctn.ID, cst.State)
73+
}
74+
5775
// set the step exit code
5876
ctn.ExitCode = int(cst.State.Terminated.ExitCode)
5977

@@ -122,7 +140,7 @@ func (c *client) SetupContainer(ctx context.Context, ctn *pipeline.Container) er
122140
// the containers with the proper image.
123141
//
124142
// https://hub.docker.com/r/kubernetes/pause
125-
Image: image.Parse("kubernetes/pause:latest"),
143+
Image: image.Parse(pauseImage),
126144
Env: []v1.EnvVar{},
127145
Stdin: false,
128146
StdinOnce: false,

runtime/kubernetes/container_test.go

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,42 +18,71 @@ import (
1818
)
1919

2020
func TestKubernetes_InspectContainer(t *testing.T) {
21-
// setup types
22-
_engine, err := NewMock(_pod)
23-
if err != nil {
24-
t.Errorf("unable to create runtime engine: %v", err)
25-
}
26-
2721
// setup tests
2822
tests := []struct {
23+
name string
2924
failure bool
25+
pod *v1.Pod
3026
container *pipeline.Container
3127
}{
3228
{
29+
name: "build container",
3330
failure: false,
31+
pod: _pod,
3432
container: _container,
3533
},
3634
{
35+
name: "empty build container",
3736
failure: false,
37+
pod: _pod,
3838
container: new(pipeline.Container),
3939
},
40+
{
41+
name: "container not terminated",
42+
failure: true,
43+
pod: &v1.Pod{
44+
ObjectMeta: _pod.ObjectMeta,
45+
TypeMeta: _pod.TypeMeta,
46+
Spec: _pod.Spec,
47+
Status: v1.PodStatus{
48+
Phase: v1.PodRunning,
49+
ContainerStatuses: []v1.ContainerStatus{
50+
{
51+
Name: "step-github-octocat-1-clone",
52+
State: v1.ContainerState{
53+
Running: &v1.ContainerStateRunning{},
54+
},
55+
},
56+
},
57+
},
58+
},
59+
container: _container,
60+
},
4061
}
4162

4263
// run tests
4364
for _, test := range tests {
44-
err = _engine.InspectContainer(context.Background(), test.container)
45-
46-
if test.failure {
47-
if err == nil {
48-
t.Errorf("InspectContainer should have returned err")
65+
t.Run(test.name, func(t *testing.T) {
66+
// setup types
67+
_engine, err := NewMock(test.pod)
68+
if err != nil {
69+
t.Errorf("unable to create runtime engine: %v", err)
4970
}
5071

51-
continue
52-
}
72+
err = _engine.InspectContainer(context.Background(), test.container)
5373

54-
if err != nil {
55-
t.Errorf("InspectContainer returned err: %v", err)
56-
}
74+
if test.failure {
75+
if err == nil {
76+
t.Errorf("InspectContainer should have returned err")
77+
}
78+
79+
return // effectively "continue" to next test
80+
}
81+
82+
if err != nil {
83+
t.Errorf("InspectContainer returned err: %v", err)
84+
}
85+
})
5786
}
5887
}
5988

runtime/kubernetes/image.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ import (
1414
"github.com/go-vela/types/pipeline"
1515
)
1616

17-
const imagePatch = `
17+
const (
18+
pauseImage = "kubernetes/pause:latest"
19+
imagePatch = `
1820
{
1921
"spec": {
2022
"containers": [
@@ -26,6 +28,7 @@ const imagePatch = `
2628
}
2729
}
2830
`
31+
)
2932

3033
// CreateImage creates the pipeline container image.
3134
func (c *client) CreateImage(ctx context.Context, ctn *pipeline.Container) error {

0 commit comments

Comments
 (0)