From 470284ef042a0e86bb657aa3c8ace0a8d211970d Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 31 Jul 2022 13:42:47 +1000 Subject: [PATCH] Added support for ARM (M1). (#7) * Updated parent image version. * Updated tests to support arm64. * Updated mariadb version in test. * Added publishing of the feature branches to DockerHub from CI. * Updated readme. * Fixed CI config. --- .circleci/config.yml | 10 ++++++++ Dockerfile | 2 +- README.md | 23 ++++++++++++++--- seed-db.sh | 16 ++++++++++++ tests/bats/data.bats | 57 ++++++++++++++++++++++++++++--------------- tests/dgoss/goss.yaml | 2 +- 6 files changed, 84 insertions(+), 26 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a3bc1e6..395ccb9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -32,3 +32,13 @@ jobs: - run: name: Run Bats tests command: bats tests/bats/data.bats --tap + - run: + name: Deploy image for feature branches + command: | + if [ "${CIRCLE_BRANCH:0:8}" = "feature/" ]; then + export DOCKER_IMAGE_NAME_SRC="$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME" + export DOCKER_IMAGE_NAME_DST="$DOCKER_IMAGE_NAME_SRC:feature-${CIRCLE_BRANCH:8}" + docker tag "$DOCKER_IMAGE_NAME_SRC:latest" $DOCKER_IMAGE_NAME_DST + echo "${DREVOPS_DOCKER_REGISTRY_TOKEN}" | docker login --username "${DREVOPS_DOCKER_REGISTRY_USERNAME}" --password-stdin "${DREVOPS_DOCKER_REGISTRY:-docker.io}" + docker push "$DOCKER_IMAGE_NAME_DST" + fi diff --git a/Dockerfile b/Dockerfile index 3cb52db..3223dc4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ # 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:21.7.0 +FROM uselagoon/mariadb-drupal:22.7.0 ENV MARIADB_DATA_DIR=/var/lib/db-data diff --git a/README.md b/README.md index 137ce0e..3dd2399 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ Allows capturing database data as a Docker layer. ![LICENSE](https://img.shields.io/github/license/drevops/mariadb-drupal-data) ## How it works + Usually, MariaDB uses data directory specified as a Docker volume that is mounted onto host: this allows retaining data after container restarts. @@ -35,15 +36,29 @@ imported database, which saves a significant amount of time for database imports. ## Seeding image with your database + `./seed-db.sh` allows to easily create your own image with "seeded" database. 1. `./seed-db.sh path/to/db.sql myorg/myimage:latest` 2. `docker push myorg/myimage:latest` +In some cases, shell may report platform incorrectly. Run with forced platform: + + DOCKER_DEFAULT_PLATFORM=linux/amd64 ./seed-db.sh path/to/db.sql myorg/myimage:latest + ## Maintenance -This image is built and pushed manually to DockerHub once parent image -is updated. -Versions are following versions of the upstream image to ease maintenance. +### Running tests + + bats tests/bats/data.bats --tap + # or + DOCKER_DEFAULT_PLATFORM=linux/amd64 bats --tap tests/bats/data.bats + +### Publishing + +This image is built and pushed automatically to DockerHub: +1. For all commits to `master` branch as `:latest` tag. +2. For releases as `:` tag. +3. For `feature/*` branches as `:` tag. -See the [CI configuration](.circleci/config.yml) for running tests locally. +Versions are following versions of the [upstream image](https://hub.docker.com/r/uselagoon/mariadb-drupal/tags) to ease maintenance. diff --git a/seed-db.sh b/seed-db.sh index 5bacb5a..b69ebad 100755 --- a/seed-db.sh +++ b/seed-db.sh @@ -5,9 +5,12 @@ # Usage: # ./seed-db.sh path/to/db.sql myorg/myimage:latest # +# DOCKER_DEFAULT_PLATFORM=linux/amd64 ./seed-db.sh path/to/db.sql myorg/myimage:latest +# # shellcheck disable=SC2002 set -e +[ -n "${DREVOPS_DEBUG}" ] && set -x # Database dump file as a first argument to the script. DB_FILE="${DB_FILE:-$1}" @@ -21,12 +24,25 @@ BASE_IMAGE="${BASE_IMAGE:-drevops/mariadb-drupal-data}" # User ID to run the container with. RUN_USER="${RUN_USER:-1000}" +# Docker target platform architecture. +# Note that some shells report platform incorrectly. In such cases, run +# as `DOCKER_DEFAULT_PLATFORM=linux/amd64 ./seed-db.sh path/to/db.sql myorg/myimage:latest` +DOCKER_DEFAULT_PLATFORM="${DOCKER_DEFAULT_PLATFORM:-}" + # ------------------------------------------------------------------------------ [ -z "${DB_FILE}" ] && echo "ERROR: Path to the database dump file must be provided as a first argument." && exit 1 [ -z "${DST_IMAGE}" ] && echo "ERROR: Destination docker image name must be provided as a second argument." && exit 1 [ ! -f "${DB_FILE}" ] && echo "ERROR: Specified database dump file ${DB_FILE} does not exist." && exit 1 +if [ "$(uname -m)" = "arm64" ]; then + export DOCKER_DEFAULT_PLATFORM=linux/amd64 +fi + +if [ -n "${DOCKER_DEFAULT_PLATFORM}" ]; then + echo "==> Using ${DOCKER_DEFAULT_PLATFORM} platform architecture." +fi + # Normalise image - add ":latest" if tag was not provided. image="${DST_IMAGE}" [ -n "${image##*:*}" ] && image="${image}:latest" diff --git a/tests/bats/data.bats b/tests/bats/data.bats index bb2ee27..2e4c95c 100644 --- a/tests/bats/data.bats +++ b/tests/bats/data.bats @@ -1,28 +1,45 @@ #!/usr/bin/env bats # -# Test for clean functionality. +# Test functionality. +# +# bats --tap tests/bats/data.bats +# +# In some cases, shell may report platform incorrectly. Run with forced platform: +# DOCKER_DEFAULT_PLATFORM=linux/amd64 bats --tap tests/bats/data.bats # load _helper setup(){ - export CUR_DIR="$(pwd)" + CUR_DIR="$(pwd)" + export CUR_DIR export BUILD_DIR="${BUILD_DIR:-"${BATS_TEST_TMPDIR}/drevops-maria-drupal-data$(random_string)"}" - export DOCKER_TAG_PREFIX="bats-test-" + export TEST_DOCKER_TAG_PREFIX="bats-test-" prepare_fixture_dir "${BUILD_DIR}" copy_code "${BUILD_DIR}" + if [ "$(uname -m)" = "arm64" ]; then + export DOCKER_DEFAULT_PLATFORM=linux/amd64 + fi + + if [ -n "${DOCKER_DEFAULT_PLATFORM}" ]; then + step "Using ${DOCKER_DEFAULT_PLATFORM} platform architecture." + fi + + # Force full debug output in scritps. + export DREVOPS_DEBUG=1 + pushd "${BUILD_DIR}" > /dev/null || exit 1 } teardown(){ # Stop and remove all test containers. - docker ps --all --format "{{.ID}}\t{{.Image}}" | grep "${DOCKER_TAG_PREFIX}" | awk '{print $1}' | xargs docker rm -f -v + docker ps --all --format "{{.ID}}\t{{.Image}}" | grep "${TEST_DOCKER_TAG_PREFIX}" | awk '{print $1}' | xargs docker rm -f -v # Remove all test images. - docker images -a | grep "${DOCKER_TAG_PREFIX}" | awk '{print $3}' | xargs docker rmi -f || true + docker images -a | grep "${TEST_DOCKER_TAG_PREFIX}" | awk '{print $3}' | xargs docker rmi -f || true popd > /dev/null || cd "${CUR_DIR}" || exit 1 } @@ -53,9 +70,9 @@ copy_code(){ @test "Data added to the image is captured and preserved" { user=1000 - tag="${DOCKER_TAG_PREFIX}$(random_string_lower)" + tag="${TEST_DOCKER_TAG_PREFIX}$(random_string_lower)" - step "Build default image from tag $tag." + step "Build default image tagged with $tag." docker build -t "${tag}" . step "Starting new detached container from the built image." @@ -70,12 +87,12 @@ copy_code(){ step "Wait for mysql to start." sleep 5 - step "Assert that the database is present." + step "Assert that the database is present after start." run docker exec --user ${user} "${cid}" mysql -e "SELECT schema_name FROM information_schema.schemata WHERE schema_name = 'drupal';" assert_success assert_contains "drupal" "${output}" - step "Assert that the table is not present." + step "Assert that the table is not present after start." run docker exec --user ${user} "${cid}" mysql -e "USE 'drupal'; show tables like 'mytesttable';" assert_success assert_not_contains "mytesttable" "${output}" @@ -83,12 +100,12 @@ copy_code(){ step "Create a table in the database." docker exec --user ${user} "${cid}" mysql -e "USE 'drupal'; CREATE TABLE mytesttable(c CHAR(20) CHARACTER SET utf8 COLLATE utf8_bin);" - step "Assert that the table is present." + step "Assert that the table is present after creation." run docker exec --user ${user} "${cid}" mysql -e "USE 'drupal'; show tables like 'mytesttable';" assert_success assert_contains "mytesttable" "${output}" - step "Commit an image from the last container and get image id." + step "Commit an image from the last container and get the image ID." run docker commit "${cid}" assert_success committed_image_id="${output}" @@ -97,7 +114,7 @@ copy_code(){ step "Create a new tag for committed image." new_tag="${tag}-latest" docker tag "${committed_image_id}" "${new_tag}" - substep "Tagged committed image ${committed_image_id} with tag ${new_tag}." + substep "Tagged committed image ${committed_image_id} with a tag ${new_tag}." step "Start new container from the committed image." run docker run --user ${user} -d "${new_tag}" @@ -108,38 +125,38 @@ copy_code(){ step "Wait for mysql to start." sleep 5 - step "Assert that the database is present." + step "Assert that the database is present after restart." run docker exec --user ${user} "${new_cid}" mysql -e "SELECT schema_name FROM information_schema.schemata WHERE schema_name = 'drupal';" assert_success assert_contains "drupal" "${output}" - step "Assert that the table is present." + step "Assert that the table is present after restart." run docker exec --user ${user} "${new_cid}" mysql -e "USE 'drupal'; show tables like 'mytesttable';" assert_success assert_contains "mytesttable" "${output}" } @test "Seeding of the image works" { - tag="${DOCKER_TAG_PREFIX}$(random_string_lower)" + tag="${TEST_DOCKER_TAG_PREFIX}$(random_string_lower)" - step "Build fresh image from tag $tag." + step "Build fresh image tagged with $tag." docker build --no-cache -t "${tag}" . step "Download fixture DB dump." file="${BUILD_DIR}/db.sql" - CURL_DB_URL=https://raw.githubusercontent.com/wiki/drevops/drevops/db_d8.dist.sql.md + CURL_DB_URL=https://raw.githubusercontent.com/wiki/drevops/drevops/db_d9.dist.sql.md curl -L "${CURL_DB_URL}" -o "${file}" export BASE_IMAGE="${tag}" export RUN_USER="1000" - step "Run DB seeding script from base image ${BASE_IMAGE}" - run ./seed-db.sh "${file}" testorg/tesimage:latest + step "Run DB seeding script from base image tagged with ${BASE_IMAGE}" + run ./seed-db.sh "${file}" testorgdst/tesimagedst:latest assert_success debug "${output}" step "Start container from the seeded image." # Start container with a non-root user to imitate limited host permissions. - cid=$(docker run --user 1000 -d --rm "testorg/tesimage:latest") + cid=$(docker run --user 1000 -d --rm "testorgdst/tesimagedst:latest") substep "Waiting for the service to become ready." docker exec -i "${cid}" sh -c "until nc -z localhost 3306; do sleep 1; echo -n .; done; echo" diff --git a/tests/dgoss/goss.yaml b/tests/dgoss/goss.yaml index c159ac6..edb183f 100644 --- a/tests/dgoss/goss.yaml +++ b/tests/dgoss/goss.yaml @@ -15,7 +15,7 @@ package: mariadb: installed: true versions: - - 10.4.19-r0 + - 10.4.25-r0 user: mysql: exists: true