Skip to content

Commit

Permalink
feat(build): Add Build waiting condition
Browse files Browse the repository at this point in the history
* Add on Build.Status a "Scheduled" condition containing the reason for it's scheduling status

Ref apache#4542
  • Loading branch information
gansheer committed Feb 15, 2024
1 parent 3f31f36 commit 855544b
Show file tree
Hide file tree
Showing 5 changed files with 320 additions and 76 deletions.
70 changes: 70 additions & 0 deletions e2e/builder/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (

. "github.com/apache/camel-k/v2/e2e/support"
v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
corev1 "k8s.io/api/core/v1"
)

type kitOptions struct {
Expand Down Expand Up @@ -130,11 +131,34 @@ func TestKitMaxBuildLimit(t *testing.T) {

// verify that all builds are successful
Eventually(BuildPhase(ns, buildA), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
Eventually(BuildConditions(ns, buildA), TestTimeoutLong).ShouldNot(BeNil())
Eventually(
Build(ns, buildA)().Status.GetCondition(v1.BuildConditionScheduled).Status,
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
Eventually(
Build(ns, buildA)().Status.GetCondition(v1.BuildConditionScheduled).Reason,
TestTimeoutShort).Should(Equal(v1.BuildConditionReadyReason))
Eventually(KitPhase(ns, buildA), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady))

Eventually(BuildPhase(ns1, buildB), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
Eventually(KitPhase(ns1, buildB), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady))
Eventually(BuildConditions(ns1, buildB), TestTimeoutLong).ShouldNot(BeNil())
Eventually(
Build(ns1, buildB)().Status.GetCondition(v1.BuildConditionScheduled).Status,
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
Eventually(
Build(ns1, buildB)().Status.GetCondition(v1.BuildConditionScheduled).Reason,
TestTimeoutShort).Should(Equal(v1.BuildConditionReadyReason))

Eventually(BuildPhase(ns2, buildC), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
Eventually(KitPhase(ns2, buildC), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady))
Eventually(BuildConditions(ns2, buildC), TestTimeoutLong).ShouldNot(BeNil())
Eventually(
Build(ns2, buildC)().Status.GetCondition(v1.BuildConditionScheduled).Status,
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
Eventually(
Build(ns2, buildC)().Status.GetCondition(v1.BuildConditionScheduled).Reason,
TestTimeoutShort).Should(Equal(v1.BuildConditionReadyReason))
})
})
})
Expand Down Expand Up @@ -207,10 +231,33 @@ func TestKitMaxBuildLimitFIFOStrategy(t *testing.T) {
// verify that all builds are successful
Eventually(BuildPhase(ns, buildA), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
Eventually(KitPhase(ns, buildA), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady))
Eventually(BuildConditions(ns, buildA), TestTimeoutLong).ShouldNot(BeNil())
Eventually(
Build(ns, buildA)().Status.GetCondition(v1.BuildConditionScheduled).Status,
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
Eventually(
Build(ns, buildA)().Status.GetCondition(v1.BuildConditionScheduled).Reason,
TestTimeoutShort).Should(Equal(v1.BuildConditionReadyReason))

Eventually(BuildPhase(ns, buildB), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
Eventually(KitPhase(ns, buildB), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady))
Eventually(BuildConditions(ns, buildB), TestTimeoutLong).ShouldNot(BeNil())
Eventually(
Build(ns, buildB)().Status.GetCondition(v1.BuildConditionScheduled).Status,
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
Eventually(
Build(ns, buildB)().Status.GetCondition(v1.BuildConditionScheduled).Reason,
TestTimeoutShort).Should(Equal(v1.BuildConditionReadyReason))

Eventually(BuildPhase(ns, buildC), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
Eventually(KitPhase(ns, buildC), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady))
Eventually(BuildConditions(ns, buildC), TestTimeoutLong).ShouldNot(BeNil())
Eventually(
Build(ns, buildC)().Status.GetCondition(v1.BuildConditionScheduled).Status,
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
Eventually(
Build(ns, buildC)().Status.GetCondition(v1.BuildConditionScheduled).Reason,
TestTimeoutShort).Should(Equal(v1.BuildConditionReadyReason))
})
}

Expand Down Expand Up @@ -281,10 +328,33 @@ func TestKitMaxBuildLimitDependencyMatchingStrategy(t *testing.T) {
// verify that all builds are successful
Eventually(BuildPhase(ns, buildA), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
Eventually(KitPhase(ns, buildA), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady))
Eventually(BuildConditions(ns, buildA), TestTimeoutLong).ShouldNot(BeNil())
Eventually(
Build(ns, buildA)().Status.GetCondition(v1.BuildConditionScheduled).Status,
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
Eventually(
Build(ns, buildA)().Status.GetCondition(v1.BuildConditionScheduled).Reason,
TestTimeoutShort).Should(Equal(v1.BuildConditionReadyReason))

Eventually(BuildPhase(ns, buildB), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
Eventually(KitPhase(ns, buildB), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady))
Eventually(BuildConditions(ns, buildB), TestTimeoutLong).ShouldNot(BeNil())
Eventually(
Build(ns, buildB)().Status.GetCondition(v1.BuildConditionScheduled).Status,
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
Eventually(
Build(ns, buildB)().Status.GetCondition(v1.BuildConditionScheduled).Reason,
TestTimeoutShort).Should(Equal(v1.BuildConditionReadyReason))

Eventually(BuildPhase(ns, buildC), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded))
Eventually(KitPhase(ns, buildC), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady))
Eventually(BuildConditions(ns, buildC), TestTimeoutLong).ShouldNot(BeNil())
Eventually(
Build(ns, buildC)().Status.GetCondition(v1.BuildConditionScheduled).Status,
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
Eventually(
Build(ns, buildC)().Status.GetCondition(v1.BuildConditionScheduled).Reason,
TestTimeoutShort).Should(Equal(v1.BuildConditionReadyReason))
})
}

Expand Down
8 changes: 8 additions & 0 deletions pkg/apis/camel/v1/build_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,14 @@ const (
BuildPhaseInterrupted = "Interrupted"
// BuildPhaseError -- .
BuildPhaseError BuildPhase = "Error"

// BuildConditionScheduled --.
BuildConditionScheduled BuildConditionType = "Scheduled"

// BuildConditionReadyReason --.
BuildConditionReadyReason string = "Ready"
// BuildConditionWaitingReason --.
BuildConditionWaitingReason string = "Waiting"
)

// +genclient
Expand Down
21 changes: 21 additions & 0 deletions pkg/controller/build/build_monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"fmt"
"sync"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/selection"
"k8s.io/apimachinery/pkg/types"
Expand Down Expand Up @@ -56,6 +57,16 @@ func (bm *Monitor) canSchedule(ctx context.Context, c ctrl.Reader, build *v1.Bui
if runningBuildsTotal >= bm.maxRunningBuilds {
Log.WithValues("request-namespace", requestNamespace, "request-name", requestName, "max-running-builds-limit", runningBuildsTotal).
ForBuild(build).Infof("Maximum number of running builds (%d) exceeded - the build (%s) gets enqueued", runningBuildsTotal, build.Name)
build.Status.SetCondition(
v1.BuildConditionScheduled,
corev1.ConditionFalse,
v1.BuildConditionWaitingReason,
fmt.Sprintf(
"Maximum number of running builds (%d) exceeded - the build (%s) gets enqueued",
runningBuildsTotal,
build.Name,
),
)

// max number of running builds limit exceeded
return false, nil
Expand Down Expand Up @@ -117,6 +128,16 @@ func (bm *Monitor) canSchedule(ctx context.Context, c ctrl.Reader, build *v1.Bui
if !allowed {
Log.WithValues("request-namespace", requestNamespace, "request-name", requestName, "order-strategy", bm.buildOrderStrategy).
ForBuild(build).Infof("%s - the build (%s) gets enqueued", reason, build.Name)
build.Status.SetCondition(
v1.BuildConditionScheduled,
corev1.ConditionFalse,
v1.BuildConditionWaitingReason,
fmt.Sprintf(
"%s - the build (%s) gets enqueued",
reason,
build.Name,
),
)
}

return allowed, nil
Expand Down
Loading

0 comments on commit 855544b

Please sign in to comment.