mirror of
https://github.com/yavook/kiwi-backup.git
synced 2024-11-22 06:53:00 +00:00
Merge branch 'release/0.5'
This commit is contained in:
commit
fa60ebd2cb
3 changed files with 115 additions and 69 deletions
|
@ -96,6 +96,7 @@ ENV \
|
||||||
SCHEDULE_RMINCR="36 05 * * SUN" \
|
SCHEDULE_RMINCR="36 05 * * SUN" \
|
||||||
BACKUP_VOLSIZE=1024 \
|
BACKUP_VOLSIZE=1024 \
|
||||||
BACKUP_TARGET="file:///backup/target" \
|
BACKUP_TARGET="file:///backup/target" \
|
||||||
|
OPTIONS_ALL="" \
|
||||||
OPTIONS_BACKUP="" \
|
OPTIONS_BACKUP="" \
|
||||||
OPTIONS_CLEANUP="" \
|
OPTIONS_CLEANUP="" \
|
||||||
OPTIONS_RMFULL="" \
|
OPTIONS_RMFULL="" \
|
||||||
|
|
34
README.md
34
README.md
|
@ -79,6 +79,37 @@ backup:
|
||||||
KEEP_NUM_FULL_CHAINS: "2"
|
KEEP_NUM_FULL_CHAINS: "2"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Handling Secrets
|
||||||
|
|
||||||
|
`duplicity` usually handles secrets by [reading its environment](http://duplicity.nongnu.org/vers7/duplicity.1.html#sect6). Some of its backends also accept secrets via environment, [notably the AWS S3 backend](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html).
|
||||||
|
|
||||||
|
There are three major ways to for inject secrets into `kiwi-backup` environments:
|
||||||
|
|
||||||
|
#### Container environment
|
||||||
|
|
||||||
|
Just fire up your container using `docker run -e "FTP_PASSWORD=my_secret_here" ldericher/kiwi-backup`
|
||||||
|
|
||||||
|
#### Image environment
|
||||||
|
|
||||||
|
Create a simple `Dockerfile` from following template.
|
||||||
|
|
||||||
|
```Dockerfile
|
||||||
|
FROM ldericher/kiwi-backup
|
||||||
|
ENV FTP_PASSWORD="my_secret_here"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### "Secrets" file in container
|
||||||
|
|
||||||
|
Create a shell script:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
export FTP_PASSWORD="my_secret_here"
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, include that file as `/root/duplicity_secrets` into your container by building a custom `Dockerfile` or by mounting it as a (read-only) volume.
|
||||||
|
|
||||||
### Additional options
|
### Additional options
|
||||||
|
|
||||||
There's more environment variables for further customization. You'll likely know if you need to change these.
|
There's more environment variables for further customization. You'll likely know if you need to change these.
|
||||||
|
@ -105,6 +136,9 @@ backup:
|
||||||
# default: some docker volume
|
# default: some docker volume
|
||||||
BACKUP_TARGET: "file:///backup/target"
|
BACKUP_TARGET: "file:///backup/target"
|
||||||
|
|
||||||
|
# Additional options for all "duplicity" commands
|
||||||
|
OPTIONS_ALL: ""
|
||||||
|
|
||||||
# Additional options for "duplicity --full-if-older-than" command
|
# Additional options for "duplicity --full-if-older-than" command
|
||||||
OPTIONS_BACKUP: ""
|
OPTIONS_BACKUP: ""
|
||||||
|
|
||||||
|
|
149
do-plicity
149
do-plicity
|
@ -5,42 +5,13 @@
|
||||||
#############
|
#############
|
||||||
|
|
||||||
# commands
|
# commands
|
||||||
env_exe="$(command -v env)"
|
this_exe="$(command -v "${0}")"
|
||||||
ionice_exe="$(command -v ionice)"
|
ionice_exe="$(command -v ionice)"
|
||||||
duplicity_exe="$(command -v duplicity)"
|
duplicity_exe="$(command -v duplicity)"
|
||||||
|
|
||||||
# files
|
# files
|
||||||
duplicity_secrets_file='/root/duplicity_secrets'
|
duplicity_secrets_file='/root/duplicity_secrets'
|
||||||
|
|
||||||
###############
|
|
||||||
# ENVIRONMENT #
|
|
||||||
###############
|
|
||||||
|
|
||||||
# load secrets file
|
|
||||||
if [ -f "${duplicity_secrets_file}" ]; then
|
|
||||||
# shellcheck disable=SC1090
|
|
||||||
. "${duplicity_secrets_file}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
env_changes=""
|
|
||||||
|
|
||||||
# check if uses encryption
|
|
||||||
if [ -n "${GPG_KEY_ID}" ]; then
|
|
||||||
# gpg key given
|
|
||||||
env_changes="${env_changes} PASSPHRASE='${GPG_PASSPHRASE}'"
|
|
||||||
encrypt_opts="--encrypt-key='${GPG_KEY_ID}'"
|
|
||||||
else
|
|
||||||
# no key given
|
|
||||||
encrypt_opts="--no-encryption"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# check if uses AWS
|
|
||||||
if [ -n "${AWS_ACCESS_KEY_ID}" ]; then
|
|
||||||
# export AWS credentials
|
|
||||||
env_changes="${env_changes} AWS_ACCESS_KEY_ID='${AWS_ACCESS_KEY_ID}'"
|
|
||||||
env_changes="${env_changes} AWS_SECRET_ACCESS_KEY='${AWS_SECRET_ACCESS_KEY}'"
|
|
||||||
fi
|
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# FUNCTIONS #
|
# FUNCTIONS #
|
||||||
#############
|
#############
|
||||||
|
@ -50,15 +21,14 @@ append_options() {
|
||||||
ao_options="${2}"
|
ao_options="${2}"
|
||||||
shift 1
|
shift 1
|
||||||
|
|
||||||
# remove leading whitespace characters
|
if [ -n "${ao_cmdline}" ] && [ -n "${ao_options}" ]; then
|
||||||
ao_options="${ao_options#"${ao_options%%[![:space:]]*}"}"
|
# if both are given, stitch together with a space
|
||||||
# remove trailing whitespace characters
|
|
||||||
ao_options="${ao_options%"${ao_options##*[![:space:]]}"}"
|
|
||||||
|
|
||||||
# if options are given, stitch together with a space
|
|
||||||
if [ -n "${ao_options}" ]; then
|
|
||||||
echo "${ao_cmdline} ${ao_options}"
|
echo "${ao_cmdline} ${ao_options}"
|
||||||
|
elif [ -n "${ao_options}" ]; then
|
||||||
|
# if only options are given, output them
|
||||||
|
echo "${ao_options}"
|
||||||
else
|
else
|
||||||
|
# if at most a cmdline is given, output that
|
||||||
echo "${ao_cmdline}"
|
echo "${ao_cmdline}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -67,33 +37,30 @@ print_command() {
|
||||||
pc_task="${1}"
|
pc_task="${1}"
|
||||||
shift 1
|
shift 1
|
||||||
|
|
||||||
# if environment should be changed, call with "env"
|
pc_cmdline="${ionice_exe} -c 3 ${duplicity_exe}"
|
||||||
if [ -n "${env_changes}" ]; then
|
pc_cmdline="$( append_options "${pc_cmdline}" "${OPTIONS_ALL}" )"
|
||||||
pc_cmdline="${env_exe}${env_changes} "
|
|
||||||
else
|
|
||||||
pc_cmdline=""
|
|
||||||
fi
|
|
||||||
|
|
||||||
pc_cmdline="${pc_cmdline}${ionice_exe} -c 3 ${duplicity_exe} ${encrypt_opts}"
|
|
||||||
|
|
||||||
case "${pc_task}" in
|
case "${pc_task}" in
|
||||||
backup)
|
backup)
|
||||||
pc_cmdline="${pc_cmdline} --allow-source-mismatch --volsize ${BACKUP_VOLSIZE} --full-if-older-than ${FULL_BACKUP_FREQUENCY}"
|
pc_cmdline="$( append_options "${pc_cmdline}" "--allow-source-mismatch" )"
|
||||||
pc_cmdline="$( append_options "${pc_cmdline}" "${OPTIONS_BACKUP} /backup/source" )"
|
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)
|
cleanup)
|
||||||
pc_cmdline="${pc_cmdline} cleanup --force"
|
pc_cmdline="$( append_options "${pc_cmdline}" "cleanup --force" )"
|
||||||
pc_cmdline="$( append_options "${pc_cmdline}" "${OPTIONS_CLEAN}" )"
|
pc_cmdline="$( append_options "${pc_cmdline}" "${OPTIONS_CLEAN}" )"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
rmfull)
|
rmfull)
|
||||||
pc_cmdline="${pc_cmdline} remove-older-than ${BACKUP_RETENTION_TIME} --force"
|
pc_cmdline="$( append_options "${pc_cmdline}" "remove-older-than ${BACKUP_RETENTION_TIME} --force" )"
|
||||||
pc_cmdline="$( append_options "${pc_cmdline}" "${OPTIONS_RMFULL}" )"
|
pc_cmdline="$( append_options "${pc_cmdline}" "${OPTIONS_RMFULL}" )"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
rmincr)
|
rmincr)
|
||||||
pc_cmdline="${pc_cmdline} remove-all-inc-of-but-n-full ${KEEP_NUM_FULL_CHAINS} --force"
|
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}" )"
|
pc_cmdline="$( append_options "${pc_cmdline}" "${OPTIONS_RMINCR}" )"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
@ -122,42 +89,86 @@ print_crontab() {
|
||||||
# don't split the '#' from 'min'
|
# don't split the '#' from 'min'
|
||||||
print_cron_schedule '#_min hour day month weekday' 'command' | tr '_' ' '
|
print_cron_schedule '#_min hour day month weekday' 'command' | tr '_' ' '
|
||||||
|
|
||||||
print_cron_schedule "${SCHEDULE_BACKUP}" "$( print_command backup )"
|
print_cron_schedule "${SCHEDULE_BACKUP}" "${this_exe} backup"
|
||||||
print_cron_schedule "${SCHEDULE_CLEANUP}" "$( print_command cleanup )"
|
print_cron_schedule "${SCHEDULE_CLEANUP}" "${this_exe} cleanup"
|
||||||
print_cron_schedule "${SCHEDULE_RMFULL}" "$( print_command rmfull )"
|
print_cron_schedule "${SCHEDULE_RMFULL}" "${this_exe} rmfull"
|
||||||
print_cron_schedule "${SCHEDULE_RMINCR}" "$( print_command rmincr )"
|
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 #
|
# MAIN #
|
||||||
########
|
########
|
||||||
|
|
||||||
|
|
||||||
if [ "${#}" -gt 0 ]; then
|
if [ "${#}" -gt 0 ]; then
|
||||||
# run a command
|
|
||||||
case "${1}" in
|
# CLI
|
||||||
print-crontab)
|
task="${1}"
|
||||||
print_crontab
|
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
|
||||||
;;
|
;;
|
||||||
|
|
||||||
print-backup|print-cleanup|print-rmfull|print-rmincr)
|
# execute single task
|
||||||
print_command "${1##*-}"
|
|
||||||
;;
|
|
||||||
|
|
||||||
# execute single command
|
|
||||||
backup|cleanup|rmfull|rmincr)
|
backup|cleanup|rmfull|rmincr)
|
||||||
print_command "${1}"
|
# shellcheck disable=SC2091
|
||||||
cmd="$(print_command "${1}")"
|
$(print_command "${task}")
|
||||||
${cmd}
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
# unknown task
|
||||||
*)
|
*)
|
||||||
>&2 echo "Unknown command '${1}'."
|
>&2 echo "Unknown task '${task}'."
|
||||||
|
>&2 echo "Choose from: backup, cleanup, rmfull, rmincr"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
# default run: replace crontab, then start crond
|
# default run: replace crontab, then start crond
|
||||||
print_crontab | crontab -
|
print_crontab | crontab -
|
||||||
crond -fl 8
|
crond -fl 8
|
||||||
|
|
Loading…
Reference in a new issue