Skip to content

Commit 04431da

Browse files
Merge pull request #17267 from bparees/build_logs
Automatic merge from submit-queue (batch tested with PRs 16843, 17095, 17267, 17261, 17274). retry build watch on error/expiration fixes #17266
2 parents bd221dc + dd5a01b commit 04431da

File tree

1 file changed

+79
-26
lines changed

1 file changed

+79
-26
lines changed

pkg/build/registry/rest.go

+79-26
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ import (
44
"fmt"
55
"time"
66

7+
"k8s.io/apimachinery/pkg/api/errors"
78
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
89
"k8s.io/apimachinery/pkg/fields"
10+
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
11+
"k8s.io/apimachinery/pkg/util/wait"
912
"k8s.io/apimachinery/pkg/watch"
1013

1114
buildapi "github.com/openshift/origin/pkg/build/apis/build"
@@ -18,41 +21,91 @@ var (
1821
ErrBuildDeleted = fmt.Errorf("build was deleted")
1922
)
2023

24+
type ErrWatchError struct {
25+
error
26+
}
27+
2128
// WaitForRunningBuild waits until the specified build is no longer New or Pending. Returns true if
2229
// the build ran within timeout, false if it did not, and an error if any other error state occurred.
2330
// The last observed Build state is returned.
2431
func WaitForRunningBuild(buildClient buildtypedclient.BuildsGetter, build *buildapi.Build, timeout time.Duration) (*buildapi.Build, bool, error) {
2532
fieldSelector := fields.OneTermEqualSelector("metadata.name", build.Name)
26-
options := metav1.ListOptions{FieldSelector: fieldSelector.String(), ResourceVersion: build.ResourceVersion}
27-
w, err := buildClient.Builds(build.Namespace).Watch(options)
28-
if err != nil {
29-
return build, false, err
30-
}
33+
options := metav1.ListOptions{FieldSelector: fieldSelector.String(), ResourceVersion: "0"}
3134

32-
observed := build
33-
_, err = watch.Until(timeout, w, func(event watch.Event) (bool, error) {
34-
obj, ok := event.Object.(*buildapi.Build)
35-
if !ok {
36-
return false, fmt.Errorf("received unknown object while watching for builds: %T", event.Object)
37-
}
38-
observed = obj
35+
done := make(chan interface{}, 1)
36+
var resultBuild *buildapi.Build
37+
var success bool
38+
var resultErr error
3939

40-
if event.Type == watch.Deleted {
41-
return false, ErrBuildDeleted
42-
}
43-
switch obj.Status.Phase {
44-
case buildapi.BuildPhaseRunning, buildapi.BuildPhaseComplete, buildapi.BuildPhaseFailed, buildapi.BuildPhaseError, buildapi.BuildPhaseCancelled:
45-
return true, nil
46-
case buildapi.BuildPhaseNew, buildapi.BuildPhasePending:
47-
default:
48-
return false, ErrUnknownBuildPhase
40+
deadline := time.Now().Add(timeout)
41+
go func() {
42+
defer close(done)
43+
defer utilruntime.HandleCrash()
44+
45+
for time.Now().Before(deadline) {
46+
47+
// make sure the build has not been deleted before we start trying to watch on it because
48+
// we won't get a watch event for it if it's been deleted (because we are watching starting
49+
// at resource version 0).
50+
_, err := buildClient.Builds(build.Namespace).Get(build.Name, metav1.GetOptions{})
51+
if err != nil {
52+
resultErr = err
53+
if errors.IsNotFound(err) {
54+
resultErr = ErrBuildDeleted
55+
}
56+
return
57+
}
58+
59+
w, err := buildClient.Builds(build.Namespace).Watch(options)
60+
if err != nil {
61+
resultErr = err
62+
return
63+
}
64+
65+
_, err = watch.Until(timeout, w, func(event watch.Event) (bool, error) {
66+
if event.Type == watch.Error {
67+
return false, ErrWatchError{fmt.Errorf("watch event type error: %v", event)}
68+
}
69+
obj, ok := event.Object.(*buildapi.Build)
70+
if !ok {
71+
return false, fmt.Errorf("received unknown object while watching for builds: %T", event.Object)
72+
}
73+
74+
if event.Type == watch.Deleted {
75+
return false, ErrBuildDeleted
76+
}
77+
78+
switch obj.Status.Phase {
79+
case buildapi.BuildPhaseRunning, buildapi.BuildPhaseComplete, buildapi.BuildPhaseFailed, buildapi.BuildPhaseError, buildapi.BuildPhaseCancelled:
80+
resultBuild = obj
81+
return true, nil
82+
case buildapi.BuildPhaseNew, buildapi.BuildPhasePending:
83+
default:
84+
return false, ErrUnknownBuildPhase
85+
}
86+
87+
return false, nil
88+
})
89+
90+
if err != nil {
91+
if _, ok := err.(ErrWatchError); ok {
92+
continue
93+
}
94+
resultErr = err
95+
success = false
96+
resultBuild = nil
97+
return
98+
}
99+
success = true
100+
return
49101
}
102+
}()
50103

51-
return false, nil
52-
})
53-
if err != nil {
54-
return nil, false, err
104+
select {
105+
case <-time.After(timeout):
106+
return nil, false, wait.ErrWaitTimeout
107+
case <-done:
108+
return resultBuild, success, resultErr
55109
}
56110

57-
return observed, true, nil
58111
}

0 commit comments

Comments
 (0)