Skip to content

Commit b39afdb

Browse files
author
Romuald Atchadé
committed
Merge branch 'k8s-pod-event-on-failure'
Add warning events on failure with k8s executor Closes https://gitlab.com/gitlab-org/gitlab-runner/-/issues/31052 See merge request https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/4211 Merged-by: Romuald Atchadé <[email protected]> Approved-by: Axel von Bertoldi <[email protected]> Reviewed-by: Axel von Bertoldi <[email protected]>
2 parents f29584e + 5c4c6da commit b39afdb

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

executors/kubernetes/kubernetes.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ const (
8484
k8sResourcesNameSuffixLength = 8
8585
k8sResourcesNameMaxLength = 63
8686

87+
k8sEventWarningType = "Warning"
88+
8789
// errorDialingBackendMessage is an error prefix that is encountered when
8890
// connectivity to a Pod fails. This can happen for a number of reasons,
8991
// such as the Pod or Node still being configured.
@@ -448,6 +450,10 @@ func (s *executor) Run(cmd common.ExecutorCommand) error {
448450
err = s.runWithAttach(cmd)
449451
}
450452

453+
if err != nil {
454+
s.logPodWarningEvents(k8sEventWarningType)
455+
}
456+
451457
var imagePullErr *pull.ImagePullError
452458
if errors.As(err, &imagePullErr) {
453459
if s.pullManager.UpdatePolicyForImage(attempt, imagePullErr) {
@@ -460,6 +466,41 @@ func (s *executor) Run(cmd common.ExecutorCommand) error {
460466
}
461467
}
462468

469+
func (s *executor) logPodWarningEvents(eventType string) {
470+
if s.pod == nil {
471+
return
472+
}
473+
474+
var eventList *api.EventList
475+
r := retry.WithBuildLog(
476+
&retryableKubeAPICall{
477+
maxTries: defaultTries,
478+
fn: func() error {
479+
// TODO: handle the context properly with https://gitlab.com/gitlab-org/gitlab-runner/-/issues/27932
480+
el, err := s.kubeClient.CoreV1().Events(s.pod.Namespace).
481+
List(context.Background(), metav1.ListOptions{
482+
FieldSelector: fmt.Sprintf("involvedObject.name=%s,type=%s", s.pod.Name, eventType),
483+
})
484+
if err == nil {
485+
eventList = el
486+
}
487+
return err
488+
},
489+
},
490+
&s.BuildLogger,
491+
)
492+
retryable := retry.NewWithBackoffDuration(r, defaultRetryMinBackoff, defaultRetryMaxBackoff)
493+
err := retryable.Run()
494+
if err != nil {
495+
s.Errorln(fmt.Sprintf("Error retrieving events list: %s", err.Error()))
496+
return
497+
}
498+
499+
for _, event := range eventList.Items {
500+
s.Warningln(fmt.Sprintf("Event retrieved from the cluster: %s", event.Message))
501+
}
502+
}
503+
463504
func (s *executor) runWithExecLegacy(cmd common.ExecutorCommand) error {
464505
if s.pod == nil {
465506
err := s.setupCredentials()

executors/kubernetes/kubernetes_integration_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ func TestRunIntegrationTestsWithFeatureFlag(t *testing.T) {
133133
"testKubernetesLongLogsFeatureFlag": testKubernetesLongLogsFeatureFlag,
134134
"testKubernetesHugeScriptAndAfterScriptFeatureFlag": testKubernetesHugeScriptAndAfterScriptFeatureFlag,
135135
"testKubernetesCustomPodSpec": testKubernetesCustomPodSpec,
136+
"testKubernetesClusterWarningEvent": testKubernetesClusterWarningEvent,
136137
}
137138

138139
featureFlags := []string{
@@ -1565,6 +1566,47 @@ func testKubernetesWaitResources(t *testing.T, featureFlagName string, featureFl
15651566
}
15661567
}
15671568

1569+
func testKubernetesClusterWarningEvent(t *testing.T, featureFlagName string, featureFlagValue bool) {
1570+
helpers.SkipIntegrationTests(t, "kubectl", "cluster-info")
1571+
1572+
tests := map[string]struct {
1573+
image string
1574+
verifyFn func(*testing.T, string, error)
1575+
}{
1576+
"invalid image": {
1577+
image: "alpine333",
1578+
verifyFn: func(t *testing.T, out string, err error) {
1579+
assert.Error(t, err)
1580+
assert.Contains(
1581+
t,
1582+
out,
1583+
"WARNING: Event retrieved from the cluster: Failed to pull image \"alpine333\": rpc error:",
1584+
)
1585+
assert.Contains(t, out, "WARNING: Event retrieved from the cluster: Error: ErrImagePull")
1586+
assert.Contains(t, out, "WARNING: Event retrieved from the cluster: Error: ImagePullBackOff")
1587+
},
1588+
},
1589+
}
1590+
1591+
for tn, tc := range tests {
1592+
t.Run(tn, func(t *testing.T) {
1593+
build := getTestBuild(t, func() (common.JobResponse, error) {
1594+
jobResponse, err := common.GetRemoteBuildResponse(
1595+
"echo Hello World",
1596+
)
1597+
require.NoError(t, err)
1598+
1599+
return jobResponse, nil
1600+
})
1601+
build.Runner.Kubernetes.Image = tc.image
1602+
buildtest.SetBuildFeatureFlag(build, featureFlagName, featureFlagValue)
1603+
1604+
out, err := buildtest.RunBuildReturningOutput(t, build)
1605+
tc.verifyFn(t, out, err)
1606+
})
1607+
}
1608+
}
1609+
15681610
// TestLogDeletionAttach tests the outcome when the log files are all deleted
15691611
func TestLogDeletionAttach(t *testing.T) {
15701612
helpers.SkipIntegrationTests(t, "kubectl", "cluster-info")

0 commit comments

Comments
 (0)