From 2d6485f06cb3fce2ca12dd8c98a361bd73463820 Mon Sep 17 00:00:00 2001 From: Christoph Date: Tue, 17 Dec 2024 00:48:00 +0100 Subject: [PATCH 01/10] Only send log messages on errors. --- borg-backup-nc.sh | 103 +++++++++++++++++++++++++------- borg-backup.sh | 102 +++++++++++++++++++++++-------- conf/borg-backup-nc.conf.sample | 9 +++ conf/borg-backup.conf.sample | 9 +++ 4 files changed, 176 insertions(+), 47 deletions(-) diff --git a/borg-backup-nc.sh b/borg-backup-nc.sh index b3549b9..eae6fb2 100755 --- a/borg-backup-nc.sh +++ b/borg-backup-nc.sh @@ -697,48 +697,105 @@ durationReadable=$(printf "%02d hours %02d minutes %02d seconds" $durationHour $ echo -e "\n\n###### Server backup finished on ${endDateReadable} (${durationReadable}) ######\n" >> ${BORG_LOG_FILE} +blank_line -# Send Summery + +# Error Handling # -if $terminal ; then - echo -e -n " Send Summary.." -fi +declare -i error=$(grep -i -e"\[\s*ERROR" ${BORG_LOG_FILE} | wc -l) +declare -i warning=$(grep -i -e"\[\s*WARN" ${BORG_LOG_FILE} | wc -l) -datum="$(date +"%d.%m.%Y %H:%M")" +if [ $error -gt 0 -o $warning -gt 0 ] ; then -filesystem_usage="$(df -h)" + # Send Summery + # + if $terminal ; then + echo -e -n " Send Summary.." + fi -msg_head_line="\n\n# ---\n# Server backup finished on ${endDateReadable} (${durationReadable})\n# ---\n\n" + datum="$(date +"%d.%m.%Y %H:%M")" -msg="$(cat "${BORG_LOG_FILE}")" + filesystem_usage="$(df -h)" -datum="$(date +"%d.%m.%Y")" + msg_head_line="\n\n# ---\n# Server backup finished on ${endDateReadable} (${durationReadable})\n# ---\n\n" -content_type='Content-Type: text/plain;\n charset="utf-8"' + msg="$(cat "${BORG_LOG_FILE}")" -subject="Borg Backup - ${COMPANY} - ${datum}" -subject_utf8="$(echo "$subject" | iconv -t UTF8)" -subject_utf8_encoded="=?utf-8?B?$(echo $subject_utf8 | base64 --wrap=0)?=" + datum="$(date +"%d.%m.%Y")" + + content_type='Content-Type: text/plain;\n charset="utf-8"' + + subject="Borg Backup - ${COMPANY} - ${datum}" + subject_utf8="$(echo "$subject" | iconv -t UTF8)" + subject_utf8_encoded="=?utf-8?B?$(echo $subject_utf8 | base64 --wrap=0)?=" -cat <> ${BORG_LOG_FILE} - -echo -e "To:${ADMIN_EMAIL}\n${content_type}\nSubject:${subject_utf8_encoded}\n\${filesystem_usage}\n\${msg_head_line}\n\${msg}\n" | /usr/sbin/sendmail -F "BACKUP ${COMPANY}" -f ${FROM_ADDRESS} ${ADMIN_EMAIL} -EOF + echo -e "To:${ADMIN_EMAIL}\n${content_type}\nSubject:${subject_utf8_encoded}\n${filesystem_usage}\n${msg_head_line}\n${msg}\n" | /usr/sbin/sendmail -F "BACKUP ${COMPANY}" -f ${FROM_ADDRESS} ${ADMIN_EMAIL} > ${log_file} 2>&1 -echo -e "To:${ADMIN_EMAIL}\n${content_type}\nSubject:${subject_utf8_encoded}\n${filesystem_usage}\n${msg_head_line}\n${msg}\n" | /usr/sbin/sendmail -F "BACKUP ${COMPANY}" -f ${FROM_ADDRESS} ${ADMIN_EMAIL} > ${log_file} 2>&1 + if [[ $? -gt 0 ]] ; then + echo_failed + error "$(cat "${log_file}")" + else + echo_ok + fi + + blank_line + + # Send Error Message + # + if $terminal ; then + echo -e -n " Send Error Message to ${ADMIN_EMAIL}.." + fi -if [[ $? -gt 0 ]] ; then - echo_failed - error "$(cat "${log_file}")" -else - echo_ok + err_msg="$(grep -A 2 -i -e"\[\s*ERROR" ${BORG_LOG_FILE})\n" + warn_msg="$(grep -A 2 -i -e"\[\s*WARN" ${BORG_LOG_FILE})\n" + + msg_top="Borg Backup Error ${COMPANY} vom ${datum}.\nBorg Backup on '$(hostname -f)' beendet mit:" + msg_body_01="\t${error} Error(s)\n\t${warning} Warning(s)\n" + msg_body_02="\n\n--- ERROR(S) ---\n${err_msg}\n\n--- WARNING(S) ...\n${warn_msg}" + + msg="${msg_top}\n${msg_body_01}\n${msg_body_02}" + + subject="Borg Backup Errors at ${host_name} -- ${datum}" + subject_utf8="$(echo "${subject}" | iconv -t UTF8)" + subject_utf8_encoded="=?utf-8?B?$(echo ${subject_utf8} | base64 --wrap=0)?=" + + echo -e "To:${ADMIN_EMAIL}\n${content_type}\nSubject:${subject_utf8_encoded}\n${msg}\n" | /usr/sbin/sendmail -F "Errors Borg BACKUP ${COMPANY}" -f ${FROM_ADDRESS} ${ADMIN_EMAIL} > ${log_file} 2>&1 + + if [[ $? -gt 0 ]] ; then + echo_failed + error "$(cat "${log_file}")" + else + echo_ok + fi + + if [[ -n "${ADMIN_EXTRA_EMAIL}" ]] ; then + + echo -e "To:${ADMIN_EXTRA_EMAIL}\n${content_type}\nSubject:${subject_utf8_encoded}\n${msg}\n" | /usr/sbin/sendmail -F "Errors Borg BACKUP ${COMPANY}" -f ${FROM_ADDRESS} ${ADMIN_EXTRA_EMAIL} > ${log_file} 2>&1 + + # Send Error Message + # + if $terminal ; then + echo -e -n " Send Error Message to ${ADMIN_EMAIL}.." + fi + + if [[ $? -gt 0 ]] ; then + echo_failed + error "$(cat "${log_file}")" + else + echo_ok + fi + fi + + blank_line + fi blank_line + echononl "Create temporary logorotate configuration file 'logrotate_borg.conf'.." cat << EOF > ${LOCK_DIR}/logrotate_borg.conf 2> ${log_file} diff --git a/borg-backup.sh b/borg-backup.sh index 56f41de..1de0db0 100755 --- a/borg-backup.sh +++ b/borg-backup.sh @@ -666,51 +666,105 @@ durationReadable=$(printf "%02d hours %02d minutes %02d seconds" $durationHour $ echo -e "\n\n###### Server backup finished on ${endDateReadable} (${durationReadable}) ######\n" >> ${BORG_LOG_FILE} - blank_line -# Send Summery +# Error Handling # -if $terminal ; then - echo -e -n " Send Summary.." -fi +declare -i error=$(grep -i -e"\[\s*ERROR" ${BORG_LOG_FILE} | wc -l) +declare -i warning=$(grep -i -e"\[\s*WARN" ${BORG_LOG_FILE} | wc -l) -datum="$(date +"%d.%m.%Y %H:%M")" + if [ $error -gt 0 -o $warning -gt 0 ] ; then -filesystem_usage="$(df -h)" + # Send Summery + # + if $terminal ; then + echo -e -n " Send Summary.." + fi -msg_head_line="\n\n# ---\n# Server backup finished on ${endDateReadable} (${durationReadable})\n# ---\n\n" + datum="$(date +"%d.%m.%Y %H:%M")" -msg="$(cat "${BORG_LOG_FILE}")" + filesystem_usage="$(df -h)" -datum="$(date +"%d.%m.%Y")" + msg_head_line="\n\n# ---\n# Server backup finished on ${endDateReadable} (${durationReadable})\n# ---\n\n" -content_type='Content-Type: text/plain;\n charset="utf-8"' + msg="$(cat "${BORG_LOG_FILE}")" -subject="Borg Backup - ${COMPANY} - ${datum}" -subject_utf8="$(echo "$subject" | iconv -t UTF8)" -subject_utf8_encoded="=?utf-8?B?$(echo $subject_utf8 | base64 --wrap=0)?=" + datum="$(date +"%d.%m.%Y")" + + content_type='Content-Type: text/plain;\n charset="utf-8"' + + subject="Borg Backup - ${COMPANY} - ${datum}" + subject_utf8="$(echo "$subject" | iconv -t UTF8)" + subject_utf8_encoded="=?utf-8?B?$(echo $subject_utf8 | base64 --wrap=0)?=" -cat <> ${BORG_LOG_FILE} - -echo -e "To:${ADMIN_EMAIL}\n${content_type}\nSubject:${subject_utf8_encoded}\n\${filesystem_usage}\n\${msg_head_line}\n\${msg}\n" | /usr/sbin/sendmail -F "BACKUP ${COMPANY}" -f ${FROM_ADDRESS} ${ADMIN_EMAIL} -EOF + echo -e "To:${ADMIN_EMAIL}\n${content_type}\nSubject:${subject_utf8_encoded}\n${filesystem_usage}\n${msg_head_line}\n${msg}\n" | /usr/sbin/sendmail -F "BACKUP ${COMPANY}" -f ${FROM_ADDRESS} ${ADMIN_EMAIL} > ${log_file} 2>&1 -echo -e "To:${ADMIN_EMAIL}\n${content_type}\nSubject:${subject_utf8_encoded}\n${filesystem_usage}\n${msg_head_line}\n${msg}\n" | /usr/sbin/sendmail -F "BACKUP ${COMPANY}" -f ${FROM_ADDRESS} ${ADMIN_EMAIL} > ${log_file} 2>&1 + if [[ $? -gt 0 ]] ; then + echo_failed + error "$(cat "${log_file}")" + else + echo_ok + fi + + blank_line + + # Send Error Message + # + if $terminal ; then + echo -e -n " Send Error Message to ${ADMIN_EMAIL}.." + fi -if [[ $? -gt 0 ]] ; then - echo_failed - error "$(cat "${log_file}")" -else - echo_ok + err_msg="$(grep -A 2 -i -e"\[\s*ERROR" ${BORG_LOG_FILE})\n" + warn_msg="$(grep -A 2 -i -e"\[\s*WARN" ${BORG_LOG_FILE})\n" + + msg_top="Borg Backup Error ${COMPANY} vom ${datum}.\nBorg Backup on '$(hostname -f)' beendet mit:" + msg_body_01="\t${error} Error(s)\n\t${warning} Warning(s)\n" + msg_body_02="\n\n--- ERROR(S) ---\n${err_msg}\n\n--- WARNING(S) ...\n${warn_msg}" + + msg="${msg_top}\n${msg_body_01}\n${msg_body_02}" + + subject="Borg Backup Errors at ${host_name} -- ${datum}" + subject_utf8="$(echo "${subject}" | iconv -t UTF8)" + subject_utf8_encoded="=?utf-8?B?$(echo ${subject_utf8} | base64 --wrap=0)?=" + + echo -e "To:${ADMIN_EMAIL}\n${content_type}\nSubject:${subject_utf8_encoded}\n${msg}\n" | /usr/sbin/sendmail -F "Errors Borg BACKUP ${COMPANY}" -f ${FROM_ADDRESS} ${ADMIN_EMAIL} > ${log_file} 2>&1 + + if [[ $? -gt 0 ]] ; then + echo_failed + error "$(cat "${log_file}")" + else + echo_ok + fi + + if [[ -n "${ADMIN_EXTRA_EMAIL}" ]] ; then + + echo -e "To:${ADMIN_EXTRA_EMAIL}\n${content_type}\nSubject:${subject_utf8_encoded}\n${msg}\n" | /usr/sbin/sendmail -F "Errors Borg BACKUP ${COMPANY}" -f ${FROM_ADDRESS} ${ADMIN_EXTRA_EMAIL} > ${log_file} 2>&1 + + # Send Error Message + # + if $terminal ; then + echo -e -n " Send Error Message to ${ADMIN_EMAIL}.." + fi + + if [[ $? -gt 0 ]] ; then + echo_failed + error "$(cat "${log_file}")" + else + echo_ok + fi + fi + + blank_line + fi blank_line + echononl "Create temporary logorotate configuration file 'logrotate_borg.conf'.." cat << EOF > ${LOCK_DIR}/logrotate_borg.conf 2> ${log_file} diff --git a/conf/borg-backup-nc.conf.sample b/conf/borg-backup-nc.conf.sample index 19d5536..56ff8c4 100644 --- a/conf/borg-backup-nc.conf.sample +++ b/conf/borg-backup-nc.conf.sample @@ -161,6 +161,15 @@ #ADMIN_EMAIL="root" +# ADMIN_EXTRA_EMAIL +# +# Send Informations about the backup process also to this e-mail address +# +# Defaults to empty string (NOT SET) +# +#ADMIN_EXTRA_EMAIL="" + + # FROM_ADDRESS # # Defaults to: diff --git a/conf/borg-backup.conf.sample b/conf/borg-backup.conf.sample index 6d6f3e3..90dfa77 100644 --- a/conf/borg-backup.conf.sample +++ b/conf/borg-backup.conf.sample @@ -197,6 +197,15 @@ #ADMIN_EMAIL="root" +# ADMIN_EXTRA_EMAIL +# +# Send Informations about the backup process also to this e-mail address +# +# Defaults to empty string (NOT SET) +# +#ADMIN_EXTRA_EMAIL="" + + # FROM_ADDRESS # # Defaults to: From d85ce20eba43ce38f1ddf2ae5b1d064e39f28067 Mon Sep 17 00:00:00 2001 From: Christoph Date: Tue, 31 Dec 2024 18:46:33 +0100 Subject: [PATCH 02/10] borg-mount-archiv.sh: print out the commans used to ,ount archive. --- borg-mount-archiv.sh | 196 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 181 insertions(+), 15 deletions(-) diff --git a/borg-mount-archiv.sh b/borg-mount-archiv.sh index 42a1b21..a50fee7 100755 --- a/borg-mount-archiv.sh +++ b/borg-mount-archiv.sh @@ -268,24 +268,26 @@ export BORG_RSH BORG_RELOCATED_REPO_ACCESS_IS_OK=yes export BORG_RELOCATED_REPO_ACCESS_IS_OK -echononl "Create Restore Directory '${BORG_FUSE_MOUNT_DIR}'." -if [ ! -d "${BORG_FUSE_MOUNT_DIR}" ]; then - mkdir -p "${BORG_FUSE_MOUNT_DIR}" > ${log_file} 2>&1 - if [[ $? -gt 0 ]] ; then - echo_failed - error "$(cat "${log_file}")" +blank_line - fatal "No restore directory '${BORG_FUSE_MOUNT_DIR}' present!" - - else - echo_ok - fi -else - echo_skipped +LIST_OF_FILES_OR_DIRECTORIES= +echo -e "\033[32m--\033[m" +echo "" +echo "Specify a space-separated list of files or directories to be part of the mounted filesystem." +echo "" +echo -e " Type \"\033[33mall\033[m\" or leave emty to mount the full archive" +echo "" +echononl "List of files or directories: " +read LIST_OF_FILES_OR_DIRECTORIES +if [[ "X${LIST_OF_FILES_OR_DIRECTORIES}" = "X" ]] || [[ "$(trim ${LIST_OF_FILES_OR_DIRECTORIES,,})" = 'all' ]] ; then + LIST_OF_FILES_OR_DIRECTORIES="" fi blank_line +echo -e "\033[32m--\033[m" +echo "" + # List Borg Backups # @@ -306,9 +308,173 @@ read BORG_BACKUP_ID echo -e " \033[33m--------------------------------------------\033[m" echo "" -echononl "Mount archive '${BORG_REPO}::${BORG_BACKUP_ID}' to '${BORG_FUSE_MOUNT_DIR}'.." +blank_line -borg mount ${BORG_URL}::${BORG_BACKUP_ID} ${BORG_FUSE_MOUNT_DIR} >> "${log_file}" 2>&1 + +echo "" +echo "" +echo -e "\t\033[32mStart script for (readonly) mounting repository archiv '${BORG_BACKUP_ID}'..\033[m" +echo "" +echo -e "\tBORG_HOST......................: ${BORG_HOST}" +echo -e "\tBORG_REPO......................: ${BORG_REPO}" +echo "" +echo -e "\tBORG_PASSPHRASE................: ${BORG_PASSPHRASE}" +echo "" +echo -e "\tSSH_USER ......................: ${SSH_USER}" +echo -e "\tSSH_PORT.......................: ${SSH_PORT}" +echo -e "\tBORG_RSH.......................: ${BORG_RSH}" +echo "" +echo -e "\tBORG_URL.......................: ${BORG_URL}" +echo "" +echo -e "\tBORG_FUSE_MOUNT_DIR............: ${BORG_FUSE_MOUNT_DIR}" +if [[ -z "${LIST_OF_FILES_OR_DIRECTORIES}" ]]; then + echo -e "\tLIST_OF_FILES_OR_DIRECTORIES...: \033[33mMount the full archive\033[m" +else + echo -e "\tLIST_OF_FILES_OR_DIRECTORIES...: ${LIST_OF_FILES_OR_DIRECTORIES}" +fi +echo "" +echo "" + +declare -i _CHOOSE +echo -e " Ho to continue?" +echo "" +echo -e " \033[1m[1] Mount files from repository $(basename "${BORG_REPO}") archive ${BORG_BACKUP_ID}\033[m" +echo -e " [2] Only print out the commands for mounting files/folders" +echo -e " [3] Exit borg2 mount script." +echo "" +echo " Type a number or press to choose highlighted value" +echo "" +echononl "Eingabe: " +while [[ -z "${_CHOOSE}" ]]; do + read OPTION + [[ -z "$OPTION" ]] && OPTION=1 + case $OPTION in + 1) _CHOOSE=1 + ;; + 2) _CHOOSE=2 + ;; + 3) _CHOOSE=3 + ;; + *) + echo "" + echo -e "\tFalsche Eingabe ! [1/2/3] or type for the highlited default" + echo "" + echononl "Eingabe: " + ;; + esac +done + +if [[ ${_CHOOSE} -gt 2 ]] ; then + echo "" + clean_up 0 +elif [[ ${_CHOOSE} -gt 1 ]] ; then + + _MOUNT_DIR_BACKUP_HOST="${BORG_FUSE_MOUNT_DIR}/$(basename "${BORG_REPO}")/${BORG_BACKUP_ID}" + + echo -e "\033[40m\033[37m +----------------------------------------------------------------------------------------- + +export BORG_PASSPHRASE=\"${BORG_PASSPHRASE}\" +export BORG_REPO=\"${BORG_REPO}\" +export BORG_RSH=\"${BORG_RSH}\" +export BORG_RELOCATED_REPO_ACCESS_IS_OK=yes + +mkdir -p \"${BORG_FUSE_MOUNT_DIR}/${BORG_BACKUP_ID}\" + +borg mount ${BORG_URL}::${BORG_BACKUP_ID} ${BORG_FUSE_MOUNT_DIR}/${BORG_BACKUP_ID} ${LIST_OF_FILES_OR_DIRECTORIES} + + +On Backup Host type: +==================== + +export BORG_PASSPHRASE=\"${BORG_PASSPHRASE}\" +export BORG_REPO=\"${BORG_REPO}\" +export BORG_RELOCATED_REPO_ACCESS_IS_OK=yes + +mkdir -p \"${_MOUNT_DIR_BACKUP_HOST}\" + +borg mount ${BORG_REPO}::${BORG_BACKUP_ID} ${_MOUNT_DIR_BACKUP_HOST} ${LIST_OF_FILES_OR_DIRECTORIES} + + +You can find the mounted fuse archive at; + + ${_MOUNT_DIR_BACKUP_HOST} + + +In Order to unmount repository archive type: + + umount ${_MOUNT_DIR_BACKUP_HOST} + +----------------------------------------------------------------------------------------- +\033[m\n" + +clean_up 0 +fi + +echononl "Create Mount Directory '${BORG_FUSE_MOUNT_DIR}/${BORG_BACKUP_ID}'." +if [ ! -d "${BORG_FUSE_MOUNT_DIR}/${BORG_BACKUP_ID}" ]; then + mkdir -p "${BORG_FUSE_MOUNT_DIR}/${BORG_BACKUP_ID}" > ${log_file} 2>&1 + if [[ $? -gt 0 ]] ; then + echo_failed + error "$(cat "${log_file}")" + + fatal "Mount directory '${BORG_FUSE_MOUNT_DIR}/${BORG_BACKUP_ID}' present!" + + else + echo_ok + fi +else + echo_skipped +fi + +blank_line + +_MOUNT_DIR_BACKUP_HOST="${BORG_FUSE_MOUNT_DIR}/$(basename "${BORG_REPO}")/${BORG_BACKUP_ID}" + +echo -e "\033[40m\033[37m +----------------------------------------------------------------------------------------- + +export BORG_PASSPHRASE=\"${BORG_PASSPHRASE}\" +export BORG_REPO=\"${BORG_REPO}\" +export BORG_RSH=\"${BORG_RSH}\" +export BORG_RELOCATED_REPO_ACCESS_IS_OK=yes + +mkdir -p \"${BORG_FUSE_MOUNT_DIR}/${BORG_BACKUP_ID}\" + +borg mount ${BORG_URL}::${BORG_BACKUP_ID} ${BORG_FUSE_MOUNT_DIR}/${BORG_BACKUP_ID} ${LIST_OF_FILES_OR_DIRECTORIES} + + +On Backup Host type: +==================== + +export BORG_PASSPHRASE=\"${BORG_PASSPHRASE}\" +export BORG_REPO=\"${BORG_REPO}\" +export BORG_RELOCATED_REPO_ACCESS_IS_OK=yes + +mkdir -p \"${_MOUNT_DIR_BACKUP_HOST}\" + +borg mount ${BORG_REPO}::${BORG_BACKUP_ID} ${_MOUNT_DIR_BACKUP_HOST} ${LIST_OF_FILES_OR_DIRECTORIES} + + +You can find the mounted fuse archive at; + + ${_MOUNT_DIR_BACKUP_HOST} + + +In Order to unmount repository archive type: + + umount ${_MOUNT_DIR_BACKUP_HOST} + +----------------------------------------------------------------------------------------- +\033[m\n" + + +blank_line + +echo " Mount archive '${BORG_REPO}::${BORG_BACKUP_ID}' to" +echononl " '${BORG_FUSE_MOUNT_DIR}/${BORG_BACKUP_ID}'.." + +borg mount ${BORG_URL}::${BORG_BACKUP_ID} ${BORG_FUSE_MOUNT_DIR}/${BORG_BACKUP_ID} ${LIST_OF_FILES_OR_DIRECTORIES} > "${log_file}" 2>&1 if [[ $? -gt 0 ]] ; then echo_failed From 17a65e641d7edaf55430ea52147cb119b718f8fa Mon Sep 17 00:00:00 2001 From: Christoph Date: Tue, 31 Dec 2024 18:48:22 +0100 Subject: [PATCH 03/10] borg-umount-archiv.sh: umount ALL mounted archives from repository. --- borg-umount-archiv.sh | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/borg-umount-archiv.sh b/borg-umount-archiv.sh index fd3f0cc..df6eabd 100755 --- a/borg-umount-archiv.sh +++ b/borg-umount-archiv.sh @@ -268,15 +268,25 @@ export BORG_RSH BORG_RELOCATED_REPO_ACCESS_IS_OK=yes export BORG_RELOCATED_REPO_ACCESS_IS_OK -echononl "Unmount fuse filesystem mounted at '${BORG_FUSE_MOUNT_DIR}'.." +for _dir in $(ls /mnt/borg-fuse-mount) ; do -borg umount ${BORG_FUSE_MOUNT_DIR} >> "${log_file}" 2>&1 + echononl "Unmount fuse filesystem mounted at '${BORG_FUSE_MOUNT_DIR}/${_dir}'.." + + #borg umount ${BORG_FUSE_MOUNT_DIR} >> "${log_file}" 2>&1 + + if [[ $? -gt 0 ]] ; then + echo_failed + error "$(cat "${log_file}")" + else + echo_ok + fi + + borg umount ${BORG_FUSE_MOUNT_DIR}/${_dir} >> "${log_file}" 2>&1 + + #echo ${_dir} + #umount ${BORG_FUSE_MOUNT_DIR}/${_dir} + rmdir ${BORG_FUSE_MOUNT_DIR}/${_dir} +done -if [[ $? -gt 0 ]] ; then - echo_failed - error "$(cat "${log_file}")" -else - echo_ok -fi clean_up 0 From 4b35efda162795fe1ddf059ed27059ff1b26ec50 Mon Sep 17 00:00:00 2001 From: Christoph Date: Wed, 1 Jan 2025 02:57:26 +0100 Subject: [PATCH 04/10] borg-list-backups.sh: redirect stderr to 'dev/null' for 'borg list' command. --- borg-list-backups.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/borg-list-backups.sh b/borg-list-backups.sh index 99e4dd3..46f763e 100755 --- a/borg-list-backups.sh +++ b/borg-list-backups.sh @@ -282,6 +282,6 @@ while read -r _borg_id _date_weekday _date_date _date_time _time_stamp_borg_bac echo -e " ${_date_weekday} ${_date_date} ${_date_time} [ \033[33m${_borg_id}\033[m ]" -done < <(borg list ${BORG_URL}) +done < <(borg list ${BORG_URL} 2> /dev/null) clean_up 0 From 8bd5fd5eedcab63b417b4501e32dec55bd535777 Mon Sep 17 00:00:00 2001 From: Christoph Date: Wed, 1 Jan 2025 03:01:26 +0100 Subject: [PATCH 05/10] borg-umount-archiv.sh: some minor changes on script output. --- borg-umount-archiv.sh | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/borg-umount-archiv.sh b/borg-umount-archiv.sh index df6eabd..5b9dc27 100755 --- a/borg-umount-archiv.sh +++ b/borg-umount-archiv.sh @@ -268,9 +268,11 @@ export BORG_RSH BORG_RELOCATED_REPO_ACCESS_IS_OK=yes export BORG_RELOCATED_REPO_ACCESS_IS_OK -for _dir in $(ls /mnt/borg-fuse-mount) ; do +declare -i index=0 +for _dir in $(ls /mnt/borg-fuse-mount) ; do - echononl "Unmount fuse filesystem mounted at '${BORG_FUSE_MOUNT_DIR}/${_dir}'.." + echo " Unmount fuse filesystem mounted at" + echo -e -n " '${BORG_FUSE_MOUNT_DIR}/${_dir}'.." #borg umount ${BORG_FUSE_MOUNT_DIR} >> "${log_file}" 2>&1 @@ -283,10 +285,16 @@ for _dir in $(ls /mnt/borg-fuse-mount) ; do borg umount ${BORG_FUSE_MOUNT_DIR}/${_dir} >> "${log_file}" 2>&1 - #echo ${_dir} + #echo ${_dir} #umount ${BORG_FUSE_MOUNT_DIR}/${_dir} rmdir ${BORG_FUSE_MOUNT_DIR}/${_dir} + + ((index++)) done +if [[ $index -lt 1 ]] ; then + warn "No borgfs mounted." +fi + clean_up 0 From 7f1114500a4948b05bc230f818f0e0a0081a3903 Mon Sep 17 00:00:00 2001 From: Christoph Date: Wed, 1 Jan 2025 13:01:15 +0100 Subject: [PATCH 06/10] Add script 'borg-extract-archiv.sh'. --- borg-extract-archiv.sh | 666 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 666 insertions(+) create mode 100755 borg-extract-archiv.sh diff --git a/borg-extract-archiv.sh b/borg-extract-archiv.sh new file mode 100755 index 0000000..646ebc8 --- /dev/null +++ b/borg-extract-archiv.sh @@ -0,0 +1,666 @@ +#!/usr/bin/env bash + +script_name="$(basename $(realpath $0))" +working_dir="$(dirname $(realpath $0))" + + +if [[ -f "${working_dir}/conf/borg-backup-nc.conf" ]] ; then + conf_file="${working_dir}/conf/borg-backup-nc.conf" +else + conf_file="${working_dir}/conf/borg-backup.conf" +fi + +LOCK_DIR="/tmp/${script_name%%.*}.LOCK" +log_file="${LOCK_DIR}/${script_name%%.*}.log" + + + +# ---------- +# Base Function(s) +# ---------- + +clean_up() { + + # Perform program exit housekeeping + rm -rf "$LOCK_DIR" + blank_line + exit $1 +} + +echononl(){ + if $terminal ; then + + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n " $*\\c" 1>&2 + else + echo -e -n " $*" 1>&2 + fi + rm /tmp/shprompt$$ + + fi + +} + +fatal(){ + echo "" + if $terminal ; then + echo -e " [ \033[31m\033[1mFatal\033[m ]: $*" + echo "" + echo -e " \033[31m\033[1mScript was interupted\033[m!" + else + echo " [ Fatal ]: $*" + echo "" + echo " Script was terminated...." + fi + echo "" + clean_up 1 +} +error (){ + echo "" + if $terminal ; then + echo -e " [ \033[31m\033[1mError\033[m ]: $*" + else + echo "[ Error ]: $*" + fi +} + +warn (){ + echo "" + if $terminal ; then + echo -e " [ \033[33m\033[1mWarning\033[m ]: $*" + else + echo "[ Warning ]: $*" + fi + echo "" +} + +warn_only_terminal () { + if $terminal ; then + echo "" + echo -e "\t[ \033[33m\033[1mWarning\033[m ]: $*" + echo "" + fi +} + +info (){ + if $terminal ; then + echo "" + echo -e " [ \033[32m\033[1mInfo\033[m ] $*" + echo "" + fi +} + +ok (){ + if $terminal ; then + echo "" + echo -e " [ \033[32m\033[1mOk\033[m ] $*" + echo "" + fi +} + +echo_done() { + if $terminal ; then + echo -e "\033[75G[ \033[32mdone\033[m ]" + fi +} +echo_ok() { + if $terminal ; then + echo -e "\033[75G[ \033[32mok\033[m ]" + fi +} +echo_warn() { + if $terminal ; then + echo -e "\033[75G[ \033[33mwarn\033[m ]" + fi +} +echo_failed(){ + if $terminal ; then + echo -e "\033[75G[ \033[1;31mfailed\033[m ]" + fi +} +echo_skipped() { + if $terminal ; then + echo -e "\033[75G[ \033[90m\033[1mskipped\033[m ]" + fi +} +echo_wait(){ + if $terminal ; then + echo -en "\033[75G[ \033[5m\033[1m...\033[m ]" + fi +} + +trim() { + local var="$*" + var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters + var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters + echo -n "$var" +} + +blank_line() { + if $terminal ; then + echo "" + fi +} + +# ---------- +# - Some checks .. +# ---------- + +# - Running in a terminal? +# - +if [[ -t 1 ]] ; then + terminal=true +else + terminal=false +fi + + +# ------------- +# - Job is already running? +# ------------- + +# - If job already runs, stop execution.. +# - +if mkdir "$LOCK_DIR" 2> /dev/null ; then + + ## - Remove lockdir when the script finishes, or when it receives a signal + trap "clean_up 1" SIGHUP SIGINT SIGTERM + +else + + datum="$(date +"%d.%m.%Y %H:%M")" + + msg="[ Error ]: A previos instance of \"`basename $0`\" seems already be running.\n\n Exiting now.." + + echo "" + echo "[ Error ]: A previos instance of that script \"`basename $0`\" seems already be running." + echo "" + echo -e " Exiting now.." + echo "" + + for _email in ${alert_email_arr[@]} ; do + echo -e "To:${_email}\n${content_type}\nSubject:Error cronjob `basename $0` -- $datum\n${msg}\n" \ + | sendmail -F "Error `hostname -f`" -f $sender_address $_email + done + + exit 1 + +fi + + +# ========== +# - Begin Main Script +# ========== + +# ---------- +# - Headline +# ---------- + +if $terminal ; then + echo "" + echo -e "\033[1m----------\033[m" + echo -e "\033[32m\033[1mRunning script \033[m\033[1m$script_name\033[32m .. \033[m" + echo -e "\033[1m----------\033[m" + echo "" +fi + +# ---------- +# Default values +# ---------- + +DEFAULT_SSH_USER="borg" +DEFAULT_SSH_PORT=22 +DEFAULT_BORG_RSH='ssh -i /root/.ssh/id_ed25519-borg-backup' + +# ---------- +# Read Configurations from $conf_file +# ---------- + + +if [[ -f "$conf_file" ]]; then + source "$conf_file" +else + fatal "No configuration file '$conf_file' present!" +fi + + +# ---------- +# Set Parameter values +# ---------- + +#if [[ -z "${BORG_PASSPHRASE}" ]] ; then +# fatal "Borg Passphrase (BORG_PASSPHRASE) NOT found!" +#fi + +[[ -n "${BORG_PASSPHRASE}" ]] && _BORG_PASSPHRASE="${BORG_PASSPHRASE}" + +[[ -n "${BORG_HOST}" ]] && _BORG_HOST="${BORG_HOST}" + +[[ -n "${BORG_REPO}" ]] && _BORG_REPO="${BORG_REPO}" + +if [[ -n "${SSH_USER}" ]] ; then + _SSH_USER="${SSH_USER}" +else + _SSH_USER="${DEFAULT_SSH_USER}" +fi + +if [[ -n "${SSH_PORT}" ]] ; then + _SSH_PORT="${SSH_PORT}" +else + _SSH_PORT="${DEFAULT_SSH_PORT}" +fi + +if [[ -n "${BORG_RSH}" ]] ; then + _BORG_RSH="${BORG_RSH}" +else + _BORG_RSH="${DEFAULT_BORG_RSH}" +fi + +[[ -z "${BORG_FUSE_MOUNT_DIR}" ]] && BORG_FUSE_MOUNT_DIR="${DEFAULT_BORG_FUSE_MOUNT_DIR}" + +# --- +# Some automatic “answerers” (if set, they automatically answer confirmation questions): +# --- + +# For 'Warning: The repository at location … was previously located at ..' +# +BORG_RELOCATED_REPO_ACCESS_IS_OK=yes +export BORG_RELOCATED_REPO_ACCESS_IS_OK + +FQHN_BORG_HOSTNAME="" +echo -e "\033[32m--\033[m" +echo "" +echo "Specify the computer that hosts the borg repository." +echo "" +if [[ -n "${_BORG_HOST}" ]] ; then + while [[ "X${FQHN_BORG_HOSTNAME}" = "X" ]]; do + echononl "Borg Repository Host [${_BORG_HOST}]: " + read FQHN_BORG_HOSTNAME + if [[ "X${FQHN_BORG_HOSTNAME}" = "X" ]]; then + FQHN_BORG_HOSTNAME="${_BORG_HOST}" + break + fi + if [[ ${FQHN_BORG_HOSTNAME} =~ ^127 ]] || [[ "${FQHN_BORG_HOSTNAME,,}" =~ "localhost" ]] ; then + break + fi + if [[ ! ${FQHN_BORG_HOSTNAME} =~ \. ]]; then + echo -e "\n\tGiven Host \033[33m\033[1m${FQHN_BORG_HOSTNAME}\033[m seems not to be a full qualified hostname.\n" + FQHN_BORG_HOSTNAME="" + fi + done +else + while [[ "X${FQHN_BORG_HOSTNAME}" = "X" ]]; do + echononl "Full borg hostname: " + read FQHN_BORG_HOSTNAME + if [[ "X${FQHN_BORG_HOSTNAME}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mFull qualified hostname is reqired\033[m\n" + fi + if [[ ! $FQHN_BORG_HOSTNAME =~ \. ]]; then + echo -e "\n\tGiven Host \033[33m\033[1m$FQHN_BORG_HOSTNAME\033[m seems not to be a full qualified hostname.\n" + FQHN_BORG_HOSTNAME="" + fi + done +fi +BORG_HOST="${FQHN_BORG_HOSTNAME,,}" + + +FQPN_BORG_REPO="" +echo -e "\033[32m--\033[m" +echo "" +echo "Specify the borg repository path from which files are to be extracted." +echo "" +if [[ -n "${_BORG_REPO}" ]] ; then + echononl "Full Qualified Borg Repository Path [${_BORG_REPO}]: " + read FQPN_BORG_REPO + if [[ "X${FQPN_BORG_REPO}" = "X" ]]; then + FQPN_BORG_REPO="${_BORG_REPO}" + fi +else + while [[ "X${FQPN_BORG_REPO}" = "X" ]]; do + echononl "Full Qualified Borg Repository Path: " + read FQPN_BORG_REPO + if [[ "X${FQPN_BORG_REPO}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mFull qualified hostname is reqired\033[m\n" + fi + done +fi +BORG_REPO="${FQPN_BORG_REPO%%.*}" + + +LIST_OF_FILES_TO_RESTORE= +echo -e "\033[32m--\033[m" +echo "" +echo "Specify a space-separated list of files or directories to be restored." +echo "" +echo -e " Type \"\033[33mall\033[m\" or leave emty to restore the full archive" +echo "" +echononl "List of files or directories: " +read LIST_OF_FILES_TO_RESTORE +if [[ "X${LIST_OF_FILES_TO_RESTORE}" = "X" ]] || [[ "$(trim ${LIST_OF_FILES_TO_RESTORE,,})" = 'all' ]] ; then + LIST_OF_FILES_TO_RESTORE="" +fi + + +BORG_PASSPHRASE="" +echo -e "\033[32m--\033[m" +echo "" +echo "Specify the password for borg repository '$(basename "${BORG_REPO}")'." +echo "" +if [[ -n "${_BORG_PASSPHRASE}" ]] ; then + echononl "Repositories Passphrase [${_BORG_PASSPHRASE}]: " + read BORG_PASSPHRASE + if [[ "X${BORG_PASSPHRASE}" = "X" ]]; then + BORG_PASSPHRASE="${_BORG_PASSPHRASE}" + fi +else + while [[ "X${BORG_PASSPHRASE}" = "X" ]]; do + echononl "Repositories Passphrase: " + read BORG_PASSPHRASE + if [[ "X${BORG_PASSPHRASE}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1m is reqired\033[m\n" + fi + done +fi + + +SSH_USER="" +echo -e "\033[32m--\033[m" +echo "" +echo "Specify the ssh user to connect to the Borg host '${BORG_HOST}'." +echo "" +echononl "SSH user [${_SSH_USER}]: " +read SSH_USER +if [[ "X${SSH_USER}" = "X" ]]; then + SSH_USER="${_SSH_USER}" +fi + + +SSH_PORT="" +echo -e "\033[32m--\033[m" +echo "" +echo "Specify the ssh port to connect to the Borg host '${BORG_HOST}'." +echo "" +while [[ "X${SSH_PORT}" = "X" ]]; do + echononl "SSH user [${_SSH_PORT}]: " + read SSH_PORT + if [[ "X${SSH_PORT}" = "X" ]]; then + SSH_PORT="${_SSH_PORT}" + fi +done + + +BORG_RSH="" +echo -e "\033[32m--\033[m" +echo "" +echo "Specify the ssh command which is used to connect to the Borg host '${BORG_HOST}'." +echo "" +while [[ "X${BORG_RSH}" = "X" ]]; do + echononl "SSH command [${_BORG_RSH}]: " + read BORG_RSH + if [[ "X${BORG_RSH}" = "X" ]]; then + BORG_RSH="${_BORG_RSH}" + fi +done + +blank_line + +echo -e "\033[32m--\033[m" +echo "" + +# List Borg Backups +# +( + source ${working_dir}/borg-list-backups.sh +) + +BORG_BACKUP_ID="" +echo "" +echo -e " \033[33m---------------------------------------------\033[m" +echo " Which Borg Archiv should be extracted?" +echo "" +echo " Give a Borg Backup ID from above list" +echo "" +while [[ "X${BORG_BACKUP_ID}" = "X" ]]; do + echo -n " Borg Backup ID: " + read BORG_BACKUP_ID + if [[ "X$(trim ${BORG_BACKUP_ID})" = "X" ]] ; then + echo -e "\n\t\033[33m\033[1mIncorrect entry\033[m\n" + fi +done +echo -e " \033[33m---------------------------------------------\033[m" +echo "" + +export BORG_PASSPHRASE +export BORG_REPO +export BORG_RSH + +_BORG_RESTORE_PATH="/data/RESTORE/$(basename "${BORG_REPO}")/${BORG_BACKUP_ID}" + +BORG_RESTORE_PATH="" +echo -e "\033[32m--\033[m" +echo "" +echo "Specify the pathname to which the archive or parts of it are to be restored.." +echo "" +while [[ "X${BORG_RESTORE_PATH}" = "X" ]]; do + echononl "FQPN of restore path [${_BORG_RESTORE_PATH}]: " + read BORG_RESTORE_PATH + if [[ "X${BORG_RESTORE_PATH}" = "X" ]]; then + BORG_RESTORE_PATH="${_BORG_RESTORE_PATH}" + fi +done + + +if [[ ${BORG_HOST} =~ ^127 ]] || [[ ${BORG_HOST,,} =~ localhost ]] ; then + BORG_URL="${BORG_REPO}" +else + BORG_URL="ssh://${SSH_USER}@${BORG_HOST}:${SSH_PORT}${BORG_REPO}" +fi + + +blank_line + + +echo "" +echo "" +echo -e "\t\033[32mStart script for extracting borg backup..\033[m" +echo "" +echo -e "\tBORG_HOST................: ${BORG_HOST}" +echo -e "\tBORG_REPO................: ${BORG_REPO}" +echo "" +echo -e "\tBORG_PASSPHRASE..........: ${BORG_PASSPHRASE}" +echo "" +echo -e "\tSSH_USER ................: ${SSH_USER}" +echo -e "\tSSH_PORT.................: ${SSH_PORT}" +echo -e "\tBORG_RSH.................: ${BORG_RSH}" +echo "" +echo -e "\tBORG_URL.................: ${BORG_URL}" +echo "" +echo -e "\tBORG_RESTORE_PATH........: ${BORG_RESTORE_PATH}" +if [[ -z "${LIST_OF_FILES_TO_RESTORE}" ]]; then + echo -e "\tLIST_OF_FILES_TO_RESTORE.: \033[33mRestore the full archive\033[m" +else + echo -e "\tLIST_OF_FILES_TO_RESTORE.: ${LIST_OF_FILES_TO_RESTORE}" +fi +echo "" +echo "" + +declare -i _CHOOSE +echo -e " Ho to continue?" +echo "" +echo -e " \033[1m[1] Restore files from repository $(basename "${BORG_REPO}") archive ${BORG_BACKUP_ID}\033[m" +echo -e " [2] Only print out the commands for restoring files/folders" +echo -e " [3] Exit borg extract script." +echo "" +echo " Type a number or press to choose highlighted value" +echo "" +echononl "Eingabe: " +while [[ -z "${_CHOOSE}" ]]; do + read OPTION + [[ -z "$OPTION" ]] && OPTION=1 + case $OPTION in + 1) _CHOOSE=1 + ;; + 2) _CHOOSE=2 + ;; + 3) _CHOOSE=3 + ;; + *) + echo "" + echo -e "\tFalsche Eingabe ! [1/2/3] or type for the highlited default" + echo "" + echononl "Eingabe: " + ;; + esac +done + +if [[ ${_CHOOSE} -gt 2 ]] ; then + echo "" + clean_up 0 +elif [[ ${_CHOOSE} -gt 1 ]] ; then + + echo -e "\033[40m\033[37m +----------------------------------------------------------------------------------------- + +export BORG_PASSPHRASE=\"${BORG_PASSPHRASE}\" +export BORG_REPO=\"${BORG_REPO}\" +export BORG_RSH=\"${BORG_RSH}\" +export BORG_RELOCATED_REPO_ACCESS_IS_OK=yes + +mkdir -p \"${BORG_RESTORE_PATH}\" + +cd \"${BORG_RESTORE_PATH}\" + +borg --remote-path borg extract ${BORG_URL}::${BORG_BACKUP_ID} ${LIST_OF_FILES_TO_RESTORE} +" + if [[ ! ${BORG_HOST} =~ ^127 ]] && [[ ! ${BORG_HOST,,} =~ localhost ]] ; then + + echo -e " +On Backup Host type: +==================== + +export BORG_PASSPHRASE=\"${BORG_PASSPHRASE}\" +export BORG_REPO=\"${BORG_REPO}\" +export BORG_RELOCATED_REPO_ACCESS_IS_OK=yes + +mkdir -p \"${BORG_RESTORE_PATH}\" + +cd "${BORG_RESTORE_PATH}" + +borg --remote-path borg extract ${BORG_REPO}::${BORG_BACKUP_ID} ${LIST_OF_FILES_TO_RESTORE} +" + fi + + echo -e "-----------------------------------------------------------------------------------------\033[m\n" + clean_up 0 +fi + +echo "" +info "\033[32mStart restoring from archive with the above settings\033[m?" +echo -n " To continue type uppercase 'YES': " +read OK +echo "" +if [[ "$OK" != "YES" ]] ; then + fatal "Abort by user request - Answer as not 'YES'" +fi + +blank_line + +echononl "Create Restore Directory '${BORG_RESTORE_PATH}'." +if [ ! -d "${BORG_RESTORE_PATH}" ]; then + mkdir -p "${BORG_RESTORE_PATH}" > ${log_file} 2>&1 + if [[ $? -gt 0 ]] ; then + echo_failed + error "$(cat "${log_file}")" + + fatal "Creating restore directory '${BORG_RESTORE_PATH}' failed!" + + else + echo_ok + fi +else + echo_skipped +fi + +blank_line + + +echononl "Change into Restore Path '${BORG_RESTORE_PATH}'.." + +cd "${BORG_RESTORE_PATH}" > ${log_file} 2>&1 + +if [[ $? -gt 0 ]] ; then + echo_failed + fatal "$(cat "${log_file}")" +else + echo_ok +fi + +blank_line + +echo -e "\033[40m\033[37m +----------------------------------------------------------------------------------------- + +export BORG_PASSPHRASE=\"${BORG_PASSPHRASE}\" +export BORG_REPO=\"${BORG_REPO}\" +export BORG_RSH=\"${BORG_RSH}\" +export BORG_RELOCATED_REPO_ACCESS_IS_OK=yes + +mkdir -p \"${BORG_RESTORE_PATH}\" + +cd \"${BORG_RESTORE_PATH}\" + +borg --remote-path borg extract ${BORG_URL}::${BORG_BACKUP_ID} ${LIST_OF_FILES_TO_RESTORE} +" +if [[ ! ${BORG_HOST} =~ ^127 ]] && [[ ! ${BORG_HOST,,} =~ localhost ]] ; then + + echo -e " +On Backup Host type: +==================== + +export BORG_PASSPHRASE=\"${BORG_PASSPHRASE}\" +export BORG_REPO=\"${BORG_REPO}\" +export BORG_RELOCATED_REPO_ACCESS_IS_OK=yes + +mkdir -p \"${BORG_RESTORE_PATH}\" + +cd "${BORG_RESTORE_PATH}" + +borg --remote-path borg extract ${BORG_REPO}::${BORG_BACKUP_ID} ${LIST_OF_FILES_TO_RESTORE} +" +fi +echo -e "-----------------------------------------------------------------------------------------\033[m\n" + + +blank_line + +echo " Restore from archive '$(basename "${BORG_REPO}")::${BORG_BACKUP_ID}' to" +echononl " '${BORG_RESTORE_PATH}'.." + +if [[ ${BORG_HOST} =~ ^127 ]] || [[ ${BORG_HOST,,} =~ localhost ]] ; then + borg --remote-path borg extract ${BORG_REPO}::${BORG_BACKUP_ID} ${LIST_OF_FILES_TO_RESTORE} > "${log_file}" 2>&1 + if [[ $? -gt 0 ]] ; then + echo_failed + error "$(cat "${log_file}")" + else + echo_ok + fi +else + borg --remote-path borg extract ${BORG_URL}::${BORG_BACKUP_ID} ${LIST_OF_FILES_TO_RESTORE} > "${log_file}" 2>&1 + if [[ $? -gt 0 ]] ; then + echo_failed + error "$(cat "${log_file}")" + else + echo_ok + fi +fi + + +blank_line + +info "The data restored from the archive can be found in the directory: + + \033[1m${BORG_RESTORE_PATH}\033[m" + +clean_up 0 + From 957993aff537fece7d3d3d7a6cbbf10cab4ca0e3 Mon Sep 17 00:00:00 2001 From: Christoph Date: Wed, 1 Jan 2025 13:30:26 +0100 Subject: [PATCH 07/10] borg-extract-archiv.sh,borg-list-backups.sh: some minor fixes in case og localhost. --- borg-extract-archiv.sh | 84 ++++++++++++++++++++++-------------------- borg-list-backups.sh | 4 +- 2 files changed, 48 insertions(+), 40 deletions(-) diff --git a/borg-extract-archiv.sh b/borg-extract-archiv.sh index 646ebc8..ed1da14 100755 --- a/borg-extract-archiv.sh +++ b/borg-extract-archiv.sh @@ -221,7 +221,8 @@ DEFAULT_BORG_RSH='ssh -i /root/.ssh/id_ed25519-borg-backup' if [[ -f "$conf_file" ]]; then source "$conf_file" else - fatal "No configuration file '$conf_file' present!" + warn "No configuration file '$conf_file' present!" + #fatal "No configuration file '$conf_file' present!" fi @@ -281,7 +282,7 @@ if [[ -n "${_BORG_HOST}" ]] ; then FQHN_BORG_HOSTNAME="${_BORG_HOST}" break fi - if [[ ${FQHN_BORG_HOSTNAME} =~ ^127 ]] || [[ "${FQHN_BORG_HOSTNAME,,}" =~ "localhost" ]] ; then + if [[ ${FQHN_BORG_HOSTNAME} =~ ^127 ]] || [[ "${FQHN_BORG_HOSTNAME,,}" = "localhost" ]] ; then break fi if [[ ! ${FQHN_BORG_HOSTNAME} =~ \. ]]; then @@ -293,6 +294,9 @@ else while [[ "X${FQHN_BORG_HOSTNAME}" = "X" ]]; do echononl "Full borg hostname: " read FQHN_BORG_HOSTNAME + if [[ ${FQHN_BORG_HOSTNAME} =~ ^127 ]] || [[ "${FQHN_BORG_HOSTNAME,,}" = "localhost" ]] ; then + break + fi if [[ "X${FQHN_BORG_HOSTNAME}" = "X" ]]; then echo -e "\n\t\033[33m\033[1mFull qualified hostname is reqired\033[m\n" fi @@ -363,46 +367,48 @@ else done fi +if [[ ! ${FQHN_BORG_HOSTNAME} =~ ^127 ]] && [[ ! "${FQHN_BORG_HOSTNAME,,}" = "localhost" ]] ; then -SSH_USER="" -echo -e "\033[32m--\033[m" -echo "" -echo "Specify the ssh user to connect to the Borg host '${BORG_HOST}'." -echo "" -echononl "SSH user [${_SSH_USER}]: " -read SSH_USER -if [[ "X${SSH_USER}" = "X" ]]; then - SSH_USER="${_SSH_USER}" + SSH_USER="" + echo -e "\033[32m--\033[m" + echo "" + echo "Specify the ssh user to connect to the Borg host '${BORG_HOST}'." + echo "" + echononl "SSH user [${_SSH_USER}]: " + read SSH_USER + if [[ "X${SSH_USER}" = "X" ]]; then + SSH_USER="${_SSH_USER}" + fi + + + SSH_PORT="" + echo -e "\033[32m--\033[m" + echo "" + echo "Specify the ssh port to connect to the Borg host '${BORG_HOST}'." + echo "" + while [[ "X${SSH_PORT}" = "X" ]]; do + echononl "SSH user [${_SSH_PORT}]: " + read SSH_PORT + if [[ "X${SSH_PORT}" = "X" ]]; then + SSH_PORT="${_SSH_PORT}" + fi + done + + + BORG_RSH="" + echo -e "\033[32m--\033[m" + echo "" + echo "Specify the ssh command which is used to connect to the Borg host '${BORG_HOST}'." + echo "" + while [[ "X${BORG_RSH}" = "X" ]]; do + echononl "SSH command [${_BORG_RSH}]: " + read BORG_RSH + if [[ "X${BORG_RSH}" = "X" ]]; then + BORG_RSH="${_BORG_RSH}" + fi + done fi - -SSH_PORT="" -echo -e "\033[32m--\033[m" -echo "" -echo "Specify the ssh port to connect to the Borg host '${BORG_HOST}'." -echo "" -while [[ "X${SSH_PORT}" = "X" ]]; do - echononl "SSH user [${_SSH_PORT}]: " - read SSH_PORT - if [[ "X${SSH_PORT}" = "X" ]]; then - SSH_PORT="${_SSH_PORT}" - fi -done - - -BORG_RSH="" -echo -e "\033[32m--\033[m" -echo "" -echo "Specify the ssh command which is used to connect to the Borg host '${BORG_HOST}'." -echo "" -while [[ "X${BORG_RSH}" = "X" ]]; do - echononl "SSH command [${_BORG_RSH}]: " - read BORG_RSH - if [[ "X${BORG_RSH}" = "X" ]]; then - BORG_RSH="${_BORG_RSH}" - fi -done - blank_line echo -e "\033[32m--\033[m" diff --git a/borg-list-backups.sh b/borg-list-backups.sh index 46f763e..2ddf68a 100755 --- a/borg-list-backups.sh +++ b/borg-list-backups.sh @@ -228,7 +228,9 @@ DEFAULT_BORG_RSH='ssh -i /root/.ssh/id_ed25519-borg-backup' if [[ -f "$conf_file" ]]; then source "$conf_file" else - fatal "No configuration file '$conf_file' present!" + if [[ -z "${BORG_HOST}" ]] || [[ -z "${BORG_REPO}" ]] || [[ -z "${BORG_PASSPHRASE}" ]] ; then + fatal "No configuration file '$conf_file' present!" + fi fi From ef9886bd52116f7c1ffa3e0d4ba6ab42194d2a1e Mon Sep 17 00:00:00 2001 From: Christoph Date: Wed, 1 Jan 2025 14:17:02 +0100 Subject: [PATCH 08/10] borg-list-backups.sh: Add support for running script om backup host. --- borg-list-backups.sh | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/borg-list-backups.sh b/borg-list-backups.sh index 2ddf68a..9bd3f1b 100755 --- a/borg-list-backups.sh +++ b/borg-list-backups.sh @@ -225,11 +225,11 @@ DEFAULT_BORG_RSH='ssh -i /root/.ssh/id_ed25519-borg-backup' # ---------- -if [[ -f "$conf_file" ]]; then - source "$conf_file" -else - if [[ -z "${BORG_HOST}" ]] || [[ -z "${BORG_REPO}" ]] || [[ -z "${BORG_PASSPHRASE}" ]] ; then - fatal "No configuration file '$conf_file' present!" +if [[ -z "${BORG_HOST}" ]] || [[ -z "${BORG_REPO}" ]] || [[ -z "${BORG_PASSPHRASE}" ]] ; then + if [[ -f "$conf_file" ]]; then + source "$conf_file" + else + fatal "No configuration file '$conf_file' present!" fi fi @@ -280,10 +280,18 @@ export BORG_RELOCATED_REPO_ACCESS_IS_OK echo -e " \033[1mDate\033[33GBorg Backup ID\033[m\n" -while read -r _borg_id _date_weekday _date_date _date_time _time_stamp_borg_backup || [[ -n $_line ]] ; do +if [[ ${BORG_HOST} =~ ^127 ]] || [[ "${BORG_HOST,,}" =~ "localhost" ]] ; then + while read -r _borg_id _date_weekday _date_date _date_time _time_stamp_borg_backup || [[ -n $_line ]] ; do - echo -e " ${_date_weekday} ${_date_date} ${_date_time} [ \033[33m${_borg_id}\033[m ]" + echo -e " ${_date_weekday} ${_date_date} ${_date_time} [ \033[33m${_borg_id}\033[m ]" -done < <(borg list ${BORG_URL} 2> /dev/null) + done < <(borg list ${BORG_REPO} 2> /dev/null) +else + while read -r _borg_id _date_weekday _date_date _date_time _time_stamp_borg_backup || [[ -n $_line ]] ; do + + echo -e " ${_date_weekday} ${_date_date} ${_date_time} [ \033[33m${_borg_id}\033[m ]" + + done < <(borg list ${BORG_URL} 2> /dev/null) +fi clean_up 0 From ebca1bde5de34d97e8f85c52b5b4b334b2cf0ad2 Mon Sep 17 00:00:00 2001 From: Christoph Date: Wed, 1 Jan 2025 14:18:54 +0100 Subject: [PATCH 09/10] borg-extract-archiv.sh: call script 'borg-list-backups.sh' with the right values. --- borg-extract-archiv.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/borg-extract-archiv.sh b/borg-extract-archiv.sh index ed1da14..718ec07 100755 --- a/borg-extract-archiv.sh +++ b/borg-extract-archiv.sh @@ -329,7 +329,7 @@ else fi done fi -BORG_REPO="${FQPN_BORG_REPO%%.*}" +BORG_REPO="${FQPN_BORG_REPO}" LIST_OF_FILES_TO_RESTORE= @@ -407,6 +407,8 @@ if [[ ! ${FQHN_BORG_HOSTNAME} =~ ^127 ]] && [[ ! "${FQHN_BORG_HOSTNAME,,}" = " BORG_RSH="${_BORG_RSH}" fi done + + export BORG_RSH fi blank_line @@ -414,6 +416,10 @@ blank_line echo -e "\033[32m--\033[m" echo "" +export BORG_HOST +export BORG_PASSPHRASE +export BORG_REPO + # List Borg Backups # ( @@ -437,9 +443,6 @@ done echo -e " \033[33m---------------------------------------------\033[m" echo "" -export BORG_PASSPHRASE -export BORG_REPO -export BORG_RSH _BORG_RESTORE_PATH="/data/RESTORE/$(basename "${BORG_REPO}")/${BORG_BACKUP_ID}" From 74b94e4c644745c02c57da3dcac9c57cdee61bdb Mon Sep 17 00:00:00 2001 From: Christoph Date: Fri, 10 Jan 2025 10:47:46 +0100 Subject: [PATCH 10/10] borg-extract-archiv.sh: change restote path for backup server. --- borg-extract-archiv.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/borg-extract-archiv.sh b/borg-extract-archiv.sh index 718ec07..0619f87 100755 --- a/borg-extract-archiv.sh +++ b/borg-extract-archiv.sh @@ -443,6 +443,7 @@ done echo -e " \033[33m---------------------------------------------\033[m" echo "" +BORG_RESTORE_PATH_BACKUP_SERVER="/backup/RESTORE/$(basename "${BORG_REPO}")/${BORG_BACKUP_ID}" _BORG_RESTORE_PATH="/data/RESTORE/$(basename "${BORG_REPO}")/${BORG_BACKUP_ID}" @@ -536,9 +537,9 @@ export BORG_REPO=\"${BORG_REPO}\" export BORG_RSH=\"${BORG_RSH}\" export BORG_RELOCATED_REPO_ACCESS_IS_OK=yes -mkdir -p \"${BORG_RESTORE_PATH}\" +mkdir -p \"${BORG_RESTORE_PATH_BACKUP_SERVER}\" -cd \"${BORG_RESTORE_PATH}\" +cd \"${BORG_RESTORE_PATH_BACKUP_SERVER}\" borg --remote-path borg extract ${BORG_URL}::${BORG_BACKUP_ID} ${LIST_OF_FILES_TO_RESTORE} " @@ -631,9 +632,9 @@ export BORG_PASSPHRASE=\"${BORG_PASSPHRASE}\" export BORG_REPO=\"${BORG_REPO}\" export BORG_RELOCATED_REPO_ACCESS_IS_OK=yes -mkdir -p \"${BORG_RESTORE_PATH}\" +mkdir -p \"${BORG_RESTORE_PATH_BACKUP_SERVER}\" -cd "${BORG_RESTORE_PATH}" +cd "${BORG_RESTORE_PATH_BACKUP_SERVER}" borg --remote-path borg extract ${BORG_REPO}::${BORG_BACKUP_ID} ${LIST_OF_FILES_TO_RESTORE} "