mirror of
https://github.com/zalando/postgres-operator.git
synced 2026-10-17 23:58:40 +02:00
feat: Add SubPathExpr option for additionalVolumes (#2463)
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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).
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -168,6 +168,9 @@ var PostgresCRDResourceValidation = apiextv1.CustomResourceValidation{
|
|||||||
"subPath": {
|
"subPath": {
|
||||||
Type: "string",
|
Type: "string",
|
||||||
},
|
},
|
||||||
|
"isSubPathExpr": {
|
||||||
|
Type: "boolean",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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"`
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-3
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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{
|
||||||
@@ -1935,9 +1954,10 @@ func TestAdditionalVolume(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user