Linux Training

Linux training for private, public & voluntary sector.

0793 572 8612

City LinUX sample scripts - archive


#!/bin/bash
# $Id: archive,v 1.256 2024/02/05 20:01:50 fulford Exp $
# $Source: /src/admin/usr/local/etc/RCS/archive,v $
# $Revision: 1.256 $
# Author C W Fulford.
# Copyright 2014 - 2018 (c) C W Fulford. 
# Licensed for public use under the GPL.
# For assistance contact fulford@fulford.net 0793 572 8612
###############################################################
logpath=/var/log/archive
out=$logpath/out.`date +%w`
[ ! -f $out ] && {
	sudo mkdir -p $logpath
	sudo chmod 775 $logpath
}
if [ ! -t 0 ];then
	exec >$out 2>&1
fi
cmd=`basename $0`
trap 'echo $cmd: terminated with signal 2;exit' 2
trap 'echo $cmd: terminated with signal 15;exit' 15
 
syntax="$cmd [[-b]|[[-f]|[-r]] [-c <config>] [-d(debug)] [-v(erbose)] [-z(ip)] -h <host_id> |-V"
ver=`echo "$Id: archive,v 1.256 2024/02/05 20:01:50 fulford Exp $"|awk '{print $3,$4,$5}'`
r=0
dbtmp=/tmp/$cmd-db$$
mailto=fulford@citylinux.com
maibriansg=/tmp/mailmsg$$
mysqldump=/usr/bin/mysqldump
rsync=rsync
sendmail=/usr/sbin/sendmail #correct in config file if necessary
tmp=/tmp/$cmd-$$
xtmp=/tmp/$cmd-x$$
ddstatus="status=none" # used by dd NB does not work on badon-hill. Possibly
			# stripped out version. Redirect stderr instead.


while [ $# -gt 0 ] ;do
	case $1 in 
		-D) delete=0;shift;;
		-b) archive="$archive db";shift;; #do database dump
		-c) config=$2;shift 2;;
		-d) debug=1;set -x;unset ddstatus;ssh_opts=-v;shift;;
		-h) host_id=$2;shift 2 ;;
		-l) log=:;shift;;
		-m) email=0;shift;;
		-r) archive="$archive rs";shift;; # do sync backup
		-t) archive="$archive tar";shift;; # do tar backup
		-v) verbose=:;shift;;
		-V) echo "$cmd $ver";exit;;
		-x) echo $2>$xtmp;shift 2;;
		-z) zip=y;shift;;
		 *) echo $syntax >&2; exit 1;;
	esac
done
archive=${archive:="rs"} # default action rsync
config=${config:-"/usr/local/etc/archive.cf"}
[ -z "$host_id" ]&&{ echo "$cmd: host_id required" >&2 ;exit 1 ;}
start=`date`

# Notify start of archive
[ "$verbose" ] && echo "$cmd  started `date`" >&2
[ "$email" ] && echo "$cmd $host_id started `date`" >$maibriansg

# Check if host available
if ! ping -W 1 -c 1 $host_id >/dev/null 2>&1;then
	[ "$log" ] && logger -t $cmd "$host_id unavailable"
	[ "$verbose" ] && echo "$host_id unavailable" >&2
	[ "$email" ] && echo "$host_id unavailable" >$maibriansg
	exit 1
fi

_chkSSH (){
	$ssh ls
	return $? 
}



# Finish off
_end (){ 
	overall=$1
	[ $verbose ] && echo "$cmd: `date` $host_id completed"
	[ $email -a "$result" = "failed" ] &&{
		[ -x $sendmail ]||{
			echo "$cmd $sendmail not found" >&2
			exit 1
		}
		[ -r $out ] && cat $out >>$maibriansg
		if [ "$verbose" ];then
			cat $tmp >>$maibriansg
			cat $dbtmp >>$maibriansg
			cat $xtmp >>$maibriansg
		fi
		echo "$cmd $host_id completed `date`" >>$maibriansg

		$sendmail -f $mailfrom  $mailto <<- .
			Subject: $archive archive $host_id $overall

			`cat $maibriansg` 
		.
	} 
	[ -f $out ] && rm $out
	[ -f $tmp ] && rm $tmp
	[ -f $dbtmp ] && rm $dbtmp
	[ -f $xtmp ] && rm $xtmp
	exit $ex_rv
}

# Check if configuration available
if [ -r $config ];then
	grep -q "^$host_id:$" $config ||{
		echo "$cmd: $host_id not found in $config">&2
		logger -t $cmd "$host_id not found in $config."
		_end 1
	}
else
	echo "$cmd: Can't read $config" >&2
	exit 1
fi

# Extract config for host_id
sed -ne '/^'$host_id':/,/^$/{
	/^[	 ]db:<database>=<passwd>
	/^[	 ]exclude:.*/d 
	/^[	 ].*/p
}' $config >$tmp


[ $verbose ] && cat $tmp >&2

# Set config
. $tmp

if [ $email ] ;then
	[ -n "$mailto" -a -n "$mailfrom" ] ||{
		echo "$cmd: \$mailto and  \$mailfrom must be set." >&2 
		exit 1
	}
fi

# Check if sudo required
[ "$root_usr" = y ] && {
		[ `id -un` = "root" ] ||{	
			sudo=${sudo:=/usr/bin/sudo}
			[ -x $sudo ] ||{
				echo "$cmd: Can\'t find $sudo" >&2
				exit 1
			}

		}
}
# Check if rsh required
thisHost=`hostname`
[ $thisHost = $host_id ]||{
	ssh="ssh $host"
}
	
# Get excludes for host
sed -ne '/^'$host_id':$/,/^$/{
          s/[\t ]*exclude:\(.*\)$/\1/p
}' <$config >>$xtmp
[ $verbose ] && cat $xtmp >&2


# Get databases to archive
sed -ne '/^'$host_id':/,/^$/p' $config|
	awk -F: '/^[ \t]db:<database>=<passwd>
ftphost=${ftphost:-$host}
if [ "$setremote" = "yes" ]; then 
	[ $host != `hostname -f` ] && { ssh="ssh -y $host";bs="bs=8192" ;		}
fi


# Functions
# tar dump
_tardump () {
	[ -n "$tarcmd" ] ||{
		echo "$cmd: tar command not set">&2
		exit 1
	}
	if echo $tar_dest|grep -q ":" ;then
		tar_host=`echo $tar_dest |awk -F: '{print $1}'` 
		tar_dest=`echo $tar_dest |awk -F: '{print $2}'` 
	fi
	tdmsg="tardump started `date`"
	[ $verbose ] &&{
		echo "$cmd: tar archive of $fs starte"
	}
	[ $log ] &&{
		logger -t $cmd "$tdmsg"
	}
	[ $email ] &&{
		echo "$tdmsg" >>$maibriansg
	}
	
	for fs in $tarsrc ;do
		case $fs in
			/) fsd=root;;
			*) fsd=`echo $fsd|sed -ne 's/\///'`
		esac
		fsd=${fsd}`date +%w`.tar.gz
		echo "$sudo $tarcmd $fs|ssh $tar_host \"sudo dd=$tar_dest$fs\""
		$sudo $tarcmd $fs|ssh $tar_host "sudo dd of=$tar_dest/$fsd"
		if [ $? -eq 0 ] ;then
			result=completed
		else 
			result=failed
			overall=errors
		fi
		[ $verbose ] &&{
			echo "$cmd: tar archive of $fs $result"
		}
		[ $log ] &&{
			logger -t archive "tar archive of $fs $result"
		}
		[ $email ] &&{
			echo "tar archive of $fs $result">maibriansg
		}
	done

}

# backup databases i
_dbdump () {
	cat $dbtmp|
	while read line;do
		db=`echo $line|awk -F: '{printf $2}'`
		user=`echo $line|awk -F: '{printf $3}'`
		pass=<password>
		if [ $pass ] ;then 
			pass=<password>
		else
			user=root
			pass=<password>
		fi
		arc_file=$db.`date +%u`.sql
		tdbhost=`echo $dbdest|awk -F: '{printf $1}'`
		tdbdir=`echo $dbdest|awk -F: '{printf $2}'`

		dbmsg="sqldump of $db as $user on $host" 

		[ $verbose ] &&{
			echo "$cmd: $dbmsg started"
		}

		$mysqldump -h $host -u $user $pass $db|\
			ssh $tdbhost "dd of=$tdbdir/$arc_file 2>/dev/null" 
		db_rv=$?
		ex_rv=$(expr $ex_rv + $db_rv)
		
		if [ $db_rv -eq 0 ] ;then
			result=completed
		else
			result=failed
			overall=Errors
		fi
		[ $verbose ] &&{
			echo "$cmd: $dbmsg $result" 
		}	
		[ $log ] && {
			logger -t $cmd "$dbmsg $result"
		}
		[ $email ] &&{
			ftime=`date +%T`
			echo "$dbmsg $result $ftime" >>$maibriansg
		}
	done
}

_rsync (){
	# Add -v to rsync opts if in verbose mode
	if [ $verbose ];then
		rs_opts="$rs_opts -v"
	fi

	# Add --del to rsync opts if delete set
	if [ $delete ];then
		rs_opts="$rs_opts --del"
	fi

	# Add excludes if any 
	xclude=`awk <$xtmp '{printf(" --exclude %s",$1)}'`

	rsmsg="$cmd: `date` $host_id"

	[ $verbose ] &&{
		echo "$cmd: $rsmsg started" 
	}
	
	[ $log ] &&{
		logger -t $cmd "$rsmsg started"
	}
	[ $email ] &&{
		echo "$rsmsg started">>$maibriansg
	}
	
	# run rsync and check status on completion
	[ $verbose ] &&{
		echo "Desnaittion $rs_dest"
		echo "Source $host:$rsrc"
	}	
	if _chkSSH ;then
		$ssh $ssh_opts $rsudo $rsync $rs_opts $xclude  $rsrc $rs_dest
		rs_rv=$?
		ex_rv=$(expr $ex_rv + $rs_rv)
		if [ $rs_rv -eq 0 ];then
			result="success"
		else
			result="failed" 
			overall="Errors"
		fi
		[ $verbose ] &&{
			echo "$cmd: $rsmsg $result" 
		}
		[ $log ] &&{
			logger -t $cmd  "$rsmsg $result"
		}
		[ $email ] &&{
			echo "$rsmsg $result" >>$maibriansg
		}
	else
		echo "$cmd: ssh not available" >&2
		logger -t $cmd: "rsmsg failed. SSH not available."	
		[ $email ] &&{
			echo "$rmsg failed. SSH not available."
		}
	fi	
} # end of _rsync

# run selected archive 
for action in $archive; do
	case $action in
		rs) _rsync;shift;;
		db) _dbdump;shift;;
		tar) _tardump;shift;;
	esac
done

overall=${overall:-OK}
_end $overall


######################################################################
# This program is free software: you can redistribute it and or      #
# modify it under the terms of the Lesser GNU General Public License #
# as published by the Free Software Foundation, either version 3 of  #
# the License, or (at your option) any later version.                #
#                                                                    #
# This program is distributed in the hope that it will be useful,    #
# but WITHOUT ANY WARRANTY; without even the implied warranty of     #    
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      #
# GNU General Public License for more details.                       #
#                                                                    # 
# A copy of the Lesser GNU General Public License and the GNU        #
# General Public License is available at                             #
# <http://www.gnu.org/licenses/>.                                    #
######################################################################

The layout and associated style sheets for this page are taken from the World Wide Web Consortium and used here under the W3C software licence.