summaryrefslogtreecommitdiff
path: root/backup.in
diff options
context:
space:
mode:
authorErich Eckner <erich.eckner.ext@bestsecret.com>2023-10-10 13:34:31 +0200
committerErich Eckner <erich.eckner.ext@bestsecret.com>2023-10-10 13:34:31 +0200
commit6b736c31b540720bb38e8411b60057013d413fef (patch)
tree1bb899b431c28cf817a73c6904eecb5b04b4524a /backup.in
parent7ee0416a6af469cc61e65649ec6fc20a36b6fe37 (diff)
downloadhardlinkedBackups-6b736c31b540720bb38e8411b60057013d413fef.tar.xz
rename backup -> hardlinked-backup
* avoid file conflict with tar's /usr/bin/backup script
Diffstat (limited to 'backup.in')
-rwxr-xr-xbackup.in302
1 files changed, 0 insertions, 302 deletions
diff --git a/backup.in b/backup.in
deleted file mode 100755
index f530e08..0000000
--- a/backup.in
+++ /dev/null
@@ -1,302 +0,0 @@
-#!/bin/bash
-
-rsyncOptions='-vxcaHAXF'
-rsync --help | \
- grep -q -- --may-modify-others && \
- rsyncOptions="${rsyncOptions} --may-modify-others"
-
-[ -r "#ETCDIR#/backup.conf" ] && \
- . "#ETCDIR#/backup.conf"
-
-usage()
-{
- >&2 echo \
-'Usage: backup /tmp/pidFile /path/to/destination/ user@source:path [proxy_user@ssh_host]
-Backup files from remote with rsync, possibly via SSH-tunnel.
-
-With no arguments, information is expected to be in array $backups in #ETCDIR#/backup.conf with name of executable (e.g. a symlink) as key.
-With one argument, information is expected to be in array ${backups[$1]} in #ETCDIR#/backup.conf.
-
-Options:
- /tmp/pidFile location of file to store PID in
- /path/to/destination location to store backups in
- user@source:path remote data to back up
- proxy_user@ssh_host ssh login to proxy node (optional)
-#HELPTEXT# #'
- [ -z "$1" ] && exit 1
- exit $1
-}
-
-extract_ssh_host() {
- {
- printf '%s\n' "$1"
- if [ -f ~/.ssh/config ]; then
- sed '
- /^Host\s\+'"$1"'$/,/^Host\s/ {
- s/^\s*Hostname\s\+//
- t
- }
- d
- ' ~/.ssh/config
- fi
- } \
- | tail -n1
-}
-
-extract_ssh_ip_protocols() {
- getent ahosts "$(extract_ssh_host "$1")" \
- | sed '
- s/^\([0-9]\+\.\)\{3\}[0-9]\+\s\+STREAM\(\s.*\)\?$/4/
- t
- s/^[0-9a-f][0-9a-f:]\+\s\+STREAM\(\s.*\)\?$/6/
- t
- d
- ' \
- | sort -u \
- | if [ -f ~/.ssh/config ]; then
- grep -vxF "$(
- sed '
- /^Host\s\+'"$1"'$/,/^Host\s/ {
- s/^\s*AddressFamily\s\+inet\s*$/6/
- t
- s/^\s*AddressFamily\s\+inet6\s*$/4/
- t
- }
- d
- ' ~/.ssh/config
- )"
- else
- cat
- fi
-}
-
-connected_ip_versions() {
- ip -o addr show scope global \
- | awk '{print $4}' \
- | sed '
- s@^\([0-9]\+\.\)\{3\}[0-9]\+\(/[0-9]\+\)\?$@4@
- t
- s@^[0-9a-f][0-9a-f:]\+\(/[0-9]\+\)\?$@6@
- t
- d
- ' \
- | sort -u
-}
-
-if [ $# -eq 1 ]; then
- if [ "$1" == "--help" ]; then
- usage 0
- elif [ "$1" == "--version" ]; then
- echo '#VERSION#'
- exit
- fi
-fi
-
-seldom=false
-if [ $# -eq 0 ] || [ $# -eq 1 ]; then
- if [ $# -eq 0 ]; then
- backupID="$(basename $0)"
- else
- backupID="$1"
- fi
- [ -z "${backups[${backupID}]}" ] && usage
- set /tmp/${backupID}.pid ${backups[${backupID}]}
- if printf '%s\n' "${seldomBackups[@]}" | \
- grep -qxF "${backupID}"; then
- seldom=true
- fi
-fi
-
-Basis="$2"
-pidFile="$1"
-QuellIP=$(echo "$3" | sed "s|^[a-zA-Z]*://||; s|^[a-zA-Z]*@||; s|:\?/.*$||")
-
-if [ "$#" -eq 3 ]; then
- Quelle="$3"
- ipVer=$(
- {
- extract_ssh_ip_protocols "${QuellIP}" \
- | sort -n
- extract_ssh_ip_protocols "${QuellIP}" \
- | grep -xF "$(connected_ip_versions)" \
- | sort -n
- } \
- | tail -n1
- )
-elif [ "$#" -eq 4 ]; then
- sshHopp="$4"
- lokPort=$[$RANDOM/2+8000]
- HoppIP="${sshHopp#*@}"
- ipVer=$(
- {
- extract_ssh_ip_protocols "${QuellIP}"
- extract_ssh_ip_protocols "${HoppIP}"
- } \
- | sort -n \
- | uniq -d \
- | tail -n1
- )
- if [ -z ${ipVer} ]; then
- >&2 echo 'not reachable'
- exit 11
- fi
- if [ ${ipVer} -eq 4 ]; then
- localAddress='127.0.0.1'
- elif [ ${ipVer} -eq 6 ]; then
- localAddress='[::1]'
- else
- >&2 echo 'ip version of hopp and target must be the same'
- exit 1
- fi
- rsyncShell="-e ssh -${ipVer} -p${lokPort} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
- tunnelBefehl="ssh -${ipVer} -t -t -L${localAddress}:${lokPort}:${QuellIP}:22 ${sshHopp} while sleep 60; do date; done"
- Quelle="$(echo "$3" | sed "s|${QuellIP}|${localAddress}|")"
-else
- usage
-fi
-
-rsyncOptions="${rsyncOptions}${ipVer}"
-
-if [ ! -d ${Basis} ]; then
- for neededMount in "${neededMounts[@]}"; do
- if ! mountpoint -q "${neededMount}"; then
- >&2 printf 'Mountpoint %s is not available.\n' "${neededMount}"
- exit 11
- fi
- done
- exit 2
-fi
-
-neues_Datum="${Basis}/$(date "+%Y_%m_%d")"
-neues="${Basis}/aktuell"
-linkdests=""
-for s in $(ls -1 "${Basis}" | sort -r | grep -vxF -m 20 aktuell ); do
- linkdests="${linkdests} --link-dest ${Basis}/${s}"
-done
-
-if [ ! "$(whoami)" == "root" ]; then
- echo "I need to be root."
- exit 3
-fi
-
-[ -e "${neues_Datum}" ] && exit 4
-if ${seldom}; then
- for date_diff in $(seq ${seldomness}); do
- if [ -e "${Basis}/$(date '+%Y_%m_%d' -d@$(($(date '+%s')-24*60*60*date_diff)))" ]; then
- exit 4
- fi
- done
-fi
-[ -w "${Basis}" ] || exit 11
-[ -s "${pidFile}" ] && [ -d "/proc/$(cat "${pidFile}")" ] && exit 5
-
-echo $$ > "${pidFile}"
-
-if [ -n "${tunnelBefehl}" ]; then
- preConnectHook
- ${tunnelBefehl} &
- backgroundPid=$!
- sleep 4
-fi
-
-for toExclude in "${excludes[@]}"; do
- excludeArgs="${excludeArgs} --exclude ${toExclude}"
-done
-
-mkdir -p "${neues}/wip"
-chmod 750 "${neues}"{,/wip}
-chown root:root "${neues}"{,/wip}
-if [ -z "${rsyncShell}" ]; then
- preConnectHook
- if [ -z "${Quelle#*@*:/}" ]; then
- ssh "-${ipVer}" "${Quelle%:/}" '
- pacman-conf Architecture
- find /var/lib/pacman/local -name desc -exec cat {} +
- ' \
- | {
- read -r arch
- sed -n '
- /^%\(NAME\|VERSION\|ARCH\)%/ {
- N
- s/\n/ /
- p
- }
- ' \
- | sed '
- N
- N
- s@^%NAME% \(\S\+\)\n%VERSION% \(\S\+\)\n%ARCH% \(\S\+\)$@\1-\2-\3.pkg.tar.zst@
- t
- w /dev/stderr
- d
- ' \
- | while read -r file; do
- cache_file='/var/cache/pacman/pkg/'"${file}"
- if [ ! -f "${cache_file}" ]; then
- case "${arch}" in
- 'x86_64')
- for url in \
- 'https://mirror.f4st.host/archlinux/pool/packages/'"${file}" \
- 'https://archive.archlinux.org/packages/'"${file:0:1}"'/'"${file%-*}"'/'"${file}"; do
- curl -Lo "${cache_file}" "${url}" || continue
- tar --zstd -tf "${cache_file}" >/dev/null 2>&1 && break
- done
- ;;
- 'i486'|'i686'|'pentium4')
- for url in \
- 'https://mirror.archlinux32.org/pool/'"${file}" \
- 'https://archive.archlinux32.org/packages/'"${file:0:1}"'/'"${file%-*}"'/'"${file}"; do
- curl -Lo "${cache_file}" "${url}" || continue
- tar --zstd -tf "${cache_file}" >/dev/null 2>&1 && break
- done
- ;;
- *)
- for url in \
- 'https://mirror.archlinux.org/'"${arch}"'/'{extra,community,core,alarm,aur}'/'"${file}"; do
- curl -Lo "${cache_file}" "${url}" || continue
- tar --zstd -tf "${cache_file}" >/dev/null 2>&1 && break
- done
- ;;
- esac
- fi
- if [ -f "${cache_file}" ]; then
- tar -C "${neues:?}/wip/" --zstd -xkf "${cache_file}"
- fi
- done
- }
- fi
- rsync ${rsyncOptions} \
- ${linkdests} \
- ${excludeArgs} \
- ${Quelle} "${neues}/wip/"
- sleep 1
- preConnectHook
- rsync ${Quelle}
-else
- preConnectHook
- rsync "${rsyncShell}" \
- ${rsyncOptions} \
- ${linkdests} \
- ${excludeArgs} \
- ${Quelle} "${neues}/wip/"
- sleep 1
- preConnectHook
- rsync "${rsyncShell}" ${Quelle}
-fi
-erg=$?
-
-[ -n "${backgroundPid}" ] && kill "${backgroundPid}"
-
-if [ ${erg} -eq 0 ] || [ ${erg} -eq 24 ] && ! rmdir "${neues}/wip" 2>/dev/null; then
- chmod o-rwx "${neues}/wip"
- neueres_Datum="${Basis}/$(date "+%Y_%m_%d")"
- if [ ! -e "${neueres_Datum}" ]; then
- neues_Datum="${neueres_Datum}"
- fi
- mv "${neues}/wip" "${neues_Datum}"
- rmdir "${neues}"
- rm "${pidFile}"
-else
- rm "${pidFile}"
- exit 11
-fi