diff --git a/.circleci/config.yml b/.circleci/config.yml index 5470420..01129a5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,29 +2,21 @@ version: 2.1 jobs: canary: - docker: - - image: cimg/base:2020.06 + machine: + image: ubuntu-1604:202007-01 working_directory: ~/docker-volume-backup steps: - checkout - - setup_remote_docker: - version: 20.10.6 - run: name: Build command: | docker build . -t offen/docker-volume-backup:canary - run: - name: Create container from image + name: Run tests command: | - docker run -d offen/docker-volume-backup:canary - echo "Sleeping for 30s before checking if container is still running." - sleep 30 - count=$(docker ps -q | wc -l) - if [[ $count != "1" ]]; then - echo "Expected one container to be running, found $count." - exit 1 - fi - docker stop $(docker ps -q) + for test in test/**/test.sh; do + /bin/sh $test + done build: docker: diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..9daeafb --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +test diff --git a/src/backup.sh b/src/backup.sh index d46c7a2..ab98f96 100644 --- a/src/backup.sh +++ b/src/backup.sh @@ -17,13 +17,12 @@ DOCKER_SOCK="/var/run/docker.sock" if [ -S "$DOCKER_SOCK" ]; then TEMPFILE="$(mktemp)" - docker ps \ - --format "{{.ID}}" \ + docker ps -q \ --filter "label=docker-volume-backup.stop-during-backup=$BACKUP_STOP_CONTAINER_LABEL" \ > "$TEMPFILE" CONTAINERS_TO_STOP="$(cat $TEMPFILE | tr '\n' ' ')" CONTAINERS_TO_STOP_TOTAL="$(cat $TEMPFILE | wc -l)" - CONTAINERS_TOTAL="$(docker ps --format "{{.ID}}" | wc -l)" + CONTAINERS_TOTAL="$(docker ps -q | wc -l)" rm "$TEMPFILE" echo "$CONTAINERS_TOTAL containers running on host in total." echo "$CONTAINERS_TO_STOP_TOTAL containers marked to be stopped during backup." @@ -99,7 +98,12 @@ if [ ! -z "$BACKUP_RETENTION_DAYS" ]; then sleep "$BACKUP_PRUNING_LEEWAY" bucket=$AWS_S3_BUCKET_NAME - rule_applies_to=$(mc rm $MC_GLOBAL_OPTIONS --fake --recursive -force --older-than "${BACKUP_RETENTION_DAYS}d" "backup-target/$bucket" | wc -l) + rule_applies_to=$( + mc rm $MC_GLOBAL_OPTIONS --fake --recursive -force \ + --older-than "${BACKUP_RETENTION_DAYS}d" \ + "backup-target/$bucket" \ + | wc -l + ) if [ "$rule_applies_to" == "0" ]; then echo "No backups found older than the configured retention period of $BACKUP_RETENTION_DAYS days." echo "Doing nothing." @@ -114,6 +118,8 @@ if [ ! -z "$BACKUP_RETENTION_DAYS" ]; then exit 1 fi - mc rm $MC_GLOBAL_OPTIONS --recursive -force --older-than "${BACKUP_RETENTION_DAYS}d" "backup-target/$bucket" + mc rm $MC_GLOBAL_OPTIONS \ + --recursive -force \ + --older-than "${BACKUP_RETENTION_DAYS}d" "backup-target/$bucket" echo "Successfully pruned ${rule_applies_to} backups older than ${BACKUP_RETENTION_DAYS} days." fi diff --git a/src/entrypoint.sh b/src/entrypoint.sh index 1584ef6..10a39ed 100644 --- a/src/entrypoint.sh +++ b/src/entrypoint.sh @@ -19,6 +19,7 @@ BACKUP_PRUNING_LEEWAY="${BACKUP_PRUNING_LEEWAY:-10m}" AWS_S3_BUCKET_NAME="${AWS_S3_BUCKET_NAME:-}" AWS_ENDPOINT="${AWS_ENDPOINT:-s3.amazonaws.com}" +AWS_ENDPOINT_PROTO="${AWS_ENDPOINT_PROTO:-https}" GPG_PASSPHRASE="${GPG_PASSPHRASE:-}" @@ -29,7 +30,7 @@ EOF chmod a+x env.sh source env.sh -mc $MC_GLOBAL_OPTIONS alias set backup-target "https://$AWS_ENDPOINT" "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" +mc $MC_GLOBAL_OPTIONS alias set backup-target "$AWS_ENDPOINT_PROTO://$AWS_ENDPOINT" "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" # Add our cron entry, and direct stdout & stderr to Docker commands stdout echo "Installing cron.d entry with expression $BACKUP_CRON_EXPRESSION." diff --git a/test/default/docker-compose.yml b/test/default/docker-compose.yml new file mode 100644 index 0000000..f9e942e --- /dev/null +++ b/test/default/docker-compose.yml @@ -0,0 +1,42 @@ +version: '3' + +services: + minio: + image: minio/minio:RELEASE.2020-08-04T23-10-51Z + environment: + MINIO_ROOT_USER: test + MINIO_ROOT_PASSWORD: test + MINIO_ACCESS_KEY: test + MINIO_SECRET_KEY: GMusLtUmILge2by+z890kQ + entrypoint: /bin/ash -c 'mkdir -p /data/backup && minio server /data' + volumes: + - backup_data:/data + + backup: &default_backup_service + image: offen/docker-volume-backup:canary + depends_on: + - minio + restart: always + environment: + AWS_ACCESS_KEY_ID: test + AWS_SECRET_ACCESS_KEY: GMusLtUmILge2by+z890kQ + AWS_ENDPOINT: minio:9000 + AWS_ENDPOINT_PROTO: http + AWS_S3_BUCKET_NAME: backup + BACKUP_FILENAME: test.tar.gz + BACKUP_CRON_EXPRESSION: 0 0 5 31 2 ? + volumes: + - app_data:/backup/app_data:ro + - /var/run/docker.sock:/var/run/docker.sock + + offen: + image: offen/offen:latest + labels: + - docker-volume-backup.stop-during-backup=true + volumes: + - app_data:/var/opt/offen + + +volumes: + backup_data: + app_data: diff --git a/test/default/test.sh b/test/default/test.sh new file mode 100755 index 0000000..550cfec --- /dev/null +++ b/test/default/test.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +set -e + +cd $(dirname $0) + +docker-compose up -d +sleep 5 + +docker-compose exec backup backup + +docker run --rm -it \ + -v default_backup_data:/data alpine \ + ash -c 'tar -xf /data/backup/test.tar.gz && test -f /backup/app_data/offen.db' + +if [ "$(docker-compose ps -q | wc -l)" != "3" ]; then + echo "Expected all containers to be running post backup, instead seen:" + docker-compose ps + exit 1 +fi + +docker-compose down --volumes + +echo "Test passed"