feat: Add SubPathExpr option for additionalVolumes (#2463)

This commit is contained in:
Samuel Mutel 2024-05-24 11:55:22 +02:00 committed by GitHub
parent 1839baaad3
commit 7bcb73a402
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 78 additions and 7 deletions

View File

@ -101,6 +101,8 @@ spec:
x-kubernetes-preserve-unknown-fields: true x-kubernetes-preserve-unknown-fields: true
subPath: subPath:
type: string type: string
isSubPathExpr:
type: boolean
allowedSourceRanges: allowedSourceRanges:
type: array type: array
nullable: true nullable: true

View File

@ -242,6 +242,7 @@ These parameters are grouped directly under the `spec` key in the manifest.
It allows you to mount existing PersistentVolumeClaims, ConfigMaps and Secrets inside the StatefulSet. It allows you to mount existing PersistentVolumeClaims, ConfigMaps and Secrets inside the StatefulSet.
Also an `emptyDir` volume can be shared between initContainer and statefulSet. Also an `emptyDir` volume can be shared between initContainer and statefulSet.
Additionaly, you can provide a `SubPath` for volume mount (a file in a configMap source volume, for example). Additionaly, you can provide a `SubPath` for volume mount (a file in a configMap source volume, for example).
Set `isSubPathExpr` to true if you want to include [API environment variables](https://kubernetes.io/docs/concepts/storage/volumes/#using-subpath-expanded-environment).
You can also specify in which container the additional Volumes will be mounted with the `targetContainers` array option. You can also specify in which container the additional Volumes will be mounted with the `targetContainers` array option.
If `targetContainers` is empty, additional volumes will be mounted only in the `postgres` container. If `targetContainers` is empty, additional volumes will be mounted only in the `postgres` container.
If you set the `all` special item, it will be mounted in all containers (postgres + sidecars). If you set the `all` special item, it will be mounted in all containers (postgres + sidecars).

View File

@ -83,6 +83,16 @@ spec:
# PersistentVolumeClaim: # PersistentVolumeClaim:
# claimName: pvc-postgresql-data-partitions # claimName: pvc-postgresql-data-partitions
# readyOnly: false # readyOnly: false
# - name: data
# mountPath: /home/postgres/pgdata/partitions
# subPath: $(NODE_NAME)/$(POD_NAME)
# isSubPathExpr: true
# targetContainers:
# - postgres
# volumeSource:
# PersistentVolumeClaim:
# claimName: pvc-postgresql-data-partitions
# readyOnly: false
# - name: conf # - name: conf
# mountPath: /etc/telegraf # mountPath: /etc/telegraf
# subPath: telegraf.conf # subPath: telegraf.conf

View File

@ -99,6 +99,8 @@ spec:
x-kubernetes-preserve-unknown-fields: true x-kubernetes-preserve-unknown-fields: true
subPath: subPath:
type: string type: string
isSubPathExpr:
type: boolean
allowedSourceRanges: allowedSourceRanges:
type: array type: array
nullable: true nullable: true

View File

@ -168,6 +168,9 @@ var PostgresCRDResourceValidation = apiextv1.CustomResourceValidation{
"subPath": { "subPath": {
Type: "string", Type: "string",
}, },
"isSubPathExpr": {
Type: "boolean",
},
}, },
}, },
}, },

View File

@ -143,6 +143,7 @@ type AdditionalVolume struct {
Name string `json:"name"` Name string `json:"name"`
MountPath string `json:"mountPath"` MountPath string `json:"mountPath"`
SubPath string `json:"subPath,omitempty"` SubPath string `json:"subPath,omitempty"`
IsSubPathExpr bool `json:"isSubPathExpr,omitemtpy"`
TargetContainers []string `json:"targetContainers"` TargetContainers []string `json:"targetContainers"`
VolumeSource v1.VolumeSource `json:"volumeSource"` VolumeSource v1.VolumeSource `json:"volumeSource"`
} }

View File

@ -1820,11 +1820,18 @@ func (c *Cluster) addAdditionalVolumes(podSpec *v1.PodSpec,
for _, additionalVolume := range additionalVolumes { for _, additionalVolume := range additionalVolumes {
for _, target := range additionalVolume.TargetContainers { for _, target := range additionalVolume.TargetContainers {
if podSpec.Containers[i].Name == target || target == "all" { if podSpec.Containers[i].Name == target || target == "all" {
mounts = append(mounts, v1.VolumeMount{ v := v1.VolumeMount{
Name: additionalVolume.Name, Name: additionalVolume.Name,
MountPath: additionalVolume.MountPath, MountPath: additionalVolume.MountPath,
SubPath: additionalVolume.SubPath, }
})
if additionalVolume.IsSubPathExpr {
v.SubPathExpr = additionalVolume.SubPath
} else {
v.SubPath = additionalVolume.SubPath
}
mounts = append(mounts, v)
} }
} }
} }

View File

@ -1889,6 +1889,25 @@ func TestAdditionalVolume(t *testing.T) {
EmptyDir: &v1.EmptyDirVolumeSource{}, EmptyDir: &v1.EmptyDirVolumeSource{},
}, },
}, },
{
Name: "test5",
MountPath: "/test5",
SubPath: "subpath",
TargetContainers: nil, // should mount only to postgres
VolumeSource: v1.VolumeSource{
EmptyDir: &v1.EmptyDirVolumeSource{},
},
},
{
Name: "test6",
MountPath: "/test6",
SubPath: "$(POD_NAME)",
IsSubPathExpr: true,
TargetContainers: nil, // should mount only to postgres
VolumeSource: v1.VolumeSource{
EmptyDir: &v1.EmptyDirVolumeSource{},
},
},
} }
pg := acidv1.Postgresql{ pg := acidv1.Postgresql{
@ -1938,6 +1957,7 @@ func TestAdditionalVolume(t *testing.T) {
subTest string subTest string
container string container string
expectedMounts []string expectedMounts []string
expectedSubPath []string
}{ }{
{ {
subTest: "checking volume mounts of postgres container", subTest: "checking volume mounts of postgres container",
@ -1949,6 +1969,17 @@ func TestAdditionalVolume(t *testing.T) {
container: "sidecar", container: "sidecar",
expectedMounts: []string{"pgdata", "test1", "test2"}, expectedMounts: []string{"pgdata", "test1", "test2"},
}, },
{
subTest: "checking volume mounts with subPath",
container: constants.PostgresContainerName,
expectedMounts: []string{"test5"},
expectedSubPath: []string{"subpath"},
},
{
subTest: "checking volume mounts with subPathExpr",
container: constants.PostgresContainerName,
expectedMounts: []string{"test6"},
},
} }
for _, tt := range tests { for _, tt := range tests {
@ -1957,12 +1988,26 @@ func TestAdditionalVolume(t *testing.T) {
continue continue
} }
mounts := []string{} mounts := []string{}
subPaths := []string{}
subPathExprs := []string{}
for _, volumeMounts := range container.VolumeMounts { for _, volumeMounts := range container.VolumeMounts {
mounts = append(mounts, volumeMounts.Name) mounts = append(mounts, volumeMounts.Name)
subPaths = append(subPaths, volumeMounts.SubPath)
subPathExprs = append(subPathExprs, volumeMounts.SubPathExpr)
} }
if !util.IsEqualIgnoreOrder(mounts, tt.expectedMounts) { if !util.IsEqualIgnoreOrder(mounts, tt.expectedMounts) {
t.Errorf("%s %s: different volume mounts: got %v, epxected %v", t.Errorf("%s %s: different volume mounts: got %v, expected %v",
t.Name(), tt.subTest, mounts, tt.expectedMounts)
}
if !util.IsEqualIgnoreOrder(subPaths, tt.expectedSubPath) {
t.Errorf("%s %s: different volume subPaths: got %v, expected %v",
t.Name(), tt.subTest, mounts, tt.expectedSubPath)
}
if !util.IsEqualIgnoreOrder(subPathExprs, []string{container.Name}) {
t.Errorf("%s %s: different volume subPathExprs: got %v, expected %v",
t.Name(), tt.subTest, mounts, tt.expectedMounts) t.Name(), tt.subTest, mounts, tt.expectedMounts)
} }
} }