autobackup

Automatically choose backup location and perform backups using rsync
Log | Files | Refs | README | LICENSE

commit 60fe0e8789a9c4567f7f2edd94bb3e9d46e50a38
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date:   Tue,  6 Jun 2023 10:31:57 -0700

Initialize

Add LICENSE, README, Makefile, and various scripts and manuals.

Diffstat:
ALICENSE | 13+++++++++++++
AMakefile | 17+++++++++++++++++
AREADME | 9+++++++++
Aautobackup | 13+++++++++++++
Aautobackup.1 | 41+++++++++++++++++++++++++++++++++++++++++
Aautobackup.5 | 21+++++++++++++++++++++
Aautobackup_log | 19+++++++++++++++++++
Aautobackup_pick | 40++++++++++++++++++++++++++++++++++++++++
Aautobackup_recieve | 45+++++++++++++++++++++++++++++++++++++++++++++
Aautobackup_send | 12++++++++++++
10 files changed, 230 insertions(+), 0 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -0,0 +1,13 @@ +Copyright 2023 Jacob R. Edwards <jacob@jacobedwards.org> + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Makefile b/Makefile @@ -0,0 +1,17 @@ +prefix = /usr/local +manprefix = ${prefix}/man +bin = ${prefix}/bin + +scripts = autobackup autobackup_send autobackup_recieve autobackup_pick autobackup_log +mans = autobackup.1 autobackup.5 + +install: +.for script in ${scripts} + install -o root -g bin -m 0755 ${script} ${bin}/${script} +.endfor + install -o root -g bin -m 0444 autobackup.1 ${manprefix}/man1/autobackup.1 + install -o root -g bin -m 0444 autobackup.5 ${manprefix}/man5/autobackup.5 + +uninstall: + cd ${manprefix} && rm -f autobackup.[15] + cd ${bin} && rm -f ${scripts} diff --git a/README b/README @@ -0,0 +1,9 @@ +This is a set of scripts I whipped together to automatically backup +all my files to a local server over ssh using rsync. + +The scripts are ugly and the manuals are bad. I'm just tossing it +into a repository to make it easy for myself. Use it if you will, +but I advise against it. + +In the future I might actually make a system like this that is good, +but for now this is working well enough for me. diff --git a/autobackup b/autobackup @@ -0,0 +1,13 @@ +#!/bin/sh +# Copyright 2023 Jacob R. Edwards <jacob@jacobedwards.org> +# Licensed under OpenBSD's ISC license; see LICENSE +# +# Wrapper for autobackup_* scripts. + +printenv DEBUG >/dev/null && + set -x + +case "$1" in +(--server) autobackup_recieve "$@" +(*) autobackup_send "$@" +esac diff --git a/autobackup.1 b/autobackup.1 @@ -0,0 +1,41 @@ +.\" Licensed under OpenBSD's ISC license; see LICENSE +.Dd "June 6th, 2023" +.Dt AUTOBACKUP 1 +.Os +.Sh NAME +.Nm autobackup +.Nd Automatic backup script +.Sh SYNOPSIS +.Nm +.Ar host Op Ar rsync-options +.Sh DESCRIPTION +The +.Nm +script connects to the sshd at +.Ar host +using +.Xr rsync 1 +with a custom reciever. This reciever chooses a backup location +using the configuration file located at +.Pa /etc/autobackup +and described in +.Xr autobackup 5 . +.Sh ENVIRONMENT +.Bl -tag -width indent +.It Ev DEBUG +Define to set Xtrace in all +.Xr sh(1) +scripts. +.El +.Sh FILES +.Bl -tag -width indent +.It Pa /etc/autobackup +List of mirror bases, described in +.Xr autobackup 5 . +.Sh EXIT STATUS +.Ex -std +.Sh EXAMPLES +Automatically backup to backup.lan: +.Dl "$ autobackup backup.lan +.Sh AUTHORS +.An Jacob R. Edwards Aq Mt jacob@jacobedwards.org diff --git a/autobackup.5 b/autobackup.5 @@ -0,0 +1,21 @@ +.\" Licensed under OpenBSD's ISC license; see LICENSE +.Dd June 6th, 2023 +.Dt AUTOBACKUP 5 +.Os +.Sh +.Nm autobackup +.Nm /etc/autobackup +.Nd Configuration file for +.Xr autobackup 1 +reciever +.Sh DESCRIPTION +The configuration file consists of a newline separated list of paths +which point to the base of the mirror directories. Mirrors go into +.Pa mirrors/ Va host +in the base directory. The log file is located at +.Pa mirrors/log . +.Pp +To eliminated the need to run the reciever as root, it is recommended +to mount backup disks with the noperm flag under a directory owned +by the user you wish to backup with and sufficiently protected with +permissions. diff --git a/autobackup_log b/autobackup_log @@ -0,0 +1,19 @@ +#!/bin/sh +# Copyright 2023 Jacob R. Edwards <jacob@jacobedwards.org> +# Licensed under OpenBSD's ISC license; see LICENSE +# +# Log completed mirrors (used by autobackup_recieve). + +printenv DEBUG >/dev/null && + set -x + +if test $# -ne 3 +then + echo 'usage: logmirror host base status' 1>&2 + exit 1 +fi + +host="$1" +base="$2" +status="$3" +date "+$host @ %F [$status]" >> "$base"/mirrors/log diff --git a/autobackup_pick b/autobackup_pick @@ -0,0 +1,40 @@ +#!/bin/sh +# Copyright 2023 Jacob R. Edwards <jacob@jacobedwards.org> +# Licensed under OpenBSD's ISC license; see LICENSE +# +# Pick mirror to backup to (used by autobackup_recieve). +# It outputs the oldest mirror. + +printenv DEBUG >/dev/null && + set -x + +get() { + awk -v host="$host" -v base="$base" \ +'host == $1 && $NF == "[0]" { + $1 = base + last = $0 +} + +END { + if (!last) + print base, " @ 0000-00-00 [0]" + else + print last +}' +} + +host="${1:?no host}" +shift + +for base in "${@:?no base directories}" +do + if ! test -d "$base"/mirrors + then + echo "warning: '$base' not setup as a mirror (lacks the mirrors directory)" 1>&2 + elif ! test -f "$base"/mirrors/log + then + echo "$base 0000-00-00 [0]" + else + get < "$base"/mirrors/log + fi +done | sort -k3 | sed 's/ .*//;q' diff --git a/autobackup_recieve b/autobackup_recieve @@ -0,0 +1,45 @@ +#!/bin/sh +# Copyright 2023 Jacob R. Edwards <jacob@jacobedwards.org> +# Licensed under OpenBSD's ISC license; see LICENSE +# +# Autobackup server. + +printenv DEBUG >/dev/null && + set -x + +set -e + +base="$(dirname $0)" +config=/etc/autobackup + +! test -f "$config" && { + echo 'No config' 1>&2 + exit 1 +} + +case $# in +(0) + echo "usage: [rsync-args] host" 1>&2 + exit 1 +esac + +IFS=' +' +host="$(eval echo "$"{$#})" +dir="$("$base"/autobackup_pick "$host" $(<"$config"))" +! test "$dir" && { + echo 'No dir' 1>&2 + exit 1 +} +path="$dir/mirrors/$host" +set -- $(echo "$*" | sed "\${i\\ +$path +d;}") + +echo "Backing up to '$path'" 1>&2 +/usr/local/bin/rsync "$@" || : +status=$? + +echo "Logging mirror (status $status)" 1>&2 +"$base"/autobackup_log "$host" "$dir" $status +exit $status diff --git a/autobackup_send b/autobackup_send @@ -0,0 +1,12 @@ +#!/bin/sh +# Copyright 2023 Jacob R. Edwards <jacob@jacobedwards.org> +# Licensed under OpenBSD's ISC license; see LICENSE +# +# Autobackup client. + +printenv DEBUG >/dev/null && + set -x + +d="${1:?"usage: ${0##*/} destination [rsync-options ...]"}" +shift +rsync "$@" -aHu --rsync-path="/usr/local/bin/autobackup_recieve" /home/ "$d:$(hostname -s)"