Skip to content

Commit dbdb6a7

Browse files
committed
Retry to watch for builds
This fixes a bug when running, e.g.: $ oc start-build --wait --follow my-build In some cases the watcher expires and we need to try again with a new watcher.
1 parent ac4434e commit dbdb6a7

File tree

1 file changed

+35
-23
lines changed

1 file changed

+35
-23
lines changed

pkg/build/registry/rest.go

+35-23
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
kapi "k8s.io/kubernetes/pkg/api"
88
"k8s.io/kubernetes/pkg/api/rest"
9+
"k8s.io/kubernetes/pkg/api/unversioned"
910
"k8s.io/kubernetes/pkg/fields"
1011

1112
"github.com/openshift/origin/pkg/build/api"
@@ -20,33 +21,44 @@ var ErrUnknownBuildPhase = fmt.Errorf("unknown build phase")
2021
func WaitForRunningBuild(watcher rest.Watcher, ctx kapi.Context, build *api.Build, timeout time.Duration) (*api.Build, bool, error) {
2122
fieldSelector := fields.OneTermEqualSelector("metadata.name", build.Name)
2223
options := &kapi.ListOptions{FieldSelector: fieldSelector, ResourceVersion: build.ResourceVersion}
23-
w, err := watcher.Watch(ctx, options)
24-
if err != nil {
25-
return nil, false, err
26-
}
27-
defer w.Stop()
2824

29-
ch := w.ResultChan()
30-
observed := build
3125
expire := time.After(timeout)
32-
for {
33-
select {
34-
case event := <-ch:
35-
obj, ok := event.Object.(*api.Build)
36-
if !ok {
37-
return observed, false, fmt.Errorf("received unknown object while watching for builds")
38-
}
39-
observed = obj
4026

41-
switch obj.Status.Phase {
42-
case api.BuildPhaseRunning, api.BuildPhaseComplete, api.BuildPhaseFailed, api.BuildPhaseError, api.BuildPhaseCancelled:
43-
return observed, true, nil
44-
case api.BuildPhaseNew, api.BuildPhasePending:
45-
default:
46-
return observed, false, ErrUnknownBuildPhase
27+
watcherLoop:
28+
for {
29+
w, err := watcher.Watch(ctx, options)
30+
if err != nil {
31+
return nil, false, err
32+
}
33+
defer w.Stop()
34+
ch := w.ResultChan()
35+
eventLoop:
36+
for {
37+
select {
38+
case event := <-ch:
39+
switch observed := event.Object.(type) {
40+
case *api.Build:
41+
switch observed.Status.Phase {
42+
case api.BuildPhaseRunning, api.BuildPhaseComplete, api.BuildPhaseFailed, api.BuildPhaseError, api.BuildPhaseCancelled:
43+
// Build has started, return it.
44+
return observed, true, nil
45+
case api.BuildPhaseNew, api.BuildPhasePending:
46+
// Build haven't started yet, continue waiting for more events.
47+
continue eventLoop
48+
default:
49+
// Build has an unknown phase.
50+
return observed, false, ErrUnknownBuildPhase
51+
}
52+
case *unversioned.Status:
53+
if observed.Reason == unversioned.StatusReasonExpired {
54+
// The watcher expired, need to start over with a new watcher.
55+
continue watcherLoop
56+
}
57+
}
58+
return build, false, fmt.Errorf("received unknown object while watching for builds: %v", event.Object)
59+
case <-expire:
60+
return build, false, nil
4761
}
48-
case <-expire:
49-
return observed, false, nil
5062
}
5163
}
5264
}

0 commit comments

Comments
 (0)