From 03ab5713d7b984e69c661bc666b38d6d1057db90 Mon Sep 17 00:00:00 2001 From: Karl Baker Date: Wed, 15 Dec 2021 11:13:46 +0000 Subject: [PATCH 1/2] Define replica set config for MongoDB 2.6 This commit adds a definition for the replica set config to use for MongoDB 2.6. Previously in this repo we initialised a replica set without specifying any config, which has the effect of creating a config using the container id of said container running MongoDB 2.6. The issue here is that this replica set config is persisted to the `govuk-docker_mongo-2.6` volume, meaning that when the current container is eventually removed and a new container created to run MongoDB 2.6 the replica set won't be properly provisioned as it references the wrong container id. To get around this problem in govuk-docker, this commit specifies the replica set config to use during initialisation and uses the name of the container to route to, rather than the container id; through this change, the replica set config can remain persisted in the associated volume whilst containers come and go, all whilst enabling these new instances to take part in the replica set. This isn't a problem with MongoDB 2.6 in production as we're not running it in containers. For clarity, the replica set is used by Router to poll for updates to Routes, using the `optime` property from `rs.status()` to determine if it holds an up-to-date copy of routes; for more context [see this commit](https://github.com/alphagov/router/commit/678ef634657885e4eb552954ef89dcc29b47193c) and [RFC](https://github.com/alphagov/govuk-rfcs/blob/main/rfc-135-updating-routes-in-router.md). --- projects/router/Makefile | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/projects/router/Makefile b/projects/router/Makefile index cf124a22..4c704420 100644 --- a/projects/router/Makefile +++ b/projects/router/Makefile @@ -1,4 +1,13 @@ router: clone-router $(GOVUK_DOCKER) up -d mongo-2.6 - $(GOVUK_DOCKER) exec mongo-2.6 mongo --eval "rs.initiate()" + $(GOVUK_DOCKER) exec mongo-2.6 mongo --eval 'rs.initiate({ \ + "_id" : "mongo-replica-set", \ + "version" : 1, \ + "members" : [ \ + { \ + "_id" : 0, \ + "host" : "mongo-2.6:27017" \ + } \ + ]\ + }).ok || rs.status().ok' $(GOVUK_DOCKER) run $@-lite make build From f94325619b6a95f426b23febb67ac5d48b4bf356 Mon Sep 17 00:00:00 2001 From: Karl Baker Date: Wed, 15 Dec 2021 10:36:50 +0000 Subject: [PATCH 2/2] Update `replicate-mongodb.sh` script for Router database This commit updates the `replicate-mongodb.sh` script to work for the `router` and `draft-router` databases. Specifically, Router uses MongoDB 2.6, but the replication script previously made no provision for this and so wouldn't have worked for these databases. When restoring a back-up of either `router` or `draft-router` using MongoDB 2.6, a `sleep 60` has been added to allow for the replica set to properly initialise, as described by MongoDB when you run `rs.initiate()`; whilst I can't find any documentation related to this on the MongoDB docs, there are references to it elsewhere (see [here](https://medium.com/@ManagedKube/deploy-a-mongodb-cluster-in-steps-9-using-docker-49205e231319) and [here](https://www.ceondo.com/notes/mongodb/)). --- bin/replicate-mongodb.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/bin/replicate-mongodb.sh b/bin/replicate-mongodb.sh index 452d11d8..1470b39b 100755 --- a/bin/replicate-mongodb.sh +++ b/bin/replicate-mongodb.sh @@ -13,6 +13,8 @@ replication_dir="${GOVUK_DOCKER_REPLICATION_DIR:-${GOVUK_DOCKER_DIR:-${GOVUK_ROO bucket="govuk-integration-database-backups" +mongo_version=3.6 + case "$app" in "authenticating-proxy") hostname=router_backend @@ -21,6 +23,8 @@ case "$app" in "router"|"draft-router") hostname=router_backend database="${app//-/_}" + mongo_version=2.6 + wait_for_rs=1 ;; "asset-manager") hostname=mongo @@ -67,12 +71,18 @@ pv "$archive_path" | gunzip | tar -zx -f - -C "$extract_path" "var/lib/mongodb/b echo "stopping running govuk-docker containers..." govuk-docker down -container=$(govuk-docker run -d --rm -v "${extract_path}:/replication" mongo-3.6 | tail -n1) +container=$(govuk-docker run -d --rm -v "${extract_path}:/replication" --name "mongo-${mongo_version}" mongo-${mongo_version} | tail -n1) # we want $container to be expanded now # shellcheck disable=SC2064 trap "docker stop '$container'" EXIT echo "waiting for mongo..." + +if [[ -n "${wait_for_rs:-}" ]]; then + echo "Sleeping for 60s to allow replica set initialisation..." + sleep 60 +fi + until docker exec "$container" mongo --eval 1 &>/dev/null; do sleep 1 done