This is an automated email from the ASF dual-hosted git repository.
houston pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr-operator.git
The following commit(s) were added to refs/heads/main by this push:
new 36a6207 Enable automatic scheduled restarts managed by the Operator
(#279)
36a6207 is described below
commit 36a62072a28ae7482dc90fee2754616d8c51a1d3
Author: Houston Putman <[email protected]>
AuthorDate: Thu Jul 8 12:29:57 2021 -0400
Enable automatic scheduled restarts managed by the Operator (#279)
These restarts are scheduled via a CRON string in the SolrCloud spec.
---
api/v1beta1/solrcloud_types.go | 13 ++++++
config/crd/bases/solr.apache.org_solrclouds.yaml | 3 ++
controllers/solrcloud_controller.go | 34 ++++++++++++++--
controllers/solrcloud_controller_test.go | 7 +++-
controllers/util/solr_update_util.go | 51 +++++++++++++++++++++++
controllers/util/solr_update_util_test.go | 52 ++++++++++++++++++++++++
dependency_licenses.csv | 1 +
docs/solr-cloud/solr-cloud-crd.md | 4 +-
go.mod | 1 +
go.sum | 3 ++
helm/solr-operator/Chart.yaml | 9 ++--
helm/solr-operator/crds/crds.yaml | 3 ++
helm/solr/README.md | 3 +-
helm/solr/templates/solrcloud.yaml | 11 ++++-
helm/solr/values.yaml | 3 ++
15 files changed, 184 insertions(+), 14 deletions(-)
diff --git a/api/v1beta1/solrcloud_types.go b/api/v1beta1/solrcloud_types.go
index e60839c..6509d46 100644
--- a/api/v1beta1/solrcloud_types.go
+++ b/api/v1beta1/solrcloud_types.go
@@ -475,6 +475,19 @@ type SolrUpdateStrategy struct {
// Options for Solr Operator Managed rolling updates.
// +optional
ManagedUpdateOptions ManagedUpdateOptions `json:"managed,omitempty"`
+
+ // Perform a scheduled restart on the given schedule, in CRON format.
+ //
+ // Multiple CRON syntaxes are supported
+ // - Standard CRON (e.g. "CRON_TZ=Asia/Seoul 0 6 * * ?")
+ // - Predefined Schedules (e.g. "@yearly", "@weekly", etc.)
+ // - Intervals (e.g. "@every 10h30m")
+ //
+ // For more information please check this reference:
+ //
https://pkg.go.dev/github.com/robfig/cron/v3?utm_source=godoc#hdr-CRON_Expression_Format
+ //
+ // +optional
+ RestartSchedule string `json:"restartSchedule,omitempty"`
}
// SolrUpdateMethod is a string enumeration type that enumerates
diff --git a/config/crd/bases/solr.apache.org_solrclouds.yaml
b/config/crd/bases/solr.apache.org_solrclouds.yaml
index c6172e3..25d39c0 100644
--- a/config/crd/bases/solr.apache.org_solrclouds.yaml
+++ b/config/crd/bases/solr.apache.org_solrclouds.yaml
@@ -4668,6 +4668,9 @@ spec:
- StatefulSet
- Manual
type: string
+ restartSchedule:
+ description: "Perform a scheduled restart on the given
schedule, in CRON format. \n Multiple CRON syntaxes are supported - Standard
CRON (e.g. \"CRON_TZ=Asia/Seoul 0 6 * * ?\") - Predefined Schedules (e.g.
\"@yearly\", \"@weekly\", etc.) - Intervals (e.g. \"@every 10h30m\") \n For
more information please check this reference:
https://pkg.go.dev/github.com/robfig/cron/v3?utm_source=godoc#hdr-CRON_Expression_Format"
+ type: string
type: object
zookeeperRef:
description: The information for the Zookeeper this SolrCloud
should connect to Can be a zookeeper that is running, or one that is created by
the solr operator
diff --git a/controllers/solrcloud_controller.go
b/controllers/solrcloud_controller.go
index c2dae2f..a7624a3 100644
--- a/controllers/solrcloud_controller.go
+++ b/controllers/solrcloud_controller.go
@@ -414,6 +414,26 @@ func (r *SolrCloudReconciler) Reconcile(req ctrl.Request)
(ctrl.Result, error) {
statefulSetLogger := logger.WithValues("statefulSet",
statefulSet.Name)
foundStatefulSet := &appsv1.StatefulSet{}
err = r.Get(context.TODO(), types.NamespacedName{Name:
statefulSet.Name, Namespace: statefulSet.Namespace}, foundStatefulSet)
+
+ // Set the annotation for a scheduled restart, if necessary.
+ if nextRestartAnnotation, reconcileWaitDuration, err :=
util.ScheduleNextRestart(instance.Spec.UpdateStrategy.RestartSchedule,
foundStatefulSet.Spec.Template.Annotations); err != nil {
+ logger.Error(err, "Cannot parse restartSchedule cron:
%s", instance.Spec.UpdateStrategy.RestartSchedule)
+ } else {
+ if nextRestartAnnotation != "" {
+ // Set the new restart time annotation
+
statefulSet.Spec.Template.Annotations[util.SolrScheduledRestartAnnotation] =
nextRestartAnnotation
+ // TODO: Create event for the CRD.
+ } else if existingRestartAnnotation, exists :=
foundStatefulSet.Spec.Template.Annotations[util.SolrScheduledRestartAnnotation];
exists {
+ // Keep the existing nextRestart annotation if
it exists and we aren't setting a new one.
+
statefulSet.Spec.Template.Annotations[util.SolrScheduledRestartAnnotation] =
existingRestartAnnotation
+ }
+ if reconcileWaitDuration != nil {
+ // Set the requeueAfter if it has not been set,
or is greater than the time we need to wait to restart again
+ updateRequeueAfter(&requeueOrNot,
*reconcileWaitDuration)
+ }
+ }
+
+ // Update or Create the StatefulSet
if err != nil && errors.IsNotFound(err) {
statefulSetLogger.Info("Creating StatefulSet")
if err =
controllerutil.SetControllerReference(instance, statefulSet, r.scheme); err ==
nil {
@@ -458,7 +478,8 @@ func (r *SolrCloudReconciler) Reconcile(req ctrl.Request)
(ctrl.Result, error) {
// Otherwise it will delete all PVCs possibly
if len(pvcLabelSelector) > 0 {
if err := r.reconcileStorageFinalizer(instance,
pvcLabelSelector, logger); err != nil {
- return reconcile.Result{RequeueAfter: time.Second *
10}, nil
+ logger.Error(err, "Cannot delete PVCs while garbage
collecting after deletion.")
+ updateRequeueAfter(&requeueOrNot, time.Second*15)
}
}
@@ -502,9 +523,7 @@ func (r *SolrCloudReconciler) Reconcile(req ctrl.Request)
(ctrl.Result, error) {
// TODO: Create event for the CRD.
}
if err != nil || retryLater {
- if requeueOrNot.RequeueAfter <= 0 ||
requeueOrNot.RequeueAfter > time.Second*15 {
- requeueOrNot.RequeueAfter = time.Second * 15
- }
+ updateRequeueAfter(&requeueOrNot, time.Second*15)
}
}
@@ -1021,3 +1040,10 @@ func (r *SolrCloudReconciler)
verifyTLSSecretConfig(secretName string, secretNam
return foundTLSSecret, nil
}
+
+// Set the requeueAfter if it has not been set, or is greater than the new
time to requeue at
+func updateRequeueAfter(requeueOrNot *reconcile.Result, newWait time.Duration)
{
+ if requeueOrNot.RequeueAfter <= 0 || requeueOrNot.RequeueAfter >
newWait {
+ requeueOrNot.RequeueAfter = newWait
+ }
+}
diff --git a/controllers/solrcloud_controller_test.go
b/controllers/solrcloud_controller_test.go
index 21eabfc..ec285c8 100644
--- a/controllers/solrcloud_controller_test.go
+++ b/controllers/solrcloud_controller_test.go
@@ -192,7 +192,8 @@ func TestCustomKubeOptionsCloudReconcile(t *testing.T) {
},
},
UpdateStrategy: solr.SolrUpdateStrategy{
- Method: solr.StatefulSetUpdate,
+ Method: solr.StatefulSetUpdate,
+ RestartSchedule: "@every 30m",
},
SolrGCTune: "gc Options",
CustomSolrKubeOptions: solr.CustomSolrKubeOptions{
@@ -285,6 +286,10 @@ func TestCustomKubeOptionsCloudReconcile(t *testing.T) {
testMapsEqual(t, "statefulSet labels",
util.MergeLabelsOrAnnotations(expectedStatefulSetLabels, testSSLabels),
statefulSet.Labels)
testMapsEqual(t, "statefulSet annotations",
util.MergeLabelsOrAnnotations(expectedStatefulSetAnnotations,
testSSAnnotations), statefulSet.Annotations)
testMapsEqual(t, "pod labels",
util.MergeLabelsOrAnnotations(expectedStatefulSetLabels, testPodLabels),
statefulSet.Spec.Template.ObjectMeta.Labels)
+ if assert.True(t,
metav1.HasAnnotation(statefulSet.Spec.Template.ObjectMeta,
util.SolrScheduledRestartAnnotation), "Pod Template does not have scheduled
restart annotation when it should") {
+ // Remove the annotation when we know that it exists, we don't
know the exact value so we can't check it below.
+ delete(statefulSet.Spec.Template.Annotations,
util.SolrScheduledRestartAnnotation)
+ }
testMapsEqual(t, "pod annotations",
util.MergeLabelsOrAnnotations(map[string]string{"solr.apache.org/solrXmlMd5":
fmt.Sprintf("%x", md5.Sum([]byte(configMap.Data["solr.xml"])))},
testPodAnnotations), statefulSet.Spec.Template.Annotations)
testMapsEqual(t, "pod node selectors", testNodeSelectors,
statefulSet.Spec.Template.Spec.NodeSelector)
testPodProbe(t, testProbeLivenessNonDefaults,
statefulSet.Spec.Template.Spec.Containers[0].LivenessProbe)
diff --git a/controllers/util/solr_update_util.go
b/controllers/util/solr_update_util.go
index ba441d2..a825d26 100644
--- a/controllers/util/solr_update_util.go
+++ b/controllers/util/solr_update_util.go
@@ -22,17 +22,68 @@ import (
solr "github.com/apache/solr-operator/api/v1beta1"
"github.com/apache/solr-operator/controllers/util/solr_api"
"github.com/go-logr/logr"
+ cron "github.com/robfig/cron/v3"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"net/url"
"sort"
+ "time"
)
const (
DefaultMaxPodsUnavailable = "25%"
DefaultMaxShardReplicasUnavailable = 1
+
+ SolrScheduledRestartAnnotation = "solr.apache.org/nextScheduledRestart"
)
+func ScheduleNextRestart(restartSchedule string, podTemplateAnnotations
map[string]string) (nextRestart string, reconcileWaitDuration *time.Duration,
err error) {
+ return scheduleNextRestartWithTime(restartSchedule,
podTemplateAnnotations, time.Now())
+}
+
+func scheduleNextRestartWithTime(restartSchedule string,
podTemplateAnnotations map[string]string, currentTime time.Time) (nextRestart
string, reconcileWaitDuration *time.Duration, err error) {
+ lastScheduledTime := currentTime.UTC()
+ if restartSchedule == "" {
+ return
+ }
+ scheduledTime, hasScheduled :=
podTemplateAnnotations[SolrScheduledRestartAnnotation]
+
+ scheduleNextRestart := false
+
+ if hasScheduled {
+ parsedScheduledTime, parseErr := time.Parse(time.RFC3339,
scheduledTime)
+ if parseErr != nil {
+ // If the scheduled time cannot be parsed, then go
ahead and create a new time.
+ scheduleNextRestart = true
+ } else {
+ parsedScheduledTime = parsedScheduledTime.UTC()
+ if parsedScheduledTime.Before(currentTime) {
+ // If the already-scheduled time is passed,
then schedule a new one.
+ scheduleNextRestart = true
+ lastScheduledTime = parsedScheduledTime
+ } else {
+ // If the already-scheduled time is in the
future, re-reconcile at that time
+ reconcileWaitDurationTmp :=
parsedScheduledTime.Sub(currentTime)
+ reconcileWaitDuration =
&reconcileWaitDurationTmp
+ }
+ }
+ } else {
+ scheduleNextRestart = true
+ }
+
+ if scheduleNextRestart {
+ if parsedSchedule, parseErr :=
cron.ParseStandard(restartSchedule); parseErr != nil {
+ err = parseErr
+ } else {
+ nextRestartTime :=
parsedSchedule.Next(lastScheduledTime)
+ nextRestart =
parsedSchedule.Next(lastScheduledTime).Format(time.RFC3339)
+ reconcileWaitDurationTmp :=
nextRestartTime.Sub(currentTime)
+ reconcileWaitDuration = &reconcileWaitDurationTmp
+ }
+ }
+ return
+}
+
// DeterminePodsSafeToUpdate takes a list of solr Pods and returns a list of
pods that are safe to upgrade now.
// This function MUST be idempotent and return the same list of pods given the
same kubernetes/solr state.
//
diff --git a/controllers/util/solr_update_util_test.go
b/controllers/util/solr_update_util_test.go
index cd799cc..76c3f61 100644
--- a/controllers/util/solr_update_util_test.go
+++ b/controllers/util/solr_update_util_test.go
@@ -26,6 +26,7 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
"strconv"
"testing"
+ "time"
)
func TestPickPodsToUpgrade(t *testing.T) {
@@ -944,3 +945,54 @@ func getPodNames(pods []corev1.Pod) []string {
}
return names
}
+
+func TestScheduleNextRestart(t *testing.T) {
+ var schedule, nextRestart string
+ var lastRestart time.Time
+ var reconcileWaitDuration *time.Duration
+ var err error
+ now := time.Date(2020, 8, 10, 20, 10, 22, 0, time.Local)
+ utcNow := now.UTC()
+
+ // Test that no restart should happen
+ nextRestart, reconcileWaitDuration, err =
scheduleNextRestartWithTime(schedule, map[string]string{}, now)
+ assert.Empty(t, nextRestart, "There should be no restart when the
schedule is blank")
+ assert.Nil(t, reconcileWaitDuration, "There should be no reconcile wait
when the schedule is blank")
+ assert.Empty(t, err, "There should be no error when the schedule is
blank")
+
+ // Test a bad schedule string
+ schedule = "adasfdsdas"
+ nextRestart, reconcileWaitDuration, err =
scheduleNextRestartWithTime(schedule, map[string]string{}, now)
+ assert.Empty(t, nextRestart, "There should be no restart when the
schedule is blank")
+ assert.Nil(t, reconcileWaitDuration, "There should be no reconcile wait
when the schedule is blank")
+ assert.Error(t, err, "There should be a parsing error for a bad
schedule")
+
+ // Test first restart
+ schedule = "@every 10m"
+ nextRestart, reconcileWaitDuration, err =
scheduleNextRestartWithTime(schedule, map[string]string{}, now)
+ assert.EqualValuesf(t, utcNow.Add(time.Minute*10).Format(time.RFC3339),
nextRestart, "The restart is incorrect for schedule: %s", schedule)
+ if assert.NotNil(t, reconcileWaitDuration, "There should be a reconcile
wait when there is a non-empty schedule") {
+ assert.EqualValues(t, time.Minute*10, *reconcileWaitDuration,
"The reconcile wait is incorrect for the first scheduled restart")
+ }
+ assert.Emptyf(t, err, "There should be no error when the schedule is:
%s", schedule)
+
+ // Test new restart scheduled
+ schedule = "@every 10m"
+ lastRestart = utcNow.Add(time.Minute * -1)
+ nextRestart, reconcileWaitDuration, err =
scheduleNextRestartWithTime(schedule,
map[string]string{SolrScheduledRestartAnnotation:
lastRestart.Format(time.RFC3339)}, now)
+ assert.EqualValuesf(t, utcNow.Add(time.Minute*9).Format(time.RFC3339),
nextRestart, "The new next restart time is incorrect for previous nextRestart
at \"%s\" and schedule: %s", lastRestart.Format(time.RFC3339), schedule)
+ if assert.NotNil(t, reconcileWaitDuration, "There should be a reconcile
wait when there is a non-empty schedule") {
+ assert.EqualValuesf(t, time.Minute*9, *reconcileWaitDuration,
"The reconcile wait is incorrect for a next restart at \"%s\" and a current
time of \"%s\"", nextRestart, now)
+ }
+ assert.Emptyf(t, err, "There should be no error when the schedule is:
%s", schedule)
+
+ // Test new restart scheduled
+ schedule = "@every 10m"
+ lastRestart = utcNow.Add(time.Minute * 6)
+ nextRestart, reconcileWaitDuration, err =
scheduleNextRestartWithTime(schedule,
map[string]string{SolrScheduledRestartAnnotation:
lastRestart.Format(time.RFC3339)}, now)
+ assert.Emptyf(t, nextRestart, "There should be no new restart time when
the nextRestart is in the future: \"%s\"", lastRestart)
+ if assert.NotNil(t, reconcileWaitDuration, "There should be a reconcile
wait when there is a non-empty schedule") {
+ assert.EqualValuesf(t, time.Minute*6, *reconcileWaitDuration,
"The reconcile wait is incorrect for a next restart at \"%s\" and a current
time of \"%s\"", nextRestart, now)
+ }
+ assert.Emptyf(t, err, "There should be no error when the schedule is:
%s", schedule)
+}
diff --git a/dependency_licenses.csv b/dependency_licenses.csv
index a1ff2fc..2252eab 100644
--- a/dependency_licenses.csv
+++ b/dependency_licenses.csv
@@ -27,6 +27,7 @@
github.com/prometheus/client_model/go,https://github.com/prometheus/client_model
github.com/prometheus/common,https://github.com/prometheus/common/blob/master/LICENSE,Apache-2.0
github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg,https://github.com/prometheus/common/blob/master/internal/bitbucket.org/ww/goautoneg/README.txt,BSD-3-Clause
github.com/prometheus/procfs,https://github.com/prometheus/procfs/blob/master/LICENSE,Apache-2.0
+github.com/robfig/cron/v3,https://github.com/robfig/cron/blob/master/v3/LICENSE,MIT
github.com/spf13/pflag,https://github.com/spf13/pflag/blob/master/LICENSE,BSD-3-Clause
go.uber.org/atomic,Unknown,MIT
go.uber.org/multierr,Unknown,MIT
diff --git a/docs/solr-cloud/solr-cloud-crd.md
b/docs/solr-cloud/solr-cloud-crd.md
index 9d0a049..06c6453 100644
--- a/docs/solr-cloud/solr-cloud-crd.md
+++ b/docs/solr-cloud/solr-cloud-crd.md
@@ -58,7 +58,9 @@ Under `SolrCloud.Spec.updateStrategy`:
- **`maxPodsUnavailable`** - (Defaults to `"25%"`) The number of Solr pods
in a Solr Cloud that are allowed to be unavailable during the rolling restart.
More pods may become unavailable during the restart, however the Solr
Operator will not kill pods if the limit has already been reached.
- **`maxShardReplicasUnavailable`** - (Defaults to `1`) The number of
replicas for each shard allowed to be unavailable during the restart.
-
+- **`restartSchedule`** - A [CRON](https://en.wikipedia.org/wiki/Cron)
schedule for automatically restarting the Solr Cloud.
+ [Multiple CRON
syntaxes](https://pkg.go.dev/github.com/robfig/cron/v3?utm_source=godoc#hdr-CRON_Expression_Format)
are supported, such as intervals (e.g. `@every 10h`) or predefined schedules
(e.g. `@yearly`, `@weekly`, etc.).
+
**Note:** Both `maxPodsUnavailable` and `maxShardReplicasUnavailable` are
intOrString fields. So either an int or string can be provided for the field.
- **int** - The parameter is treated as an absolute value, unless the value is
<= 0 which is interpreted as unlimited.
- **string** - Only percentage string values (`"0%"` - `"100%"`) are accepted,
all other values will be ignored.
diff --git a/go.mod b/go.mod
index c9de22b..7abb01e 100644
--- a/go.mod
+++ b/go.mod
@@ -11,6 +11,7 @@ require (
github.com/kr/pretty v0.2.1 // indirect
github.com/onsi/gomega v1.10.1
github.com/pravega/zookeeper-operator v0.2.9
+ github.com/robfig/cron/v3 v3.0.1
github.com/stretchr/testify v1.6.1
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b
golang.org/x/tools v0.0.0-20200616195046-dc31b401abb5 // indirect
diff --git a/go.sum b/go.sum
index 9fc2b2e..de0e5eb 100644
--- a/go.sum
+++ b/go.sum
@@ -766,7 +766,10 @@ github.com/prometheus/prometheus
v2.3.2+incompatible/go.mod h1:oAIUtOny2rjMX0OWN
github.com/prometheus/tsdb v0.7.1/go.mod
h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod
h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod
h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
+github.com/robfig/cron v0.0.0-20170526150127-736158dc09e1
h1:NZInwlJPD/G44mJDgBEMFvBfbv/QQKCrpo+az/QXn8c=
github.com/robfig/cron v0.0.0-20170526150127-736158dc09e1/go.mod
h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
+github.com/robfig/cron/v3 v3.0.1
h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
+github.com/robfig/cron/v3 v3.0.1/go.mod
h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod
h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod
h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod
h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
diff --git a/helm/solr-operator/Chart.yaml b/helm/solr-operator/Chart.yaml
index 85e7114..2b951c9 100644
--- a/helm/solr-operator/Chart.yaml
+++ b/helm/solr-operator/Chart.yaml
@@ -55,15 +55,12 @@ annotations:
# Allowed syntax is described at:
https://artifacthub.io/docs/topics/annotations/helm/#example
artifacthub.io/changes: |
- kind: added
- description: Addition 1
+ description: Ability to schedule automatic restarts
links:
- name: Github Issue
- url: https://github.com/issue-url
- - kind: changed
- description: Change 2
- links:
+ url: https://github.com/apache/solr-operator/issues/281
- name: Github PR
- url: https://github.com/pr-url
+ url: https://github.com/apache/solr-operator/pull/279
artifacthub.io/images: |
- name: solr-operator
image: apache/solr-operator:v0.4.0-prerelease
diff --git a/helm/solr-operator/crds/crds.yaml
b/helm/solr-operator/crds/crds.yaml
index 105a28b..0a9eca6 100644
--- a/helm/solr-operator/crds/crds.yaml
+++ b/helm/solr-operator/crds/crds.yaml
@@ -5795,6 +5795,9 @@ spec:
- StatefulSet
- Manual
type: string
+ restartSchedule:
+ description: "Perform a scheduled restart on the given
schedule, in CRON format. \n Multiple CRON syntaxes are supported - Standard
CRON (e.g. \"CRON_TZ=Asia/Seoul 0 6 * * ?\") - Predefined Schedules (e.g.
\"@yearly\", \"@weekly\", etc.) - Intervals (e.g. \"@every 10h30m\") \n For
more information please check this reference:
https://pkg.go.dev/github.com/robfig/cron/v3?utm_source=godoc#hdr-CRON_Expression_Format"
+ type: string
type: object
zookeeperRef:
description: The information for the Zookeeper this SolrCloud
should connect to Can be a zookeeper that is running, or one that is created by
the solr operator
diff --git a/helm/solr/README.md b/helm/solr/README.md
index 001cf5f..94c8938 100644
--- a/helm/solr/README.md
+++ b/helm/solr/README.md
@@ -41,7 +41,7 @@ To install the Solr Operator for the first time in your
cluster, you can use the
helm install example apache-solr/solr --version 0.4.0-prerelease --set
image.tag=8.8.0
```
-The command deploys the a SolrCloud object on the Kubernetes cluster with the
default configuration.
+The command deploys a SolrCloud object on the Kubernetes cluster with the
default configuration.
The [Solr Operator](https://solr.apache.org/operator) is then in charge of
creating the necessary Kubernetes resources to run that Solr Cloud.
The [configuration](#chart-values) section lists the parameters that can be
configured during installation.
@@ -96,6 +96,7 @@ The command removes the SolrCloud resource, and then
Kubernetes will garbage col
| updateStrategy.method | string | `"Managed"` | The method for conducting
updates of Solr pods. Either `Managed`, `StatefulSet` or `Manual`. See the
[docs](https://apache.github.io/solr-operator/docs/solr-cloud/solr-cloud-crd.html#update-strategy)
for more information |
| updateStrategy.managedUpdate.maxPodsUnavailable | int-or-string | `"25%"` |
The number of Solr pods in a Solr Cloud that are allowed to be unavailable
during the rolling restart. Either a static number, or a percentage
representing the percentage of total pods requested for the statefulSet. |
| updateStrategy.managedUpdate.maxShardReplicasUnavailable | int-or-string |
`1` | The number of replicas for each shard allowed to be unavailable during
the restart. Either a static number, or a percentage representing the
percentage of the number of replicas for a shard. |
+| updateStrategy.restartSchedule | [string
(CRON)](https://pkg.go.dev/github.com/robfig/cron/v3?utm_source=godoc#hdr-CRON_Expression_Format)
| | A CRON schedule for automatically restarting the Solr Cloud. [Refer
here](https://pkg.go.dev/github.com/robfig/cron/v3?utm_source=godoc#hdr-CRON_Expression_Format)
for all possible CRON syntaxes accepted. |
### Data Storage Options
diff --git a/helm/solr/templates/solrcloud.yaml
b/helm/solr/templates/solrcloud.yaml
index b4efce1..ce001a9 100644
--- a/helm/solr/templates/solrcloud.yaml
+++ b/helm/solr/templates/solrcloud.yaml
@@ -92,7 +92,16 @@ spec:
{{- if .Values.updateStrategy }}
updateStrategy:
- {{- toYaml .Values.updateStrategy | nindent 4 }}
+ {{- if .Values.updateStrategy.method }}
+ method: {{ .Values.updateStrategy.method }}
+ {{- end }}
+ {{- if .Values.updateStrategy.managed }}
+ managed:
+ {{- toYaml .Values.updateStrategy.managed | nindent 6 }}
+ {{- end }}
+ {{- if .Values.updateStrategy.restartSchedule }}
+ restartSchedule: {{ .Values.updateStrategy.restartSchedule | quote }}
+ {{- end }}
{{- end }}
{{- if .Values.dataStorage }}
diff --git a/helm/solr/values.yaml b/helm/solr/values.yaml
index d29f46e..bb80840 100644
--- a/helm/solr/values.yaml
+++ b/helm/solr/values.yaml
@@ -86,6 +86,9 @@ updateStrategy:
# Either a static number, or a percentage representing the percentage of
the number of replicas for a shard.
# Defaults to 1
# maxShardReplicasUnavailable: 1
+ # Cron schedule for automatically restarting the Solr Cloud
+ # For available CRON syntaxes, check here:
https://pkg.go.dev/github.com/robfig/cron/v3?utm_source=godoc#hdr-CRON_Expression_Format
+ restartSchedule: ""
# More information can be found at:
#
https://apache.github.io/solr-operator/docs/solr-cloud/solr-cloud-crd.html#data-storage