diff --git a/CHANGELOG.md b/CHANGELOG.md
index 89c23ed80..bd9d49a69 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -32,6 +32,7 @@
- (Improvement) (ML) CronJob status update
- (Improvement) (ML) Job Sidecar Shutdown
- (Feature) (ML) Handler for Extension StatefulSet and Service
+- (Feature) (ML) Pod & Container Config
## [1.2.35](https://github.com/arangodb/kube-arangodb/tree/1.2.35) (2023-11-06)
- (Maintenance) Update go-driver to v1.6.0, update IsNotFound() checks
diff --git a/docs/api/ArangoMLExtension.V1Alpha1.md b/docs/api/ArangoMLExtension.V1Alpha1.md
index 2ee955e8e..3333f3c4b 100644
--- a/docs/api/ArangoMLExtension.V1Alpha1.md
+++ b/docs/api/ArangoMLExtension.V1Alpha1.md
@@ -38,7 +38,7 @@ PullSecrets define Secrets used to pull Image from registry
### .spec.deployment.prediction.resources
-Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/resources.go#L33)
+Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/resources.go#L34)
Resources holds resource requests & limits for container
@@ -83,7 +83,7 @@ PullSecrets define Secrets used to pull Image from registry
### .spec.deployment.project.resources
-Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/resources.go#L33)
+Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/resources.go#L34)
Resources holds resource requests & limits for container
@@ -155,7 +155,7 @@ PullSecrets define Secrets used to pull Image from registry
### .spec.deployment.training.resources
-Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/resources.go#L33)
+Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/resources.go#L34)
Resources holds resource requests & limits for container
@@ -172,6 +172,48 @@ Image define image details
***
+### .spec.init.affinity
+
+Type: `core.Affinity` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/scheduling.go#L37)
+
+Affinity defines scheduling constraints for workload
+
+Links:
+* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity)
+
+***
+
+### .spec.init.hostIPC
+
+Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/container_namespace.go#L33)
+
+HostIPC defines to use the host's ipc namespace.
+
+Default Value: `false`
+
+***
+
+### .spec.init.hostNetwork
+
+Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/container_namespace.go#L27)
+
+HostNetwork requests Host network for this pod. Use the host's network namespace.
+If this option is set, the ports that will be used must be specified.
+
+Default Value: `false`
+
+***
+
+### .spec.init.hostPID
+
+Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/container_namespace.go#L30)
+
+HostPID define to use the host's pid namespace.
+
+Default Value: `false`
+
+***
+
### .spec.init.image
Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/image.go#L31)
@@ -180,6 +222,28 @@ Image define image details
***
+### .spec.init.nodeSelector
+
+Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/scheduling.go#L32)
+
+NodeSelector is a selector that must be true for the workload to fit on a node.
+
+Links:
+* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector)
+
+***
+
+### .spec.init.podSecurityContext
+
+Type: `core.PodSecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/security_pod.go#L29)
+
+PodSecurityContext holds pod-level security attributes and common container settings.
+
+Links:
+* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
+
+***
+
### .spec.init.pullPolicy
Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/image.go#L35)
@@ -198,6 +262,63 @@ PullSecrets define Secrets used to pull Image from registry
***
+### .spec.init.resources
+
+Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/resources.go#L34)
+
+Resources holds resource requests & limits for container
+
+Links:
+* [Documentation of core.ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#resourcerequirements-v1-core)
+
+***
+
+### .spec.init.schedulerName
+
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/scheduling.go#L47)
+
+SchedulerName specifies, the pod will be dispatched by specified scheduler.
+If not specified, the pod will be dispatched by default scheduler.
+
+Default Value: `""`
+
+***
+
+### .spec.init.securityContext
+
+Type: `core.SecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/security_container.go#L29)
+
+PodSecurityContext holds pod-level security attributes and common container settings.
+
+Links:
+* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
+
+***
+
+### .spec.init.shareProcessNamespace
+
+Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/container_namespace.go#L39)
+
+ShareProcessNamespace defines to share a single process namespace between all of the containers in a pod.
+When this is set containers will be able to view and signal processes from other containers
+in the same pod, and the first process in each container will not be assigned PID 1.
+HostPID and ShareProcessNamespace cannot both be set.
+
+Default Value: `false`
+
+***
+
+### .spec.init.tolerations
+
+Type: `[]core.Toleration` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/scheduling.go#L42)
+
+Tolerations defines tolerations
+
+Links:
+* [Kubernetes docs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)
+
+***
+
### .spec.metadataService.local.arangoMLFeatureStore
Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/ml/v1alpha1/extension_spec_metadata_service.go#L65)
diff --git a/docs/api/ArangoMLStorage.V1Alpha1.md b/docs/api/ArangoMLStorage.V1Alpha1.md
index 371485ec8..1768faf15 100644
--- a/docs/api/ArangoMLStorage.V1Alpha1.md
+++ b/docs/api/ArangoMLStorage.V1Alpha1.md
@@ -136,7 +136,7 @@ PullSecrets define Secrets used to pull Image from registry
### .spec.mode.sidecar.resources
-Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/resources.go#L33)
+Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/resources.go#L34)
Resources holds resource requests & limits for container
@@ -145,6 +145,17 @@ Links:
***
+### .spec.mode.sidecar.securityContext
+
+Type: `core.SecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/shared/v1/security_container.go#L29)
+
+PodSecurityContext holds pod-level security attributes and common container settings.
+
+Links:
+* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
+
+***
+
### .spec.mode.sidecar.shutdownListenPort
Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.35/pkg/apis/ml/v1alpha1/storage_spec_mode_sidecar.go#L36)
diff --git a/pkg/apis/ml/v1alpha1/extension_spec.go b/pkg/apis/ml/v1alpha1/extension_spec.go
index 17f311377..b1f7e6818 100644
--- a/pkg/apis/ml/v1alpha1/extension_spec.go
+++ b/pkg/apis/ml/v1alpha1/extension_spec.go
@@ -92,7 +92,7 @@ func (a *ArangoMLExtensionSpec) Validate() error {
shared.PrefixResourceErrors("storage", shared.ValidateRequired(a.GetStorage(), func(obj sharedApi.Object) error { return obj.Validate() })),
a.GetImage().Validate(),
shared.PrefixResourceErrors("init", a.GetInit().Validate()),
- shared.ValidateAnyNotNil(".image or .init.image needs to be specified", a.GetImage(), a.GetInit().GetImage()),
+ shared.ValidateAnyNotNil(".image or .init.image needs to be specified", a.GetImage(), a.GetInit().GetContainerTemplate().GetImage()),
shared.PrefixResourceErrors("deployment", a.GetDeployment().Validate()),
))
}
diff --git a/pkg/apis/ml/v1alpha1/extension_spec_init.go b/pkg/apis/ml/v1alpha1/extension_spec_init_job.go
similarity index 64%
rename from pkg/apis/ml/v1alpha1/extension_spec_init.go
rename to pkg/apis/ml/v1alpha1/extension_spec_init_job.go
index cdc4a774b..42eab49b3 100644
--- a/pkg/apis/ml/v1alpha1/extension_spec_init.go
+++ b/pkg/apis/ml/v1alpha1/extension_spec_init_job.go
@@ -26,23 +26,36 @@ import (
)
type ArangoMLExtensionSpecInit struct {
- // Image define default image used for the init job
- *sharedApi.Image `json:",inline"`
+ // PodTemplate keeps the information about Pod configuration
+ *sharedApi.PodTemplate `json:",inline"`
+
+ // ContainerTemplate Keeps the information about Container configuration
+ *sharedApi.ContainerTemplate `json:",inline"`
}
-func (a *ArangoMLExtensionSpecInit) GetImage() *sharedApi.Image {
- if a == nil || a.Image == nil {
+func (a *ArangoMLExtensionSpecInit) GetPodTemplate() *sharedApi.PodTemplate {
+ if a == nil {
return nil
}
- return a.Image
+ return a.PodTemplate
+}
+
+func (a *ArangoMLExtensionSpecInit) GetContainerTemplate() *sharedApi.ContainerTemplate {
+ if a == nil {
+ return nil
+ }
+
+ return a.ContainerTemplate
}
func (a *ArangoMLExtensionSpecInit) Validate() error {
if a == nil {
return nil
}
+
return shared.WithErrors(
- a.GetImage().Validate(),
+ a.GetPodTemplate().Validate(),
+ a.GetContainerTemplate().Validate(),
)
}
diff --git a/pkg/apis/ml/v1alpha1/storage_spec_mode_sidecar.go b/pkg/apis/ml/v1alpha1/storage_spec_mode_sidecar.go
index e858d0070..b401e4158 100644
--- a/pkg/apis/ml/v1alpha1/storage_spec_mode_sidecar.go
+++ b/pkg/apis/ml/v1alpha1/storage_spec_mode_sidecar.go
@@ -35,27 +35,16 @@ type ArangoMLStorageSpecModeSidecar struct {
// +doc/default: 9202
ShutdownListenPort *uint16 `json:"shutdownListenPort,omitempty"`
- // Image define default image used for the extension
- *sharedApi.Image `json:",inline"`
-
- // Resources holds resource requests & limits for sidecar container
- *sharedApi.Resources `json:",inline"`
+ // ContainerTemplate Keeps the information about Container configuration
+ *sharedApi.ContainerTemplate `json:",inline"`
}
-func (s *ArangoMLStorageSpecModeSidecar) GetImage() *sharedApi.Image {
- if s == nil || s.Image == nil {
+func (s *ArangoMLStorageSpecModeSidecar) GetContainerTemplate() *sharedApi.ContainerTemplate {
+ if s == nil || s.ContainerTemplate == nil {
return nil
}
- return s.Image
-}
-
-func (s *ArangoMLStorageSpecModeSidecar) GetResources() *sharedApi.Resources {
- if s == nil || s.Resources == nil {
- return nil
- }
-
- return s.Resources
+ return s.ContainerTemplate
}
func (s *ArangoMLStorageSpecModeSidecar) Validate() error {
@@ -73,7 +62,7 @@ func (s *ArangoMLStorageSpecModeSidecar) Validate() error {
err = append(err, shared.PrefixResourceErrors("shutdownListenPort", errors.Newf("must be positive")))
}
- err = append(err, s.GetResources().Validate())
+ err = append(err, s.GetContainerTemplate().Validate())
return shared.WithErrors(err...)
}
diff --git a/pkg/apis/ml/v1alpha1/storage_spec_test.go b/pkg/apis/ml/v1alpha1/storage_spec_test.go
index 88032862e..78bbcb7d1 100644
--- a/pkg/apis/ml/v1alpha1/storage_spec_test.go
+++ b/pkg/apis/ml/v1alpha1/storage_spec_test.go
@@ -66,6 +66,7 @@ func Test_ArangoMLStorageSpec(t *testing.T) {
core.ResourceMemory: resource.MustParse("128Mi"),
},
}
+ s.Mode.Sidecar.ContainerTemplate = &sharedApi.ContainerTemplate{}
s.Mode.Sidecar.Resources = &sharedApi.Resources{Resources: &assignedRequirements}
expectedRequirements := core.ResourceRequirements{
@@ -76,7 +77,7 @@ func Test_ArangoMLStorageSpec(t *testing.T) {
},
}
- actualRequirements := s.Mode.Sidecar.GetResources().With(core.ResourceRequirements{
+ actualRequirements := s.Mode.Sidecar.GetResources().With(&sharedApi.Resources{Resources: &core.ResourceRequirements{
Limits: core.ResourceList{
core.ResourceCPU: resource.MustParse("100m"),
core.ResourceMemory: resource.MustParse("128Mi"),
@@ -85,7 +86,7 @@ func Test_ArangoMLStorageSpec(t *testing.T) {
core.ResourceCPU: resource.MustParse("200m"),
core.ResourceMemory: resource.MustParse("256Mi"),
},
- })
- require.Equal(t, expectedRequirements, actualRequirements)
+ }})
+ require.Equal(t, expectedRequirements, *actualRequirements.GetResources())
})
}
diff --git a/pkg/apis/ml/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/ml/v1alpha1/zz_generated.deepcopy.go
index 6a97c20ef..1b7b81efd 100644
--- a/pkg/apis/ml/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/ml/v1alpha1/zz_generated.deepcopy.go
@@ -446,9 +446,14 @@ func (in *ArangoMLExtensionSpecDeploymentService) DeepCopy() *ArangoMLExtensionS
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ArangoMLExtensionSpecInit) DeepCopyInto(out *ArangoMLExtensionSpecInit) {
*out = *in
- if in.Image != nil {
- in, out := &in.Image, &out.Image
- *out = new(sharedv1.Image)
+ if in.PodTemplate != nil {
+ in, out := &in.PodTemplate, &out.PodTemplate
+ *out = new(sharedv1.PodTemplate)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.ContainerTemplate != nil {
+ in, out := &in.ContainerTemplate, &out.ContainerTemplate
+ *out = new(sharedv1.ContainerTemplate)
(*in).DeepCopyInto(*out)
}
return
@@ -779,14 +784,9 @@ func (in *ArangoMLStorageSpecModeSidecar) DeepCopyInto(out *ArangoMLStorageSpecM
*out = new(uint16)
**out = **in
}
- if in.Image != nil {
- in, out := &in.Image, &out.Image
- *out = new(sharedv1.Image)
- (*in).DeepCopyInto(*out)
- }
- if in.Resources != nil {
- in, out := &in.Resources, &out.Resources
- *out = new(sharedv1.Resources)
+ if in.ContainerTemplate != nil {
+ in, out := &in.ContainerTemplate, &out.ContainerTemplate
+ *out = new(sharedv1.ContainerTemplate)
(*in).DeepCopyInto(*out)
}
return
diff --git a/pkg/apis/shared/v1/container_namespace.go b/pkg/apis/shared/v1/container_namespace.go
new file mode 100644
index 000000000..248683ef0
--- /dev/null
+++ b/pkg/apis/shared/v1/container_namespace.go
@@ -0,0 +1,76 @@
+//
+// DISCLAIMER
+//
+// Copyright 2023 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 v1
+
+type ContainerNamespace struct {
+ // HostNetwork requests Host network for this pod. Use the host's network namespace.
+ // If this option is set, the ports that will be used must be specified.
+ // +doc/default: false
+ HostNetwork bool `json:"hostNetwork,omitempty" protobuf:"varint,11,opt,name=hostNetwork"`
+ // HostPID define to use the host's pid namespace.
+ // +doc/default: false
+ HostPID bool `json:"hostPID,omitempty" protobuf:"varint,12,opt,name=hostPID"`
+ // HostIPC defines to use the host's ipc namespace.
+ // +doc/default: false
+ HostIPC bool `json:"hostIPC,omitempty" protobuf:"varint,13,opt,name=hostIPC"`
+ // ShareProcessNamespace defines to share a single process namespace between all of the containers in a pod.
+ // When this is set containers will be able to view and signal processes from other containers
+ // in the same pod, and the first process in each container will not be assigned PID 1.
+ // HostPID and ShareProcessNamespace cannot both be set.
+ // +doc/default: false
+ ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" protobuf:"varint,27,opt,name=shareProcessNamespace"`
+}
+
+func (c *ContainerNamespace) GetHostNetwork() bool {
+ if c == nil {
+ return false
+ }
+
+ return c.HostNetwork
+}
+
+func (c *ContainerNamespace) GetHostPID() bool {
+ if c == nil {
+ return false
+ }
+
+ return c.HostPID
+}
+
+func (c *ContainerNamespace) GetHostIPC() bool {
+ if c == nil {
+ return false
+ }
+
+ return c.HostIPC
+}
+
+func (c *ContainerNamespace) GetShareProcessNamespace() *bool {
+ if c == nil {
+ return nil
+ }
+
+ return c.ShareProcessNamespace
+}
+
+func (c *ContainerNamespace) Validate() error {
+ return nil
+}
diff --git a/pkg/apis/shared/v1/core_container_spec.go b/pkg/apis/shared/v1/core_container_spec.go
new file mode 100644
index 000000000..003da9885
--- /dev/null
+++ b/pkg/apis/shared/v1/core_container_spec.go
@@ -0,0 +1,91 @@
+//
+// DISCLAIMER
+//
+// Copyright 2023 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 v1
+
+import (
+ "github.com/arangodb/kube-arangodb/pkg/apis/shared"
+)
+
+type ContainerTemplate struct {
+ // Image define default image used for the job
+ *Image `json:",inline"`
+
+ // Resources define resources assigned to the pod
+ *Resources `json:",inline"`
+
+ // SecurityContainer keeps the security settings for Container
+ *SecurityContainer `json:",inline"`
+}
+
+func (a *ContainerTemplate) With(other *ContainerTemplate) *ContainerTemplate {
+ if a == nil && other == nil {
+ return nil
+ }
+
+ if a == nil {
+ return other.DeepCopy()
+ }
+
+ if other == nil {
+ return a.DeepCopy()
+ }
+
+ return &ContainerTemplate{
+ Image: a.GetImage().With(other.GetImage()),
+ Resources: a.GetResources().With(other.GetResources()),
+ SecurityContainer: a.GetSecurityContainer().With(other.GetSecurityContainer()),
+ }
+}
+
+func (a *ContainerTemplate) GetImage() *Image {
+ if a == nil || a.Image == nil {
+ return nil
+ }
+
+ return a.Image
+}
+
+func (a *ContainerTemplate) GetSecurityContainer() *SecurityContainer {
+ if a == nil || a.SecurityContainer == nil {
+ return nil
+ }
+
+ return a.SecurityContainer
+}
+
+func (a *ContainerTemplate) GetResources() *Resources {
+ if a == nil || a.Resources == nil {
+ return nil
+ }
+
+ return a.Resources
+}
+
+func (a *ContainerTemplate) Validate() error {
+ if a == nil {
+ return nil
+ }
+ return shared.WithErrors(
+ a.GetImage().Validate(),
+ a.GetResources().Validate(),
+ a.GetSecurityContainer().Validate(),
+ )
+}
diff --git a/pkg/apis/shared/v1/core_pod_spec.go b/pkg/apis/shared/v1/core_pod_spec.go
new file mode 100644
index 000000000..0a5da9f27
--- /dev/null
+++ b/pkg/apis/shared/v1/core_pod_spec.go
@@ -0,0 +1,69 @@
+//
+// DISCLAIMER
+//
+// Copyright 2023 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 v1
+
+import "github.com/arangodb/kube-arangodb/pkg/apis/shared"
+
+type PodTemplate struct {
+ // Scheduling keeps the scheduling information
+ *Scheduling `json:",inline"`
+
+ // ContainerNamespace keeps the Container layer Kernel namespace configuration
+ *ContainerNamespace `json:",inline"`
+
+ // SecurityPod keeps the security settings for Pod
+ *SecurityPod `json:",inline"`
+}
+
+func (a *PodTemplate) GetSecurityPod() *SecurityPod {
+ if a == nil {
+ return nil
+ }
+
+ return a.SecurityPod
+}
+
+func (a *PodTemplate) GetScheduling() *Scheduling {
+ if a == nil {
+ return nil
+ }
+
+ return a.Scheduling
+}
+
+func (a *PodTemplate) GetContainerNamespace() *ContainerNamespace {
+ if a == nil {
+ return nil
+ }
+
+ return a.ContainerNamespace
+}
+
+func (a *PodTemplate) Validate() error {
+ if a == nil {
+ return nil
+ }
+ return shared.WithErrors(
+ a.GetScheduling().Validate(),
+ a.GetContainerNamespace().Validate(),
+ a.GetSecurityPod().Validate(),
+ )
+}
diff --git a/pkg/apis/shared/v1/image.go b/pkg/apis/shared/v1/image.go
index e40de8043..d27948edd 100644
--- a/pkg/apis/shared/v1/image.go
+++ b/pkg/apis/shared/v1/image.go
@@ -38,6 +38,18 @@ type Image struct {
PullSecrets []string `json:"pullSecrets,omitempty"`
}
+func (i *Image) With(other *Image) *Image {
+ if i == nil && other == nil {
+ return nil
+ }
+
+ if other == nil {
+ return i.DeepCopy()
+ }
+
+ return other.DeepCopy()
+}
+
func (i *Image) GetImage() string {
if i == nil || i.Image == nil {
return ""
diff --git a/pkg/apis/shared/v1/resources.go b/pkg/apis/shared/v1/resources.go
index 6c9afca04..0fb3fe133 100644
--- a/pkg/apis/shared/v1/resources.go
+++ b/pkg/apis/shared/v1/resources.go
@@ -23,6 +23,7 @@ package v1
import (
core "k8s.io/api/core/v1"
+ "github.com/arangodb/kube-arangodb/pkg/util"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources"
)
@@ -33,12 +34,20 @@ type Resources struct {
Resources *core.ResourceRequirements `json:"resources,omitempty"`
}
-func (r *Resources) With(newResources core.ResourceRequirements) core.ResourceRequirements {
- if res := r.GetResources(); res == nil {
- return newResources
- } else {
- return resources.ApplyContainerResource(*res, newResources)
+func (r *Resources) With(newResources *Resources) *Resources {
+ if r == nil && newResources == nil {
+ return nil
}
+
+ if r == nil {
+ return newResources.DeepCopy()
+ }
+
+ if newResources == nil {
+ return r.DeepCopy()
+ }
+
+ return &Resources{Resources: util.NewType(resources.ApplyContainerResource(util.TypeOrDefault(r.GetResources()), util.TypeOrDefault(newResources.GetResources())))}
}
func (r *Resources) GetResources() *core.ResourceRequirements {
diff --git a/pkg/apis/shared/v1/scheduling.go b/pkg/apis/shared/v1/scheduling.go
new file mode 100644
index 000000000..340f7028e
--- /dev/null
+++ b/pkg/apis/shared/v1/scheduling.go
@@ -0,0 +1,84 @@
+//
+// DISCLAIMER
+//
+// Copyright 2023 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 v1
+
+import (
+ core "k8s.io/api/core/v1"
+)
+
+type SchedulingTolerations []core.Toleration
+
+type Scheduling struct {
+ // NodeSelector is a selector that must be true for the workload to fit on a node.
+ // +doc/link: Kubernetes docs|https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
+ NodeSelector map[string]string `json:"nodeSelector,omitempty"`
+
+ // Affinity defines scheduling constraints for workload
+ // +doc/type: core.Affinity
+ // +doc/link: Kubernetes docs|https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
+ Affinity *core.Affinity `json:"affinity,omitempty"`
+
+ // Tolerations defines tolerations
+ // +doc/type: []core.Toleration
+ // +doc/link: Kubernetes docs|https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/
+ Tolerations SchedulingTolerations `json:"tolerations,omitempty"`
+
+ // SchedulerName specifies, the pod will be dispatched by specified scheduler.
+ // If not specified, the pod will be dispatched by default scheduler.
+ // +doc/default: ""
+ SchedulerName *string `json:"schedulerName,omitempty"`
+}
+
+func (s *Scheduling) GetNodeSelector() map[string]string {
+ if s != nil {
+ return s.NodeSelector
+ }
+
+ return nil
+}
+
+func (s *Scheduling) GetSchedulerName() string {
+ if s != nil && s.SchedulerName != nil {
+ return *s.SchedulerName
+ }
+
+ return ""
+}
+
+func (s *Scheduling) GetAffinity() *core.Affinity {
+ if s != nil {
+ return s.Affinity
+ }
+
+ return nil
+}
+
+func (s *Scheduling) GetTolerations() SchedulingTolerations {
+ if s != nil {
+ return s.Tolerations
+ }
+
+ return nil
+}
+
+func (s *Scheduling) Validate() error {
+ return nil
+}
diff --git a/pkg/apis/shared/v1/security_container.go b/pkg/apis/shared/v1/security_container.go
new file mode 100644
index 000000000..d8d10f934
--- /dev/null
+++ b/pkg/apis/shared/v1/security_container.go
@@ -0,0 +1,56 @@
+//
+// DISCLAIMER
+//
+// Copyright 2023 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 v1
+
+import core "k8s.io/api/core/v1"
+
+type SecurityContainer struct {
+ // PodSecurityContext holds pod-level security attributes and common container settings.
+ // +doc/type: core.SecurityContext
+ // +doc/link: Kubernetes docs|https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
+ SecurityContext *core.SecurityContext `json:"securityContext,omitempty"`
+}
+
+func (s *SecurityContainer) With(other *SecurityContainer) *SecurityContainer {
+ if s == nil && other == nil {
+ return nil
+ }
+
+ if other == nil {
+ return s.DeepCopy()
+ }
+
+ // TODO: Add fine graned merge
+
+ return other.DeepCopy()
+}
+
+func (s *SecurityContainer) GetSecurityContext() *core.SecurityContext {
+ if s == nil {
+ return nil
+ }
+
+ return s.SecurityContext
+}
+
+func (s *SecurityContainer) Validate() error {
+ return nil
+}
diff --git a/pkg/apis/shared/v1/security_pod.go b/pkg/apis/shared/v1/security_pod.go
new file mode 100644
index 000000000..3d788b4c3
--- /dev/null
+++ b/pkg/apis/shared/v1/security_pod.go
@@ -0,0 +1,42 @@
+//
+// DISCLAIMER
+//
+// Copyright 2023 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 v1
+
+import core "k8s.io/api/core/v1"
+
+type SecurityPod struct {
+ // PodSecurityContext holds pod-level security attributes and common container settings.
+ // +doc/type: core.PodSecurityContext
+ // +doc/link: Kubernetes docs|https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
+ PodSecurityContext *core.PodSecurityContext `json:"podSecurityContext,omitempty"`
+}
+
+func (s *SecurityPod) GetPodSecurityContext() *core.PodSecurityContext {
+ if s == nil {
+ return nil
+ }
+
+ return s.PodSecurityContext
+}
+
+func (s *SecurityPod) Validate() error {
+ return nil
+}
diff --git a/pkg/apis/shared/v1/zz_generated.deepcopy.go b/pkg/apis/shared/v1/zz_generated.deepcopy.go
index 02d8e5454..3eb567e46 100644
--- a/pkg/apis/shared/v1/zz_generated.deepcopy.go
+++ b/pkg/apis/shared/v1/zz_generated.deepcopy.go
@@ -30,6 +30,58 @@ import (
types "k8s.io/apimachinery/pkg/types"
)
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ContainerNamespace) DeepCopyInto(out *ContainerNamespace) {
+ *out = *in
+ if in.ShareProcessNamespace != nil {
+ in, out := &in.ShareProcessNamespace, &out.ShareProcessNamespace
+ *out = new(bool)
+ **out = **in
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerNamespace.
+func (in *ContainerNamespace) DeepCopy() *ContainerNamespace {
+ if in == nil {
+ return nil
+ }
+ out := new(ContainerNamespace)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ContainerTemplate) DeepCopyInto(out *ContainerTemplate) {
+ *out = *in
+ if in.Image != nil {
+ in, out := &in.Image, &out.Image
+ *out = new(Image)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.Resources != nil {
+ in, out := &in.Resources, &out.Resources
+ *out = new(Resources)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.SecurityContainer != nil {
+ in, out := &in.SecurityContainer, &out.SecurityContainer
+ *out = new(SecurityContainer)
+ (*in).DeepCopyInto(*out)
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerTemplate.
+func (in *ContainerTemplate) DeepCopy() *ContainerTemplate {
+ if in == nil {
+ return nil
+ }
+ out := new(ContainerTemplate)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in HashList) DeepCopyInto(out *HashList) {
{
@@ -107,6 +159,37 @@ func (in *Object) DeepCopy() *Object {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *PodTemplate) DeepCopyInto(out *PodTemplate) {
+ *out = *in
+ if in.Scheduling != nil {
+ in, out := &in.Scheduling, &out.Scheduling
+ *out = new(Scheduling)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.ContainerNamespace != nil {
+ in, out := &in.ContainerNamespace, &out.ContainerNamespace
+ *out = new(ContainerNamespace)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.SecurityPod != nil {
+ in, out := &in.SecurityPod, &out.SecurityPod
+ *out = new(SecurityPod)
+ (*in).DeepCopyInto(*out)
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodTemplate.
+func (in *PodTemplate) DeepCopy() *PodTemplate {
+ if in == nil {
+ return nil
+ }
+ out := new(PodTemplate)
+ 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
@@ -128,6 +211,110 @@ func (in *Resources) DeepCopy() *Resources {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Scheduling) DeepCopyInto(out *Scheduling) {
+ *out = *in
+ if in.NodeSelector != nil {
+ in, out := &in.NodeSelector, &out.NodeSelector
+ *out = make(map[string]string, len(*in))
+ for key, val := range *in {
+ (*out)[key] = val
+ }
+ }
+ if in.Affinity != nil {
+ in, out := &in.Affinity, &out.Affinity
+ *out = new(corev1.Affinity)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.Tolerations != nil {
+ in, out := &in.Tolerations, &out.Tolerations
+ *out = make(SchedulingTolerations, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.SchedulerName != nil {
+ in, out := &in.SchedulerName, &out.SchedulerName
+ *out = new(string)
+ **out = **in
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Scheduling.
+func (in *Scheduling) DeepCopy() *Scheduling {
+ if in == nil {
+ return nil
+ }
+ out := new(Scheduling)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in SchedulingTolerations) DeepCopyInto(out *SchedulingTolerations) {
+ {
+ in := &in
+ *out = make(SchedulingTolerations, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ return
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SchedulingTolerations.
+func (in SchedulingTolerations) DeepCopy() SchedulingTolerations {
+ if in == nil {
+ return nil
+ }
+ out := new(SchedulingTolerations)
+ in.DeepCopyInto(out)
+ return *out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SecurityContainer) DeepCopyInto(out *SecurityContainer) {
+ *out = *in
+ if in.SecurityContext != nil {
+ in, out := &in.SecurityContext, &out.SecurityContext
+ *out = new(corev1.SecurityContext)
+ (*in).DeepCopyInto(*out)
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityContainer.
+func (in *SecurityContainer) DeepCopy() *SecurityContainer {
+ if in == nil {
+ return nil
+ }
+ out := new(SecurityContainer)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SecurityPod) DeepCopyInto(out *SecurityPod) {
+ *out = *in
+ if in.PodSecurityContext != nil {
+ in, out := &in.PodSecurityContext, &out.PodSecurityContext
+ *out = new(corev1.PodSecurityContext)
+ (*in).DeepCopyInto(*out)
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityPod.
+func (in *SecurityPod) DeepCopy() *SecurityPod {
+ if in == nil {
+ return nil
+ }
+ out := new(SecurityPod)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ServiceAccount) DeepCopyInto(out *ServiceAccount) {
*out = *in
diff --git a/pkg/crd/crds/ml-extension.schema.generated.yaml b/pkg/crd/crds/ml-extension.schema.generated.yaml
index 865964bba..772cc7d2c 100644
--- a/pkg/crd/crds/ml-extension.schema.generated.yaml
+++ b/pkg/crd/crds/ml-extension.schema.generated.yaml
@@ -122,9 +122,385 @@ v1alpha1:
init:
description: ArangoMLExtensionSpecInit define Init job specification
properties:
+ affinity:
+ description: Affinity defines scheduling constraints for workload
+ properties:
+ nodeAffinity:
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ items:
+ properties:
+ preference:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchFields:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ type: object
+ weight:
+ format: int32
+ type: integer
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ properties:
+ nodeSelectorTerms:
+ items:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchFields:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ type: object
+ type: array
+ type: object
+ type: object
+ podAffinity:
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ items:
+ properties:
+ podAffinityTerm:
+ properties:
+ labelSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ namespaceSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ namespaces:
+ items:
+ type: string
+ type: array
+ topologyKey:
+ type: string
+ type: object
+ weight:
+ format: int32
+ type: integer
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ items:
+ properties:
+ labelSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ namespaceSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ namespaces:
+ items:
+ type: string
+ type: array
+ topologyKey:
+ type: string
+ type: object
+ type: array
+ type: object
+ podAntiAffinity:
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ items:
+ properties:
+ podAffinityTerm:
+ properties:
+ labelSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ namespaceSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ namespaces:
+ items:
+ type: string
+ type: array
+ topologyKey:
+ type: string
+ type: object
+ weight:
+ format: int32
+ type: integer
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ items:
+ properties:
+ labelSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ namespaceSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ namespaces:
+ items:
+ type: string
+ type: array
+ topologyKey:
+ type: string
+ type: object
+ type: array
+ type: object
+ type: object
+ hostIPC:
+ description: HostIPC defines to use the host's ipc namespace.
+ type: boolean
+ hostNetwork:
+ description: |-
+ HostNetwork requests Host network for this pod. Use the host's network namespace.
+ If this option is set, the ports that will be used must be specified.
+ type: boolean
+ hostPID:
+ description: HostPID define to use the host's pid namespace.
+ type: boolean
image:
description: Image define image details
type: string
+ nodeSelector:
+ additionalProperties:
+ type: string
+ description: NodeSelector is a selector that must be true for the workload to fit on a node.
+ type: object
+ podSecurityContext:
+ description: PodSecurityContext holds pod-level security attributes and common container settings.
+ properties:
+ fsGroup:
+ format: int64
+ type: integer
+ fsGroupChangePolicy:
+ type: string
+ runAsGroup:
+ format: int64
+ type: integer
+ runAsNonRoot:
+ type: boolean
+ runAsUser:
+ format: int64
+ type: integer
+ seLinuxOptions:
+ properties:
+ level:
+ type: string
+ role:
+ type: string
+ type:
+ type: string
+ user:
+ type: string
+ type: object
+ seccompProfile:
+ properties:
+ localhostProfile:
+ type: string
+ type:
+ type: string
+ type: object
+ supplementalGroups:
+ items:
+ format: int64
+ type: integer
+ type: array
+ sysctls:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ windowsOptions:
+ properties:
+ gmsaCredentialSpec:
+ type: string
+ gmsaCredentialSpecName:
+ type: string
+ hostProcess:
+ type: boolean
+ runAsUserName:
+ type: string
+ type: object
+ type: object
pullPolicy:
description: PullPolicy define Image pull policy
type: string
@@ -133,6 +509,107 @@ v1alpha1:
items:
type: string
type: array
+ resources:
+ description: Resources holds resource requests & limits for container
+ properties:
+ limits:
+ additionalProperties:
+ type: string
+ type: object
+ requests:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ schedulerName:
+ description: |-
+ SchedulerName specifies, the pod will be dispatched by specified scheduler.
+ If not specified, the pod will be dispatched by default scheduler.
+ type: string
+ securityContext:
+ description: PodSecurityContext holds pod-level security attributes and common container settings.
+ properties:
+ allowPrivilegeEscalation:
+ type: boolean
+ capabilities:
+ properties:
+ add:
+ items:
+ type: string
+ type: array
+ drop:
+ items:
+ type: string
+ type: array
+ type: object
+ privileged:
+ type: boolean
+ procMount:
+ type: string
+ readOnlyRootFilesystem:
+ type: boolean
+ runAsGroup:
+ format: int64
+ type: integer
+ runAsNonRoot:
+ type: boolean
+ runAsUser:
+ format: int64
+ type: integer
+ seLinuxOptions:
+ properties:
+ level:
+ type: string
+ role:
+ type: string
+ type:
+ type: string
+ user:
+ type: string
+ type: object
+ seccompProfile:
+ properties:
+ localhostProfile:
+ type: string
+ type:
+ type: string
+ type: object
+ windowsOptions:
+ properties:
+ gmsaCredentialSpec:
+ type: string
+ gmsaCredentialSpecName:
+ type: string
+ hostProcess:
+ type: boolean
+ runAsUserName:
+ type: string
+ type: object
+ type: object
+ shareProcessNamespace:
+ description: |-
+ ShareProcessNamespace defines to share a single process namespace between all of the containers in a pod.
+ When this is set containers will be able to view and signal processes from other containers
+ in the same pod, and the first process in each container will not be assigned PID 1.
+ HostPID and ShareProcessNamespace cannot both be set.
+ type: boolean
+ tolerations:
+ description: Tolerations defines tolerations
+ items:
+ properties:
+ effect:
+ type: string
+ key:
+ type: string
+ operator:
+ type: string
+ tolerationSeconds:
+ format: int64
+ type: integer
+ value:
+ type: string
+ type: object
+ type: array
type: object
metadataService:
description: MetadataService keeps the MetadataService configuration
diff --git a/pkg/crd/crds/ml-storage.schema.generated.yaml b/pkg/crd/crds/ml-storage.schema.generated.yaml
index addb482bc..a102f7fc1 100644
--- a/pkg/crd/crds/ml-storage.schema.generated.yaml
+++ b/pkg/crd/crds/ml-storage.schema.generated.yaml
@@ -95,6 +95,66 @@ v1alpha1:
type: string
type: object
type: object
+ securityContext:
+ description: PodSecurityContext holds pod-level security attributes and common container settings.
+ properties:
+ allowPrivilegeEscalation:
+ type: boolean
+ capabilities:
+ properties:
+ add:
+ items:
+ type: string
+ type: array
+ drop:
+ items:
+ type: string
+ type: array
+ type: object
+ privileged:
+ type: boolean
+ procMount:
+ type: string
+ readOnlyRootFilesystem:
+ type: boolean
+ runAsGroup:
+ format: int64
+ type: integer
+ runAsNonRoot:
+ type: boolean
+ runAsUser:
+ format: int64
+ type: integer
+ seLinuxOptions:
+ properties:
+ level:
+ type: string
+ role:
+ type: string
+ type:
+ type: string
+ user:
+ type: string
+ type: object
+ seccompProfile:
+ properties:
+ localhostProfile:
+ type: string
+ type:
+ type: string
+ type: object
+ windowsOptions:
+ properties:
+ gmsaCredentialSpec:
+ type: string
+ gmsaCredentialSpecName:
+ type: string
+ hostProcess:
+ type: boolean
+ runAsUserName:
+ type: string
+ type: object
+ type: object
shutdownListenPort:
description: ShutdownListenPort defines on which port the sidecar container will be listening for shutdown connections
format: int32
diff --git a/pkg/util/dict.go b/pkg/util/dict.go
index a516d3209..fa138e97b 100644
--- a/pkg/util/dict.go
+++ b/pkg/util/dict.go
@@ -43,6 +43,18 @@ func SortKeys(m interface{}) []string {
return r
}
+func CopyFullMap[K comparable, V any](src map[K]V) map[K]V {
+ if src == nil {
+ return nil
+ }
+
+ r := map[K]V{}
+
+ CopyMap(r, src)
+
+ return r
+}
+
func CopyMap[K comparable, V any](dst, src map[K]V) {
// TODO: replace with maps.Copy when switching to go1.21
for k, v := range src {
diff --git a/pkg/util/k8sutil/deepcopy.go b/pkg/util/k8sutil/deepcopy.go
index 837475c8c..455197ca9 100644
--- a/pkg/util/k8sutil/deepcopy.go
+++ b/pkg/util/k8sutil/deepcopy.go
@@ -21,5 +21,5 @@
package k8sutil
type DeepCopy[T interface{}] interface {
- DeepCopy() T
+ DeepCopy() DeepCopy[T]
}
diff --git a/pkg/util/k8sutil/pods.go b/pkg/util/k8sutil/pods.go
index d49471479..90485e0df 100644
--- a/pkg/util/k8sutil/pods.go
+++ b/pkg/util/k8sutil/pods.go
@@ -36,6 +36,7 @@ import (
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/apis/shared"
+ sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1"
"github.com/arangodb/kube-arangodb/pkg/deployment/features"
"github.com/arangodb/kube-arangodb/pkg/deployment/patch"
"github.com/arangodb/kube-arangodb/pkg/handlers/utils"
@@ -763,3 +764,41 @@ func GetFinalizers(spec api.ServerGroupSpec, group api.ServerGroup) []string {
return finalizers
}
+
+func InjectPodTemplate(spec *sharedApi.PodTemplate, pod *core.PodTemplateSpec) error {
+ if scheduling := spec.GetScheduling(); scheduling != nil {
+ pod.Spec.Tolerations = scheduling.GetTolerations().DeepCopy()
+ pod.Spec.Affinity = scheduling.GetAffinity().DeepCopy()
+ pod.Spec.NodeSelector = util.CopyFullMap(scheduling.GetNodeSelector())
+ pod.Spec.SchedulerName = spec.GetSchedulerName()
+ }
+
+ if namespace := spec.GetContainerNamespace(); namespace != nil {
+ pod.Spec.HostNetwork = namespace.GetHostNetwork()
+ pod.Spec.HostPID = namespace.GetHostPID()
+ pod.Spec.HostIPC = namespace.GetHostIPC()
+ pod.Spec.ShareProcessNamespace = util.NewType(util.TypeOrDefault(namespace.GetShareProcessNamespace(), false))
+ }
+
+ if security := spec.GetSecurityPod(); security != nil {
+ pod.Spec.SecurityContext = security.PodSecurityContext.DeepCopy()
+ }
+
+ return nil
+}
+
+func InjectContainerTemplate(spec *sharedApi.ContainerTemplate, pod *core.PodTemplateSpec, container *core.Container) error {
+ if err := InjectImageDetails(spec.GetImage(), pod, container); err != nil {
+ return err
+ }
+
+ if res := spec.GetResources(); res != nil {
+ container.Resources = util.TypeOrDefault(res.GetResources())
+ }
+
+ if security := spec.GetSecurityContainer(); security != nil {
+ container.SecurityContext = security.SecurityContext.DeepCopy()
+ }
+
+ return nil
+}