diff --git a/controllers/solrcloud_controller.go b/controllers/solrcloud_controller.go index 6bd81e8d..4a0338c1 100644 --- a/controllers/solrcloud_controller.go +++ b/controllers/solrcloud_controller.go @@ -225,9 +225,9 @@ func (r *SolrCloudReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( if hasSolrXml { // make sure the user-provided solr.xml is valid - if !strings.Contains(solrXml, "${hostPort:") { + if !(strings.Contains(solrXml, "${solr.port.advertise:") || strings.Contains(solrXml, "${hostPort:")) { return requeueOrNot, - fmt.Errorf("custom solr.xml in ConfigMap %s must contain a placeholder for the 'hostPort' variable, such as ${hostPort:80}", + fmt.Errorf("custom solr.xml in ConfigMap %s must contain a placeholder for either 'solr.port.advertise', or its deprecated alternative 'hostPort', e.g. ${solr.port.advertise:80}", providedConfigMapName) } // stored in the pod spec annotations on the statefulset so that we get a restart when solr.xml changes diff --git a/controllers/solrcloud_controller_backup_test.go b/controllers/solrcloud_controller_backup_test.go index 0e8cafda..566b7c7e 100644 --- a/controllers/solrcloud_controller_backup_test.go +++ b/controllers/solrcloud_controller_backup_test.go @@ -102,11 +102,12 @@ var _ = FDescribe("SolrCloud controller - Backup Repositories", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace, - "SOLR_PORT": "8983", - "SOLR_NODE_PORT": "8983", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", + "ZK_HOST": "host:7271/", + "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace, + "SOLR_PORT": "8983", + "SOLR_NODE_PORT": "8983", + "SOLR_PORT_ADVERTISE": "8983", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", } foundEnv := statefulSet.Spec.Template.Spec.Containers[0].Env @@ -150,12 +151,13 @@ var _ = FDescribe("SolrCloud controller - Backup Repositories", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": "$(POD_NAME)." + foundSolrCloud.HeadlessServiceName() + "." + foundSolrCloud.Namespace, - "SOLR_PORT": "8983", - "SOLR_NODE_PORT": "8983", - "SOLR_LOG_LEVEL": "INFO", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", + "ZK_HOST": "host:7271/", + "SOLR_HOST": "$(POD_NAME)." + foundSolrCloud.HeadlessServiceName() + "." + foundSolrCloud.Namespace, + "SOLR_PORT": "8983", + "SOLR_NODE_PORT": "8983", + "SOLR_PORT_ADVERTISE": "8983", + "SOLR_LOG_LEVEL": "INFO", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", } foundEnv := found.Spec.Template.Spec.Containers[0].Env @@ -204,12 +206,13 @@ var _ = FDescribe("SolrCloud controller - Backup Repositories", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": "$(POD_NAME)." + foundSolrCloud.HeadlessServiceName() + "." + foundSolrCloud.Namespace, - "SOLR_PORT": "8983", - "SOLR_NODE_PORT": "8983", - "SOLR_LOG_LEVEL": "INFO", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", + "ZK_HOST": "host:7271/", + "SOLR_HOST": "$(POD_NAME)." + foundSolrCloud.HeadlessServiceName() + "." + foundSolrCloud.Namespace, + "SOLR_PORT": "8983", + "SOLR_NODE_PORT": "8983", + "SOLR_PORT_ADVERTISE": "8983", + "SOLR_LOG_LEVEL": "INFO", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", } foundEnv := found.Spec.Template.Spec.Containers[0].Env diff --git a/controllers/solrcloud_controller_externaldns_test.go b/controllers/solrcloud_controller_externaldns_test.go index b63a1ffc..92d7e7ea 100644 --- a/controllers/solrcloud_controller_externaldns_test.go +++ b/controllers/solrcloud_controller_externaldns_test.go @@ -97,11 +97,12 @@ var _ = FDescribe("SolrCloud controller - External DNS", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": "$(POD_NAME)." + solrCloud.Namespace + "." + testDomain, - "SOLR_PORT": "3000", - "SOLR_NODE_PORT": "3000", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", + "ZK_HOST": "host:7271/", + "SOLR_HOST": "$(POD_NAME)." + solrCloud.Namespace + "." + testDomain, + "SOLR_PORT": "3000", + "SOLR_NODE_PORT": "3000", + "SOLR_PORT_ADVERTISE": "3000", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", } testPodEnvVariables(expectedEnvVars, statefulSet.Spec.Template.Spec.Containers[0].Env) Expect(statefulSet.Spec.Template.Spec.Containers[0].Lifecycle.PreStop.Exec.Command).To(Equal([]string{"solr", "stop", "-p", "3000"}), "Incorrect pre-stop command") @@ -177,11 +178,12 @@ var _ = FDescribe("SolrCloud controller - External DNS", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace, - "SOLR_PORT": "2000", - "SOLR_NODE_PORT": "2000", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", + "ZK_HOST": "host:7271/", + "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace, + "SOLR_PORT": "2000", + "SOLR_NODE_PORT": "2000", + "SOLR_PORT_ADVERTISE": "2000", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", } testPodEnvVariables(expectedEnvVars, statefulSet.Spec.Template.Spec.Containers[0].Env) Expect(statefulSet.Spec.Template.Spec.Containers[0].Lifecycle.PreStop.Exec.Command).To(Equal([]string{"solr", "stop", "-p", "2000"}), "Incorrect pre-stop command") @@ -248,11 +250,12 @@ var _ = FDescribe("SolrCloud controller - External DNS", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": "$(POD_NAME)." + solrCloud.Namespace + "." + testDomain, - "SOLR_PORT": "3000", - "SOLR_NODE_PORT": "3000", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", + "ZK_HOST": "host:7271/", + "SOLR_HOST": "$(POD_NAME)." + solrCloud.Namespace + "." + testDomain, + "SOLR_PORT": "3000", + "SOLR_NODE_PORT": "3000", + "SOLR_PORT_ADVERTISE": "3000", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", } testPodEnvVariables(expectedEnvVars, statefulSet.Spec.Template.Spec.Containers[0].Env) Expect(statefulSet.Spec.Template.Spec.Containers[0].Lifecycle.PreStop.Exec.Command).To(Equal([]string{"solr", "stop", "-p", "3000"}), "Incorrect pre-stop command") @@ -318,11 +321,12 @@ var _ = FDescribe("SolrCloud controller - External DNS", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace, - "SOLR_PORT": "3000", - "SOLR_NODE_PORT": "3000", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", + "ZK_HOST": "host:7271/", + "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace, + "SOLR_PORT": "3000", + "SOLR_NODE_PORT": "3000", + "SOLR_PORT_ADVERTISE": "3000", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", } testPodEnvVariables(expectedEnvVars, statefulSet.Spec.Template.Spec.Containers[0].Env) Expect(statefulSet.Spec.Template.Spec.Containers[0].Lifecycle.PreStop.Exec.Command).To(Equal([]string{"solr", "stop", "-p", "3000"}), "Incorrect pre-stop command") @@ -386,11 +390,12 @@ var _ = FDescribe("SolrCloud controller - External DNS", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": "$(POD_NAME)." + solrCloud.Namespace + "." + testDomain, - "SOLR_PORT": "3000", - "SOLR_NODE_PORT": "3000", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", + "ZK_HOST": "host:7271/", + "SOLR_HOST": "$(POD_NAME)." + solrCloud.Namespace + "." + testDomain, + "SOLR_PORT": "3000", + "SOLR_NODE_PORT": "3000", + "SOLR_PORT_ADVERTISE": "3000", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", } testPodEnvVariables(expectedEnvVars, statefulSet.Spec.Template.Spec.Containers[0].Env) Expect(statefulSet.Spec.Template.Spec.Containers[0].Lifecycle.PreStop.Exec.Command).To(Equal([]string{"solr", "stop", "-p", "3000"}), "Incorrect pre-stop command") @@ -466,11 +471,12 @@ var _ = FDescribe("SolrCloud controller - External DNS", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace + ".svc." + testKubeDomain, - "SOLR_PORT": "2000", - "SOLR_NODE_PORT": "2000", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", + "ZK_HOST": "host:7271/", + "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace + ".svc." + testKubeDomain, + "SOLR_PORT": "2000", + "SOLR_NODE_PORT": "2000", + "SOLR_PORT_ADVERTISE": "2000", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", } testPodEnvVariables(expectedEnvVars, statefulSet.Spec.Template.Spec.Containers[0].Env) Expect(statefulSet.Spec.Template.Spec.Containers[0].Lifecycle.PreStop.Exec.Command).To(Equal([]string{"solr", "stop", "-p", "2000"}), "Incorrect pre-stop command") @@ -531,11 +537,12 @@ var _ = FDescribe("SolrCloud controller - External DNS", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": "$(POD_NAME)." + solrCloud.Namespace + "." + testDomain, - "SOLR_PORT": "2000", - "SOLR_NODE_PORT": "2000", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", + "ZK_HOST": "host:7271/", + "SOLR_HOST": "$(POD_NAME)." + solrCloud.Namespace + "." + testDomain, + "SOLR_PORT": "2000", + "SOLR_NODE_PORT": "2000", + "SOLR_PORT_ADVERTISE": "2000", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", } testPodEnvVariables(expectedEnvVars, statefulSet.Spec.Template.Spec.Containers[0].Env) Expect(statefulSet.Spec.Template.Spec.Containers[0].Lifecycle.PreStop.Exec.Command).To(Equal([]string{"solr", "stop", "-p", "2000"}), "Incorrect pre-stop command") diff --git a/controllers/solrcloud_controller_ingress_test.go b/controllers/solrcloud_controller_ingress_test.go index f9c61ba6..d9ad9bf0 100644 --- a/controllers/solrcloud_controller_ingress_test.go +++ b/controllers/solrcloud_controller_ingress_test.go @@ -113,11 +113,12 @@ var _ = FDescribe("SolrCloud controller - Ingress", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": solrCloud.Namespace + "-$(POD_NAME)." + testDomain, - "SOLR_PORT": "3000", - "SOLR_NODE_PORT": "100", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", + "ZK_HOST": "host:7271/", + "SOLR_HOST": solrCloud.Namespace + "-$(POD_NAME)." + testDomain, + "SOLR_PORT": "3000", + "SOLR_NODE_PORT": "100", + "SOLR_PORT_ADVERTISE": "100", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", } testPodEnvVariables(expectedEnvVars, statefulSet.Spec.Template.Spec.Containers[0].Env) Expect(statefulSet.Spec.Template.Spec.Containers[0].Lifecycle.PreStop.Exec.Command).To(Equal([]string{"solr", "stop", "-p", "3000"}), "Incorrect pre-stop command") @@ -213,11 +214,12 @@ var _ = FDescribe("SolrCloud controller - Ingress", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace, - "SOLR_PORT": "3000", - "SOLR_NODE_PORT": "3000", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", + "ZK_HOST": "host:7271/", + "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace, + "SOLR_PORT": "3000", + "SOLR_NODE_PORT": "3000", + "SOLR_PORT_ADVERTISE": "3000", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", } testPodEnvVariables(expectedEnvVars, statefulSet.Spec.Template.Spec.Containers[0].Env) Expect(statefulSet.Spec.Template.Spec.Containers[0].Lifecycle.PreStop.Exec.Command).To(Equal([]string{"solr", "stop", "-p", "3000"}), "Incorrect pre-stop command") @@ -292,11 +294,12 @@ var _ = FDescribe("SolrCloud controller - Ingress", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": solrCloud.Namespace + "-$(POD_NAME)." + testDomain, - "SOLR_PORT": "3000", - "SOLR_NODE_PORT": "100", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", + "ZK_HOST": "host:7271/", + "SOLR_HOST": solrCloud.Namespace + "-$(POD_NAME)." + testDomain, + "SOLR_PORT": "3000", + "SOLR_NODE_PORT": "100", + "SOLR_PORT_ADVERTISE": "100", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", } testPodEnvVariables(expectedEnvVars, statefulSet.Spec.Template.Spec.Containers[0].Env) Expect(statefulSet.Spec.Template.Spec.Containers[0].Lifecycle.PreStop.Exec.Command).To(Equal([]string{"solr", "stop", "-p", "3000"}), "Incorrect pre-stop command") @@ -369,11 +372,12 @@ var _ = FDescribe("SolrCloud controller - Ingress", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": "$(POD_NAME)." + solrCloud.Namespace, - "SOLR_PORT": "3000", - "SOLR_NODE_PORT": "100", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", + "ZK_HOST": "host:7271/", + "SOLR_HOST": "$(POD_NAME)." + solrCloud.Namespace, + "SOLR_PORT": "3000", + "SOLR_NODE_PORT": "100", + "SOLR_PORT_ADVERTISE": "100", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", } testPodEnvVariables(expectedEnvVars, statefulSet.Spec.Template.Spec.Containers[0].Env) Expect(statefulSet.Spec.Template.Spec.Containers[0].Lifecycle.PreStop.Exec.Command).To(Equal([]string{"solr", "stop", "-p", "3000"}), "Incorrect pre-stop command") @@ -446,11 +450,12 @@ var _ = FDescribe("SolrCloud controller - Ingress", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": solrCloud.Namespace + "-$(POD_NAME)." + testDomain, - "SOLR_PORT": "3000", - "SOLR_NODE_PORT": "100", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", + "ZK_HOST": "host:7271/", + "SOLR_HOST": solrCloud.Namespace + "-$(POD_NAME)." + testDomain, + "SOLR_PORT": "3000", + "SOLR_NODE_PORT": "100", + "SOLR_PORT_ADVERTISE": "100", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", } testPodEnvVariables(expectedEnvVars, statefulSet.Spec.Template.Spec.Containers[0].Env) Expect(statefulSet.Spec.Template.Spec.Containers[0].Lifecycle.PreStop.Exec.Command).To(Equal([]string{"solr", "stop", "-p", "3000"}), "Incorrect pre-stop command") @@ -519,11 +524,12 @@ var _ = FDescribe("SolrCloud controller - Ingress", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": "$(POD_NAME)." + solrCloud.Namespace + ".svc." + testKubeDomain, - "SOLR_PORT": "3000", - "SOLR_NODE_PORT": "100", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", + "ZK_HOST": "host:7271/", + "SOLR_HOST": "$(POD_NAME)." + solrCloud.Namespace + ".svc." + testKubeDomain, + "SOLR_PORT": "3000", + "SOLR_NODE_PORT": "100", + "SOLR_PORT_ADVERTISE": "100", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", } testPodEnvVariables(expectedEnvVars, statefulSet.Spec.Template.Spec.Containers[0].Env) Expect(statefulSet.Spec.Template.Spec.Containers[0].Lifecycle.PreStop.Exec.Command).To(Equal([]string{"solr", "stop", "-p", "3000"}), "Incorrect pre-stop command") @@ -595,11 +601,12 @@ var _ = FDescribe("SolrCloud controller - Ingress", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": solrCloud.Namespace + "-$(POD_NAME)." + testDomain, - "SOLR_PORT": "3000", - "SOLR_NODE_PORT": "100", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", + "ZK_HOST": "host:7271/", + "SOLR_HOST": solrCloud.Namespace + "-$(POD_NAME)." + testDomain, + "SOLR_PORT": "3000", + "SOLR_NODE_PORT": "100", + "SOLR_PORT_ADVERTISE": "100", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", } testPodEnvVariables(expectedEnvVars, statefulSet.Spec.Template.Spec.Containers[0].Env) Expect(statefulSet.Spec.Template.Spec.Containers[0].Lifecycle.PreStop.Exec.Command).To(Equal([]string{"solr", "stop", "-p", "3000"}), "Incorrect pre-stop command") diff --git a/controllers/solrcloud_controller_test.go b/controllers/solrcloud_controller_test.go index 16460139..2c568585 100644 --- a/controllers/solrcloud_controller_test.go +++ b/controllers/solrcloud_controller_test.go @@ -117,13 +117,14 @@ var _ = FDescribe("SolrCloud controller - General", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace, - "SOLR_JAVA_MEM": "-Xmx4G", - "SOLR_PORT": "8983", - "SOLR_NODE_PORT": "8983", - "SOLR_LOG_LEVEL": "DEBUG", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT) extra-opts", + "ZK_HOST": "host:7271/", + "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace, + "SOLR_JAVA_MEM": "-Xmx4G", + "SOLR_PORT": "8983", + "SOLR_NODE_PORT": "8983", + "SOLR_PORT_ADVERTISE": "8983", + "SOLR_LOG_LEVEL": "DEBUG", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT) extra-opts", } foundEnv := statefulSet.Spec.Template.Spec.Containers[0].Env // Note that this check changes the variable foundEnv, so the values are no longer valid afterwards. @@ -247,13 +248,14 @@ var _ = FDescribe("SolrCloud controller - General", func() { Expect(statefulSet.Spec.Template.Spec.Containers).To(HaveLen(1), "Solr StatefulSet requires a container.") expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/test", - "SOLR_HOST": "$(POD_NAME).foo-solrcloud-headless.default", - "SOLR_PORT": "8983", - "SOLR_NODE_PORT": "8983", - "GC_TUNE": "gc Options", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", - "SOLR_STOP_WAIT": strconv.FormatInt(testTerminationGracePeriodSeconds-5, 10), + "ZK_HOST": "host:7271/test", + "SOLR_HOST": "$(POD_NAME).foo-solrcloud-headless.default", + "SOLR_PORT": "8983", + "SOLR_NODE_PORT": "8983", + "SOLR_PORT_ADVERTISE": "8983", + "GC_TUNE": "gc Options", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", + "SOLR_STOP_WAIT": strconv.FormatInt(testTerminationGracePeriodSeconds-5, 10), } expectedStatefulSetLabels := util.MergeLabelsOrAnnotations(solrCloud.SharedLabelsWith(solrCloud.Labels), map[string]string{"technology": util.SolrCloudPVCTechnology}) expectedStatefulSetAnnotations := map[string]string{util.SolrZKConnectionStringAnnotation: "host:7271/test"} @@ -438,11 +440,12 @@ var _ = FDescribe("SolrCloud controller - General", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace + ".svc." + testKubeDomain, - "SOLR_PORT": "2000", - "SOLR_NODE_PORT": "2000", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", + "ZK_HOST": "host:7271/", + "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace + ".svc." + testKubeDomain, + "SOLR_PORT": "2000", + "SOLR_NODE_PORT": "2000", + "SOLR_PORT_ADVERTISE": "2000", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT)", } testPodEnvVariables(expectedEnvVars, statefulSet.Spec.Template.Spec.Containers[0].Env) By("testing the Solr Common Service") diff --git a/controllers/solrcloud_controller_zk_test.go b/controllers/solrcloud_controller_zk_test.go index 8fb8a745..57917fb4 100644 --- a/controllers/solrcloud_controller_zk_test.go +++ b/controllers/solrcloud_controller_zk_test.go @@ -104,11 +104,12 @@ var _ = FDescribe("SolrCloud controller - Zookeeper", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/", - "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace, - "SOLR_PORT": "8983", - "SOLR_NODE_PORT": "8983", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT) $(SOLR_ZK_CREDS_AND_ACLS) -Dextra -Dopts", + "ZK_HOST": "host:7271/", + "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace, + "SOLR_PORT": "8983", + "SOLR_NODE_PORT": "8983", + "SOLR_PORT_ADVERTISE": "8983", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT) $(SOLR_ZK_CREDS_AND_ACLS) -Dextra -Dopts", } insertExpectedAclEnvVars(expectedEnvVars, false) for _, envVar := range extraVars { @@ -169,11 +170,12 @@ var _ = FDescribe("SolrCloud controller - Zookeeper", func() { // Env Variable Tests expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/a-ch/root", - "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace, - "SOLR_PORT": "8983", - "SOLR_NODE_PORT": "8983", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT) $(SOLR_ZK_CREDS_AND_ACLS) -Dextra -Dopts", + "ZK_HOST": "host:7271/a-ch/root", + "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace, + "SOLR_PORT": "8983", + "SOLR_NODE_PORT": "8983", + "SOLR_PORT_ADVERTISE": "8983", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT) $(SOLR_ZK_CREDS_AND_ACLS) -Dextra -Dopts", } insertExpectedAclEnvVars(expectedEnvVars, true) for _, envVar := range extraVars { @@ -449,12 +451,13 @@ var _ = FDescribe("SolrCloud controller - Zookeeper", func() { // Env Variable Tests expectedZKHost := expectedZkConnStr + "/a-ch/root" expectedEnvVars := map[string]string{ - "ZK_HOST": expectedZKHost, - "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace, - "SOLR_PORT": "8983", - "SOLR_NODE_PORT": "8983", - "ZK_CHROOT": "/a-ch/root", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT) $(SOLR_ZK_CREDS_AND_ACLS) -Dextra -Dopts", + "ZK_HOST": expectedZKHost, + "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace, + "SOLR_PORT": "8983", + "SOLR_NODE_PORT": "8983", + "SOLR_PORT_ADVERTISE": "8983", + "ZK_CHROOT": "/a-ch/root", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT) $(SOLR_ZK_CREDS_AND_ACLS) -Dextra -Dopts", } insertExpectedAclEnvVars(expectedEnvVars, false) for _, envVar := range extraVars { @@ -525,11 +528,12 @@ var _ = FDescribe("SolrCloud controller - Zookeeper", func() { // Env Variable Tests expectedZKHost := expectedZkConnStr + "/" expectedEnvVars := map[string]string{ - "ZK_HOST": expectedZKHost, - "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace, - "SOLR_PORT": "8983", - "SOLR_NODE_PORT": "8983", - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT) $(SOLR_ZK_CREDS_AND_ACLS) -Dextra -Dopts", + "ZK_HOST": expectedZKHost, + "SOLR_HOST": "$(POD_NAME)." + solrCloud.HeadlessServiceName() + "." + solrCloud.Namespace, + "SOLR_PORT": "8983", + "SOLR_NODE_PORT": "8983", + "SOLR_PORT_ADVERTISE": "8983", + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT) $(SOLR_ZK_CREDS_AND_ACLS) -Dextra -Dopts", } insertExpectedAclEnvVars(expectedEnvVars, true) for _, envVar := range extraVars { @@ -565,13 +569,14 @@ var _ = FDescribe("SolrCloud controller - Zookeeper", func() { statefulSet := expectStatefulSet(ctx, solrCloud, solrCloud.StatefulSetName()) Expect(statefulSet.Spec.Template.Spec.Containers).To(HaveLen(1), "Solr StatefulSet requires a container.") expectedEnvVars := map[string]string{ - "ZK_HOST": "host:7271/test", - "SOLR_HOST": "$(POD_NAME).foo-solrcloud-headless.default", - "SOLR_PORT": "8983", - "SOLR_NODE_PORT": "8983", - "SOLR_ZK_OPTS": testSolrZKOpts, - "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT) $(SOLR_ZK_OPTS) " + testSolrOpts, - "SOLR_STOP_WAIT": strconv.FormatInt(60-5, 10), + "ZK_HOST": "host:7271/test", + "SOLR_HOST": "$(POD_NAME).foo-solrcloud-headless.default", + "SOLR_PORT": "8983", + "SOLR_NODE_PORT": "8983", + "SOLR_PORT_ADVERTISE": "8983", + "SOLR_ZK_OPTS": testSolrZKOpts, + "SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT) $(SOLR_ZK_OPTS) " + testSolrOpts, + "SOLR_STOP_WAIT": strconv.FormatInt(60-5, 10), } testPodEnvVariables(expectedEnvVars, statefulSet.Spec.Template.Spec.Containers[0].Env) diff --git a/controllers/util/solr_util.go b/controllers/util/solr_util.go index 5c5b6142..f73eb974 100644 --- a/controllers/util/solr_util.go +++ b/controllers/util/solr_util.go @@ -61,8 +61,9 @@ const ( DefaultStatefulSetPodManagementPolicy = appsv1.ParallelPodManagement - DistLibs = "/opt/solr/dist" - ContribLibs = "/opt/solr/contrib/%s/lib" + DistLibs = "/opt/solr/dist" + ContribLibs = "/opt/solr/contrib/%s/lib" + SysPropLibPlaceholder = "${solr.sharedLib:}" ) var ( @@ -305,9 +306,15 @@ func GenerateStatefulSet(solrCloud *solr.SolrCloud, solrCloudStatus *solr.SolrCl }, { // This is the port that the Solr Node will advertise itself as listening on in live_nodes + // TODO Remove in 0.9.0 once users have had a chance to switch any custom solr.xml files over to using the `solr.port.advertise` placeholder Name: "SOLR_NODE_PORT", Value: strconv.Itoa(solrAdressingPort), }, + { + // Supercedes SOLR_NODE_PORT above. 'bin/solr' converts to 'solr.port.advertise' sysprop automatically. + Name: "SOLR_PORT_ADVERTISE", + Value: strconv.Itoa(solrAdressingPort), + }, // POD_HOSTNAME is deprecated and will be removed in a future version. Use POD_NAME instead { Name: "POD_HOSTNAME", @@ -771,7 +778,7 @@ const DefaultSolrXML = ` %s ${host:} - ${hostPort:80} + ${solr.port.advertise:80} ${hostContext:solr} ${genericCoreNodeNames:true} ${zkClientTimeout:30000} @@ -786,6 +793,8 @@ const DefaultSolrXML = ` ${connTimeout:60000} ${solr.max.booleanClauses:1024} + ${solr.allowPaths:} + %s ` @@ -831,6 +840,9 @@ func GenerateSolrXMLString(backupSection string, solrModules []string, additiona func GenerateAdditionalLibXMLPart(solrModules []string, additionalLibs []string) string { libs := make(map[string]bool, 0) + // Placeholder for users to specify libs via sysprop + libs[SysPropLibPlaceholder] = true + // Add all module library locations if len(solrModules) > 0 { libs[DistLibs] = true @@ -844,16 +856,12 @@ func GenerateAdditionalLibXMLPart(solrModules []string, additionalLibs []string) libs[libPath] = true } - libXml := "" - if len(libs) > 0 { - libList := make([]string, 0) - for lib := range libs { - libList = append(libList, lib) - } - sort.Strings(libList) - libXml = fmt.Sprintf("%s", strings.Join(libList, ",")) + libList := make([]string, 0) + for lib := range libs { + libList = append(libList, lib) } - return libXml + sort.Strings(libList) + return fmt.Sprintf("%s", strings.Join(libList, ",")) } func getAppProtocol(solrCloud *solr.SolrCloud) *string { diff --git a/controllers/util/solr_util_test.go b/controllers/util/solr_util_test.go index 0e3f6352..b6d6bb43 100644 --- a/controllers/util/solr_util_test.go +++ b/controllers/util/solr_util_test.go @@ -116,25 +116,29 @@ func TestGeneratedGcsRepositoryXmlSkipsCredentialIfUnset(t *testing.T) { } func TestGenerateAdditionalLibXMLPart(t *testing.T) { + // No specified libs + xmlString := GenerateAdditionalLibXMLPart([]string{}, []string{}) + assert.EqualValuesf(t, xmlString, "${solr.sharedLib:}", "Wrong sharedLib xml for no specified libs") + // Just 1 repeated solr module - xmlString := GenerateAdditionalLibXMLPart([]string{"gcs-repository", "gcs-repository"}, []string{}) - assert.EqualValuesf(t, xmlString, "/opt/solr/contrib/gcs-repository/lib,/opt/solr/dist", "Wrong sharedLib xml for just 1 repeated solr module") + xmlString = GenerateAdditionalLibXMLPart([]string{"gcs-repository", "gcs-repository"}, []string{}) + assert.EqualValuesf(t, xmlString, "${solr.sharedLib:},/opt/solr/contrib/gcs-repository/lib,/opt/solr/dist", "Wrong sharedLib xml for just 1 repeated solr module") // Just 2 different solr modules xmlString = GenerateAdditionalLibXMLPart([]string{"gcs-repository", "analytics"}, []string{}) - assert.EqualValuesf(t, xmlString, "/opt/solr/contrib/analytics/lib,/opt/solr/contrib/gcs-repository/lib,/opt/solr/dist", "Wrong sharedLib xml for just 2 different solr modules") + assert.EqualValuesf(t, xmlString, "${solr.sharedLib:},/opt/solr/contrib/analytics/lib,/opt/solr/contrib/gcs-repository/lib,/opt/solr/dist", "Wrong sharedLib xml for just 2 different solr modules") // Just 2 repeated libs xmlString = GenerateAdditionalLibXMLPart([]string{}, []string{"/ext/lib", "/ext/lib"}) - assert.EqualValuesf(t, xmlString, "/ext/lib", "Wrong sharedLib xml for just 1 repeated additional lib") + assert.EqualValuesf(t, xmlString, "${solr.sharedLib:},/ext/lib", "Wrong sharedLib xml for just 1 repeated additional lib") // Just 2 different libs xmlString = GenerateAdditionalLibXMLPart([]string{}, []string{"/ext/lib2", "/ext/lib1"}) - assert.EqualValuesf(t, xmlString, "/ext/lib1,/ext/lib2", "Wrong sharedLib xml for just 2 different additional libs") + assert.EqualValuesf(t, xmlString, "${solr.sharedLib:},/ext/lib1,/ext/lib2", "Wrong sharedLib xml for just 2 different additional libs") // Combination of everything xmlString = GenerateAdditionalLibXMLPart([]string{"gcs-repository", "analytics", "analytics"}, []string{"/ext/lib2", "/ext/lib2", "/ext/lib1"}) - assert.EqualValuesf(t, xmlString, "/ext/lib1,/ext/lib2,/opt/solr/contrib/analytics/lib,/opt/solr/contrib/gcs-repository/lib,/opt/solr/dist", "Wrong sharedLib xml for mix of additional libs and solr modules") + assert.EqualValuesf(t, xmlString, "${solr.sharedLib:},/ext/lib1,/ext/lib2,/opt/solr/contrib/analytics/lib,/opt/solr/contrib/gcs-repository/lib,/opt/solr/dist", "Wrong sharedLib xml for mix of additional libs and solr modules") } func TestGenerateSolrXMLStringForCloud(t *testing.T) { @@ -151,7 +155,7 @@ func TestGenerateSolrXMLStringForCloud(t *testing.T) { SolrModules: []string{"ltr", "analytics"}, }, } - assert.Containsf(t, GenerateSolrXMLStringForCloud(solrCloud), "/ext/lib1,/ext/lib2,/opt/solr/contrib/analytics/lib,/opt/solr/contrib/gcs-repository/lib,/opt/solr/contrib/ltr/lib,/opt/solr/dist", "Wrong sharedLib xml for a cloud with a backupRepo, additionalLibs and solrModules") + assert.Containsf(t, GenerateSolrXMLStringForCloud(solrCloud), "${solr.sharedLib:},/ext/lib1,/ext/lib2,/opt/solr/contrib/analytics/lib,/opt/solr/contrib/gcs-repository/lib,/opt/solr/contrib/ltr/lib,/opt/solr/dist", "Wrong sharedLib xml for a cloud with a backupRepo, additionalLibs and solrModules") // Just SolrModules and AdditionalLibs solrCloud = &solr.SolrCloud{ @@ -160,7 +164,7 @@ func TestGenerateSolrXMLStringForCloud(t *testing.T) { SolrModules: []string{"ltr", "analytics"}, }, } - assert.Containsf(t, GenerateSolrXMLStringForCloud(solrCloud), "/ext/lib1,/ext/lib2,/opt/solr/contrib/analytics/lib,/opt/solr/contrib/ltr/lib,/opt/solr/dist", "Wrong sharedLib xml for a cloud with additionalLibs and solrModules") + assert.Containsf(t, GenerateSolrXMLStringForCloud(solrCloud), "${solr.sharedLib:},/ext/lib1,/ext/lib2,/opt/solr/contrib/analytics/lib,/opt/solr/contrib/ltr/lib,/opt/solr/dist", "Wrong sharedLib xml for a cloud with additionalLibs and solrModules") // Just SolrModules and Backups solrCloud = &solr.SolrCloud{ @@ -174,7 +178,7 @@ func TestGenerateSolrXMLStringForCloud(t *testing.T) { SolrModules: []string{"ltr", "analytics"}, }, } - assert.Containsf(t, GenerateSolrXMLStringForCloud(solrCloud), "/opt/solr/contrib/analytics/lib,/opt/solr/contrib/gcs-repository/lib,/opt/solr/contrib/ltr/lib,/opt/solr/dist", "Wrong sharedLib xml for a cloud with a backupRepo and solrModules") + assert.Containsf(t, GenerateSolrXMLStringForCloud(solrCloud), "${solr.sharedLib:},/opt/solr/contrib/analytics/lib,/opt/solr/contrib/gcs-repository/lib,/opt/solr/contrib/ltr/lib,/opt/solr/dist", "Wrong sharedLib xml for a cloud with a backupRepo and solrModules") // Just AdditionalLibs and Backups solrCloud = &solr.SolrCloud{ @@ -188,7 +192,7 @@ func TestGenerateSolrXMLStringForCloud(t *testing.T) { AdditionalLibs: []string{"/ext/lib2", "/ext/lib1"}, }, } - assert.Containsf(t, GenerateSolrXMLStringForCloud(solrCloud), "/ext/lib1,/ext/lib2,/opt/solr/contrib/gcs-repository/lib,/opt/solr/dist", "Wrong sharedLib xml for a cloud with a backupRepo and additionalLibs") + assert.Containsf(t, GenerateSolrXMLStringForCloud(solrCloud), "${solr.sharedLib:},/ext/lib1,/ext/lib2,/opt/solr/contrib/gcs-repository/lib,/opt/solr/dist", "Wrong sharedLib xml for a cloud with a backupRepo and additionalLibs") // Just SolrModules solrCloud = &solr.SolrCloud{ @@ -196,7 +200,7 @@ func TestGenerateSolrXMLStringForCloud(t *testing.T) { SolrModules: []string{"ltr", "analytics"}, }, } - assert.Containsf(t, GenerateSolrXMLStringForCloud(solrCloud), "/opt/solr/contrib/analytics/lib,/opt/solr/contrib/ltr/lib,/opt/solr/dist", "Wrong sharedLib xml for a cloud with just solrModules") + assert.Containsf(t, GenerateSolrXMLStringForCloud(solrCloud), "${solr.sharedLib:},/opt/solr/contrib/analytics/lib,/opt/solr/contrib/ltr/lib,/opt/solr/dist", "Wrong sharedLib xml for a cloud with just solrModules") // Just Backups solrCloud = &solr.SolrCloud{ @@ -209,7 +213,7 @@ func TestGenerateSolrXMLStringForCloud(t *testing.T) { }, }, } - assert.Containsf(t, GenerateSolrXMLStringForCloud(solrCloud), "/opt/solr/contrib/gcs-repository/lib,/opt/solr/dist", "Wrong sharedLib xml for a cloud with just a backupRepo") + assert.Containsf(t, GenerateSolrXMLStringForCloud(solrCloud), "${solr.sharedLib:},/opt/solr/contrib/gcs-repository/lib,/opt/solr/dist", "Wrong sharedLib xml for a cloud with just a backupRepo") // Just AdditionalLibs solrCloud = &solr.SolrCloud{ @@ -217,5 +221,5 @@ func TestGenerateSolrXMLStringForCloud(t *testing.T) { AdditionalLibs: []string{"/ext/lib2", "/ext/lib1"}, }, } - assert.Containsf(t, GenerateSolrXMLStringForCloud(solrCloud), "/ext/lib1,/ext/lib2", "Wrong sharedLib xml for a cloud with a just additionalLibs") + assert.Containsf(t, GenerateSolrXMLStringForCloud(solrCloud), "${solr.sharedLib:},/ext/lib1,/ext/lib2", "Wrong sharedLib xml for a cloud with a just additionalLibs") } diff --git a/docs/solr-cloud/solr-cloud-crd.md b/docs/solr-cloud/solr-cloud-crd.md index d2080d96..b30ea670 100644 --- a/docs/solr-cloud/solr-cloud-crd.md +++ b/docs/solr-cloud/solr-cloud-crd.md @@ -338,7 +338,7 @@ data: ... CUSTOM CONFIG HERE ... ``` -**Important: Your custom `solr.xml` must include `${hostPort:0}` as the operator relies on this element to set the port Solr pods advertise to ZooKeeper. If this element is missing, then your Solr pods will not be created.** +**Important: Your custom `solr.xml` must include `${solr.port.advertise:0}` as the operator relies on this element to set the port Solr pods advertise to ZooKeeper. If this element is missing, then your Solr pods will not be created.** You can get the default `solr.xml` from a Solr pod as a starting point for creating a custom config using `kubectl cp` as shown in the example below: ```bash diff --git a/docs/upgrade-notes.md b/docs/upgrade-notes.md index 6f5ad4aa..128be56b 100644 --- a/docs/upgrade-notes.md +++ b/docs/upgrade-notes.md @@ -130,6 +130,8 @@ _Note that the Helm chart version does not contain a `v` prefix, which the downl - The `POD_HOSTNAME` envVar in SolrCloud Pods has been deprecated. Use `POD_NAME` instead. +- Use of the `hostPort` system property placeholder in custom solr.xml files has been deprecated. Use `${solr.port.advertise:80}`, the default value used by Solr, instead. + ### v0.7.0 - **Kubernetes support is now limited to 1.21+.** If you are unable to use a newer version of Kubernetes, please install the `v0.6.0` version of the Solr Operator for use with Kubernetes `1.20` and below. diff --git a/helm/solr/Chart.yaml b/helm/solr/Chart.yaml index 44070f56..f265d4b8 100644 --- a/helm/solr/Chart.yaml +++ b/helm/solr/Chart.yaml @@ -55,6 +55,13 @@ annotations: url: https://github.com/apache/solr-operator/issues/630 - name: Github PR url: https://github.com/apache/solr-operator/pull/631 + - kind: changed + description: The default solr.xml now includes the necessary boilerplate to specify additional `sharedLib` and `allowPath` values (via the `solr.sharedLib` and `solr.allowPaths` system properties respectively). The `metricsEnabled` system property can also be used to toggle Solr's metrics processing (defaults to `true`). Lastly, the `solr.port.advertise` property can be used to control the port Solr is advertised under in `/live_nodes` and other cluster state. Users providing their own `solr.xml` should replace any references to the `hostPort` system property with `solr.port.advertise`, as support for the `hostPort` placeholder will be removed in a future release. + links: + - name: Github Issue + url: https://github.com/apache/solr-operator/issues/635 + - name: Github PR + url: https://github.com/apache/solr-operator/pull/636 artifacthub.io/containsSecurityUpdates: "false" artifacthub.io/recommendations: | - url: https://artifacthub.io/packages/helm/apache-solr/solr-operator