Skip to content

Commit

Permalink
[#43] Switch to new MariaDB image.
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexSkrypnyk committed Dec 2, 2024
1 parent 4acfded commit 6368bb0
Show file tree
Hide file tree
Showing 10 changed files with 243 additions and 93 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: 2.1

executors:
default:
docker:
docker:
- image: drevops/ci-runner:24.11.0
environment:
BUILDX_VERSION: v0.10.4
Expand Down
5 changes: 4 additions & 1 deletion 9999-mariadb-init.bash
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,10 @@ if [ "$1" = 'mysqld' -a -z "$wantHelp" ]; then
# @note: Added a flag to force upgrade.
if [ "${FORCE_MYSQL_UPGRADE:-}" = "1" ]; then
echo "starting mysql upgrade"
mysql_upgrade --force
# @note: mariadb-upgrade may fail on the first run due to the unresolved
# permissions, but will succeed on the second run.
# @see https://mariadb.com/kb/en/mariadb-upgrade/#
mariadb-upgrade --force || mariadb-upgrade --force
fi

if ! kill -s TERM "$pid" || ! wait "$pid"; then
Expand Down
14 changes: 7 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@
# support setting data directory as an environment variable) to support new
# location and overriding default CMD to include our custom data directory.
#
FROM uselagoon/mariadb-drupal:24.11.0
FROM uselagoon/mariadb-10.11-drupal:24.11.0

# Set the data directory to a different location that a mounted volume.
ENV MARIADB_DATA_DIR=/var/lib/db-data
ENV MARIADB_DATA_DIR=/home/db-data

# Add customised entrypoint script.
COPY 9999-mariadb-init.bash /lagoon/entrypoints/

# Create the custom data directory and set permissions.
USER root

RUN mkdir -p /var/lib/db-data \
&& chown -R mysql /var/lib/db-data \
&& chgrp -R mysql /var/lib/db-data \
&& /bin/fix-permissions /var/lib/db-data
RUN mkdir -p /home/db-data \
&& chown -R mysql:mysql /home/db-data \
&& /bin/fix-permissions /home/db-data

USER mysql

# @todo Try removing the CMD override.
CMD ["mysqld", "--datadir=/var/lib/db-data"]
CMD ["mysqld", "--datadir=/home/db-data"]
13 changes: 4 additions & 9 deletions Dockerfile.seed
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
ARG SEED_IMAGE=drevops/mariadb-drupal-data:latest
ARG BASE_IMAGE=drevops/mariadb-drupal-data:latest

FROM ${SEED_IMAGE}
FROM ${BASE_IMAGE}

# Data directory to copy from.
ARG SRC_DATADIR=.data

COPY ${SRC_DATADIR} /var/lib/db-data/
COPY --chown=mysql:mysql .data /home/db-data/

USER root

RUN chown -R mysql /var/lib/db-data \
&& chgrp -R mysql /var/lib/db-data \
&& /bin/fix-permissions /var/lib/db-data
RUN /bin/fix-permissions /home/db-data

USER mysql
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ captured as a Docker layer and stored as an image to docker registry.
Image consumers download the image and start containers with instantaneously
available data (no time-consuming database imports required).

Technically, majority of the functionality is relying on upstream [`uselagoon/mariadb-drupal`](https://github.com/uselagoon/lagoon-images/blob/main/images/mariadb-drupal/10.6.Dockerfile) Docker image.
Technically, majority of the functionality is relying on upstream [`uselagoon/mariadb-drupal`](https://github.com/uselagoon/lagoon-images/blob/main/images/mariadb-drupal/10.11.Dockerfile) Docker image.
[Entrypoint script](entrypoint.bash) had to be copied from [upstream script](https://github.com/uselagoon/lagoon-images/blob/main/images/mariadb/entrypoints/9999-mariadb-init.bash) and adjusted to support custom data directory.

## Use case
Expand Down Expand Up @@ -80,4 +80,4 @@ This image is built and pushed automatically to DockerHub:
Versions are following versions of the [upstream image](https://hub.docker.com/r/uselagoon/mariadb-drupal/tags) to ease maintenance.

---
Repository created using https://getscaffold.dev/ project scaffold template
_This repository was created using the [Scaffold](https://getscaffold.dev/) project template_
93 changes: 72 additions & 21 deletions seed-db.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
##
# Seed image with a database from file.
#
# The seeding process has 3-phases build:
# 1. Create extracted DB files by starting a temporary container and importing database.
# The seeding process has 3-phases:
# 1. Create extracted DB files by starting a temporary container and importing the database.
# 2. Build a new image from the base image and extracted DB files.
# 3. Start a container from the new image and verify that the database was imported.
#
Expand All @@ -15,7 +15,7 @@
# shellcheck disable=SC2002,SC2015

set -eu
[ -n "${DREVOPS_DEBUG:-}" ] && set -x
[ -n "${DEBUG:-}" ] && set -x

# Database dump file as a first argument to the script.
DB_FILE="${DB_FILE:-$1}"
Expand All @@ -42,11 +42,12 @@ LOG_DIR="${LOG_DIR:-.logs}"
# Temporary data directory on host.
TMP_DATA_DIR="${TMP_DATA_DIR:-.data}"

# Show verbose output.
LOG_IS_VERBOSE="${LOG_IS_VERBOSE:-}"

# ------------------------------------------------------------------------------

# @formatter:off
#info() { printf "%s\n" "$1"; echo;}

info() { [ -z "${TERM_NO_COLOR:-}" ] && tput colors >/dev/null 2>&1 && printf "\n[\033[36mINFO\033[0m] %s\n\n" "$1" || printf "\n[INFO] %s\n" "$1"; }
task() { [ -z "${TERM_NO_COLOR:-}" ] && tput colors >/dev/null 2>&1 && printf "[\033[34mTASK\033[0m] %s\n" "$1" || printf "[TASK] %s\n" "$1"; }
pass() { [ -z "${TERM_NO_COLOR:-}" ] && tput colors >/dev/null 2>&1 && printf "[ \033[32mOK\033[0m ] %s\n" "$1" || printf "[ OK ] %s\n" "$1"; }
Expand All @@ -60,20 +61,61 @@ note() { printf " %s\n" "$1"; }
[ "${BASE_IMAGE##*/}" = "$BASE_IMAGE" ] && fail "${BASE_IMAGE} should be in a format myorg/myimage." && exit 1
[ "${DST_IMAGE##*/}" = "$DST_IMAGE" ] && fail "${DST_IMAGE} should be in a format myorg/myimage." && exit 1

# Collect logs and display them on script exit.
cleanup() {
if [ $? -ne 0 ]; then
fail "Collecting logs after failure."
if [ -d "${LOG_DIR}" ] && [ -z "${LOG_IS_VERBOSE}" ]; then
for log_file in "${LOG_DIR}"/*.log; do
echo
note "--- Displaying ${log_file} ---"
echo
cat "${log_file}"
echo
done
else
note "No logs available to display."
fi
fi
}

trap cleanup EXIT

log_container() {
name="${1?Missing log name}"
prefix=${2:-}

mkdir -p "${LOG_DIR}" >/dev/null
docker logs "${1}" >>"${LOG_DIR}/${2:-}${1}.log" 2>&1
log_file="${LOG_DIR}/${prefix}${name}.log"

if [ -n "${LOG_IS_VERBOSE}" ]; then
docker logs "${1}" | tee -a "${log_file}"
else
docker logs "${1}" &>>"${log_file}"
fi
}

wait_for_db_service() {
cid="${1}"

user=()
[ -n "${2-}" ] && user=("--user=${2}")

echo -n " Waiting for the service to become ready."
docker exec --user 1000 -i "${1}" sh -c "until nc -z localhost 3306; do sleep 1; echo -n .; done; echo"
if ! docker exec "${user[@]}" -i "${cid}" sh -c "until nc -z localhost 3306; do sleep 1; echo -n .; done; echo"; then
fail "MYSQL service did not start successfully."
log_container "${cid}"
return 1
fi
log_container "${cid}"
pass "MYSQL is running."
}

assert_db_system_tables_present() {
if docker exec --user 1000 "${1}" /usr/bin/mysql -e "show tables from information_schema;" | grep -q user_variables; then
user=()
[ -n "${2-}" ] && user=("--user=${2}")

if docker exec "${user[@]}" "${1}" /usr/bin/mysql -e "show tables from information_schema;" | grep -q user_variables; then
pass "Database system tables present."
else
pass "Database system tables are not present in container ${1}"
Expand All @@ -82,7 +124,10 @@ assert_db_system_tables_present() {
}

assert_db_was_imported() {
if docker exec --user 1000 "${1}" /usr/bin/mysql -e "show tables;" | grep -q users; then
user=()
[ -n "${2-}" ] && user=("--user=${2}")

if docker exec "${user[@]}" "${1}" /usr/bin/mysql -e "show tables;" | grep -q users; then
pass "Imported database exists."
else
fail "Imported database does not exist in container ${1}"
Expand All @@ -92,19 +137,25 @@ assert_db_was_imported() {

start_container() {
task "Start container from the image ${1}"
cid=$(docker run -d --rm "${1}" 2>"$LOG_DIR"/container-start.log)

user=()
[ -n "${2-}" ] && user=("--user=${2}")

cid=$(docker run "${user[@]}" -d "${1}" 2>"$LOG_DIR"/container-start.log)
cat "${LOG_DIR}"/container-start.log >>"$LOG_DIR/${cid}.log" && rm "${LOG_DIR}"/container-start.log || true

wait_for_db_service "${cid}" "${2-}"
assert_db_system_tables_present "${cid}" "${2-}"

pass "Started container ${cid}"
wait_for_db_service "${cid}"
assert_db_system_tables_present "${cid}"
}

get_started_container_id() {
docker ps -q --filter ancestor="${1}" --filter status=running | head -n 1
}

stop_container() {
task "Stop and removing container ${1}"
task "Stop and remove container ${1}"
# Log container output before stopping it into a separate log file for debugging.
log_container "${1}" "stopped-"
docker stop "${1}" >/dev/null
Expand Down Expand Up @@ -134,7 +185,7 @@ fi
note "Destination image: ${DST_IMAGE}"
note "Destination platform(s): ${DESTINATION_PLATFORMS}"

info "Stage 1: Produce database structure files from dump"
info "Stage 1: Produce database structure files from dump file"

start_container "${BASE_IMAGE}"
cid="$(get_started_container_id "${BASE_IMAGE}")"
Expand All @@ -152,28 +203,28 @@ assert_db_was_imported "${cid}"
pass "Upgraded database after import."

task "Update permissions on the seeded database files."
docker exec "${cid}" bash -c "chown -R mysql /var/lib/db-data && /bin/fix-permissions /var/lib/db-data" || true
docker exec "${cid}" bash -c "chown -R mysql /home/db-data && /bin/fix-permissions /home/db-data" || true
pass "Updated permissions on the seeded database files."

task "Copy expanded database files to host"
mkdir -p "${TMP_DATA_DIR}"
docker cp "${cid}":/var/lib/db-data/. "${TMP_DATA_DIR}/"
docker cp "${cid}":/home/db-data/. "${TMP_DATA_DIR}/" >/dev/null
[ ! -d "${TMP_DATA_DIR}/mysql" ] && fail "Unable to copy expanded database files to host " && ls -al "${TMP_DATA_DIR}" && exit 1
pass "Copied expanded database files to host"

stop_container "${cid}"

info "Stage 2: Build image"

task "Build image ${DST_IMAGE} for ${DESTINATION_PLATFORMS} platform(s)."
docker buildx build --no-cache --platform "${DESTINATION_PLATFORMS}" --tag "${DST_IMAGE}" --push -f Dockerfile.seed .
pass "Built image ${DST_IMAGE} for ${DESTINATION_PLATFORMS} platform(s)."
task "Build image ${DST_IMAGE} for ${DESTINATION_PLATFORMS} platform(s) from ${BASE_IMAGE}."
docker buildx build --no-cache --build-arg="BASE_IMAGE=${BASE_IMAGE}" --platform "${DESTINATION_PLATFORMS}" --tag "${DST_IMAGE}" --push -f Dockerfile.seed .
pass "Built image ${DST_IMAGE} for ${DESTINATION_PLATFORMS} platform(s) from ${BASE_IMAGE}."

info "Stage 3: Test image"

start_container "${DST_IMAGE}"
start_container "${DST_IMAGE}" 1000
cid="$(get_started_container_id "${DST_IMAGE}")"
assert_db_was_imported "${cid}"
assert_db_was_imported "${cid}" 1000
stop_container "${cid}"

info "Finished database seeding."
Expand Down
9 changes: 9 additions & 0 deletions tests/bats/_helper.bash
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,12 @@ random_string_lower() {
ret=$(cat /dev/urandom | env LC_CTYPE=C tr -dc 'a-z0-9' | fold -w "${len}" | head -n 1)
echo "${ret}"
}

wait_mysql() {
cid="${1?Missing container ID}"
substep "Wait for mysql to start in container ${cid}."
if ! docker exec --user 1000 -i "${cid}" sh -c "until nc -z localhost 3306; do sleep 1; echo -n .; done; echo" 1>&3; then
docker logs "${cid}"
exit 1
fi
}
Loading

0 comments on commit 6368bb0

Please sign in to comment.