Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SubPathExpr option for additionalVolumes #2463

Merged
merged 1 commit into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions charts/postgres-operator/crds/postgresqls.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ spec:
x-kubernetes-preserve-unknown-fields: true
subPath:
type: string
isSubPathExpr:
type: boolean
allowedSourceRanges:
type: array
nullable: true
Expand Down
1 change: 1 addition & 0 deletions docs/reference/cluster_manifest.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,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.
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).
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.
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).
Expand Down
10 changes: 10 additions & 0 deletions manifests/complete-postgres-manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ spec:
# PersistentVolumeClaim:
# claimName: pvc-postgresql-data-partitions
# 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
# mountPath: /etc/telegraf
# subPath: telegraf.conf
Expand Down
2 changes: 2 additions & 0 deletions manifests/postgresql.crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ spec:
x-kubernetes-preserve-unknown-fields: true
subPath:
type: string
isSubPathExpr:
type: boolean
allowedSourceRanges:
type: array
nullable: true
Expand Down
3 changes: 3 additions & 0 deletions pkg/apis/acid.zalan.do/v1/crds.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ var PostgresCRDResourceValidation = apiextv1.CustomResourceValidation{
"subPath": {
Type: "string",
},
"isSubPathExpr": {
Type: "boolean",
},
smutel marked this conversation as resolved.
Show resolved Hide resolved
},
},
},
Expand Down
1 change: 1 addition & 0 deletions pkg/apis/acid.zalan.do/v1/postgresql_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ type AdditionalVolume struct {
Name string `json:"name"`
MountPath string `json:"mountPath"`
SubPath string `json:"subPath,omitempty"`
IsSubPathExpr bool `json:"isSubPathExpr,omitemtpy"`
TargetContainers []string `json:"targetContainers"`
VolumeSource v1.VolumeSource `json:"volumeSource"`
}
Expand Down
13 changes: 10 additions & 3 deletions pkg/cluster/k8sres.go
Original file line number Diff line number Diff line change
Expand Up @@ -1751,11 +1751,18 @@ func (c *Cluster) addAdditionalVolumes(podSpec *v1.PodSpec,
for _, additionalVolume := range additionalVolumes {
for _, target := range additionalVolume.TargetContainers {
if podSpec.Containers[i].Name == target || target == "all" {
mounts = append(mounts, v1.VolumeMount{
v := v1.VolumeMount{
Name: additionalVolume.Name,
MountPath: additionalVolume.MountPath,
SubPath: additionalVolume.SubPath,
})
}

if additionalVolume.IsSubPathExpr {
v.SubPathExpr = additionalVolume.SubPath
} else {
v.SubPath = additionalVolume.SubPath
}

mounts = append(mounts, v)
}
}
}
Expand Down
53 changes: 49 additions & 4 deletions pkg/cluster/k8sres_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1812,6 +1812,25 @@ func TestAdditionalVolume(t *testing.T) {
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{
Expand Down Expand Up @@ -1858,9 +1877,10 @@ func TestAdditionalVolume(t *testing.T) {
assert.NoError(t, err)

tests := []struct {
subTest string
container string
expectedMounts []string
subTest string
container string
expectedMounts []string
expectedSubPath []string
}{
{
subTest: "checking volume mounts of postgres container",
Expand All @@ -1872,6 +1892,17 @@ func TestAdditionalVolume(t *testing.T) {
container: "sidecar",
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 {
Expand All @@ -1880,12 +1911,26 @@ func TestAdditionalVolume(t *testing.T) {
continue
}
mounts := []string{}
subPaths := []string{}
subPathExprs := []string{}
for _, volumeMounts := range container.VolumeMounts {
mounts = append(mounts, volumeMounts.Name)
subPaths = append(subPaths, volumeMounts.SubPath)
subPathExprs = append(subPathExprs, volumeMounts.SubPathExpr)
}

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)
}
}
Expand Down