This is an automated email from the ASF dual-hosted git repository.
roryqi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-uniffle.git
The following commit(s) were added to refs/heads/master by this push:
new a4d8c8f9d [#288] feat(operator): Supports mounting PVC for
shuffleserver (#1813)
a4d8c8f9d is described below
commit a4d8c8f9d9c61cff06d472dd97b6e13b62cf3c74
Author: roryqi <[email protected]>
AuthorDate: Thu Jun 20 10:17:49 2024 +0800
[#288] feat(operator): Supports mounting PVC for shuffleserver (#1813)
### What changes were proposed in this pull request?
Previous pull request is
https://github.com/apache/incubator-uniffle/pull/466
Supports mounting PVC for shuffleserver
### Why are the changes needed?
Fix: #288
### Does this PR introduce _any_ user-facing change?
Yes, added the document.
### How was this patch tested?
Add uts and test by hand in the GKE.
Co-authored-by: alexcqtan <[email protected]>
---
.../uniffle/v1alpha1/remoteshuffleservice_types.go | 23 +++
.../api/uniffle/v1alpha1/zz_generated.deepcopy.go | 28 +++
.../uniffle.apache.org_remoteshuffleservices.yaml | 199 +++++++++++++++++++++
.../operator/examples/pvc-example/README.md | 28 +++
.../examples/pvc-example/gce-storage-class.yml | 25 +++
.../examples/pvc-example/rss-pvc-on-gce.yaml | 69 +++++++
.../controller/sync/shuffleserver/shuffleserver.go | 16 ++
.../sync/shuffleserver/shuffleserver_test.go | 49 +++++
8 files changed, 437 insertions(+)
diff --git
a/deploy/kubernetes/operator/api/uniffle/v1alpha1/remoteshuffleservice_types.go
b/deploy/kubernetes/operator/api/uniffle/v1alpha1/remoteshuffleservice_types.go
index cd53c2a12..978695343 100644
---
a/deploy/kubernetes/operator/api/uniffle/v1alpha1/remoteshuffleservice_types.go
+++
b/deploy/kubernetes/operator/api/uniffle/v1alpha1/remoteshuffleservice_types.go
@@ -142,6 +142,29 @@ type ShuffleServerConfig struct {
// UpgradeStrategy defines upgrade strategy of shuffle servers.
UpgradeStrategy *ShuffleServerUpgradeStrategy `json:"upgradeStrategy"`
+
+ // volumeClaimTemplates is a list of claims that pods are allowed to
reference.
+ // The StatefulSet controller is responsible for mapping network
identities to
+ // claims in a way that maintains the identity of a pod. Every claim in
+ // this list must have at least one matching (by name) volumeMount in
one
+ // container in the template. A claim in this list takes precedence over
+ // any volumes in the template, with the same name.
+ // +optional
+ VolumeClaimTemplates []ShuffleServerPersistentVolumeClaimTemplate
`json:"volumeClaimTemplates,omitempty"
protobuf:"bytes,4,rep,name=volumeClaimTemplates"`
+}
+
+type ShuffleServerPersistentVolumeClaimTemplate struct {
+ // May contain labels and annotations that will be copied into the PVC
+ // when creating it. No other fields are allowed and will be rejected
during
+ // validation.
+ //
+ VolumeNameTemplate *string `json:"volumeNameTemplate"`
+
+ // The specification for the PersistentVolumeClaim. The entire content
is
+ // copied unchanged into the PVC that gets created from this
+ // template. The same fields as in a PersistentVolumeClaim
+ // are also valid here.
+ Spec corev1.PersistentVolumeClaimSpec `json:"spec"
protobuf:"bytes,2,name=spec"`
}
// ShuffleServerUpgradeStrategy defines upgrade strategy of shuffle servers.
diff --git
a/deploy/kubernetes/operator/api/uniffle/v1alpha1/zz_generated.deepcopy.go
b/deploy/kubernetes/operator/api/uniffle/v1alpha1/zz_generated.deepcopy.go
index 8d4d40def..0c7389f29 100644
--- a/deploy/kubernetes/operator/api/uniffle/v1alpha1/zz_generated.deepcopy.go
+++ b/deploy/kubernetes/operator/api/uniffle/v1alpha1/zz_generated.deepcopy.go
@@ -443,6 +443,13 @@ func (in *ShuffleServerConfig) DeepCopyInto(out
*ShuffleServerConfig) {
*out = new(ShuffleServerUpgradeStrategy)
(*in).DeepCopyInto(*out)
}
+ if in.VolumeClaimTemplates != nil {
+ in, out := &in.VolumeClaimTemplates, &out.VolumeClaimTemplates
+ *out = make([]ShuffleServerPersistentVolumeClaimTemplate,
len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver,
creating a new ShuffleServerConfig.
@@ -455,6 +462,27 @@ func (in *ShuffleServerConfig) DeepCopy()
*ShuffleServerConfig {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver,
writing into out. in must be non-nil.
+func (in *ShuffleServerPersistentVolumeClaimTemplate) DeepCopyInto(out
*ShuffleServerPersistentVolumeClaimTemplate) {
+ *out = *in
+ if in.VolumeNameTemplate != nil {
+ in, out := &in.VolumeNameTemplate, &out.VolumeNameTemplate
+ *out = new(string)
+ **out = **in
+ }
+ in.Spec.DeepCopyInto(&out.Spec)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver,
creating a new ShuffleServerPersistentVolumeClaimTemplate.
+func (in *ShuffleServerPersistentVolumeClaimTemplate) DeepCopy()
*ShuffleServerPersistentVolumeClaimTemplate {
+ if in == nil {
+ return nil
+ }
+ out := new(ShuffleServerPersistentVolumeClaimTemplate)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver,
writing into out. in must be non-nil.
func (in *ShuffleServerUpgradeStrategy) DeepCopyInto(out
*ShuffleServerUpgradeStrategy) {
*out = *in
diff --git
a/deploy/kubernetes/operator/config/crd/bases/uniffle.apache.org_remoteshuffleservices.yaml
b/deploy/kubernetes/operator/config/crd/bases/uniffle.apache.org_remoteshuffleservices.yaml
index 314304cd5..9dca5b422 100644
---
a/deploy/kubernetes/operator/config/crd/bases/uniffle.apache.org_remoteshuffleservices.yaml
+++
b/deploy/kubernetes/operator/config/crd/bases/uniffle.apache.org_remoteshuffleservices.yaml
@@ -8362,6 +8362,205 @@ spec:
required:
- type
type: object
+ volumeClaimTemplates:
+ description: volumeClaimTemplates is a list of claims that
pods
+ are allowed to reference. The StatefulSet controller is
responsible
+ for mapping network identities to claims in a way that
maintains
+ the identity of a pod. Every claim in this list must
have at
+ least one matching (by name) volumeMount in one
container in
+ the template. A claim in this list takes precedence over
any
+ volumes in the template, with the same name.
+ items:
+ properties:
+ spec:
+ description: The specification for the
PersistentVolumeClaim.
+ The entire content is copied unchanged into the
PVC that
+ gets created from this template. The same fields
as in
+ a PersistentVolumeClaim are also valid here.
+ properties:
+ accessModes:
+ description: 'accessModes contains the desired
access
+ modes the volume should have. More info:
https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1'
+ items:
+ type: string
+ type: array
+ dataSource:
+ description: 'dataSource field can be used to
specify
+ either: * An existing VolumeSnapshot object
(snapshot.storage.k8s.io/VolumeSnapshot)
+ * An existing PVC (PersistentVolumeClaim) If
the provisioner
+ or an external controller can support the
specified
+ data source, it will create a new volume based
on
+ the contents of the specified data source. If
the
+ AnyVolumeDataSource feature gate is enabled,
this
+ field will always have the same contents as
the DataSourceRef
+ field.'
+ properties:
+ apiGroup:
+ description: APIGroup is the group for the
resource
+ being referenced. If APIGroup is not
specified,
+ the specified Kind must be in the core API
group.
+ For any other third-party types, APIGroup
is required.
+ type: string
+ kind:
+ description: Kind is the type of resource
being
+ referenced
+ type: string
+ name:
+ description: Name is the name of resource
being
+ referenced
+ type: string
+ required:
+ - kind
+ - name
+ type: object
+ x-kubernetes-map-type: atomic
+ dataSourceRef:
+ description: 'dataSourceRef specifies the object
from
+ which to populate the volume with data, if a
non-empty
+ volume is desired. This may be any local
object from
+ a non-empty API group (non core object) or a
PersistentVolumeClaim
+ object. When this field is specified, volume
binding
+ will only succeed if the type of the specified
object
+ matches some installed volume populator or
dynamic
+ provisioner. This field will replace the
functionality
+ of the DataSource field and as such if both
fields
+ are non-empty, they must have the same value.
For
+ backwards compatibility, both fields
(DataSource and
+ DataSourceRef) will be set to the same value
automatically
+ if one of them is empty and the other is
non-empty.
+ There are two important differences between
DataSource
+ and DataSourceRef: * While DataSource only
allows
+ two specific types of objects, DataSourceRef
allows
+ any non-core object, as well as
PersistentVolumeClaim
+ objects. * While DataSource ignores disallowed
values
+ (dropping them), DataSourceRef preserves all
values,
+ and generates an error if a disallowed value
is specified.
+ (Beta) Using this field requires the
AnyVolumeDataSource
+ feature gate to be enabled.'
+ properties:
+ apiGroup:
+ description: APIGroup is the group for the
resource
+ being referenced. If APIGroup is not
specified,
+ the specified Kind must be in the core API
group.
+ For any other third-party types, APIGroup
is required.
+ type: string
+ kind:
+ description: Kind is the type of resource
being
+ referenced
+ type: string
+ name:
+ description: Name is the name of resource
being
+ referenced
+ type: string
+ required:
+ - kind
+ - name
+ type: object
+ x-kubernetes-map-type: atomic
+ resources:
+ description: 'resources represents the minimum
resources
+ the volume should have. If
RecoverVolumeExpansionFailure
+ feature is enabled users are allowed to
specify resource
+ requirements that are lower than previous
value but
+ must still be higher than capacity recorded in
the
+ status field of the claim. More info:
https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources'
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern:
^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum
amount
+ of compute resources allowed. More info:
https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern:
^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum
amount
+ of compute resources required. If Requests
is
+ omitted for a container, it defaults to
Limits
+ if that is explicitly specified, otherwise
to
+ an implementation-defined value. More
info:
https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ type: object
+ selector:
+ description: selector is a label query over
volumes
+ to consider for binding.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of
label
+ selector requirements. The requirements
are ANDed.
+ items:
+ description: A label selector requirement
is a
+ selector that contains values, a key,
and an
+ operator that relates the key and values.
+ properties:
+ key:
+ description: key is the label key that
the
+ selector applies to.
+ type: string
+ operator:
+ description: operator represents a
key's relationship
+ to a set of values. Valid operators
are
+ In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of
string
+ values. If the operator is In or
NotIn,
+ the values array must be non-empty.
If the
+ operator is Exists or DoesNotExist,
the
+ values array must be empty. This
array is
+ replaced during a strategic merge
patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of
{key,value}
+ pairs. A single {key,value} in the
matchLabels
+ map is equivalent to an element of
matchExpressions,
+ whose key field is "key", the operator is
"In",
+ and the values array contains only
"value". The
+ requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ storageClassName:
+ description: 'storageClassName is the name of
the StorageClass
+ required by the claim. More info:
https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1'
+ type: string
+ volumeMode:
+ description: volumeMode defines what type of
volume
+ is required by the claim. Value of Filesystem
is implied
+ when not included in claim spec.
+ type: string
+ volumeName:
+ description: volumeName is the binding reference
to
+ the PersistentVolume backing this claim.
+ type: string
+ type: object
+ volumeNameTemplate:
+ description: May contain labels and annotations that
will
+ be copied into the PVC when creating it. No other
fields
+ are allowed and will be rejected during validation.
+ type: string
+ required:
+ - spec
+ - volumeNameTemplate
+ type: object
+ type: array
volumeMounts:
description: VolumeMounts indicates describes mountings of
volumes
within shuffle servers' container.
diff --git a/deploy/kubernetes/operator/examples/pvc-example/README.md
b/deploy/kubernetes/operator/examples/pvc-example/README.md
new file mode 100644
index 000000000..ea18de844
--- /dev/null
+++ b/deploy/kubernetes/operator/examples/pvc-example/README.md
@@ -0,0 +1,28 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You 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.
+ -->
+
+# Use PVC for Shuffle Servers
+
+If we want to use PVC for shuffle servers, we need to edit the rss object as
follows.
+
++ update `.spec.shuffleServer.volumeMounts` with the mount points of PVC.
++ update `.spec.shuffleServer.volumeClaimTemplates` with the correct volume
claim templates.
+
+We can refer to the [example](rss-pvc-on-gce.yaml).
+Of course, you should create a storage class first if it's not already created.
+You may have to ask your K8S administrator to create one.
+A [storage class](gce-storage-class.yml) is also provided in this example dir.
\ No newline at end of file
diff --git
a/deploy/kubernetes/operator/examples/pvc-example/gce-storage-class.yml
b/deploy/kubernetes/operator/examples/pvc-example/gce-storage-class.yml
new file mode 100644
index 000000000..7a09ae372
--- /dev/null
+++ b/deploy/kubernetes/operator/examples/pvc-example/gce-storage-class.yml
@@ -0,0 +1,25 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+---
+apiVersion: storage.k8s.io/v1
+kind: StorageClass
+metadata:
+ name: fast
+provisioner: kubernetes.io/gce-pd
+parameters:
+ type: pd-ssd
diff --git
a/deploy/kubernetes/operator/examples/pvc-example/rss-pvc-on-gce.yaml
b/deploy/kubernetes/operator/examples/pvc-example/rss-pvc-on-gce.yaml
new file mode 100644
index 000000000..a72020d36
--- /dev/null
+++ b/deploy/kubernetes/operator/examples/pvc-example/rss-pvc-on-gce.yaml
@@ -0,0 +1,69 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+---
+apiVersion: uniffle.apache.org/v1alpha1
+kind: RemoteShuffleService
+metadata:
+ name: rss-pvc-full-restart-demo
+ namespace: kube-system
+spec:
+ configMapName: "${rss-configuration-name}"
+ coordinator:
+ image: "${rss-shuffle-server-image}"
+ initContainerImage: "busybox:latest"
+ rpcNodePort:
+ - 32005
+ - 32015
+ httpNodePort:
+ - 32006
+ - 32016
+ xmxSize: "10G"
+ configDir: "/data/rssadmin/rss/conf"
+ replicas: 1
+ excludeNodesFilePath: "/data/rssadmin/rss/coo/exclude_nodes"
+ securityContext:
+ runAsUser: 1000
+ fsGroup: 1000
+ shuffleServer:
+ sync: true
+ replicas: 2
+ rpcPort: 20009
+ rpcNodePort: 20009
+ httpPort: 20019
+ httpNodePort: 20019
+ image: "${rss-shuffle-server-image}"
+ initContainerImage: "busybox:latest"
+ upgradeStrategy:
+ type: "FullRestart"
+ xmxSize: "10G"
+ configDir: "/data/rssadmin/rss/conf"
+ securityContext:
+ runAsUser: 1000
+ fsGroup: 1000
+ # volumeMount.name is mapping to volumeClaimTemplate.volumeNameTemplate
+ volumeMounts:
+ - name: volume
+ mountPath: /data1
+ volumeClaimTemplates:
+ - volumeNameTemplate: "volume"
+ spec:
+ accessModes: ["ReadWriteOnce"]
+ storageClassName: fast
+ resources:
+ requests:
+ storage: "${storage-size}"
diff --git
a/deploy/kubernetes/operator/pkg/controller/sync/shuffleserver/shuffleserver.go
b/deploy/kubernetes/operator/pkg/controller/sync/shuffleserver/shuffleserver.go
index a96c0eba0..867a40386 100644
---
a/deploy/kubernetes/operator/pkg/controller/sync/shuffleserver/shuffleserver.go
+++
b/deploy/kubernetes/operator/pkg/controller/sync/shuffleserver/shuffleserver.go
@@ -198,6 +198,17 @@ func GenerateSts(kubeClient kubernetes.Interface, rss
*unifflev1alpha1.RemoteShu
sts.Spec.Template.Spec.RuntimeClassName =
rss.Spec.ShuffleServer.RuntimeClassName
}
+ // add VolumeClaimTemplates, support cloud storage
+ sts.Spec.VolumeClaimTemplates = make([]corev1.PersistentVolumeClaim, 0,
len(rss.Spec.ShuffleServer.VolumeClaimTemplates))
+ for _, pvcTemplate := range rss.Spec.ShuffleServer.VolumeClaimTemplates
{
+ sts.Spec.VolumeClaimTemplates =
append(sts.Spec.VolumeClaimTemplates, corev1.PersistentVolumeClaim{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: *pvcTemplate.VolumeNameTemplate,
+ },
+ Spec: pvcTemplate.Spec,
+ })
+ }
+
// add init containers, the main container and other containers.
sts.Spec.Template.Spec.InitContainers =
util.GenerateInitContainers(rss.Spec.ShuffleServer.RSSPodSpec)
containers := []corev1.Container{*generateMainContainer(rss)}
@@ -238,6 +249,11 @@ func generateStorageBasePath(rss
*unifflev1alpha1.RemoteShuffleService) string {
}
paths = append(paths, strings.TrimSuffix(v,
"/")+"/"+controllerconstants.RssDataDir)
}
+
+ for _, vm := range rss.Spec.ShuffleServer.VolumeMounts {
+ paths = append(paths, strings.TrimSuffix(vm.MountPath,
"/")+"/"+controllerconstants.RssDataDir)
+ }
+
sort.Strings(paths)
return strings.Join(paths, ",")
}
diff --git
a/deploy/kubernetes/operator/pkg/controller/sync/shuffleserver/shuffleserver_test.go
b/deploy/kubernetes/operator/pkg/controller/sync/shuffleserver/shuffleserver_test.go
index f8c7e0a7e..dc151c5df 100644
---
a/deploy/kubernetes/operator/pkg/controller/sync/shuffleserver/shuffleserver_test.go
+++
b/deploy/kubernetes/operator/pkg/controller/sync/shuffleserver/shuffleserver_test.go
@@ -27,6 +27,8 @@ import (
appsv1 "k8s.io/api/apps/v1"
autoscalingv2 "k8s.io/api/autoscaling/v2"
corev1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/api/resource"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/utils/pointer"
@@ -138,6 +140,26 @@ var (
Name: "default-secret",
},
}
+
+ standard = "standard"
+ testVolumeClaimTemplates = []corev1.PersistentVolumeClaim{
+ {
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "testVolumeClaimTemplate",
+ },
+ Spec: corev1.PersistentVolumeClaimSpec{
+ AccessModes:
[]corev1.PersistentVolumeAccessMode{
+ "ReadWriteOnce",
+ },
+ Resources: corev1.ResourceRequirements{
+ Requests: corev1.ResourceList{
+ "storage":
*resource.NewQuantity(5*1000*1000*1000, resource.DecimalSI),
+ },
+ },
+ StorageClassName: &standard,
+ },
+ },
+ }
)
func buildRssWithLabels() *uniffleapi.RemoteShuffleService {
@@ -199,6 +221,18 @@ func withCustomImagePullSecrets(imagePullSecrets
[]corev1.LocalObjectReference)
return rss
}
+func withCustomVolumeClaimTemplates(volumeClaimTemplates
[]corev1.PersistentVolumeClaim) *uniffleapi.RemoteShuffleService {
+ rss := utils.BuildRSSWithDefaultValue()
+ rss.Spec.ShuffleServer.VolumeClaimTemplates =
make([]uniffleapi.ShuffleServerPersistentVolumeClaimTemplate, 0,
len(volumeClaimTemplates))
+ for _, pvcTemplate := range volumeClaimTemplates {
+ rss.Spec.ShuffleServer.VolumeClaimTemplates =
append(rss.Spec.ShuffleServer.VolumeClaimTemplates,
uniffleapi.ShuffleServerPersistentVolumeClaimTemplate{
+ VolumeNameTemplate: &pvcTemplate.ObjectMeta.Name,
+ Spec: pvcTemplate.Spec,
+ })
+ }
+ return rss
+}
+
func buildRssWithHPA() *uniffleapi.RemoteShuffleService {
rss := utils.BuildRSSWithDefaultValue()
rss.Spec.ShuffleServer.Autoscaler.Enable = true
@@ -486,6 +520,21 @@ func TestGenerateSts(t *testing.T) {
return false, fmt.Errorf("generated sts should
include imagePullSecrets: %v", testImagePullSecrets)
},
},
+ {
+ name: "set volume claim templates",
+ rss:
withCustomVolumeClaimTemplates(testVolumeClaimTemplates),
+ IsValidSts: func(deploy *appsv1.StatefulSet, rss
*uniffleapi.RemoteShuffleService) (bool, error) {
+ if deploy.Spec.VolumeClaimTemplates != nil {
+ for _, volumeClaimTemplate := range
deploy.Spec.VolumeClaimTemplates {
+ equal :=
reflect.DeepEqual(volumeClaimTemplate, testVolumeClaimTemplates[0])
+ if equal {
+ return true, nil
+ }
+ }
+ }
+ return false, fmt.Errorf("generated sts should
include volumeClaimTemplates: %v", testImagePullSecrets)
+ },
+ },
} {
t.Run(tt.name, func(tc *testing.T) {
sts := GenerateSts(nil, tt.rss)