Skip to content

Commit f055390

Browse files
committed
Add additional volume for postgres, v0
1 parent 71b7c08 commit f055390

File tree

9 files changed

+724
-0
lines changed

9 files changed

+724
-0
lines changed

config/crd/bases/postgres-operator.crunchydata.com_postgresclusters.yaml

Lines changed: 479 additions & 0 deletions
Large diffs are not rendered by default.

internal/controller/postgrescluster/instance.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,6 +1184,10 @@ func (r *Reconciler) reconcileInstance(
11841184
if err == nil {
11851185
tablespaceVolumes, err = r.reconcileTablespaceVolumes(ctx, cluster, spec, instance, clusterVolumes)
11861186
}
1187+
if err == nil {
1188+
_, err = r.reconcileAdditionalVolumes(ctx,
1189+
cluster, spec.Volumes.Additional)
1190+
}
11871191
if err == nil {
11881192
postgres.InstancePod(
11891193
ctx, cluster, spec,
@@ -1254,6 +1258,11 @@ func (r *Reconciler) reconcileInstance(
12541258
addDevSHM(&instance.Spec.Template)
12551259
}
12561260

1261+
// mount additional volumes to the Postgres instance containers
1262+
if err == nil && spec.Volumes != nil && spec.Volumes.Additional != nil {
1263+
addAdditionalVolumes(&instance.Spec.Template, cluster, spec.Volumes.Additional)
1264+
}
1265+
12571266
if err == nil {
12581267
err = errors.WithStack(r.apply(ctx, instance))
12591268
}

internal/controller/postgrescluster/util.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99
"hash/fnv"
1010
"io"
11+
"slices"
1112

1213
batchv1 "k8s.io/api/batch/v1"
1314
corev1 "k8s.io/api/core/v1"
@@ -16,6 +17,7 @@ import (
1617

1718
"github.com/crunchydata/postgres-operator/internal/initialize"
1819
"github.com/crunchydata/postgres-operator/internal/naming"
20+
"github.com/crunchydata/postgres-operator/pkg/apis/postgres-operator.crunchydata.com/v1beta1"
1921
)
2022

2123
var tmpDirSizeLimit = resource.MustParse("16Mi")
@@ -285,3 +287,63 @@ func safeHash32(content func(w io.Writer) error) (string, error) {
285287
}
286288
return rand.SafeEncodeString(fmt.Sprint(hash.Sum32())), nil
287289
}
290+
291+
// AdditionalVolumeMount returns the name and mount path of the additional volume.
292+
func AdditionalVolumeMount(cluster *v1beta1.PostgresCluster,
293+
additionalVolume *v1beta1.AdditionalVolume) corev1.VolumeMount {
294+
295+
volumeName := naming.AdditionalVolume(cluster, additionalVolume).Name
296+
297+
return corev1.VolumeMount{
298+
Name: volumeName,
299+
MountPath: "volumes" + "/" + additionalVolume.Name}
300+
}
301+
302+
// addAdditionalVolumes adds additional volumes to the Postgres pod
303+
func addAdditionalVolumes(template *corev1.PodTemplateSpec,
304+
inCluster *v1beta1.PostgresCluster,
305+
additionalVolumes []*v1beta1.AdditionalVolume) {
306+
307+
for _, additionalVolume := range additionalVolumes {
308+
309+
additionalVolumeMount := AdditionalVolumeMount(
310+
inCluster,
311+
additionalVolume)
312+
313+
additionalVolumeSpec := corev1.Volume{
314+
Name: additionalVolumeMount.Name,
315+
VolumeSource: corev1.VolumeSource{
316+
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
317+
ClaimName: additionalVolumeMount.Name,
318+
ReadOnly: additionalVolume.ReadOnly,
319+
},
320+
},
321+
}
322+
323+
for i := range template.Spec.Containers {
324+
if len(additionalVolume.Containers) == 0 ||
325+
slices.Contains(
326+
additionalVolume.Containers,
327+
template.Spec.Containers[i].Name) {
328+
template.Spec.Containers[i].VolumeMounts = append(
329+
template.Spec.Containers[i].VolumeMounts,
330+
additionalVolumeMount)
331+
}
332+
}
333+
334+
for i := range template.Spec.InitContainers {
335+
if len(additionalVolume.Containers) == 0 ||
336+
slices.Contains(
337+
additionalVolume.Containers,
338+
template.Spec.InitContainers[i].Name) {
339+
template.Spec.InitContainers[i].VolumeMounts = append(
340+
template.Spec.InitContainers[i].VolumeMounts,
341+
additionalVolumeMount)
342+
}
343+
}
344+
345+
template.Spec.Volumes = append(
346+
template.Spec.Volumes,
347+
additionalVolumeSpec)
348+
}
349+
}

internal/controller/postgrescluster/volumes.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,3 +906,64 @@ func getPVCName(volumes []*corev1.PersistentVolumeClaim, selector labels.Selecto
906906
}
907907
return ""
908908
}
909+
910+
// +kubebuilder:rbac:groups="",resources="persistentvolumeclaims",verbs={get}
911+
// +kubebuilder:rbac:groups="",resources="persistentvolumeclaims",verbs={create,delete,patch}
912+
913+
// reconcileAdditionalVolumes writes the PersistentVolumeClaim for additional volumes.
914+
func (r *Reconciler) reconcileAdditionalVolumes(
915+
ctx context.Context,
916+
cluster *v1beta1.PostgresCluster,
917+
additionalVolumes []*v1beta1.AdditionalVolume,
918+
// instance *appsv1.StatefulSet,
919+
// observed *Instance,
920+
) (additionalVolumePVCs []*corev1.PersistentVolumeClaim, err error) {
921+
922+
if additionalVolumes == nil || len(additionalVolumes) == 0 {
923+
return
924+
}
925+
926+
for _, additionalVolume := range additionalVolumes {
927+
// If the user provides a PVC, we leave it alone here
928+
// and use it to mount the volume
929+
if additionalVolume.ClaimName != "" {
930+
continue
931+
}
932+
933+
// TODO: What labels do we want to add
934+
labelMap := map[string]string{
935+
naming.LabelCluster: cluster.Name,
936+
}
937+
938+
pvc := &corev1.PersistentVolumeClaim{ObjectMeta: naming.AdditionalVolume(cluster, additionalVolume)}
939+
940+
pvc.SetGroupVersionKind(corev1.SchemeGroupVersion.WithKind("PersistentVolumeClaim"))
941+
942+
err = errors.WithStack(r.setControllerReference(cluster, pvc))
943+
944+
// TODO: Do we have other labels/annotation sources we want to merge?
945+
pvc.Annotations = naming.Merge(
946+
cluster.Spec.Metadata.GetAnnotationsOrNil())
947+
948+
pvc.Labels = naming.Merge(
949+
cluster.Spec.Metadata.GetLabelsOrNil(),
950+
labelMap,
951+
)
952+
953+
pvc.Spec = additionalVolume.ClaimTemplate.AsPersistentVolumeClaimSpec()
954+
955+
if err == nil {
956+
err = r.handlePersistentVolumeClaimError(cluster,
957+
errors.WithStack(r.apply(ctx, pvc)))
958+
}
959+
960+
if err != nil {
961+
return nil, err
962+
}
963+
964+
additionalVolumePVCs = append(additionalVolumePVCs, pvc)
965+
}
966+
967+
return
968+
969+
}

internal/naming/names.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,21 @@ func InstancePostgresWALVolume(instance *appsv1.StatefulSet) metav1.ObjectMeta {
350350
}
351351
}
352352

353+
// AdditionalVolume returns the ObjectMeta for the additional
354+
// volume for instance.
355+
func AdditionalVolume(cluster *v1beta1.PostgresCluster,
356+
volume *v1beta1.AdditionalVolume) metav1.ObjectMeta {
357+
// TODO: What's the name for the PVC if not given?
358+
volumeName := volume.ClaimName
359+
if volumeName == "" {
360+
volumeName = cluster.GetName() + "-additional-something"
361+
}
362+
return metav1.ObjectMeta{
363+
Namespace: cluster.GetNamespace(),
364+
Name: volumeName,
365+
}
366+
}
367+
353368
// MonitoringUserSecret returns ObjectMeta necessary to lookup the Secret
354369
// containing authentication credentials for monitoring tools.
355370
func MonitoringUserSecret(cluster *v1beta1.PostgresCluster) metav1.ObjectMeta {

pkg/apis/postgres-operator.crunchydata.com/v1/postgrescluster_types.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,16 @@ type PostgresVolumesSpec struct {
534534
// ---
535535
// +optional
536536
Temp *v1beta1.VolumeClaimSpec `json:"temp,omitempty"`
537+
538+
// TODO: Update when v1beta1 is worked out
539+
// Additional volumes to add to the pod.
540+
// ---
541+
// +optional
542+
// +listType=map
543+
// +listMapKey=name
544+
// +kubebuilder:validation:MaxItems=10
545+
// // +kubebuilder:validation:items:XValidation:rule=`[has(self.claimName), has(self.claimTemplate)].filter(x, x == true).size() <= 1`,message=`can only have one of claimName, claimTemplate`
546+
Additional []*v1beta1.AdditionalVolume `json:"additional,omitempty"`
537547
}
538548

539549
type TablespaceVolume struct {

pkg/apis/postgres-operator.crunchydata.com/v1/zz_generated.deepcopy.go

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/apis/postgres-operator.crunchydata.com/v1beta1/postgrescluster_types.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,48 @@ type PostgresVolumesSpec struct {
531531
// ---
532532
// +optional
533533
Temp *VolumeClaimSpec `json:"temp,omitempty"`
534+
535+
// These CRD xvalidation rules were over the complexity budget
536+
// so I turned them off -- what's wrong here
537+
// Additional volumes to add to the pod.
538+
// ---
539+
// +optional
540+
// +listType=map
541+
// +listMapKey=name
542+
// +kubebuilder:validation:MaxItems=10
543+
// // +kubebuilder:validation:items:XValidation:rule=`[has(self.claimName), has(self.claimTemplate)].filter(x, x == true).size() <= 1`,message=`can only have one of claimName, claimTemplate`
544+
Additional []*AdditionalVolume `json:"additional,omitempty"`
545+
}
546+
547+
type AdditionalVolume struct {
548+
// The name of the volume used for mounting path.
549+
// Must be unique.
550+
// ---
551+
// +kubebuilder:validation:Required
552+
// // +kubebuilder:validation:XValidation:rule=`self == oldSelf`,message="immutable"
553+
Name string `json:"name,omitempty"`
554+
555+
// A reference to a preexisting PVC.
556+
// ---
557+
// +optional
558+
// // +kubebuilder:validation:XValidation:rule=`self == oldSelf`,message="immutable"
559+
ClaimName string `json:"claimName,omitempty"`
560+
561+
// A PVC request.
562+
// ---
563+
// +optional
564+
ClaimTemplate *VolumeClaimSpec `json:"claimTemplate,omitempty"`
565+
566+
// The containers to attach this volume to.
567+
// ---
568+
// +optional
569+
// +listType=set
570+
Containers []string `json:"containers,omitempty"`
571+
572+
// Sets the write/read mode of the volume
573+
// ---
574+
// +optional
575+
ReadOnly bool `json:"readOnly,omitempty"`
534576
}
535577

536578
type TablespaceVolume struct {

pkg/apis/postgres-operator.crunchydata.com/v1beta1/zz_generated.deepcopy.go

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)