From 67ecbb1b3e2b37c753ec1b714662b044aa80b5da Mon Sep 17 00:00:00 2001 From: Pau Rodriguez-Estivill Date: Sat, 20 Aug 2022 19:29:18 +0200 Subject: [PATCH] Implement hooks with run-parts #58 --- README.md | 11 +++++++++-- alpine.Dockerfile | 2 +- backup.sh | 24 ++++++++++++++++-------- debian.Dockerfile | 2 +- hooks/00-webhook.sh | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 61 insertions(+), 12 deletions(-) create mode 100755 hooks/00-webhook.sh diff --git a/README.md b/README.md index ab7b38d..a4486d1 100644 --- a/README.md +++ b/README.md @@ -90,8 +90,8 @@ Most variables are the same as in the [official postgres image](https://hub.dock | POSTGRES_USER_FILE | Alternative to POSTGRES_USER, for usage with docker secrets. | | SCHEDULE | [Cron-schedule](http://godoc.org/github.com/robfig/cron#hdr-Predefined_schedules) specifying the interval between postgres backups. Defaults to `@daily`. | | TZ | [POSIX TZ variable](https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html) specifying the timezone used to evaluate SCHEDULE cron (example "Europe/Paris"). | -| WEBHOOK_EXTRA_URL | Extra arguments for the webhook. | -| WEBHOOK_URL | URL to be called after a successful backup. | +| WEBHOOK_URL | URL to be called after an error or after a successful backup (POST with a JSON payload, check `hooks/00-webhook.sh` file for more info). Default disabled. | +| WEBHOOK_EXTRA_ARGS | Extra arguments for the `curl` execution in the webhook (check `hooks/00-webhook.sh` file for more info). | #### Special Environment Variables @@ -132,6 +132,13 @@ To do so it is using the following independent variables: * BACKUP_KEEP_WEEKS: will remove files from the `weekly` folder that are older than its value in weeks after a new successfull backup (remember that it starts counting from the end of each week not the beggining). * BACKUP_KEEP_MONTHS: will remove files from the `monthly` folder that are older than its value in months (of 31 days) after a new successfull backup (remember that it starts counting from the end of each month not the beggining). +### Hooks + +The folder `hooks` inside the container can contain hooks/scripts to be run in differrent cases getting the exact situation as a first argument (`error`, `pre-backup` or `post-backup`). + +Just create an script in that folder with execution permission so that [run-parts](https://manpages.debian.org/stable/debianutils/run-parts.8.en.html) can execute it on each state change. + +Please, as an example take a look in the script already present there that implements the `WEBHOOK_URL` functionality. ### Manual Backups diff --git a/alpine.Dockerfile b/alpine.Dockerfile index a63c863..d3dc5db 100644 --- a/alpine.Dockerfile +++ b/alpine.Dockerfile @@ -31,7 +31,7 @@ ENV POSTGRES_DB="**None**" \ WEBHOOK_URL="**None**" \ WEBHOOK_EXTRA_ARGS="" -COPY backup.sh /backup.sh +COPY backup.sh hooks / VOLUME /backups diff --git a/backup.sh b/backup.sh index 007f4fe..ac9fd21 100755 --- a/backup.sh +++ b/backup.sh @@ -1,6 +1,14 @@ #!/usr/bin/env bash set -Eeo pipefail +HOOKS_DIR="/hooks" +if [ -d "${HOOKS_DIR}" ]; then + on_error(){ + run-parts -a "error" "${HOOKS_DIR}" + } + trap 'on_error' ERR +fi + if [ "${POSTGRES_DB}" = "**None**" -a "${POSTGRES_DB_FILE}" = "**None**" ]; then echo "You need to set the POSTGRES_DB or POSTGRES_DB_FILE environment variable." exit 1 @@ -60,6 +68,11 @@ KEEP_DAYS=${BACKUP_KEEP_DAYS} KEEP_WEEKS=`expr $(((${BACKUP_KEEP_WEEKS} * 7) + 1))` KEEP_MONTHS=`expr $(((${BACKUP_KEEP_MONTHS} * 31) + 1))` +# Pre-backup hook +if [ -d "${HOOKS_DIR}" ]; then + run-parts -a "pre-backup" --exit-on-error "${HOOKS_DIR}" +fi + #Initialize dirs mkdir -p "${BACKUP_DIR}/last/" "${BACKUP_DIR}/daily/" "${BACKUP_DIR}/weekly/" "${BACKUP_DIR}/monthly/" @@ -126,12 +139,7 @@ done echo "SQL backup created successfully" -if [ "${WEBHOOK_URL}" != "**None**" ]; then - echo "Execute post-backup webhook call to ${WEBHOOK_URL}" - curl --request POST \ - --url "${WEBHOOK_URL}" \ - --max-time 10 \ - --retry 5 \ - ${WEBHOOK_EXTRA_ARGS} - exit 1 +# Post-backup hook +if [ -d "${HOOKS_DIR}" ]; then + run-parts -a "post-backup" --reverse --exit-on-error "${HOOKS_DIR}" fi diff --git a/debian.Dockerfile b/debian.Dockerfile index 1b275a3..547f44d 100644 --- a/debian.Dockerfile +++ b/debian.Dockerfile @@ -46,7 +46,7 @@ ENV POSTGRES_DB="**None**" \ WEBHOOK_URL="**None**" \ WEBHOOK_EXTRA_ARGS="" -COPY backup.sh /backup.sh +COPY backup.sh hooks / VOLUME /backups diff --git a/hooks/00-webhook.sh b/hooks/00-webhook.sh new file mode 100755 index 0000000..869adab --- /dev/null +++ b/hooks/00-webhook.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +set -e + +# Possible actions: error, pre-backup, post-backup +ACTION="${1}" + +if [ "${WEBHOOK_URL}" != "**None**" ]; then + case "${ACTION}" in + "error") + echo "Execute error webhook call to ${WEBHOOK_URL}" + curl --request POST \ + --url "${WEBHOOK_URL}" \ + --header 'Content-Type: application/json' \ + --data '{"status": "error"}' \ + --max-time 10 \ + --retry 5 \ + ${WEBHOOK_EXTRA_ARGS} + ;; +# "pre-backup") +# echo "Nothing to do" +# ;; + "post-backup") + echo "Execute post-backup webhook call to ${WEBHOOK_URL}" + curl --request POST \ + --url "${WEBHOOK_URL}" \ + --header 'Content-Type: application/json' \ + --data '{"status": "post-backup"}' \ + --max-time 10 \ + --retry 5 \ + ${WEBHOOK_EXTRA_ARGS} + ;; + esac +fi