From a157672c5675161833f9b61bb9952289294b56fe Mon Sep 17 00:00:00 2001 From: Tim McCormack Date: Wed, 4 Oct 2023 19:08:39 +0000 Subject: [PATCH] feat: Add util for waiting for container startup; use in dbcopyall8 `make dev.dbcopyall8` doesn't work unless the mysql containers have been started and are ready to run. This is not the only place we need to wait for a functional check on a container, so in this commit I've gone ahead and started a utility for doing so. This first pass only supports MySQL, but we should at least add Mongo as well, as that's also needed in one of the provisioning scripts. Also, I've moved the _db_copy8_targets from being an order-only prerequisite to being a recursive make call. I'm not sure why the order-only syntax was in use here, but in any case I needed to add in a script call before those targets were called, so it's likely moot. --- Makefile | 5 ++++- provision.sh | 26 ++++---------------------- wait-ready.sh | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 23 deletions(-) create mode 100755 wait-ready.sh diff --git a/Makefile b/Makefile index 82e180c3a35..d503eb83b06 100644 --- a/Makefile +++ b/Makefile @@ -461,7 +461,10 @@ dev.dbshell: DB_NAMES_LIST = credentials discovery ecommerce notes registrar xqueue edxapp edxapp_csmh dashboard analytics-api reports reports_v1 _db_copy8_targets = $(addprefix dev.dbcopy8.,$(DB_NAMES_LIST)) -dev.dbcopyall8: | $(_db_copy8_targets) ## Copy data from old mysql 5.7 containers into new mysql8 dbs +dev.dbcopyall8: ## Copy data from old mysql 5.7 containers into new mysql8 dbs + $(MAKE) dev.up.mysql57+mysql80 + ./wait-ready.sh mysql57 mysql80 + $(MAKE) $(_db_copy8_targets) dev.dbcopy8.%: ## Copy data from old mysql 5.7 container into a new 8 db docker compose exec mysql57 bash -c "mysqldump $*" > .dev/$*.sql diff --git a/provision.sh b/provision.sh index e22c97f670d..0f8eb24f05b 100755 --- a/provision.sh +++ b/provision.sh @@ -130,40 +130,22 @@ fi # Ensure the MySQL5 server is online and usable echo "${GREEN}Waiting for MySQL 5.7.${NC}" -until docker compose exec -T mysql57 bash -e -c "mysql -uroot -se \"SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = 'root')\"" &> /dev/null -do - printf "." - sleep 1 -done +./wait-ready.sh mysql57 # Ensure the MySQL8 server is online and usable echo "${GREEN}Waiting for MySQL 8.0.${NC}" -until docker compose exec -T mysql80 bash -e -c "mysql -uroot -se \"SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = 'root')\"" &> /dev/null -do - printf "." - sleep 1 -done +./wait-ready.sh mysql80 # In the event of a fresh MySQL container, wait a few seconds for the server to restart # See https://github.com/docker-library/mysql/issues/245 for why this is necessary. sleep 10 echo "${GREEN}Waiting for MySQL 5.7 to restart.${NC}" -until docker compose exec -T mysql57 bash -e -c "mysql -uroot -se \"SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = 'root')\"" &> /dev/null -do - printf "." - sleep 1 -done - +./wait-ready.sh mysql57 echo -e "${GREEN}MySQL5 ready.${NC}" echo "${GREEN}Waiting for MySQL 8.0 to restart.${NC}" -until docker compose exec -T mysql80 bash -e -c "mysql -uroot -se \"SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = 'root')\"" &> /dev/null -do - printf "." - sleep 1 -done - +./wait-ready.sh mysql80 echo -e "${GREEN}MySQL8 ready.${NC}" # Ensure that the MySQL databases and users are created for all IDAs. diff --git a/wait-ready.sh b/wait-ready.sh new file mode 100755 index 00000000000..1f26c0ef0c1 --- /dev/null +++ b/wait-ready.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# Wait for the listed services to become ready. +# +# This does not start the containers; that should be performed separately +# via `make dev.up` in order to allow for parallel startup. + +set -eu -o pipefail + +function print_usage { + echo "Usage: $0 service1 service2 ..." +} + +if [[ $# == 0 ]]; then + print_usage + exit 0 +fi + +function wait_db { + container_name="$1" + mysql_probe="SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = 'root')" + until docker compose exec -T "$container_name" mysql -uroot -se "$mysql_probe" &> /dev/null; do + printf "." >&2 + sleep 1 + done + echo >&2 "$container_name is ready" +} + + +for service_name in "$@"; do + case "$service_name" in + mysql*) + wait_db "$service_name" + ;; + # TODO: Add other services... + *) + echo >&2 "Unknown service: $service_name" + exit 1 + ;; + esac +done