diff --git a/crds/sme.sap.com_capapplications.yaml b/crds/sme.sap.com_capapplications.yaml index 1251078..b8f291c 100644 --- a/crds/sme.sap.com_capapplications.yaml +++ b/crds/sme.sap.com_capapplications.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: capapplications.sme.sap.com spec: group: sme.sap.com diff --git a/crds/sme.sap.com_capapplicationversions.yaml b/crds/sme.sap.com_capapplicationversions.yaml index 5e2be37..57819a3 100644 --- a/crds/sme.sap.com_capapplicationversions.yaml +++ b/crds/sme.sap.com_capapplicationversions.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: capapplicationversions.sme.sap.com spec: group: sme.sap.com @@ -1654,6 +1654,8 @@ spec: x-kubernetes-int-or-string: true type: object type: object + restartPolicy: + type: string securityContext: properties: allowPrivilegeEscalation: @@ -3927,6 +3929,8 @@ spec: x-kubernetes-int-or-string: true type: object type: object + restartPolicy: + type: string securityContext: properties: allowPrivilegeEscalation: diff --git a/crds/sme.sap.com_captenantoperations.yaml b/crds/sme.sap.com_captenantoperations.yaml index c608d8a..56a68e0 100644 --- a/crds/sme.sap.com_captenantoperations.yaml +++ b/crds/sme.sap.com_captenantoperations.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: captenantoperations.sme.sap.com spec: group: sme.sap.com diff --git a/crds/sme.sap.com_captenantoutputs.yaml b/crds/sme.sap.com_captenantoutputs.yaml index 5cf6942..4feda9e 100644 --- a/crds/sme.sap.com_captenantoutputs.yaml +++ b/crds/sme.sap.com_captenantoutputs.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: captenantoutputs.sme.sap.com spec: group: sme.sap.com diff --git a/crds/sme.sap.com_captenants.yaml b/crds/sme.sap.com_captenants.yaml index 4ff3f17..63c6ef3 100644 --- a/crds/sme.sap.com_captenants.yaml +++ b/crds/sme.sap.com_captenants.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.4 + controller-gen.kubebuilder.io/version: v0.16.5 name: captenants.sme.sap.com spec: group: sme.sap.com diff --git a/internal/controller/reconcile-capapplicationversion.go b/internal/controller/reconcile-capapplicationversion.go index 01c994b..2e4b4fc 100644 --- a/internal/controller/reconcile-capapplicationversion.go +++ b/internal/controller/reconcile-capapplicationversion.go @@ -328,7 +328,7 @@ func newContentDeploymentJob(cav *v1alpha1.CAPApplicationVersion, workload *v1al ServiceAccountName: workload.JobDefinition.ServiceAccountName, Volumes: workload.JobDefinition.Volumes, ImagePullSecrets: convertToLocalObjectReferences(cav.Spec.RegistrySecrets), - RestartPolicy: corev1.RestartPolicyOnFailure, + RestartPolicy: getRestartPolicy(workload.JobDefinition.RestartPolicy, true), NodeSelector: workload.JobDefinition.NodeSelector, NodeName: workload.JobDefinition.NodeName, PriorityClassName: workload.JobDefinition.PriorityClassName, @@ -743,6 +743,7 @@ func createDeployment(params *DeploymentParameters) *appsv1.Deployment { Affinity: params.WorkloadDetails.DeploymentDefinition.Affinity, TopologySpreadConstraints: params.WorkloadDetails.DeploymentDefinition.TopologySpreadConstraints, Tolerations: params.WorkloadDetails.DeploymentDefinition.Tolerations, + RestartPolicy: getRestartPolicy(params.WorkloadDetails.DeploymentDefinition.RestartPolicy, false), }, }, }, diff --git a/internal/controller/reconcile-captenantoperation.go b/internal/controller/reconcile-captenantoperation.go index 1fb72cc..930b58d 100644 --- a/internal/controller/reconcile-captenantoperation.go +++ b/internal/controller/reconcile-captenantoperation.go @@ -51,6 +51,7 @@ type tentantOperationWorkload struct { tolerations []corev1.Toleration backoffLimit *int32 ttlSecondsAfterFinished *int32 + restartPolicy corev1.RestartPolicy } const ( @@ -484,7 +485,7 @@ func (c *Controller) createTenantOperationJob(ctx context.Context, ctop *v1alpha Annotations: params.annotations, }, Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, + RestartPolicy: getRestartPolicy(derivedWorkload.restartPolicy, true), ImagePullSecrets: params.imagePullSecrets, Containers: getContainers(ctop, derivedWorkload, workload, params), InitContainers: *updateInitContainers(derivedWorkload.initContainers, getCTOPEnv(params, ctop, v1alpha1.JobTenantOperation), params.vcapSecretName), @@ -574,6 +575,7 @@ func deriveWorkloadForTenantOperation(workload *v1alpha1.WorkloadDetails) tentan if workload.JobDefinition.TTLSecondsAfterFinished != nil { result.ttlSecondsAfterFinished = workload.JobDefinition.TTLSecondsAfterFinished } + result.restartPolicy = workload.JobDefinition.RestartPolicy result.affinity = workload.JobDefinition.Affinity result.nodeSelector = workload.JobDefinition.NodeSelector result.nodeName = workload.JobDefinition.NodeName @@ -603,7 +605,7 @@ func (c *Controller) createCustomTenantOperationJob(ctx context.Context, ctop *v Annotations: params.annotations, }, Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, + RestartPolicy: getRestartPolicy(workload.JobDefinition.RestartPolicy, true), SecurityContext: workload.JobDefinition.PodSecurityContext, Volumes: workload.JobDefinition.Volumes, ServiceAccountName: workload.JobDefinition.ServiceAccountName, diff --git a/internal/controller/reconcile.go b/internal/controller/reconcile.go index e5ce583..12a3051 100644 --- a/internal/controller/reconcile.go +++ b/internal/controller/reconcile.go @@ -611,3 +611,10 @@ func updateInitContainers(initContainers []corev1.Container, additionalEnv []cor func getWorkloadName(cavName, workloadName string) string { return fmt.Sprintf("%s-%s", cavName, strings.ToLower(workloadName)) } + +func getRestartPolicy(restartPolicy corev1.RestartPolicy, isJob bool) corev1.RestartPolicy { + if isJob && restartPolicy == "" { + return corev1.RestartPolicyNever + } + return restartPolicy +} diff --git a/internal/controller/testdata/capapplicationversion/all-mulitple-content-job-completed.yaml b/internal/controller/testdata/capapplicationversion/all-mulitple-content-job-completed.yaml index 0a66001..5ad129e 100644 --- a/internal/controller/testdata/capapplicationversion/all-mulitple-content-job-completed.yaml +++ b/internal/controller/testdata/capapplicationversion/all-mulitple-content-job-completed.yaml @@ -56,7 +56,7 @@ spec: dnsPolicy: ClusterFirst imagePullSecrets: - name: regcred - restartPolicy: OnFailure + restartPolicy: Never schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 @@ -128,7 +128,7 @@ spec: dnsPolicy: ClusterFirst imagePullSecrets: - name: regcred - restartPolicy: OnFailure + restartPolicy: Never schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 diff --git a/internal/controller/testdata/capapplicationversion/content-job-completed.yaml b/internal/controller/testdata/capapplicationversion/content-job-completed.yaml index c48fade..c653e6c 100644 --- a/internal/controller/testdata/capapplicationversion/content-job-completed.yaml +++ b/internal/controller/testdata/capapplicationversion/content-job-completed.yaml @@ -56,7 +56,7 @@ spec: dnsPolicy: ClusterFirst imagePullSecrets: - name: regcred - restartPolicy: OnFailure + restartPolicy: Never schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 diff --git a/internal/controller/testdata/capapplicationversion/content-job-failed.yaml b/internal/controller/testdata/capapplicationversion/content-job-failed.yaml index 9432e0f..aab7d0c 100644 --- a/internal/controller/testdata/capapplicationversion/content-job-failed.yaml +++ b/internal/controller/testdata/capapplicationversion/content-job-failed.yaml @@ -56,7 +56,7 @@ spec: dnsPolicy: ClusterFirst imagePullSecrets: - name: regcred - restartPolicy: OnFailure + restartPolicy: Never schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 diff --git a/internal/controller/testdata/capapplicationversion/content-job-pending.yaml b/internal/controller/testdata/capapplicationversion/content-job-pending.yaml index 142fe3c..4798ccb 100644 --- a/internal/controller/testdata/capapplicationversion/content-job-pending.yaml +++ b/internal/controller/testdata/capapplicationversion/content-job-pending.yaml @@ -56,7 +56,7 @@ spec: dnsPolicy: ClusterFirst imagePullSecrets: - name: regcred - restartPolicy: OnFailure + restartPolicy: Never schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 diff --git a/internal/controller/testdata/capapplicationversion/one-of-mulitple-content-job-completed.yaml b/internal/controller/testdata/capapplicationversion/one-of-mulitple-content-job-completed.yaml index 5c1239e..d4d3e77 100644 --- a/internal/controller/testdata/capapplicationversion/one-of-mulitple-content-job-completed.yaml +++ b/internal/controller/testdata/capapplicationversion/one-of-mulitple-content-job-completed.yaml @@ -56,7 +56,7 @@ spec: dnsPolicy: ClusterFirst imagePullSecrets: - name: regcred - restartPolicy: OnFailure + restartPolicy: Never schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 diff --git a/internal/controller/testdata/capapplicationversion/one-of-mulitple-content-job-failed.yaml b/internal/controller/testdata/capapplicationversion/one-of-mulitple-content-job-failed.yaml index 71793d1..e14ee6a 100644 --- a/internal/controller/testdata/capapplicationversion/one-of-mulitple-content-job-failed.yaml +++ b/internal/controller/testdata/capapplicationversion/one-of-mulitple-content-job-failed.yaml @@ -56,7 +56,7 @@ spec: dnsPolicy: ClusterFirst imagePullSecrets: - name: regcred - restartPolicy: OnFailure + restartPolicy: Never schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 diff --git a/pkg/apis/sme.sap.com/v1alpha1/types.go b/pkg/apis/sme.sap.com/v1alpha1/types.go index b5c8cf1..30d8a5b 100644 --- a/pkg/apis/sme.sap.com/v1alpha1/types.go +++ b/pkg/apis/sme.sap.com/v1alpha1/types.go @@ -397,6 +397,8 @@ type CommonDetails struct { TopologySpreadConstraints []corev1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"` // List of containers executed before the main container is started InitContainers []corev1.Container `json:"initContainers,omitempty"` + // Restart policy for the Pod. See: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy + RestartPolicy corev1.RestartPolicy `json:"restartPolicy,omitempty"` } // Configuration of Service Ports for the deployment diff --git a/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/commondetails.go b/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/commondetails.go index e98c7b2..fbc30f6 100644 --- a/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/commondetails.go +++ b/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/commondetails.go @@ -32,6 +32,7 @@ type CommonDetailsApplyConfiguration struct { Tolerations []v1.Toleration `json:"tolerations,omitempty"` TopologySpreadConstraints []v1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"` InitContainers []v1.Container `json:"initContainers,omitempty"` + RestartPolicy *v1.RestartPolicy `json:"restartPolicy,omitempty"` } // CommonDetailsApplyConfiguration constructs a declarative configuration of the CommonDetails type for use with @@ -205,3 +206,11 @@ func (b *CommonDetailsApplyConfiguration) WithInitContainers(values ...v1.Contai } return b } + +// WithRestartPolicy sets the RestartPolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the RestartPolicy field is set to the value of the last call. +func (b *CommonDetailsApplyConfiguration) WithRestartPolicy(value v1.RestartPolicy) *CommonDetailsApplyConfiguration { + b.RestartPolicy = &value + return b +} diff --git a/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/deploymentdetails.go b/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/deploymentdetails.go index ed9cb05..fd8aa0b 100644 --- a/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/deploymentdetails.go +++ b/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/deploymentdetails.go @@ -196,6 +196,14 @@ func (b *DeploymentDetailsApplyConfiguration) WithInitContainers(values ...v1.Co return b } +// WithRestartPolicy sets the RestartPolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the RestartPolicy field is set to the value of the last call. +func (b *DeploymentDetailsApplyConfiguration) WithRestartPolicy(value v1.RestartPolicy) *DeploymentDetailsApplyConfiguration { + b.RestartPolicy = &value + return b +} + // WithType sets the Type field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Type field is set to the value of the last call. diff --git a/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/jobdetails.go b/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/jobdetails.go index f171a2d..72335a3 100644 --- a/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/jobdetails.go +++ b/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/jobdetails.go @@ -193,6 +193,14 @@ func (b *JobDetailsApplyConfiguration) WithInitContainers(values ...v1.Container return b } +// WithRestartPolicy sets the RestartPolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the RestartPolicy field is set to the value of the last call. +func (b *JobDetailsApplyConfiguration) WithRestartPolicy(value v1.RestartPolicy) *JobDetailsApplyConfiguration { + b.RestartPolicy = &value + return b +} + // WithType sets the Type field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Type field is set to the value of the last call.