Skip to content

Commit 29e1896

Browse files
Fix incremental backups for volume repos. (#374)
Add smoke tester for this feature.
1 parent b176b8f commit 29e1896

File tree

7 files changed

+97
-13
lines changed

7 files changed

+97
-13
lines changed

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,16 @@ SHELL = /usr/bin/env bash -o pipefail
4848

4949
all: generate
5050

51-
.PHONY: version tag
51+
.PHONY: version tag git-sha
5252
version:
5353
@echo $(VERSION)
5454

5555
tag:
5656
@echo $(TAG)
5757

58+
git-sha:
59+
@echo $(GIT_SHA)
60+
5861
##@ General
5962

6063
# The help target prints out all targets with their descriptions organized

controllers/util/backup_util.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ func EnsureDirectoryForBackup(solrCloud *solr.SolrCloud, backupRepository *solr.
150150
return RunExecForPod(
151151
solrCloud.GetAllSolrPodNames()[0],
152152
solrCloud.Namespace,
153-
[]string{"/bin/bash", "-c", "rm -rf " + backupPath + " && mkdir -p " + backupPath},
153+
[]string{"/bin/bash", "-c", "mkdir -p " + backupPath},
154154
config,
155155
)
156156
}

hack/release/smoke_test/smoke_test.sh

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ set -u
2323

2424
show_help() {
2525
cat << EOF
26-
Usage: ./hack/release/smoke_test/smoke_test.sh [-h] [-i IMAGE] [-s GIT_SHA] [-k KUBERNETES_VERSION] -v VERSION -l LOCATION -g GPG_KEY
26+
Usage: ./hack/release/smoke_test/smoke_test.sh [-h] [-i IMAGE] [-s GIT_SHA] [-k KUBERNETES_VERSION] [-t SOLR_VERSION] -v VERSION -l LOCATION -g GPG_KEY
2727
2828
Smoke test the Solr Operator release artifacts.
2929
@@ -34,11 +34,12 @@ Smoke test the Solr Operator release artifacts.
3434
-l Base location of the staged artifacts. Can be a URL or relative or absolute file path.
3535
-g GPG Key (fingerprint) used to sign the artifacts
3636
-k Kubernetes Version to test with (Optional, defaults to a compatible version)
37+
-t Solr Version to test with (Optional, defaults to a compatible version)
3738
EOF
3839
}
3940

4041
OPTIND=1
41-
while getopts hv:i:l:s:g:k: opt; do
42+
while getopts hv:i:l:s:g:k:t: opt; do
4243
case $opt in
4344
h)
4445
show_help
@@ -56,6 +57,8 @@ while getopts hv:i:l:s:g:k: opt; do
5657
;;
5758
k) KUBERNETES_VERSION=$OPTARG
5859
;;
60+
t) SOLR_VERSION=$OPTARG
61+
;;
5962
*)
6063
show_help >&2
6164
exit 1
@@ -79,6 +82,9 @@ fi
7982
if [[ -n "${KUBERNETES_VERSION:-}" ]]; then
8083
export KUBERNETES_VERSION="${KUBERNETES_VERSION}"
8184
fi
85+
if [[ -n "${SOLR_VERSION:-}" ]]; then
86+
export SOLR_VERSION="${SOLR_VERSION}"
87+
fi
8288

8389
PULL_PASS_THROUGH=""
8490
# If LOCATION is a URL, we want to pull the Docker image

hack/release/smoke_test/test_cluster.sh

Lines changed: 79 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ set -u
2323

2424
show_help() {
2525
cat << EOF
26-
Usage: ./hack/release/smoke_test/test_cluster.sh [-h] [-i IMAGE] [-k KUBERNETES_VERSION] -v VERSION -l LOCATION -g GPG_KEY
26+
Usage: ./hack/release/smoke_test/test_cluster.sh [-h] [-i IMAGE] [-k KUBERNETES_VERSION] [-t SOLR_VERSION] -v VERSION -l LOCATION -g GPG_KEY
2727
2828
Test the release candidate in a Kind cluster
2929
@@ -33,11 +33,12 @@ Test the release candidate in a Kind cluster
3333
-l Base location of the staged artifacts. Can be a URL or relative or absolute file path.
3434
-g GPG Key (fingerprint) used to sign the artifacts
3535
-k Kubernetes Version to test with (full tag, e.g. v1.21.2)
36+
-t Solr Version, or image, to test with (full tag, e.g. 8.10.0)
3637
EOF
3738
}
3839

3940
OPTIND=1
40-
while getopts hv:i:l:g:k: opt; do
41+
while getopts hv:i:l:g:k:t: opt; do
4142
case $opt in
4243
h)
4344
show_help
@@ -53,6 +54,8 @@ while getopts hv:i:l:g:k: opt; do
5354
;;
5455
k) KUBERNETES_VERSION=$OPTARG
5556
;;
57+
t) SOLR_VERSION=$OPTARG
58+
;;
5659
*)
5760
show_help >&2
5861
exit 1
@@ -76,6 +79,9 @@ fi
7679
if [[ -z "${KUBERNETES_VERSION:-}" ]]; then
7780
KUBERNETES_VERSION="v1.21.2"
7881
fi
82+
if [[ -z "${SOLR_VERSION:-}" ]]; then
83+
SOLR_VERSION="8.10.0"
84+
fi
7985

8086
# If LOCATION is not a URL, then get the absolute path
8187
if ! (echo "${LOCATION}" | grep "http"); then
@@ -114,6 +120,9 @@ kind create cluster --name "${CLUSTER_NAME}" --image "kindest/node:${KUBERNETES_
114120
# Load the docker image into the cluster
115121
kind load docker-image --name "${CLUSTER_NAME}" "${IMAGE}"
116122

123+
# Add a temporary directory for backups
124+
docker exec "${CLUSTER_NAME}-control-plane" bash -c "mkdir -p /tmp/backup"
125+
117126
echo "Import Solr Keys"
118127
curl -sL0 "https://dist.apache.org/repos/dist/release/solr/KEYS" | gpg --import --quiet
119128

@@ -131,13 +140,20 @@ helm install --kube-context "${KUBE_CONTEXT}" --verify solr-operator "${OP_HELM_
131140
printf "\nInstall a test Solr Cluster\n"
132141
helm install --kube-context "${KUBE_CONTEXT}" --verify example "${SOLR_HELM_CHART}" \
133142
--set replicas=3 \
134-
--set solrImage.tag=8.9.0 \
143+
--set image.tag=${SOLR_VERSION} \
135144
--set solrJavaMem="-Xms1g -Xmx3g" \
136145
--set customSolrKubeOptions.podOptions.resources.limits.memory="1G" \
137146
--set customSolrKubeOptions.podOptions.resources.requests.cpu="300m" \
138147
--set customSolrKubeOptions.podOptions.resources.requests.memory="512Mi" \
139148
--set zookeeperRef.provided.persistence.spec.resources.requests.storage="5Gi" \
140-
--set zookeeperRef.provided.replicas=1
149+
--set zookeeperRef.provided.replicas=1 \
150+
--set "backupRepositories[0].name=local" \
151+
--set "backupRepositories[0].volume.source.hostPath.path=/tmp/backup"
152+
153+
# If LOCATION is a URL, then remove the helm repo after use
154+
if (echo "${LOCATION}" | grep "http"); then
155+
helm repo remove "apache-solr-test-${VERSION}"
156+
fi
141157

142158
# Wait for solrcloud to be ready
143159
printf '\nWait for all 3 Solr nodes to become ready.\n\n'
@@ -156,6 +172,23 @@ curl --silent "http://localhost:18983/solr/admin/collections?action=CREATE&name=
156172
printf "\nQuery the test collection, test for 0 docs\n"
157173
curl --silent "http://localhost:18983/solr/smoke-test/select" | grep '\"numFound\":0' > /dev/null
158174

175+
printf "\nCreate a Solr Backup to take local backups of the test collection\n"
176+
cat <<EOF | kubectl apply -f -
177+
apiVersion: solr.apache.org/v1beta1
178+
kind: SolrBackup
179+
metadata:
180+
name: ex-back
181+
spec:
182+
solrCloud: example
183+
collections:
184+
- smoke-test
185+
location: test-dir/
186+
repositoryName: local
187+
recurrence:
188+
schedule: "@every 10s"
189+
maxSaved: 3
190+
EOF
191+
159192
printf "\nCreate a Solr Prometheus Exporter to expose metrics for the Solr Cloud\n"
160193
cat <<EOF | kubectl apply -f -
161194
apiVersion: solr.apache.org/v1beta1
@@ -182,9 +215,48 @@ sleep 15
182215
printf "\nQuery the prometheus exporter, test for 'http://example-solrcloud-*.example-solrcloud-headless.default:8983/solr' (internal) URL being scraped.\n"
183216
curl --silent "http://localhost:18984/metrics" | grep 'http://example-solrcloud-.*.example-solrcloud-headless.default:8983/solr' > /dev/null
184217

185-
# If LOCATION is a URL, then remove the helm repo at the end
186-
if (echo "${LOCATION}" | grep "http"); then
187-
helm repo remove "apache-solr-test-${VERSION}"
218+
printf "\nWait 20 seconds, so that more backups can be taken.\n"
219+
sleep 20
220+
221+
printf "\nList the backups, and make sure that >= 3 have been taken (should be four), but only 3 are saved.\n"
222+
BACKUP_RESP=$(curl --silent -L "http://localhost:18983/solr/admin/collections?action=LISTBACKUP&name=ex-back-smoke-test&repository=local&collection=smoke-test&location=/var/solr/data/backup-restore/local/test-dir")
223+
SAVED_BACKUPS=$(echo "${BACKUP_RESP}" | jq --raw-output '.backups | length')
224+
if [[ "${SAVED_BACKUPS}" != "3" ]]; then
225+
echo "Wrong number of saved backups, should be 3, found ${SAVED_BACKUPS}" >&2
226+
exit 1
227+
fi
228+
LAST_BACKUP_ID=$(echo "${BACKUP_RESP}" | jq --raw-output '.backups[-1].backupId')
229+
if (( "${LAST_BACKUP_ID}" < 4 )); then
230+
echo "The last backup id must be > 3, since we should have taken at least 4 backups. Last backup id found: ${LAST_BACKUP_ID}" >&2
231+
exit 1
232+
fi
233+
234+
printf "\nStop recurring backup\n"
235+
cat <<EOF | kubectl apply -f -
236+
apiVersion: solr.apache.org/v1beta1
237+
kind: SolrBackup
238+
metadata:
239+
name: ex-back
240+
spec:
241+
solrCloud: example
242+
collections:
243+
- smoke-test
244+
location: test-dir/
245+
repositoryName: local
246+
recurrence:
247+
schedule: "@every 10s"
248+
maxSaved: 3
249+
disabled: true
250+
EOF
251+
sleep 5
252+
LAST_BACKUP_ID=$(curl --silent -L "http://localhost:18983/solr/admin/collections?action=LISTBACKUP&name=ex-back-smoke-test&repository=local&collection=smoke-test&location=/var/solr/data/backup-restore/local/test-dir" | jq --raw-output '.backups[-1].backupId')
253+
254+
printf "\nWait to make sure more backups are not taken\n"
255+
sleep 15
256+
FOUND_BACKUP_ID=$(curl --silent -L "http://localhost:18983/solr/admin/collections?action=LISTBACKUP&name=ex-back-smoke-test&repository=local&collection=smoke-test&location=/var/solr/data/backup-restore/local/test-dir" | jq --raw-output '.backups[-1].backupId')
257+
if (( "${FOUND_BACKUP_ID}" != "${LAST_BACKUP_ID}" )); then
258+
echo "The another backup has been taken since recurrence was stopped. Last backupId should be '${LAST_BACKUP_ID}', but instead found '${FOUND_BACKUP_ID}'." >&2
259+
exit 1
188260
fi
189261

190262
echo "Delete test Kind Kubernetes cluster."

hack/release/smoke_test/test_source.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ echo "Download source artifact, verify and run 'make check'"
9191
# Check the version
9292
FOUND_VERSION=$(make version)
9393
if [[ "$FOUND_VERSION" != "${VERSION}" ]]; then
94-
error "Version in source release should be ${VERSION}, but found ${FOUND_VERSION}"
94+
echo "Version in source release should be ${VERSION}, but found ${FOUND_VERSION}" >&2
9595
exit 1
9696
fi
9797

hack/release/wizard/releaseWizard.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -891,9 +891,12 @@ groups:
891891
-l 'https://dist.apache.org/repos/dist/dev/solr/solr-operator/{{ build_rc.rc_folder | default("<rc_folder>", True) }}'
892892
893893
If you want to run the smoke test with a specific version of kubernetes, use the -k option with a full version tag. (e.g. -k v1.19.3)
894+
If you want to run the smoke test with a custom version of solr, use the -t option with an official Solr image version. (e.g. -t 8.10.0)
895+
However, for this smoke test, you must use a solr version that supports incremental backups. (i.e. 8.9+)
894896
895897
Make sure you have the following installed before running the smoke test:
896898
- Docker (Give it enough memory and CPU to run ~12 containers, 3 of which are Solr nodes)
899+
More information on required resources can be found here: https://kind.sigs.k8s.io/docs/user/quick-start/#settings-for-docker-desktop
897900
- Go 1.16
898901
- Kubectl
899902
- GnuPG

helm/solr/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ Descriptions on how to use these options can be found in the [SolrCloud document
108108
| 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. |
109109
| serviceAccount.create | boolean | `false` | Create a serviceAccount to be used for all pods being deployed (Solr & ZK). If `serviceAccount.name` is not specified, the full name of the deployment will be used. |
110110
| serviceAccount.name | string | | The optional default service account used for Solr and ZK unless overridden below. If `serviceAccount.create` is set to `false`, this serviceAccount must exist in the target namespace. |
111-
| backupRepositories | []object | | A list of BackupRepositories to connect your SolrCloud to. Visit https://apache.github.io/solr-operator/docs/solr-backup or run `kubectl explain solrcloud.spec.backupRepositories` to see the available options. |
111+
| backupRepositories | []object | | A list of BackupRepositories to connect your SolrCloud to. Visit the [SolrBackup docs](https://apache.github.io/solr-operator/docs/solr-backup) or run `kubectl explain solrcloud.spec.backupRepositories` to see the available options. |
112112

113113
### Data Storage Options
114114

0 commit comments

Comments
 (0)