diff --git a/api/v1/runtimecomponent_types.go b/api/v1/runtimecomponent_types.go index 2b889bfc1..50b928c6c 100644 --- a/api/v1/runtimecomponent_types.go +++ b/api/v1/runtimecomponent_types.go @@ -168,6 +168,10 @@ type RuntimeComponentSpec struct { // The list of hostnames and IPs that will be injected into the application pod's hosts file // +operator-sdk:csv:customresourcedefinitions:order=30,type=spec,displayName="Host Aliases" HostAliases *[]corev1.HostAlias `json:"hostAliases,omitempty"` + + // Name of the PriorityClass for the pod. + // +operator-sdk:csv:customresourcedefinitions:order=31,type=spec,displayName="Priority Class Name" + PriorityClassName *string `json:"priorityClassName,omitempty"` } // Defines the DNS @@ -1107,6 +1111,10 @@ func (cr *RuntimeComponent) GetHostAliases() *[]corev1.HostAlias { return cr.Spec.HostAliases } +func (cr *RuntimeComponent) GetPriorityClassName() *string { + return cr.Spec.PriorityClassName +} + // Initialize the RuntimeComponent instance func (cr *RuntimeComponent) Initialize() { if cr.Spec.PullPolicy == nil { diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index ca62123d2..69f61cdb5 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -697,6 +697,11 @@ func (in *RuntimeComponentSpec) DeepCopyInto(out *RuntimeComponentSpec) { } } } + if in.PriorityClassName != nil { + in, out := &in.PriorityClassName, &out.PriorityClassName + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RuntimeComponentSpec. diff --git a/bundle/manifests/rc.app.stacks_runtimecomponents.yaml b/bundle/manifests/rc.app.stacks_runtimecomponents.yaml index 1407a9aec..0b3f49bc4 100644 --- a/bundle/manifests/rc.app.stacks_runtimecomponents.yaml +++ b/bundle/manifests/rc.app.stacks_runtimecomponents.yaml @@ -4590,6 +4590,9 @@ spec: is allowed from. type: object type: object + priorityClassName: + description: Name of the PriorityClass for the pod. + type: string probes: description: Define health checks on application container to determine whether it is alive or ready to receive traffic diff --git a/bundle/manifests/runtime-component.clusterserviceversion.yaml b/bundle/manifests/runtime-component.clusterserviceversion.yaml index 50695e155..d0c01ed16 100644 --- a/bundle/manifests/runtime-component.clusterserviceversion.yaml +++ b/bundle/manifests/runtime-component.clusterserviceversion.yaml @@ -422,6 +422,11 @@ spec: application pod's hosts file displayName: Host Aliases path: hostAliases + - description: Name of the PriorityClass for the pod. + displayName: Priority Class Name + path: priorityClassName + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text - description: Labels to set on ServiceMonitor. displayName: Monitoring Labels path: monitoring.labels diff --git a/common/types.go b/common/types.go index 350123abd..0417d90fa 100644 --- a/common/types.go +++ b/common/types.go @@ -264,4 +264,5 @@ type BaseComponent interface { GetDNS() BaseComponentDNS GetDisableTopologyRouting() *bool GetHostAliases() *[]corev1.HostAlias + GetPriorityClassName() *string } diff --git a/config/crd/bases/rc.app.stacks_runtimecomponents.yaml b/config/crd/bases/rc.app.stacks_runtimecomponents.yaml index e2a9489a2..1dc093f9f 100644 --- a/config/crd/bases/rc.app.stacks_runtimecomponents.yaml +++ b/config/crd/bases/rc.app.stacks_runtimecomponents.yaml @@ -4586,6 +4586,9 @@ spec: is allowed from. type: object type: object + priorityClassName: + description: Name of the PriorityClass for the pod. + type: string probes: description: Define health checks on application container to determine whether it is alive or ready to receive traffic diff --git a/examples/priorityclass/01-priorityclass.yaml b/examples/priorityclass/01-priorityclass.yaml new file mode 100644 index 000000000..14182cee4 --- /dev/null +++ b/examples/priorityclass/01-priorityclass.yaml @@ -0,0 +1,7 @@ +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: service-critical +value: 1000000 +globalDefault: false +description: "Reserved for critical workloads. Pods with this class may preempt lower-priority pods during resource contention. Pods are Priority 0 by default." \ No newline at end of file diff --git a/examples/priorityclass/02-runtimecomponent.yaml b/examples/priorityclass/02-runtimecomponent.yaml new file mode 100644 index 000000000..289cd9711 --- /dev/null +++ b/examples/priorityclass/02-runtimecomponent.yaml @@ -0,0 +1,42 @@ +apiVersion: rc.app.stacks/v1 +kind: RuntimeComponent +metadata: + name: payment-service +spec: + applicationImage: icr.io/appcafe/open-liberty/samples/getting-started@sha256:80a28b6a71ec02369cc13f621e4c3cca0d63b1977be76e15dabbfba48411107f + manageTLS: true + resources: + limits: + cpu: 500m + memory: 1Gi + requests: + cpu: 200m + memory: 512Mi + replicas: 2 + priorityClassName: service-critical + service: + port: 9443 + serviceAccount: + mountToken: true + probes: + startup: + failureThreshold: 12 + periodSeconds: 5 + httpGet: + path: /health/started + port: 9443 + readiness: + httpGet: + path: /health/ready + port: 9443 + initialDelaySeconds: 1 + periodSeconds: 5 + failureThreshold: 24 + liveness: + httpGet: + path: /health/live + port: 9443 + initialDelaySeconds: 8 + periodSeconds: 5 + + diff --git a/internal/deploy/kubectl/runtime-component-crd.yaml b/internal/deploy/kubectl/runtime-component-crd.yaml index 741c46fa6..42636b780 100644 --- a/internal/deploy/kubectl/runtime-component-crd.yaml +++ b/internal/deploy/kubectl/runtime-component-crd.yaml @@ -4589,6 +4589,9 @@ spec: is allowed from. type: object type: object + priorityClassName: + description: Name of the PriorityClass for the pod. + type: string probes: description: Define health checks on application container to determine whether it is alive or ready to receive traffic diff --git a/internal/deploy/kustomize/daily/base/runtime-component-crd.yaml b/internal/deploy/kustomize/daily/base/runtime-component-crd.yaml index 741c46fa6..42636b780 100644 --- a/internal/deploy/kustomize/daily/base/runtime-component-crd.yaml +++ b/internal/deploy/kustomize/daily/base/runtime-component-crd.yaml @@ -4589,6 +4589,9 @@ spec: is allowed from. type: object type: object + priorityClassName: + description: Name of the PriorityClass for the pod. + type: string probes: description: Define health checks on application container to determine whether it is alive or ready to receive traffic diff --git a/utils/utils.go b/utils/utils.go index e6a0d413c..750e07218 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -767,6 +767,11 @@ func CustomizePodSpec(pts *corev1.PodTemplateSpec, ba common.BaseComponent) { } pts.Spec.Tolerations = ba.GetTolerations() + + pts.Spec.PriorityClassName = "" + if ba.GetPriorityClassName() != nil { + pts.Spec.PriorityClassName = *ba.GetPriorityClassName() + } } // Initialize an empty TopologySpreadConstraints list and optionally prefers scheduling across zones/hosts for pods with podMatchLabels diff --git a/utils/utils_test.go b/utils/utils_test.go index a3d58bb82..ade25f0e9 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -494,6 +494,40 @@ func TestCustomizePodSpecServiceLinks(t *testing.T) { verifyTests(testCPS, t) } +func TestCustomizePodSpecPriorityClassName(t *testing.T) { + logger := zap.New() + logf.SetLogger(logger) + + spec := appstacksv1.RuntimeComponentSpec{ + ApplicationImage: appImage, + Service: service, + } + + pts, runtime := &corev1.PodTemplateSpec{}, createRuntimeComponent(name, namespace, spec) + CustomizePodSpec(pts, runtime) + defaultPriorityClassName := pts.Spec.PriorityClassName + + priorityClassName := "high-priority" + spec.PriorityClassName = &priorityClassName + pts, runtime = &corev1.PodTemplateSpec{}, createRuntimeComponent(name, namespace, spec) + CustomizePodSpec(pts, runtime) + setPriorityClassName := pts.Spec.PriorityClassName + + spec.PriorityClassName = nil + pts = &corev1.PodTemplateSpec{} + pts.Spec.PriorityClassName = priorityClassName + runtime = createRuntimeComponent(name, namespace, spec) + CustomizePodSpec(pts, runtime) + clearPriorityClassName := pts.Spec.PriorityClassName + + testCPS := []Test{ + {"Default PriorityClassName (not set)", "", defaultPriorityClassName}, + {"Set PriorityClassName", priorityClassName, setPriorityClassName}, + {"Clearing PriorityClassName", "", clearPriorityClassName}, + } + verifyTests(testCPS, t) +} + func TestCustomizePersistence(t *testing.T) { logger := zap.New() logf.SetLogger(logger)