From 105466f13ee13c06009056c5763281ca23865a58 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Mon, 24 Oct 2022 18:45:05 -0700 Subject: removing literate file; editing source directly --- rsyncshot.org | 208 ---------------------------------------------------------- 1 file changed, 208 deletions(-) delete mode 100644 rsyncshot.org diff --git a/rsyncshot.org b/rsyncshot.org deleted file mode 100644 index 2d2f8d7..0000000 --- a/rsyncshot.org +++ /dev/null @@ -1,208 +0,0 @@ -* rsyncshot -#+begin_SRC sh :tangle rsyncshot :comments no :shebang "#!/bin/bash" -# rsyncshot -# Craig Jennings craigmartinjennings@gmail.com -# Inspired by Mike Rubel: http://www.mikerubel.org/computers/rsync_snapshots/ -#+end_SRC -* Debugging -#+begin_SRC sh :tangle rsyncshot :comments org -# uncomment next 4 lines for debugging output -# exec 5> >(logger -t $0) -# BASH_XTRACEFD="5" -# PS4='$LINENO: ' -# set -x -#+end_SRC -* Default Locations For Setup -Modify BACKUPLOCATION to point to the mount point of your backup -#+begin_SRC sh :tangle rsyncshot :comments org -MOUNTPOINT=/media/backup; -SCRIPTLOC=/usr/local/bin/rsyncshot; -DESTINATION=$MOUNTPOINT/$HOSTNAME - -INSTALLHOME=/etc/rsyncshot -LOGHOME=/var/log/rsyncshot.log; - -INCLUDES="$INSTALLHOME/include.txt"; -EXCLUDES="$INSTALLHOME/exclude.txt"; -#+end_SRC -* Sidestep Alias Conflicts -Copy, move, and rm commands are often aliased to require user input. -Using a variable allows us to sidestep this and complete the actions without any interaction. -#+begin_SRC sh :tangle rsyncshot :comments org -CP="/usr/bin/cp" -MV="/usr/bin/mv" -RM="/usr/bin/rm" -#+end_SRC -* Prevent Overlapping Runs with Flock -#+begin_src sh :tangle rsyncshot :comments org -FLOCKCHECK="flock -x /tmp/rsyncshot.lock -c" -#+end_src -* Default Cron Job Entries -CRON_H = hourly on minute 0 from 1am to 11pm -CRON_D = daily at midnight, Monday - Saturday -CRON_W = weekly at midnight on Sundays -#+begin_SRC sh :tangle rsyncshot :comments org -CRON_H="0 1-23 * * * $FLOCKCHECK $SCRIPTLOC hourly 22"; -CRON_D="0 0 * * 1-6 $FLOCKCHECK $SCRIPTLOC daily 6"; -CRON_W="0 0 * * 7 $FLOCKCHECK $SCRIPTLOC weekly 51"; -#+end_SRC -* Functions -** Help Function -#+begin_SRC sh :tangle rsyncshot :comments org -help() -{ - printf "\nrsyncshot - compact snapshots on Linux using rsync and hard links.\n\n" - printf "Usage:\nrsyncshot \n" - printf " setup (installs rsyncshot and cron jobs)\n" - printf " help (prints this info)\n" - printf "Notes:\n" - printf '%s\n' "- rsyncshot must be run as root" - printf '%s\n' "- install and log locations defined in script." - printf '%s\n' -} -#+end_SRC -** Error Function -#+begin_SRC sh :tangle rsyncshot :comments org -error() -{ - echo "ERROR: $0: $@" 1>&2; - echo "See \"rsyncshot help\" for usage." - exit 1; -} -#+end_SRC -** Setup Function -#+begin_SRC sh :tangle rsyncshot :comments org -setup() -{ # copy this file to directory on path and make executable - $CP -f $0 $SCRIPTLOC - sudo chmod +x $SCRIPTLOC - echo "$0 copied to $SCRIPTLOC and is executable" - - # make install home if it doesn't exist; - if [ ! -d $INSTALLHOME ]; then - mkdir -p $INSTALLHOME; - echo "Created install home at $INSTALLHOME."; - fi - - # create includes file and add default entries - if [ -f $INCLUDES ]; then $RM $INCLUDES; fi - printf "/home /etc /usr/local/bin" >> $INCLUDES; - echo "modify include file at $INCLUDES"; - - # create excludes file and add default entries - if [ -f $EXCLUDES ]; then $RM $EXCLUDES; fi - printf "*.pyc\n*.pyo\n*.class\n*.elc\n*.o\n*.tmp\n.cache*" >> $EXCLUDES; - echo "modify exclude file at $EXCLUDES"; - - # write out current crontab, append default entries, and install - crontab -l > crontemp; - echo "$CRON_H >> $LOGHOME 2>&1" >> crontemp; - echo "$CRON_D >> $LOGHOME 2>&1" >> crontemp; - echo "$CRON_W >> $LOGHOME 2>&1">> crontemp; - crontab crontemp; - $RM crontemp; - echo "hourly, daily, and weekly cron jobs installed."; -} -#+end_SRC - -* Display Help If Requested -Make the argument uppercase for case insensitivity. -#+begin_SRC sh :tangle rsyncshot :comments org -TYPE=$(tr '[a-z]' '[A-Z]' <<< $1); -if [ "$TYPE" = "HELP" ]; then help; exit; fi -#+end_SRC -* Ensure We're Running As Root -#+begin_SRC sh :tangle rsyncshot :comments org -if [ "$EUID" -ne 0 ]; then error "This script must be run as root."; fi -#+end_SRC -* Display Start Information -#+begin_SRC sh :tangle rsyncshot :comments org -echo "rsyncshot invoked on `date -u` with: $0 $1 $2"; -#+end_SRC -* Validate Backup Type -First argument must be alpha characters -#+begin_SRC sh :tangle rsyncshot :comments org -if ! [[ $1 =~ [a-zA-Z] ]]; then error "snapshot type not recognized."; fi -if [ "$TYPE" = "SETUP" ]; then setup; exit; fi -#+end_SRC -* Validate Max Snapshots -Second argument must be numeric -#+begin_SRC sh :tangle rsyncshot :comments org -if ! [[ $2 =~ [0-9] ]]; then error "max snapshots not a number."; fi -MAX=$(($2-1)); -#+end_SRC -* Validate Include File (Source Directories) Exist -Validates the include file exists, and checks the file contents are valid directories -#+begin_SRC sh :tangle rsyncshot :comments org -if [ ! -f "$INCLUDES" ]; then error "include file $INCLUDES not found."; fi -SOURCES=$(<$INCLUDES); -for SOURCE in $SOURCES -do - if [ ! -d "$SOURCE" ]; then error "source $SOURCE not found"; fi -done -#+end_SRC -* Validate Exclude File (Exclusion Patterns) Exist -#+begin_SRC sh :tangle rsyncshot :comments org -if [ ! -f "$EXCLUDES" ]; then error "Exclude file $EXCLUDES not found."; fi -#+end_SRC -* Validate Mountpoint -Fail if mountpoint doesn't exist. -Attempt mounting if destination filesystem not mounted; error if attempt fails. -#+begin_SRC sh :tangle rsyncshot :comments org - [ -d $MOUNTPOINT ] || error "$MOUNTPOINT doesn't exist!" - - if grep -qs "$MOUNTPOINT" /proc/mounts ; then - true - else if [ $? -eq 0 ]; then - true - else - error "$MOUNTPOINT unmounted, and mount attempt failed." - fi - fi -#+end_SRC -* Validate Destination Directory Exists -#+begin_SRC sh :tangle rsyncshot :comments org -[ -d $DESTINATION ] || mkdir $DESTINATION || error "$DESTINATION doesn't exist, and attempt to create failed." -#+end_SRC -* Sync Each Backup Directory In Turn -#+begin_SRC sh :tangle rsyncshot :comments org -for SOURCE in $SOURCES -do - rsync -avh -i --times \ - --delete --delete-excluded \ - --exclude-from=$EXCLUDES \ - --update $SOURCE $DESTINATION/latest ; -done -#+end_SRC -* If Exists, Delete Max+1 Snapshot -#+begin_SRC sh :tangle rsyncshot :comments org -if [ -d $DESTINATION/$TYPE.$MAX ]; then - $RM -rf $DESTINATION/$TYPE.$MAX; -fi -#+end_SRC -* Rotate Remaining Snapshots Descending -#+begin_SRC sh :tangle rsyncshot :comments org -for (( start=$(($MAX)); start>=0; start--)); do - end=$(($start+1)); - if [ -d $DESTINATION/$TYPE.$start ]; then - $MV $DESTINATION/$TYPE.$start $DESTINATION/$TYPE.$end; - fi -done -#+end_SRC -* Reset Directory Timestamp -#+begin_SRC sh :tangle rsyncshot :comments org -touch $DESTINATION/latest -#+end_SRC -* Hard Link Only Copy to Destination -#+begin_SRC sh :tangle rsyncshot :comments org -$CP -al $DESTINATION/latest $DESTINATION/$TYPE.0; -#+end_SRC -* Make Directory Type Read-Only -#+begin_SRC sh :tangle rsyncshot :comments org -chmod -w $DESTINATION/$TYPE.0 -#+end_SRC -* Print Time and Exit -#+begin_SRC sh :tangle rsyncshot :comments org -echo "rsyncshot completed `date -u` "; -exit 0; -#+end_SRC -- cgit v1.2.3