Support readOnlyRootFilesystem for SolrCloud pods (#648)
Add /tmp as emptyDir to zk-init and make it readOnlyRootFilesystem
diff --git a/controllers/solrcloud_controller_backup_test.go b/controllers/solrcloud_controller_backup_test.go
index 566b7c7..a0be8d5 100644
--- a/controllers/solrcloud_controller_backup_test.go
+++ b/controllers/solrcloud_controller_backup_test.go
@@ -119,9 +119,9 @@
extraVolumes[0].DefaultContainerMount.Name = extraVolumes[0].Name
Expect(statefulSet.Spec.Template.Spec.Containers[0].VolumeMounts).To(HaveLen(len(extraVolumes)+1), "Container has wrong number of volumeMounts")
Expect(statefulSet.Spec.Template.Spec.Containers[0].VolumeMounts[1]).To(Equal(*extraVolumes[0].DefaultContainerMount), "Additional Volume from podOptions not mounted into container properly.")
- Expect(statefulSet.Spec.Template.Spec.Volumes).To(HaveLen(len(extraVolumes)+2), "Pod has wrong number of volumes")
- Expect(statefulSet.Spec.Template.Spec.Volumes[2].Name).To(Equal(extraVolumes[0].Name), "Additional Volume from podOptions not loaded into pod properly.")
- Expect(statefulSet.Spec.Template.Spec.Volumes[2].VolumeSource).To(Equal(extraVolumes[0].Source), "Additional Volume from podOptions not loaded into pod properly.")
+ Expect(statefulSet.Spec.Template.Spec.Volumes).To(HaveLen(len(extraVolumes)+3), "Pod has wrong number of volumes")
+ Expect(statefulSet.Spec.Template.Spec.Volumes[3].Name).To(Equal(extraVolumes[0].Name), "Additional Volume from podOptions not loaded into pod properly.")
+ Expect(statefulSet.Spec.Template.Spec.Volumes[3].VolumeSource).To(Equal(extraVolumes[0].Source), "Additional Volume from podOptions not loaded into pod properly.")
By("adding credentials to the S3 repository (envVars)")
s3Credentials := &solrv1beta1.S3Credentials{
@@ -183,9 +183,9 @@
extraVolumes[0].DefaultContainerMount.Name = extraVolumes[0].Name
g.Expect(found.Spec.Template.Spec.Containers[0].VolumeMounts).To(HaveLen(len(extraVolumes)+1), "Container has wrong number of volumeMounts")
g.Expect(found.Spec.Template.Spec.Containers[0].VolumeMounts[1]).To(Equal(*extraVolumes[0].DefaultContainerMount), "Additional Volume from podOptions not mounted into container properly.")
- g.Expect(found.Spec.Template.Spec.Volumes).To(HaveLen(len(extraVolumes)+2), "Pod has wrong number of volumes")
- g.Expect(found.Spec.Template.Spec.Volumes[2].Name).To(Equal(extraVolumes[0].Name), "Additional Volume from podOptions not loaded into pod properly.")
- g.Expect(found.Spec.Template.Spec.Volumes[2].VolumeSource).To(Equal(extraVolumes[0].Source), "Additional Volume from podOptions not loaded into pod properly.")
+ g.Expect(found.Spec.Template.Spec.Volumes).To(HaveLen(len(extraVolumes)+3), "Pod has wrong number of volumes")
+ g.Expect(found.Spec.Template.Spec.Volumes[3].Name).To(Equal(extraVolumes[0].Name), "Additional Volume from podOptions not loaded into pod properly.")
+ g.Expect(found.Spec.Template.Spec.Volumes[3].VolumeSource).To(Equal(extraVolumes[0].Source), "Additional Volume from podOptions not loaded into pod properly.")
})
By("adding credentials to the S3 repository (envVars & credentials file)")
@@ -245,15 +245,15 @@
g.Expect(found.Spec.Template.Spec.Containers[0].VolumeMounts[1].MountPath).To(Equal("/var/solr/data/backup-restore/test-repo/s3credential"), "S3Credentials file volumeMount has wrong mount path.")
g.Expect(found.Spec.Template.Spec.Containers[0].VolumeMounts[1].ReadOnly).To(BeTrue(), "S3Credentials file volumeMount must be read-only.")
g.Expect(found.Spec.Template.Spec.Containers[0].VolumeMounts[2]).To(Equal(*extraVolumes[0].DefaultContainerMount), "Additional Volume from podOptions not mounted into container properly.")
- g.Expect(found.Spec.Template.Spec.Volumes).To(HaveLen(len(extraVolumes)+3), "Pod has wrong number of volumes")
- g.Expect(found.Spec.Template.Spec.Volumes[2].Name).To(Equal("backup-repository-test-repo"), "S3Credentials file volume has wrong name.")
- g.Expect(found.Spec.Template.Spec.Volumes[2].VolumeSource.Secret).To(Not(BeNil()), "S3Credentials file has to be loaded via a secret volume.")
- g.Expect(found.Spec.Template.Spec.Volumes[2].VolumeSource.Secret.SecretName).To(Equal(s3Credentials.CredentialsFileSecret.Name), "S3Credentials file is loaded into the pod using the wrong secret name.")
- g.Expect(found.Spec.Template.Spec.Volumes[2].VolumeSource.Secret.Items).To(Equal(
+ g.Expect(found.Spec.Template.Spec.Volumes).To(HaveLen(len(extraVolumes)+4), "Pod has wrong number of volumes")
+ g.Expect(found.Spec.Template.Spec.Volumes[3].Name).To(Equal("backup-repository-test-repo"), "S3Credentials file volume has wrong name.")
+ g.Expect(found.Spec.Template.Spec.Volumes[3].VolumeSource.Secret).To(Not(BeNil()), "S3Credentials file has to be loaded via a secret volume.")
+ g.Expect(found.Spec.Template.Spec.Volumes[3].VolumeSource.Secret.SecretName).To(Equal(s3Credentials.CredentialsFileSecret.Name), "S3Credentials file is loaded into the pod using the wrong secret name.")
+ g.Expect(found.Spec.Template.Spec.Volumes[3].VolumeSource.Secret.Items).To(Equal(
[]corev1.KeyToPath{{Key: s3Credentials.CredentialsFileSecret.Key, Path: util.S3CredentialFileName}}), "S3Credentials file pod volume has the wrong items.")
- g.Expect(found.Spec.Template.Spec.Volumes[2].VolumeSource.Secret.DefaultMode).To(BeEquivalentTo(&util.SecretReadOnlyPermissions), "S3Credentials file pod volume has the wrong default mode.")
- g.Expect(found.Spec.Template.Spec.Volumes[3].Name).To(Equal(extraVolumes[0].Name), "Additional Volume from podOptions not loaded into pod properly.")
- g.Expect(found.Spec.Template.Spec.Volumes[3].VolumeSource).To(Equal(extraVolumes[0].Source), "Additional Volume from podOptions not loaded into pod properly.")
+ g.Expect(found.Spec.Template.Spec.Volumes[3].VolumeSource.Secret.DefaultMode).To(BeEquivalentTo(&util.SecretReadOnlyPermissions), "S3Credentials file pod volume has the wrong default mode.")
+ g.Expect(found.Spec.Template.Spec.Volumes[4].Name).To(Equal(extraVolumes[0].Name), "Additional Volume from podOptions not loaded into pod properly.")
+ g.Expect(found.Spec.Template.Spec.Volumes[4].VolumeSource).To(Equal(extraVolumes[0].Source), "Additional Volume from podOptions not loaded into pod properly.")
})
By("adding extra options to the S3 repository")
diff --git a/controllers/solrcloud_controller_storage_test.go b/controllers/solrcloud_controller_storage_test.go
index d4664fa..d73c850 100644
--- a/controllers/solrcloud_controller_storage_test.go
+++ b/controllers/solrcloud_controller_storage_test.go
@@ -97,7 +97,7 @@
By("testing the Solr StatefulSet PVC Spec")
expectStatefulSetWithChecks(ctx, solrCloud, solrCloud.StatefulSetName(), func(g Gomega, found *appsv1.StatefulSet) {
- g.Expect(found.Spec.Template.Spec.Volumes).To(HaveLen(2), "Pod has wrong number of volumes")
+ g.Expect(found.Spec.Template.Spec.Volumes).To(HaveLen(3), "Pod has wrong number of volumes")
g.Expect(found.Spec.VolumeClaimTemplates[0].Name).To(Equal(solrCloud.Spec.StorageOptions.PersistentStorage.PersistentVolumeClaimTemplate.ObjectMeta.Name), "Data volume claim doesn't exist")
g.Expect(found.Spec.VolumeClaimTemplates[0].Labels[util.SolrPVCTechnologyLabel]).To(Equal("solr-cloud"), "PVC Technology label doesn't match")
g.Expect(found.Spec.VolumeClaimTemplates[0].Labels[util.SolrPVCStorageLabel]).To(Equal("data"), "PVC Storage label doesn't match")
@@ -134,7 +134,7 @@
By("testing the Solr StatefulSet PVC Spec")
expectStatefulSetWithChecks(ctx, solrCloud, solrCloud.StatefulSetName(), func(g Gomega, found *appsv1.StatefulSet) {
- g.Expect(found.Spec.Template.Spec.Volumes).To(HaveLen(2), "Pod has wrong number of volumes")
+ g.Expect(found.Spec.Template.Spec.Volumes).To(HaveLen(3), "Pod has wrong number of volumes")
g.Expect(found.Spec.VolumeClaimTemplates[0].Name).To(Equal(solrCloud.Spec.StorageOptions.PersistentStorage.PersistentVolumeClaimTemplate.ObjectMeta.Name), "Data volume claim doesn't exist")
g.Expect(found.Spec.VolumeClaimTemplates[0].Labels[util.SolrPVCTechnologyLabel]).To(Equal("solr-cloud"), "PVC Technology label doesn't match")
g.Expect(found.Spec.VolumeClaimTemplates[0].Labels[util.SolrPVCStorageLabel]).To(Equal("data"), "PVC Storage label doesn't match")
@@ -169,9 +169,9 @@
By("testing the Solr StatefulSet Spec")
expectStatefulSetWithChecks(ctx, solrCloud, solrCloud.StatefulSetName(), func(g Gomega, found *appsv1.StatefulSet) {
- g.Expect(found.Spec.Template.Spec.Volumes).To(HaveLen(3), "Pod has wrong number of volumes")
+ g.Expect(found.Spec.Template.Spec.Volumes).To(HaveLen(4), "Pod has wrong number of volumes")
g.Expect(found.Spec.VolumeClaimTemplates).To(HaveLen(0), "No data volume claims should exist when using ephemeral storage")
- dataVolume := found.Spec.Template.Spec.Volumes[1]
+ dataVolume := found.Spec.Template.Spec.Volumes[2]
g.Expect(dataVolume.EmptyDir).To(Not(BeNil()), "The data volume should be an empty-dir.")
g.Expect(dataVolume.HostPath).To(BeNil(), "The data volume should not be a hostPath volume.")
g.Expect(found.Spec.Template.Spec.Containers[0].VolumeMounts[0].Name).To(Equal(dataVolume.Name), "Ephemeral Data volume name not used in volume mount")
@@ -198,9 +198,9 @@
By("testing the Solr StatefulSet Spec")
expectStatefulSetWithChecks(ctx, solrCloud, solrCloud.StatefulSetName(), func(g Gomega, found *appsv1.StatefulSet) {
- g.Expect(found.Spec.Template.Spec.Volumes).To(HaveLen(3), "Pod has wrong number of volumes")
+ g.Expect(found.Spec.Template.Spec.Volumes).To(HaveLen(4), "Pod has wrong number of volumes")
g.Expect(found.Spec.VolumeClaimTemplates).To(HaveLen(0), "No data volume claims should exist when using ephemeral storage")
- dataVolume := found.Spec.Template.Spec.Volumes[1]
+ dataVolume := found.Spec.Template.Spec.Volumes[2]
g.Expect(dataVolume.EmptyDir).To(Not(BeNil()), "The data volume should be an empty-dir.")
g.Expect(dataVolume.HostPath).To(BeNil(), "The data volume should not be a hostPath volume.")
g.Expect(found.Spec.Template.Spec.Containers[0].VolumeMounts[0].Name).To(Equal(dataVolume.Name), "Ephemeral Data volume name not used in volume mount")
@@ -230,9 +230,9 @@
By("testing the Solr StatefulSet Spec")
expectStatefulSetWithChecks(ctx, solrCloud, solrCloud.StatefulSetName(), func(g Gomega, found *appsv1.StatefulSet) {
- g.Expect(found.Spec.Template.Spec.Volumes).To(HaveLen(3), "Pod has wrong number of volumes")
+ g.Expect(found.Spec.Template.Spec.Volumes).To(HaveLen(4), "Pod has wrong number of volumes")
g.Expect(found.Spec.VolumeClaimTemplates).To(HaveLen(0), "No data volume claims should exist when using ephemeral storage")
- dataVolume := found.Spec.Template.Spec.Volumes[1]
+ dataVolume := found.Spec.Template.Spec.Volumes[2]
g.Expect(dataVolume.EmptyDir).To(Not(BeNil()), "The data volume should be an empty-dir.")
g.Expect(dataVolume.HostPath).To(BeNil(), "The data volume should not be a hostPath volume.")
g.Expect(dataVolume.EmptyDir).To(Equal(solrCloud.Spec.StorageOptions.EphemeralStorage.EmptyDir), "The empty dir settings do not match with what was provided.")
@@ -264,9 +264,9 @@
By("testing the Solr StatefulSet Spec")
expectStatefulSetWithChecks(ctx, solrCloud, solrCloud.StatefulSetName(), func(g Gomega, found *appsv1.StatefulSet) {
- g.Expect(found.Spec.Template.Spec.Volumes).To(HaveLen(3), "Pod has wrong number of volumes")
+ g.Expect(found.Spec.Template.Spec.Volumes).To(HaveLen(4), "Pod has wrong number of volumes")
g.Expect(found.Spec.VolumeClaimTemplates).To(HaveLen(0), "No data volume claims should exist when using ephemeral storage")
- dataVolume := found.Spec.Template.Spec.Volumes[1]
+ dataVolume := found.Spec.Template.Spec.Volumes[2]
g.Expect(dataVolume.EmptyDir).To(BeNil(), "The data volume should not be an empty-dir.")
g.Expect(dataVolume.HostPath).To(Not(BeNil()), "The data volume should be a hostPath volume.")
g.Expect(dataVolume.HostPath).To(Equal(solrCloud.Spec.StorageOptions.EphemeralStorage.HostPath), "The hostPath settings do not match with what was provided.")
@@ -302,9 +302,9 @@
By("testing the Solr StatefulSet Spec")
expectStatefulSetWithChecks(ctx, solrCloud, solrCloud.StatefulSetName(), func(g Gomega, found *appsv1.StatefulSet) {
- g.Expect(found.Spec.Template.Spec.Volumes).To(HaveLen(3), "Pod has wrong number of volumes")
+ g.Expect(found.Spec.Template.Spec.Volumes).To(HaveLen(4), "Pod has wrong number of volumes")
g.Expect(found.Spec.VolumeClaimTemplates).To(HaveLen(0), "No data volume claims should exist when using ephemeral storage")
- dataVolume := found.Spec.Template.Spec.Volumes[1]
+ dataVolume := found.Spec.Template.Spec.Volumes[2]
g.Expect(dataVolume.EmptyDir).To(BeNil(), "The data volume should not be an empty-dir.")
g.Expect(dataVolume.HostPath).To(Not(BeNil()), "The data volume should be a hostPath volume.")
g.Expect(dataVolume.HostPath).To(Equal(solrCloud.Spec.StorageOptions.EphemeralStorage.HostPath), "The hostPath settings do not match with what was provided.")
diff --git a/controllers/solrcloud_controller_test.go b/controllers/solrcloud_controller_test.go
index 8d81397..de590e1 100644
--- a/controllers/solrcloud_controller_test.go
+++ b/controllers/solrcloud_controller_test.go
@@ -143,9 +143,9 @@
extraVolumes[0].DefaultContainerMount.Name = extraVolumes[0].Name
Expect(statefulSet.Spec.Template.Spec.Containers[0].VolumeMounts).To(HaveLen(len(extraVolumes)+1), "Container has wrong number of volumeMounts")
Expect(statefulSet.Spec.Template.Spec.Containers[0].VolumeMounts[1]).To(Equal(*extraVolumes[0].DefaultContainerMount), "Additional Volume from podOptions not mounted into container properly.")
- Expect(statefulSet.Spec.Template.Spec.Volumes).To(HaveLen(len(extraVolumes)+2), "Pod has wrong number of volumes")
- Expect(statefulSet.Spec.Template.Spec.Volumes[2].Name).To(Equal(extraVolumes[0].Name), "Additional Volume from podOptions not loaded into pod properly.")
- Expect(statefulSet.Spec.Template.Spec.Volumes[2].VolumeSource).To(Equal(extraVolumes[0].Source), "Additional Volume from podOptions not loaded into pod properly.")
+ Expect(statefulSet.Spec.Template.Spec.Volumes).To(HaveLen(len(extraVolumes)+3), "Pod has wrong number of volumes")
+ Expect(statefulSet.Spec.Template.Spec.Volumes[3].Name).To(Equal(extraVolumes[0].Name), "Additional Volume from podOptions not loaded into pod properly.")
+ Expect(statefulSet.Spec.Template.Spec.Volumes[3].VolumeSource).To(Equal(extraVolumes[0].Source), "Additional Volume from podOptions not loaded into pod properly.")
Expect(statefulSet.Spec.Template.Spec.ReadinessGates).To(ContainElement(corev1.PodReadinessGate{ConditionType: util.SolrIsNotStoppedReadinessCondition}), "All pods should contain the isNotStopped readinessGate.")
By("testing the Solr Common Service")
diff --git a/controllers/util/solr_util.go b/controllers/util/solr_util.go
index 0c7f098..47f8c07 100644
--- a/controllers/util/solr_util.go
+++ b/controllers/util/solr_util.go
@@ -27,6 +27,7 @@
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/utils/pointer"
+ "k8s.io/utils/ptr"
"sort"
"strconv"
"strings"
@@ -153,6 +154,12 @@
},
},
},
+ {
+ Name: "tmp",
+ VolumeSource: corev1.VolumeSource{
+ EmptyDir: &corev1.EmptyDirVolumeSource{},
+ },
+ },
}
solrDataVolumeName := solrCloud.DataVolumeName()
@@ -1247,6 +1254,12 @@
corev1.ResourceMemory: *DefaultSolrZKPrepInitContainerMemory,
}
if cmd != "" {
+ volumeMounts := []corev1.VolumeMount{
+ {
+ Name: "tmp",
+ MountPath: "/tmp",
+ },
+ }
return true, corev1.Container{
Name: "setup-zk",
Image: solrCloud.Spec.SolrImage.ToImageName(),
@@ -1259,6 +1272,10 @@
Requests: zkSetupResources,
Limits: zkSetupResources,
},
+ SecurityContext: &corev1.SecurityContext{
+ ReadOnlyRootFilesystem: ptr.To(true),
+ },
+ VolumeMounts: volumeMounts,
}
}
diff --git a/go.mod b/go.mod
index 17747b4..1605800 100644
--- a/go.mod
+++ b/go.mod
@@ -6,7 +6,7 @@
github.com/cert-manager/cert-manager v1.13.0
github.com/fsnotify/fsnotify v1.6.0
github.com/go-logr/logr v1.2.4
- github.com/onsi/ginkgo/v2 v2.12.1
+ github.com/onsi/ginkgo/v2 v2.13.0
github.com/onsi/gomega v1.27.10
github.com/pravega/zookeeper-operator v0.2.15
github.com/robfig/cron/v3 v3.0.1
diff --git a/go.sum b/go.sum
index 4cb9ef3..6747978 100644
--- a/go.sum
+++ b/go.sum
@@ -478,8 +478,8 @@
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
-github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA=
-github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
+github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4=
+github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
diff --git a/helm/solr-operator/Chart.yaml b/helm/solr-operator/Chart.yaml
index a507836..765525f 100644
--- a/helm/solr-operator/Chart.yaml
+++ b/helm/solr-operator/Chart.yaml
@@ -54,16 +54,13 @@
# Add change log for a single release here.
# Allowed syntax is described at: https://artifacthub.io/docs/topics/annotations/helm/#example
artifacthub.io/changes: |
- - kind: added
- description: Addition 1
+ - kind: changed
+ description: SolrClouds now support auto-readOnlyRootFilesystem setting.
links:
- name: Github Issue
- url: https://github.com/issue-url
- - kind: changed
- description: Change 2
- links:
+ url: https://github.com/apache/solr-operator/issues/624
- name: Github PR
- url: https://github.com/pr-url
+ url: https://github.com/apache/solr-operator/pull/648
artifacthub.io/images: |
- name: solr-operator
image: apache/solr-operator:v0.9.0-prerelease