1
0
Fork 0
mirror of https://github.com/arangodb/kube-arangodb.git synced 2024-12-14 11:57:37 +00:00

[Feature] JobScheduler Volumes, Probes, Lifecycle and Ports integration (#1607)

This commit is contained in:
Adam Janikowski 2024-03-04 13:59:13 +01:00 committed by GitHub
parent e7ae432b24
commit bc0c654e44
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
38 changed files with 11611 additions and 61 deletions

View file

@ -43,6 +43,8 @@ linters-settings:
alias: sharedApi
- pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1
alias: schedulerApi
- pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/profiles
alias: schedulerProfiles
- pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container
alias: schedulerContainerApi
- pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources

View file

@ -7,6 +7,7 @@
- (Bugfix) Wait for ImageStatus in ImageDiscover
- (Bugfix) Fix Image Error Propagation
- (Feature) JobScheduler Coverage
- (Feature) JobScheduler Volumes, Probes, Lifecycle and Ports integration
## [1.2.38](https://github.com/arangodb/kube-arangodb/tree/1.2.38) (2024-02-22)
- (Feature) Extract GRPC Server

View file

@ -130,6 +130,26 @@ ImagePullSecrets define Secrets used to pull Image from registry
***
### .spec.deployment.prediction.lifecycle
Type: `core.Lifecycle` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/lifecycle.go#L35)</sup>
Lifecycle keeps actions that the management system should take in response to container lifecycle events.
***
### .spec.deployment.prediction.livenessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L37)</sup>
LivenessProbe keeps configuration of periodic probe of container liveness.
Container will be restarted if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.deployment.prediction.port
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/ml/v1alpha1/extension_spec_deployment_component.go#L34)</sup>
@ -138,6 +158,29 @@ Port defines on which port the container will be listening for connections
***
### .spec.deployment.prediction.ports
Type: `[]core.ContainerPort` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/networking.go#L39)</sup>
Ports contains list of ports to expose from the container. Not specifying a port here
DOES NOT prevent that port from being exposed. Any port which is
listening on the default "0.0.0.0" address inside a container will be
accessible from the network.
***
### .spec.deployment.prediction.readinessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L42)</sup>
ReadinessProbe keeps configuration of periodic probe of container service readiness.
Container will be removed from service endpoints if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.deployment.prediction.resources
Type: `core.ResourceRequirements` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/resources.go#L37)</sup>
@ -160,6 +203,29 @@ Links:
***
### .spec.deployment.prediction.startupProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L50)</sup>
StartupProbe indicates that the Pod has successfully initialized.
If specified, no other probes are executed until this completes successfully.
If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.
This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,
when it might take a long time to load data or warm a cache, than during steady-state operation.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.deployment.prediction.volumeMounts
Type: `[]core.VolumeMount` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/volume_mounts.go#L35)</sup>
VolumeMounts keeps list of pod volumes to mount into the container's filesystem.
***
### .spec.deployment.project.env
Type: `core.EnvVar` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/environments.go#L36)</sup>
@ -218,6 +284,26 @@ ImagePullSecrets define Secrets used to pull Image from registry
***
### .spec.deployment.project.lifecycle
Type: `core.Lifecycle` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/lifecycle.go#L35)</sup>
Lifecycle keeps actions that the management system should take in response to container lifecycle events.
***
### .spec.deployment.project.livenessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L37)</sup>
LivenessProbe keeps configuration of periodic probe of container liveness.
Container will be restarted if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.deployment.project.port
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/ml/v1alpha1/extension_spec_deployment_component.go#L34)</sup>
@ -226,6 +312,29 @@ Port defines on which port the container will be listening for connections
***
### .spec.deployment.project.ports
Type: `[]core.ContainerPort` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/networking.go#L39)</sup>
Ports contains list of ports to expose from the container. Not specifying a port here
DOES NOT prevent that port from being exposed. Any port which is
listening on the default "0.0.0.0" address inside a container will be
accessible from the network.
***
### .spec.deployment.project.readinessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L42)</sup>
ReadinessProbe keeps configuration of periodic probe of container service readiness.
Container will be removed from service endpoints if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.deployment.project.resources
Type: `core.ResourceRequirements` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/resources.go#L37)</sup>
@ -248,6 +357,29 @@ Links:
***
### .spec.deployment.project.startupProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L50)</sup>
StartupProbe indicates that the Pod has successfully initialized.
If specified, no other probes are executed until this completes successfully.
If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.
This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,
when it might take a long time to load data or warm a cache, than during steady-state operation.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.deployment.project.volumeMounts
Type: `[]core.VolumeMount` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/volume_mounts.go#L35)</sup>
VolumeMounts keeps list of pod volumes to mount into the container's filesystem.
***
### .spec.deployment.replicas
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/ml/v1alpha1/extension_spec_deployment.go#L56)</sup>
@ -368,6 +500,26 @@ ImagePullSecrets define Secrets used to pull Image from registry
***
### .spec.deployment.training.lifecycle
Type: `core.Lifecycle` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/lifecycle.go#L35)</sup>
Lifecycle keeps actions that the management system should take in response to container lifecycle events.
***
### .spec.deployment.training.livenessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L37)</sup>
LivenessProbe keeps configuration of periodic probe of container liveness.
Container will be restarted if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.deployment.training.port
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/ml/v1alpha1/extension_spec_deployment_component.go#L34)</sup>
@ -376,6 +528,29 @@ Port defines on which port the container will be listening for connections
***
### .spec.deployment.training.ports
Type: `[]core.ContainerPort` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/networking.go#L39)</sup>
Ports contains list of ports to expose from the container. Not specifying a port here
DOES NOT prevent that port from being exposed. Any port which is
listening on the default "0.0.0.0" address inside a container will be
accessible from the network.
***
### .spec.deployment.training.readinessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L42)</sup>
ReadinessProbe keeps configuration of periodic probe of container service readiness.
Container will be removed from service endpoints if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.deployment.training.resources
Type: `core.ResourceRequirements` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/resources.go#L37)</sup>
@ -398,6 +573,40 @@ Links:
***
### .spec.deployment.training.startupProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L50)</sup>
StartupProbe indicates that the Pod has successfully initialized.
If specified, no other probes are executed until this completes successfully.
If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.
This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,
when it might take a long time to load data or warm a cache, than during steady-state operation.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.deployment.training.volumeMounts
Type: `[]core.VolumeMount` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/volume_mounts.go#L35)</sup>
VolumeMounts keeps list of pod volumes to mount into the container's filesystem.
***
### .spec.deployment.volumes
Type: `[]core.Volume` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/volumes.go#L36)</sup>
Volumes keeps list of volumes that can be mounted by containers belonging to the pod.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/storage/volumes)
***
### .spec.image
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/image.go#L37)</sup>
@ -514,6 +723,26 @@ ImagePullSecrets define Secrets used to pull Image from registry
***
### .spec.init.lifecycle
Type: `core.Lifecycle` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/lifecycle.go#L35)</sup>
Lifecycle keeps actions that the management system should take in response to container lifecycle events.
***
### .spec.init.livenessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L37)</sup>
LivenessProbe keeps configuration of periodic probe of container liveness.
Container will be restarted if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.init.nodeSelector
Type: `object` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L39)</sup>
@ -536,6 +765,29 @@ Links:
***
### .spec.init.ports
Type: `[]core.ContainerPort` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/networking.go#L39)</sup>
Ports contains list of ports to expose from the container. Not specifying a port here
DOES NOT prevent that port from being exposed. Any port which is
listening on the default "0.0.0.0" address inside a container will be
accessible from the network.
***
### .spec.init.readinessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L42)</sup>
ReadinessProbe keeps configuration of periodic probe of container service readiness.
Container will be removed from service endpoints if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.init.resources
Type: `core.ResourceRequirements` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/resources.go#L37)</sup>
@ -582,6 +834,21 @@ Default Value: `false`
***
### .spec.init.startupProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L50)</sup>
StartupProbe indicates that the Pod has successfully initialized.
If specified, no other probes are executed until this completes successfully.
If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.
This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,
when it might take a long time to load data or warm a cache, than during steady-state operation.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.init.tolerations
Type: `[]core.Toleration` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L49)</sup>
@ -593,6 +860,25 @@ Links:
***
### .spec.init.volumeMounts
Type: `[]core.VolumeMount` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/volume_mounts.go#L35)</sup>
VolumeMounts keeps list of pod volumes to mount into the container's filesystem.
***
### .spec.init.volumes
Type: `[]core.Volume` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/volumes.go#L36)</sup>
Volumes keeps list of volumes that can be mounted by containers belonging to the pod.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/storage/volumes)
***
### .spec.jobsTemplates.featurization.cpu.affinity
Type: `core.Affinity` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L44)</sup>
@ -683,6 +969,26 @@ ImagePullSecrets define Secrets used to pull Image from registry
***
### .spec.jobsTemplates.featurization.cpu.lifecycle
Type: `core.Lifecycle` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/lifecycle.go#L35)</sup>
Lifecycle keeps actions that the management system should take in response to container lifecycle events.
***
### .spec.jobsTemplates.featurization.cpu.livenessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L37)</sup>
LivenessProbe keeps configuration of periodic probe of container liveness.
Container will be restarted if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.jobsTemplates.featurization.cpu.nodeSelector
Type: `object` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L39)</sup>
@ -705,6 +1011,29 @@ Links:
***
### .spec.jobsTemplates.featurization.cpu.ports
Type: `[]core.ContainerPort` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/networking.go#L39)</sup>
Ports contains list of ports to expose from the container. Not specifying a port here
DOES NOT prevent that port from being exposed. Any port which is
listening on the default "0.0.0.0" address inside a container will be
accessible from the network.
***
### .spec.jobsTemplates.featurization.cpu.readinessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L42)</sup>
ReadinessProbe keeps configuration of periodic probe of container service readiness.
Container will be removed from service endpoints if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.jobsTemplates.featurization.cpu.resources
Type: `core.ResourceRequirements` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/resources.go#L37)</sup>
@ -751,6 +1080,21 @@ Default Value: `false`
***
### .spec.jobsTemplates.featurization.cpu.startupProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L50)</sup>
StartupProbe indicates that the Pod has successfully initialized.
If specified, no other probes are executed until this completes successfully.
If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.
This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,
when it might take a long time to load data or warm a cache, than during steady-state operation.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.jobsTemplates.featurization.cpu.tolerations
Type: `[]core.Toleration` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L49)</sup>
@ -762,6 +1106,25 @@ Links:
***
### .spec.jobsTemplates.featurization.cpu.volumeMounts
Type: `[]core.VolumeMount` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/volume_mounts.go#L35)</sup>
VolumeMounts keeps list of pod volumes to mount into the container's filesystem.
***
### .spec.jobsTemplates.featurization.cpu.volumes
Type: `[]core.Volume` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/volumes.go#L36)</sup>
Volumes keeps list of volumes that can be mounted by containers belonging to the pod.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/storage/volumes)
***
### .spec.jobsTemplates.featurization.gpu.affinity
Type: `core.Affinity` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L44)</sup>
@ -852,6 +1215,26 @@ ImagePullSecrets define Secrets used to pull Image from registry
***
### .spec.jobsTemplates.featurization.gpu.lifecycle
Type: `core.Lifecycle` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/lifecycle.go#L35)</sup>
Lifecycle keeps actions that the management system should take in response to container lifecycle events.
***
### .spec.jobsTemplates.featurization.gpu.livenessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L37)</sup>
LivenessProbe keeps configuration of periodic probe of container liveness.
Container will be restarted if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.jobsTemplates.featurization.gpu.nodeSelector
Type: `object` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L39)</sup>
@ -874,6 +1257,29 @@ Links:
***
### .spec.jobsTemplates.featurization.gpu.ports
Type: `[]core.ContainerPort` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/networking.go#L39)</sup>
Ports contains list of ports to expose from the container. Not specifying a port here
DOES NOT prevent that port from being exposed. Any port which is
listening on the default "0.0.0.0" address inside a container will be
accessible from the network.
***
### .spec.jobsTemplates.featurization.gpu.readinessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L42)</sup>
ReadinessProbe keeps configuration of periodic probe of container service readiness.
Container will be removed from service endpoints if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.jobsTemplates.featurization.gpu.resources
Type: `core.ResourceRequirements` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/resources.go#L37)</sup>
@ -920,6 +1326,21 @@ Default Value: `false`
***
### .spec.jobsTemplates.featurization.gpu.startupProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L50)</sup>
StartupProbe indicates that the Pod has successfully initialized.
If specified, no other probes are executed until this completes successfully.
If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.
This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,
when it might take a long time to load data or warm a cache, than during steady-state operation.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.jobsTemplates.featurization.gpu.tolerations
Type: `[]core.Toleration` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L49)</sup>
@ -931,6 +1352,25 @@ Links:
***
### .spec.jobsTemplates.featurization.gpu.volumeMounts
Type: `[]core.VolumeMount` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/volume_mounts.go#L35)</sup>
VolumeMounts keeps list of pod volumes to mount into the container's filesystem.
***
### .spec.jobsTemplates.featurization.gpu.volumes
Type: `[]core.Volume` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/volumes.go#L36)</sup>
Volumes keeps list of volumes that can be mounted by containers belonging to the pod.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/storage/volumes)
***
### .spec.jobsTemplates.prediction.cpu.affinity
Type: `core.Affinity` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L44)</sup>
@ -1021,6 +1461,26 @@ ImagePullSecrets define Secrets used to pull Image from registry
***
### .spec.jobsTemplates.prediction.cpu.lifecycle
Type: `core.Lifecycle` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/lifecycle.go#L35)</sup>
Lifecycle keeps actions that the management system should take in response to container lifecycle events.
***
### .spec.jobsTemplates.prediction.cpu.livenessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L37)</sup>
LivenessProbe keeps configuration of periodic probe of container liveness.
Container will be restarted if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.jobsTemplates.prediction.cpu.nodeSelector
Type: `object` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L39)</sup>
@ -1043,6 +1503,29 @@ Links:
***
### .spec.jobsTemplates.prediction.cpu.ports
Type: `[]core.ContainerPort` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/networking.go#L39)</sup>
Ports contains list of ports to expose from the container. Not specifying a port here
DOES NOT prevent that port from being exposed. Any port which is
listening on the default "0.0.0.0" address inside a container will be
accessible from the network.
***
### .spec.jobsTemplates.prediction.cpu.readinessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L42)</sup>
ReadinessProbe keeps configuration of periodic probe of container service readiness.
Container will be removed from service endpoints if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.jobsTemplates.prediction.cpu.resources
Type: `core.ResourceRequirements` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/resources.go#L37)</sup>
@ -1089,6 +1572,21 @@ Default Value: `false`
***
### .spec.jobsTemplates.prediction.cpu.startupProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L50)</sup>
StartupProbe indicates that the Pod has successfully initialized.
If specified, no other probes are executed until this completes successfully.
If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.
This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,
when it might take a long time to load data or warm a cache, than during steady-state operation.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.jobsTemplates.prediction.cpu.tolerations
Type: `[]core.Toleration` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L49)</sup>
@ -1100,6 +1598,25 @@ Links:
***
### .spec.jobsTemplates.prediction.cpu.volumeMounts
Type: `[]core.VolumeMount` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/volume_mounts.go#L35)</sup>
VolumeMounts keeps list of pod volumes to mount into the container's filesystem.
***
### .spec.jobsTemplates.prediction.cpu.volumes
Type: `[]core.Volume` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/volumes.go#L36)</sup>
Volumes keeps list of volumes that can be mounted by containers belonging to the pod.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/storage/volumes)
***
### .spec.jobsTemplates.prediction.gpu.affinity
Type: `core.Affinity` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L44)</sup>
@ -1190,6 +1707,26 @@ ImagePullSecrets define Secrets used to pull Image from registry
***
### .spec.jobsTemplates.prediction.gpu.lifecycle
Type: `core.Lifecycle` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/lifecycle.go#L35)</sup>
Lifecycle keeps actions that the management system should take in response to container lifecycle events.
***
### .spec.jobsTemplates.prediction.gpu.livenessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L37)</sup>
LivenessProbe keeps configuration of periodic probe of container liveness.
Container will be restarted if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.jobsTemplates.prediction.gpu.nodeSelector
Type: `object` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L39)</sup>
@ -1212,6 +1749,29 @@ Links:
***
### .spec.jobsTemplates.prediction.gpu.ports
Type: `[]core.ContainerPort` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/networking.go#L39)</sup>
Ports contains list of ports to expose from the container. Not specifying a port here
DOES NOT prevent that port from being exposed. Any port which is
listening on the default "0.0.0.0" address inside a container will be
accessible from the network.
***
### .spec.jobsTemplates.prediction.gpu.readinessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L42)</sup>
ReadinessProbe keeps configuration of periodic probe of container service readiness.
Container will be removed from service endpoints if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.jobsTemplates.prediction.gpu.resources
Type: `core.ResourceRequirements` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/resources.go#L37)</sup>
@ -1258,6 +1818,21 @@ Default Value: `false`
***
### .spec.jobsTemplates.prediction.gpu.startupProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L50)</sup>
StartupProbe indicates that the Pod has successfully initialized.
If specified, no other probes are executed until this completes successfully.
If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.
This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,
when it might take a long time to load data or warm a cache, than during steady-state operation.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.jobsTemplates.prediction.gpu.tolerations
Type: `[]core.Toleration` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L49)</sup>
@ -1269,6 +1844,25 @@ Links:
***
### .spec.jobsTemplates.prediction.gpu.volumeMounts
Type: `[]core.VolumeMount` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/volume_mounts.go#L35)</sup>
VolumeMounts keeps list of pod volumes to mount into the container's filesystem.
***
### .spec.jobsTemplates.prediction.gpu.volumes
Type: `[]core.Volume` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/volumes.go#L36)</sup>
Volumes keeps list of volumes that can be mounted by containers belonging to the pod.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/storage/volumes)
***
### .spec.jobsTemplates.training.cpu.affinity
Type: `core.Affinity` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L44)</sup>
@ -1359,6 +1953,26 @@ ImagePullSecrets define Secrets used to pull Image from registry
***
### .spec.jobsTemplates.training.cpu.lifecycle
Type: `core.Lifecycle` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/lifecycle.go#L35)</sup>
Lifecycle keeps actions that the management system should take in response to container lifecycle events.
***
### .spec.jobsTemplates.training.cpu.livenessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L37)</sup>
LivenessProbe keeps configuration of periodic probe of container liveness.
Container will be restarted if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.jobsTemplates.training.cpu.nodeSelector
Type: `object` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L39)</sup>
@ -1381,6 +1995,29 @@ Links:
***
### .spec.jobsTemplates.training.cpu.ports
Type: `[]core.ContainerPort` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/networking.go#L39)</sup>
Ports contains list of ports to expose from the container. Not specifying a port here
DOES NOT prevent that port from being exposed. Any port which is
listening on the default "0.0.0.0" address inside a container will be
accessible from the network.
***
### .spec.jobsTemplates.training.cpu.readinessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L42)</sup>
ReadinessProbe keeps configuration of periodic probe of container service readiness.
Container will be removed from service endpoints if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.jobsTemplates.training.cpu.resources
Type: `core.ResourceRequirements` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/resources.go#L37)</sup>
@ -1427,6 +2064,21 @@ Default Value: `false`
***
### .spec.jobsTemplates.training.cpu.startupProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L50)</sup>
StartupProbe indicates that the Pod has successfully initialized.
If specified, no other probes are executed until this completes successfully.
If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.
This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,
when it might take a long time to load data or warm a cache, than during steady-state operation.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.jobsTemplates.training.cpu.tolerations
Type: `[]core.Toleration` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L49)</sup>
@ -1438,6 +2090,25 @@ Links:
***
### .spec.jobsTemplates.training.cpu.volumeMounts
Type: `[]core.VolumeMount` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/volume_mounts.go#L35)</sup>
VolumeMounts keeps list of pod volumes to mount into the container's filesystem.
***
### .spec.jobsTemplates.training.cpu.volumes
Type: `[]core.Volume` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/volumes.go#L36)</sup>
Volumes keeps list of volumes that can be mounted by containers belonging to the pod.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/storage/volumes)
***
### .spec.jobsTemplates.training.gpu.affinity
Type: `core.Affinity` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L44)</sup>
@ -1528,6 +2199,26 @@ ImagePullSecrets define Secrets used to pull Image from registry
***
### .spec.jobsTemplates.training.gpu.lifecycle
Type: `core.Lifecycle` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/lifecycle.go#L35)</sup>
Lifecycle keeps actions that the management system should take in response to container lifecycle events.
***
### .spec.jobsTemplates.training.gpu.livenessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L37)</sup>
LivenessProbe keeps configuration of periodic probe of container liveness.
Container will be restarted if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.jobsTemplates.training.gpu.nodeSelector
Type: `object` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L39)</sup>
@ -1550,6 +2241,29 @@ Links:
***
### .spec.jobsTemplates.training.gpu.ports
Type: `[]core.ContainerPort` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/networking.go#L39)</sup>
Ports contains list of ports to expose from the container. Not specifying a port here
DOES NOT prevent that port from being exposed. Any port which is
listening on the default "0.0.0.0" address inside a container will be
accessible from the network.
***
### .spec.jobsTemplates.training.gpu.readinessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L42)</sup>
ReadinessProbe keeps configuration of periodic probe of container service readiness.
Container will be removed from service endpoints if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.jobsTemplates.training.gpu.resources
Type: `core.ResourceRequirements` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/resources.go#L37)</sup>
@ -1596,6 +2310,21 @@ Default Value: `false`
***
### .spec.jobsTemplates.training.gpu.startupProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L50)</sup>
StartupProbe indicates that the Pod has successfully initialized.
If specified, no other probes are executed until this completes successfully.
If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.
This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,
when it might take a long time to load data or warm a cache, than during steady-state operation.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.jobsTemplates.training.gpu.tolerations
Type: `[]core.Toleration` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L49)</sup>
@ -1607,6 +2336,25 @@ Links:
***
### .spec.jobsTemplates.training.gpu.volumeMounts
Type: `[]core.VolumeMount` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/volume_mounts.go#L35)</sup>
VolumeMounts keeps list of pod volumes to mount into the container's filesystem.
***
### .spec.jobsTemplates.training.gpu.volumes
Type: `[]core.Volume` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/pod/resources/volumes.go#L36)</sup>
Volumes keeps list of volumes that can be mounted by containers belonging to the pod.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/storage/volumes)
***
### .spec.metadataService.local.arangoMLFeatureStore
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/ml/v1alpha1/extension_spec_metadata_service.go#L65)</sup>

View file

@ -162,6 +162,14 @@ ImagePullSecrets define Secrets used to pull Image from registry
***
### .spec.mode.sidecar.lifecycle
Type: `core.Lifecycle` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/lifecycle.go#L35)</sup>
Lifecycle keeps actions that the management system should take in response to container lifecycle events.
***
### .spec.mode.sidecar.listenPort
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/ml/v1alpha1/storage_spec_mode_sidecar.go#L32)</sup>
@ -172,6 +180,41 @@ Default Value: `9201`
***
### .spec.mode.sidecar.livenessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L37)</sup>
LivenessProbe keeps configuration of periodic probe of container liveness.
Container will be restarted if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.mode.sidecar.ports
Type: `[]core.ContainerPort` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/networking.go#L39)</sup>
Ports contains list of ports to expose from the container. Not specifying a port here
DOES NOT prevent that port from being exposed. Any port which is
listening on the default "0.0.0.0" address inside a container will be
accessible from the network.
***
### .spec.mode.sidecar.readinessProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L42)</sup>
ReadinessProbe keeps configuration of periodic probe of container service readiness.
Container will be removed from service endpoints if the probe fails.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.mode.sidecar.resources
Type: `core.ResourceRequirements` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/resources.go#L37)</sup>
@ -192,6 +235,29 @@ SecurityContext holds container-level security attributes and common container s
Links:
* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
***
### .spec.mode.sidecar.startupProbe
Type: `core.Probe` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/probes.go#L50)</sup>
StartupProbe indicates that the Pod has successfully initialized.
If specified, no other probes are executed until this completes successfully.
If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.
This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,
when it might take a long time to load data or warm a cache, than during steady-state operation.
Links:
* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes)
***
### .spec.mode.sidecar.volumeMounts
Type: `[]core.VolumeMount` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.38/pkg/apis/scheduler/v1alpha1/container/resources/volume_mounts.go#L35)</sup>
VolumeMounts keeps list of pod volumes to mount into the container's filesystem.
## Status
### .status.conditions

View file

@ -110,11 +110,23 @@ type Container struct {
// Environments keeps the environment variables for Container
*schedulerContainerResourcesApi.Environments `json:",inline"`
// Image define default image used for the job
// Image define default image used for the Container
*schedulerContainerResourcesApi.Image `json:",inline"`
// Resources define resources assigned to the pod
// Resources define resources assigned to the Container
*schedulerContainerResourcesApi.Resources `json:",inline"`
// VolumeMounts define volume mounts assigned to the Container
*schedulerContainerResourcesApi.VolumeMounts `json:",inline"`
// Probes define probes assigned to the Container
*schedulerContainerResourcesApi.Probes `json:",inline"`
// Networking define networking assigned to the Container
*schedulerContainerResourcesApi.Networking `json:",inline"`
// Lifecycle define lifecycle assigned to the Container
*schedulerContainerResourcesApi.Lifecycle `json:",inline"`
}
func (c *Container) Apply(template *core.PodTemplateSpec, container *core.Container) error {
@ -127,6 +139,10 @@ func (c *Container) Apply(template *core.PodTemplateSpec, container *core.Contai
c.Environments.Apply(template, container),
c.Image.Apply(template, container),
c.Resources.Apply(template, container),
c.VolumeMounts.Apply(template, container),
c.Probes.Apply(template, container),
c.Networking.Apply(template, container),
c.Lifecycle.Apply(template, container),
)
}
@ -162,6 +178,38 @@ func (c *Container) GetEnvironments() *schedulerContainerResourcesApi.Environmen
return c.Environments
}
func (c *Container) GetVolumeMounts() *schedulerContainerResourcesApi.VolumeMounts {
if c == nil || c.VolumeMounts == nil {
return nil
}
return c.VolumeMounts
}
func (c *Container) GetProbes() *schedulerContainerResourcesApi.Probes {
if c == nil || c.Probes == nil {
return nil
}
return c.Probes
}
func (c *Container) GetNetworking() *schedulerContainerResourcesApi.Networking {
if c == nil || c.Networking == nil {
return nil
}
return c.Networking
}
func (c *Container) GetLifecycle() *schedulerContainerResourcesApi.Lifecycle {
if c == nil || c.Lifecycle == nil {
return nil
}
return c.Lifecycle
}
func (c *Container) With(other *Container) *Container {
if c == nil && other == nil {
return nil
@ -180,6 +228,10 @@ func (c *Container) With(other *Container) *Container {
Environments: c.Environments.With(other.Environments),
Image: c.Image.With(other.Image),
Resources: c.Resources.With(other.Resources),
VolumeMounts: c.VolumeMounts.With(other.VolumeMounts),
Lifecycle: c.Lifecycle.With(other.Lifecycle),
Networking: c.Networking.With(other.Networking),
Probes: c.Probes.With(other.Probes),
}
}
@ -193,5 +245,9 @@ func (c *Container) Validate() error {
shared.PrefixResourceErrors("containerEnvironments", c.Environments.Validate()),
shared.PrefixResourceErrors("containerResources", c.Image.Validate()),
shared.PrefixResourceErrors("containerImage", c.Resources.Validate()),
shared.PrefixResourceErrors("volumeMounts", c.VolumeMounts.Validate()),
shared.PrefixResourceErrors("lifecycle", c.Lifecycle.Validate()),
shared.PrefixResourceErrors("networking", c.Networking.Validate()),
shared.PrefixResourceErrors("probes", c.Probes.Validate()),
)
}

View file

@ -129,6 +129,46 @@ func Test_Container(t *testing.T) {
},
},
},
VolumeMounts: &schedulerContainerResourcesApi.VolumeMounts{
VolumeMounts: []core.VolumeMount{
{
Name: "TEST",
MountPath: "/data",
},
},
},
Probes: &schedulerContainerResourcesApi.Probes{
LivenessProbe: &core.Probe{
InitialDelaySeconds: 1,
},
ReadinessProbe: &core.Probe{
InitialDelaySeconds: 2,
},
StartupProbe: &core.Probe{
InitialDelaySeconds: 3,
},
},
Lifecycle: &schedulerContainerResourcesApi.Lifecycle{
Lifecycle: &core.Lifecycle{
PostStart: &core.LifecycleHandler{
HTTPGet: &core.HTTPGetAction{
Path: "test1",
},
},
PreStop: &core.LifecycleHandler{
HTTPGet: &core.HTTPGetAction{
Path: "test2",
},
},
},
},
Networking: &schedulerContainerResourcesApi.Networking{
Ports: []core.ContainerPort{
{
Name: "TEST",
},
},
},
})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container, spec *Container) {
// Spec
require.NotNil(t, spec.Resources)
@ -149,6 +189,31 @@ func Test_Container(t *testing.T) {
require.Len(t, spec.Environments.Env, 1)
require.EqualValues(t, "key1", spec.Environments.Env[0].Name)
require.EqualValues(t, "value1", spec.Environments.Env[0].Value)
require.NotNil(t, spec.VolumeMounts)
require.Len(t, spec.VolumeMounts.VolumeMounts, 1)
require.EqualValues(t, "TEST", spec.VolumeMounts.VolumeMounts[0].Name)
require.NotNil(t, spec.Probes)
require.NotNil(t, spec.Probes.LivenessProbe)
require.EqualValues(t, 1, spec.Probes.LivenessProbe.InitialDelaySeconds)
require.NotNil(t, spec.Probes.ReadinessProbe)
require.EqualValues(t, 2, spec.Probes.ReadinessProbe.InitialDelaySeconds)
require.NotNil(t, spec.Probes.StartupProbe)
require.EqualValues(t, 3, spec.Probes.StartupProbe.InitialDelaySeconds)
require.NotNil(t, spec.Lifecycle)
require.NotNil(t, spec.Lifecycle.Lifecycle)
require.NotNil(t, spec.Lifecycle.Lifecycle.PostStart)
require.NotNil(t, spec.Lifecycle.Lifecycle.PostStart.HTTPGet)
require.EqualValues(t, "test1", spec.Lifecycle.Lifecycle.PostStart.HTTPGet.Path)
require.NotNil(t, spec.Lifecycle.Lifecycle.PreStop)
require.NotNil(t, spec.Lifecycle.Lifecycle.PreStop.HTTPGet)
require.EqualValues(t, "test2", spec.Lifecycle.Lifecycle.PreStop.HTTPGet.Path)
require.NotNil(t, spec.Networking)
require.Len(t, spec.Networking.Ports, 1)
require.EqualValues(t, "TEST", spec.Networking.Ports[0].Name)
})
})
}
@ -169,6 +234,29 @@ image: test
resources:
limits:
cpu: 1
volumeMounts:
- name: TEST
livenessProbe:
initialDelaySeconds: 1
readinessProbe:
initialDelaySeconds: 2
startupProbe:
initialDelaySeconds: 3
lifecycle:
postStart:
httpGet:
path: test1
preStop:
httpGet:
path: test2
ports:
- name: TEST
`, `
---
@ -194,6 +282,31 @@ securityContext:
require.Len(t, spec.Environments.Env, 1)
require.EqualValues(t, "key1", spec.Environments.Env[0].Name)
require.EqualValues(t, "value1", spec.Environments.Env[0].Value)
require.NotNil(t, spec.VolumeMounts)
require.Len(t, spec.VolumeMounts.VolumeMounts, 1)
require.EqualValues(t, "TEST", spec.VolumeMounts.VolumeMounts[0].Name)
require.NotNil(t, spec.Probes)
require.NotNil(t, spec.Probes.LivenessProbe)
require.EqualValues(t, 1, spec.Probes.LivenessProbe.InitialDelaySeconds)
require.NotNil(t, spec.Probes.ReadinessProbe)
require.EqualValues(t, 2, spec.Probes.ReadinessProbe.InitialDelaySeconds)
require.NotNil(t, spec.Probes.StartupProbe)
require.EqualValues(t, 3, spec.Probes.StartupProbe.InitialDelaySeconds)
require.NotNil(t, spec.Lifecycle)
require.NotNil(t, spec.Lifecycle.Lifecycle)
require.NotNil(t, spec.Lifecycle.Lifecycle.PostStart)
require.NotNil(t, spec.Lifecycle.Lifecycle.PostStart.HTTPGet)
require.EqualValues(t, "test1", spec.Lifecycle.Lifecycle.PostStart.HTTPGet.Path)
require.NotNil(t, spec.Lifecycle.Lifecycle.PreStop)
require.NotNil(t, spec.Lifecycle.Lifecycle.PreStop.HTTPGet)
require.EqualValues(t, "test2", spec.Lifecycle.Lifecycle.PreStop.HTTPGet.Path)
require.NotNil(t, spec.Networking)
require.Len(t, spec.Networking.Ports, 1)
require.EqualValues(t, "TEST", spec.Networking.Ports[0].Name)
})
})
t.Run("With fields", func(t *testing.T) {

View file

@ -24,7 +24,7 @@ import (
core "k8s.io/api/core/v1"
"github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/interfaces"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/envs"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources"
)
var _ interfaces.Container[Environments] = &Environments{}
@ -46,8 +46,8 @@ func (e *Environments) Apply(_ *core.PodTemplateSpec, container *core.Container)
return nil
}
container.Env = envs.MergeEnvs(container.Env, e.Env...)
container.EnvFrom = envs.MergeEnvFrom(container.EnvFrom, e.EnvFrom...)
container.Env = resources.MergeEnvs(container.Env, e.Env...)
container.EnvFrom = resources.MergeEnvFrom(container.EnvFrom, e.EnvFrom...)
return nil
}
@ -66,8 +66,8 @@ func (e *Environments) With(other *Environments) *Environments {
}
return &Environments{
Env: envs.MergeEnvs(e.Env, other.Env...),
EnvFrom: envs.MergeEnvFrom(e.EnvFrom, other.EnvFrom...),
Env: resources.MergeEnvs(e.Env, other.Env...),
EnvFrom: resources.MergeEnvFrom(e.EnvFrom, other.EnvFrom...),
}
}

View file

@ -0,0 +1,68 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package resources
import (
core "k8s.io/api/core/v1"
"github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/interfaces"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources"
)
var _ interfaces.Container[Lifecycle] = &Lifecycle{}
type Lifecycle struct {
// Lifecycle keeps actions that the management system should take in response to container lifecycle events.
// +doc/type: core.Lifecycle
Lifecycle *core.Lifecycle `json:"lifecycle,omitempty"`
}
func (n *Lifecycle) Apply(_ *core.PodTemplateSpec, template *core.Container) error {
if n == nil {
return nil
}
template.Lifecycle = n.Lifecycle.DeepCopy()
return nil
}
func (n *Lifecycle) With(newResources *Lifecycle) *Lifecycle {
if n == nil && newResources == nil {
return nil
}
if n == nil {
return newResources.DeepCopy()
}
if newResources == nil {
return n.DeepCopy()
}
return &Lifecycle{
Lifecycle: resources.MergeLifecycle(n.Lifecycle, newResources.Lifecycle),
}
}
func (n *Lifecycle) Validate() error {
return nil
}

View file

@ -0,0 +1,181 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package resources
import (
"testing"
"github.com/stretchr/testify/require"
core "k8s.io/api/core/v1"
)
func applyLifecycle(t *testing.T, template *core.PodTemplateSpec, container *core.Container, ns ...*Lifecycle) func(in func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container)) {
var i *Lifecycle
for _, n := range ns {
require.NoError(t, n.Validate())
i = i.With(n)
require.NoError(t, i.Validate())
}
template = template.DeepCopy()
if template == nil {
template = &core.PodTemplateSpec{}
}
container = container.DeepCopy()
if container == nil {
container = &core.Container{}
}
template.Spec.Containers = append(template.Spec.Containers, *container)
container = &template.Spec.Containers[0]
require.NoError(t, i.Apply(template, container))
return func(in func(t *testing.T, spec *core.PodTemplateSpec, container *core.Container)) {
t.Run("Validate", func(t *testing.T) {
in(t, template, container)
})
}
}
func Test_Lifecycle(t *testing.T) {
t.Run("With Nil", func(t *testing.T) {
applyLifecycle(t, nil, nil)(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.Nil(t, container.Lifecycle)
})
})
t.Run("With Empty", func(t *testing.T) {
applyLifecycle(t, &core.PodTemplateSpec{}, &core.Container{})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.Nil(t, container.Lifecycle)
})
})
t.Run("With lifecycles", func(t *testing.T) {
applyLifecycle(t, &core.PodTemplateSpec{}, &core.Container{}, &Lifecycle{
Lifecycle: &core.Lifecycle{
PostStart: &core.LifecycleHandler{
Exec: &core.ExecAction{
Command: []string{"test"},
},
},
PreStop: &core.LifecycleHandler{
HTTPGet: &core.HTTPGetAction{
Path: "/test",
},
},
},
})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.NotNil(t, container.Lifecycle)
require.NotNil(t, container.Lifecycle.PostStart)
require.NotNil(t, container.Lifecycle.PostStart.Exec)
require.Nil(t, container.Lifecycle.PostStart.HTTPGet)
require.Len(t, container.Lifecycle.PostStart.Exec.Command, 1)
require.EqualValues(t, "test", container.Lifecycle.PostStart.Exec.Command[0])
require.NotNil(t, container.Lifecycle.PreStop)
require.Nil(t, container.Lifecycle.PreStop.Exec)
require.NotNil(t, container.Lifecycle.PreStop.HTTPGet)
require.EqualValues(t, "/test", container.Lifecycle.PreStop.HTTPGet.Path)
})
})
t.Run("With merge", func(t *testing.T) {
applyLifecycle(t, &core.PodTemplateSpec{}, &core.Container{},
&Lifecycle{
Lifecycle: &core.Lifecycle{
PostStart: &core.LifecycleHandler{
Exec: &core.ExecAction{
Command: []string{"test"},
},
},
},
},
&Lifecycle{
Lifecycle: &core.Lifecycle{
PreStop: &core.LifecycleHandler{
HTTPGet: &core.HTTPGetAction{
Path: "/test",
},
},
},
})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.NotNil(t, container.Lifecycle)
require.NotNil(t, container.Lifecycle.PostStart)
require.NotNil(t, container.Lifecycle.PostStart.Exec)
require.Nil(t, container.Lifecycle.PostStart.HTTPGet)
require.Len(t, container.Lifecycle.PostStart.Exec.Command, 1)
require.EqualValues(t, "test", container.Lifecycle.PostStart.Exec.Command[0])
require.NotNil(t, container.Lifecycle.PreStop)
require.Nil(t, container.Lifecycle.PreStop.Exec)
require.NotNil(t, container.Lifecycle.PreStop.HTTPGet)
require.EqualValues(t, "/test", container.Lifecycle.PreStop.HTTPGet.Path)
})
})
t.Run("With override", func(t *testing.T) {
applyLifecycle(t, &core.PodTemplateSpec{}, &core.Container{}, &Lifecycle{
Lifecycle: &core.Lifecycle{
PostStart: &core.LifecycleHandler{
Exec: &core.ExecAction{
Command: []string{"test"},
},
},
PreStop: &core.LifecycleHandler{
HTTPGet: &core.HTTPGetAction{
Path: "/test",
},
},
},
}, &Lifecycle{
Lifecycle: &core.Lifecycle{
PostStart: &core.LifecycleHandler{
HTTPGet: &core.HTTPGetAction{
Path: "/test",
},
},
PreStop: &core.LifecycleHandler{
Exec: &core.ExecAction{
Command: []string{"test"},
},
},
},
})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.NotNil(t, container.Lifecycle)
require.NotNil(t, container.Lifecycle.PreStop)
require.NotNil(t, container.Lifecycle.PreStop.Exec)
require.Nil(t, container.Lifecycle.PreStop.HTTPGet)
require.Len(t, container.Lifecycle.PreStop.Exec.Command, 1)
require.EqualValues(t, "test", container.Lifecycle.PreStop.Exec.Command[0])
require.NotNil(t, container.Lifecycle.PostStart)
require.Nil(t, container.Lifecycle.PostStart.Exec)
require.NotNil(t, container.Lifecycle.PostStart.HTTPGet)
require.EqualValues(t, "/test", container.Lifecycle.PostStart.HTTPGet.Path)
})
})
}

View file

@ -0,0 +1,86 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package resources
import (
core "k8s.io/api/core/v1"
"github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/interfaces"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources"
)
var _ interfaces.Container[Networking] = &Networking{}
type Networking struct {
// Ports contains list of ports to expose from the container. Not specifying a port here
// DOES NOT prevent that port from being exposed. Any port which is
// listening on the default "0.0.0.0" address inside a container will be
// accessible from the network.
// +doc/type: []core.ContainerPort
Ports []core.ContainerPort `json:"ports,omitempty"`
}
func (n *Networking) Apply(pod *core.PodTemplateSpec, template *core.Container) error {
if n == nil {
return nil
}
for _, port := range n.Ports {
if port.Name == "" {
continue
}
for _, container := range pod.Spec.Containers {
for _, existingPort := range container.Ports {
if port.Name == existingPort.Name {
return errors.Errorf("Port with name `%s` already exposed in container `%s`", port.Name, container.Name)
}
}
}
}
obj := n.DeepCopy()
template.Ports = obj.Ports
return nil
}
func (n *Networking) With(newResources *Networking) *Networking {
if n == nil && newResources == nil {
return nil
}
if n == nil {
return newResources.DeepCopy()
}
if newResources == nil {
return n.DeepCopy()
}
return &Networking{Ports: resources.MergeContainerPorts(n.Ports, newResources.Ports...)}
}
func (n *Networking) Validate() error {
return nil
}

View file

@ -0,0 +1,140 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package resources
import (
"testing"
"github.com/stretchr/testify/require"
core "k8s.io/api/core/v1"
)
func applyNetworking(t *testing.T, template *core.PodTemplateSpec, container *core.Container, ns ...*Networking) func(in func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container)) {
var i *Networking
for _, n := range ns {
require.NoError(t, n.Validate())
i = i.With(n)
require.NoError(t, i.Validate())
}
template = template.DeepCopy()
if template == nil {
template = &core.PodTemplateSpec{}
}
container = container.DeepCopy()
if container == nil {
container = &core.Container{}
}
template.Spec.Containers = append(template.Spec.Containers, *container)
container = &template.Spec.Containers[0]
require.NoError(t, i.Apply(template, container))
return func(in func(t *testing.T, spec *core.PodTemplateSpec, container *core.Container)) {
t.Run("Validate", func(t *testing.T) {
in(t, template, container)
})
}
}
func Test_Networking(t *testing.T) {
t.Run("With Nil", func(t *testing.T) {
applyNetworking(t, nil, nil)(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.Len(t, container.Ports, 0)
})
})
t.Run("With Empty", func(t *testing.T) {
applyNetworking(t, &core.PodTemplateSpec{}, &core.Container{})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.Len(t, container.Ports, 0)
})
})
t.Run("With Port", func(t *testing.T) {
applyNetworking(t, &core.PodTemplateSpec{}, &core.Container{}, &Networking{
Ports: []core.ContainerPort{
{
Name: "TEST",
ContainerPort: 1,
},
},
})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.Len(t, container.Ports, 1)
require.EqualValues(t, "TEST", container.Ports[0].Name)
require.EqualValues(t, 1, container.Ports[0].ContainerPort)
})
})
t.Run("With Port Append", func(t *testing.T) {
applyNetworking(t, &core.PodTemplateSpec{}, &core.Container{}, &Networking{
Ports: []core.ContainerPort{
{
Name: "TEST",
ContainerPort: 1,
},
},
}, &Networking{
Ports: []core.ContainerPort{
{
Name: "TEST2",
ContainerPort: 2,
},
},
})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.Len(t, container.Ports, 2)
require.EqualValues(t, "TEST", container.Ports[0].Name)
require.EqualValues(t, 1, container.Ports[0].ContainerPort)
require.EqualValues(t, "TEST2", container.Ports[1].Name)
require.EqualValues(t, 2, container.Ports[1].ContainerPort)
})
})
t.Run("With Port Update", func(t *testing.T) {
applyNetworking(t, &core.PodTemplateSpec{}, &core.Container{}, &Networking{
Ports: []core.ContainerPort{
{
Name: "TEST",
ContainerPort: 1,
HostIP: "IP",
},
},
}, &Networking{
Ports: []core.ContainerPort{
{
Name: "TEST",
ContainerPort: 2,
},
},
})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.Len(t, container.Ports, 1)
require.EqualValues(t, "TEST", container.Ports[0].Name)
require.EqualValues(t, 2, container.Ports[0].ContainerPort)
require.EqualValues(t, "", container.Ports[0].HostIP)
})
})
}

View file

@ -0,0 +1,87 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package resources
import (
core "k8s.io/api/core/v1"
"github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/interfaces"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources"
)
var _ interfaces.Container[Probes] = &Probes{}
type Probes struct {
// LivenessProbe keeps configuration of periodic probe of container liveness.
// Container will be restarted if the probe fails.
// +doc/type: core.Probe
// +doc/link: Kubernetes docs|https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
LivenessProbe *core.Probe `json:"livenessProbe,omitempty"`
// ReadinessProbe keeps configuration of periodic probe of container service readiness.
// Container will be removed from service endpoints if the probe fails.
// +doc/type: core.Probe
// +doc/link: Kubernetes docs|https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
ReadinessProbe *core.Probe `json:"readinessProbe,omitempty"`
// StartupProbe indicates that the Pod has successfully initialized.
// If specified, no other probes are executed until this completes successfully.
// If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.
// This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,
// when it might take a long time to load data or warm a cache, than during steady-state operation.
// +doc/type: core.Probe
// +doc/link: Kubernetes docs|https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
StartupProbe *core.Probe `json:"startupProbe,omitempty"`
}
func (n *Probes) Apply(_ *core.PodTemplateSpec, template *core.Container) error {
if n == nil {
return nil
}
template.LivenessProbe = n.LivenessProbe.DeepCopy()
template.StartupProbe = n.StartupProbe.DeepCopy()
template.ReadinessProbe = n.ReadinessProbe.DeepCopy()
return nil
}
func (n *Probes) With(newResources *Probes) *Probes {
if n == nil && newResources == nil {
return nil
}
if n == nil {
return newResources.DeepCopy()
}
if newResources == nil {
return n.DeepCopy()
}
return &Probes{
LivenessProbe: resources.MergeProbes(n.LivenessProbe, newResources.LivenessProbe),
ReadinessProbe: resources.MergeProbes(n.ReadinessProbe, newResources.ReadinessProbe),
StartupProbe: resources.MergeProbes(n.StartupProbe, newResources.StartupProbe),
}
}
func (n *Probes) Validate() error {
return nil
}

View file

@ -0,0 +1,271 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package resources
import (
"testing"
"github.com/stretchr/testify/require"
core "k8s.io/api/core/v1"
)
func applyProbes(t *testing.T, template *core.PodTemplateSpec, container *core.Container, ns ...*Probes) func(in func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container)) {
var i *Probes
for _, n := range ns {
require.NoError(t, n.Validate())
i = i.With(n)
require.NoError(t, i.Validate())
}
template = template.DeepCopy()
if template == nil {
template = &core.PodTemplateSpec{}
}
container = container.DeepCopy()
if container == nil {
container = &core.Container{}
}
template.Spec.Containers = append(template.Spec.Containers, *container)
container = &template.Spec.Containers[0]
require.NoError(t, i.Apply(template, container))
return func(in func(t *testing.T, spec *core.PodTemplateSpec, container *core.Container)) {
t.Run("Validate", func(t *testing.T) {
in(t, template, container)
})
}
}
func Test_Probes(t *testing.T) {
t.Run("With Nil", func(t *testing.T) {
applyProbes(t, nil, nil)(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.Nil(t, container.ReadinessProbe)
require.Nil(t, container.LivenessProbe)
require.Nil(t, container.StartupProbe)
})
})
t.Run("With Empty", func(t *testing.T) {
applyProbes(t, &core.PodTemplateSpec{}, &core.Container{})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.Nil(t, container.ReadinessProbe)
require.Nil(t, container.LivenessProbe)
require.Nil(t, container.StartupProbe)
})
})
t.Run("With Probes", func(t *testing.T) {
applyProbes(t, &core.PodTemplateSpec{}, &core.Container{}, &Probes{
ReadinessProbe: &core.Probe{
ProbeHandler: core.ProbeHandler{
Exec: &core.ExecAction{
Command: []string{"test"},
},
},
InitialDelaySeconds: 10,
},
LivenessProbe: &core.Probe{
ProbeHandler: core.ProbeHandler{
HTTPGet: &core.HTTPGetAction{
Path: "/test",
},
},
InitialDelaySeconds: 15,
},
StartupProbe: &core.Probe{
ProbeHandler: core.ProbeHandler{
GRPC: &core.GRPCAction{
Port: 33,
},
},
InitialDelaySeconds: 20,
},
})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.NotNil(t, container.ReadinessProbe)
require.EqualValues(t, 10, container.ReadinessProbe.InitialDelaySeconds)
require.EqualValues(t, 0, container.ReadinessProbe.TimeoutSeconds)
require.Nil(t, container.ReadinessProbe.HTTPGet)
require.NotNil(t, container.ReadinessProbe.Exec)
require.Nil(t, container.ReadinessProbe.GRPC)
require.Len(t, container.ReadinessProbe.Exec.Command, 1)
require.EqualValues(t, "test", container.ReadinessProbe.Exec.Command[0])
require.NotNil(t, container.LivenessProbe)
require.EqualValues(t, 15, container.LivenessProbe.InitialDelaySeconds)
require.EqualValues(t, 0, container.LivenessProbe.TimeoutSeconds)
require.NotNil(t, container.LivenessProbe.HTTPGet)
require.Nil(t, container.LivenessProbe.Exec)
require.Nil(t, container.LivenessProbe.GRPC)
require.EqualValues(t, "/test", container.LivenessProbe.HTTPGet.Path)
require.NotNil(t, container.StartupProbe)
require.EqualValues(t, 20, container.StartupProbe.InitialDelaySeconds)
require.EqualValues(t, 0, container.StartupProbe.TimeoutSeconds)
require.Nil(t, container.StartupProbe.HTTPGet)
require.Nil(t, container.StartupProbe.Exec)
require.NotNil(t, container.StartupProbe.GRPC)
require.EqualValues(t, 33, container.StartupProbe.GRPC.Port)
})
})
t.Run("With Time Updates", func(t *testing.T) {
applyProbes(t, &core.PodTemplateSpec{}, &core.Container{}, &Probes{
ReadinessProbe: &core.Probe{
ProbeHandler: core.ProbeHandler{
Exec: &core.ExecAction{
Command: []string{"test"},
},
},
InitialDelaySeconds: 10,
},
LivenessProbe: &core.Probe{
ProbeHandler: core.ProbeHandler{
HTTPGet: &core.HTTPGetAction{
Path: "/test",
},
},
InitialDelaySeconds: 15,
},
StartupProbe: &core.Probe{
ProbeHandler: core.ProbeHandler{
GRPC: &core.GRPCAction{
Port: 33,
},
},
InitialDelaySeconds: 20,
},
}, &Probes{
ReadinessProbe: &core.Probe{
InitialDelaySeconds: 60,
},
LivenessProbe: &core.Probe{
InitialDelaySeconds: 61,
},
StartupProbe: &core.Probe{
TimeoutSeconds: 62,
},
})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.NotNil(t, container.ReadinessProbe)
require.EqualValues(t, 60, container.ReadinessProbe.InitialDelaySeconds)
require.EqualValues(t, 0, container.ReadinessProbe.TimeoutSeconds)
require.Nil(t, container.ReadinessProbe.HTTPGet)
require.NotNil(t, container.ReadinessProbe.Exec)
require.Nil(t, container.ReadinessProbe.GRPC)
require.Len(t, container.ReadinessProbe.Exec.Command, 1)
require.EqualValues(t, "test", container.ReadinessProbe.Exec.Command[0])
require.NotNil(t, container.LivenessProbe)
require.EqualValues(t, 61, container.LivenessProbe.InitialDelaySeconds)
require.EqualValues(t, 0, container.LivenessProbe.TimeoutSeconds)
require.NotNil(t, container.LivenessProbe.HTTPGet)
require.Nil(t, container.LivenessProbe.Exec)
require.Nil(t, container.LivenessProbe.GRPC)
require.EqualValues(t, "/test", container.LivenessProbe.HTTPGet.Path)
require.NotNil(t, container.StartupProbe)
require.EqualValues(t, 20, container.StartupProbe.InitialDelaySeconds)
require.EqualValues(t, 62, container.StartupProbe.TimeoutSeconds)
require.Nil(t, container.StartupProbe.HTTPGet)
require.Nil(t, container.StartupProbe.Exec)
require.NotNil(t, container.StartupProbe.GRPC)
require.EqualValues(t, 33, container.StartupProbe.GRPC.Port)
})
})
t.Run("With Exec Updates", func(t *testing.T) {
applyProbes(t, &core.PodTemplateSpec{}, &core.Container{}, &Probes{
ReadinessProbe: &core.Probe{
ProbeHandler: core.ProbeHandler{
Exec: &core.ExecAction{
Command: []string{"test"},
},
},
InitialDelaySeconds: 10,
},
LivenessProbe: &core.Probe{
ProbeHandler: core.ProbeHandler{
HTTPGet: &core.HTTPGetAction{
Path: "/test",
},
},
InitialDelaySeconds: 15,
},
StartupProbe: &core.Probe{
ProbeHandler: core.ProbeHandler{
GRPC: &core.GRPCAction{
Port: 33,
},
},
InitialDelaySeconds: 20,
},
}, &Probes{
ReadinessProbe: &core.Probe{
ProbeHandler: core.ProbeHandler{
GRPC: &core.GRPCAction{
Port: 33,
},
},
},
LivenessProbe: &core.Probe{
ProbeHandler: core.ProbeHandler{
Exec: &core.ExecAction{
Command: []string{"test"},
},
},
},
StartupProbe: &core.Probe{
ProbeHandler: core.ProbeHandler{
HTTPGet: &core.HTTPGetAction{
Path: "/test",
},
},
},
})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.NotNil(t, container.ReadinessProbe)
require.EqualValues(t, 10, container.ReadinessProbe.InitialDelaySeconds)
require.EqualValues(t, 0, container.ReadinessProbe.TimeoutSeconds)
require.Nil(t, container.ReadinessProbe.HTTPGet)
require.Nil(t, container.ReadinessProbe.Exec)
require.NotNil(t, container.ReadinessProbe.GRPC)
require.EqualValues(t, 33, container.ReadinessProbe.GRPC.Port)
require.NotNil(t, container.LivenessProbe)
require.EqualValues(t, 15, container.LivenessProbe.InitialDelaySeconds)
require.EqualValues(t, 0, container.LivenessProbe.TimeoutSeconds)
require.Nil(t, container.LivenessProbe.HTTPGet)
require.NotNil(t, container.LivenessProbe.Exec)
require.Nil(t, container.LivenessProbe.GRPC)
require.Len(t, container.LivenessProbe.Exec.Command, 1)
require.EqualValues(t, "test", container.LivenessProbe.Exec.Command[0])
require.NotNil(t, container.StartupProbe)
require.EqualValues(t, 20, container.StartupProbe.InitialDelaySeconds)
require.EqualValues(t, 0, container.StartupProbe.TimeoutSeconds)
require.NotNil(t, container.StartupProbe.HTTPGet)
require.Nil(t, container.StartupProbe.Exec)
require.Nil(t, container.StartupProbe.GRPC)
require.EqualValues(t, "/test", container.StartupProbe.HTTPGet.Path)
})
})
}

View file

@ -0,0 +1,70 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package resources
import (
core "k8s.io/api/core/v1"
"github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/interfaces"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources"
)
var _ interfaces.Container[VolumeMounts] = &VolumeMounts{}
type VolumeMounts struct {
// VolumeMounts keeps list of pod volumes to mount into the container's filesystem.
// +doc/type: []core.VolumeMount
VolumeMounts []core.VolumeMount `json:"volumeMounts,omitempty"`
}
func (v *VolumeMounts) Apply(_ *core.PodTemplateSpec, container *core.Container) error {
if v == nil {
return nil
}
obj := v.DeepCopy()
container.VolumeMounts = obj.VolumeMounts
return nil
}
func (v *VolumeMounts) With(other *VolumeMounts) *VolumeMounts {
if v == nil && other == nil {
return nil
}
if v == nil {
return other.DeepCopy()
}
if other == nil {
return v.DeepCopy()
}
return &VolumeMounts{
VolumeMounts: resources.MergeVolumeMounts(v.VolumeMounts, other.VolumeMounts...),
}
}
func (v *VolumeMounts) Validate() error {
return nil
}

View file

@ -0,0 +1,145 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package resources
import (
"testing"
"github.com/stretchr/testify/require"
core "k8s.io/api/core/v1"
)
func applyVolumeMounts(t *testing.T, template *core.PodTemplateSpec, container *core.Container, ns ...*VolumeMounts) func(in func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container)) {
var i *VolumeMounts
for _, n := range ns {
require.NoError(t, n.Validate())
i = i.With(n)
require.NoError(t, i.Validate())
}
template = template.DeepCopy()
if template == nil {
template = &core.PodTemplateSpec{}
}
container = container.DeepCopy()
if container == nil {
container = &core.Container{}
}
template.Spec.Containers = append(template.Spec.Containers, *container)
container = &template.Spec.Containers[0]
require.NoError(t, i.Apply(template, container))
return func(in func(t *testing.T, spec *core.PodTemplateSpec, container *core.Container)) {
t.Run("Validate", func(t *testing.T) {
in(t, template, container)
})
}
}
func Test_VolumeMounts(t *testing.T) {
t.Run("With Nil", func(t *testing.T) {
applyVolumeMounts(t, nil, nil)(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.Len(t, container.VolumeMounts, 0)
})
})
t.Run("With Empty", func(t *testing.T) {
applyVolumeMounts(t, &core.PodTemplateSpec{}, &core.Container{})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.Len(t, container.VolumeMounts, 0)
})
})
t.Run("Add mount", func(t *testing.T) {
applyVolumeMounts(t, &core.PodTemplateSpec{}, &core.Container{}, &VolumeMounts{
VolumeMounts: []core.VolumeMount{
{
Name: "test",
ReadOnly: false,
MountPath: "/var/test",
},
},
})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.Len(t, container.VolumeMounts, 1)
require.EqualValues(t, "test", container.VolumeMounts[0].Name)
require.EqualValues(t, "/var/test", container.VolumeMounts[0].MountPath)
require.False(t, container.VolumeMounts[0].ReadOnly)
})
})
t.Run("Append mount", func(t *testing.T) {
applyVolumeMounts(t, &core.PodTemplateSpec{}, &core.Container{}, &VolumeMounts{
VolumeMounts: []core.VolumeMount{
{
Name: "test",
ReadOnly: false,
MountPath: "/var/test",
},
{
Name: "test2",
ReadOnly: true,
MountPath: "/var/test2",
},
},
})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.Len(t, container.VolumeMounts, 2)
require.EqualValues(t, "test", container.VolumeMounts[0].Name)
require.EqualValues(t, "/var/test", container.VolumeMounts[0].MountPath)
require.False(t, container.VolumeMounts[0].ReadOnly)
require.EqualValues(t, "test2", container.VolumeMounts[1].Name)
require.EqualValues(t, "/var/test2", container.VolumeMounts[1].MountPath)
require.True(t, container.VolumeMounts[1].ReadOnly)
})
})
t.Run("Second mount", func(t *testing.T) {
applyVolumeMounts(t, &core.PodTemplateSpec{}, &core.Container{}, &VolumeMounts{
VolumeMounts: []core.VolumeMount{
{
Name: "test",
ReadOnly: false,
MountPath: "/var/test",
},
{
Name: "test",
ReadOnly: true,
MountPath: "/var/test2",
},
},
})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) {
require.Len(t, container.VolumeMounts, 2)
require.EqualValues(t, "test", container.VolumeMounts[0].Name)
require.EqualValues(t, "/var/test", container.VolumeMounts[0].MountPath)
require.False(t, container.VolumeMounts[0].ReadOnly)
require.EqualValues(t, "test", container.VolumeMounts[1].Name)
require.EqualValues(t, "/var/test2", container.VolumeMounts[1].MountPath)
require.True(t, container.VolumeMounts[1].ReadOnly)
})
})
}

View file

@ -110,6 +110,79 @@ func (in ImagePullSecrets) DeepCopy() ImagePullSecrets {
return *out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Lifecycle) DeepCopyInto(out *Lifecycle) {
*out = *in
if in.Lifecycle != nil {
in, out := &in.Lifecycle, &out.Lifecycle
*out = new(v1.Lifecycle)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Lifecycle.
func (in *Lifecycle) DeepCopy() *Lifecycle {
if in == nil {
return nil
}
out := new(Lifecycle)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Networking) DeepCopyInto(out *Networking) {
*out = *in
if in.Ports != nil {
in, out := &in.Ports, &out.Ports
*out = make([]v1.ContainerPort, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Networking.
func (in *Networking) DeepCopy() *Networking {
if in == nil {
return nil
}
out := new(Networking)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Probes) DeepCopyInto(out *Probes) {
*out = *in
if in.LivenessProbe != nil {
in, out := &in.LivenessProbe, &out.LivenessProbe
*out = new(v1.Probe)
(*in).DeepCopyInto(*out)
}
if in.ReadinessProbe != nil {
in, out := &in.ReadinessProbe, &out.ReadinessProbe
*out = new(v1.Probe)
(*in).DeepCopyInto(*out)
}
if in.StartupProbe != nil {
in, out := &in.StartupProbe, &out.StartupProbe
*out = new(v1.Probe)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Probes.
func (in *Probes) DeepCopy() *Probes {
if in == nil {
return nil
}
out := new(Probes)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Resources) DeepCopyInto(out *Resources) {
*out = *in
@ -151,3 +224,26 @@ func (in *Security) DeepCopy() *Security {
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VolumeMounts) DeepCopyInto(out *VolumeMounts) {
*out = *in
if in.VolumeMounts != nil {
in, out := &in.VolumeMounts, &out.VolumeMounts
*out = make([]v1.VolumeMount, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeMounts.
func (in *VolumeMounts) DeepCopy() *VolumeMounts {
if in == nil {
return nil
}
out := new(VolumeMounts)
in.DeepCopyInto(out)
return out
}

View file

@ -52,6 +52,26 @@ func (in *Container) DeepCopyInto(out *Container) {
*out = new(resources.Resources)
(*in).DeepCopyInto(*out)
}
if in.VolumeMounts != nil {
in, out := &in.VolumeMounts, &out.VolumeMounts
*out = new(resources.VolumeMounts)
(*in).DeepCopyInto(*out)
}
if in.Probes != nil {
in, out := &in.Probes, &out.Probes
*out = new(resources.Probes)
(*in).DeepCopyInto(*out)
}
if in.Networking != nil {
in, out := &in.Networking, &out.Networking
*out = new(resources.Networking)
(*in).DeepCopyInto(*out)
}
if in.Lifecycle != nil {
in, out := &in.Lifecycle, &out.Lifecycle
*out = new(resources.Lifecycle)
(*in).DeepCopyInto(*out)
}
return
}

View file

@ -39,6 +39,9 @@ type Pod struct {
// Security keeps the security settings for Pod
*schedulerPodResourcesApi.Security `json:",inline"`
// Volumes keeps the volumes settings for Pod
*schedulerPodResourcesApi.Volumes `json:",inline"`
}
func (a *Pod) With(other *Pod) *Pod {
@ -58,6 +61,7 @@ func (a *Pod) With(other *Pod) *Pod {
Scheduling: a.Scheduling.With(other.Scheduling),
Namespace: a.Namespace.With(other.Namespace),
Security: a.Security.With(other.Security),
Volumes: a.Volumes.With(other.Volumes),
}
}
@ -70,6 +74,7 @@ func (a *Pod) Apply(template *core.PodTemplateSpec) error {
a.Scheduling.Apply(template),
a.Namespace.Apply(template),
a.Security.Apply(template),
a.Volumes.Apply(template),
)
}
@ -97,6 +102,14 @@ func (a *Pod) GetContainerNamespace() *schedulerPodResourcesApi.Namespace {
return a.Namespace
}
func (a *Pod) GetVolumes() *schedulerPodResourcesApi.Volumes {
if a == nil {
return nil
}
return a.Volumes
}
func (a *Pod) Validate() error {
if a == nil {
return nil
@ -105,5 +118,6 @@ func (a *Pod) Validate() error {
a.Scheduling.Validate(),
a.Namespace.Validate(),
a.Security.Validate(),
a.Volumes.Validate(),
)
}

View file

@ -182,6 +182,9 @@ nodeSelector:
podSecurityContext:
runAsUser: 10
hostPID: true
volumes:
- name: test
emptyDir: {}
`)(func(t *testing.T, pod *core.PodTemplateSpec, spec *Pod) {
// Spec
require.NotNil(t, spec.Security)
@ -195,6 +198,10 @@ hostPID: true
require.NotNil(t, spec.Namespace)
require.NotNil(t, spec.Namespace.HostPID)
require.True(t, *spec.Namespace.HostPID)
require.NotNil(t, spec.Volumes)
require.Len(t, spec.Volumes.Volumes, 1)
require.EqualValues(t, "test", spec.Volumes.Volumes[0].Name)
require.NotNil(t, spec.Volumes.Volumes[0].EmptyDir)
// Pod
require.NotNil(t, pod.Spec.SecurityContext)
@ -207,6 +214,9 @@ hostPID: true
require.Nil(t, pod.Spec.Affinity)
require.NotNil(t, pod.Spec.HostPID)
require.True(t, pod.Spec.HostPID)
require.Len(t, pod.Spec.Volumes, 1)
require.EqualValues(t, "test", pod.Spec.Volumes[0].Name)
require.NotNil(t, pod.Spec.Volumes[0].EmptyDir)
})
})
}

View file

@ -0,0 +1,71 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package resources
import (
core "k8s.io/api/core/v1"
"github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/interfaces"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources"
)
var _ interfaces.Pod[Volumes] = &Volumes{}
type Volumes struct {
// Volumes keeps list of volumes that can be mounted by containers belonging to the pod.
// +doc/type: []core.Volume
// +doc/link: Kubernetes docs|https://kubernetes.io/docs/concepts/storage/volumes
Volumes []core.Volume `json:"volumes,omitempty"`
}
func (v *Volumes) Apply(template *core.PodTemplateSpec) error {
if v == nil {
return nil
}
obj := v.DeepCopy()
template.Spec.Volumes = obj.Volumes
return nil
}
func (v *Volumes) With(other *Volumes) *Volumes {
if v == nil && other == nil {
return nil
}
if v == nil {
return other.DeepCopy()
}
if other == nil {
return v.DeepCopy()
}
return &Volumes{
Volumes: resources.MergeVolumes(v.Volumes, other.Volumes...),
}
}
func (v *Volumes) Validate() error {
return nil
}

View file

@ -0,0 +1,149 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package resources
import (
"testing"
"github.com/stretchr/testify/require"
core "k8s.io/api/core/v1"
)
func applyVolumes(t *testing.T, template *core.PodTemplateSpec, ns ...*Volumes) func(in func(t *testing.T, pod *core.PodTemplateSpec)) {
var i *Volumes
for _, n := range ns {
require.NoError(t, n.Validate())
i = i.With(n)
require.NoError(t, i.Validate())
}
template = template.DeepCopy()
if template == nil {
template = &core.PodTemplateSpec{}
}
require.NoError(t, i.Apply(template))
return func(in func(t *testing.T, spec *core.PodTemplateSpec)) {
t.Run("Validate", func(t *testing.T) {
in(t, template)
})
}
}
func Test_Volumes(t *testing.T) {
t.Run("Nil", func(t *testing.T) {
applyVolumes(t, nil)(func(t *testing.T, pod *core.PodTemplateSpec) {
require.Len(t, pod.Spec.Volumes, 0)
})
})
t.Run("Empty", func(t *testing.T) {
applyVolumes(t, &core.PodTemplateSpec{})(func(t *testing.T, pod *core.PodTemplateSpec) {
require.Len(t, pod.Spec.Volumes, 0)
})
})
t.Run("Add volume", func(t *testing.T) {
applyVolumes(t, &core.PodTemplateSpec{}, &Volumes{
Volumes: []core.Volume{
{
Name: "test",
VolumeSource: core.VolumeSource{
EmptyDir: &core.EmptyDirVolumeSource{},
},
},
},
})(func(t *testing.T, pod *core.PodTemplateSpec) {
require.Len(t, pod.Spec.Volumes, 1)
require.EqualValues(t, "test", pod.Spec.Volumes[0].Name)
require.NotNil(t, pod.Spec.Volumes[0].VolumeSource.EmptyDir)
require.Nil(t, pod.Spec.Volumes[0].VolumeSource.Secret)
})
})
t.Run("Append volume", func(t *testing.T) {
applyVolumes(t, &core.PodTemplateSpec{}, &Volumes{
Volumes: []core.Volume{
{
Name: "test",
VolumeSource: core.VolumeSource{
EmptyDir: &core.EmptyDirVolumeSource{},
},
},
},
}, &Volumes{
Volumes: []core.Volume{
{
Name: "test2",
VolumeSource: core.VolumeSource{
Secret: &core.SecretVolumeSource{
SecretName: "test",
},
},
},
},
})(func(t *testing.T, pod *core.PodTemplateSpec) {
require.Len(t, pod.Spec.Volumes, 2)
require.EqualValues(t, "test", pod.Spec.Volumes[0].Name)
require.NotNil(t, pod.Spec.Volumes[0].VolumeSource.EmptyDir)
require.Nil(t, pod.Spec.Volumes[0].VolumeSource.Secret)
require.EqualValues(t, "test2", pod.Spec.Volumes[1].Name)
require.Nil(t, pod.Spec.Volumes[1].VolumeSource.EmptyDir)
require.NotNil(t, pod.Spec.Volumes[1].VolumeSource.Secret)
require.EqualValues(t, "test", pod.Spec.Volumes[1].VolumeSource.Secret.SecretName)
})
})
t.Run("Update volume", func(t *testing.T) {
applyVolumes(t, &core.PodTemplateSpec{}, &Volumes{
Volumes: []core.Volume{
{
Name: "test",
VolumeSource: core.VolumeSource{
EmptyDir: &core.EmptyDirVolumeSource{},
},
},
},
}, &Volumes{
Volumes: []core.Volume{
{
Name: "test",
VolumeSource: core.VolumeSource{
Secret: &core.SecretVolumeSource{
SecretName: "test",
},
},
},
},
})(func(t *testing.T, pod *core.PodTemplateSpec) {
require.Len(t, pod.Spec.Volumes, 1)
require.EqualValues(t, "test", pod.Spec.Volumes[0].Name)
require.Nil(t, pod.Spec.Volumes[0].VolumeSource.EmptyDir)
require.NotNil(t, pod.Spec.Volumes[0].VolumeSource.Secret)
require.EqualValues(t, "test", pod.Spec.Volumes[0].VolumeSource.Secret.SecretName)
})
})
}

View file

@ -147,3 +147,26 @@ func (in Tolerations) DeepCopy() Tolerations {
in.DeepCopyInto(out)
return *out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Volumes) DeepCopyInto(out *Volumes) {
*out = *in
if in.Volumes != nil {
in, out := &in.Volumes, &out.Volumes
*out = make([]v1.Volume, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Volumes.
func (in *Volumes) DeepCopy() *Volumes {
if in == nil {
return nil
}
out := new(Volumes)
in.DeepCopyInto(out)
return out
}

View file

@ -47,6 +47,11 @@ func (in *Pod) DeepCopyInto(out *Pod) {
*out = new(resources.Security)
(*in).DeepCopyInto(*out)
}
if in.Volumes != nil {
in, out := &in.Volumes, &out.Volumes
*out = new(resources.Volumes)
(*in).DeepCopyInto(*out)
}
return
}

View file

@ -24,18 +24,31 @@ import (
core "k8s.io/api/core/v1"
schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container"
"github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/interfaces"
shared "github.com/arangodb/kube-arangodb/pkg/apis/shared"
)
var _ interfaces.Pod[ProfileContainerTemplate] = &ProfileContainerTemplate{}
type ProfileContainerTemplate struct {
Containers schedulerContainerApi.Containers `json:"containers,omitempty"`
All *schedulerContainerApi.Generic `json:"all,omitempty"`
}
func (p *ProfileContainerTemplate) ApplyContainers(template *core.PodTemplateSpec) error {
if p == nil {
return nil
}
return p.Containers.Apply(template)
}
func (p *ProfileContainerTemplate) ApplyGeneric(template *core.PodTemplateSpec) error {
if p == nil {
return nil
}
return p.All.Apply(template)
}
func (p *ProfileContainerTemplate) With(other *ProfileContainerTemplate) *ProfileContainerTemplate {
if p == nil && other == nil {
return nil
@ -65,14 +78,3 @@ func (p *ProfileContainerTemplate) Validate() error {
shared.PrefixResourceErrors("all", p.All.Validate()),
)
}
func (p *ProfileContainerTemplate) Apply(template *core.PodTemplateSpec) error {
if p == nil {
return nil
}
return shared.WithErrors(
shared.PrefixResourceErrors("containers", p.Containers.Apply(template)),
shared.PrefixResourceErrors("all", p.All.Apply(template)),
)
}

View file

@ -21,16 +21,10 @@
package v1alpha1
import (
core "k8s.io/api/core/v1"
"github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/interfaces"
schedulerPodApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/pod"
shared "github.com/arangodb/kube-arangodb/pkg/apis/shared"
"github.com/arangodb/kube-arangodb/pkg/util"
)
var _ interfaces.Pod[ProfileTemplate] = &ProfileTemplate{}
type ProfileTemplate struct {
Priority *int `json:"priority,omitempty"`
@ -39,26 +33,6 @@ type ProfileTemplate struct {
Container *ProfileContainerTemplate `json:"container,omitempty"`
}
func (p *ProfileTemplate) With(other *ProfileTemplate) *ProfileTemplate {
if p == nil && other == nil {
return nil
}
if p == nil {
return other.DeepCopy()
}
if other == nil {
return p.DeepCopy()
}
return &ProfileTemplate{
Priority: util.First(other.Priority, p.Priority),
Pod: p.Pod.With(other.Pod),
Container: p.Container.With(other.Container),
}
}
func (p *ProfileTemplate) Validate() error {
if p == nil {
return nil
@ -69,14 +43,3 @@ func (p *ProfileTemplate) Validate() error {
shared.PrefixResourceErrors("container", p.Container.Validate()),
)
}
func (p *ProfileTemplate) Apply(template *core.PodTemplateSpec) error {
if p == nil {
return nil
}
return shared.WithErrors(
shared.PrefixResourceErrors("pod", p.Pod.Apply(template)),
shared.PrefixResourceErrors("container", p.Container.Apply(template)),
)
}

View file

@ -0,0 +1,69 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package v1alpha1
import (
"sort"
core "k8s.io/api/core/v1"
"github.com/arangodb/kube-arangodb/pkg/util"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
)
type ProfileTemplates []ProfileTemplate
func (p ProfileTemplates) Sort() ProfileTemplates {
sort.Slice(p, func(i, j int) bool {
if a, b := util.WithDefault(p[i].Priority), util.WithDefault(p[j].Priority); a != b {
return a < b
}
return false
})
return p
}
func (p ProfileTemplates) Render() (*core.PodTemplateSpec, error) {
var pod core.PodTemplateSpec
// Apply Pod Spec
for id := range p {
if err := p[id].Pod.Apply(&pod); err != nil {
return nil, errors.Wrapf(err, "Error while rendering Pod for %d", id)
}
}
// Apply Containers Spec
for id := range p {
if err := p[id].Container.ApplyContainers(&pod); err != nil {
return nil, errors.Wrapf(err, "Error while rendering Pod for %d", id)
}
}
// Apply Generic Containers Spec
for id := range p {
if err := p[id].Container.ApplyGeneric(&pod); err != nil {
return nil, errors.Wrapf(err, "Error while rendering Pod for %d", id)
}
}
return pod.DeepCopy(), nil
}

View file

@ -0,0 +1,76 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package profiles
import (
core "k8s.io/api/core/v1"
schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1"
schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container"
schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources"
)
func ContainerKubernetesEnvironments() *schedulerApi.ProfileTemplate {
return containerKubernetesEnvironments.DeepCopy()
}
var containerKubernetesEnvironments = schedulerApi.ProfileTemplate{
Container: &schedulerApi.ProfileContainerTemplate{
All: &schedulerContainerApi.Generic{
Environments: &schedulerContainerResourcesApi.Environments{
Env: []core.EnvVar{
{
Name: "KUBE_NAMESPACE",
ValueFrom: &core.EnvVarSource{
FieldRef: &core.ObjectFieldSelector{
FieldPath: "metadata.namespace",
},
},
},
{
Name: "KUBE_NAME",
ValueFrom: &core.EnvVarSource{
FieldRef: &core.ObjectFieldSelector{
FieldPath: "metadata.name",
},
},
},
{
Name: "KUBE_IP",
ValueFrom: &core.EnvVarSource{
FieldRef: &core.ObjectFieldSelector{
FieldPath: "status.podIP",
},
},
},
{
Name: "KUBE_SERVICE_ACCOUNT",
ValueFrom: &core.EnvVarSource{
FieldRef: &core.ObjectFieldSelector{
FieldPath: "spec.serviceAccountName",
},
},
},
},
},
},
},
}

View file

@ -0,0 +1,86 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package profiles
import (
core "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1"
schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container"
schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources"
)
var (
divisor1m = resource.MustParse("1m")
divisor1Mi = resource.MustParse("1Mi")
)
func ContainerResourceEnvironments() *schedulerApi.ProfileTemplate {
return containerResourceEnvironments.DeepCopy()
}
var containerResourceEnvironments = schedulerApi.ProfileTemplate{
Container: &schedulerApi.ProfileContainerTemplate{
All: &schedulerContainerApi.Generic{
Environments: &schedulerContainerResourcesApi.Environments{
Env: []core.EnvVar{
{
Name: "CONTAINER_CPU_REQUESTS",
ValueFrom: &core.EnvVarSource{
ResourceFieldRef: &core.ResourceFieldSelector{
Resource: "requests.cpu",
Divisor: divisor1m,
},
},
},
{
Name: "CONTAINER_MEMORY_REQUESTS",
ValueFrom: &core.EnvVarSource{
ResourceFieldRef: &core.ResourceFieldSelector{
Resource: "requests.memory",
Divisor: divisor1Mi,
},
},
},
{
Name: "CONTAINER_CPU_LIMITS",
ValueFrom: &core.EnvVarSource{
ResourceFieldRef: &core.ResourceFieldSelector{
Resource: "limits.cpu",
Divisor: divisor1m,
},
},
},
{
Name: "CONTAINER_MEMORY_LIMITS",
ValueFrom: &core.EnvVarSource{
ResourceFieldRef: &core.ResourceFieldSelector{
Resource: "limits.memory",
Divisor: divisor1Mi,
},
},
},
},
},
},
},
}

View file

@ -88,3 +88,25 @@ func (in *ProfileTemplate) DeepCopy() *ProfileTemplate {
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in ProfileTemplates) DeepCopyInto(out *ProfileTemplates) {
{
in := &in
*out = make(ProfileTemplates, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
return
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProfileTemplates.
func (in ProfileTemplates) DeepCopy() ProfileTemplates {
if in == nil {
return nil
}
out := new(ProfileTemplates)
in.DeepCopyInto(out)
return *out
}

File diff suppressed because it is too large Load diff

View file

@ -147,10 +147,238 @@ v1alpha1:
items:
type: string
type: array
lifecycle:
properties:
postStart:
properties:
exec:
properties:
command:
items:
type: string
type: array
type: object
httpGet:
properties:
host:
type: string
httpHeaders:
items:
properties:
name:
type: string
value:
type: string
type: object
type: array
path:
type: string
port:
format: int-or-string
type: string
scheme:
type: string
type: object
tcpSocket:
properties:
host:
type: string
port:
format: int-or-string
type: string
type: object
type: object
preStop:
properties:
exec:
properties:
command:
items:
type: string
type: array
type: object
httpGet:
properties:
host:
type: string
httpHeaders:
items:
properties:
name:
type: string
value:
type: string
type: object
type: array
path:
type: string
port:
format: int-or-string
type: string
scheme:
type: string
type: object
tcpSocket:
properties:
host:
type: string
port:
format: int-or-string
type: string
type: object
type: object
type: object
listenPort:
description: ListenPort defines on which port the sidecar container will be listening for connections
format: int32
type: integer
livenessProbe:
properties:
exec:
properties:
command:
items:
type: string
type: array
type: object
failureThreshold:
format: int32
type: integer
grpc:
properties:
port:
format: int32
type: integer
service:
type: string
type: object
httpGet:
properties:
host:
type: string
httpHeaders:
items:
properties:
name:
type: string
value:
type: string
type: object
type: array
path:
type: string
port:
format: int-or-string
type: string
scheme:
type: string
type: object
initialDelaySeconds:
format: int32
type: integer
periodSeconds:
format: int32
type: integer
successThreshold:
format: int32
type: integer
tcpSocket:
properties:
host:
type: string
port:
format: int-or-string
type: string
type: object
terminationGracePeriodSeconds:
format: int64
type: integer
timeoutSeconds:
format: int32
type: integer
type: object
ports:
items:
properties:
containerPort:
format: int32
type: integer
hostIP:
type: string
hostPort:
format: int32
type: integer
name:
type: string
protocol:
type: string
type: object
type: array
readinessProbe:
properties:
exec:
properties:
command:
items:
type: string
type: array
type: object
failureThreshold:
format: int32
type: integer
grpc:
properties:
port:
format: int32
type: integer
service:
type: string
type: object
httpGet:
properties:
host:
type: string
httpHeaders:
items:
properties:
name:
type: string
value:
type: string
type: object
type: array
path:
type: string
port:
format: int-or-string
type: string
scheme:
type: string
type: object
initialDelaySeconds:
format: int32
type: integer
periodSeconds:
format: int32
type: integer
successThreshold:
format: int32
type: integer
tcpSocket:
properties:
host:
type: string
port:
format: int-or-string
type: string
type: object
terminationGracePeriodSeconds:
format: int64
type: integer
timeoutSeconds:
format: int32
type: integer
type: object
resources:
properties:
claims:
@ -228,6 +456,88 @@ v1alpha1:
type: string
type: object
type: object
startupProbe:
properties:
exec:
properties:
command:
items:
type: string
type: array
type: object
failureThreshold:
format: int32
type: integer
grpc:
properties:
port:
format: int32
type: integer
service:
type: string
type: object
httpGet:
properties:
host:
type: string
httpHeaders:
items:
properties:
name:
type: string
value:
type: string
type: object
type: array
path:
type: string
port:
format: int-or-string
type: string
scheme:
type: string
type: object
initialDelaySeconds:
format: int32
type: integer
periodSeconds:
format: int32
type: integer
successThreshold:
format: int32
type: integer
tcpSocket:
properties:
host:
type: string
port:
format: int-or-string
type: string
type: object
terminationGracePeriodSeconds:
format: int64
type: integer
timeoutSeconds:
format: int32
type: integer
type: object
volumeMounts:
items:
properties:
mountPath:
type: string
mountPropagation:
type: string
name:
type: string
readOnly:
type: boolean
subPath:
type: string
subPathExpr:
type: string
type: object
type: array
type: object
type: object
type: object

View file

@ -1,7 +1,7 @@
//
// DISCLAIMER
//
// Copyright 2023 ArangoDB GmbH, Cologne, Germany
// Copyright 2023-2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -18,7 +18,7 @@
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package envs
package resources
import core "k8s.io/api/core/v1"

View file

@ -0,0 +1,58 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package resources
import core "k8s.io/api/core/v1"
func MergeLifecycle(a, b *core.Lifecycle) *core.Lifecycle {
if a == nil && b == nil {
return nil
}
if a == nil {
return b.DeepCopy()
}
if b == nil {
return a.DeepCopy()
}
return &core.Lifecycle{
PostStart: MergeLifecycleHandler(b.PostStart, a.PostStart),
PreStop: MergeLifecycleHandler(b.PreStop, a.PreStop),
}
}
func MergeLifecycleHandler(a, b *core.LifecycleHandler) *core.LifecycleHandler {
if a == nil && b == nil {
return nil
}
if a == nil {
return b.DeepCopy()
}
if b == nil {
return a.DeepCopy()
}
if a.HTTPGet != nil || a.Exec != nil || a.TCPSocket != nil {
return a.DeepCopy()
}
return b.DeepCopy()
}

View file

@ -0,0 +1,49 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package resources
import core "k8s.io/api/core/v1"
func MergeContainerPorts(in []core.ContainerPort, envs ...core.ContainerPort) []core.ContainerPort {
out := append([]core.ContainerPort{}, in...)
for _, env := range envs {
var envCopy core.ContainerPort
env.DeepCopyInto(&envCopy)
if id := ContainerPortId(out, envCopy.Name); id == -1 {
out = append(out, envCopy)
} else {
out[id] = envCopy
}
}
return out
}
func ContainerPortId(in []core.ContainerPort, name string) int {
for id := range in {
if in[id].Name == name {
return id
}
}
return -1
}

View file

@ -0,0 +1,49 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package resources
import (
core "k8s.io/api/core/v1"
"github.com/arangodb/kube-arangodb/pkg/util"
)
func MergeProbes(a, b *core.Probe) *core.Probe {
if a == nil && b == nil {
return nil
}
if a == nil {
return b.DeepCopy()
}
if b == nil {
return a.DeepCopy()
}
return &core.Probe{
ProbeHandler: util.FirstNotDefault(b.ProbeHandler, a.ProbeHandler),
InitialDelaySeconds: util.FirstNotDefault(b.InitialDelaySeconds, a.InitialDelaySeconds),
TimeoutSeconds: util.FirstNotDefault(b.TimeoutSeconds, a.TimeoutSeconds),
PeriodSeconds: util.FirstNotDefault(b.PeriodSeconds, a.PeriodSeconds),
SuccessThreshold: util.FirstNotDefault(b.SuccessThreshold, a.SuccessThreshold),
FailureThreshold: util.FirstNotDefault(b.FailureThreshold, a.FailureThreshold),
TerminationGracePeriodSeconds: util.FirstNotDefault(b.TerminationGracePeriodSeconds, a.TerminationGracePeriodSeconds),
}
}

View file

@ -0,0 +1,57 @@
//
// DISCLAIMER
//
// Copyright 2023-2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package resources
import core "k8s.io/api/core/v1"
func MergeVolumes(in []core.Volume, envs ...core.Volume) []core.Volume {
out := append([]core.Volume{}, in...)
for _, env := range envs {
var envCopy core.Volume
env.DeepCopyInto(&envCopy)
if id := VolumeID(out, envCopy.Name); id == -1 {
out = append(out, envCopy)
} else {
out[id] = envCopy
}
}
return out
}
func MergeVolumeMounts(in []core.VolumeMount, envs ...core.VolumeMount) []core.VolumeMount {
out := append([]core.VolumeMount{}, in...)
out = append(out, envs...)
return out
}
func VolumeID(in []core.Volume, name string) int {
for id := range in {
if in[id].Name == name {
return id
}
}
return -1
}

View file

@ -20,6 +20,8 @@
package util
import "reflect"
// NewType returns a reference to a simple type with given value.
func NewType[T interface{}](input T) *T {
return &input
@ -72,6 +74,17 @@ func First[T interface{}](input ...*T) *T {
return nil
}
// FirstNotDefault returns first not default value
func FirstNotDefault[T interface{}](input ...T) T {
for _, i := range input {
if !reflect.DeepEqual(i, Default[T]()) {
return i
}
}
return Default[T]()
}
// LastFromList returns last element on the list
func LastFromList[T interface{}](in []T) T {
return in[len(in)-1]

View file

@ -1,7 +1,7 @@
//
// DISCLAIMER
//
// Copyright 2023 ArangoDB GmbH, Cologne, Germany
// Copyright 2023-2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -153,3 +153,45 @@ func Test_CheckConditionalNil(t *testing.T) {
})
})
}
func Test_FirstNotDefault(t *testing.T) {
t.Run("String", func(t *testing.T) {
require.Equal(t, "", FirstNotDefault[string]())
require.Equal(t, "", FirstNotDefault[string](""))
require.Equal(t, "test", FirstNotDefault[string]("", "test"))
require.Equal(t, "test1", FirstNotDefault[string]("test1", "test"))
})
t.Run("Int", func(t *testing.T) {
require.Equal(t, 0, FirstNotDefault[int]())
require.Equal(t, 0, FirstNotDefault[int](0))
require.Equal(t, 1, FirstNotDefault[int](0, 1))
require.Equal(t, 2, FirstNotDefault[int](2, 1))
})
t.Run("Structs", func(t *testing.T) {
type z struct {
v int
}
require.Equal(t, z{}, FirstNotDefault[z]())
require.Equal(t, z{}, FirstNotDefault[z](z{}))
require.Equal(t, z{4}, FirstNotDefault[z](z{}, z{4}))
require.Equal(t, z{1}, FirstNotDefault[z](z{1}, z{4}))
})
t.Run("Pointers", func(t *testing.T) {
type z struct {
v int
}
var z1, z2 z
z1 = z{1}
z2 = z{2}
require.Equal(t, (*z)(nil), FirstNotDefault[*z]())
require.Equal(t, &z1, FirstNotDefault[*z](&z1))
require.NotEqual(t, nil, FirstNotDefault[*z](&z1))
require.NotEqual(t, &z2, FirstNotDefault[*z](&z1))
require.Equal(t, &z1, FirstNotDefault[*z](nil, &z1))
require.Equal(t, &z2, FirstNotDefault[*z](&z2, &z1))
})
}