A simple backup script
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

150 lines
4.6KB

  1. #!/usr/bin/env bash
  2. __CONFIG_FILE="/etc/backups.conf"
  3. # A simple wrapper for a Gentoo ebuild-like `die`.
  4. die() {
  5. echo "$*" 1>&2
  6. exit 1
  7. }
  8. # Source the configuration file.
  9. [[ -f ${__CONFIG_FILE} ]] || die "Cannot find ${__CONFIG_FILE}. Exiting."
  10. source ${__CONFIG_FILE}
  11. # Check the required / optional variables.
  12. [[ -z ${__BACKUP_DIR} ]] && die "__BACKUP_DIR is not set."
  13. [[ -z ${__BACKUP_EXT} ]] && __BACKUP_EXT=".tar.gz" # default compression format
  14. [[ -z ${__BACKUP_AGE} ]] && __BACKUP_AGE=2 # 2 day-old backups stored by default
  15. # Set the date to be inserted to tarball names.
  16. __DATE="$(date +%Y-%m-%d-%H-%M)"
  17. # Wrapper around `mkdir -p`.
  18. mkdir_p() {
  19. [[ ! -d "${1}" ]] && mkdir -p "${1}" && \
  20. echo "Created ${1} for you."
  21. }
  22. # Create the backup directory if it does not exist yet.
  23. mkdir_p ${__BACKUP_DIR}
  24. # Creates an empty tar archive. Accepts a single parameter, the filename.
  25. empty_archive() {
  26. /usr/bin/env tar -cf "${1}" -T /dev/null --xattrs || \
  27. die "Creating ${1} failed!"
  28. # This works on BSD and Linux. Not tested with others.
  29. }
  30. # Accepts two parameters, the archive filename and the file to be added.
  31. add_to_archive() {
  32. /usr/bin/env tar --xattrs --append -pf 2>/dev/null "${1}" "${2}" || \
  33. die "Adding ${2} to ${1} failed!"
  34. }
  35. clean_up() {
  36. /usr/bin/env find "${1}" -ctime +${__BACKUP_AGE} -delete || \
  37. die "Cleanup failed!"
  38. }
  39. backup_docker() {
  40. echo "Running a Docker volumes backup..."
  41. if [[ -z ${__BACKUP_DIR_DOCKER} ]]; then
  42. __BACKUP_DIR_DOCKER=${__BACKUP_DIR}
  43. fi
  44. mkdir_p ${__BACKUP_DIR_DOCKER}
  45. __FILENAME="${__BACKUP_DIR_DOCKER}/${__DATE}-docker${__BACKUP_EXT}"
  46. # Check the presence of the Docker directory.
  47. [[ -d /var/lib/docker ]] || die "Docker is likely to not be installed."
  48. empty_archive ${__FILENAME}
  49. add_to_archive ${__FILENAME} /var/lib/docker/volumes
  50. }
  51. backup_postgres() {
  52. echo "Running a PostgreSQL databases backup..."
  53. if [[ -z ${__BACKUP_DIR_POSTGRES} ]]; then
  54. __BACKUP_DIR_POSTGRES=${__BACKUP_DIR}
  55. fi
  56. mkdir_p ${__BACKUP_DIR_POSTGRES}
  57. __FILENAME="${__BACKUP_DIR_POSTGRES}/${__DATE}-postgres${__BACKUP_EXT}"
  58. # The databases need to be listed in a special variable.
  59. [[ -z ${__BACKUP_DATABASES} ]] && die "The databases list is not specified."
  60. for database in "${__BACKUP_DATABASES[@]}"; do
  61. __DUMP_NAME="${__FILENAME}-$database"
  62. pg_dump -Fc $database > ${__DUMP_NAME} || \
  63. die "Failed backing up database $database."
  64. add_to_archive ${__FILENAME} ${__DUMP_NAME}
  65. rm ${__DUMP_NAME}
  66. done
  67. }
  68. backup_configs() {
  69. echo "Running config files backups..."
  70. if [[ -z ${__BACKUP_DIR_CONFIGS} ]]; then
  71. __BACKUP_DIR_CONFIGS=${__BACKUP_DIR}
  72. fi
  73. mkdir_p ${__BACKUP_DIR_CONFIGS}
  74. __FILENAME="${__BACKUP_DIR_CONFIGS}/${__DATE}-configs${__BACKUP_EXT}"
  75. # The files to be saved need to be listed in a special variable.
  76. [[ -z ${__BACKUP_FILES} ]] && \
  77. die "The files to be backed up are not specified."
  78. for file in "${__BACKUP_FILES[@]}"; do
  79. add_to_archive ${__FILENAME} $file
  80. done
  81. }
  82. print_help() {
  83. cat <<EOF
  84. backup.sh: a simple backup script.
  85. Usage:
  86. backup.sh [flags]
  87. Options:
  88. -a | --all: run the default set of backups (configs and Docker as of now)
  89. -p | --postgres: run the backups on PostgreSQL databases
  90. -d | --docker: run the backups on Docker volumes
  91. -c | --configs: run the backups on the files specified in /etc/backups.conf
  92. --no-cleanup: don't cleanup after the backup has finished
  93. EOF
  94. }
  95. case ${1} in
  96. "-a" | "--all")
  97. backup_configs
  98. backup_docker
  99. # backup_postgres
  100. # This is commented out by default, as PostgreSQL backups might be
  101. # preferable to run under a separate user.
  102. ;;
  103. "-h" | "--help")
  104. print_help
  105. __BACKUP_NO_CLEANUP=1 # prevent cleanup on displaying help
  106. ;;
  107. *)
  108. while [[ ! -z ${1} ]]; do
  109. case ${1} in
  110. "-d" | "--docker")
  111. backup_docker
  112. ;;
  113. "-p" | "--postgres")
  114. backup_postgres
  115. ;;
  116. "-c" | "--configs")
  117. backup_configs
  118. ;;
  119. "--no-cleanup")
  120. __BACKUP_NO_CLEANUP=1
  121. ;;
  122. esac
  123. shift
  124. done
  125. ;;
  126. esac
  127. if [[ -z ${__BACKUP_NO_CLEANUP} ]]; then
  128. echo "Cleaning up..."
  129. # Run cleanup on every backup directory.
  130. for i in ${__BACKUP_DIR} ${__BACKUP_DIR_CONFIGS} ${__BACKUP_DIR_DOCKER} \
  131. ${__BACKUP_DIR_POSTGRES}; do
  132. [[ ! -z $i ]] && clean_up $i
  133. done
  134. fi