Skip to content

generate build state events #13660

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions pkg/build/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,23 @@ const (
// forces the build to be processed by the build controller queue without waiting
// for a resync.
BuildAcceptedAnnotation = "build.openshift.io/accepted"

// BuildStartedEventReason is the reason associated with the event registered when a build is started (pod is created).
BuildStartedEventReason = "BuildStarted"
// BuildStartedEventMessage is the message associated with the event registered when a build is started (pod is created).
BuildStartedEventMessage = "Build %s/%s is now running"
// BuildCompletedEventReason is the reason associated with the event registered when build completes successfully.
BuildCompletedEventReason = "BuildCompleted"
// BuildCompletedEventMessage is the message associated with the event registered when build completes successfully.
BuildCompletedEventMessage = "Build %s/%s completed successfully"
// BuildFailedEventReason is the reason associated with the event registered when build fails.
BuildFailedEventReason = "BuildFailed"
// BuildFailedEventMessage is the message associated with the event registered when build fails.
BuildFailedEventMessage = "Build %s/%s failed"
// BuildCancelledEventReason is the reason associated with the event registered when build is cancelled.
BuildCancelledEventReason = "BuildCancelled"
// BuildCancelledEventMessage is the message associated with the event registered when build is cancelled.
BuildCancelledEventMessage = "Build %s/%s has been cancelled"
)

// +genclient=true
Expand Down
2 changes: 1 addition & 1 deletion pkg/build/client/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ type BuildLister interface {
List(namespace string, opts kapi.ListOptions) (*buildapi.BuildList, error)
}

// OSClientBuildClient deletes build create and update operations to the OpenShift client interface
// OSClientBuildClient delegates build create and update operations to the OpenShift client interface
type OSClientBuildClient struct {
Client osclient.Interface
}
Expand Down
16 changes: 16 additions & 0 deletions pkg/build/controller/buildpod/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"k8s.io/kubernetes/pkg/client/cache"
kclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
kcoreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
"k8s.io/kubernetes/pkg/client/record"
kcontroller "k8s.io/kubernetes/pkg/controller"
utilruntime "k8s.io/kubernetes/pkg/util/runtime"
"k8s.io/kubernetes/pkg/util/wait"
Expand Down Expand Up @@ -49,16 +50,22 @@ type BuildPodController struct {
podStoreSynced func() bool

runPolicies []policy.RunPolicy

recorder record.EventRecorder
}

// NewBuildPodController creates a new BuildPodController.
func NewBuildPodController(buildInformer, podInformer cache.SharedIndexInformer, kc kclientset.Interface, oc osclient.Interface) *BuildPodController {
eventBroadcaster := record.NewBroadcaster()
eventBroadcaster.StartRecordingToSink(&kcoreclient.EventSinkImpl{Interface: kc.Core().Events("")})

buildListerUpdater := buildclient.NewOSClientBuildClient(oc)
c := &BuildPodController{
buildUpdater: buildListerUpdater,
secretClient: kc.Core(), // TODO: Replace with cache client
podClient: kc.Core(),
queue: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()),
recorder: eventBroadcaster.NewRecorder(kapi.EventSource{Component: "build-pod-controller"}),
}

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

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

Expand Down Expand Up @@ -259,6 +273,8 @@ func (bc *BuildPodController) HandleBuildPodDeletion(pod *kapi.Pod) error {
build.Status.Reason = buildapi.StatusReasonBuildPodDeleted
build.Status.Message = buildapi.StatusMessageBuildPodDeleted
common.SetBuildCompletionTimeAndDuration(build)
bc.recorder.Eventf(build, kapi.EventTypeNormal, buildapi.BuildFailedEventReason, fmt.Sprintf(buildapi.BuildFailedEventMessage, build.Namespace, build.Name))

if err := bc.buildUpdater.Update(build.Namespace, build); err != nil {
return fmt.Errorf("Failed to update build %s/%s: %v", build.Namespace, build.Name, err)
}
Expand Down
1 change: 1 addition & 0 deletions pkg/build/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ func (bc *BuildController) CancelBuild(build *buildapi.Build) error {

build.Status.Phase = buildapi.BuildPhaseCancelled
common.SetBuildCompletionTimeAndDuration(build)
bc.Recorder.Eventf(build, kapi.EventTypeNormal, buildapi.BuildCancelledEventReason, fmt.Sprintf(buildapi.BuildCancelledEventMessage, build.Namespace, build.Name))
// set the status details for the cancelled build before updating the build
// object.
build.Status.Reason = buildapi.StatusReasonCancelledBuild
Expand Down
18 changes: 18 additions & 0 deletions test/common/build/controllers.go
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,24 @@ func RunBuildRunningPodDeleteTest(t testingT, clusterAdminClient *client.Client,
if newBuild.Status.Phase != buildapi.BuildPhaseError {
t.Fatalf("expected build status to be marked error, but was marked %s", newBuild.Status.Phase)
}
events, err := clusterAdminKubeClientset.Core().Events(testutil.Namespace()).Search(newBuild)
if err != nil {
t.Fatalf("error getting build events: %v", err)
}
foundFailed := false
for _, event := range events.Items {
if event.Reason == buildapi.BuildFailedEventReason {
foundFailed = true
expect := fmt.Sprintf(buildapi.BuildFailedEventMessage, newBuild.Namespace, newBuild.Name)
if event.Message != expect {
t.Fatalf("expected failed event message to be %s, got %s", expect, event.Message)
}
break
}
}
if !foundFailed {
t.Fatalf("expected to find a failed event on the build %s/%s", newBuild.Namespace, newBuild.Name)
}
}

func RunBuildCompletePodDeleteTest(t testingT, clusterAdminClient *client.Client, clusterAdminKubeClientset *kclientset.Clientset) {
Expand Down
16 changes: 16 additions & 0 deletions test/extended/builds/failure_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ var _ = g.Describe("[builds][Slow] update failure status", func() {
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(build.Status.Reason).To(o.Equal(buildapi.StatusReasonPostCommitHookFailed))
o.Expect(build.Status.Message).To(o.Equal(buildapi.StatusMessagePostCommitHookFailed))

exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildFailedEventReason, buildapi.BuildFailedEventMessage)
})
})

Expand All @@ -70,6 +72,8 @@ var _ = g.Describe("[builds][Slow] update failure status", func() {
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(build.Status.Reason).To(o.Equal(buildapi.StatusReasonFetchSourceFailed))
o.Expect(build.Status.Message).To(o.Equal(buildapi.StatusMessageFetchSourceFailed))

exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildFailedEventReason, buildapi.BuildFailedEventMessage)
})
})

Expand All @@ -87,6 +91,8 @@ var _ = g.Describe("[builds][Slow] update failure status", func() {
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(build.Status.Reason).To(o.Equal(buildapi.StatusReasonFetchSourceFailed))
o.Expect(build.Status.Message).To(o.Equal(buildapi.StatusMessageFetchSourceFailed))

exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildFailedEventReason, buildapi.BuildFailedEventMessage)
})
})

Expand All @@ -104,6 +110,8 @@ var _ = g.Describe("[builds][Slow] update failure status", func() {
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(build.Status.Reason).To(o.Equal(buildapi.StatusReasonPullBuilderImageFailed))
o.Expect(build.Status.Message).To(o.Equal(buildapi.StatusMessagePullBuilderImageFailed))

exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildFailedEventReason, buildapi.BuildFailedEventMessage)
})
})

Expand All @@ -121,6 +129,8 @@ var _ = g.Describe("[builds][Slow] update failure status", func() {
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(build.Status.Reason).To(o.Equal(buildapi.StatusReasonPushImageToRegistryFailed))
o.Expect(build.Status.Message).To(o.Equal(buildapi.StatusMessagePushImageToRegistryFailed))

exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildFailedEventReason, buildapi.BuildFailedEventMessage)
})
})

Expand All @@ -138,6 +148,8 @@ var _ = g.Describe("[builds][Slow] update failure status", func() {
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(build.Status.Reason).To(o.Equal(reasonAssembleFailed))
o.Expect(build.Status.Message).To(o.Equal(messageAssembleFailed))

exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildFailedEventReason, buildapi.BuildFailedEventMessage)
})
})

Expand All @@ -155,6 +167,8 @@ var _ = g.Describe("[builds][Slow] update failure status", func() {
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(build.Status.Reason).To(o.Equal(reasonFetchRuntimeArtifacts))
o.Expect(build.Status.Message).To(o.Equal(messageFetchRuntimeArtifacts))

exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildFailedEventReason, buildapi.BuildFailedEventMessage)
})
})

Expand All @@ -172,6 +186,8 @@ var _ = g.Describe("[builds][Slow] update failure status", func() {
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(build.Status.Reason).To(o.Equal(buildapi.StatusReasonGenericBuildFailed))
o.Expect(build.Status.Message).To(o.Equal(buildapi.StatusMessageGenericBuildFailed))

exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildFailedEventReason, buildapi.BuildFailedEventMessage)
})
})
})
9 changes: 9 additions & 0 deletions test/extended/builds/s2i_quota.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
g "github.com/onsi/ginkgo"
o "github.com/onsi/gomega"

buildapi "github.com/openshift/origin/pkg/build/api"
exutil "github.com/openshift/origin/test/extended/util"
)

Expand Down Expand Up @@ -52,6 +53,14 @@ var _ = g.Describe("[builds][Conformance] s2i build with a quota", func() {
o.Expect(buildLog).To(o.ContainSubstring("SHARES=61"))
o.Expect(buildLog).To(o.ContainSubstring("PERIOD=100000"))
o.Expect(buildLog).To(o.ContainSubstring("QUOTA=6000"))

events, err := oc.KubeClient().Core().Events(oc.Namespace()).Search(br.Build)
o.Expect(err).NotTo(o.HaveOccurred(), "Should be able to get events from the build")
o.Expect(events).NotTo(o.BeNil(), "Build event list should not be nil")

exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildStartedEventReason, buildapi.BuildStartedEventMessage)
exutil.CheckForBuildEvent(oc.KubeClient().Core(), br.Build, buildapi.BuildCompletedEventReason, buildapi.BuildCompletedEventMessage)

})
})
})
10 changes: 8 additions & 2 deletions test/extended/builds/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,11 @@ var _ = g.Describe("[builds][Slow] starting a build using CLI", func() {
err := exutil.WaitForABuild(oc.Client().Builds(oc.Namespace()), "sample-build-binary-invalidnodeselector-1", nil, nil, cancelFn)
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(build.Status.Phase).To(o.Equal(buildapi.BuildPhaseCancelled))
exutil.CheckForBuildEvent(oc.KubeClient().Core(), build, buildapi.BuildCancelledEventReason, buildapi.BuildCancelledEventMessage)
})
})

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

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

g.By(fmt.Sprintf("cancelling the build %q", buildName))
err := oc.Run("cancel-build").Args(buildName).Execute()
err = oc.Run("cancel-build").Args(buildName).Execute()
o.Expect(err).ToNot(o.HaveOccurred())
wg.Wait()
exutil.CheckForBuildEvent(oc.KubeClient().Core(), build, buildapi.BuildCancelledEventReason, buildapi.BuildCancelledEventMessage)

})

})
Expand Down
16 changes: 16 additions & 0 deletions test/extended/util/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -1400,3 +1400,19 @@ func CreateExecPodOnNode(client kcoreclient.CoreInterface, ns, nodeName, name st
o.Expect(err).NotTo(o.HaveOccurred())
return created.Name
}

func CheckForBuildEvent(client kcoreclient.CoreInterface, build *buildapi.Build, reason, message string) {
events, err := client.Events(build.Namespace).Search(build)
o.ExpectWithOffset(1, err).NotTo(o.HaveOccurred(), "Should be able to get events from the build")
o.ExpectWithOffset(1, events).NotTo(o.BeNil(), "Build event list should not be nil")

found := false
for _, event := range events.Items {
framework.Logf("Found event %#v", event)
if reason == event.Reason {
found = true
o.ExpectWithOffset(1, event.Message).To(o.Equal(fmt.Sprintf(message, build.Namespace, build.Name)))
}
}
o.ExpectWithOffset(1, found).To(o.BeTrue(), "Did not find a %q event on build %s/%s", reason, build.Namespace, build.Name)
}