Skip to content

Commit

Permalink
Added support for ARM (M1). (#7)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
Alex Skrypnyk authored Jul 31, 2022
1 parent 1da28ef commit 470284e
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 26 deletions.
10 changes: 10 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
23 changes: 19 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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 `:<version>` tag.
3. For `feature/*` branches as `:<branch>` 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.
16 changes: 16 additions & 0 deletions seed-db.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
Expand All @@ -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"
Expand Down
57 changes: 37 additions & 20 deletions tests/bats/data.bats
Original file line number Diff line number Diff line change
@@ -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
}
Expand Down Expand Up @@ -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."
Expand All @@ -70,25 +87,25 @@ 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}"

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}"
Expand All @@ -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}"
Expand All @@ -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"

Expand Down
2 changes: 1 addition & 1 deletion tests/dgoss/goss.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ package:
mariadb:
installed: true
versions:
- 10.4.19-r0
- 10.4.25-r0
user:
mysql:
exists: true
Expand Down

0 comments on commit 470284e

Please sign in to comment.