diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..d3cefcc --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,17 @@ +--- +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.4.0 + hooks: + - id: check-added-large-files + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-merge-conflict + - id: mixed-line-ending + - id: check-executables-have-shebangs + - id: check-symlinks + - id: check-case-conflict + - repo: git://github.com/jumanjihouse/pre-commit-hooks + rev: 1.11.0 + hooks: + - id: shellcheck diff --git a/.travis.yml b/.travis.yml index 3595a5f..55e135b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ services: docker before_script: - docker run --rm --privileged multiarch/qemu-user-static:register --reset + - pip install pre-commit script: - - make all + - make check all diff --git a/Dockerfile b/Dockerfile index 413273f..8a774b3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,13 +36,17 @@ VOLUME /var/lock/duplicity ENV BACKUP_DEST="file:///backups" ENV BACKUP_NAME="backup" -ENV PATH_TO_BACKUP="/data" -ENV PASSPHRASE="Correct.Horse.Battery.Staple" -ENV FLOCK_WAIT=60 - -# Cron schedules +ENV CLEANUP_COMMAND="" ENV CRON_SCHEDULE="" +ENV FLOCK_WAIT=60 ENV FULL_CRON_SCHEDULE="" +ENV GPG_KEY_ID="" +ENV OPT_ARGUMENTS="" +ENV PASSPHRASE="Correct.Horse.Battery.Staple" +ENV PATH_TO_BACKUP="/data" +ENV RESTORE_ON_EMPTY_START="" +ENV SKIP_ON_START="" +ENV VERIFY_CRON_SCHEDULE="" ENV VERIFY_CRON_SCHEDULE="" # Create script dirs diff --git a/Makefile b/Makefile index 2cf3acc..aa52457 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,10 @@ all: build-all test-all test-s3-all .PHONY: test test: test-amd64 +.PHONY: check +check: + pre-commit run --all-files + .PHONY: build-amd64 build-amd64: docker build --build-arg REPO=library -f ./Dockerfile -t $(DOCKER_TAG):amd64 . diff --git a/backup.sh b/backup.sh index 9115891..ec0af9d 100755 --- a/backup.sh +++ b/backup.sh @@ -1,39 +1,48 @@ #! /bin/bash -set -e +set -euf + +BACKUP_CMD="" +if test $# -gt 0; then + BACKUP_CMD="$1" +fi ( - if ! flock -x -w $FLOCK_WAIT 200 ; then + if ! flock -x -w "$FLOCK_WAIT" 200 ; then echo 'ERROR: Could not obtain lock. Exiting.' exit 1 fi # Run pre-backup scripts for f in /scripts/backup/before/*; do - if [ -f $f -a -x $f ]; then - bash $f + if [ -f "$f" ] && [ -x "$f" ]; then + bash "$f" fi done + # Intentionally not wrapping BACKUP_CMD and OPT_ARGUMENTS + # shellcheck disable=SC2086 duplicity \ - $1 \ + $BACKUP_CMD \ --asynchronous-upload \ --log-file /root/duplicity.log \ - --name $BACKUP_NAME \ + --name "$BACKUP_NAME" \ $OPT_ARGUMENTS \ - $PATH_TO_BACKUP \ - $BACKUP_DEST + "$PATH_TO_BACKUP" \ + "$BACKUP_DEST" if [ -n "$CLEANUP_COMMAND" ]; then + # Intentionally not wrapping CLEANUP_COMMAND + # shellcheck disable=SC2086 duplicity $CLEANUP_COMMAND \ --log-file /root/duplicity.log \ - --name $BACKUP_NAME \ - $BACKUP_DEST + --name "$BACKUP_NAME" \ + "$BACKUP_DEST" fi # Run post-backup scripts for f in /scripts/backup/after/*; do - if [ -f $f -a -x $f ]; then - bash $f + if [ -f "$f" ] && [ -x "$f" ]; then + bash "$f" fi done diff --git a/cron-exec.sh b/cron-exec.sh index 2812ca8..c42607d 100755 --- a/cron-exec.sh +++ b/cron-exec.sh @@ -4,8 +4,15 @@ ENV=/env.sh LOG=/cron.log HEALTH_FILE=/unhealthy -touch $ENV -source $ENV +if [ -f "$ENV" ]; then + # shellcheck disable=SC1090 + source "$ENV" +fi # Execute command and write output to log -$@ 2>> $LOG && rm -f $HEALTH_FILE || { touch $HEALTH_FILE; exit 1; } +if eval "$@" 2>> "$LOG"; then + rm -f "$HEALTH_FILE" +else + touch "$HEALTH_FILE" + exit 1; +fi diff --git a/healthcheck.sh b/healthcheck.sh index b7052a1..e2e1027 100755 --- a/healthcheck.sh +++ b/healthcheck.sh @@ -2,4 +2,8 @@ HEALTH_FILE=/unhealthy -test -f $HEALTH_FILE || exit 0 && exit 1 +if [ -f "$HEALTH_FILE" ]; then + exit 1 +else + exit 0 +fi diff --git a/multi-arch-manifest-tmpl.yml b/multi-arch-manifest-tmpl.yml index c2fb853..844c0d6 100644 --- a/multi-arch-manifest-tmpl.yml +++ b/multi-arch-manifest-tmpl.yml @@ -35,4 +35,4 @@ manifests: - image: "{DOCKER_REPO}:{TAG_ROOT}-ppc64le" platform: architecture: ppc64le - os: linux \ No newline at end of file + os: linux diff --git a/restore.sh b/restore.sh index fc2dec7..378a0cf 100755 --- a/restore.sh +++ b/restore.sh @@ -1,32 +1,34 @@ #! /bin/bash -set -e +set -euf ( - if ! flock -x -w $FLOCK_WAIT 200 ; then + if ! flock -x -w "$FLOCK_WAIT" 200 ; then echo 'ERROR: Could not obtain lock. Exiting.' exit 1 fi # Run pre-restore scripts for f in /scripts/restore/before/*; do - if [ -f $f -a -x $f ]; then - bash $f + if [ -f "$f" ] && [ -x "$f" ]; then + bash "$f" fi done + # Intentionally not wrapping OPT_ARGUMENTS + # shellcheck disable=SC2086 duplicity restore \ --force \ --log-file /root/duplicity.log \ - --name $BACKUP_NAME \ + --name "$BACKUP_NAME" \ $OPT_ARGUMENTS \ - $@ \ - $BACKUP_DEST \ - $PATH_TO_BACKUP + "$@" \ + "$BACKUP_DEST" \ + "$PATH_TO_BACKUP" # Run post-restore scripts for f in /scripts/restore/after/*; do - if [ -f $f -a -x $f ]; then - bash $f + if [ -f "$f" ] && [ -x "$f" ]; then + bash "$f" fi done diff --git a/start.sh b/start.sh index d339b3c..0052dd6 100755 --- a/start.sh +++ b/start.sh @@ -1,23 +1,24 @@ #! /bin/bash +set -euf # If first arg is bash, we'll just execute directly -if [ "$1" == "bash" ]; then +if [ $# -gt 0 ] && [ "$1" == "bash" ]; then exec "$@" exit 0 fi # If no env variable set, get from command line if [ "$OPT_ARGUMENTS" == "" ]; then - export OPT_ARGUMENTS="$@" + export OPT_ARGUMENTS="$*" fi # If key id is provied add arg -if [ -e "$GPG_KEY_ID" ]; then +if [ -n "$GPG_KEY_ID" ]; then export OPT_ARGUMENTS="$OPT_ARGUMENTS --encrypt-sign-key=\"$GPG_KEY_ID\"" fi # If set to restore on start, restore if the data volume is empty -if [ "$RESTORE_ON_EMPTY_START" == "true" -a -z "$(ls -A $PATH_TO_BACKUP)" ]; then +if [ "$RESTORE_ON_EMPTY_START" == "true" ] && [ -z "$(ls -A "$PATH_TO_BACKUP")" ]; then /cron-exec.sh /restore.sh fi diff --git a/tests/test-pre-scripts/backup/after/post-backup.sh b/tests/test-pre-scripts/backup/after/post-backup.sh index a606858..65cf8df 100755 --- a/tests/test-pre-scripts/backup/after/post-backup.sh +++ b/tests/test-pre-scripts/backup/after/post-backup.sh @@ -1,3 +1,4 @@ +#! /bin/bash set -e cd /data diff --git a/tests/test-pre-scripts/backup/before/pre-backup.sh b/tests/test-pre-scripts/backup/before/pre-backup.sh index b0da835..7c35bfc 100755 --- a/tests/test-pre-scripts/backup/before/pre-backup.sh +++ b/tests/test-pre-scripts/backup/before/pre-backup.sh @@ -1,3 +1,4 @@ +#! /bin/bash set -e cd /data diff --git a/tests/test-pre-scripts/restore/after/post-restore.sh b/tests/test-pre-scripts/restore/after/post-restore.sh index 7ede126..c1a4ea7 100755 --- a/tests/test-pre-scripts/restore/after/post-restore.sh +++ b/tests/test-pre-scripts/restore/after/post-restore.sh @@ -1,3 +1,4 @@ +#! /bin/bash set -e cd /data diff --git a/tests/test-pre-scripts/restore/before/pre-restore.sh b/tests/test-pre-scripts/restore/before/pre-restore.sh index ea3e3e4..1869dbd 100755 --- a/tests/test-pre-scripts/restore/before/pre-restore.sh +++ b/tests/test-pre-scripts/restore/before/pre-restore.sh @@ -1,3 +1,4 @@ +#! /bin/bash set -e # Don't really need to do anything here diff --git a/tests/test.sh b/tests/test.sh index f302cf9..88e4937 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -1,10 +1,10 @@ #! /bin/bash -set -e +set -euf -image="$1" -if [ "$IN_CONTAINER" != "true" ] ; then +if [ -z "${IN_CONTAINER+x}" ] ; then # Run the test script within the container + image="$1" docker run --rm \ -e IN_CONTAINER=true \ -e SKIP_ON_START=true \ @@ -31,7 +31,7 @@ else /cron-exec.sh /verify.sh || { cat /cron.log && exit 1; } echo "Delete test data..." - rm -fr /data/* + rm -fr /data/test.txt echo "Verify deleted..." test -f /data/test.txt && exit 1 || echo "Gone" @@ -48,7 +48,7 @@ else /cron-exec.sh /verify.sh || { cat /cron.log && exit 1; } echo "Delete test data again..." - rm -fr /data/* + rm -fr /data/test.txt echo "Verify deleted..." test -f /data/test.txt && exit 1 || echo "Gone" diff --git a/verify.sh b/verify.sh index f11ff35..816a660 100755 --- a/verify.sh +++ b/verify.sh @@ -1,10 +1,12 @@ #! /bin/bash -set -e +set -euf +# Intentionally not wrapping OPT_ARGUMENTS +# shellcheck disable=SC2086 duplicity verify \ --compare-data \ --log-file /root/duplicity.log \ - --name $BACKUP_NAME \ + --name "$BACKUP_NAME" \ $OPT_ARGUMENTS \ - $BACKUP_DEST \ - $PATH_TO_BACKUP + "$BACKUP_DEST" \ + "$PATH_TO_BACKUP"