diff options
Diffstat (limited to 'handlers')
| -rw-r--r-- | handlers/ldap | 69 | ||||
| -rw-r--r-- | handlers/mysql | 133 | ||||
| -rw-r--r-- | handlers/parseini | 130 | ||||
| -rw-r--r-- | handlers/rdiff | 116 | ||||
| -rw-r--r-- | handlers/sh | 6 | 
5 files changed, 454 insertions, 0 deletions
| diff --git a/handlers/ldap b/handlers/ldap new file mode 100644 index 0000000..06e4e28 --- /dev/null +++ b/handlers/ldap @@ -0,0 +1,69 @@ +# +# openldap backup handler script for backupninja +# + +getconf backupdir /var/backups/ldap +getconf conf /etc/ldap/slapd.conf +getconf databases all +getconf compress yes +getconf ldif yes +getconf hotcopy no + +# hot copy is not yet supported + +status="ok" + +[ -f $conf ] || fatal "slapd config file ($conf) not found" +[ -d $backupdir ] || mkdir -p $backupdir +[ -d $backupdir ] || fatal "Backup directory '$backupdir'" + +dbsuffixes=(`awk 'BEGIN {OFS=":"} /[:space:]*^database[:space:]*\w*/ {db=$2}; /^[:space:]*suffix[:space:]*\w*/ {if (db=="bdb"||db=="ldbm") print db,$2}' $conf|sed -e 's/[" ]//g'`) + +## LDIF DUMP + +if [ "$ldif" == "yes" ]; then +	dumpdir="$backupdir" +	[ -d $dumpdir ] || mkdir -p $dumpdir + +	if [ "$databases" == 'all' ]; then +		dbcount=`grep '^database' $conf | wc -l` +		let "dbcount = dbcount - 1" +		databases=`seq 0 $dbcount`; +	fi	 +	 +	for db in $databases; do +		if [ `expr index "$dbnum" "="` == "0" ]; then +			# db is a number, get the suffix. +			dbsuffix=${dbsuffixes[$db]/*:/} +		else +			dbsuffix=$db +		fi +		# some databases don't have suffix (like monitor), skip these +		if [ "$dbsuffix" == "" ]; then +			continue; +		fi +		touch $dumpdir/$dbsuffix.ldif +		if [ ! -f $dumpdir/$dbsuffix.ldif ]; then +			fatal "Couldn't create ldif dump file: $dumpdir/$dbsuffix.ldif" +		fi +		execstr="$SLAPCAT -f $conf -b $dbsuffix -l $dumpdir/$dbsuffix.ldif" +		debug 0 "$execstr" +		if [ ! $test ]; then +			output=`$execstr` +			code=$? +			if [ "$code" == "0" ]; then +				debug 0 $output +				debug 1 "Successfully finished ldif export of $dbsuffix" +			else +				debug 2 $output +				debug 2 "Failed ldif export of $dbsuffix" +			fi +			if [ "$compress" == "yes" ]; then +				output=`$GZIP -f "$dumpdir/$dbsuffix.ldif" 2>&1` +				debug 0 $output +			fi +		fi +	done	 +fi + +return 0 diff --git a/handlers/mysql b/handlers/mysql new file mode 100644 index 0000000..4439bcc --- /dev/null +++ b/handlers/mysql @@ -0,0 +1,133 @@ +# +# mysql handler script for backupninja +# + +getconf backupdir /var/backups/mysql +getconf databases all +getconf compress yes +getconf dbusername +getconf dbpassword +getconf dbhost localhost +getconf hotcopy no +getconf sqldump no +getconf user root + +# create backup dirs + +[ -d $backupdir ] || mkdir -p $backupdir +[ -d $backupdir ] || fatal "Backup directory '$backupdir'" +hotdir="$backupdir/hotcopy" +dumpdir="$backupdir/sqldump" +[ "$sqldump" == "no" -o -d $dumpdir ] || mkdir -p $dumpdir +[ "$hotcopy" == "no" -o -d $hotdir ] || mkdir -p $hotdir + +# create .my.cnf + # (we do this because we don't want to have to specify the password on the command line + # because then anyone would be able to see it with a 'ps aux'. instead, we create a  + # temporary ~/.my.cnf in root's home directory). + +if [ "$dbusername" != "" ]; then +	home=`grep '^root' /etc/passwd | awk -F: '{print $6}'` +	[ -d $home ] || fatal "Can't find root's home directory ($home)." +	mycnf="$home/.my.cnf" +	if [ -f $mycnf ]; then +		# rename temporarily +		tmpcnf="$home/my.cnf.disable" +		debug 0 "mv $mycnf $tmpcnf" +		mv $mycnf $tmpcnf +	fi +	oldmask=`umask` +	umask 077 +	cat > $mycnf <<EOF +# auto generated backupninja mysql conf +[mysql] +user=$dbusername +password=$dbpassword + +[mysqldump] +user=$dbusername +password=$dbpassword + +[mysqlhotcopy] +user=$dbusername +password=$dbpassword +EOF +	umask $oldmask +fi +	 +## HOT COPY + +if [ "$hotcopy" == "yes" ]; then  +	if [ "$databases" == "all" ]; then +		execstr="$MYSQLHOTCOPY --quiet --allowold --regexp /.\*/./.\*/ $hotdir" +		debug 0 "su $user -c '$execstr'" +		if [ ! $test ]; then +			output=`su $user -c "$execstr" 2>&1` +			code=$? +			if [ "$code" == "0" ]; then +				debug 0 $output +				debug 1 "Successfully finished hotcopy of all mysql databases" +			else +				debug 2 $output +				debug 2 "Failed to hotcopy all mysql databases" +			fi +		fi +	else	 +		for db in $databases; do +			execstr="$MYSQLHOTCOPY --allowold $db $hotdir" +			debug 0 "su $user -c '$execstr'" +			if [ ! $test ]; then +				output=`su $user -c "$execstr" 2>&1` +				code=$? +				if [ "$code" == "0" ]; then +					debug 0 $output +					debug 1 "Successfully finished hotcopy of mysql database $db" +				else +					debug 2 $output +					debug 2 "Failed to hotcopy mysql database $db" +				fi +			fi +		done +	fi +fi +	 +## SQL DUMP + +if [ "$sqldump" == "yes" ]; then +	if [ "$databases" == "all" ]; then +		databases=`echo 'show databases' | su $user -c "$MYSQL" | grep -v Database` +	fi + +	for db in $databases; do +		execstr="$MYSQLDUMP --lock-tables --complete-insert --add-drop-table --quick --quote-names $db > $dumpdir/${db}.sql" +		debug 0 "su $user -c '$execstr'" +		if [ ! $test ]; then +			output=`su $user -c "$execstr" 2>&1` +			code=$? +			if [ "$code" == "0" ]; then +				debug 0 $output +				debug 1 "Successfully finished dump of mysql database $db" +			else +				debug 2 $output +				debug 2 "Failed to dump mysql databases $db" +			fi +		fi +	done +	 +	if [ "$compress" == "yes" ]; then +		output=`$GZIP -f $dumpdir/*.sql 2>&1` +		debug 0 $output +	fi +fi + +if [ "$dbusername" != "" ]; then +	## clean up tmp config file +	debug 0 "rm $mycnf" +	rm $mycnf +	if [ -f "$tmpcnf" ]; then +		debug 0 "mv $tmpcnf $mycnf" +		mv $tmpcnf $mycnf +	fi +fi + +return 0 diff --git a/handlers/parseini b/handlers/parseini new file mode 100644 index 0000000..6f56d42 --- /dev/null +++ b/handlers/parseini @@ -0,0 +1,130 @@ +#  +# parseini --- parses 'ini' style configuration files. +# +# Usage: +#   awk -f parseini S=<section> P=<param> <ini file> +# +# if section is an empty string, then we use the default section +# +# example ini file: +#  +#		fruit = apple +#		fruit = pear +#		multiline = this is a multiline \ +#       parameter +# +#       # this is a comment +# +#		[colors]   +#		red = yes +#		green = no +#		blue = maybe +#		 +#		[ocean]  +#		fish = red  +#		fish = blue +#        +# example usage: +#       > awk -f parseini S=ocean P=fish testfile.ini  +# would return:  +#       red +#       blue +# +    +BEGIN {  +    readlines = 1  +    implied = 1  +}  + +# remove lines starting with #, but not #! +/^#[^!]/ {next}  + +# skip blank +/^[ \r\t]*$/ {next}  + +# we want to read the lines of the matched section +# and disable for other sections +/^\[.+\][ \r\t]*$/ {  +    continueline = 0  +    if (S && implied) {  +        nline = 0  +        implied = 0  +    }  +    if (S && match($0, "^\\[" S "\\][ \n]*")) {  +        # we found the section, so start reading. +        readlines = 1  +    }  +    else {  +        # no section, so stop reading lines +        if (readlines) readlines = 0  +    }  +    next  +}  + +# when reading, store lines. + +{  +    if (!readlines) next  +    line[nline++] = $0  +    if ($0 ~ /\\[ \r\t]*$/)  +        continueline = 1  +    else  +        continueline = 0  +}  + +# process the read lines lines, matching parameters + +END {  +    # if section is set but implied is still true +    # then we never found the section, so use everything +    if (S && implied) {  +        nline = 0  +    }  + +    # if have P then find P in read lines and get values  +    if (P) {  +        MATCH = "^[ \r\t]*" P "[ \r\t]*="  +        continueline = 0  +        for (x = 0; x < nline; ++x) {  +            v = line[x]  +            if (continueline) {  +                sub(/[ \r\t]+$/, "", v)  +                if (v ~ /\\$/) {  +                   v = substr(v, 1, length(v)-1)  +                   sub(/[ \r\t]+$/, "", v)  +                }  +                if (v) value[nvalue++] = v  +            }  +            else if (v ~ MATCH) {  +                sub(MATCH, "", v)  +                sub(/^[ \r\t]+/, "", v)  +                sub(/[ \r\t]+$/, "", v)  +                if (v ~ /\\$/) {  +                    continueline = 1  +                    v = substr(v, 1, length(v)-1)  +                    sub(/[ \r\t]+$/, "", v)  +                }  +                if (v) value[nvalue++] = v  +            }  +        }  +        # copy parameter definition to output array  +        nline = nvalue  +        for (x = 0; x < nvalue; ++x)  +            line[x] = value[x]  +    }  + +    # trim all leading & trailing whitespace;  +    # except for leading whitespace in continuation lines,  +  +    for (x = 0; x < nline; ++x) {  +        sub(/^[ \r\t]+/, "", line[x])  +        sub(/[ \r\t]+$/, "", line[x])  +     }  +  +    # output the final result +    for (x = 0; x < nline; ++x)  +        print line[x]  + +    if (nline) exit 0  +    else exit 1  +} diff --git a/handlers/rdiff b/handlers/rdiff new file mode 100644 index 0000000..1f2058f --- /dev/null +++ b/handlers/rdiff @@ -0,0 +1,116 @@ +# +# rdiff-backup handler script for backupninja +# requires rdiff-backup +# + +setsection source +getconf type; sourcetype=$type +getconf label +getconf user; sourceuser=$user +getconf keep +getconf include +getconf exclude + +### DESTINATION ### + +setsection dest +getconf directory; destdir=$directory +# strip trailing / +destdir=${destdir%/} +getconf type; desttype=$type +getconf user; destuser=$user +getconf host; desthost=$host + +[ "$destdir" != "" ] || fatal "Destination directory not set" +[ "$desttype" == "remote" ] || fatal "Only remote destinations are supported" + +# see if we can login +debug 0 "su $sourceuser -c \"ssh -o PasswordAuthentication=no $desthost -l $destuser 'echo -n 1'\"" +if [ ! $test ]; then +	result=`su $sourceuser -c "ssh -o PasswordAuthentication=no $desthost -l $destuser 'echo -n 1'" 2>&1` +	if [ "$result" != "1" ]; then +		fatal "Can't connect to $desthost as $destuser." +	fi +fi + +# see that rdiff-backup has the same version as here +debug 0 "su $sourceuser -c \"ssh $desthost -l $destuser '$RDIFFBACKUP -V'\"" +if [ ! $test ]; then +	remoteversion=`su $sourceuser -c "ssh $desthost -l $destuser '$RDIFFBACKUP -V'" 2>&1` +	localversion=`$RDIFFBACKUP -V` +	if [ "$remoteversion" != "$localversion" ]; then +		fatal "rdiff-backup does not have the same version on this computer and the backup server." +	fi +fi + +execstr_serverpart="$destuser@$desthost::$destdir/$label" +		 +### SOURCE ### + +[ "$label" != "" ] || fatal "Source missing label" +[ "$sourcetype" == "local" ] || fatal "Only local source type supported" +[ "$include" != "" ] || fatal "No source includes specified" + +execstr_clientpart="/" +	 +## REMOVE OLD BACKUPS + +if [ "$keep" -gt "0" ]; then +	removestr="rdiff-backup --force --remove-older-than ${keep}D " +	if [ "$desttype" == "remote" ]; then +		removestr="${removestr}${destuser}@${desthost}::" +	fi +	removestr="${removestr}${destdir}/${label}"; +	 +	debug 0 "su $sourceuser -c '$removestr'" +	if [ ! $test ]; then +		output=`su $sourceuser -c "$removestr" 2>&1` +		code=$? +		if [ "$code" == "0" ]; then +			debug 0 $output +			debug 1 "Removing backups older than $keep days succeeded." +		else +			debug 2 $output +			debug 2 "Failed removing backups older than $keep." +		fi +	fi +fi + +## EXECUTE ## +	 +execstr="$RDIFFBACKUP --print-statistics " + +# TODO: order the includes and excludes + +# excludes +for i in $exclude; do +	str="${i//__star__/*}" +	execstr="${execstr}--exclude '$str' " +done +	 +# includes  +for i in $include; do +	str="${i//__star__/*}" +	execstr="${execstr}--include '$str' " +done + +# exclude everything else +execstr="${execstr}--exclude '/*' " +		 +# include client-part and server-part +execstr="${execstr}$execstr_clientpart $execstr_serverpart" + +debug 0 "su $sourceuser -c '$execstr'" +if [ ! $test ]; then +	output=`su $sourceuser -c "$execstr" 2>&1` +	code=$? +	if [ "$code" == "0" ]; then +		debug 0 $output +		debug 1 "Successfully finished backing up source '$label'" +	else +		debug 2 $output +		debug 2 "Failed backup up source '$label'" +	fi +fi	 + +return 0 diff --git a/handlers/sh b/handlers/sh new file mode 100644 index 0000000..6b1644d --- /dev/null +++ b/handlers/sh @@ -0,0 +1,6 @@ +# +# shell script handler for backupninja +# runs the file /etc/backup.d/scriptname.sh +#  + +[ $test ] || ( . $1 ) | 
