Skip to content

Commit 1462117

Browse files
committed
generate build state events
1 parent d521c48 commit 1462117

File tree

9 files changed

+102
-3
lines changed

9 files changed

+102
-3
lines changed

pkg/build/api/types.go

+17
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,23 @@ const (
6363
// forces the build to be processed by the build controller queue without waiting
6464
// for a resync.
6565
BuildAcceptedAnnotation = "build.openshift.io/accepted"
66+
67+
// BuildStartedEventReason is the reason associated with the event registered when a build is started (pod is created).
68+
BuildStartedEventReason = "BuildStarted"
69+
// BuildStartedEventMessage is the message associated with the event registered when a build is started (pod is created).
70+
BuildStartedEventMessage = "Build %s/%s is now running"
71+
// BuildCompletedEventReason is the reason associated with the event registered when build completes successfully.
72+
BuildCompletedEventReason = "BuildCompleted"
73+
// BuildCompletedEventMessage is the message associated with the event registered when build completes successfully.
74+
BuildCompletedEventMessage = "Build %s/%s completed successfully"
75+
// BuildFailedEventReason is the reason associated with the event registered when build fails.
76+
BuildFailedEventReason = "BuildFailed"
77+
// BuildFailedEventMessage is the message associated with the event registered when build fails.
78+
BuildFailedEventMessage = "Build %s/%s failed"
79+
// BuildCancelledEventReason is the reason associated with the event registered when build is cancelled.
80+
BuildCancelledEventReason = "BuildCancelled"
81+
// BuildCancelledEventMessage is the message associated with the event registered when build is cancelled.
82+
BuildCancelledEventMessage = "Build %s/%s has been cancelled"
6683
)
6784

6885
// +genclient=true

pkg/build/client/clients.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ type BuildLister interface {
4747
List(namespace string, opts kapi.ListOptions) (*buildapi.BuildList, error)
4848
}
4949

50-
// OSClientBuildClient deletes build create and update operations to the OpenShift client interface
50+
// OSClientBuildClient delegates build create and update operations to the OpenShift client interface
5151
type OSClientBuildClient struct {
5252
Client osclient.Interface
5353
}

pkg/build/controller/buildpod/controller.go

+16
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"k8s.io/kubernetes/pkg/client/cache"
1212
kclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
1313
kcoreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
14+
"k8s.io/kubernetes/pkg/client/record"
1415
kcontroller "k8s.io/kubernetes/pkg/controller"
1516
utilruntime "k8s.io/kubernetes/pkg/util/runtime"
1617
"k8s.io/kubernetes/pkg/util/wait"
@@ -49,16 +50,22 @@ type BuildPodController struct {
4950
podStoreSynced func() bool
5051

5152
runPolicies []policy.RunPolicy
53+
54+
recorder record.EventRecorder
5255
}
5356

5457
// NewBuildPodController creates a new BuildPodController.
5558
func NewBuildPodController(buildInformer, podInformer cache.SharedIndexInformer, kc kclientset.Interface, oc osclient.Interface) *BuildPodController {
59+
eventBroadcaster := record.NewBroadcaster()
60+
eventBroadcaster.StartRecordingToSink(&kcoreclient.EventSinkImpl{Interface: kc.Core().Events("")})
61+
5662
buildListerUpdater := buildclient.NewOSClientBuildClient(oc)
5763
c := &BuildPodController{
5864
buildUpdater: buildListerUpdater,
5965
secretClient: kc.Core(), // TODO: Replace with cache client
6066
podClient: kc.Core(),
6167
queue: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()),
68+
recorder: eventBroadcaster.NewRecorder(kapi.EventSource{Component: "build-pod-controller"}),
6269
}
6370

6471
c.runPolicies = policy.GetAllRunPolicies(buildListerUpdater, buildListerUpdater)
@@ -197,6 +204,7 @@ func (bc *BuildPodController) HandlePod(pod *kapi.Pod) error {
197204
if build.Status.Phase == buildapi.BuildPhaseRunning {
198205
now := unversioned.Now()
199206
build.Status.StartTimestamp = &now
207+
bc.recorder.Eventf(build, kapi.EventTypeNormal, buildapi.BuildStartedEventReason, fmt.Sprintf(buildapi.BuildStartedEventMessage, build.Namespace, build.Name))
200208
}
201209
}
202210

@@ -218,6 +226,12 @@ func (bc *BuildPodController) HandlePod(pod *kapi.Pod) error {
218226
// handle completion for it. otherwise ignore it because we've already
219227
// handled its completion previously.
220228
if !buildWasComplete && buildutil.IsBuildComplete(build) {
229+
switch build.Status.Phase {
230+
case buildapi.BuildPhaseComplete:
231+
bc.recorder.Eventf(build, kapi.EventTypeNormal, buildapi.BuildCompletedEventReason, fmt.Sprintf(buildapi.BuildCompletedEventMessage, build.Namespace, build.Name))
232+
case buildapi.BuildPhaseError, buildapi.BuildPhaseFailed:
233+
bc.recorder.Eventf(build, kapi.EventTypeNormal, buildapi.BuildFailedEventReason, fmt.Sprintf(buildapi.BuildFailedEventMessage, build.Namespace, build.Name))
234+
}
221235
common.HandleBuildCompletion(build, bc.runPolicies)
222236
}
223237

@@ -259,6 +273,8 @@ func (bc *BuildPodController) HandleBuildPodDeletion(pod *kapi.Pod) error {
259273
build.Status.Reason = buildapi.StatusReasonBuildPodDeleted
260274
build.Status.Message = buildapi.StatusMessageBuildPodDeleted
261275
common.SetBuildCompletionTimeAndDuration(build)
276+
bc.recorder.Eventf(build, kapi.EventTypeNormal, buildapi.BuildFailedEventReason, fmt.Sprintf(buildapi.BuildFailedEventMessage, build.Namespace, build.Name))
277+
262278
if err := bc.buildUpdater.Update(build.Namespace, build); err != nil {
263279
return fmt.Errorf("Failed to update build %s/%s: %v", build.Namespace, build.Name, err)
264280
}

pkg/build/controller/controller.go

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ func (bc *BuildController) CancelBuild(build *buildapi.Build) error {
7272

7373
build.Status.Phase = buildapi.BuildPhaseCancelled
7474
common.SetBuildCompletionTimeAndDuration(build)
75+
bc.Recorder.Eventf(build, kapi.EventTypeNormal, buildapi.BuildCancelledEventReason, fmt.Sprintf(buildapi.BuildCancelledEventMessage, build.Namespace, build.Name))
7576
// set the status details for the cancelled build before updating the build
7677
// object.
7778
build.Status.Reason = buildapi.StatusReasonCancelledBuild

test/common/build/controllers.go

+18
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,24 @@ func RunBuildRunningPodDeleteTest(t testingT, clusterAdminClient *client.Client,
624624
if newBuild.Status.Phase != buildapi.BuildPhaseError {
625625
t.Fatalf("expected build status to be marked error, but was marked %s", newBuild.Status.Phase)
626626
}
627+
events, err := clusterAdminKubeClientset.Core().Events(testutil.Namespace()).Search(newBuild)
628+
if err != nil {
629+
t.Fatalf("error getting build events: %v", err)
630+
}
631+
foundFailed := false
632+
for _, event := range events.Items {
633+
if event.Reason == buildapi.BuildFailedEventReason {
634+
foundFailed = true
635+
expect := fmt.Sprintf(buildapi.BuildFailedEventMessage, newBuild.Namespace, newBuild.Name)
636+
if event.Message != expect {
637+
t.Fatalf("expected failed event message to be %s, got %s", expect, event.Message)
638+
}
639+
break
640+
}
641+
}
642+
if !foundFailed {
643+
t.Fatalf("expected to find a failed event on the build %s/%s", newBuild.Namespace, newBuild.Name)
644+
}
627645
}
628646

629647
func RunBuildCompletePodDeleteTest(t testingT, clusterAdminClient *client.Client, clusterAdminKubeClientset *kclientset.Clientset) {

test/extended/builds/failure_status.go

+16
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ var _ = g.Describe("[builds][Slow] update failure status", func() {
5353
o.Expect(err).NotTo(o.HaveOccurred())
5454
o.Expect(build.Status.Reason).To(o.Equal(buildapi.StatusReasonPostCommitHookFailed))
5555
o.Expect(build.Status.Message).To(o.Equal(buildapi.StatusMessagePostCommitHookFailed))
56+
57+
exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildFailedEventReason, buildapi.BuildFailedEventMessage)
5658
})
5759
})
5860

@@ -70,6 +72,8 @@ var _ = g.Describe("[builds][Slow] update failure status", func() {
7072
o.Expect(err).NotTo(o.HaveOccurred())
7173
o.Expect(build.Status.Reason).To(o.Equal(buildapi.StatusReasonFetchSourceFailed))
7274
o.Expect(build.Status.Message).To(o.Equal(buildapi.StatusMessageFetchSourceFailed))
75+
76+
exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildFailedEventReason, buildapi.BuildFailedEventMessage)
7377
})
7478
})
7579

@@ -87,6 +91,8 @@ var _ = g.Describe("[builds][Slow] update failure status", func() {
8791
o.Expect(err).NotTo(o.HaveOccurred())
8892
o.Expect(build.Status.Reason).To(o.Equal(buildapi.StatusReasonFetchSourceFailed))
8993
o.Expect(build.Status.Message).To(o.Equal(buildapi.StatusMessageFetchSourceFailed))
94+
95+
exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildFailedEventReason, buildapi.BuildFailedEventMessage)
9096
})
9197
})
9298

@@ -104,6 +110,8 @@ var _ = g.Describe("[builds][Slow] update failure status", func() {
104110
o.Expect(err).NotTo(o.HaveOccurred())
105111
o.Expect(build.Status.Reason).To(o.Equal(buildapi.StatusReasonPullBuilderImageFailed))
106112
o.Expect(build.Status.Message).To(o.Equal(buildapi.StatusMessagePullBuilderImageFailed))
113+
114+
exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildFailedEventReason, buildapi.BuildFailedEventMessage)
107115
})
108116
})
109117

@@ -121,6 +129,8 @@ var _ = g.Describe("[builds][Slow] update failure status", func() {
121129
o.Expect(err).NotTo(o.HaveOccurred())
122130
o.Expect(build.Status.Reason).To(o.Equal(buildapi.StatusReasonPushImageToRegistryFailed))
123131
o.Expect(build.Status.Message).To(o.Equal(buildapi.StatusMessagePushImageToRegistryFailed))
132+
133+
exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildFailedEventReason, buildapi.BuildFailedEventMessage)
124134
})
125135
})
126136

@@ -138,6 +148,8 @@ var _ = g.Describe("[builds][Slow] update failure status", func() {
138148
o.Expect(err).NotTo(o.HaveOccurred())
139149
o.Expect(build.Status.Reason).To(o.Equal(reasonAssembleFailed))
140150
o.Expect(build.Status.Message).To(o.Equal(messageAssembleFailed))
151+
152+
exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildFailedEventReason, buildapi.BuildFailedEventMessage)
141153
})
142154
})
143155

@@ -155,6 +167,8 @@ var _ = g.Describe("[builds][Slow] update failure status", func() {
155167
o.Expect(err).NotTo(o.HaveOccurred())
156168
o.Expect(build.Status.Reason).To(o.Equal(reasonFetchRuntimeArtifacts))
157169
o.Expect(build.Status.Message).To(o.Equal(messageFetchRuntimeArtifacts))
170+
171+
exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildFailedEventReason, buildapi.BuildFailedEventMessage)
158172
})
159173
})
160174

@@ -172,6 +186,8 @@ var _ = g.Describe("[builds][Slow] update failure status", func() {
172186
o.Expect(err).NotTo(o.HaveOccurred())
173187
o.Expect(build.Status.Reason).To(o.Equal(buildapi.StatusReasonGenericBuildFailed))
174188
o.Expect(build.Status.Message).To(o.Equal(buildapi.StatusMessageGenericBuildFailed))
189+
190+
exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildFailedEventReason, buildapi.BuildFailedEventMessage)
175191
})
176192
})
177193
})

test/extended/builds/s2i_quota.go

+9
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
g "github.com/onsi/ginkgo"
77
o "github.com/onsi/gomega"
88

9+
buildapi "github.com/openshift/origin/pkg/build/api"
910
exutil "github.com/openshift/origin/test/extended/util"
1011
)
1112

@@ -52,6 +53,14 @@ var _ = g.Describe("[builds][Conformance] s2i build with a quota", func() {
5253
o.Expect(buildLog).To(o.ContainSubstring("SHARES=61"))
5354
o.Expect(buildLog).To(o.ContainSubstring("PERIOD=100000"))
5455
o.Expect(buildLog).To(o.ContainSubstring("QUOTA=6000"))
56+
57+
events, err := oc.KubeClient().Core().Events(oc.Namespace()).Search(br.Build)
58+
o.Expect(err).NotTo(o.HaveOccurred(), "Should be able to get events from the build")
59+
o.Expect(events).NotTo(o.BeNil(), "Build event list should not be nil")
60+
61+
exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildStartedEventReason, buildapi.BuildStartedEventMessage)
62+
exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildCompletedEventReason, buildapi.BuildCompletedEventMessage)
63+
5564
})
5665
})
5766
})

test/extended/builds/start.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,11 @@ var _ = g.Describe("[builds][Slow] starting a build using CLI", func() {
216216
err := exutil.WaitForABuild(oc.Client().Builds(oc.Namespace()), "sample-build-binary-invalidnodeselector-1", nil, nil, cancelFn)
217217
o.Expect(err).NotTo(o.HaveOccurred())
218218
o.Expect(build.Status.Phase).To(o.Equal(buildapi.BuildPhaseCancelled))
219+
exutil.CheckForBuildEvent(oc.KubeClient().Core(), build, buildapi.BuildCancelledEventReason, buildapi.BuildCancelledEventMessage)
219220
})
220221
})
221222

222-
g.Describe("cancelling build started by oc start-build --wait", func() {
223+
g.Describe("cancel a build started by oc start-build --wait", func() {
223224
g.It("should start a build and wait for the build to cancel", func() {
224225
g.By("starting the build with --wait flag")
225226
var wg sync.WaitGroup
@@ -247,11 +248,16 @@ var _ = g.Describe("[builds][Slow] starting a build using CLI", func() {
247248
})
248249

249250
o.Expect(buildName).ToNot(o.BeEmpty())
251+
build, err := oc.Client().Builds(oc.Namespace()).Get(buildName)
252+
o.Expect(err).NotTo(o.HaveOccurred())
253+
o.Expect(build).NotTo(o.BeNil(), "build object should exist")
250254

251255
g.By(fmt.Sprintf("cancelling the build %q", buildName))
252-
err := oc.Run("cancel-build").Args(buildName).Execute()
256+
err = oc.Run("cancel-build").Args(buildName).Execute()
253257
o.Expect(err).ToNot(o.HaveOccurred())
254258
wg.Wait()
259+
exutil.CheckForBuildEvent(oc.KubeClient().Core(), build, buildapi.BuildCancelledEventReason, buildapi.BuildCancelledEventMessage)
260+
255261
})
256262

257263
})

test/extended/util/framework.go

+16
Original file line numberDiff line numberDiff line change
@@ -1400,3 +1400,19 @@ func CreateExecPodOnNode(client kcoreclient.CoreInterface, ns, nodeName, name st
14001400
o.Expect(err).NotTo(o.HaveOccurred())
14011401
return created.Name
14021402
}
1403+
1404+
func CheckForBuildEvent(client kcoreclient.CoreInterface, build *buildapi.Build, reason, message string) {
1405+
events, err := client.Events(build.Namespace).Search(build)
1406+
o.ExpectWithOffset(1, err).NotTo(o.HaveOccurred(), "Should be able to get events from the build")
1407+
o.ExpectWithOffset(1, events).NotTo(o.BeNil(), "Build event list should not be nil")
1408+
1409+
found := false
1410+
for _, event := range events.Items {
1411+
framework.Logf("Found event %#v", event)
1412+
if reason == event.Reason {
1413+
found = true
1414+
o.ExpectWithOffset(1, event.Message).To(o.Equal(fmt.Sprintf(message, build.Namespace, build.Name)))
1415+
}
1416+
}
1417+
o.ExpectWithOffset(1, found).To(o.BeTrue(), "Did not find a %q event on build %s/%s", reason, build.Namespace, build.Name)
1418+
}

0 commit comments

Comments
 (0)