From 213215faf236cf3a420b905afa3765de94179ddd Mon Sep 17 00:00:00 2001 From: Dylan Orzel Date: Tue, 21 Jan 2025 10:42:54 -0700 Subject: [PATCH] Add Custom Scheduler Name to Build and BuildRun objects Signed-off-by: Dylan Orzel --- deploy/crds/shipwright.io_buildruns.yaml | 12 +++++++ deploy/crds/shipwright.io_builds.yaml | 4 +++ pkg/apis/build/v1beta1/build_types.go | 7 +++- pkg/apis/build/v1beta1/buildrun_types.go | 4 +++ pkg/reconciler/build/build.go | 1 + pkg/reconciler/buildrun/buildrun.go | 1 + pkg/reconciler/buildrun/resources/build.go | 1 + pkg/reconciler/buildrun/resources/taskrun.go | 9 +++++ pkg/validate/scheduler_name.go | 37 ++++++++++++++++++++ pkg/validate/validate.go | 4 +++ 10 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 pkg/validate/scheduler_name.go diff --git a/deploy/crds/shipwright.io_buildruns.yaml b/deploy/crds/shipwright.io_buildruns.yaml index 9797b1387..595fdf666 100644 --- a/deploy/crds/shipwright.io_buildruns.yaml +++ b/deploy/crds/shipwright.io_buildruns.yaml @@ -7439,6 +7439,10 @@ spec: format: duration type: string type: object + schedulerName: + description: SchedulerName specifies the scheduler to be used + to dispatch the Pod + type: string source: description: |- Source refers to the location where the source code is, @@ -9753,6 +9757,10 @@ spec: format: duration type: string type: object + schedulerName: + description: SchedulerName specifies the scheduler to be used to dispatch + the Pod + type: string serviceAccount: description: |- ServiceAccount refers to the kubernetes serviceaccount @@ -11941,6 +11949,10 @@ spec: format: duration type: string type: object + schedulerName: + description: SchedulerName specifies the scheduler to be used + to dispatch the Pod + type: string source: description: |- Source refers to the location where the source code is, diff --git a/deploy/crds/shipwright.io_builds.yaml b/deploy/crds/shipwright.io_builds.yaml index 9873c9594..e91fe4791 100644 --- a/deploy/crds/shipwright.io_builds.yaml +++ b/deploy/crds/shipwright.io_builds.yaml @@ -2818,6 +2818,10 @@ spec: format: duration type: string type: object + schedulerName: + description: SchedulerName specifies the scheduler to be used to dispatch + the Pod + type: string source: description: |- Source refers to the location where the source code is, diff --git a/pkg/apis/build/v1beta1/build_types.go b/pkg/apis/build/v1beta1/build_types.go index 73822614b..c1868727e 100644 --- a/pkg/apis/build/v1beta1/build_types.go +++ b/pkg/apis/build/v1beta1/build_types.go @@ -80,7 +80,8 @@ const ( NodeSelectorNotValid BuildReason = "NodeSelectorNotValid" // TolerationNotValid indicates that the Toleration value is not valid TolerationNotValid BuildReason = "TolerationNotValid" - + // SchedulerNameNotValid indicates that the Scheduler name is not valid + SchedulerNameNotValid BuildReason = "SchedulerNameNotValid" // AllValidationsSucceeded indicates a Build was successfully validated AllValidationsSucceeded = "all validations succeeded" ) @@ -191,6 +192,10 @@ type BuildSpec struct { // +patchMergeKey=Key // +patchStrategy=merge Tolerations []corev1.Toleration `json:"tolerations,omitempty" patchStrategy:"merge" patchMergeKey:"Key"` + + // SchedulerName specifies the scheduler to be used to dispatch the Pod + // +optional + SchedulerName string `json:"schedulerName,omitempty"` } // BuildVolume is a volume that will be mounted in build pod during build step diff --git a/pkg/apis/build/v1beta1/buildrun_types.go b/pkg/apis/build/v1beta1/buildrun_types.go index af2882fbb..a3f6a2687 100644 --- a/pkg/apis/build/v1beta1/buildrun_types.go +++ b/pkg/apis/build/v1beta1/buildrun_types.go @@ -121,6 +121,10 @@ type BuildRunSpec struct { // +patchMergeKey=Key // +patchStrategy=merge Tolerations []corev1.Toleration `json:"tolerations,omitempty" patchStrategy:"merge" patchMergeKey:"Key"` + + // SchedulerName specifies the scheduler to be used to dispatch the Pod + // +optional + SchedulerName string `json:"schedulerName,omitempty"` } // BuildRunRequestedState defines the buildrun state the user can provide to override whatever is the current state. diff --git a/pkg/reconciler/build/build.go b/pkg/reconciler/build/build.go index 805d13a63..0a56bad39 100644 --- a/pkg/reconciler/build/build.go +++ b/pkg/reconciler/build/build.go @@ -35,6 +35,7 @@ var validationTypes = [...]string{ validate.Triggers, validate.NodeSelector, validate.Tolerations, + validate.SchedulerName, } // ReconcileBuild reconciles a Build object diff --git a/pkg/reconciler/buildrun/buildrun.go b/pkg/reconciler/buildrun/buildrun.go index b5945cda9..056d3c9cf 100644 --- a/pkg/reconciler/buildrun/buildrun.go +++ b/pkg/reconciler/buildrun/buildrun.go @@ -162,6 +162,7 @@ func (r *ReconcileBuildRun) Reconcile(ctx context.Context, request reconcile.Req validate.NewEnv(build), validate.NewNodeSelector(build), validate.NewTolerations(build), + validate.NewSchedulerName(build), ) // an internal/technical error during validation happened diff --git a/pkg/reconciler/buildrun/resources/build.go b/pkg/reconciler/buildrun/resources/build.go index 686fca289..32e006458 100644 --- a/pkg/reconciler/buildrun/resources/build.go +++ b/pkg/reconciler/buildrun/resources/build.go @@ -44,6 +44,7 @@ func GetBuildObject(ctx context.Context, client client.Client, buildRun *buildv1 // explicitly setting them here is required for validation to happen. build.Spec.NodeSelector = buildRun.Spec.NodeSelector build.Spec.Tolerations = buildRun.Spec.Tolerations + build.Spec.SchedulerName = buildRun.Spec.SchedulerName return nil } diff --git a/pkg/reconciler/buildrun/resources/taskrun.go b/pkg/reconciler/buildrun/resources/taskrun.go index 9a770fad3..7a54aa0fe 100644 --- a/pkg/reconciler/buildrun/resources/taskrun.go +++ b/pkg/reconciler/buildrun/resources/taskrun.go @@ -249,6 +249,15 @@ func GenerateTaskRun( taskRunPodTemplate.Tolerations = taskRunTolerations } + // Set custom scheduler name if specified, giving preference to BuildRun values + if buildRun.Spec.SchedulerName != "" { + taskRunPodTemplate.SchedulerName = buildRun.Spec.SchedulerName + } else { + if build.Spec.SchedulerName != "" { + taskRunPodTemplate.SchedulerName = build.Spec.SchedulerName + } + } + if !(taskRunPodTemplate.Equals(&pod.PodTemplate{})) { expectedTaskRun.Spec.PodTemplate = taskRunPodTemplate } diff --git a/pkg/validate/scheduler_name.go b/pkg/validate/scheduler_name.go new file mode 100644 index 000000000..954ca5e55 --- /dev/null +++ b/pkg/validate/scheduler_name.go @@ -0,0 +1,37 @@ +// Copyright The Shipwright Contributors +// +// SPDX-License-Identifier: Apache-2.0 + +package validate + +import ( + "context" + "strings" + + "k8s.io/apimachinery/pkg/util/validation" + "k8s.io/utils/ptr" + + build "github.com/shipwright-io/build/pkg/apis/build/v1beta1" +) + +// SchedulerNameRef contains all required fields +// to validate a Scheduler name +type SchedulerNameRef struct { + Build *build.Build // build instance for analysis +} + +func NewSchedulerName(build *build.Build) *SchedulerNameRef { + return &SchedulerNameRef{build} +} + +// ValidatePath implements BuildPath interface and validates +// that SchedulerName values are valid +func (b *SchedulerNameRef) ValidatePath(_ context.Context) error { + if b.Build.Spec.SchedulerName != "" { + if errs := validation.IsQualifiedName(b.Build.Spec.SchedulerName); len(errs) > 0 { + b.Build.Status.Reason = ptr.To(build.SchedulerNameNotValid) + b.Build.Status.Message = ptr.To(strings.Join(errs, ", ")) + } + } + return nil +} diff --git a/pkg/validate/validate.go b/pkg/validate/validate.go index 219d84c0b..d1eed529f 100644 --- a/pkg/validate/validate.go +++ b/pkg/validate/validate.go @@ -39,6 +39,8 @@ const ( NodeSelector = "nodeselector" // Tolerations for validating `spec.tolerations` entry Tolerations = "tolerations" + // SchedulerName for validating `spec.schedulerName` entry + SchedulerName = "schedulername" ) const ( @@ -83,6 +85,8 @@ func NewValidation( return &NodeSelectorRef{Build: build}, nil case Tolerations: return &TolerationsRef{Build: build}, nil + case SchedulerName: + return &SchedulerNameRef{Build: build}, nil default: return nil, fmt.Errorf("unknown validation type") }