Skip to content

Commit f8d3cfa

Browse files
committed
ensure next build is kicked off when a build completes
https://bugzilla.redhat.com/show_bug.cgi?id=1436395
1 parent 4b16943 commit f8d3cfa

File tree

3 files changed

+53
-23
lines changed

3 files changed

+53
-23
lines changed

pkg/build/controller/buildpod/controller.go

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ func (bc *BuildPodController) HandlePod(pod *kapi.Pod) error {
121121
nextStatus := build.Status.Phase
122122
currentReason := build.Status.Reason
123123

124+
// if the build is marked failed, the build status reason has already been
125+
// set (probably by the build pod itself), so don't do any updating here
126+
// or we'll overwrite the correct value.
124127
if build.Status.Phase != buildapi.BuildPhaseFailed {
125128
switch pod.Status.Phase {
126129
case kapi.PodPending:
@@ -176,33 +179,45 @@ func (bc *BuildPodController) HandlePod(pod *kapi.Pod) error {
176179
build.Status.Message = ""
177180
}
178181
}
182+
183+
needsUpdate := false
179184
// Update the build object when it progress to a next state or the reason for
180-
// the current state changed.
181-
if (!common.HasBuildPodNameAnnotation(build) || build.Status.Phase != nextStatus || build.Status.Phase == buildapi.BuildPhaseFailed) && !buildutil.IsBuildComplete(build) {
185+
// the current state changed. Do not touch builds that were marked failed
186+
// because we'd potentially be overwriting build state information set by the
187+
// build pod directly.
188+
if (!common.HasBuildPodNameAnnotation(build) || build.Status.Phase != nextStatus) && build.Status.Phase != buildapi.BuildPhaseFailed {
189+
needsUpdate = true
182190
common.SetBuildPodNameAnnotation(build, pod.Name)
183191
reason := ""
184192
if len(build.Status.Reason) > 0 {
185193
reason = " (" + string(build.Status.Reason) + ")"
186194
}
187195
glog.V(4).Infof("Updating build %s/%s status %s -> %s%s", build.Namespace, build.Name, build.Status.Phase, nextStatus, reason)
188196
build.Status.Phase = nextStatus
189-
190-
if buildutil.IsBuildComplete(build) {
191-
common.SetBuildCompletionTimeAndDuration(build)
192-
}
193197
if build.Status.Phase == buildapi.BuildPhaseRunning {
194198
now := unversioned.Now()
195199
build.Status.StartTimestamp = &now
196200
}
201+
}
202+
203+
// we're going to get pod relist events for completed/failed pods,
204+
// there's no reason to re-update the build and rerun
205+
// HandleBuildCompletion if we've already done it for this
206+
// build previously.
207+
buildWasComplete := build.Status.CompletionTimestamp != nil
208+
if !buildWasComplete && buildutil.IsBuildComplete(build) {
209+
needsUpdate = common.SetBuildCompletionTimeAndDuration(build)
210+
}
211+
if needsUpdate {
197212
if err := bc.buildUpdater.Update(build.Namespace, build); err != nil {
198213
return fmt.Errorf("failed to update build %s/%s: %v", build.Namespace, build.Name, err)
199214
}
200215
glog.V(4).Infof("Build %s/%s status was updated to %s", build.Namespace, build.Name, build.Status.Phase)
201-
202-
if buildutil.IsBuildComplete(build) {
203-
common.HandleBuildCompletion(build, bc.runPolicies)
204-
}
205216
}
217+
if !buildWasComplete && buildutil.IsBuildComplete(build) {
218+
common.HandleBuildCompletion(build, bc.runPolicies)
219+
}
220+
206221
return nil
207222
}
208223

pkg/build/controller/common/util.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,23 @@ import (
1111
utilruntime "k8s.io/kubernetes/pkg/util/runtime"
1212
)
1313

14-
func SetBuildCompletionTimeAndDuration(build *buildapi.Build) {
14+
// SetBuildCompletionTimeAndDuration will set the build completion timestamp
15+
// to the current time if it is nil. It will also set the start timestamp to
16+
// the same value if if it nil. Returns true if the build object was
17+
// modified.
18+
func SetBuildCompletionTimeAndDuration(build *buildapi.Build) boolean {
19+
if build.Status.CompletionTimestamp != nil {
20+
return false
21+
}
1522
now := unversioned.Now()
1623
build.Status.CompletionTimestamp = &now
17-
if build.Status.StartTimestamp != nil {
18-
build.Status.Duration = build.Status.CompletionTimestamp.Rfc3339Copy().Time.Sub(build.Status.StartTimestamp.Rfc3339Copy().Time)
24+
// apparently this build completed so fast we didn't see the pod running event,
25+
// so just use the completion time as the start time.
26+
if build.Status.StartTimestamp == nil {
27+
build.Status.StartTimestamp = &now
1928
}
29+
build.Status.Duration = build.Status.CompletionTimestamp.Rfc3339Copy().Time.Sub(build.Status.StartTimestamp.Rfc3339Copy().Time)
30+
return true
2031
}
2132

2233
func HandleBuildCompletion(build *buildapi.Build, runPolicies []policy.RunPolicy) {

pkg/build/controller/policy/policy.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -142,17 +142,21 @@ func handleComplete(lister buildclient.BuildLister, updater buildclient.BuildUpd
142142
}
143143
for _, build := range nextBuilds {
144144
// TODO: replace with informer notification requeueing in the future
145-
build.Annotations[buildapi.BuildAcceptedAnnotation] = uuid.NewRandom().String()
146-
err := wait.Poll(500*time.Millisecond, 5*time.Second, func() (bool, error) {
147-
err := updater.Update(build.Namespace, build)
148-
if err != nil && errors.IsConflict(err) {
149-
glog.V(5).Infof("Error updating build %s/%s: %v (will retry)", build.Namespace, build.Name, err)
150-
return false, nil
145+
146+
// only set the annotation once.
147+
if _, ok := build.Annotations[buildapi.BuildAcceptedAnnotation]; !ok {
148+
build.Annotations[buildapi.BuildAcceptedAnnotation] = uuid.NewRandom().String()
149+
err := wait.Poll(500*time.Millisecond, 5*time.Second, func() (bool, error) {
150+
err := updater.Update(build.Namespace, build)
151+
if err != nil && errors.IsConflict(err) {
152+
glog.V(5).Infof("Error updating build %s/%s: %v (will retry)", build.Namespace, build.Name, err)
153+
return false, nil
154+
}
155+
return true, err
156+
})
157+
if err != nil {
158+
return err
151159
}
152-
return true, err
153-
})
154-
if err != nil {
155-
return err
156160
}
157161
}
158162
return nil

0 commit comments

Comments
 (0)