diff --git a/Dockerfile b/Dockerfile index 5ed3bce..cc5d085 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,14 @@ FROM yavook/kiwi-cron:0.1 LABEL maintainer="jmm@yavook.de" +COPY requirements.txt /tmp/ + RUN set -ex; \ \ # create backup source mkdir -p /backup/source; \ \ + # duplicity software dependencies apk --no-cache add \ ca-certificates \ gettext \ @@ -20,11 +23,7 @@ RUN set -ex; \ python3 \ rsync \ ; \ - update-ca-certificates; - -COPY requirements.txt /tmp/ - -RUN set -ex; \ + update-ca-certificates; \ \ # python packages buildtime dependencies apk --no-cache add --virtual .build-deps \ @@ -60,23 +59,23 @@ RUN set -ex; \ ; \ apk del --purge .build-deps; \ rm -f "/tmp/requirements.txt"; \ - rm -rf "${HOME}/.cargo"; - -# create non-root user -RUN adduser -D -u 1368 duplicity; + rm -rf "${HOME}/.cargo"; \ + \ + # create a non-root user + adduser -D -u 1368 duplicity; USER duplicity RUN set -ex; \ + \ + # confirm duplicity is working + duplicity --version; \ \ mkdir -p "${HOME}/.cache/duplicity"; \ mkdir -pm 600 "${HOME}/.gnupg"; VOLUME [ "/home/duplicity/.cache/duplicity" ] -# confirm duplicity is working -RUN duplicity --version - ENV \ ################# # BACKUP POLICY # @@ -106,4 +105,5 @@ ENV \ GPG_KEY_ID="" \ GPG_PASSPHRASE="" -CMD ["do-plicity"] +COPY bin /usr/local/bin/ +COPY libexec /usr/local/libexec/ diff --git a/bin/kiwi-backup b/bin/kiwi-backup new file mode 100755 index 0000000..0208e18 --- /dev/null +++ b/bin/kiwi-backup @@ -0,0 +1,5 @@ +#!/bin/sh + +exec /usr/local/libexec/kiwi-cron/run_cron \ + "${@}" \ + /usr/local/libexec/kiwi-backup/scheduler diff --git a/do-plicity b/do-plicity deleted file mode 100755 index 6d310cf..0000000 --- a/do-plicity +++ /dev/null @@ -1,177 +0,0 @@ -#!/bin/sh - -############# -# CONSTANTS # -############# - -# commands -this_exe="$(command -v "${0}")" -ionice_exe="$(command -v ionice)" -duplicity_exe="$(command -v duplicity)" - -# files -duplicity_secrets_file='/root/duplicity_secrets' - -############# -# FUNCTIONS # -############# - -append_options() { - ao_cmdline="${1}" - ao_options="${2}" - shift 1 - - if [ -n "${ao_cmdline}" ] && [ -n "${ao_options}" ]; then - # if both are given, stitch together with a space - echo "${ao_cmdline} ${ao_options}" - elif [ -n "${ao_options}" ]; then - # if only options are given, output them - echo "${ao_options}" - else - # if at most a cmdline is given, output that - echo "${ao_cmdline}" - fi -} - -print_command() { - pc_task="${1}" - shift 1 - - pc_cmdline="${ionice_exe} -c 3 ${duplicity_exe}" - pc_cmdline="$( append_options "${pc_cmdline}" "${OPTIONS_ALL}" )" - - case "${pc_task}" in - backup) - pc_cmdline="$( append_options "${pc_cmdline}" "--allow-source-mismatch" )" - pc_cmdline="$( append_options "${pc_cmdline}" "--volsize ${BACKUP_VOLSIZE}" )" - pc_cmdline="$( append_options "${pc_cmdline}" "--full-if-older-than ${FULL_BACKUP_FREQUENCY}" )" - pc_cmdline="$( append_options "${pc_cmdline}" "${OPTIONS_BACKUP}" )" - pc_cmdline="$( append_options "${pc_cmdline}" "/backup/source" )" - ;; - - cleanup) - pc_cmdline="$( append_options "${pc_cmdline}" "cleanup --force" )" - pc_cmdline="$( append_options "${pc_cmdline}" "${OPTIONS_CLEAN}" )" - ;; - - rmfull) - pc_cmdline="$( append_options "${pc_cmdline}" "remove-older-than ${BACKUP_RETENTION_TIME} --force" )" - pc_cmdline="$( append_options "${pc_cmdline}" "${OPTIONS_RMFULL}" )" - ;; - - rmincr) - pc_cmdline="$( append_options "${pc_cmdline}" "remove-all-inc-of-but-n-full ${KEEP_NUM_FULL_CHAINS} --force" )" - pc_cmdline="$( append_options "${pc_cmdline}" "${OPTIONS_RMINCR}" )" - ;; - esac - - pc_cmdline="${pc_cmdline} ${BACKUP_TARGET}" - echo "${pc_cmdline}" -} - -print_cron_schedule() { - pcs_min="$( echo "${1}" | awk '{print $1}' )" - pcs_hour="$( echo "${1}" | awk '{print $2}' )" - pcs_day="$( echo "${1}" | awk '{print $3}' )" - pcs_month="$( echo "${1}" | awk '{print $4}' )" - pcs_weekday="$( echo "${1}" | awk '{print $5}' )" - pcs_command="${2}" - shift 2 - - printf '%-8s%-8s%-8s%-8s%-8s%s\n' "${pcs_min}" "${pcs_hour}" "${pcs_day}" "${pcs_month}" "${pcs_weekday}" "${pcs_command}" -} - -print_crontab() { - echo '# crontab generated for kiwi-backup' - printf '# generation time: '; date - echo '#' - - # don't split the '#' from 'min' - print_cron_schedule '#_min hour day month weekday' 'command' | tr '_' ' ' - - print_cron_schedule "${SCHEDULE_BACKUP}" "${this_exe} backup" - print_cron_schedule "${SCHEDULE_CLEANUP}" "${this_exe} cleanup" - print_cron_schedule "${SCHEDULE_RMFULL}" "${this_exe} rmfull" - print_cron_schedule "${SCHEDULE_RMINCR}" "${this_exe} rmincr" -} - -############### -# ENVIRONMENT # -############### - -# load secrets file -if [ -f "${duplicity_secrets_file}" ]; then - # shellcheck disable=SC1090 - . "${duplicity_secrets_file}" -fi - -# check if uses encryption -if [ -n "${GPG_KEY_ID}" ]; then - # gpg key given - OPTIONS_ALL="$( append_options "${OPTIONS_ALL}" "--encrypt-key=${GPG_KEY_ID}" )" - - # handle more verbose "GPG_PASSPHRASE" env_var - PASSPHRASE="${GPG_PASSPHRASE:-${PASSPHRASE}}" - export PASSPHRASE - unset GPG_PASSPHRASE -else - # no key given - OPTIONS_ALL="$( append_options "${OPTIONS_ALL}" "--no-encryption" )" -fi - -######## -# MAIN # -######## - -if [ "${#}" -gt 0 ]; then - - # CLI - task="${1}" - shift 1 - - # run task - case "${task}" in - print-*) - task="${task##*-}" - - case "${task}" in - # print out the crontab - crontab) - print_crontab - ;; - - # print out a task - backup|cleanup|rmfull|rmincr) - print_command "${task}" - ;; - - # unknown task - *) - >&2 echo "Cannot print '${task}'." - >&2 echo "Choose from: crontab, backup, cleanup, rmfull, rmincr" - exit 1 - ;; - esac - ;; - - # execute single task - backup|cleanup|rmfull|rmincr) - # shellcheck disable=SC2091 - $(print_command "${task}") - ;; - - # unknown task - *) - >&2 echo "Unknown task '${task}'." - >&2 echo "Choose from: backup, cleanup, rmfull, rmincr" - exit 1 - ;; - esac -else - - # default run: replace crontab, then start crond - print_crontab | crontab - - crond -fl 8 -fi - -exit 0 \ No newline at end of file diff --git a/libexec/kiwi-backup/build_command b/libexec/kiwi-backup/build_command new file mode 100755 index 0000000..76a8525 --- /dev/null +++ b/libexec/kiwi-backup/build_command @@ -0,0 +1,81 @@ +#!/bin/sh + +############# +# CONSTANTS # +############# + +# commands +ionice_exe="$(command -v ionice)" +duplicity_exe="$(command -v duplicity)" + +# files +duplicity_secrets_file="${HOME}/duplicity_secrets" + +######## +# MAIN # +######## + +# load secrets file +if [ -f "${duplicity_secrets_file}" ]; then + # shellcheck disable=SC1090 + . "${duplicity_secrets_file}" +fi + +# check if uses encryption +if [ -n "${GPG_KEY_ID}" ]; then + # gpg key given + options_encryption="--encrypt-key=${GPG_KEY_ID}" + + # handle more verbose "GPG_PASSPHRASE" env_var + PASSPHRASE="${GPG_PASSPHRASE:-${PASSPHRASE}}" + export PASSPHRASE + unset GPG_PASSPHRASE +else + # no key given + options_encryption="--no-encryption" +fi + +task="${1}" +shift 1 + +add_space () { + if [ -n "${1}" ]; then + echo " ${1}" + fi +} + +printf "%s -c 3 %s%s %s" \ + "${ionice_exe}" \ + "${duplicity_exe}" \ + "$( add_space "${OPTIONS_ALL}" )" \ + "${options_encryption}" + +case "${task}" in + backup) + printf ' --allow-source-mismatch' + printf ' --volsize' + printf ' --full-if-older-than' + printf '%s' "$( add_space "${OPTIONS_BACKUP}" )" + printf ' /backup/source' + ;; + + cleanup) + printf ' cleanup' + printf ' --force' + printf '%s' "$( add_space "${OPTIONS_CLEAN}" )" + ;; + + rmfull) + printf ' remove-older-than %s' "${BACKUP_RETENTION_TIME}" + printf ' --force' + printf '%s' "$( add_space "${OPTIONS_RMFULL}" )" + ;; + + rmincr) + printf ' remove-all-inc-of-but-n-full %s' "${KEEP_NUM_FULL_CHAINS}" + printf ' --force' + printf '%s' "$( add_space "${OPTIONS_RMINCR}" )" + ;; +esac + +echo " ${BACKUP_TARGET}" diff --git a/libexec/kiwi-backup/scheduler b/libexec/kiwi-backup/scheduler new file mode 100755 index 0000000..52f4b42 --- /dev/null +++ b/libexec/kiwi-backup/scheduler @@ -0,0 +1,9 @@ +#!/bin/sh + +this_script="$( readlink -f "${0}" )" +this_dir="${this_script%/*}" + +echo "${SCHEDULE_BACKUP}" "$( "${this_dir}/build_command" backup )" +echo "${SCHEDULE_CLEANUP}" "$( "${this_dir}/build_command" cleanup )" +echo "${SCHEDULE_RMFULL}" "$( "${this_dir}/build_command" rmfull )" +echo "${SCHEDULE_RMINCR}" "$( "${this_dir}/build_command" rmincr )"