#!/bin/sh # # Local version: 1.0.2 # Copyright (c) 2008 Peter Kuyarov, All rights reserved # Thu Jan 27 22:02:32 MST 2011 # Using the '-A' option to 'du' by default now. # Fri Nov 5 00:26:14 MDT 2010 # finalize notrm, it is a go # Wed Sep 15 14:38:05 MDT 2010 # set $dayofweektonotrm to leave backups weekly # Fri Dec 4 01:07:15 MST 2009 # get rid of $psql and replace with $pg_dump # default to "pg_dump -c" # Wed Nov 25 04:12:31 MST 2009 - 1.0.2 # add '/root' to default backup list instead of '/root/bin' # Tue Aug 25 13:13:38 MDT 2009 - 1.0.1 # add '/var/db/ports' to default backup list # Fri Apr 11 08:08:11 MDT 2008-move $deldate to be set after pull_config() # -it was being set before $conf was pulled # Wed Apr 9 08:34:44 MDT 2008-code cleanup - version 1.0 # Fri Apr 4 10:07:36 MDT 2008-added do_pgsqlbackup() for pg databases # Wed Mar 19 08:41:37 MDT 2008-added display size of backup file # Wed Mar 5 08:16:53 MST 2008-additions and cleanup # Tue Mar 4 12:42:02 MST 2008-documentation addition, and bug fixes # Tue Feb 19 10:47:51 MST 2008-cosmetic changes # Tue Feb 12 09:51:36 MST 2008 # # Very simple shell backup script; # takes a filename or directory and tars it to # specified 'basedirectory/$date/$datetime.srcdir.tbz' # # all work is done at end of file, first are all functions # type 'backup.sh help' for usage info # or # 'backup.sh make_config' to make configuration file # # scripts@pknet.net # http://peterk.org/scripts/ # # PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin:/root/bin export PATH ################################################## # # defaults below - custom ones are in # /usr/local/etc/backup.conf # start backup.conf [default] [this line required for make_config()] # date=`date "+%Y.%m.%d"` umask='0077' hostname=`hostname` destdir="/data/BU/$hostname" #what dir to store backups [.tbz] in #where to duplicate above backups [ie:nfs/datastore/pc2] or 'NONE' #cpdestdir=/server2/data/BU | /drive2/data/BUCP | etc. cpdestdir="NONE" tar="/usr/bin/tar ycLf" rm="/bin/rm -rf" cp="/bin/cp" mv="/bin/mv" du="/usr/bin/du -A -h" su="/usr/bin/su" mkdir="/bin/mkdir" pg_dump="/usr/local/bin/pg_dump -c" retentiondays=9 cpretentiondays=9 dayofweektonotrm="0" # # directories to backup; # $BACKUPSOURCE from $conf overrides this # start source variable [ no comments allowed ] BACKUPSOURCE=" /boot/loader.conf /etc /home/*/bin /root /usr/local/etc /usr/src/sys/i386/conf /usr/src/sys/amd64/conf /var/cron /var/db/ports /var/db/pkg /var/named/etc/namedb " # # pgsql databases to backup BACKUPDB=" NONE " # end source variable [comments allowed] # # end backup.conf [default] [this line required for make_config()] # end user configurable variables # # # short name this script self=`basename $0` # config file for this script conf="/usr/local/etc/backup.conf" usage() { printf "Usage:\n" printf "\t'$self' - Full backup from defaults,\n " printf "\t\t or overridden by $conf\n" printf "\t'$self now /path/to/dir/or/file' - Backup " printf "only that dir/file \n" printf "\t'$self test' - Show what would be done\n" printf "\t'$self make_config' - Make custom configuration file\n" printf "\t\t $conf\n" } make_config() { grep -A 99 "^# start backup.conf \[default\]" $0 | \ grep -B 99 "^# end backup.conf \[default\]" | \ grep -v overrides | \ sed 's/default.*/custom\]/g' > $conf.sample && \ printf "Config created: $conf.sample\n" printf "Customize as needed and move to $conf\n" } pull_config() { # #pull in local system settings below # from $conf # if [ -r $conf ]; then printf "Sourcing local settings - $conf \n\n" . $conf else printf "Local settings [$conf] do NOT exist, using defaults\n" printf "\tPlease run '$self make_config'\n" sleep 1 fi # set deldate - current minus retention from above/config deldate="`date -v -${retentiondays}d \"+%Y.%m.%d\"`" cpdeldate="`date -v -${cpretentiondays}d \"+%Y.%m.%d\"`" deldatedayofweek="`date -v -${retentiondays}d +\"%w\"`" # set umask for backups # rw for owner only umask $umask } test_args() { # # if [ $# -gt 0 ] && [ $1 = 'test' ] then tar="echo $tar" rm=" echo $rm" cp=" echo $cp" mv=" echo $mv" du=" echo $du" su=" echo $su" mkdir=" echo $mkdir" pg_dump=" echo $pg_dump" elif [ $# -gt 1 ] && [ $1 = 'now' ] && ( [ -f $2 ] || [ -d $2 ] ) then BACKUPSOURCE=$2 BACKUPDB="NONE" # no way to specify DB backup yet... elif [ $# -gt 1 ] && [ $1 = 'now' ] && ( [ ! -f $2 ] || [ ! -d $2 ] ) then echo " '$2' not found " usage exit 1 elif [ $# -gt 0 ] && [ $1 = 'make_config' ] then make_config exit 0 elif [ $# -gt 0 ] then usage exit 1 else # display warning and continue normally warning_msg fi } create_destdir() { # # $1 and $2 passed from other functions calling this one; # $1=[cp]destdir / $2=$date in "reality" #check if $[cp]destdir directory exists and is writeable; # if $[cp]destdir exists, check write perms and create $date # if [ ! -d $1 ]; then echo "Cannot backup to '$1'" echo " '$1' does not exist" echo "Please create directory" echo " or specify a different one in '$conf'" exit 1 elif [ ! -d $1/$2 ] && [ -w $1 ]; then printf "\nCreating: $1/$2\n\n" $mkdir $1/$2 elif [ ! -d $1/$2 ] && [ ! -w $1 ] then printf "'$1' is NOT a writetable directory\n" printf "cannot create\n '$1/$2' for backups\n" printf "check if '$1'\n exists and is writeable by current user\n" printf "or manually create a writeable dir of\n '$1/$2'\n" exit 1 elif [ -d $1/$2 ] && [ ! -w $1/$2 ] then printf "'$1/$2' is NOT writeable by current user\n" printf "check if '$1/$2'\n exists and writeable by current user\n" printf "or manually create a writeable dir of\n '$1/$2'\n" exit 1 fi } warning_msg() { echo "Type '$self help' for options" echo "Doing full backup in 5 seconds" echo "Press ctrl+c to cancel" count=5 while [ $count -gt 0 ] do printf " $count " count=$(($count-1)) sleep 1 done printf " 0 \n\n" } do_backup() { # # parse backup sources from $BACKUPSOURCE # first check if $sourcedir [or file] exists, then do backup # create_destdir $destdir $date for sourcedir in $BACKUPSOURCE do backupfilename=`echo $sourcedir|sed 's/\//_/g'| sed 's/^_//g'|sed 's/$/\.tbz/g'` if [ ! -f $sourcedir ] && [ ! -d $sourcedir ] then echo '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' printf "\t$sourcedir DOES NOT EXIST FF\n" echo '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' else datetime=`date "+%Y.%m.%d.%H%M.%S"` echo '--------------------------------------------------' #echo "Backing up \"$sourcedir\" to: " #echo -n " $destdir/$date/$datetime.$backupfilename - " $tar $destdir/$date/$datetime.$backupfilename $sourcedir 2>&1 | \ grep -v "tar: Removing leading '/' from member names" echo "Backed up \"$sourcedir\" to: " $du $destdir/$date/$datetime.$backupfilename #| sed 's/ .*//g' echo '--------------------------------------------------' fi done } do_pgsqlbackup() { # # parse backup dbs from $BACKUPDB # first check if $sourcedir [or file] exists, then do backup # assumes user 'pgsql' has "passwordless" access to DBs # echo BACKUPDB: for sourcedb in $BACKUPDB do if [ "$sourcedb" = 'NONE' ] || [ "$sourcedb" = '' ] then echo ' NODB' else { datetime=`date "+%Y.%m.%d.%H%M.%S"` echo '--------------------------------------------------' $su - pgsql -c "$pg_dump $sourcedb > $datetime.$sourcedb.pgsql" $mv ~pgsql/$datetime.$sourcedb.pgsql $destdir/$date/ $du $destdir/$date/$datetime.$sourcedb.pgsql } fi done } cp_backup() { # # copy backup sources from $BACKUPSOURCE and do cp_backup() # case $cpdestdir in [Nn][Oo][Nn][Ee]) cpdestdir='NONE' # do nothing ;; *) echo "" echo "Copying backup files to $cpdestdir/" create_destdir $cpdestdir $date for sourcedir in $BACKUPSOURCE do backupfilename=`echo $sourcedir|sed 's/\//_/g'| sed 's/^_//g'|sed 's/$/\.tbz/g'` if [ -d $destdir ] && [ -d $cpdestdir ] then $cp $destdir/$date/*$backupfilename $cpdestdir/$date/ else echo "'cp_backup()' failed, \$cpdestdir [$cpdestdir] does not exist" fi done esac } del_oldbackup() { # # delete old backups [current date minus retention days ] # if [ -d $destdir/$deldate ] && [ "${deldatedayofweek}" -ne ${dayofweektonotrm} ] then echo "=================================================" echo "Deleting $destdir/$deldate" $rm $destdir/$deldate elif [ -d $destdir/$deldate ] && [ "${deldatedayofweek}" -eq ${dayofweektonotrm} ] then echo "notrm today" $mv -v $destdir/$deldate $destdir/${deldate}.notrm else echo "deldate does not exist:" echo " $destdir/$deldate" fi } del_oldcp() { case $cpdestdir in [Nn][Oo][Nn][Ee]) cpdestdir='NONE' # do nothing; ;; *) if [ -d $cpdestdir/$cpdeldate ] then echo "Deleting $cpdestdir/$cpdeldate" $rm $cpdestdir/$cpdeldate else echo "del_oldcp() - $cpdestdir/$cpdeldate does NOT exist, unable to rm" fi esac } # # do actual work # pull configs, test arguments, # if all is well, create destdir # pull_config test_args $* # can do make_config(),usage(), and warning_msg(); exit del_oldbackup do_backup do_pgsqlbackup del_oldcp cp_backup # # end of script #