From: intrigeri Date: Fri, 12 Oct 2007 17:06:09 +0000 (+0000) Subject: fixed autotools build, broken since r466, inhandlers/Makefile.am X-Git-Url: https://git.stderr.nl/gitweb?a=commitdiff_plain;h=2bca513c38c70cd7a56bef23512183629e91bade;p=matthijs%2Fupstream%2Fbackupninja.git fixed autotools build, broken since r466, inhandlers/Makefile.am git-svn-id: http://code.autistici.org/svn/backupninja/trunk@478 758a04ac-41e6-0310-8a23-8373a73cc35d --- diff --git a/handlers/Makefile.am b/handlers/Makefile.am index b627f79..24efe89 100644 --- a/handlers/Makefile.am +++ b/handlers/Makefile.am @@ -1,7 +1,7 @@ -HANDLERS = dup dup.helper maildir mysql.helper rdiff sys makecd makecd.helper \ - rdiff.helper rsnap rub sys.helper ldap pgsql sh trac \ - ldap.helper mysql pgsql.helper svn +HANDLERS = dup dup.helper ldap ldap.helper maildir makecd \ + makecd.helper mysql mysql.helper pgsql pgsql.helper rdiff \ + rdiff.helper rsnap rub sh svn sys sys.helper trac EXTRA_DIST = Makefile.am $(HANDLERS) @@ -11,3 +11,84 @@ edit = sed \ -e "s,@SED\@,$(SED),g" dist_pkgdata_DATA = $(HANDLERS) + +dup: $(srcdir)/dup.in + rm -f dup + $(edit) $(srcdir)/dup.in > dup + +dup.helper: $(srcdir)/dup.helper.in + rm -f dup.helper + $(edit) $(srcdir)/dup.helper.in > dup.helper + +ldap: $(srcdir)/ldap.in + rm -f ldap + $(edit) $(srcdir)/ldap.in > ldap + +ldap.helper: $(srcdir)/ldap.helper.in + rm -f ldap.helper + $(edit) $(srcdir)/ldap.helper.in > ldap.helper + +maildir: $(srcdir)/maildir.in + rm -f maildir + $(edit) $(srcdir)/maildir.in > maildir + +makecd: $(srcdir)/makecd.in + rm -f makecd + $(edit) $(srcdir)/makecd.in > makecd + +makecd.helper: $(srcdir)/makecd.helper.in + rm -f makecd.helper + $(edit) $(srcdir)/makecd.helper.in > makecd.helper + +mysql: $(srcdir)/mysql.in + rm -f mysql + $(edit) $(srcdir)/mysql.in > mysql + +mysql.helper: $(srcdir)/mysql.helper.in + rm -f mysql.helper + $(edit) $(srcdir)/mysql.helper.in > mysql.helper + +pgsql: $(srcdir)/pgsql.in + rm -f pgsql + $(edit) $(srcdir)/pgsql.in > pgsql + +pgsql.helper: $(srcdir)/pgsql.helper.in + rm -f pgsql.helper + $(edit) $(srcdir)/pgsql.helper.in > pgsql.helper + +rdiff: $(srcdir)/rdiff.in + rm -f rdiff + $(edit) $(srcdir)/rdiff.in > rdiff + +rdiff.helper: $(srcdir)/rdiff.helper.in + rm -f rdiff.helper + $(edit) $(srcdir)/rdiff.helper.in > rdiff.helper + +rsnap: $(srcdir)/rsnap.in + rm -f rsnap + $(edit) $(srcdir)/rsnap.in > rsnap + +rub: $(srcdir)/rub.in + rm -f rub + $(edit) $(srcdir)/rub.in > rub + +sh: $(srcdir)/sh.in + rm -f sh + $(edit) $(srcdir)/sh.in > sh + +svn: $(srcdir)/svn.in + rm -f svn + $(edit) $(srcdir)/svn.in > svn + +sys: $(srcdir)/sys.in + rm -f sys + $(edit) $(srcdir)/sys.in > sys + +sys.helper: $(srcdir)/sys.helper.in + rm -f sys.helper + $(edit) $(srcdir)/sys.helper.in > sys.helper + +trac: $(srcdir)/trac.in + rm -f trac + $(edit) $(srcdir)/trac.in > trac + diff --git a/handlers/dup b/handlers/dup deleted file mode 100644 index edb43ac..0000000 --- a/handlers/dup +++ /dev/null @@ -1,178 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- -# -# duplicity script for backupninja -# requires duplicity -# - -getconf options -getconf testconnect yes -getconf nicelevel 0 - -setsection gpg -getconf password -getconf sign no -getconf encryptkey -getconf signkey - -setsection source -getconf include -getconf vsnames all -getconf vsinclude -getconf exclude - -setsection dest -getconf incremental yes -getconf keep 60 -getconf sshoptions -getconf bandwidthlimit 0 -getconf desthost -getconf destdir -getconf destuser -destdir=${destdir%/} - -[ "$destdir" != "" ] || fatal "Destination directory not set" -[ "$include" != "" ] || fatal "No source includes specified" - -### vservers stuff ### - -# If vservers are configured, check that the ones listed in $vsnames do exist. -local usevserver=no -if [ $vservers_are_available = yes ]; then - if [ "$vsnames" = all ]; then - vsnames="$found_vservers" - else - if ! vservers_exist "$vsnames" ; then - fatal "At least one of the vservers listed in vsnames ($vsnames) does not exist." - fi - fi - if [ -n "$vsinclude" ]; then - info "Using vservers '$vsnames'" - usevserver=yes - fi -else - [ -z "$vsinclude" ] || warning 'vservers support disabled in backupninja.conf, vsincludes configuration lines will be ignored' -fi - - -### see if we can login ### - -if [ "$testconnect" == "yes" ]; then - debug "ssh $sshoptions -o PasswordAuthentication=no $desthost -l $destuser 'echo -n 1'" - if [ ! $test ]; then - result=`ssh $sshoptions -o PasswordAuthentication=no $desthost -l $destuser 'echo -n 1'` - if [ "$result" != "1" ]; then - fatal "Can't connect to $desthost as $destuser." - else - debug "Connected to $desthost as $destuser successfully" - fi - fi -fi - -### COMMAND-LINE MANGLING ### - -# duplicity >= 0.4.2 needs --sftp-command (NB: sftp does not support the -l option) -duplicity_version="`duplicity --version | @AWK@ '{print $2}'`" -duplicity_major="`echo $duplicity_version | @AWK@ -F '.' '{print $1}'`" -duplicity_minor="`echo $duplicity_version | @AWK@ -F '.' '{print $2}'`" -duplicity_sub="`echo $duplicity_version | @AWK@ -F '.' '{print $3}'`" -if [ "$duplicity_major" -ge 0 -a "$duplicity_minor" -ge 4 -a "$duplicity_sub" -ge 2 ]; then - sftpoptions="$sshoptions" -fi - -scpoptions="$sshoptions" -[ "$bandwidthlimit" == 0 ] || scpoptions="$scpoptions -l $bandwidthlimit" - -if [ -z "$sftpoptions" ]; then - execstr="$options --no-print-statistics --scp-command 'scp $scpoptions' --ssh-command 'ssh $sshoptions' " -else - execstr="$options --no-print-statistics --scp-command 'scp $scpoptions' --sftp-command 'sftp $sftpoptions' --ssh-command 'ssh $sshoptions' " -fi - -# deal with symmetric or asymmetric (public/private key pair) encryption -if [ -n "$encryptkey" ]; then - execstr="${execstr}--encrypt-key $encryptkey " - debug "Data will be encrypted with the GnuPG key $encryptkey." -else - debug "Data will be encrypted using symmetric encryption." -fi - -# deal with data signing -if [ "$sign" == yes ]; then - # duplicity is not able to sign data when using symmetric encryption - [ -n "$encryptkey" ] || fatal "The encryptkey option must be set when signing." - # if needed, initialize signkey to a value that is not empty (checked above) - [ -n "$signkey" ] || signkey="$encryptkey" - execstr="${execstr}--sign-key $signkey " - debug "Data will be signed will the GnuPG key $signkey." -else - debug "Data won't be signed." -fi - -# deal with GnuPG passphrase -[ -n "$password" ] || fatal "The password option must be set." - -if [ "$keep" != "yes" ]; then - if [ "`echo $keep | tr -d 0-9`" == "" ]; then - keep="${keep}D" - fi - execstr="${execstr}--remove-older-than $keep " -fi - -if [ "$incremental" == "no" ]; then - execstr="${execstr}--full " -fi - -execstr_serverpart="scp://$destuser@$desthost/$destdir" -execstr_clientpart="/" - -### SOURCE ### - -set -o noglob - -# excludes -for i in $exclude; do - str="${i//__star__/*}" - execstr="${execstr}--exclude '$str' " -done - -# includes -for i in $include; do - [ "$i" != "/" ] || fatal "Sorry, you cannot use 'include = /'" - str="${i//__star__/*}" - execstr="${execstr}--include '$str' " -done - -# vsincludes -if [ $usevserver = yes ]; then - for vserver in $vsnames; do - for vi in $vsinclude; do - str="${vi//__star__/*}" - str="$VROOTDIR/$vserver$str" - execstr="${execstr}--include '$str' " - done - done -fi - -set +o noglob - -### EXECUTE ### - -execstr=${execstr//\\*/\\\\\\*} - -debug "duplicity $execstr --exclude '**' / $execstr_serverpart" -if [ ! $test ]; then - export PASSPHRASE=$password - output=`nice -n $nicelevel \ - su -c \ - "duplicity $execstr --exclude '**' / $execstr_serverpart 2>&1"` - code=$? - if [ $code -eq 0 ]; then - debug $output - info "Duplicity finished successfully." - else - debug $output - fatal "Duplicity failed." - fi -fi - -return 0 diff --git a/handlers/dup.helper b/handlers/dup.helper deleted file mode 100644 index eee0256..0000000 --- a/handlers/dup.helper +++ /dev/null @@ -1,508 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- - -HELPERS="$HELPERS dup:incremental_encrypted_remote_filesystem_backup" - -### Functions - -do_dup_host_includes() { - set -o noglob - # choose the files to backup - REPLY= - while [ -z "$REPLY" ]; do - formBegin "$dup_title - host system: includes" - [ -z "$dup_includes" ] && dup_includes="$dup_default_includes" - for i in $dup_includes; do - formItem include "$i" - done - formItem include "" - formItem include "" - formItem include "" - formDisplay - [ $? = 0 ] || return 1 - dup_includes="$REPLY" - done - set +o noglob -} - -do_dup_vserver() { - # choose the vservers to backup (into $selected_vservers) - choose_one_or_more_vservers "$dup_title" - [ $? = 0 ] || return 1 - - set -o noglob - # choose the files to backup - REPLY= - while [ -z "$REPLY" ]; do - formBegin "$dup_title - vservers: vsincludes (backup these directories from every selected vserver)" - [ -z "$dup_vsincludes" ] && dup_vsincludes="$dup_default_includes" - for i in $dup_vsincludes; do - formItem include "$i" - done - formItem include "" - formItem include "" - formItem include "" - formDisplay - [ $? = 0 ] || return 1 - dup_vsincludes="$REPLY" - done - set +o noglob -} - -do_dup_excludes() { - set -o noglob - formBegin "$dup_title: excludes" - [ -z "$dup_excludes" ] && dup_excludes="$dup_default_excludes" - for i in $dup_excludes; do - formItem exclude "$i" - done - formItem exclude "" - formItem exclude "" - formItem exclude "" - formDisplay - [ $? = 0 ] || return 1 - dup_excludes="$REPLY" - set +o noglob -} - -do_dup_src() { - choose_host_or_vservers_or_both "$dup_title" - [ $? = 0 ] || return 1 - case $host_or_vservers in - 'host') - do_dup_host_includes - [ $? = 0 ] || return 1 - ;; - 'vservers') - do_dup_vserver - [ $? = 0 ] || return 1 - ;; - 'both') - do_dup_host_includes - [ $? = 0 ] || return 1 - do_dup_vserver - [ $? = 0 ] || return 1 - ;; - *) - return 1 - ;; - esac - do_dup_excludes - [ $? = 0 ] || return 1 - - _src_done="(DONE)" - setDefault dest -} - -do_dup_dest() { - - local replyconverted - local thereply - - set -o noglob - REPLY= - while [ -z "$REPLY" -o -z "$dup_destdir" -o -z "$dup_desthost" -o -z "$dup_destuser" ]; do - formBegin "$dup_title - destination: first three items are compulsory" - formItem "desthost" "$dup_desthost" - formItem "destuser" "$dup_destuser" - formItem "destdir" "$dup_destdir" - formItem "keep" "$dup_keep" - formItem "incremental" "$dup_incremental" - formItem "bandwidthlimit" "$dup_bandwidth" - formItem "sshoptions" "$dup_sshoptions" - formDisplay - [ $? = 0 ] || return 1 - - IFS=$'' - replyconverted=`echo $REPLY | tr '\n' :` - IFS=$':' - thereply=($replyconverted) - IFS=$' \t\n' - - dup_desthost=${thereply[0]} - dup_destuser=${thereply[1]} - dup_destdir=${thereply[2]} - dup_keep=${thereply[3]} - dup_incremental=${thereply[4]} - dup_bandwidth=${thereply[5]} - dup_sshoptions=${thereply[6]} - - done - set +o noglob - - _dest_done="(DONE)" - setDefault gpg -} - -do_dup_gpg_encryptkey() { - REPLY= - while [ -z "$REPLY" -o -z "$dup_gpg_encryptkey" ]; do - inputBox "$dup_title - GnuPG" "Enter ID of the public GnuPG key to be used to encrypt the backups:" "$dup_gpg_encryptkey" - [ $? = 0 ] || return 1 - dup_gpg_encryptkey="$REPLY" - done -} - -do_dup_gpg_sign() { - # sign ? - booleanBox "$dup_title - GnuPG" "Sign the backups?" "$dup_gpg_sign" - if [ $? = 0 ]; then - dup_gpg_sign=yes - else - dup_gpg_sign=no - fi -} - -do_dup_gpg_signkey() { - # one key pair ? - booleanBox "$dup_title - GnuPG" "Use the same GnuPG key pair for encryption and signing?" "$dup_gpg_onekeypair" - if [ $? = 0 ]; then - dup_gpg_onekeypair=yes - else - dup_gpg_onekeypair=no - fi - - if [ "$dup_gpg_onekeypair" == "no" }; then - # signkey ? - REPLY= - while [ -z "$REPLY" -o -z "$dup_gpg_signkey" ]; do - inputBox "$dup_title - GnuPG" "Enter the ID of the private GnuPG key to be used to sign the backups:" "$dup_gpg_signkey" - [ $? = 0 ] || return 1 - dup_gpg_signkey="$REPLY" - done - fi -} - -do_dup_gpg_passphrase() { - local question="Enter the passphrase needed to unlock the GnuPG key:" - REPLY= - while [ -z "$REPLY" -o -z "$dup_gpg_password" ]; do - passwordBox "$dup_title - GnuPG" "$question" - [ $? = 0 ] || return 1 - dup_gpg_password="$REPLY" - done -} - -do_dup_gpg() { - - # symmetric or public key encryption ? - booleanBox "$dup_title - GnuPG" "Use public key encryption? Otherwise, symmetric encryption will be used, and data signing will be impossible." "$dup_gpg_asymmetric_encryption" - if [ $? = 0 ]; then - dup_gpg_asymmetric_encryption=yes - else - dup_gpg_asymmetric_encryption=no - fi - - # when using public/private key pair encryption, ask for the keys to use - if [ "$dup_gpg_asymmetric_encryption" == yes ]; then - do_dup_gpg_encryptkey ; [ $? = 0 ] || return 1 - do_dup_gpg_sign ; [ $? = 0 ] || return 1 - if [ "$dup_gpg_sign" == yes ]; then - do_dup_gpg_signkey ; [ $? = 0 ] || return 1 - fi - else - dup_gpg_sign=no - fi - - # a passphrase is alway needed - do_dup_gpg_passphrase - - _gpg_done="(DONE)" - setDefault adv - # TODO: replace the above line by the following when do_dup_conn is written - # setDefault conn -} - -# TODO: share rdiff.helper code in some lib, and use it here -do_dup_conn() { - _con_done="(DONE)" - setDefault adv -} - -do_dup_misc_options() { - - set -o noglob - local replyconverted - local thereply - - formBegin "$dup_title - misc. options" - formItem "nicelevel" "$dup_nicelevel" - formItem "testconnect" "$dup_testconnect" - formItem "options" "$dup_options" - formDisplay - [ $? = 0 ] || return 1 - - IFS=$'' - replyconverted=`echo $REPLY | tr '\n' :` - IFS=$':' - thereply=($replyconverted) - IFS=$' \t\n' - - dup_nicelevel=${thereply[0]} - dup_testconnect=${thereply[1]} - dup_options=${thereply[2]} - - set +o noglob -} - -# (rdiff.helper compatible interface... there could be some sode to share, hmmm.) -do_dup_adv() { - do_dup_misc_options - [ $? = 0 ] || return 1 - _adv_done="(DONE)" - setDefault finish -} - -do_dup_finish() { - get_next_filename $configdirectory/90.dup - cat > $next_filename <> $next_filename - done - set +o noglob - fi - - cat >> $next_filename < ... (default = all) -# vsinclude = -# vsinclude = -# ... -# Any path specified in vsinclude is added to the include list for each vserver -# listed in vsnames (or all if vsnames = all, which is the default). -# -# For example, vsinclude = /home will backup the /home directory in every -# vserver listed in vsnames. If you have 'vsnames = foo bar baz', this -# vsinclude will add to the include list /vservers/foo/home, /vservers/bar/home -# and /vservers/baz/home. -# Vservers paths are derived from $VROOTDIR. - -EOF - - if [ "$host_or_vservers" == vservers -o "$host_or_vservers" == both ]; then - set -o noglob - echo -e "vsnames = $selected_vservers\n" >> $next_filename - for i in $dup_vsincludes; do - echo "vsinclude = $i" >> $next_filename - done - set +o noglob - fi - - # excludes - cat >> $next_filename <> $next_filename - done - set +o noglob - - cat >> $next_filename <=0.4.2) -# warning: sftp does not support all scp options, especially -i; as -# a workaround, you can use "-o " -#sshoptions = -o IdentityFile=/root/.ssh/id_dsa_duplicity -sshoptions = $dup_sshoptions - -# put the backups under this directory -destdir = $dup_destdir - -# the machine which will receive the backups -desthost = $dup_desthost - -# make the files owned by this user -# note: you must be able to ssh backupuser@backhost -# without specifying a password (if type = remote). -destuser = $dup_destuser - -EOF - - chmod 600 $next_filename - -} - -dup_main_menu() { - - while true; do - srcitem="choose files to include & exclude $_src_done" - destitem="configure backup destination $_dest_done" - gpgitem="configure GnuPG encryption/signing $_gpg_done" - conitem="set up ssh keys and test remote connection $_con_done" - advitem="edit advanced settings $_adv_done" - # TODO: add the following to the menu when do_dup_conn is written - # conn "$conitem" \ - menuBox "$dup_title" "choose a step:" \ - src "$srcitem" \ - dest "$destitem" \ - gpg "$gpgitem" \ - adv "$advitem" \ - finish "finish and create config file" - [ $? = 0 ] || return 1 - result="$REPLY" - - case "$result" in - "src") do_dup_src;; - "dest") do_dup_dest;; - "gpg") do_dup_gpg;; - # TODO: enable the following when do_dup_conn is written - # "conn") do_dup_conn;; - "adv") do_dup_adv;; - "finish") - if [[ "$_dest_done$_gpg_done$_src_done" != "(DONE)(DONE)(DONE)" ]]; then - # TODO: replace the previous test by the following when do_dup_conn is written - # if [[ "$_con_done$_dest_done$_gpg_done$_src_done" != "(DONE)(DONE)(DONE)(DONE)" ]]; then - msgBox "$dup_title" "You cannot create the configuration file until the four first steps are completed." - else - do_dup_finish - break - fi - ;; - esac - - done -} - -### Main function - -dup_wizard() { - - require_packages duplicity - - # Global variables - dup_title="Duplicity action wizard" - _src_done= - _dest_done= - _con_done= - _gpg_done= - _adv_done= - dup_includes= - dup_excludes= - dup_vsincludes= - dup_incremental=yes - dup_keep=60 - dup_bandwidth= - dup_sshoptions= - dup_destdir="/backups/`hostname`" - dup_desthost= - dup_destuser= - dup_gpg_asymmetric_encryption="yes" - dup_gpg_encryptkey="" - dup_gpg_sign="yes" - dup_gpg_onekeypair="yes" - dup_gpg_signkey="" - dup_gpg_password="" - dup_nicelevel=19 - dup_testconnect=yes - dup_options= - - # Global variables whose '*' shall not be expanded - set -o noglob - dup_default_includes="/var/spool/cron/crontabs /var/backups /etc /root /home /usr/local/*bin /var/lib/dpkg/status*" - dup_default_excludes="/home/*/.gnupg /home/*/.gnupg /home/*/.local/share/Trash /home/*/.Trash /home/*/.thumbnails /home/*/.beagle /home/*/.aMule /home/*/gtk-gnutella-downloads" - set +o noglob - - dup_main_menu -} diff --git a/handlers/dup.helper.in b/handlers/dup.helper.in new file mode 100644 index 0000000..eee0256 --- /dev/null +++ b/handlers/dup.helper.in @@ -0,0 +1,508 @@ +# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- + +HELPERS="$HELPERS dup:incremental_encrypted_remote_filesystem_backup" + +### Functions + +do_dup_host_includes() { + set -o noglob + # choose the files to backup + REPLY= + while [ -z "$REPLY" ]; do + formBegin "$dup_title - host system: includes" + [ -z "$dup_includes" ] && dup_includes="$dup_default_includes" + for i in $dup_includes; do + formItem include "$i" + done + formItem include "" + formItem include "" + formItem include "" + formDisplay + [ $? = 0 ] || return 1 + dup_includes="$REPLY" + done + set +o noglob +} + +do_dup_vserver() { + # choose the vservers to backup (into $selected_vservers) + choose_one_or_more_vservers "$dup_title" + [ $? = 0 ] || return 1 + + set -o noglob + # choose the files to backup + REPLY= + while [ -z "$REPLY" ]; do + formBegin "$dup_title - vservers: vsincludes (backup these directories from every selected vserver)" + [ -z "$dup_vsincludes" ] && dup_vsincludes="$dup_default_includes" + for i in $dup_vsincludes; do + formItem include "$i" + done + formItem include "" + formItem include "" + formItem include "" + formDisplay + [ $? = 0 ] || return 1 + dup_vsincludes="$REPLY" + done + set +o noglob +} + +do_dup_excludes() { + set -o noglob + formBegin "$dup_title: excludes" + [ -z "$dup_excludes" ] && dup_excludes="$dup_default_excludes" + for i in $dup_excludes; do + formItem exclude "$i" + done + formItem exclude "" + formItem exclude "" + formItem exclude "" + formDisplay + [ $? = 0 ] || return 1 + dup_excludes="$REPLY" + set +o noglob +} + +do_dup_src() { + choose_host_or_vservers_or_both "$dup_title" + [ $? = 0 ] || return 1 + case $host_or_vservers in + 'host') + do_dup_host_includes + [ $? = 0 ] || return 1 + ;; + 'vservers') + do_dup_vserver + [ $? = 0 ] || return 1 + ;; + 'both') + do_dup_host_includes + [ $? = 0 ] || return 1 + do_dup_vserver + [ $? = 0 ] || return 1 + ;; + *) + return 1 + ;; + esac + do_dup_excludes + [ $? = 0 ] || return 1 + + _src_done="(DONE)" + setDefault dest +} + +do_dup_dest() { + + local replyconverted + local thereply + + set -o noglob + REPLY= + while [ -z "$REPLY" -o -z "$dup_destdir" -o -z "$dup_desthost" -o -z "$dup_destuser" ]; do + formBegin "$dup_title - destination: first three items are compulsory" + formItem "desthost" "$dup_desthost" + formItem "destuser" "$dup_destuser" + formItem "destdir" "$dup_destdir" + formItem "keep" "$dup_keep" + formItem "incremental" "$dup_incremental" + formItem "bandwidthlimit" "$dup_bandwidth" + formItem "sshoptions" "$dup_sshoptions" + formDisplay + [ $? = 0 ] || return 1 + + IFS=$'' + replyconverted=`echo $REPLY | tr '\n' :` + IFS=$':' + thereply=($replyconverted) + IFS=$' \t\n' + + dup_desthost=${thereply[0]} + dup_destuser=${thereply[1]} + dup_destdir=${thereply[2]} + dup_keep=${thereply[3]} + dup_incremental=${thereply[4]} + dup_bandwidth=${thereply[5]} + dup_sshoptions=${thereply[6]} + + done + set +o noglob + + _dest_done="(DONE)" + setDefault gpg +} + +do_dup_gpg_encryptkey() { + REPLY= + while [ -z "$REPLY" -o -z "$dup_gpg_encryptkey" ]; do + inputBox "$dup_title - GnuPG" "Enter ID of the public GnuPG key to be used to encrypt the backups:" "$dup_gpg_encryptkey" + [ $? = 0 ] || return 1 + dup_gpg_encryptkey="$REPLY" + done +} + +do_dup_gpg_sign() { + # sign ? + booleanBox "$dup_title - GnuPG" "Sign the backups?" "$dup_gpg_sign" + if [ $? = 0 ]; then + dup_gpg_sign=yes + else + dup_gpg_sign=no + fi +} + +do_dup_gpg_signkey() { + # one key pair ? + booleanBox "$dup_title - GnuPG" "Use the same GnuPG key pair for encryption and signing?" "$dup_gpg_onekeypair" + if [ $? = 0 ]; then + dup_gpg_onekeypair=yes + else + dup_gpg_onekeypair=no + fi + + if [ "$dup_gpg_onekeypair" == "no" }; then + # signkey ? + REPLY= + while [ -z "$REPLY" -o -z "$dup_gpg_signkey" ]; do + inputBox "$dup_title - GnuPG" "Enter the ID of the private GnuPG key to be used to sign the backups:" "$dup_gpg_signkey" + [ $? = 0 ] || return 1 + dup_gpg_signkey="$REPLY" + done + fi +} + +do_dup_gpg_passphrase() { + local question="Enter the passphrase needed to unlock the GnuPG key:" + REPLY= + while [ -z "$REPLY" -o -z "$dup_gpg_password" ]; do + passwordBox "$dup_title - GnuPG" "$question" + [ $? = 0 ] || return 1 + dup_gpg_password="$REPLY" + done +} + +do_dup_gpg() { + + # symmetric or public key encryption ? + booleanBox "$dup_title - GnuPG" "Use public key encryption? Otherwise, symmetric encryption will be used, and data signing will be impossible." "$dup_gpg_asymmetric_encryption" + if [ $? = 0 ]; then + dup_gpg_asymmetric_encryption=yes + else + dup_gpg_asymmetric_encryption=no + fi + + # when using public/private key pair encryption, ask for the keys to use + if [ "$dup_gpg_asymmetric_encryption" == yes ]; then + do_dup_gpg_encryptkey ; [ $? = 0 ] || return 1 + do_dup_gpg_sign ; [ $? = 0 ] || return 1 + if [ "$dup_gpg_sign" == yes ]; then + do_dup_gpg_signkey ; [ $? = 0 ] || return 1 + fi + else + dup_gpg_sign=no + fi + + # a passphrase is alway needed + do_dup_gpg_passphrase + + _gpg_done="(DONE)" + setDefault adv + # TODO: replace the above line by the following when do_dup_conn is written + # setDefault conn +} + +# TODO: share rdiff.helper code in some lib, and use it here +do_dup_conn() { + _con_done="(DONE)" + setDefault adv +} + +do_dup_misc_options() { + + set -o noglob + local replyconverted + local thereply + + formBegin "$dup_title - misc. options" + formItem "nicelevel" "$dup_nicelevel" + formItem "testconnect" "$dup_testconnect" + formItem "options" "$dup_options" + formDisplay + [ $? = 0 ] || return 1 + + IFS=$'' + replyconverted=`echo $REPLY | tr '\n' :` + IFS=$':' + thereply=($replyconverted) + IFS=$' \t\n' + + dup_nicelevel=${thereply[0]} + dup_testconnect=${thereply[1]} + dup_options=${thereply[2]} + + set +o noglob +} + +# (rdiff.helper compatible interface... there could be some sode to share, hmmm.) +do_dup_adv() { + do_dup_misc_options + [ $? = 0 ] || return 1 + _adv_done="(DONE)" + setDefault finish +} + +do_dup_finish() { + get_next_filename $configdirectory/90.dup + cat > $next_filename <> $next_filename + done + set +o noglob + fi + + cat >> $next_filename < ... (default = all) +# vsinclude = +# vsinclude = +# ... +# Any path specified in vsinclude is added to the include list for each vserver +# listed in vsnames (or all if vsnames = all, which is the default). +# +# For example, vsinclude = /home will backup the /home directory in every +# vserver listed in vsnames. If you have 'vsnames = foo bar baz', this +# vsinclude will add to the include list /vservers/foo/home, /vservers/bar/home +# and /vservers/baz/home. +# Vservers paths are derived from $VROOTDIR. + +EOF + + if [ "$host_or_vservers" == vservers -o "$host_or_vservers" == both ]; then + set -o noglob + echo -e "vsnames = $selected_vservers\n" >> $next_filename + for i in $dup_vsincludes; do + echo "vsinclude = $i" >> $next_filename + done + set +o noglob + fi + + # excludes + cat >> $next_filename <> $next_filename + done + set +o noglob + + cat >> $next_filename <=0.4.2) +# warning: sftp does not support all scp options, especially -i; as +# a workaround, you can use "-o " +#sshoptions = -o IdentityFile=/root/.ssh/id_dsa_duplicity +sshoptions = $dup_sshoptions + +# put the backups under this directory +destdir = $dup_destdir + +# the machine which will receive the backups +desthost = $dup_desthost + +# make the files owned by this user +# note: you must be able to ssh backupuser@backhost +# without specifying a password (if type = remote). +destuser = $dup_destuser + +EOF + + chmod 600 $next_filename + +} + +dup_main_menu() { + + while true; do + srcitem="choose files to include & exclude $_src_done" + destitem="configure backup destination $_dest_done" + gpgitem="configure GnuPG encryption/signing $_gpg_done" + conitem="set up ssh keys and test remote connection $_con_done" + advitem="edit advanced settings $_adv_done" + # TODO: add the following to the menu when do_dup_conn is written + # conn "$conitem" \ + menuBox "$dup_title" "choose a step:" \ + src "$srcitem" \ + dest "$destitem" \ + gpg "$gpgitem" \ + adv "$advitem" \ + finish "finish and create config file" + [ $? = 0 ] || return 1 + result="$REPLY" + + case "$result" in + "src") do_dup_src;; + "dest") do_dup_dest;; + "gpg") do_dup_gpg;; + # TODO: enable the following when do_dup_conn is written + # "conn") do_dup_conn;; + "adv") do_dup_adv;; + "finish") + if [[ "$_dest_done$_gpg_done$_src_done" != "(DONE)(DONE)(DONE)" ]]; then + # TODO: replace the previous test by the following when do_dup_conn is written + # if [[ "$_con_done$_dest_done$_gpg_done$_src_done" != "(DONE)(DONE)(DONE)(DONE)" ]]; then + msgBox "$dup_title" "You cannot create the configuration file until the four first steps are completed." + else + do_dup_finish + break + fi + ;; + esac + + done +} + +### Main function + +dup_wizard() { + + require_packages duplicity + + # Global variables + dup_title="Duplicity action wizard" + _src_done= + _dest_done= + _con_done= + _gpg_done= + _adv_done= + dup_includes= + dup_excludes= + dup_vsincludes= + dup_incremental=yes + dup_keep=60 + dup_bandwidth= + dup_sshoptions= + dup_destdir="/backups/`hostname`" + dup_desthost= + dup_destuser= + dup_gpg_asymmetric_encryption="yes" + dup_gpg_encryptkey="" + dup_gpg_sign="yes" + dup_gpg_onekeypair="yes" + dup_gpg_signkey="" + dup_gpg_password="" + dup_nicelevel=19 + dup_testconnect=yes + dup_options= + + # Global variables whose '*' shall not be expanded + set -o noglob + dup_default_includes="/var/spool/cron/crontabs /var/backups /etc /root /home /usr/local/*bin /var/lib/dpkg/status*" + dup_default_excludes="/home/*/.gnupg /home/*/.gnupg /home/*/.local/share/Trash /home/*/.Trash /home/*/.thumbnails /home/*/.beagle /home/*/.aMule /home/*/gtk-gnutella-downloads" + set +o noglob + + dup_main_menu +} diff --git a/handlers/dup.in b/handlers/dup.in new file mode 100644 index 0000000..edb43ac --- /dev/null +++ b/handlers/dup.in @@ -0,0 +1,178 @@ +# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- +# +# duplicity script for backupninja +# requires duplicity +# + +getconf options +getconf testconnect yes +getconf nicelevel 0 + +setsection gpg +getconf password +getconf sign no +getconf encryptkey +getconf signkey + +setsection source +getconf include +getconf vsnames all +getconf vsinclude +getconf exclude + +setsection dest +getconf incremental yes +getconf keep 60 +getconf sshoptions +getconf bandwidthlimit 0 +getconf desthost +getconf destdir +getconf destuser +destdir=${destdir%/} + +[ "$destdir" != "" ] || fatal "Destination directory not set" +[ "$include" != "" ] || fatal "No source includes specified" + +### vservers stuff ### + +# If vservers are configured, check that the ones listed in $vsnames do exist. +local usevserver=no +if [ $vservers_are_available = yes ]; then + if [ "$vsnames" = all ]; then + vsnames="$found_vservers" + else + if ! vservers_exist "$vsnames" ; then + fatal "At least one of the vservers listed in vsnames ($vsnames) does not exist." + fi + fi + if [ -n "$vsinclude" ]; then + info "Using vservers '$vsnames'" + usevserver=yes + fi +else + [ -z "$vsinclude" ] || warning 'vservers support disabled in backupninja.conf, vsincludes configuration lines will be ignored' +fi + + +### see if we can login ### + +if [ "$testconnect" == "yes" ]; then + debug "ssh $sshoptions -o PasswordAuthentication=no $desthost -l $destuser 'echo -n 1'" + if [ ! $test ]; then + result=`ssh $sshoptions -o PasswordAuthentication=no $desthost -l $destuser 'echo -n 1'` + if [ "$result" != "1" ]; then + fatal "Can't connect to $desthost as $destuser." + else + debug "Connected to $desthost as $destuser successfully" + fi + fi +fi + +### COMMAND-LINE MANGLING ### + +# duplicity >= 0.4.2 needs --sftp-command (NB: sftp does not support the -l option) +duplicity_version="`duplicity --version | @AWK@ '{print $2}'`" +duplicity_major="`echo $duplicity_version | @AWK@ -F '.' '{print $1}'`" +duplicity_minor="`echo $duplicity_version | @AWK@ -F '.' '{print $2}'`" +duplicity_sub="`echo $duplicity_version | @AWK@ -F '.' '{print $3}'`" +if [ "$duplicity_major" -ge 0 -a "$duplicity_minor" -ge 4 -a "$duplicity_sub" -ge 2 ]; then + sftpoptions="$sshoptions" +fi + +scpoptions="$sshoptions" +[ "$bandwidthlimit" == 0 ] || scpoptions="$scpoptions -l $bandwidthlimit" + +if [ -z "$sftpoptions" ]; then + execstr="$options --no-print-statistics --scp-command 'scp $scpoptions' --ssh-command 'ssh $sshoptions' " +else + execstr="$options --no-print-statistics --scp-command 'scp $scpoptions' --sftp-command 'sftp $sftpoptions' --ssh-command 'ssh $sshoptions' " +fi + +# deal with symmetric or asymmetric (public/private key pair) encryption +if [ -n "$encryptkey" ]; then + execstr="${execstr}--encrypt-key $encryptkey " + debug "Data will be encrypted with the GnuPG key $encryptkey." +else + debug "Data will be encrypted using symmetric encryption." +fi + +# deal with data signing +if [ "$sign" == yes ]; then + # duplicity is not able to sign data when using symmetric encryption + [ -n "$encryptkey" ] || fatal "The encryptkey option must be set when signing." + # if needed, initialize signkey to a value that is not empty (checked above) + [ -n "$signkey" ] || signkey="$encryptkey" + execstr="${execstr}--sign-key $signkey " + debug "Data will be signed will the GnuPG key $signkey." +else + debug "Data won't be signed." +fi + +# deal with GnuPG passphrase +[ -n "$password" ] || fatal "The password option must be set." + +if [ "$keep" != "yes" ]; then + if [ "`echo $keep | tr -d 0-9`" == "" ]; then + keep="${keep}D" + fi + execstr="${execstr}--remove-older-than $keep " +fi + +if [ "$incremental" == "no" ]; then + execstr="${execstr}--full " +fi + +execstr_serverpart="scp://$destuser@$desthost/$destdir" +execstr_clientpart="/" + +### SOURCE ### + +set -o noglob + +# excludes +for i in $exclude; do + str="${i//__star__/*}" + execstr="${execstr}--exclude '$str' " +done + +# includes +for i in $include; do + [ "$i" != "/" ] || fatal "Sorry, you cannot use 'include = /'" + str="${i//__star__/*}" + execstr="${execstr}--include '$str' " +done + +# vsincludes +if [ $usevserver = yes ]; then + for vserver in $vsnames; do + for vi in $vsinclude; do + str="${vi//__star__/*}" + str="$VROOTDIR/$vserver$str" + execstr="${execstr}--include '$str' " + done + done +fi + +set +o noglob + +### EXECUTE ### + +execstr=${execstr//\\*/\\\\\\*} + +debug "duplicity $execstr --exclude '**' / $execstr_serverpart" +if [ ! $test ]; then + export PASSPHRASE=$password + output=`nice -n $nicelevel \ + su -c \ + "duplicity $execstr --exclude '**' / $execstr_serverpart 2>&1"` + code=$? + if [ $code -eq 0 ]; then + debug $output + info "Duplicity finished successfully." + else + debug $output + fatal "Duplicity failed." + fi +fi + +return 0 diff --git a/handlers/ldap b/handlers/ldap deleted file mode 100644 index 5f9040a..0000000 --- a/handlers/ldap +++ /dev/null @@ -1,105 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- -# -# 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 restart no -getconf method ldapsearch -getconf passwordfile -getconf binddn -getconf ldaphost -getconf tls yes - -if [ $tls = 'yes' ]; then - URLBASE="ldaps" -else - URLBASE="ldap" -fi - -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 - - if [ "$method" == "slapcat" ]; then - execstr="$SLAPCAT -f $conf -b $dbsuffix" - debug "$execstr" - else - if [ -n "$ldaphost" ]; then - execstr="$LDAPSEARCH -H $URLBASE://$ldaphost -x -L -b ""$dbsuffix"" -D ""$binddn"" -y $passwordfile" - else - execstr="$LDAPSEARCH -x -L -b ""$dbsuffix"" -D ""$binddn"" -y $passwordfile" - fi - [ -f "$passwordfile" ] || fatal "Password file $passwordfile not found. When method is set to ldapsearch, you must also specify a password file." - debug "$execstr" - fi - if [ ! $test ]; then - if [ "$restart" == "yes" ]; then - debug "Shutting down ldap server..." - /etc/init.d/slapd stop - fi - - ext= - if [ "$compress" == "yes" ]; then - ext=".gz" - fi - touch $dumpdir/$dbsuffix.ldif$ext - if [ ! -f $dumpdir/$dbsuffix.ldif$ext ]; then - fatal "Couldn't create ldif dump file: $dumpdir/$dbsuffix.ldif$ext" - fi - - if [ "$compress" == "yes" ]; then - output=`$execstr | $GZIP > $dumpdir/$dbsuffix.ldif.gz` - else - output=`$execstr > $dumpdir/$dbsuffix.ldif` - fi - code=$? - if [ "$code" == "0" ]; then - debug $output - info "Successfully finished ldif export of $dbsuffix" - else - warning $output - warning "Failed ldif export of $dbsuffix" - fi - - if [ "$restart" == "yes" ]; then - debug "Starting ldap server..." - /etc/init.d/slapd start - fi - fi - done -fi - -return 0 diff --git a/handlers/ldap.helper b/handlers/ldap.helper deleted file mode 100644 index 697c720..0000000 --- a/handlers/ldap.helper +++ /dev/null @@ -1,78 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- - -HELPERS="$HELPERS ldap:ldap_database_backup" - -ldap_create_file() { -while true; do - checkBox "ldap action wizard" "check options (slapcat OR ldapsearch)" \ - "slapcat" "export ldif using slapcat" on \ - "ldapsearch" "export ldif using ldapsearch" off \ - "compress" "compress the ldif output files" on - status=$? - compress="compress = off" - method="method = " - restart="restart = no" - binddn="" - passwordfile="" - [ $status = 1 ] && return; - result="$REPLY" - for opt in $result; do - case $opt in - '"compress"') compress="compress = on";; - '"slapcat"') - method="method = slapcat" - [ "$_RESTART" == "yes" ] && restart="restart = yes" - ;; - '"ldapsearch"') - method="method = ldapsearch" - inputBox "ldap action wizard" "ldapsearch requires authentication. Specify here what password file to use. It must have the password with no trailing return and it should not be world readable." - [ $? = 1 ] && return - passwordfile="passwordfile = $REPLY" - inputBox "ldap action wizard" "ldapsearch requires authentication. Specify here what DN to bind as:" - [ $? = 1 ] && return - binddn="binddn = $REPLY" - require_packages ldap-utils - ;; - esac - done - get_next_filename $configdirectory/30.ldap - cat > $next_filename < $next_filename < $dumpdir/$dbsuffix.ldif.gz` + else + output=`$execstr > $dumpdir/$dbsuffix.ldif` + fi + code=$? + if [ "$code" == "0" ]; then + debug $output + info "Successfully finished ldif export of $dbsuffix" + else + warning $output + warning "Failed ldif export of $dbsuffix" + fi + + if [ "$restart" == "yes" ]; then + debug "Starting ldap server..." + /etc/init.d/slapd start + fi + fi + done +fi + +return 0 diff --git a/handlers/maildir b/handlers/maildir deleted file mode 100644 index 4b98deb..0000000 --- a/handlers/maildir +++ /dev/null @@ -1,348 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- - -############################################################### -# -# This handler slowly creates a backup of each user's maildir -# to a remote server. It is designed to be run with low overhead -# in terms of cpu and bandwidth so it runs pretty slow. -# Hardlinking is used to save storage space. -# -# each users maildir will contain these files: -# daily.1 -# daily.2 -# daily.3 -# weekly.1 -# weekly.2 -# monthly.1 -# if keepdaily is 3, keepweekly is 2, and keepmonthly is 1. -# the actual maildir is stored within each snapshot directory. -# -# The basic algorithm is to rsync each maildir individually, -# and to use hard links for retaining historical data. -# -# We handle each maildir individually because it becomes very -# unweldy to hardlink and rsync many hundreds of thousands -# of files at once. It is much faster to take on smaller -# chunks at a time. -# -# For the backup rotation to work, destuser must be able to run -# arbitrary bash commands on the desthost. -# -# Any maildir which is deleted from the source will be moved to -# "deleted" directory in the destination. It is up to you to -# periodically remove this directory or old maildirs in it. -# -############################################################## - -getconf rotate yes -getconf remove yes -getconf backup yes - -getconf loadlimit 5 -getconf speedlimit 0 -getconf keepdaily 5 -getconf keepweekly 3 -getconf keepmonthly 1 - -getconf srcdir /var/maildir -getconf destdir -getconf desthost -getconf destport 22 -getconf destuser - -getconf multiconnection notset - -letters="a b c d e f g h i j k l m n o p q r s t u v w x y z" -failedcount=0 -# strip trailing / -destdir=${destdir%/} -srcdir=${srcdir%/} - -# used for testing -#getconf testuser elijah - -[ -d $srcdir ] || fatal "source directory $srcdir doesn't exist" - -[ "$multiconnection" == "notset" ] && fatal "The maildir handler uses a very different destination format. See the example .maildir for more information" - -[ ! $test ] || testflags="--dry-run -v" -rsyncflags="$testflags -e 'ssh -p $destport' -r -v --ignore-existing --delete --size-only --bwlimit=$speedlimit" -excludes="--exclude '.Trash/\*' --exclude '.Mistakes/\*' --exclude '.Spam/\*'" - -################################################################## -### FUNCTIONS - -function do_user() { - local user=$1 - local btype=$2 - local letter=${user:0:1} - local source="$srcdir/$letter/$user/" - local target="$destdir/$letter/$user/$btype.1" - if [ ! -d $source ]; then - warning "maildir $source not found" - return - fi - - debug "syncing" - ret=`$RSYNC -e "ssh -p $destport" -r \ - --links --ignore-existing --delete --size-only --bwlimit=$speedlimit \ - --exclude '.Trash/*' --exclude '.Mistakes/*' --exclude '.Spam/*' \ - $source $destuser@$desthost:$target \ - 2>&1` - ret=$? - # ignore 0 (success) and 24 (file vanished before it could be copied) - if [ $ret != 0 -a $ret != 24 ]; then - warning "rsync $user failed" - warning " returned: $ret" - let "failedcount = failedcount + 1" - if [ $failedcount -gt 100 ]; then - fatal "100 rsync errors -- something is not working right. bailing out." - fi - fi - ssh -o PasswordAuthentication=no $desthost -l $destuser "date +%c%n%s > $target/created" -} - -# remove any maildirs from backup which might have been deleted -# and add new ones which have just been created. -# (actually, it just moved them to the directory "deleted") - -function do_remove() { - local tmp1=`maketemp maildir-tmp-file` - local tmp2=`maketemp maildir-tmp-file` - - ssh -p $destport $destuser@$desthost mkdir -p "$destdir/deleted" - for i in a b c d e f g h i j k l m n o p q r s t u v w x y z; do - ls -1 "$srcdir/$i/" | sort > $tmp1 - ssh -p $destport $destuser@$desthost ls -1 "$destdir/$i/" | sort > $tmp2 - for deluser in `join -v 2 $tmp1 $tmp2`; do - [ "$deluser" != "" ] || continue - info "removing $destuser@$desthost:$destdir/$i/$deluser/" - ssh -p $destport $destuser@$desthost mv "$destdir/$i/$deluser/" "$destdir/deleted" - done - done - rm $tmp1 - rm $tmp2 -} - -function do_rotate() { - [ "$rotate" == "yes" ] || return; - local user=$1 - local letter=${user:0:1} - local backuproot="$destdir/$letter/$user" -( - ssh -T -o PasswordAuthentication=no $desthost -l $destuser < 0; i-- )); do - if [ -d \$dir.\$i ]; then - if [ -f \$dir.\$i/created ]; then - created=\`tail -1 \$dir.\$i/created\` - else - created=0 - fi - cutoff_time=\$(( now - (seconds*(i-1)) )) - if [ ! \$created -gt \$cutoff_time ]; then - next=\$(( i + 1 )) - if [ ! -d \$dir.\$next ]; then - echo "Debug: \$rottype.\$i --> \$rottype.\$next" - mv \$dir.\$i \$dir.\$next - date +%c%n%s > \$dir.\$next/rotated - else - echo "Debug: skipping rotation of \$dir.\$i because \$dir.\$next already exists." - fi - else - echo "Debug: skipping rotation of \$dir.\$i because it was created" \$(( (now-created)/86400)) "days ago ("\$(( (now-cutoff_time)/86400))" needed)." - fi - fi - done - done - - max=\$((keepdaily+1)) - if [ \( \$keepweekly -gt 0 -a -d $backuproot/daily.\$max \) -a ! -d $backuproot/weekly.1 ]; then - echo "Debug: daily.\$max --> weekly.1" - mv $backuproot/daily.\$max $backuproot/weekly.1 - date +%c%n%s > $backuproot/weekly.1/rotated - fi - - max=\$((keepweekly+1)) - if [ \( \$keepmonthly -gt 0 -a -d $backuproot/weekly.\$max \) -a ! -d $backuproot/monthly.1 ]; then - echo "Debug: weekly.\$max --> monthly.1" - mv $backuproot/weekly.\$max $backuproot/monthly.1 - date +%c%n%s > $backuproot/monthly.1/rotated - fi - - for rottype in daily weekly monthly; do - max=\$((keep\${rottype}+1)) - dir="$backuproot/\$rottype" - oldest=\`find $backuproot -type d -maxdepth 1 -name \$rottype'.*' | @SED@ 's/^.*\.//' | sort -n | tail -1\` - [ "\$oldest" == "" ] && oldest=0 - # if we've rotated the last backup off the stack, remove it. - for (( i=\$oldest; i >= \$max; i-- )); do - if [ -d \$dir.\$i ]; then - if [ -d $backuproot/rotate.tmp ]; then - echo "Debug: removing rotate.tmp" - rm -rf $backuproot/rotate.tmp - fi - echo "Debug: moving \$rottype.\$i to rotate.tmp" - mv \$dir.\$i $backuproot/rotate.tmp - fi - done - done -####### END REMOTE SCRIPT ####### -EOF -) | (while read a; do passthru $a; done) - -} - - -function setup_remote_dirs() { - local user=$1 - local backuptype=$2 - local letter=${user:0:1} - local dir="$destdir/$letter/$user/$backuptype" - local tmpdir="$destdir/$letter/$user/rotate.tmp" -( - ssh -T -o PasswordAuthentication=no $desthost -l $destuser < $backuptype.1" - cp -alf $dir.2/. $dir.1 - #if [ \$? == 1 ]; then - # echo "Fatal: could not create hard links to $dir.1 on host $desthost" - # exit 1 - #fi - fi - fi - [ -f $dir.1/created ] && rm $dir.1/created - [ -f $dir.1/rotated ] && rm $dir.1/rotated - exit 0 -EOF -) | (while read a; do passthru $a; done) - - if [ $? == 1 ]; then exit; fi -} - -function start_mux() { - if [ "$multiconnection" == "yes" ]; then - debug "Starting dummy ssh connection" - ssh -p $destport $destuser@$desthost sleep 1d & - sleep 1 - fi -} - -function end_mux() { - if [ "$multiconnection" == "yes" ]; then - debug "Stopping dummy ssh connection" - ssh -p $destport $destuser@$desthost pkill sleep - fi -} - -### -################################################################## - -# see if we can login -debug "ssh -o PasswordAuthentication=no $desthost -l $destuser 'echo -n 1'" -if [ ! $test ]; then - result=`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 - -end_mux -start_mux - -## SANITY CHECKS ## -status=`ssh -p $destport $destuser@$desthost "[ -d \"$destdir\" ] && echo 'ok'"` -if [ "$status" != "ok" ]; then - end_mux - fatal "Destination directory $destdir doesn't exist!" - exit -fi - -### REMOVE OLD MAILDIRS ### - -if [ "$remove" == "yes" ]; then - do_remove -fi - -### MAKE BACKUPS ### - -if [ "$backup" == "yes" ]; then - if [ $keepdaily -gt 0 ]; then btype=daily - elif [ $keepweekly -gt 0 ]; then btype=weekly - elif [ $keepmonthly -gt 0 ]; then btype=monthly - else fatal "keeping no backups"; fi - - if [ "$testuser" != "" ]; then - cd "$srcdir/${user:0:1}" - do_rotate $testuser - setup_remote_dirs $testuser $btype - do_user $testuser $btype - else - for i in $letters; do - [ -d "$srcdir/$i" ] || fatal "directory $srcdir/$i not found." - cd "$srcdir/$i" - debug $i - for user in `ls -1`; do - [ "$user" != "" ] || continue - debug $user - do_rotate $user - setup_remote_dirs $user $btype - do_user $user $btype - done - done - fi -fi - -end_mux - diff --git a/handlers/maildir.in b/handlers/maildir.in new file mode 100644 index 0000000..4b98deb --- /dev/null +++ b/handlers/maildir.in @@ -0,0 +1,348 @@ +# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- + +############################################################### +# +# This handler slowly creates a backup of each user's maildir +# to a remote server. It is designed to be run with low overhead +# in terms of cpu and bandwidth so it runs pretty slow. +# Hardlinking is used to save storage space. +# +# each users maildir will contain these files: +# daily.1 +# daily.2 +# daily.3 +# weekly.1 +# weekly.2 +# monthly.1 +# if keepdaily is 3, keepweekly is 2, and keepmonthly is 1. +# the actual maildir is stored within each snapshot directory. +# +# The basic algorithm is to rsync each maildir individually, +# and to use hard links for retaining historical data. +# +# We handle each maildir individually because it becomes very +# unweldy to hardlink and rsync many hundreds of thousands +# of files at once. It is much faster to take on smaller +# chunks at a time. +# +# For the backup rotation to work, destuser must be able to run +# arbitrary bash commands on the desthost. +# +# Any maildir which is deleted from the source will be moved to +# "deleted" directory in the destination. It is up to you to +# periodically remove this directory or old maildirs in it. +# +############################################################## + +getconf rotate yes +getconf remove yes +getconf backup yes + +getconf loadlimit 5 +getconf speedlimit 0 +getconf keepdaily 5 +getconf keepweekly 3 +getconf keepmonthly 1 + +getconf srcdir /var/maildir +getconf destdir +getconf desthost +getconf destport 22 +getconf destuser + +getconf multiconnection notset + +letters="a b c d e f g h i j k l m n o p q r s t u v w x y z" +failedcount=0 +# strip trailing / +destdir=${destdir%/} +srcdir=${srcdir%/} + +# used for testing +#getconf testuser elijah + +[ -d $srcdir ] || fatal "source directory $srcdir doesn't exist" + +[ "$multiconnection" == "notset" ] && fatal "The maildir handler uses a very different destination format. See the example .maildir for more information" + +[ ! $test ] || testflags="--dry-run -v" +rsyncflags="$testflags -e 'ssh -p $destport' -r -v --ignore-existing --delete --size-only --bwlimit=$speedlimit" +excludes="--exclude '.Trash/\*' --exclude '.Mistakes/\*' --exclude '.Spam/\*'" + +################################################################## +### FUNCTIONS + +function do_user() { + local user=$1 + local btype=$2 + local letter=${user:0:1} + local source="$srcdir/$letter/$user/" + local target="$destdir/$letter/$user/$btype.1" + if [ ! -d $source ]; then + warning "maildir $source not found" + return + fi + + debug "syncing" + ret=`$RSYNC -e "ssh -p $destport" -r \ + --links --ignore-existing --delete --size-only --bwlimit=$speedlimit \ + --exclude '.Trash/*' --exclude '.Mistakes/*' --exclude '.Spam/*' \ + $source $destuser@$desthost:$target \ + 2>&1` + ret=$? + # ignore 0 (success) and 24 (file vanished before it could be copied) + if [ $ret != 0 -a $ret != 24 ]; then + warning "rsync $user failed" + warning " returned: $ret" + let "failedcount = failedcount + 1" + if [ $failedcount -gt 100 ]; then + fatal "100 rsync errors -- something is not working right. bailing out." + fi + fi + ssh -o PasswordAuthentication=no $desthost -l $destuser "date +%c%n%s > $target/created" +} + +# remove any maildirs from backup which might have been deleted +# and add new ones which have just been created. +# (actually, it just moved them to the directory "deleted") + +function do_remove() { + local tmp1=`maketemp maildir-tmp-file` + local tmp2=`maketemp maildir-tmp-file` + + ssh -p $destport $destuser@$desthost mkdir -p "$destdir/deleted" + for i in a b c d e f g h i j k l m n o p q r s t u v w x y z; do + ls -1 "$srcdir/$i/" | sort > $tmp1 + ssh -p $destport $destuser@$desthost ls -1 "$destdir/$i/" | sort > $tmp2 + for deluser in `join -v 2 $tmp1 $tmp2`; do + [ "$deluser" != "" ] || continue + info "removing $destuser@$desthost:$destdir/$i/$deluser/" + ssh -p $destport $destuser@$desthost mv "$destdir/$i/$deluser/" "$destdir/deleted" + done + done + rm $tmp1 + rm $tmp2 +} + +function do_rotate() { + [ "$rotate" == "yes" ] || return; + local user=$1 + local letter=${user:0:1} + local backuproot="$destdir/$letter/$user" +( + ssh -T -o PasswordAuthentication=no $desthost -l $destuser < 0; i-- )); do + if [ -d \$dir.\$i ]; then + if [ -f \$dir.\$i/created ]; then + created=\`tail -1 \$dir.\$i/created\` + else + created=0 + fi + cutoff_time=\$(( now - (seconds*(i-1)) )) + if [ ! \$created -gt \$cutoff_time ]; then + next=\$(( i + 1 )) + if [ ! -d \$dir.\$next ]; then + echo "Debug: \$rottype.\$i --> \$rottype.\$next" + mv \$dir.\$i \$dir.\$next + date +%c%n%s > \$dir.\$next/rotated + else + echo "Debug: skipping rotation of \$dir.\$i because \$dir.\$next already exists." + fi + else + echo "Debug: skipping rotation of \$dir.\$i because it was created" \$(( (now-created)/86400)) "days ago ("\$(( (now-cutoff_time)/86400))" needed)." + fi + fi + done + done + + max=\$((keepdaily+1)) + if [ \( \$keepweekly -gt 0 -a -d $backuproot/daily.\$max \) -a ! -d $backuproot/weekly.1 ]; then + echo "Debug: daily.\$max --> weekly.1" + mv $backuproot/daily.\$max $backuproot/weekly.1 + date +%c%n%s > $backuproot/weekly.1/rotated + fi + + max=\$((keepweekly+1)) + if [ \( \$keepmonthly -gt 0 -a -d $backuproot/weekly.\$max \) -a ! -d $backuproot/monthly.1 ]; then + echo "Debug: weekly.\$max --> monthly.1" + mv $backuproot/weekly.\$max $backuproot/monthly.1 + date +%c%n%s > $backuproot/monthly.1/rotated + fi + + for rottype in daily weekly monthly; do + max=\$((keep\${rottype}+1)) + dir="$backuproot/\$rottype" + oldest=\`find $backuproot -type d -maxdepth 1 -name \$rottype'.*' | @SED@ 's/^.*\.//' | sort -n | tail -1\` + [ "\$oldest" == "" ] && oldest=0 + # if we've rotated the last backup off the stack, remove it. + for (( i=\$oldest; i >= \$max; i-- )); do + if [ -d \$dir.\$i ]; then + if [ -d $backuproot/rotate.tmp ]; then + echo "Debug: removing rotate.tmp" + rm -rf $backuproot/rotate.tmp + fi + echo "Debug: moving \$rottype.\$i to rotate.tmp" + mv \$dir.\$i $backuproot/rotate.tmp + fi + done + done +####### END REMOTE SCRIPT ####### +EOF +) | (while read a; do passthru $a; done) + +} + + +function setup_remote_dirs() { + local user=$1 + local backuptype=$2 + local letter=${user:0:1} + local dir="$destdir/$letter/$user/$backuptype" + local tmpdir="$destdir/$letter/$user/rotate.tmp" +( + ssh -T -o PasswordAuthentication=no $desthost -l $destuser < $backuptype.1" + cp -alf $dir.2/. $dir.1 + #if [ \$? == 1 ]; then + # echo "Fatal: could not create hard links to $dir.1 on host $desthost" + # exit 1 + #fi + fi + fi + [ -f $dir.1/created ] && rm $dir.1/created + [ -f $dir.1/rotated ] && rm $dir.1/rotated + exit 0 +EOF +) | (while read a; do passthru $a; done) + + if [ $? == 1 ]; then exit; fi +} + +function start_mux() { + if [ "$multiconnection" == "yes" ]; then + debug "Starting dummy ssh connection" + ssh -p $destport $destuser@$desthost sleep 1d & + sleep 1 + fi +} + +function end_mux() { + if [ "$multiconnection" == "yes" ]; then + debug "Stopping dummy ssh connection" + ssh -p $destport $destuser@$desthost pkill sleep + fi +} + +### +################################################################## + +# see if we can login +debug "ssh -o PasswordAuthentication=no $desthost -l $destuser 'echo -n 1'" +if [ ! $test ]; then + result=`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 + +end_mux +start_mux + +## SANITY CHECKS ## +status=`ssh -p $destport $destuser@$desthost "[ -d \"$destdir\" ] && echo 'ok'"` +if [ "$status" != "ok" ]; then + end_mux + fatal "Destination directory $destdir doesn't exist!" + exit +fi + +### REMOVE OLD MAILDIRS ### + +if [ "$remove" == "yes" ]; then + do_remove +fi + +### MAKE BACKUPS ### + +if [ "$backup" == "yes" ]; then + if [ $keepdaily -gt 0 ]; then btype=daily + elif [ $keepweekly -gt 0 ]; then btype=weekly + elif [ $keepmonthly -gt 0 ]; then btype=monthly + else fatal "keeping no backups"; fi + + if [ "$testuser" != "" ]; then + cd "$srcdir/${user:0:1}" + do_rotate $testuser + setup_remote_dirs $testuser $btype + do_user $testuser $btype + else + for i in $letters; do + [ -d "$srcdir/$i" ] || fatal "directory $srcdir/$i not found." + cd "$srcdir/$i" + debug $i + for user in `ls -1`; do + [ "$user" != "" ] || continue + debug $user + do_rotate $user + setup_remote_dirs $user $btype + do_user $user $btype + done + done + fi +fi + +end_mux + diff --git a/handlers/makecd b/handlers/makecd deleted file mode 100644 index cdfa6b1..0000000 --- a/handlers/makecd +++ /dev/null @@ -1,88 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- -# -# burncd handler script for backupninja -# -getconf backupdir /var/backups/makecd -getconf exclude -getconf target -getconf burnertype cd -getconf system no -getconf isoonly yes -getconf imagefile backup.iso -getconf device -getconf nicelevel 0 - -# define needed executables: -MKISOFS="/usr/bin/mkisofs" -GROWISOFS="/usr/bin/growisofs" -#CDRECORD="/usr/bin/cdrecord" -CDRECORD="/usr/bin/cdrecord.mmap" -CDRDAO="/usr/bin/cdrdao" -DVDINFO="/usr/bin/dvd+rw-mediainfo" - -# create backup dirs and check existence of progs. - -[ -d $backupdir ] || mkdir -p $backupdir -[ -d $backupdir ] || fatal "Backup directory '$backupdir'" -[ -e "$target" ] || fatal "target does not exist " - -[ -x "$MKISOFS" ] || debug 3 "echo executable mkisofs not present" -[ -x "$GROWISOFS" ] || debug 3 "echo executable growisofs not present" -[ -x "$CDRECORD" ] || debug 3 "echo executable cdrecord not present" -[ -x "$CDRDAO" ] || debug 3 "echo executable cdrdao not present" - -if [ "$isoonly" == "no" ]; then - [ -e $device ] || fatal "No Burner device available" -fi - -outputfile="$backupdir/$imagefile" -execstr="nice -n $nicelevel $MKISOFS --quiet -R -o $outputfile " - -str="" -# excludes -for i in $exclude; do - str=" -x ${i}$str" -done - -debug 0 "echo $str " -execstr="${execstr} $str $target " -debug 0 "echo $execstr " - -output=` $execstr 2>&1 ` -code=$? -if [ "$code" == "0" ]; then - debug $output - info "Successfully finished creation of iso" -else - warning $output - warning "Failed to create iso" -fi - -if [ "$isoonly" == "no" ]; then - - if [ "$burnertype" == "cd" ]; then - # burning iso to CD - $CDRECORD -v gracetime=2 dev=$device speed=8 -dao -data $outputfile - code=$? - if [ "$code" == "0" ]; then - debug $output - info "Successfully burned CD" - else - warning $output - warning "Failed to create CD" - fi - fi - if [ "$burnertype" == "dvd" ]; then - # burning iso dvd - $GROWISOFS -speed=2 -Z $device=$outputfile -use-the-force-luke=notray -use-the-force-luke=tty - code=$? - if [ "$code" == "0" ]; then - debug $output - info "Successfully burned DVD" - else - warning $output - warning "Failed to create DVD" - fi - fi -fi -return 0 diff --git a/handlers/makecd.helper b/handlers/makecd.helper deleted file mode 100644 index f83b541..0000000 --- a/handlers/makecd.helper +++ /dev/null @@ -1,97 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- - -HELPERS="$HELPERS makecd:makecd_backup" -wizardname="makecd action wizard" - -declare -a makecd_excludes - -makecd_wizard() { - - inputBox "$wizardname" "specify a burner type cd or dvd:" - [ $? = 1 ] && return - burnertype="burnertype = $REPLY" - - booleanBox "$wizardname" "Make iso image only? or burn" - if [ $? = 0 ]; then - isoonly="isoonly = yes" - else - isoonly="isoonly = no" - fi - - # backupdir - inputBox "$wizardname" "Directory where to store the backups:" - [ $? = 1 ] && return - backupdir="backupdir = $REPLY" - - inputBox "$wizardname" "what name to give to the image file?" - [ $? = 1 ] && return - imagefile="imagefile = $REPLY" - - inputBox "$wizardname" "specify a burner device:" - [ $? = 1 ] && return - device="device = $REPLY" - - # target - root of system to be included - inputBox "$wizardname" "root of filesystem for burn:" - [ $? = 1 ] && return - target="target = $REPLY" - - - # excludes - - formBegin "$wizardname: excludes" - for ((i=0; i < ${#makecd_excludes[@]} ; i++)); do - formItem exclude ${makecd_excludes[$i]} - done - formItem exclude - formItem exclude - formItem exclude - formItem exclude - formItem exclude - formItem exclude - formItem exclude - formItem exclude - formItem exclude - formDisplay - [ $? = 1 ] && return; - - unset makecd_excludes - makecd_excludes=($REPLY) - - get_next_filename $configdirectory/20.makecd - cat >> $next_filename <> $next_filename - done - - chmod 600 $next_filename -} - diff --git a/handlers/makecd.helper.in b/handlers/makecd.helper.in new file mode 100644 index 0000000..f83b541 --- /dev/null +++ b/handlers/makecd.helper.in @@ -0,0 +1,97 @@ +# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- + +HELPERS="$HELPERS makecd:makecd_backup" +wizardname="makecd action wizard" + +declare -a makecd_excludes + +makecd_wizard() { + + inputBox "$wizardname" "specify a burner type cd or dvd:" + [ $? = 1 ] && return + burnertype="burnertype = $REPLY" + + booleanBox "$wizardname" "Make iso image only? or burn" + if [ $? = 0 ]; then + isoonly="isoonly = yes" + else + isoonly="isoonly = no" + fi + + # backupdir + inputBox "$wizardname" "Directory where to store the backups:" + [ $? = 1 ] && return + backupdir="backupdir = $REPLY" + + inputBox "$wizardname" "what name to give to the image file?" + [ $? = 1 ] && return + imagefile="imagefile = $REPLY" + + inputBox "$wizardname" "specify a burner device:" + [ $? = 1 ] && return + device="device = $REPLY" + + # target - root of system to be included + inputBox "$wizardname" "root of filesystem for burn:" + [ $? = 1 ] && return + target="target = $REPLY" + + + # excludes + + formBegin "$wizardname: excludes" + for ((i=0; i < ${#makecd_excludes[@]} ; i++)); do + formItem exclude ${makecd_excludes[$i]} + done + formItem exclude + formItem exclude + formItem exclude + formItem exclude + formItem exclude + formItem exclude + formItem exclude + formItem exclude + formItem exclude + formDisplay + [ $? = 1 ] && return; + + unset makecd_excludes + makecd_excludes=($REPLY) + + get_next_filename $configdirectory/20.makecd + cat >> $next_filename <> $next_filename + done + + chmod 600 $next_filename +} + diff --git a/handlers/makecd.in b/handlers/makecd.in new file mode 100644 index 0000000..cdfa6b1 --- /dev/null +++ b/handlers/makecd.in @@ -0,0 +1,88 @@ +# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- +# +# burncd handler script for backupninja +# +getconf backupdir /var/backups/makecd +getconf exclude +getconf target +getconf burnertype cd +getconf system no +getconf isoonly yes +getconf imagefile backup.iso +getconf device +getconf nicelevel 0 + +# define needed executables: +MKISOFS="/usr/bin/mkisofs" +GROWISOFS="/usr/bin/growisofs" +#CDRECORD="/usr/bin/cdrecord" +CDRECORD="/usr/bin/cdrecord.mmap" +CDRDAO="/usr/bin/cdrdao" +DVDINFO="/usr/bin/dvd+rw-mediainfo" + +# create backup dirs and check existence of progs. + +[ -d $backupdir ] || mkdir -p $backupdir +[ -d $backupdir ] || fatal "Backup directory '$backupdir'" +[ -e "$target" ] || fatal "target does not exist " + +[ -x "$MKISOFS" ] || debug 3 "echo executable mkisofs not present" +[ -x "$GROWISOFS" ] || debug 3 "echo executable growisofs not present" +[ -x "$CDRECORD" ] || debug 3 "echo executable cdrecord not present" +[ -x "$CDRDAO" ] || debug 3 "echo executable cdrdao not present" + +if [ "$isoonly" == "no" ]; then + [ -e $device ] || fatal "No Burner device available" +fi + +outputfile="$backupdir/$imagefile" +execstr="nice -n $nicelevel $MKISOFS --quiet -R -o $outputfile " + +str="" +# excludes +for i in $exclude; do + str=" -x ${i}$str" +done + +debug 0 "echo $str " +execstr="${execstr} $str $target " +debug 0 "echo $execstr " + +output=` $execstr 2>&1 ` +code=$? +if [ "$code" == "0" ]; then + debug $output + info "Successfully finished creation of iso" +else + warning $output + warning "Failed to create iso" +fi + +if [ "$isoonly" == "no" ]; then + + if [ "$burnertype" == "cd" ]; then + # burning iso to CD + $CDRECORD -v gracetime=2 dev=$device speed=8 -dao -data $outputfile + code=$? + if [ "$code" == "0" ]; then + debug $output + info "Successfully burned CD" + else + warning $output + warning "Failed to create CD" + fi + fi + if [ "$burnertype" == "dvd" ]; then + # burning iso dvd + $GROWISOFS -speed=2 -Z $device=$outputfile -use-the-force-luke=notray -use-the-force-luke=tty + code=$? + if [ "$code" == "0" ]; then + debug $output + info "Successfully burned DVD" + else + warning $output + warning "Failed to create DVD" + fi + fi +fi +return 0 diff --git a/handlers/mysql b/handlers/mysql deleted file mode 100644 index de4e4c3..0000000 --- a/handlers/mysql +++ /dev/null @@ -1,304 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- -# -# mysql handler script for backupninja -# - -getconf backupdir /var/backups/mysql -getconf databases all -getconf ignores -getconf dbhost localhost -getconf hotcopy no -getconf sqldump no -getconf compress yes -getconf vsname - -# authentication: -getconf user -getconf dbusername -getconf dbpassword -getconf configfile /etc/mysql/debian.cnf - - -# Decide if the handler should operate on a vserver or on the host. -# In the former case, check that $vsname exists and is running. -local usevserver=no -local vroot -if [ $vservers_are_available = yes ]; then - if [ -n "$vsname" ]; then - # does it exist ? - if ! vservers_exist "$vsname" ; then - fatal "The vserver given in vsname ($vsname) does not exist." - fi - # is it running ? - $VSERVERINFO -q $vsname RUNNING - if [ $? -ne 0 ]; then - fatal "The vserver $vsname is not running." - fi - # everything ok - info "Using vserver '$vsname'." - usevserver=yes - vroot="$VROOTDIR/$vsname" - else - info "No vserver name specified, actions will be performed on the host." - fi -fi - -## Prepare ignore part of the command -## This only works for mysqldump at the moment - -ignore='' -for i in $ignores; do - ignore="$ignore --ignore-table=$i" -done - -# create backup dirs, $vroot will be empty if no vsname was specified -# and we will instead proceed to operate on the host -[ -d $vroot$backupdir ] || mkdir -p $vroot$backupdir -[ -d $vroot$backupdir ] || fatal "Backup directory '$vroot$backupdir'" -hotdir="$backupdir/hotcopy" -dumpdir="$backupdir/sqldump" - -if [ $usevserver = yes ] -then - [ "$sqldump" == "no" -o -d $vroot$dumpdir ] || $VSERVER $vsname exec mkdir -p $dumpdir - [ "$hotcopy" == "no" -o -d $vroot$hotdir ] || $VSERVER $vsname exec mkdir -p $hotdir -else - [ "$sqldump" == "no" -o -d $dumpdir ] || mkdir -p $dumpdir - [ "$hotcopy" == "no" -o -d $hotdir ] || mkdir -p $hotdir -fi - -####################################################################### -## AUTHENTICATION - -# -# one of three authentication methods: -# 1. setting the user, so that /home/user/.my.cnf is used. -# 2. specifying the user and password in the handler config, -# which generates a temporary .my.cnf in /root/.my.cnf -# 3. specify the config file with --defaults-extra-file -# (this option DOESN'T WORK WITH MYSQLHOTCOPY) -# - -# create .my.cnf -# only if dbusername and dbpassword specified. -# we create a tmp file because we don't want to -# specify the password on the command line. - -defaultsfile="" - -if [ "$dbusername" != "" -a "$dbpassword" != "" ] -then - if [ $usevserver = yes ] - then - vhome=`$VSERVER $vsname exec getent passwd "root" | @AWK@ -F: '{print $6}'` - home="$vroot$vhome" - else - home=`getent passwd "root" | @AWK@ -F: '{print $6}'` - fi - - [ -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 "mv $mycnf $tmpcnf" - mv $mycnf $tmpcnf - fi - - oldmask=`umask` - umask 077 - cat > $mycnf <&1` - code=$? - if [ "$code" == "0" ] - then - debug $output - info "Successfully finished hotcopy of all mysql databases" - else - warning $output - warning "Failed to hotcopy all mysql databases" - fi - fi - else - for db in $databases - do - if [ $usevserver = yes ] - then - execstr="$VSERVER $vsname exec $MYSQLHOTCOPY --allowold $db $hotdir" - else - execstr="$MYSQLHOTCOPY --allowold $db $hotdir" - fi - debug 'su $user -c \"$execstr\"' - if [ ! $test ] - then - output=`su $user -c "$execstr" 2>&1` - code=$? - if [ "$code" == "0" ] - then - debug $output - info "Successfully finished hotcopy of mysql database $db" - else - warning $output - warning "Failed to hotcopy mysql database $db" - fi - fi - done - fi -fi - -########################################################################## -## SQL DUMP - -if [ "$sqldump" == "yes" ] -then - info "Initializing SQL dump method" - if [ "$databases" == "all" ] - then - if [ $usevserver = yes ] - then - debug 'echo show databases | $VSERVER $vsname exec su $user -c \"$MYSQL $defaultsfile\" | grep -v Database' - databases=`echo 'show databases' | $VSERVER $vsname exec su $user -c "$MYSQL $defaultsfile" | grep -v Database` - if [ $? -ne 0 ] - then - fatal "Authentication problem, maybe user/password is wrong or mysqld is not running?" - fi - else - databases=`echo 'show databases' | su $user -c "$MYSQL $defaultsfile" | grep -v Database` - if [ $? -ne 0 ] - then - fatal "Authentication problem, maybe user/password is wrong or mysqld is not running?" - fi - fi -fi - - for db in $databases - do - if [ $usevserver = yes ] - then - # Test to make sure mysqld is running, if it is not sqldump will not work - $VSERVER $vsname exec su $user -c "$MYSQLADMIN $defaultsfile ping" - if [ $? -ne 0 ]; then - fatal "Either you have an authentication problem, or mysqld doesn't appear to be running!" - fi - if [ "$compress" == "yes" ]; then - execstr="$VSERVER $vsname exec $MYSQLDUMP $defaultsfile --lock-tables --complete-insert --add-drop-table --quick --quote-names $ignore $db | $GZIP > $vroot$dumpdir/${db}.sql.gz" - else - execstr="$VSERVER $vsname exec $MYSQLDUMP $defaultsfile --lock-tables --complete-insert --add-drop-table --quick --quote-names $ignore $db -r $vroot$dumpdir/${db}.sql" - fi - else - # Test to make sure mysqld is running, if it is not sqldump will not work - su $user -c "$MYSQLADMIN $defaultsfile ping" - if [ $? -ne 0 ]; then - fatal "Either you have an authentication problem, or mysqld doesn't appear to be running!" - fi - if [ "$compress" == "yes" ]; then - execstr="$MYSQLDUMP $defaultsfile --lock-tables --complete-insert --add-drop-table --quick --quote-names $ignore $db | $GZIP > $dumpdir/${db}.sql.gz" - else - execstr="$MYSQLDUMP $defaultsfile --lock-tables --complete-insert --add-drop-table --quick --quote-names $ignore $db -r $dumpdir/${db}.sql" - fi - fi - debug "su $user -c \"$execstr\"" - if [ ! $test ] - then - output=`su $user -c "$execstr" 2>&1` - code=$? - if [ "$code" == "0" ] - then - debug $output - info "Successfully finished dump of mysql database $db" - else - warning $output - warning "Failed to dump mysql databases $db" - fi - fi - done -fi - -# clean up tmp config file -if [ "$dbusername" != "" -a "$dbpassword" != "" ] -then - ## clean up tmp config file - debug "rm $mycnf" - rm $mycnf - if [ -f "$tmpcnf" ] - then - debug "mv $tmpcnf $mycnf" - mv $tmpcnf $mycnf - fi -fi - -return 0 diff --git a/handlers/mysql.helper b/handlers/mysql.helper deleted file mode 100644 index 9622d41..0000000 --- a/handlers/mysql.helper +++ /dev/null @@ -1,212 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- - -HELPERS="$HELPERS mysql:mysql_database_backup" - -do_mysql_vserver() { - choose_one_vserver "$mysql_title" - [ $? = 0 ] || return 1 - mysql_vsname="vsname = $REPLY" -} - -do_mysql_databases() { - REPLY= - while [ -z "$REPLY" ]; do - formBegin "$mysql_title: databases" - formItem "Database:" - formItem "Database:" - formItem "Database:" - formItem "Database:" - formItem "Database:" - formItem "Database:" - formItem "Database:" - formItem "Database:" - formItem "Database:" - formItem "Database:" - formDisplay - [ $? = 0 ] || return 1 - mysql_databases="databases = " - for i in $REPLY; do - [ -n "$i" ] && mysql_databases="$mysql_databases $i" - done - done -} - -do_mysql_password() { - inputBox "$mysql_title" "specify a mysql user:" - [ $? = 1 ] && return - user=$REPLY - inputBox "$mysql_title" "specify the mysql user's password:" - [ $? = 1 ] && return - password=$REPLY - do_mysql_final "dbusername = $user\ndbpassword = $password" -} - -do_mysql_debian() { - _DISABLE_HOTCOPY=yes - do_mysql_final "configfile = /etc/mysql/debian.cnf" -} - -do_mysql_user() { - inputBox "$mysql_title" "what system user does mysql backup use?" - [ $? = 1 ] && return - do_mysql_final "user = $REPLY" -} - -do_mysql_final() { - if [ -z "$_DISABLE_HOTCOPY" ]; then - checkBox "$mysql_title" "check options" \ - "sqldump" "create a backup using mysqldump (more compat)." no \ - "hotcopy" "create a backup using mysqlhotcopy (faster)." yes \ - "compress" "compress the sql output files" yes - status=$? - sqldump="sqldump = no" - hotcopy="hotcopy = no" - else - checkBox "$mysql_title" "check options" \ - "compress" "compress the sql output files" yes - status=$? - sqldump="sqldump = yes" - hotcopy="hotcopy = no" - fi - - [ $status = 1 ] && return; - result="$REPLY" - compress="compress = no" - for opt in $result; do - case $opt in - '"sqldump"') sqldump="sqldump = yes";; - '"hotcopy"') hotcopy="hotcopy = yes";; - '"compress"') compress="compress = yes";; - esac - done - get_next_filename $configdirectory/20.mysql - - cat >> $next_filename < (default = no) -# make a backup of the actual database binary files using mysqlhotcopy. -$hotcopy - -# sqldump = < yes | no > (default = no) -# make a backup using mysqldump. this creates text files with sql commands -# sufficient to recontruct the database. -# -$sqldump - -# compress = < yes | no > (default = yes) -# if yes, compress the sqldump output. -$compress - -# dbhost = (default = localhost) - -EOF - cat >> $next_filename < (default: /var/backups/mysql) -# where to dump the backups. hotcopy backups will be in a subdirectory -# 'hotcopy' and sqldump backups will be in a subdirectory 'sqldump' -$mysql_backupdir - -# databases = (default = all) -# which databases to backup. should either be the word 'all' or a -# space separated list of database names. -$mysql_databases - -EOF - -if [ $host_or_vservers == vservers ] - then - cat >> $next_filename < (no default) -# vsname indicates which vserver to operate on, this is only used if -# vserver is set to yes in /etc/backupninja.conf -# NOTE: if you do not specify a vsname the host will be operated on -# alsoNOTE: if operating on a vserver, $VROOTDIR will be -# prepended to backupdir. -EOF - echo -e "$mysql_vsname\n" >> $next_filename -fi - - echo -e $@ >> $next_filename - - chmod 600 $next_filename -} - -mysql_wizard() { - - # Global variables - mysql_title="MySQL action wizard" - - # backup the host system or a Vserver? - choose_host_or_one_vserver "$mysql_title" - [ $? = 0 ] || return 1 - if [ $host_or_vservers == vservers ] - then - do_mysql_vserver - [ $? = 0 ] || return 1 - fi - - # backupdir - if [ $host_or_vservers == vservers ] - then - inputBox "$mysql_title" "Directory where to store the backups:`echo \"\n(Relative to chosen vserver's root directory)\"`" "/var/backups/mysql" - else - inputBox "$mysql_title" "Directory where to store the backups" "/var/backups/mysql" - fi - [ $? = 1 ] && return - mysql_backupdir="backupdir = $REPLY" - - # databases - booleanBox "$mysql_title" "Do you want to backup all of the databases? `echo \"\n\nIf not, you'll be offered to choose individual databases to backup.\"`" - if [ $? = 0 ]; then - mysql_databases="databases = all" - else - do_mysql_databases - [ $? = 0 ] || return 1 - fi - - while true; do - _DISABLE_HOTCOPY= - menuBoxHelpFile "$mysql_title" "choose a mysql authentication method:" \ - user "change to a linux user first." \ - password "manually specify mysql user and password." \ - debian "use default mysql user debian-sys-maint." - status=$? - if [ $status = 2 ]; then - # show help. - helptmp="/tmp/backupninja.help.$$" - cat > $helptmp <> $next_filename < (default = no) +# make a backup of the actual database binary files using mysqlhotcopy. +$hotcopy + +# sqldump = < yes | no > (default = no) +# make a backup using mysqldump. this creates text files with sql commands +# sufficient to recontruct the database. +# +$sqldump + +# compress = < yes | no > (default = yes) +# if yes, compress the sqldump output. +$compress + +# dbhost = (default = localhost) + +EOF + cat >> $next_filename < (default: /var/backups/mysql) +# where to dump the backups. hotcopy backups will be in a subdirectory +# 'hotcopy' and sqldump backups will be in a subdirectory 'sqldump' +$mysql_backupdir + +# databases = (default = all) +# which databases to backup. should either be the word 'all' or a +# space separated list of database names. +$mysql_databases + +EOF + +if [ $host_or_vservers == vservers ] + then + cat >> $next_filename < (no default) +# vsname indicates which vserver to operate on, this is only used if +# vserver is set to yes in /etc/backupninja.conf +# NOTE: if you do not specify a vsname the host will be operated on +# alsoNOTE: if operating on a vserver, $VROOTDIR will be +# prepended to backupdir. +EOF + echo -e "$mysql_vsname\n" >> $next_filename +fi + + echo -e $@ >> $next_filename + + chmod 600 $next_filename +} + +mysql_wizard() { + + # Global variables + mysql_title="MySQL action wizard" + + # backup the host system or a Vserver? + choose_host_or_one_vserver "$mysql_title" + [ $? = 0 ] || return 1 + if [ $host_or_vservers == vservers ] + then + do_mysql_vserver + [ $? = 0 ] || return 1 + fi + + # backupdir + if [ $host_or_vservers == vservers ] + then + inputBox "$mysql_title" "Directory where to store the backups:`echo \"\n(Relative to chosen vserver's root directory)\"`" "/var/backups/mysql" + else + inputBox "$mysql_title" "Directory where to store the backups" "/var/backups/mysql" + fi + [ $? = 1 ] && return + mysql_backupdir="backupdir = $REPLY" + + # databases + booleanBox "$mysql_title" "Do you want to backup all of the databases? `echo \"\n\nIf not, you'll be offered to choose individual databases to backup.\"`" + if [ $? = 0 ]; then + mysql_databases="databases = all" + else + do_mysql_databases + [ $? = 0 ] || return 1 + fi + + while true; do + _DISABLE_HOTCOPY= + menuBoxHelpFile "$mysql_title" "choose a mysql authentication method:" \ + user "change to a linux user first." \ + password "manually specify mysql user and password." \ + debian "use default mysql user debian-sys-maint." + status=$? + if [ $status = 2 ]; then + # show help. + helptmp="/tmp/backupninja.help.$$" + cat > $helptmp < $mycnf <&1` + code=$? + if [ "$code" == "0" ] + then + debug $output + info "Successfully finished hotcopy of all mysql databases" + else + warning $output + warning "Failed to hotcopy all mysql databases" + fi + fi + else + for db in $databases + do + if [ $usevserver = yes ] + then + execstr="$VSERVER $vsname exec $MYSQLHOTCOPY --allowold $db $hotdir" + else + execstr="$MYSQLHOTCOPY --allowold $db $hotdir" + fi + debug 'su $user -c \"$execstr\"' + if [ ! $test ] + then + output=`su $user -c "$execstr" 2>&1` + code=$? + if [ "$code" == "0" ] + then + debug $output + info "Successfully finished hotcopy of mysql database $db" + else + warning $output + warning "Failed to hotcopy mysql database $db" + fi + fi + done + fi +fi + +########################################################################## +## SQL DUMP + +if [ "$sqldump" == "yes" ] +then + info "Initializing SQL dump method" + if [ "$databases" == "all" ] + then + if [ $usevserver = yes ] + then + debug 'echo show databases | $VSERVER $vsname exec su $user -c \"$MYSQL $defaultsfile\" | grep -v Database' + databases=`echo 'show databases' | $VSERVER $vsname exec su $user -c "$MYSQL $defaultsfile" | grep -v Database` + if [ $? -ne 0 ] + then + fatal "Authentication problem, maybe user/password is wrong or mysqld is not running?" + fi + else + databases=`echo 'show databases' | su $user -c "$MYSQL $defaultsfile" | grep -v Database` + if [ $? -ne 0 ] + then + fatal "Authentication problem, maybe user/password is wrong or mysqld is not running?" + fi + fi +fi + + for db in $databases + do + if [ $usevserver = yes ] + then + # Test to make sure mysqld is running, if it is not sqldump will not work + $VSERVER $vsname exec su $user -c "$MYSQLADMIN $defaultsfile ping" + if [ $? -ne 0 ]; then + fatal "Either you have an authentication problem, or mysqld doesn't appear to be running!" + fi + if [ "$compress" == "yes" ]; then + execstr="$VSERVER $vsname exec $MYSQLDUMP $defaultsfile --lock-tables --complete-insert --add-drop-table --quick --quote-names $ignore $db | $GZIP > $vroot$dumpdir/${db}.sql.gz" + else + execstr="$VSERVER $vsname exec $MYSQLDUMP $defaultsfile --lock-tables --complete-insert --add-drop-table --quick --quote-names $ignore $db -r $vroot$dumpdir/${db}.sql" + fi + else + # Test to make sure mysqld is running, if it is not sqldump will not work + su $user -c "$MYSQLADMIN $defaultsfile ping" + if [ $? -ne 0 ]; then + fatal "Either you have an authentication problem, or mysqld doesn't appear to be running!" + fi + if [ "$compress" == "yes" ]; then + execstr="$MYSQLDUMP $defaultsfile --lock-tables --complete-insert --add-drop-table --quick --quote-names $ignore $db | $GZIP > $dumpdir/${db}.sql.gz" + else + execstr="$MYSQLDUMP $defaultsfile --lock-tables --complete-insert --add-drop-table --quick --quote-names $ignore $db -r $dumpdir/${db}.sql" + fi + fi + debug "su $user -c \"$execstr\"" + if [ ! $test ] + then + output=`su $user -c "$execstr" 2>&1` + code=$? + if [ "$code" == "0" ] + then + debug $output + info "Successfully finished dump of mysql database $db" + else + warning $output + warning "Failed to dump mysql databases $db" + fi + fi + done +fi + +# clean up tmp config file +if [ "$dbusername" != "" -a "$dbpassword" != "" ] +then + ## clean up tmp config file + debug "rm $mycnf" + rm $mycnf + if [ -f "$tmpcnf" ] + then + debug "mv $tmpcnf $mycnf" + mv $tmpcnf $mycnf + fi +fi + +return 0 diff --git a/handlers/pgsql b/handlers/pgsql deleted file mode 100644 index 23e2c2b..0000000 --- a/handlers/pgsql +++ /dev/null @@ -1,136 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- -# -# PostgreSQL handler script for backupninja -# - -getconf backupdir /var/backups/postgres -getconf databases all -getconf compress yes -getconf vsname - -localhost=`hostname` - -# Decide if the handler should operate on a vserver or on the host. -# In the former case, check that $vsname exists and is running. -local usevserver=no -local vroot -if [ $vservers_are_available = yes ]; then - if [ -n "$vsname" ]; then - # does it exist ? - if ! vservers_exist "$vsname" ; then - fatal "The vserver given in vsname ($vsname) does not exist." - fi - # is it running ? - $VSERVERINFO -q $vsname RUNNING - if [ $? -ne 0 ]; then - fatal "The vserver $vsname is not running." - fi - # everything ok - info "Using vserver '$vsname'." - usevserver=yes - vroot="$VROOTDIR/$vsname" - else - info "No vserver name specified, actions will be performed on the host." - fi -fi - -# Make sure that the system to backup has the needed executables -if [ $usevserver = yes ]; then - debug "Examining vserver '$vsname'." - if [ "$databases" == "all" ]; then - [ -x "$vroot`$VSERVER $vsname exec which $PGSQLDUMPALL`" ] || \ - fatal "Can't find $PGSQLDUMPALL in vserver $vsname." - else - [ -x "$vroot`$VSERVER $vsname exec which $PGSQLDUMP`" ] || \ - fatal "Can't find $PGSQLDUMP in vserver $vsname." - fi -else - if [ "$databases" == "all" ]; then - [ -x "`which $PGSQLDUMPALL`" ] || \ - fatal "Can't find $PGSQLDUMPALL." - else - [ -x "`which $PGSQLDUMP`" ] || \ - fatal "Can't find $PGSQLDUMP." - fi -fi - -# create backup dir, the vroot variable will be empty if no vsname was specified -# and will proceed to operate on the host -[ -d $vroot$backupdir ] || (debug "mkdir -p $vroot$backupdir"; mkdir -p $vroot$backupdir) -[ -d $vroot$backupdir ] || fatal "Backup directory '$vroot$backupdir'" - -# give backup dir the good uid and permissions -# (in respect to the vserver, if $usevserver = yes) -if [ $usevserver = yes ]; then - pguid=`$VSERVER $vsname exec getent passwd $PGSQLUSER | @AWK@ -F: '{print $3}'` -else - pguid=`getent passwd $PGSQLUSER | @AWK@ -F: '{print $3}'` -fi -[ -n "$pguid" ] || \ - fatal "No user called $PGSQLUSER`[ $usevserver = no ] || echo \" on vserver $vsname\"`." -debug "chown $pguid $vroot$backupdir" -chown $pguid $vroot$backupdir -debug "chmod 700 $vroot$backupdir" -chmod 700 $vroot$backupdir - -# if $databases = all, use pg_dumpall -if [ "$databases" == "all" ]; then - if [ $usevserver = yes ]; then - if [ "$compress" == "yes" ]; then - execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMPALL | $GZIP > $backupdir/${vsname}.sql.gz\"" - else - execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMPALL > $backupdir/${vsname}.sql\"" - fi - else - if [ "$compress" == "yes" ]; then - execstr="su - $PGSQLUSER -c \"$PGSQLDUMPALL | $GZIP > $backupdir/${localhost}-all.sql.gz\"" - else - execstr="su - $PGSQLUSER -c \"$PGSQLDUMPALL > $backupdir/${localhost}-all.sql\"" - fi - fi - debug "$execstr" - if [ ! $test ]; then - output=`eval $execstr 2>&1` - code=$? - if [ "$code" == "0" ]; then - debug $output - info "Successfully finished dump of pgsql cluster" - else - warning $output - warning "Failed to dump pgsql cluster" - fi - fi - -# else use pg_dump on each specified database -else - for db in $databases; do - if [ $usevserver = yes ]; then - if [ "$compress" == "yes" ]; then - execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMP $db | $GZIP > $backupdir/${db}.sql.gz\"" - else - execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMP $db | > $backupdir/${db}.sql\"" - fi - else - if [ "$compress" == "yes" ]; then - execstr="su - $PGSQLUSER -c \"$PGSQLDUMP $db | $GZIP > $backupdir/${db}.sql.gz\"" - else - execstr="su - $PGSQLUSER -c \"$PGSQLDUMP $db > $backupdir/${db}.sql\"" - fi - fi - debug "$execstr" - if [ ! $test ]; then - output=`eval $execstr 2>&1` - code=$? - if [ "$code" == "0" ]; then - debug $output - info "Successfully finished dump of pgsql database ${db}" - else - warning $output - warning "Failed to dump pgsql database ${db}" - fi - fi - done -fi - -return 0 - diff --git a/handlers/pgsql.helper b/handlers/pgsql.helper deleted file mode 100644 index 8024616..0000000 --- a/handlers/pgsql.helper +++ /dev/null @@ -1,107 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- - -HELPERS="$HELPERS pgsql:postgresql_database_backup" - -do_pgsql_vserver() { - choose_one_vserver "$pgsql_title" - [ $? = 0 ] || return 1 - pgsql_vsname="vsname = $REPLY" -} - -do_pgsql_databases() { - REPLY= - while [ -z "$REPLY" ]; do - formBegin "$pgsql_title: databases" - formItem "Database:" - formItem "Database:" - formItem "Database:" - formItem "Database:" - formItem "Database:" - formItem "Database:" - formItem "Database:" - formItem "Database:" - formItem "Database:" - formItem "Database:" - formDisplay - [ $? = 0 ] || return 1 - pgsql_databases="databases = " - for i in $REPLY; do - [ -n "$i" ] && pgsql_databases="$pgsql_databases $i" - done - done -} - -pgsql_wizard() { - - # constants - pgsql_title="PostgreSQL action wizard" - - # backup the host system or a Vserver? - choose_host_or_one_vserver "$pgsql_title" - [ $? = 0 ] || return 1 - if [ $host_or_vservers == vservers ]; then - do_pgsql_vserver - [ $? = 0 ] || return 1 - fi - - # backupdir - inputBox "$pgsql_title" "Directory where to store the backups:`[ -z \"$pgsql_vsname\" ] || echo \"\n(In respect to chosen vserver's root directory)\"`" "/var/backups/postgres" - [ $? = 1 ] && return - pgsql_backupdir="backupdir = $REPLY" - - # databases - booleanBox "$pgsql_title" "Do you want to backup the whole cluster? If not, you'll be offered to choose the databases to backup." - if [ $? = 0 ]; then - pgsql_databases="databases = all" - else - do_pgsql_databases - [ $? = 0 ] || return 1 - fi - - # compress - booleanBox "$pgsql_title" "Do you want to compress the backups?" - if [ $? = 0 ]; then - pgsql_compress="compress = yes" - else - pgsql_compress="compress = no" - fi - - # write config file - get_next_filename $configdirectory/20.pgsql - cat >> $next_filename < (no default) -# what vserver to operate on, only used if vserver = yes in /etc/backupninja.conf -# if you do not specify a vsname the host will be operated on -# Note: if operating on a vserver, $VROOTDIR will be prepended to backupdir. -EOF - if [ $host_or_vservers == vservers ]; then - echo -e "$pgsql_vsname\n" >> $next_filename - fi - - cat >> $next_filename < (default: /var/backups/postgres) -# where to dump the backups -$pgsql_backupdir - -# databases = < all | db1 db2 db3 > (default = all) -# which databases to backup. should either be the word 'all' or a -# space separated list of database names. -# Note: when using 'all', pg_dumpall is used instead of pg_dump, which means -# that cluster-wide data (such as users and groups) are saved. -$pgsql_databases - -# compress = < yes | no > (default = yes) -# if yes, compress the pg_dump/pg_dumpall output. -$pgsql_compress - -### You can also set the following variables in backupninja.conf: -# PGSQLDUMP: pg_dump path (default: /usr/bin/pg_dump) -# PGSQLDUMPALL: pg_dumpall path (default: /usr/bin/pg_dumpall) -# PGSQLUSER: user running PostgreSQL (default: postgres) - -EOF - chmod 600 $next_filename - -} diff --git a/handlers/pgsql.helper.in b/handlers/pgsql.helper.in new file mode 100644 index 0000000..8024616 --- /dev/null +++ b/handlers/pgsql.helper.in @@ -0,0 +1,107 @@ +# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- + +HELPERS="$HELPERS pgsql:postgresql_database_backup" + +do_pgsql_vserver() { + choose_one_vserver "$pgsql_title" + [ $? = 0 ] || return 1 + pgsql_vsname="vsname = $REPLY" +} + +do_pgsql_databases() { + REPLY= + while [ -z "$REPLY" ]; do + formBegin "$pgsql_title: databases" + formItem "Database:" + formItem "Database:" + formItem "Database:" + formItem "Database:" + formItem "Database:" + formItem "Database:" + formItem "Database:" + formItem "Database:" + formItem "Database:" + formItem "Database:" + formDisplay + [ $? = 0 ] || return 1 + pgsql_databases="databases = " + for i in $REPLY; do + [ -n "$i" ] && pgsql_databases="$pgsql_databases $i" + done + done +} + +pgsql_wizard() { + + # constants + pgsql_title="PostgreSQL action wizard" + + # backup the host system or a Vserver? + choose_host_or_one_vserver "$pgsql_title" + [ $? = 0 ] || return 1 + if [ $host_or_vservers == vservers ]; then + do_pgsql_vserver + [ $? = 0 ] || return 1 + fi + + # backupdir + inputBox "$pgsql_title" "Directory where to store the backups:`[ -z \"$pgsql_vsname\" ] || echo \"\n(In respect to chosen vserver's root directory)\"`" "/var/backups/postgres" + [ $? = 1 ] && return + pgsql_backupdir="backupdir = $REPLY" + + # databases + booleanBox "$pgsql_title" "Do you want to backup the whole cluster? If not, you'll be offered to choose the databases to backup." + if [ $? = 0 ]; then + pgsql_databases="databases = all" + else + do_pgsql_databases + [ $? = 0 ] || return 1 + fi + + # compress + booleanBox "$pgsql_title" "Do you want to compress the backups?" + if [ $? = 0 ]; then + pgsql_compress="compress = yes" + else + pgsql_compress="compress = no" + fi + + # write config file + get_next_filename $configdirectory/20.pgsql + cat >> $next_filename < (no default) +# what vserver to operate on, only used if vserver = yes in /etc/backupninja.conf +# if you do not specify a vsname the host will be operated on +# Note: if operating on a vserver, $VROOTDIR will be prepended to backupdir. +EOF + if [ $host_or_vservers == vservers ]; then + echo -e "$pgsql_vsname\n" >> $next_filename + fi + + cat >> $next_filename < (default: /var/backups/postgres) +# where to dump the backups +$pgsql_backupdir + +# databases = < all | db1 db2 db3 > (default = all) +# which databases to backup. should either be the word 'all' or a +# space separated list of database names. +# Note: when using 'all', pg_dumpall is used instead of pg_dump, which means +# that cluster-wide data (such as users and groups) are saved. +$pgsql_databases + +# compress = < yes | no > (default = yes) +# if yes, compress the pg_dump/pg_dumpall output. +$pgsql_compress + +### You can also set the following variables in backupninja.conf: +# PGSQLDUMP: pg_dump path (default: /usr/bin/pg_dump) +# PGSQLDUMPALL: pg_dumpall path (default: /usr/bin/pg_dumpall) +# PGSQLUSER: user running PostgreSQL (default: postgres) + +EOF + chmod 600 $next_filename + +} diff --git a/handlers/pgsql.in b/handlers/pgsql.in new file mode 100644 index 0000000..23e2c2b --- /dev/null +++ b/handlers/pgsql.in @@ -0,0 +1,136 @@ +# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- +# +# PostgreSQL handler script for backupninja +# + +getconf backupdir /var/backups/postgres +getconf databases all +getconf compress yes +getconf vsname + +localhost=`hostname` + +# Decide if the handler should operate on a vserver or on the host. +# In the former case, check that $vsname exists and is running. +local usevserver=no +local vroot +if [ $vservers_are_available = yes ]; then + if [ -n "$vsname" ]; then + # does it exist ? + if ! vservers_exist "$vsname" ; then + fatal "The vserver given in vsname ($vsname) does not exist." + fi + # is it running ? + $VSERVERINFO -q $vsname RUNNING + if [ $? -ne 0 ]; then + fatal "The vserver $vsname is not running." + fi + # everything ok + info "Using vserver '$vsname'." + usevserver=yes + vroot="$VROOTDIR/$vsname" + else + info "No vserver name specified, actions will be performed on the host." + fi +fi + +# Make sure that the system to backup has the needed executables +if [ $usevserver = yes ]; then + debug "Examining vserver '$vsname'." + if [ "$databases" == "all" ]; then + [ -x "$vroot`$VSERVER $vsname exec which $PGSQLDUMPALL`" ] || \ + fatal "Can't find $PGSQLDUMPALL in vserver $vsname." + else + [ -x "$vroot`$VSERVER $vsname exec which $PGSQLDUMP`" ] || \ + fatal "Can't find $PGSQLDUMP in vserver $vsname." + fi +else + if [ "$databases" == "all" ]; then + [ -x "`which $PGSQLDUMPALL`" ] || \ + fatal "Can't find $PGSQLDUMPALL." + else + [ -x "`which $PGSQLDUMP`" ] || \ + fatal "Can't find $PGSQLDUMP." + fi +fi + +# create backup dir, the vroot variable will be empty if no vsname was specified +# and will proceed to operate on the host +[ -d $vroot$backupdir ] || (debug "mkdir -p $vroot$backupdir"; mkdir -p $vroot$backupdir) +[ -d $vroot$backupdir ] || fatal "Backup directory '$vroot$backupdir'" + +# give backup dir the good uid and permissions +# (in respect to the vserver, if $usevserver = yes) +if [ $usevserver = yes ]; then + pguid=`$VSERVER $vsname exec getent passwd $PGSQLUSER | @AWK@ -F: '{print $3}'` +else + pguid=`getent passwd $PGSQLUSER | @AWK@ -F: '{print $3}'` +fi +[ -n "$pguid" ] || \ + fatal "No user called $PGSQLUSER`[ $usevserver = no ] || echo \" on vserver $vsname\"`." +debug "chown $pguid $vroot$backupdir" +chown $pguid $vroot$backupdir +debug "chmod 700 $vroot$backupdir" +chmod 700 $vroot$backupdir + +# if $databases = all, use pg_dumpall +if [ "$databases" == "all" ]; then + if [ $usevserver = yes ]; then + if [ "$compress" == "yes" ]; then + execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMPALL | $GZIP > $backupdir/${vsname}.sql.gz\"" + else + execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMPALL > $backupdir/${vsname}.sql\"" + fi + else + if [ "$compress" == "yes" ]; then + execstr="su - $PGSQLUSER -c \"$PGSQLDUMPALL | $GZIP > $backupdir/${localhost}-all.sql.gz\"" + else + execstr="su - $PGSQLUSER -c \"$PGSQLDUMPALL > $backupdir/${localhost}-all.sql\"" + fi + fi + debug "$execstr" + if [ ! $test ]; then + output=`eval $execstr 2>&1` + code=$? + if [ "$code" == "0" ]; then + debug $output + info "Successfully finished dump of pgsql cluster" + else + warning $output + warning "Failed to dump pgsql cluster" + fi + fi + +# else use pg_dump on each specified database +else + for db in $databases; do + if [ $usevserver = yes ]; then + if [ "$compress" == "yes" ]; then + execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMP $db | $GZIP > $backupdir/${db}.sql.gz\"" + else + execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMP $db | > $backupdir/${db}.sql\"" + fi + else + if [ "$compress" == "yes" ]; then + execstr="su - $PGSQLUSER -c \"$PGSQLDUMP $db | $GZIP > $backupdir/${db}.sql.gz\"" + else + execstr="su - $PGSQLUSER -c \"$PGSQLDUMP $db > $backupdir/${db}.sql\"" + fi + fi + debug "$execstr" + if [ ! $test ]; then + output=`eval $execstr 2>&1` + code=$? + if [ "$code" == "0" ]; then + debug $output + info "Successfully finished dump of pgsql database ${db}" + else + warning $output + warning "Failed to dump pgsql database ${db}" + fi + fi + done +fi + +return 0 + diff --git a/handlers/rdiff b/handlers/rdiff deleted file mode 100644 index 46cae49..0000000 --- a/handlers/rdiff +++ /dev/null @@ -1,251 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- -# -# rdiff-backup handler script for backupninja -# requires rdiff-backup -# - -### FUNCTIONS ### - -function test_connection() { - # given a user and host, - # tests the connection. - # if user or host is missing, returns 0 - # (ie, assume it's a local connection). - if [ $# -lt 2 ]; then - debug "(local is assumed to be a good connection)" - return 0 - fi - local user=$1 - local host=$2 - debug "ssh $sshoptions -o PasswordAuthentication=no $host -l $user 'echo -n 1'" - local ret=`ssh $sshoptions -o PasswordAuthentication=no $host -l $user 'echo -n host is alive'` - if echo $ret | grep "host is alive"; then - debug "Connected to $host as $user successfully" - else - fatal "Can't connect to $host as $user." - fi -} - -function get_version() { - # given no arguments, returns the local version. - # given a user and host, returns the remote version. - # if user or host is missing, returns the local version. - if [ "$#" -lt 2 ]; then - debug "$RDIFFBACKUP -V" - echo `$RDIFFBACKUP -V | cut -d. -f1,2` - else - local user=$1 - local host=$2 - debug "ssh $sshoptions $host -l $user '$RDIFFBACKUP -V'" - echo `ssh $sshoptions $host -l $user "$RDIFFBACKUP -V | grep rdiff-backup | cut -d. -f1,2"` - fi -} - -function check_consistency() { - local section=$1 - local type=$2 - local user=$3 - local host=$4 - if [ "$type" == "local" ]; then - if [ "$user" != "" ]; then - warning "User should not be specified for local $section." - fi - if [ "$host" != "" ]; then - warning "Host should not be specified for local $section." - fi - fi - if [ "$type" == "remote" ]; then - if [ "$user" == "" ]; then - fatal "User must be specified for remote $section." - fi - if [ "host" == "" ]; then - fatal "Host must be specifed for remote $section." - fi - fi -} - -function check_cstream() { - local cstream=$1 - if [ ! -x $cstream ]; then - fatal "Can't find your cstream binary (trying: $cstream). If you use bwlimit you must have cstream installed." - fi -} - -### GET CONFIG ### - -getconf options -getconf testconnect yes -getconf nicelevel 0 -getconf bwlimit - -setsection source -getconf type; sourcetype=$type -getconf user; sourceuser=$user -getconf host; sourcehost=$host -check_consistency "source" "$type" "$user" "$host" -getconf label -getconf keep 60 -getconf include -getconf vsnames all -getconf vsinclude -getconf exclude - -setsection dest -getconf directory; destdir=$directory -# strip trailing / -destdir=${destdir%/} -getconf type; desttype=$type -getconf user; destuser=$user -getconf host; desthost=$host -getconf sshoptions -check_consistency "destination" "$type" "$user" "$host" - -### CHECK CONFIG ### - -# If vservers are configured, check that the ones listed in $vsnames do exist. -local usevserver=no -if [ $vservers_are_available = yes ]; then - if [ "$vsnames" = all ]; then - vsnames="$found_vservers" - else - if ! vservers_exist "$vsnames" ; then - fatal "At least one of the vservers listed in vsnames ($vsnames) does not exist." - fi - fi - if [ -n "$vsinclude" ]; then - info "Using vservers '$vsnames'" - usevserver=yes - fi -else - [ -z "$vsinclude" ] || warning 'vservers support disabled in backupninja.conf, vsincludes configuration lines will be ignored' -fi - -# check the connection at the source and destination -[ -n "$test" ] || test=0 -if [ "$testconnect" = "yes" ] || [ "${test}" -eq 1 ]; then - test_connection $sourceuser $sourcehost - test_connection $destuser $desthost -fi - -# see that rdiff-backup has the same version at the source and destination -sourceversion=`get_version $sourceuser $sourcehost` -destversion=`get_version $destuser $desthost` -if [ "$sourceversion" != "$destversion" ]; then - fatal "rdiff-backup does not have the same version at the source and at the destination." -fi - -# source specific checks -[ "$include" != "" -o "$vsinclude" != "" ] || fatal "No source includes specified" -case $sourcetype in - remote ) execstr_sourcepart="$sourceuser@$sourcehost::/" ;; - local ) execstr_sourcepart="/" ;; - * ) fatal "sourcetype '$sourcetype' is neither local nor remote" ;; -esac - -# destination specific checks -[ "$destdir" != "" ] || fatal "Destination directory not set" -case $desttype in - remote ) execstr_destpart="$destuser@$desthost::$destdir/$label" ;; - local ) execstr_destpart="$destdir/$label" ;; - * ) fatal "desttype '$desttype' is neither local nor remote" ;; -esac - -### REMOVE OLD BACKUPS ### - -if [ "$keep" != yes ]; then - - if [ "`echo $keep | tr -d 0-9`" == "" ]; then - # add D if no other date unit is specified - keep="${keep}D" - fi - - removestr="$RDIFFBACKUP $options --force --remove-older-than $keep " - if [ "$desttype" == "remote" ]; then - removestr="${removestr}${destuser}@${desthost}::" - fi - removestr="${removestr}${destdir}/${label}"; - - debug "$removestr" - if [ $test = 0 ]; then - output="`su -c "$removestr" 2>&1`" - if [ $? = 0 ]; then - debug $output - info "Removing backups older than $keep days succeeded." - else - warning $output - warning "Failed removing backups older than $keep." - fi - fi - -fi - -# Add cstream - -if [ ! -z $bwlimit ]; then - check_cstream $CSTREAM; - if [ "$desttype" = "remote" ]; then - RDIFFBACKUP="$RDIFFBACKUP --remote-schema 'cstream -t $bwlimit | ssh %s \''rdiff-backup --server\'''" - elif [ "$sourcetype" = "remote" ]; then - RDIFFBACKUP="$RDIFFBACKUP --remote-schema 'ssh %s \''rdiff-backup --server\'' | cstream -t $bwlimit'" - else - fatal "You specified a bandwidth limit but neither your source nor destination types are remote." - fi -fi - -### EXECUTE ### - -execstr="$RDIFFBACKUP $options --print-statistics " - -set -o noglob - -symlinks_warning="Maybe you have mixed symlinks and '*' in this statement, which is not supported." - -# 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 - [ "$i" != "/" ] || fatal "Sorry, you cannot use 'include = /'" - str="${i//__star__/*}" - execstr="${execstr}--include '$str' " -done - -# vsinclude -if [ $usevserver = yes ]; then - for vserver in $vsnames; do - for vi in $vsinclude; do - str="${vi//__star__/*}" - str="$VROOTDIR/$vserver$str" - if [ -n "$str" ]; then - execstr="${execstr}--include '$str' " - else - warning "vsinclude statement '${vi//__star__/*}' will be ignored for VServer $vserver. $symlinks_warning" - fi - done - done -fi - -set +o noglob - -# exclude everything else -execstr="${execstr}--exclude '/*' " - -# include client-part and server-part -execstr="${execstr}$execstr_sourcepart $execstr_destpart" - -debug "$execstr" -if [ $test = 0 ]; then - output=`nice -n $nicelevel su -c "$execstr" 2>&1` - if [ $? = 0 ]; then - debug $output - info "Successfully finished backing up source $label" - else - warning $output - warning "Failed backup up source $label" - fi -fi - -return 0 diff --git a/handlers/rdiff.helper b/handlers/rdiff.helper deleted file mode 100644 index 42bcb1b..0000000 --- a/handlers/rdiff.helper +++ /dev/null @@ -1,401 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- - -HELPERS="$HELPERS rdiff:incremental_remote_filesystem_backup" - -declare -a rdiff_includes -declare -a rdiff_excludes -declare -a rdiff_vsincludes -declare -a rdiff_vsexcludes - -# FUNCTIONS - -do_rdiff_host_includes() { - set -o noglob - # choose the files to backup - REPLY= - while [ -z "$REPLY" ]; do - formBegin "$rdiff_title - host system: includes" - for ((i=0; i < ${#rdiff_includes[@]} ; i++)); do - formItem include ${rdiff_includes[$i]} - done - formItem include - formItem include - formItem include - formDisplay - [ $? = 0 ] || return - unset rdiff_includes - rdiff_includes=($REPLY) - done - set +o noglob -} - -do_rdiff_vserver() { - # choose the vservers to backup (into $selected_vservers) - choose_one_or_more_vservers "$rdiff_title" - [ $? = 0 ] || return 1 - - set -o noglob - # choose the files to backup - REPLY= - - while [ -z "$REPLY" ]; do - formBegin "$rdiff_title - vsincludes (backup these directories from every vserver)" - [ -z "$rdiff_vsincludes" ] && rdiff_vsincludes="$rdiff_default_includes" - - for i in $rdiff_vsincludes; do - formItem include "$i" - done - formItem include "" - formItem include "" - formItem include "" - formDisplay - [ $? = 0 ] || return 1 - rdiff_vsincludes=($REPLY) - done - - set +o noglob -} - -do_rdiff_excludes() { - set -o noglob - formBegin "$rdiff_title: excludes" - for ((i=0; i < ${#rdiff_excludes[@]} ; i++)) - do - formItem exclude ${rdiff_excludes[$i]} - done - formItem exclude - formItem exclude - formDisplay - [ $? = 0 ] || return - unset rdiff_excludes - rdiff_excludes=($REPLY) - set +o noglob -} - -do_rdiff_src() { - choose_host_or_vservers_or_both "$rdiff_title" - [ $? = 0 ] || return 1 - case $host_or_vservers in - 'host') - do_rdiff_host_includes - [ $? = 0 ] || return 1 - ;; - 'vservers') - do_rdiff_vserver - [ $? = 0 ] || return 1 - ;; - 'both') - do_rdiff_host_includes - [ $? = 0 ] || return 1 - do_rdiff_vserver - [ $? = 0 ] || return 1 - ;; - *) - return 1 - ;; - esac - do_rdiff_excludes - [ $? = 0 ] || return 1 - _src_done="(DONE)" - setDefault dest -} - -do_rdiff_dest() { - declare -a tmp_array - - set -o noglob - REPLY= - while [ -z "$REPLY" -o -z "$rdiff_directory" -o -z "$rdiff_host" -o -z "$rdiff_user" ] - do - formBegin "$rdiff_title - destination: last three items are required" - formItem "keep" "$rdiff_keep" - formItem "dest_directory" "$rdiff_directory" - formItem "dest_host" "$rdiff_host" - formItem "dest_user" "$rdiff_user" - formDisplay - [ $? = 0 ] || return - tmp_array=($REPLY) - rdiff_keep=${tmp_array[0]} - rdiff_directory=${tmp_array[1]} - rdiff_host=${tmp_array[2]} - rdiff_user=${tmp_array[3]} - done - set +o noglob - - _dest_done="(DONE)" - setDefault conn -} - -do_rdiff_ssh_con() { - local remote_status="ok" - - IFS=$' \t\n' - if [ "$_dest_done" = "" ]; then - msgBox "$rdiff_title: error" "You must first configure the destination." - return - elif [ "$rdiff_user" = "" ]; then - msgBox "$rdiff_title: error" "You must first configure the destination user." - return - elif [ "$rdiff_host" = "" ]; then - msgBox "$rdiff_title: error" "You must first configure the destination host." - return - else - booleanBox "$rdiff_title" "This step will create a ssh key for the local root user with no passphrase (if one does not already exist), and attempt to copy root's public ssh key to authorized_keys file of $rdiff_user@$rdiff_host. This will allow the local root to make unattended backups to $rdiff_user@$rdiff_host.\n\n\nAre you sure you want to continue?" - [ $? = 0 ] || return - fi - - if [ ! -f /root/.ssh/id_dsa.pub -a ! -f /root/.ssh/id_rsa.pub ]; then - echo "Creating local root's ssh key" - ssh-keygen -t dsa -f /root/.ssh/id_dsa -N "" - echo "Done. hit return to continue" - read - fi - - ssh -o PreferredAuthentications=publickey $rdiff_host -l $rdiff_user "exit" 2> /dev/null - if [ $? -ne 0 ]; then - echo "Copying root's public ssh key to authorized_keys of $rdiff_user@$rdiff_host. When prompted, specify the password for user $rdiff_user@$rdiff_host." - ssh-copy-id -i /root/.ssh/id_[rd]sa.pub $rdiff_user@$rdiff_host - if [ $? -ne 0 ]; then - echo "FAILED: Couldn't copy root's public ssh key to authorized_keys of $rdiff_user@$rdiff_host." - ssh $rdiff_user@$rdiff_host 'test -w .ssh || test -w .' - result=$? - echo "Hit return to continue." - read - case $result in - 0 ) msgBox "$rdiff_title: error" "Directories are writable: Probably just a typo the first time." ;; - 1 ) msgBox "$rdiff_title: error" "Connected successfully to $rdiff_user@$rdiff_host, but unable to write. Check ownership and modes of ~$rdiff_user on $rdiff_host." ;; - 255 ) msgBox "$rdiff_title: error" "Failed to connect to $rdiff_user@$rdiff_host. Check hostname, username, and password. Also, make sure sshd is running on the destination host." ;; - * ) msgBox "$rdiff_title: error" "Unexpected error." ;; - esac - return - else - echo "Done. hit return to continue" - read - fi - else - echo "root@localhost is already in authorized_keys of $rdiff_user@$rdiff_host." - echo "Hit return to continue." - read - fi - - # test to see if the remote rdiff backup directory exists and is writable - echo "Testing to see if remote rdiff backup directory exists and is writable" - ssh $rdiff_user@$rdiff_host "test -d ${rdiff_directory}" - if [ $? = 0 ]; then - ssh $rdiff_user@$rdiff_host "test -w $rdiff_directory" - if [ $? != 0 ]; then - msgBox "destination directory is not writable!" "The remote destination directory is not writable by the user you specified. Please fix the permissions on the directory and then try again." - remote_status=failed - fi - else - booleanBox "Remote directory does not exist" "The destination backup directory does not exist, do you want me to create it for you?" - if [ $? = 0 ]; then - ssh $rdiff_user@$rdiff_host "mkdir -p ${rdiff_directory}" - result=$? - case $result in - 0) msgBox "$rdiff_title: success" "Creation of the remote destination directory was a success!";; - 1) msgBox "$rdiff_title: error" "Connected successfully to $rdiff_user@$rdiff_host, but was unable to create the destination directory, check the directory permissions." - remote_status=failed;; - 255) msgBox "$rdiff_title: error" "Failed to connect to $rdiff_user@$rdiff_host. Check hostname, username, and password. Also, make sure sshd is running on the destination host." - remote_status=failed;; - *) msgBox "$rdiff_title: error" "Unexpected error." - remote_status=failed;; - esac - fi - fi - - if [ "$remote_status" = "ok" ]; then - do_rdiff_con - fi -} - -do_rdiff_con() { - echo "Checking for local install of rdiff-backup" - require_packages rdiff-backup - - echo "Testing to make sure destination has rdiff-backup installed and is compatible." - remote_result=`/usr/bin/rdiff-backup --test-server $rdiff_user@$rdiff_host::/ 2>&1 >&-` - if [ $? -ne 0 ]; then - echo $remote_result | grep -q "command not found" - if [ $? -eq 0 ]; then - if [ "$rdiff_user" = "root" ]; then - booleanBox "install rdiff-backup?" "It seems like the remote machine does not have rdiff-backup installed, I can attempt to install rdiff-backup on the remote machine.\n\n\nDo you want me to attempt this now?" - if [ $? = 0 ]; then - ssh $rdiff_user@$rdiff_host 'apt-get install rdiff-backup' - result=$? - echo "Hit return to continue." - read - case $result in - 0) msgBox "$rdiff_title: success" "Installation of rdiff-backup was a success!" - do_rdiff_con;; - 1) msgBox "$rdiff_title: error" "Connected successfully to $rdiff_user@$rdiff_host, but was unable to install the package for some reason.";; - 255) msgBox "$rdiff_title: error" "Failed to connect to $rdiff_user@$rdiff_host. Check hostname, username, and password. Also, make sure sshd is running on the destination host.";; - *) msgBox "$rdiff_title: error" "Unexpected error.";; - esac - return - fi - else - booleanBox "install rdiff-backup" "Please install rdiff-backup on the remote machine, this cannot be done automatically, as the remote user in your configuration is not root. \n\nIf you have installed rdiff-backup on the remote machine and you are getting this error, then there is a version incompatibility between that version and the local version.\n\nPlease resolve this problem and then try connecting again.\n\n\n\nTry connecting again?" - if [ $? = 0 ]; then - do_rdiff_con - else - return - fi - fi - else - msgBox "incompatible versions of rdiff-backup" "It looks like rdiff-backup is installed on the remote machine, but it may be an incompatible version with the one installed locally, or something else is amiss.\n\nPlease resolve this problem and then try connecting again.\n\n\nTry connecting again?" - if [ $? = 0 ]; then - do_rdiff_con - else - return - fi - fi - else - echo "SUCCESS: Everything looks good!" - echo "Hit return to continue." - read - fi - - _con_done="(DONE)" - setDefault finish -} - -do_rdiff_finish() { - get_next_filename $configdirectory/90.rdiff - cat > $next_filename <> $next_filename - done - set +o noglob - fi - - if [ "$host_or_vservers" == vservers -o "$host_or_vservers" == both ]; then - cat >> $next_filename < ... (default = all) -# vsinclude = -# vsinclude = -# ... -# Any path specified in vsinclude is added to the include list for each vserver -# listed in vsnames (or all if vsnames = all, which is the default). -# -# For example, vsinclude = /home will backup the /home directory in every -# vserver listed in vsnames. If you have 'vsnames = foo bar baz', this -# vsinclude will add to the include list /vservers/foo/home, /vservers/bar/home -# and /vservers/baz/home. -# Vservers paths are derived from $VROOTDIR. - -EOF - set -o noglob - echo -e "vsnames = $selected_vservers\n" >> $next_filename - for i in $rdiff_vsincludes; do - echo "vsinclude = $i" >> $next_filename - done - set +o noglob - fi - - ## excludes ## - set -o noglob - for ((i=0; i < ${#rdiff_excludes[@]} ; i++)); do - echo exclude = ${rdiff_excludes[$i]} >> $next_filename - done - set +o noglob - cat >> $next_filename < /dev/null + if [ $? -ne 0 ]; then + echo "Copying root's public ssh key to authorized_keys of $rdiff_user@$rdiff_host. When prompted, specify the password for user $rdiff_user@$rdiff_host." + ssh-copy-id -i /root/.ssh/id_[rd]sa.pub $rdiff_user@$rdiff_host + if [ $? -ne 0 ]; then + echo "FAILED: Couldn't copy root's public ssh key to authorized_keys of $rdiff_user@$rdiff_host." + ssh $rdiff_user@$rdiff_host 'test -w .ssh || test -w .' + result=$? + echo "Hit return to continue." + read + case $result in + 0 ) msgBox "$rdiff_title: error" "Directories are writable: Probably just a typo the first time." ;; + 1 ) msgBox "$rdiff_title: error" "Connected successfully to $rdiff_user@$rdiff_host, but unable to write. Check ownership and modes of ~$rdiff_user on $rdiff_host." ;; + 255 ) msgBox "$rdiff_title: error" "Failed to connect to $rdiff_user@$rdiff_host. Check hostname, username, and password. Also, make sure sshd is running on the destination host." ;; + * ) msgBox "$rdiff_title: error" "Unexpected error." ;; + esac + return + else + echo "Done. hit return to continue" + read + fi + else + echo "root@localhost is already in authorized_keys of $rdiff_user@$rdiff_host." + echo "Hit return to continue." + read + fi + + # test to see if the remote rdiff backup directory exists and is writable + echo "Testing to see if remote rdiff backup directory exists and is writable" + ssh $rdiff_user@$rdiff_host "test -d ${rdiff_directory}" + if [ $? = 0 ]; then + ssh $rdiff_user@$rdiff_host "test -w $rdiff_directory" + if [ $? != 0 ]; then + msgBox "destination directory is not writable!" "The remote destination directory is not writable by the user you specified. Please fix the permissions on the directory and then try again." + remote_status=failed + fi + else + booleanBox "Remote directory does not exist" "The destination backup directory does not exist, do you want me to create it for you?" + if [ $? = 0 ]; then + ssh $rdiff_user@$rdiff_host "mkdir -p ${rdiff_directory}" + result=$? + case $result in + 0) msgBox "$rdiff_title: success" "Creation of the remote destination directory was a success!";; + 1) msgBox "$rdiff_title: error" "Connected successfully to $rdiff_user@$rdiff_host, but was unable to create the destination directory, check the directory permissions." + remote_status=failed;; + 255) msgBox "$rdiff_title: error" "Failed to connect to $rdiff_user@$rdiff_host. Check hostname, username, and password. Also, make sure sshd is running on the destination host." + remote_status=failed;; + *) msgBox "$rdiff_title: error" "Unexpected error." + remote_status=failed;; + esac + fi + fi + + if [ "$remote_status" = "ok" ]; then + do_rdiff_con + fi +} + +do_rdiff_con() { + echo "Checking for local install of rdiff-backup" + require_packages rdiff-backup + + echo "Testing to make sure destination has rdiff-backup installed and is compatible." + remote_result=`/usr/bin/rdiff-backup --test-server $rdiff_user@$rdiff_host::/ 2>&1 >&-` + if [ $? -ne 0 ]; then + echo $remote_result | grep -q "command not found" + if [ $? -eq 0 ]; then + if [ "$rdiff_user" = "root" ]; then + booleanBox "install rdiff-backup?" "It seems like the remote machine does not have rdiff-backup installed, I can attempt to install rdiff-backup on the remote machine.\n\n\nDo you want me to attempt this now?" + if [ $? = 0 ]; then + ssh $rdiff_user@$rdiff_host 'apt-get install rdiff-backup' + result=$? + echo "Hit return to continue." + read + case $result in + 0) msgBox "$rdiff_title: success" "Installation of rdiff-backup was a success!" + do_rdiff_con;; + 1) msgBox "$rdiff_title: error" "Connected successfully to $rdiff_user@$rdiff_host, but was unable to install the package for some reason.";; + 255) msgBox "$rdiff_title: error" "Failed to connect to $rdiff_user@$rdiff_host. Check hostname, username, and password. Also, make sure sshd is running on the destination host.";; + *) msgBox "$rdiff_title: error" "Unexpected error.";; + esac + return + fi + else + booleanBox "install rdiff-backup" "Please install rdiff-backup on the remote machine, this cannot be done automatically, as the remote user in your configuration is not root. \n\nIf you have installed rdiff-backup on the remote machine and you are getting this error, then there is a version incompatibility between that version and the local version.\n\nPlease resolve this problem and then try connecting again.\n\n\n\nTry connecting again?" + if [ $? = 0 ]; then + do_rdiff_con + else + return + fi + fi + else + msgBox "incompatible versions of rdiff-backup" "It looks like rdiff-backup is installed on the remote machine, but it may be an incompatible version with the one installed locally, or something else is amiss.\n\nPlease resolve this problem and then try connecting again.\n\n\nTry connecting again?" + if [ $? = 0 ]; then + do_rdiff_con + else + return + fi + fi + else + echo "SUCCESS: Everything looks good!" + echo "Hit return to continue." + read + fi + + _con_done="(DONE)" + setDefault finish +} + +do_rdiff_finish() { + get_next_filename $configdirectory/90.rdiff + cat > $next_filename <> $next_filename + done + set +o noglob + fi + + if [ "$host_or_vservers" == vservers -o "$host_or_vservers" == both ]; then + cat >> $next_filename < ... (default = all) +# vsinclude = +# vsinclude = +# ... +# Any path specified in vsinclude is added to the include list for each vserver +# listed in vsnames (or all if vsnames = all, which is the default). +# +# For example, vsinclude = /home will backup the /home directory in every +# vserver listed in vsnames. If you have 'vsnames = foo bar baz', this +# vsinclude will add to the include list /vservers/foo/home, /vservers/bar/home +# and /vservers/baz/home. +# Vservers paths are derived from $VROOTDIR. + +EOF + set -o noglob + echo -e "vsnames = $selected_vservers\n" >> $next_filename + for i in $rdiff_vsincludes; do + echo "vsinclude = $i" >> $next_filename + done + set +o noglob + fi + + ## excludes ## + set -o noglob + for ((i=0; i < ${#rdiff_excludes[@]} ; i++)); do + echo exclude = ${rdiff_excludes[$i]} >> $next_filename + done + set +o noglob + cat >> $next_filename <&1`" + if [ $? = 0 ]; then + debug $output + info "Removing backups older than $keep days succeeded." + else + warning $output + warning "Failed removing backups older than $keep." + fi + fi + +fi + +# Add cstream + +if [ ! -z $bwlimit ]; then + check_cstream $CSTREAM; + if [ "$desttype" = "remote" ]; then + RDIFFBACKUP="$RDIFFBACKUP --remote-schema 'cstream -t $bwlimit | ssh %s \''rdiff-backup --server\'''" + elif [ "$sourcetype" = "remote" ]; then + RDIFFBACKUP="$RDIFFBACKUP --remote-schema 'ssh %s \''rdiff-backup --server\'' | cstream -t $bwlimit'" + else + fatal "You specified a bandwidth limit but neither your source nor destination types are remote." + fi +fi + +### EXECUTE ### + +execstr="$RDIFFBACKUP $options --print-statistics " + +set -o noglob + +symlinks_warning="Maybe you have mixed symlinks and '*' in this statement, which is not supported." + +# 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 + [ "$i" != "/" ] || fatal "Sorry, you cannot use 'include = /'" + str="${i//__star__/*}" + execstr="${execstr}--include '$str' " +done + +# vsinclude +if [ $usevserver = yes ]; then + for vserver in $vsnames; do + for vi in $vsinclude; do + str="${vi//__star__/*}" + str="$VROOTDIR/$vserver$str" + if [ -n "$str" ]; then + execstr="${execstr}--include '$str' " + else + warning "vsinclude statement '${vi//__star__/*}' will be ignored for VServer $vserver. $symlinks_warning" + fi + done + done +fi + +set +o noglob + +# exclude everything else +execstr="${execstr}--exclude '/*' " + +# include client-part and server-part +execstr="${execstr}$execstr_sourcepart $execstr_destpart" + +debug "$execstr" +if [ $test = 0 ]; then + output=`nice -n $nicelevel su -c "$execstr" 2>&1` + if [ $? = 0 ]; then + debug $output + info "Successfully finished backing up source $label" + else + warning $output + warning "Failed backup up source $label" + fi +fi + +return 0 diff --git a/handlers/rsnap b/handlers/rsnap deleted file mode 100644 index 017a456..0000000 --- a/handlers/rsnap +++ /dev/null @@ -1,244 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- -# -# rsync backup handler for backupninja -# requires rsync and optional freedups -# -# freedups: -# http://www.stearns.org/freedups/ -# http://freshmeat.net/projects/freedups/ -# -# rsync: -# http://samba.anu.edu.au/rsync/ - -# exit on error -#set -e - -# System commands used by this script -# replace with absolute path's if neccecary -getconf rm rm -getconf cp cp -getconf touch touch -getconf mv mv -getconf ssh ssh -getconf tr tr -getconf rsync $RSYNC - -setsection options -getconf options -getconf label -getconf nicelevel 0 -getconf keep 60 - -setsection source -getconf testconnect no -getconf srchost localhost -getconf compress 1 -getconf sshoptions -getconf bandwidthlimit 1000 -getconf remote_rsync rsync -getconf numericids 1 -getconf include -getconf vsnames all -getconf vsinclude -getconf include -getconf exclude - -setsection dest -getconf directory -getconf enable_mv_timestamp_bug no -getconf freedups freedups -getconf enable_freedups no -getconf incremental yes - -# Apparently, a bug in some Linux kernels between 2.4.4 and 2.4.9 causes mv to update timestamps; -# this may result in inaccurate timestamps on the snapshot directories. -# Set enable_mv_timestamp_bug=1 to enable this workaround -if [ $enable_mv_timestamp_bug == "yes" ]; then - mv=my_mv -fi; - -function my_mv() { - ref=/tmp/makesnapshot-mymv-$$; - $touch -r $1 $ref; - $mv $1 $2; - $touch -r $ref $2; - $rm $ref; -} - -if [ $enable_freedups == "yes" ]; then - # $freedups - debug "Not implemented yet!" -fi; - - -[ "$directory" != "" ] || fatal "Destination directory not set" -[ "$include" != "" ] || fatal "No source includes specified" - -### vservers stuff ### - -# If vservers are configured, check that the ones listed in $vsnames do exist. -local usevserver=no -if [ $vservers_are_available = yes ]; then - if [ "$vsnames" = all ]; then - vsnames="$found_vservers" - else - if ! vservers_exist "$vsnames" ; then - fatal "At least one of the vservers listed in vsnames ($vsnames) does not exist." - fi - fi - if [ -n "$vsinclude" ]; then - info "Using vservers '$vsnames'" - usevserver=yes - fi -else - [ -z "$vsinclude" ] || warning 'vservers support disabled in backupninja.conf, vsincludes configuration lines will be ignored' - [ -z "$vsnames" ] || warning 'vservers support disabled in backupninja.conf, vsnames configuration line will be ignored' -fi - -### see if we can login ### - -if [ "$testconnect" == "yes" ]; then - debug "$ssh $sshoptions -o PasswordAuthentication=no $srchost 'echo -n 1'" - if [ ! $test ]; then - result=`ssh $sshoptions -o PasswordAuthentication=no $srchost 'echo -n 1'` - if [ "$result" != "1" ]; then - fatal "Can't connect to $srchost." - else - debug "Connected to $srchost successfully" - fi - fi -fi - -### COMMAND-LINE MANGLING ### - -[ "$bandwidthlimit" == 1000 ] || options="$options --bwlimit=$bandwidthlimit" -[ "$numericids" == 1 ] || options="$options --numeric-ids " -[ "$compress" == 1 ] || options="$options --compress " -[ "$remote_rsync" == "rsync" ] || options="$options --rsync-path=$remote_rsync" - -if [ "$nicelevel" -ne 0 ]; then - nice="nice -n $nicelevel" ; -else - nice=""; -fi - -execstr="$options --exclude '/' --delete-during --delete-excluded --archive $sshoptions " - -if [ "$incremental" == "no" ]; then - execstr="${execstr} --whole-file " -fi - -execstr_serverpart="$srchost:/" - - -### SOURCE ### - -set -o noglob - -# excludes -for i in $exclude; do - str="${i//__star__/*}" - #execstr="${execstr}--exclude '$str' " - execstr="${execstr}--exclude $str " -done - -# includes -for i in $include; do - str="${i//__star__/*}" - #execstr="${execstr}--include '$str' " - execstr="${execstr}--include $str " -done - -# vsincludes -if [ $usevserver = yes ]; then - for vserver in $vsnames; do - for vi in $vsinclude; do - str="${vi//__star__/*}" - execstr="${execstr}--include '$label/$vserver$str' " - done - done -fi - - -### SNAPSHOT ROTATION ### - -if [ "$incremental" == "yes" ]; then - debug "starting to rotate the old dirs" - # rotating snapshots - # delete the oldest snapshot, if it exists: - debug "does $directory/$label/$keep exist?" - if [ -d "$directory/$label/$keep" ] ; then - debug "$rm -rf $directory/$label/$keep" - if [ !$test ]; then - #$rm -rf "$directory/$label/$keep" ; - debug "$rm -rf $directory/$label/$keep"; - fi; - fi; - - # shift the snapshots(s) back by one, if they exist - for (( i=$keep; $i>=0; i--)) ; do - debug "does $directory/$label/$i exist?" - if [ -d "$directory/$label/$i" ] ; then - debug "$mv $directory/$label/$i $directory/$label/$(($i + 1))" - if [ !$test ]; then - $mv "$directory/$label/$i" "$directory/$label/$(($i + 1))" - fi; - fi; - done - - # make a hard-link-only (except for dirs) copy of - # assuming that exists, into the new dir - if [ -d "$directory/$label/1" ]; then - debug "$cp -al $directory/$label/1 $directory/$label/0" - if [ !$test ]; then - $cp -al $directory/$label/1 $directory/$label/0 ; - fi; - fi; - -fi - - -set +o noglob - -### EXECUTE ### - -# exclude everything else, start with root -#execstr="${execstr}--exclude '*' " - -# include client-part and server-part -#execstr="$execstr $execstr_serverpart" - -execstr=${execstr//\\*/\\\\\\*} - -if [ "$debug" == "1" ]; then - execstr=" --verbose $execstr"; - # execstr=" --verbose --dry-run $execstr"; -else - execstr=" --quiet $execstr"; -fi; - -debug "$rsync $execstr $execstr_serverpart $directory/$label/0" - - -# rsync from the system into the latest snapshot (notice that -# rsync behaves like cp --remove-destination by default, so the destination -# is unlinked first. If it were not so, this would copy over the other -# snapshot(s) too! -output=`$nice $rsync $execstr $execstr_serverpart $directory/$label/0 2>&1` -code=$? - -# update the mtime of the 0 dir to reflect the snapshot time -$touch $directory/$label/0 - -if [ $code -eq 0 ]; then - debug $output - info "rsync finished successfully."; -else - debug "returncode $code : $output " - #fatal "rsync failed."; - warning "rsync failed."; -fi; - - -return 0; - diff --git a/handlers/rsnap.in b/handlers/rsnap.in new file mode 100644 index 0000000..017a456 --- /dev/null +++ b/handlers/rsnap.in @@ -0,0 +1,244 @@ +# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- +# +# rsync backup handler for backupninja +# requires rsync and optional freedups +# +# freedups: +# http://www.stearns.org/freedups/ +# http://freshmeat.net/projects/freedups/ +# +# rsync: +# http://samba.anu.edu.au/rsync/ + +# exit on error +#set -e + +# System commands used by this script +# replace with absolute path's if neccecary +getconf rm rm +getconf cp cp +getconf touch touch +getconf mv mv +getconf ssh ssh +getconf tr tr +getconf rsync $RSYNC + +setsection options +getconf options +getconf label +getconf nicelevel 0 +getconf keep 60 + +setsection source +getconf testconnect no +getconf srchost localhost +getconf compress 1 +getconf sshoptions +getconf bandwidthlimit 1000 +getconf remote_rsync rsync +getconf numericids 1 +getconf include +getconf vsnames all +getconf vsinclude +getconf include +getconf exclude + +setsection dest +getconf directory +getconf enable_mv_timestamp_bug no +getconf freedups freedups +getconf enable_freedups no +getconf incremental yes + +# Apparently, a bug in some Linux kernels between 2.4.4 and 2.4.9 causes mv to update timestamps; +# this may result in inaccurate timestamps on the snapshot directories. +# Set enable_mv_timestamp_bug=1 to enable this workaround +if [ $enable_mv_timestamp_bug == "yes" ]; then + mv=my_mv +fi; + +function my_mv() { + ref=/tmp/makesnapshot-mymv-$$; + $touch -r $1 $ref; + $mv $1 $2; + $touch -r $ref $2; + $rm $ref; +} + +if [ $enable_freedups == "yes" ]; then + # $freedups + debug "Not implemented yet!" +fi; + + +[ "$directory" != "" ] || fatal "Destination directory not set" +[ "$include" != "" ] || fatal "No source includes specified" + +### vservers stuff ### + +# If vservers are configured, check that the ones listed in $vsnames do exist. +local usevserver=no +if [ $vservers_are_available = yes ]; then + if [ "$vsnames" = all ]; then + vsnames="$found_vservers" + else + if ! vservers_exist "$vsnames" ; then + fatal "At least one of the vservers listed in vsnames ($vsnames) does not exist." + fi + fi + if [ -n "$vsinclude" ]; then + info "Using vservers '$vsnames'" + usevserver=yes + fi +else + [ -z "$vsinclude" ] || warning 'vservers support disabled in backupninja.conf, vsincludes configuration lines will be ignored' + [ -z "$vsnames" ] || warning 'vservers support disabled in backupninja.conf, vsnames configuration line will be ignored' +fi + +### see if we can login ### + +if [ "$testconnect" == "yes" ]; then + debug "$ssh $sshoptions -o PasswordAuthentication=no $srchost 'echo -n 1'" + if [ ! $test ]; then + result=`ssh $sshoptions -o PasswordAuthentication=no $srchost 'echo -n 1'` + if [ "$result" != "1" ]; then + fatal "Can't connect to $srchost." + else + debug "Connected to $srchost successfully" + fi + fi +fi + +### COMMAND-LINE MANGLING ### + +[ "$bandwidthlimit" == 1000 ] || options="$options --bwlimit=$bandwidthlimit" +[ "$numericids" == 1 ] || options="$options --numeric-ids " +[ "$compress" == 1 ] || options="$options --compress " +[ "$remote_rsync" == "rsync" ] || options="$options --rsync-path=$remote_rsync" + +if [ "$nicelevel" -ne 0 ]; then + nice="nice -n $nicelevel" ; +else + nice=""; +fi + +execstr="$options --exclude '/' --delete-during --delete-excluded --archive $sshoptions " + +if [ "$incremental" == "no" ]; then + execstr="${execstr} --whole-file " +fi + +execstr_serverpart="$srchost:/" + + +### SOURCE ### + +set -o noglob + +# excludes +for i in $exclude; do + str="${i//__star__/*}" + #execstr="${execstr}--exclude '$str' " + execstr="${execstr}--exclude $str " +done + +# includes +for i in $include; do + str="${i//__star__/*}" + #execstr="${execstr}--include '$str' " + execstr="${execstr}--include $str " +done + +# vsincludes +if [ $usevserver = yes ]; then + for vserver in $vsnames; do + for vi in $vsinclude; do + str="${vi//__star__/*}" + execstr="${execstr}--include '$label/$vserver$str' " + done + done +fi + + +### SNAPSHOT ROTATION ### + +if [ "$incremental" == "yes" ]; then + debug "starting to rotate the old dirs" + # rotating snapshots + # delete the oldest snapshot, if it exists: + debug "does $directory/$label/$keep exist?" + if [ -d "$directory/$label/$keep" ] ; then + debug "$rm -rf $directory/$label/$keep" + if [ !$test ]; then + #$rm -rf "$directory/$label/$keep" ; + debug "$rm -rf $directory/$label/$keep"; + fi; + fi; + + # shift the snapshots(s) back by one, if they exist + for (( i=$keep; $i>=0; i--)) ; do + debug "does $directory/$label/$i exist?" + if [ -d "$directory/$label/$i" ] ; then + debug "$mv $directory/$label/$i $directory/$label/$(($i + 1))" + if [ !$test ]; then + $mv "$directory/$label/$i" "$directory/$label/$(($i + 1))" + fi; + fi; + done + + # make a hard-link-only (except for dirs) copy of + # assuming that exists, into the new dir + if [ -d "$directory/$label/1" ]; then + debug "$cp -al $directory/$label/1 $directory/$label/0" + if [ !$test ]; then + $cp -al $directory/$label/1 $directory/$label/0 ; + fi; + fi; + +fi + + +set +o noglob + +### EXECUTE ### + +# exclude everything else, start with root +#execstr="${execstr}--exclude '*' " + +# include client-part and server-part +#execstr="$execstr $execstr_serverpart" + +execstr=${execstr//\\*/\\\\\\*} + +if [ "$debug" == "1" ]; then + execstr=" --verbose $execstr"; + # execstr=" --verbose --dry-run $execstr"; +else + execstr=" --quiet $execstr"; +fi; + +debug "$rsync $execstr $execstr_serverpart $directory/$label/0" + + +# rsync from the system into the latest snapshot (notice that +# rsync behaves like cp --remove-destination by default, so the destination +# is unlinked first. If it were not so, this would copy over the other +# snapshot(s) too! +output=`$nice $rsync $execstr $execstr_serverpart $directory/$label/0 2>&1` +code=$? + +# update the mtime of the 0 dir to reflect the snapshot time +$touch $directory/$label/0 + +if [ $code -eq 0 ]; then + debug $output + info "rsync finished successfully."; +else + debug "returncode $code : $output " + #fatal "rsync failed."; + warning "rsync failed."; +fi; + + +return 0; + diff --git a/handlers/rub b/handlers/rub deleted file mode 100644 index bdd6e99..0000000 --- a/handlers/rub +++ /dev/null @@ -1,348 +0,0 @@ -# -# backupninja handler to do incremental backups using -# rsync and hardlinks, based on -# -# http://www.mikerubel.org/computers/rsync_snapshots/ -# -# feedback: rhatto at riseup.net | gpl -# lot of enhancements grabbed from "rsnap" handler by paulv at bikkel.org -# -# Config file options -# ------------------- -# -# [general] -# log = rsync log file -# partition = partition where the backup lives -# fscheck = set to 1 if fsck should run on $partition after the backup is made -# read_only = set to 1 if $partition is mounted read-only -# mountpoint = backup partition mountpoint or backup main folder -# backupdir = folder relative do $mountpoint where the backup should be stored -# days = number of backup increments (min = 5) -# lockfile = lockfile to be kept during backup execution -# enable_mv_timestamp_bug = set to "yes" if your system isnt handling timestamps correctly -# tmp = temp folder -# -# [source] -# from = local or remote -# testconnect = when "yes", test the connection for a remote source before backup -# include = include folder on backup -# exclude = exclude folder on backup -# ssh = ssh command line (remote only) -# rsync = rsync program -# rsync_options = rsync command options -# exclude_vserver = vserver-name (valid only if vservers = yes on backupninja.conf) -# numericids = when set to 1, use numeric ids instead of user/group mappings on rsync -# compress = if set to 1, compress data on rsync (remote source only) -# bandwidthlimit = set a badnwidth limit in kbps (remote source only) -# remote_rsync = remove rsync program (remote source only) -# -# [services] -# initscripts = absolute path where scripts are located -# service = script name to be stoped at the begining of the backup and started at its end -# -# You can also specify some system comands if you don't want the default system values: -# -# [system] -# rm = rm command -# cp = cp command -# touch = touch command -# mv = mv command -# fsck = fsck command -# -# You dont need to manually specify vservers using "include = /vservers". -# They are automatically backuped if vserver is set to "yes" on you backupninja.conf. -# - -# config file evaluation - -setsection system -getconf rm rm -getconf cp cp -getconf touch touch -getconf mv mv -getconf fsck fsck - -setsection general -getconf log /var/log/backupninja-rub.log -getconf partition -getconf fscheck -getconf read_only -getconf mountpoint -getconf backupdir -getconf rotate -getconf days -getconf lockfile -getconf nicelevel 0 -getconf enable_mv_timestamp_bug no -getconf tmp /tmp - -setsection source -getconf from local -getconf testconnect no -getconf rsync $RSYNC -getconf rsync_options "-av --delete" -getconf ssh ssh -getconf user -getconf host -getconf include -getconf exclude -getconf exclude_vserver -getconf numericids 0 -getconf compress 0 -getconf bandwidthlimit -getconf remote_rsync rsync - -setsection services -getconf initscripts -getconf service - -# function definitions - -function rotate { - - if [[ "$2" -lt 4 ]]; then - error "Rotate: minimum of 4 rotations" - exit 1 - fi - - if [ -d $1.$2 ]; then - $nice $mv /$1.$2 /$1.tmp - fi - - for ((n=`echo "$2 - 1" | bc`; n >= 0; n--)); do - if [ -d $1.$n ]; then - dest=`echo "$n + 1" | bc` - $nice $mv /$1.$n /$1.$dest - $touch /$1.$dest - fi - done - - if [ -d $1.tmp ]; then - $nice $mv /$1.tmp /$1.0 - fi - - if [ -d $1.1 ]; then - $nice $cp -alf /$1.1/. /$1.0 - fi - -} - -function move_files { - - ref=$tmp/makesnapshot-mymv-$$; - $touch -r $1 $ref; - $mv $1 $2; - $touch -r $ref $2; - $rm $ref; - -} - -backupdir="$mountpoint/$backupdir" - -# does $backupdir exists? - -if [ ! -d "$backupdir" ]; then - error "Backupdir $backupdir does not exist" - exit 1 -fi - -# setup number of increments - -if [ -z "$days" ]; then - keep="4" -else - keep="`echo $days - 1 | bc -l`" -fi - -# lockfile setup - -if [ ! -z "$lockfile" ]; then - $touch $lockfile || warning "Could not create lockfile $lockfile" -fi - -# nicelevel setup - -if [ ! -z "$nicelevel" ]; then - nice="nice -n $nicelevel" -else - nice="" -fi - -# connection test - -if [ "$from" == "remote" ] && [ "$testconnect" == "yes" ]; then - debug "$ssh -o PasswordAuthentication=no $user@$host 'echo -n 1'" - result=`ssh -o PasswordAuthentication=no $user@$host 'echo -n 1'` - if [ "$result" != "1" ]; then - fatal "Can't connect to $host as $user." - else - debug "Connected to $srchost successfully" - fi -fi - -# rsync options for local sources - -if [ "$from" == "local" ]; then - - rsync_local_options="$rsync_options" - - if [ ! -z "$numericids" ]; then - rsync_local_options="$rsync_local_options --numeric-ids " - fi - -fi - -# rsync options for remote sources - -if [ "$from" == "remote" ]; then - - rsync_remote_options="$rsync_options --rsync-path=$remote_rsync" - - if [ "$compress" == "1" ]; then - rsync_remote_options="$rsync_remote_options --compress" - fi - - if [ ! -z "$bandwidthlimit" ]; then - rsync_remote_options="$rsync_remote_options --bwlimit=$bandwidthlimit" - fi - - if [ ! -z "$numericids" ]; then - rsync_remote_options="$rsync_remote_options --numeric-ids" - fi - -fi - -# set mv procedure - -if [ $enable_mv_timestamp_bug == "yes" ]; then - mv=move_files -fi - -# set excludes - -for path in $exclude; do - EXCLUDES="$EXCLUDES --exclude=$path" -done - -# stop services - -if [ ! -z "$service" ]; then - for daemon in $service; do - info "Stopping service $daemon..." - $initscripts/$daemon stop - done -fi - -echo "Starting backup at `date`" >> $log - -# mount backup destination folder as read-write - -if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then - if [ -d "$mountpoint" ]; then - mount -o remount,rw $mountpoint - if (($?)); then - error "Could not mount $mountpoint" - exit 1 - fi - fi -fi - -# add vservers to included folders - -if [ "$vservers_are_available" == "yes" ]; then - - # sane permission on backup - mkdir -p $backupdir/$VROOTDIR - chmod 000 $backupdir/$VROOTDIR - - for candidate in $found_vservers; do - candidate="`basename $candidate`" - found_excluded_vserver="0" - for excluded_vserver in $exclude_vserver; do - if [ "$excluded_vserver" == "$candidate" ]; then - found_excluded_vserver="1" - break - fi - done - if [ "$found_excluded_vserver" == "0" ]; then - include="$include $VROOTDIR/$candidate" - fi - done -fi - -# the backup procedure - -for SECTION in $include; do - - section="`basename $SECTION`" - - if [ ! -d "$backupdir/$SECTION/$section.0" ]; then - mkdir -p $backupdir/$SECTION/$section.0 - fi - - info "Rotating $backupdir/$SECTION/$section..." - echo "Rotating $backupdir/$SECTION/$section..." >> $log - rotate $backupdir/$SECTION/$section $keep - info "Syncing $SECTION on $backupdir/$SECTION/$section.0..." - - if [ "$from" == "local" ]; then - debug $rsync $rsync_local_options $EXCLUDES /$SECTION/ $backupdir/$SECTION/$section.0/ - $nice $rsync $rsync_local_options $EXCLUDES /$SECTION/ $backupdir/$SECTION/$section.0/ >> $log - if [ "$?" != "0" ]; then - warning "Rsync error when trying to transfer $SECTION" - fi - elif [ "$from" == "remote" ]; then - if [ -z "$user" ] || [ -z "$host" ]; then - error "Config file error: either user or host was not specified" - exit 1 - else - debug $nice $rsync $rsync_remote_options $EXCLUDES -e "$ssh" $user@$host:/$SECTION/ $backupdir/$SECTION/$section.0 - $nice $rsync $rsync_remote_options $EXCLUDES -e "$ssh" $user@$host:/$SECTION/ $backupdir/$SECTION/$section.0 >> $log - if [ "$?" != "0" ]; then - warning "Rsync error when trying to transfer $SECTION" - fi - fi - else - error "Invalid source $from" - exit 1 - fi - - $touch $backupdir/$SECTION/$section.0 - -done - -# remount backup destination as read-only - -if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then - mount -o remount,ro $mountpoint -fi - -# check partition for errors - -if [ "$fscheck" == "1" ] || [ "$fscheck" == "yes" ]; then - umount $mountpoint - if (($?)); then - warning "Could not umount $mountpoint to run fsck" - else - $nice $fsck -v -y $partition >> $log - mount $mountpoint - fi -fi - -# restart services - -if [ ! -z "$service" ]; then - for daemon in $service; do - info "Starting service $daemon..." - $initscripts/$daemon start - done -fi - -# removes the lockfile - -if [ ! -z "$lockfile" ]; then - $rm $lockfile || warning "Could not remove lockfile $lockfile" -fi - -echo "Finnishing backup at `date`" >> $log - diff --git a/handlers/rub.in b/handlers/rub.in new file mode 100644 index 0000000..bdd6e99 --- /dev/null +++ b/handlers/rub.in @@ -0,0 +1,348 @@ +# +# backupninja handler to do incremental backups using +# rsync and hardlinks, based on +# +# http://www.mikerubel.org/computers/rsync_snapshots/ +# +# feedback: rhatto at riseup.net | gpl +# lot of enhancements grabbed from "rsnap" handler by paulv at bikkel.org +# +# Config file options +# ------------------- +# +# [general] +# log = rsync log file +# partition = partition where the backup lives +# fscheck = set to 1 if fsck should run on $partition after the backup is made +# read_only = set to 1 if $partition is mounted read-only +# mountpoint = backup partition mountpoint or backup main folder +# backupdir = folder relative do $mountpoint where the backup should be stored +# days = number of backup increments (min = 5) +# lockfile = lockfile to be kept during backup execution +# enable_mv_timestamp_bug = set to "yes" if your system isnt handling timestamps correctly +# tmp = temp folder +# +# [source] +# from = local or remote +# testconnect = when "yes", test the connection for a remote source before backup +# include = include folder on backup +# exclude = exclude folder on backup +# ssh = ssh command line (remote only) +# rsync = rsync program +# rsync_options = rsync command options +# exclude_vserver = vserver-name (valid only if vservers = yes on backupninja.conf) +# numericids = when set to 1, use numeric ids instead of user/group mappings on rsync +# compress = if set to 1, compress data on rsync (remote source only) +# bandwidthlimit = set a badnwidth limit in kbps (remote source only) +# remote_rsync = remove rsync program (remote source only) +# +# [services] +# initscripts = absolute path where scripts are located +# service = script name to be stoped at the begining of the backup and started at its end +# +# You can also specify some system comands if you don't want the default system values: +# +# [system] +# rm = rm command +# cp = cp command +# touch = touch command +# mv = mv command +# fsck = fsck command +# +# You dont need to manually specify vservers using "include = /vservers". +# They are automatically backuped if vserver is set to "yes" on you backupninja.conf. +# + +# config file evaluation + +setsection system +getconf rm rm +getconf cp cp +getconf touch touch +getconf mv mv +getconf fsck fsck + +setsection general +getconf log /var/log/backupninja-rub.log +getconf partition +getconf fscheck +getconf read_only +getconf mountpoint +getconf backupdir +getconf rotate +getconf days +getconf lockfile +getconf nicelevel 0 +getconf enable_mv_timestamp_bug no +getconf tmp /tmp + +setsection source +getconf from local +getconf testconnect no +getconf rsync $RSYNC +getconf rsync_options "-av --delete" +getconf ssh ssh +getconf user +getconf host +getconf include +getconf exclude +getconf exclude_vserver +getconf numericids 0 +getconf compress 0 +getconf bandwidthlimit +getconf remote_rsync rsync + +setsection services +getconf initscripts +getconf service + +# function definitions + +function rotate { + + if [[ "$2" -lt 4 ]]; then + error "Rotate: minimum of 4 rotations" + exit 1 + fi + + if [ -d $1.$2 ]; then + $nice $mv /$1.$2 /$1.tmp + fi + + for ((n=`echo "$2 - 1" | bc`; n >= 0; n--)); do + if [ -d $1.$n ]; then + dest=`echo "$n + 1" | bc` + $nice $mv /$1.$n /$1.$dest + $touch /$1.$dest + fi + done + + if [ -d $1.tmp ]; then + $nice $mv /$1.tmp /$1.0 + fi + + if [ -d $1.1 ]; then + $nice $cp -alf /$1.1/. /$1.0 + fi + +} + +function move_files { + + ref=$tmp/makesnapshot-mymv-$$; + $touch -r $1 $ref; + $mv $1 $2; + $touch -r $ref $2; + $rm $ref; + +} + +backupdir="$mountpoint/$backupdir" + +# does $backupdir exists? + +if [ ! -d "$backupdir" ]; then + error "Backupdir $backupdir does not exist" + exit 1 +fi + +# setup number of increments + +if [ -z "$days" ]; then + keep="4" +else + keep="`echo $days - 1 | bc -l`" +fi + +# lockfile setup + +if [ ! -z "$lockfile" ]; then + $touch $lockfile || warning "Could not create lockfile $lockfile" +fi + +# nicelevel setup + +if [ ! -z "$nicelevel" ]; then + nice="nice -n $nicelevel" +else + nice="" +fi + +# connection test + +if [ "$from" == "remote" ] && [ "$testconnect" == "yes" ]; then + debug "$ssh -o PasswordAuthentication=no $user@$host 'echo -n 1'" + result=`ssh -o PasswordAuthentication=no $user@$host 'echo -n 1'` + if [ "$result" != "1" ]; then + fatal "Can't connect to $host as $user." + else + debug "Connected to $srchost successfully" + fi +fi + +# rsync options for local sources + +if [ "$from" == "local" ]; then + + rsync_local_options="$rsync_options" + + if [ ! -z "$numericids" ]; then + rsync_local_options="$rsync_local_options --numeric-ids " + fi + +fi + +# rsync options for remote sources + +if [ "$from" == "remote" ]; then + + rsync_remote_options="$rsync_options --rsync-path=$remote_rsync" + + if [ "$compress" == "1" ]; then + rsync_remote_options="$rsync_remote_options --compress" + fi + + if [ ! -z "$bandwidthlimit" ]; then + rsync_remote_options="$rsync_remote_options --bwlimit=$bandwidthlimit" + fi + + if [ ! -z "$numericids" ]; then + rsync_remote_options="$rsync_remote_options --numeric-ids" + fi + +fi + +# set mv procedure + +if [ $enable_mv_timestamp_bug == "yes" ]; then + mv=move_files +fi + +# set excludes + +for path in $exclude; do + EXCLUDES="$EXCLUDES --exclude=$path" +done + +# stop services + +if [ ! -z "$service" ]; then + for daemon in $service; do + info "Stopping service $daemon..." + $initscripts/$daemon stop + done +fi + +echo "Starting backup at `date`" >> $log + +# mount backup destination folder as read-write + +if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then + if [ -d "$mountpoint" ]; then + mount -o remount,rw $mountpoint + if (($?)); then + error "Could not mount $mountpoint" + exit 1 + fi + fi +fi + +# add vservers to included folders + +if [ "$vservers_are_available" == "yes" ]; then + + # sane permission on backup + mkdir -p $backupdir/$VROOTDIR + chmod 000 $backupdir/$VROOTDIR + + for candidate in $found_vservers; do + candidate="`basename $candidate`" + found_excluded_vserver="0" + for excluded_vserver in $exclude_vserver; do + if [ "$excluded_vserver" == "$candidate" ]; then + found_excluded_vserver="1" + break + fi + done + if [ "$found_excluded_vserver" == "0" ]; then + include="$include $VROOTDIR/$candidate" + fi + done +fi + +# the backup procedure + +for SECTION in $include; do + + section="`basename $SECTION`" + + if [ ! -d "$backupdir/$SECTION/$section.0" ]; then + mkdir -p $backupdir/$SECTION/$section.0 + fi + + info "Rotating $backupdir/$SECTION/$section..." + echo "Rotating $backupdir/$SECTION/$section..." >> $log + rotate $backupdir/$SECTION/$section $keep + info "Syncing $SECTION on $backupdir/$SECTION/$section.0..." + + if [ "$from" == "local" ]; then + debug $rsync $rsync_local_options $EXCLUDES /$SECTION/ $backupdir/$SECTION/$section.0/ + $nice $rsync $rsync_local_options $EXCLUDES /$SECTION/ $backupdir/$SECTION/$section.0/ >> $log + if [ "$?" != "0" ]; then + warning "Rsync error when trying to transfer $SECTION" + fi + elif [ "$from" == "remote" ]; then + if [ -z "$user" ] || [ -z "$host" ]; then + error "Config file error: either user or host was not specified" + exit 1 + else + debug $nice $rsync $rsync_remote_options $EXCLUDES -e "$ssh" $user@$host:/$SECTION/ $backupdir/$SECTION/$section.0 + $nice $rsync $rsync_remote_options $EXCLUDES -e "$ssh" $user@$host:/$SECTION/ $backupdir/$SECTION/$section.0 >> $log + if [ "$?" != "0" ]; then + warning "Rsync error when trying to transfer $SECTION" + fi + fi + else + error "Invalid source $from" + exit 1 + fi + + $touch $backupdir/$SECTION/$section.0 + +done + +# remount backup destination as read-only + +if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then + mount -o remount,ro $mountpoint +fi + +# check partition for errors + +if [ "$fscheck" == "1" ] || [ "$fscheck" == "yes" ]; then + umount $mountpoint + if (($?)); then + warning "Could not umount $mountpoint to run fsck" + else + $nice $fsck -v -y $partition >> $log + mount $mountpoint + fi +fi + +# restart services + +if [ ! -z "$service" ]; then + for daemon in $service; do + info "Starting service $daemon..." + $initscripts/$daemon start + done +fi + +# removes the lockfile + +if [ ! -z "$lockfile" ]; then + $rm $lockfile || warning "Could not remove lockfile $lockfile" +fi + +echo "Finnishing backup at `date`" >> $log + diff --git a/handlers/sh b/handlers/sh deleted file mode 100644 index f9f1926..0000000 --- a/handlers/sh +++ /dev/null @@ -1,7 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- -# -# shell script handler for backupninja -# runs the file /etc/backup.d/scriptname.sh -# - -[ $test ] || ( . $1 ) diff --git a/handlers/sh.in b/handlers/sh.in new file mode 100644 index 0000000..f9f1926 --- /dev/null +++ b/handlers/sh.in @@ -0,0 +1,7 @@ +# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- +# +# shell script handler for backupninja +# runs the file /etc/backup.d/scriptname.sh +# + +[ $test ] || ( . $1 ) diff --git a/handlers/svn b/handlers/svn deleted file mode 100644 index 377d71c..0000000 --- a/handlers/svn +++ /dev/null @@ -1,80 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- -# -# this handler will backup subversion repostitories. -# - -getconf src /var/lib/svn -getconf dest /var/backups/svn -getconf tmp /var/backups/svn.tmp -getconf HOTBACKUP "/usr/bin/svnadmin hotcopy" -getconf vsname - -error=0 - -# Decide if the handler should operate on a vserver or on the host. -# In the former case, check that $vsname exists and is running. -local usevserver=no -local vroot -if [ $vservers_are_available = yes ]; then - if [ -n "$vsname" ]; then - # does it exist ? - if ! vservers_exist "$vsname" ; then - fatal "The vserver given in vsname ($vsname) does not exist." - fi - # is it running ? - $VSERVERINFO -q $vsname RUNNING - if [ $? -ne 0 ]; then - fatal "The vserver $vsname is not running." - fi - # everything ok - info "Using vserver '$vsname'." - usevserver=yes - vroot="$VROOTDIR/$vsname" - else - info "No vserver name specified, actions will be performed on the host." - fi -fi - -cd $vroot$src -for repo in `find . -name svnserve.conf` -do - repo=`dirname $repo` - repo=`dirname $repo` - - ret=`mkdir -p $vroot$tmp/$repo 2>&1` - code=$? - if [ "$ret" ]; then - debug "$ret" - fi - if [ $code != 0 ]; then - error "command failed mkdir -p $vroot$tmp/$repo" - fi - - if [ $usevserver = yes ] - then - ret=`$VSERVER $vsname exec $HOTBACKUP $src/$repo $tmp/$repo 2>&1` - else - ret=`$HOTBACKUP $src/$repo $tmp/$repo 2>&1` - fi - code=$? - if [ "$ret" ]; then - debug "$ret" - fi - if [ $code != 0 ]; then - error "command failed -- $HOTBACKUP $vroot$src/$repo $vroot$tmp/$repo" - error=1 - fi -done - -if [ $error -eq 1 ]; then - echo "Error: because of earlier errors, we are leaving svn backups in $vroot$tmp instead of $vroot$dest" -else - if [ -d $vroot$dest -a -d $vroot$tmp ]; then - rm -rf $vroot$dest - fi - if [ -d $vroot$tmp ]; then - mv $vroot$tmp $vroot$dest - fi -fi - -exit 0 diff --git a/handlers/svn.in b/handlers/svn.in new file mode 100644 index 0000000..377d71c --- /dev/null +++ b/handlers/svn.in @@ -0,0 +1,80 @@ +# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- +# +# this handler will backup subversion repostitories. +# + +getconf src /var/lib/svn +getconf dest /var/backups/svn +getconf tmp /var/backups/svn.tmp +getconf HOTBACKUP "/usr/bin/svnadmin hotcopy" +getconf vsname + +error=0 + +# Decide if the handler should operate on a vserver or on the host. +# In the former case, check that $vsname exists and is running. +local usevserver=no +local vroot +if [ $vservers_are_available = yes ]; then + if [ -n "$vsname" ]; then + # does it exist ? + if ! vservers_exist "$vsname" ; then + fatal "The vserver given in vsname ($vsname) does not exist." + fi + # is it running ? + $VSERVERINFO -q $vsname RUNNING + if [ $? -ne 0 ]; then + fatal "The vserver $vsname is not running." + fi + # everything ok + info "Using vserver '$vsname'." + usevserver=yes + vroot="$VROOTDIR/$vsname" + else + info "No vserver name specified, actions will be performed on the host." + fi +fi + +cd $vroot$src +for repo in `find . -name svnserve.conf` +do + repo=`dirname $repo` + repo=`dirname $repo` + + ret=`mkdir -p $vroot$tmp/$repo 2>&1` + code=$? + if [ "$ret" ]; then + debug "$ret" + fi + if [ $code != 0 ]; then + error "command failed mkdir -p $vroot$tmp/$repo" + fi + + if [ $usevserver = yes ] + then + ret=`$VSERVER $vsname exec $HOTBACKUP $src/$repo $tmp/$repo 2>&1` + else + ret=`$HOTBACKUP $src/$repo $tmp/$repo 2>&1` + fi + code=$? + if [ "$ret" ]; then + debug "$ret" + fi + if [ $code != 0 ]; then + error "command failed -- $HOTBACKUP $vroot$src/$repo $vroot$tmp/$repo" + error=1 + fi +done + +if [ $error -eq 1 ]; then + echo "Error: because of earlier errors, we are leaving svn backups in $vroot$tmp instead of $vroot$dest" +else + if [ -d $vroot$dest -a -d $vroot$tmp ]; then + rm -rf $vroot$dest + fi + if [ -d $vroot$tmp ]; then + mv $vroot$tmp $vroot$dest + fi +fi + +exit 0 diff --git a/handlers/sys b/handlers/sys deleted file mode 100755 index 2e181c8..0000000 --- a/handlers/sys +++ /dev/null @@ -1,498 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- -# -# this handler will save various reports of vital system information. -# by default, all the reports are enabled and are saved in /var/backups. -# -# (1) a list of all the packages installed and removed. -# this file can be used to restore the state of installed packages -# by running "dpkg --set-selections < dpkg-selections.txt -# -# (2) the partition table of all disks. -# this partition table can be used to format another disk of -# the same size. this can be handy if using software raid and -# you have a disk go bad. just replace the disk and partition it -# by running "sfdisk /dev/sdb < partitions.sdb.txt" -# (MAKE SURE YOU PARTITION THE CORRECT DISK!!!) -# -# (3) hardware information. -# write to a text file the important things which hwinfo can gleen. -# - -if [ -f /etc/debian_version ] -then - os=debian - debug "Debian detected" - osversion="/etc/debian_version" -elif [ -f /etc/redhat-release ] -then - os=redhat - debug "Redhat detected" - osversion="/etc/redhat-release" -else - warning "Unknown OS detected!" -fi - -getconf packages yes -getconf dosfdisk yes -getconf dohwinfo yes -if [ $os = "debian" ] -then - getconf packagesfile /var/backups/dpkg-selections.txt - getconf packagemgr `which dpkg` - getconf packagemgroptions ' --get-selections *' -elif [ $os = "redhat" ] -then - getconf packagesfile /var/backups/rpmpackages.txt - getconf packagemgr `which rpm` - getconf packagemgroptions ' -qa ' - - getconf SYSREPORT `which sysreport` - getconf sysreport_options ' -norpm ' -else - getconf packagesfile /var/backups/unknownOS.txt -fi -packagemgroptions="${packagemgroptions//__star__/*}" - -getconf partitions yes -getconf partitionsfile /var/backups/partitions.__star__.txt - -getconf hardware yes -getconf hardwarefile /var/backups/hardware.txt - -getconf sysreport yes -getconf sysreportfile /var/backups/sysreport.txt - -getconf SFDISK `which sfdisk` -getconf HWINFO `which hwinfo` -getconf sfdisk_options "" -getconf hwinfo_options "" - -# See if vservers are configured -local usevserver=no -if [ $vservers_are_available = yes ] -then - info "vserver method enabled" - usevserver=yes -fi - -## PACKAGES ############################## - -# -# here we grab a list of the packages installed and removed. -# - -if [ "$packages" == "yes" ]; then - - if [ $usevserver = yes ]; then - info "vserver root directory set to: $VROOTDIR" - for vserver in $found_vservers; do - info "examining vserver: $vserver" - # is it running ? - $VSERVERINFO -q $vserver RUNNING - if [ $? -ne 0 ]; then - warning "The vserver $vserver is not running." - continue - fi - # is $packagemgr available inside $vserver ? - if [ ! -x "$VROOTDIR/$vserver`$VSERVER $vserver exec which $packagemgr`" ]; then - warning "can't find $packagemgr in vserver $vserver, skipping installed packages report." - continue - fi - # don't expand * since it can be used in $packagemgroptions - set -o noglob - debug "$VSERVER $vserver exec $packagemgr $packagemgroptions > $VROOTDIR/$vserver$packagesfile" - $VSERVER $vserver exec $packagemgr $packagemgroptions > $VROOTDIR/$vserver$packagesfile || fatal "can not save $packagemgr info to $packagesfile" - set +o noglob - done - fi - - # We want to perform this on the host as well - if [ -z "$packagemgr" -o ! -x "$packagemgr" ]; then - warning "can't find ${packagemgr}, skipping installed packages report." - else - # don't expand * since it can be used in $packagemgroptions - set -o noglob - debug "$packagemgr $packagemgroptions > $packagesfile" - $packagemgr $packagemgroptions > $packagesfile || fatal "can not save $packagemgr info to $packagesfile" - set +o noglob - fi - -fi - -## System report ############################## - -# -# here we grab a bunch of system stuff for a report -# - -export STATUS - -HASHES="#################################################################" -DASHES="-----------------------------------------------------------------" - -cat /dev/null > $sysreportfile || fatal "can not write to $sysreportfile" - - -catiffile () { - echo $HASHES >> $sysreportfile - echo "# $STATUS" >> $sysreportfile - echo $HASHES >> $sysreportfile - if [ -f $1 ]; then - echo "file: $1" >> $sysreportfile - echo $DASHES >> $sysreportfile - cat $1 >> $sysreportfile 2>&1 || info "reading of $1 failed" - fi - if [ -d $1 ]; then - echo "directory: $1" >> $sysreportfile - echo $DASHES >> $sysreportfile - for file in `find $1 -maxdepth 3 -noleaf -type f` - do - catiffile $file - done - fi - echo $DASHES >> $sysreportfile -} - -catifexec () { - echo $HASHES >> $sysreportfile - echo "# $STATUS" >> $sysreportfile - echo $HASHES >> $sysreportfile - $1 >> $sysreportfile 2>&1 || info "executing of $1 failed" -} - - -STATUS="Determining $os version:" -catiffile $osversion - -STATUS="Determinding your current hostname: " -catifexec "/bin/hostname" - -STATUS="Getting the date:" -catifexec "/bin/date" - -STATUS="Checking your systems current uptime and load average:" -catifexec "/usr/bin/uptime" - -STATUS="Checking available memory:" -catifexec "/usr/bin/free" - -STATUS="Checking free disk space:" -catifexec "/bin/df" "-al" - -STATUS="Collecting what services run at what run level:" -if [ $os = "redhat" ]; then - catifexec "/sbin/chkconfig --list" - STATUS="Collecting information about /etc/rc.d:" - catiffile "/bin/ls /etc/rc.d/rc*.d/" - -elif [ $os = "debian" ]; then - for level in 0 1 2 3 4 5 6 S; do - echo "Level: $level" >> $sysreportfile - for f in /etc/rc${level}.d/*; do - # Remove /etc/Knn or Snn from beginning - ff=$(echo $f | @SED@ 's_/etc/rc..d/[KS][0-9][0-9]__') - if [ $f != $ff ]; then - echo $ff >> $sysreportfile - fi - done - echo "" >> $sysreportfile - done -fi - -STATUS="Getting bootloader information:" -catifexec "/bin/ls -alR /boot" - -# This covers sparc, alpha, and intel (respectively) -# updated for grub -mpg -if [ -f /etc/silo.conf ]; then - STATUS="Collecting information about the boot process (silo):" - catiffile "/etc/silo.conf" -fi -if [ -f /etc/milo.conf ]; then - STATUS="Collecting information about the boot process (milo):" - catiffile "/etc/milo.conf" -fi -if [ -f /etc/lilo.conf ]; then - STATUS="Collecting information about the boot process (lilo):" - catiffile "/etc/lilo.conf" - catifexec "/sbin/lilo -q" -fi -if [ -d /boot/grub -a -f /boot/grub/grub.conf -a -f /boot/grub/device.map ]; then - STATUS="Collecting information about the boot process (grub.conf):" - catiffile "/boot/grub/grub.conf" - STATUS="Collecting information about the boot process (grub.map):" - catiffile "/boot/grub/device.map" -fi -if [ -f /etc/cluster.conf -o -f /etc/cluster.xml ] ; then - STATUS="Gathering information on cluster setup" - # 2.1 AS - if [ -f /etc/cluster.conf ] ; then - catiffile "/etc/cluster.conf" - fi - # Taroon - if [ -f /etc/cluster.xml ] ; then - catiffile "/etc/cluster.xml" - fi -fi - -STATUS="Gathering sysctl information (sysctl -a):" -catiffile "sysctl -a 2>/dev/null" -STATUS="Gathering sysctl information (/etc/sysctl.conf):" -catiffile "/etc/sysctl.conf" - -STATUS="Gathering IP information (/sbin/ifconfig):" -catifexec "/sbin/ifconfig -a" - -STATUS="Gathering additional IP information (/bin/ip addr list):" -catifexec "/bin/ip addr list" - -STATUS="Checking network routes:" -catifexec "/sbin/route -n" - -STATUS="Collecting Name Service Switch config information:" -catiffile "/etc/nsswitch.conf" - -STATUS="Collecting information about system authentication (pam):" -catiffile "/etc/pam.conf" -catiffile "/etc/pam.d" - -echo -echo "Getting information about the kernel." -echo -STATUS="Getting kernel version:" -catifexec "/bin/uname" "-a" -STATUS="Checking module information:" -catifexec "/sbin/lsmod" -for x in $(/sbin/lsmod | /bin/cut -f1 -d" " 2>/dev/null | /bin/grep -v Module 2>/dev/null -) ; do - STATUS="Checking module information $x:" - catifexec "/sbin/modinfo $x" -done - -STATUS="Currently getting ksysms information:" -catifexec "/sbin/ksyms" - -STATUS="Gathering information about your filesystems:" -catiffile "/proc/filesystems" - -STATUS="Gathering information about your system stat:" -catiffile "/proc/stat" - -STATUS="Gathering information about your partitions:" -catiffile "/proc/partitions" - -STATUS="Gathering information about your ksyms:" -catiffile "/proc/ksyms" - -STATUS="Gathering information about slabinfo:" -catiffile "/proc/slabinfo" - -# Added support to cover for the new modules.conf layout in Red Hat 7 -STATUS="Collecting information regarding kernel modules" -VER=`uname -r` -catiffile "/lib/modules/$VER/modules.dep" -if [ -f /etc/conf.modules ]; then - STATUS="Collecting information regarding kernel modules (conf.modules)" - catiffile "/etc/conf.modules" -fi -if [ -f /etc/modules.conf ]; then - STATUS="Collecting information regarding kernel modules (modules.conf)" - catiffile "/etc/modules.conf" -fi -if [ -f /etc/modprobe.conf ]; then - STATUS="Collecting information regarding kernel modules (modeprobe.conf)" - catiffile "/etc/modprobe.conf" -fi - -# dkms status -if [ -x /usr/sbin/dkms ] ; then - STATUS="Gathering current status of modules, versions and kernels (dkms):" - catifexec "/usr/sbin/dkms" "status" -fi - -if [ -f /etc/sysconfig/isdncard ] ; then - STATUS="Gathering information about ISDN:" - catiffile "/etc/sysconfig/isdncard" -fi - -STATUS="Collecting information from the proc directory:" -catiffile "/proc/pci" - -STATUS="Getting kernel command line" -catiffile "/proc/cmdline" - -STATUS="Gathering information about your CPU:" -catiffile "/proc/cpuinfo" - -STATUS="Gathering information about your Ram:" -catiffile "/proc/meminfo" - -STATUS="Gathering information about your ioports:" -catiffile "/proc/ioports" - -STATUS="Gathering information about your interrupts:" -catiffile "/proc/interrupts" - -STATUS="Gathering information about your scsi devices:" -catiffile "/proc/scsi" - -STATUS="Gathering information about your dma:" -catiffile "/proc/dma" - -STATUS="Gathering information about your devices (/proc/devices):" -catiffile "/proc/devices" - -STATUS="Gathering information about your rtc:" -catiffile "/proc/rtc" - -STATUS="Gathering information about your ide drivers:" -catiffile "/proc/ide" - -STATUS="Gathering information about your bus:" -catifexec lspci -catiffile "/proc/bus" - -echo -echo "Getting disk and filesystem information." -echo - -STATUS="Collecting information from /etc/fstab:" -catiffile "/etc/fstab" - -STATUS="Collecting disk partition information:" -catifexec "fdisk -l" - -STATUS="Checking mounted file systems (mount) " -catifexec "/bin/mount" - -STATUS="Checking mounted file systems (/proc/mounts)" -catiffile "/proc/mounts" - -STATUS="Collecting Software RAID information (/proc/mdstat)" -catiffile "/proc/mdstat" - -STATUS="Collecting Software RAID information (/etc/raidtab)" -catiffile "/etc/raidtab" - -STATUS="Collecting Software RAID information (/etc/mdadm.conf)" -catiffile "/etc/mdadm.conf" - -STATUS="Collecting Automount information (auto.master)" -catiffile "/etc/auto.master" - -STATUS="Collecting Automount information (auto.misc)" -catiffile "/etc/auto.misc" - -STATUS="Collecting Automount information (auto.net)" -catiffile "/etc/auto.net" - -STATUS="Collecting LVM information:" -if [ $os = "redhat" ]; then - catifexec "/usr/sbin/vgdisplay" "-vv" -elif [ $os = "debian" ]; then - catifexec "/sbin/vgdisplay" "-vv" -fi - -STATUS="Collecting SCSI Tape information (/etc/stinit.def)" -catiffile "/etc/stinit.def" - -if [ -x /sbin/lsusb ] ; then - STATUS="Collecting USB devices list (lsusb):" - catifexec "/sbin/lsusb" -fi - -if [ -x /usr/bin/lshal ] ; then - STATUS="Collecting global devices list (lshal):" - catifexec "/usr/bin/lshal" -fi - - -STATUS="Gathering information on SELinux setup" -catifexec "/usr/bin/selinuxconfig" -catifexec "/usr/sbin/sestatus" -if [ $os = "redhat" ]; then - catifexec "rpm" "-q -V selinux-policy-targeted" - catifexec "rpm" "-q -V selinux-policy-strict" -fi - -if [ $usevserver = yes ]; then - STATUS="Gathering vserver information" - catiffile "/proc/virtual" -fi - -if [ "$partitions" == "yes" ]; then - if [ "$dosfdisk" == "yes" ]; then - if [ ! -x "$SFDISK" ]; then - warning "can't find sfdisk, skipping sfdisk report." - partitions="no" - fi - fi - if [ "$dohwinfo" == "yes" ]; then - if [ ! -x "$HWINFO" ]; then - warning "can't find hwinfo, skipping partition report." - partitions="no" - fi - fi -fi - -if [ "$hardware" == "yes" ]; then - if [ ! -x "$HWINFO" ]; then - warning "can't find hwinfo, skipping hardware report." - hardware="no" - fi -fi - -## HARDWARE ############################# - -# -# here we use hwinfo to dump a table listing all the -# information we can find on the hardware of this machine -# - -if [ "$hardware" == "yes" ]; then - if [ "dohwinfo" == "yes" ]; then - if [ -f $hardwarefile ]; then - rm $hardwarefile - fi - touch $hardwarefile - echo -e "\n\n====================== summary ======================\n" >> $hardwarefile - debug "$HWINFO --short --cpu --network --disk --pci >> $hardwarefile" - $HWINFO --short --cpu --network --disk --pci >> $hardwarefile - for flag in cpu network bios pci; do - echo -e "\n\n====================== $flag ======================\n" >> $hardwarefile - $HWINFO --$flag >> $hardwarefile - done - fi -fi - - -## PARTITIONS ############################# - -# here we use sfdisk to dump a listing of all the partitions. -# these files can be used to directly partition a disk of the same size. - -if [ "$partitions" == "yes" ]; then - if [ "$dosfdisk" == "yes" ]; then - devices=`LC_ALL=C $SFDISK -l 2>/dev/null | grep "^Disk /dev" | @AWK@ '{print $2}' | cut -d: -f1` - if [ "$devices" == "" ]; then - warning "No harddisks found" - fi - for dev in $devices; do - debug "$SFDISK will try to backup partition tables for device $dev" - [ -b $dev ] || continue - label=${dev#/dev/} - label=${label//\//-} - outputfile=${partitionsfile//__star__/$label} - debug "$SFDISK $sfdisk_options -d $dev > $outputfile 2>/dev/null" - $SFDISK $sfdisk_options -d $dev > $outputfile 2>/dev/null - if [ $? -ne 0 ]; then - warning "The partition table for $dev could not be saved." - fi - done - fi - if [ "$dohwinfo" == "yes" ]; then - debug "Using $HWINFO to get all available disk information" - echo -e "\n\n====================== $disk ======================\n" >> $hardwarefile - $HWINFO --disk >> $hardwarefile - fi -fi diff --git a/handlers/sys.helper b/handlers/sys.helper deleted file mode 100644 index 6451ae2..0000000 --- a/handlers/sys.helper +++ /dev/null @@ -1,38 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- - -HELPERS="$HELPERS sys:general_hardware_and_system_info" - -sys_wizard() { - require_packages hwinfo - checkBox "new sys action" "check options" \ - "packages" "list of all installed packages." on \ - "partitions" "the partition table of all disks." on \ - "sfdisk" "use sfdisk to get partition information." on \ - "hardware" "detailed hardware information" on - [ $? = 1 ] && return; - result="$REPLY" - packages="packages = no" - partitions="partitions = no" - sfdisk="dosfdisk = no" - hardware="hardware = no" - for opt in $result; do - case $opt in - '"packages"') packages="packages = yes";; - '"partitions"') partitions="partitions = yes";; - '"sfdisk"') sfdisk="dosfdisk = yes";; - '"hardware"') hardware="hardware = yes";; - esac - done - get_next_filename $configdirectory/10.sys - cat > $next_filename < $next_filename < $VROOTDIR/$vserver$packagesfile" + $VSERVER $vserver exec $packagemgr $packagemgroptions > $VROOTDIR/$vserver$packagesfile || fatal "can not save $packagemgr info to $packagesfile" + set +o noglob + done + fi + + # We want to perform this on the host as well + if [ -z "$packagemgr" -o ! -x "$packagemgr" ]; then + warning "can't find ${packagemgr}, skipping installed packages report." + else + # don't expand * since it can be used in $packagemgroptions + set -o noglob + debug "$packagemgr $packagemgroptions > $packagesfile" + $packagemgr $packagemgroptions > $packagesfile || fatal "can not save $packagemgr info to $packagesfile" + set +o noglob + fi + +fi + +## System report ############################## + +# +# here we grab a bunch of system stuff for a report +# + +export STATUS + +HASHES="#################################################################" +DASHES="-----------------------------------------------------------------" + +cat /dev/null > $sysreportfile || fatal "can not write to $sysreportfile" + + +catiffile () { + echo $HASHES >> $sysreportfile + echo "# $STATUS" >> $sysreportfile + echo $HASHES >> $sysreportfile + if [ -f $1 ]; then + echo "file: $1" >> $sysreportfile + echo $DASHES >> $sysreportfile + cat $1 >> $sysreportfile 2>&1 || info "reading of $1 failed" + fi + if [ -d $1 ]; then + echo "directory: $1" >> $sysreportfile + echo $DASHES >> $sysreportfile + for file in `find $1 -maxdepth 3 -noleaf -type f` + do + catiffile $file + done + fi + echo $DASHES >> $sysreportfile +} + +catifexec () { + echo $HASHES >> $sysreportfile + echo "# $STATUS" >> $sysreportfile + echo $HASHES >> $sysreportfile + $1 >> $sysreportfile 2>&1 || info "executing of $1 failed" +} + + +STATUS="Determining $os version:" +catiffile $osversion + +STATUS="Determinding your current hostname: " +catifexec "/bin/hostname" + +STATUS="Getting the date:" +catifexec "/bin/date" + +STATUS="Checking your systems current uptime and load average:" +catifexec "/usr/bin/uptime" + +STATUS="Checking available memory:" +catifexec "/usr/bin/free" + +STATUS="Checking free disk space:" +catifexec "/bin/df" "-al" + +STATUS="Collecting what services run at what run level:" +if [ $os = "redhat" ]; then + catifexec "/sbin/chkconfig --list" + STATUS="Collecting information about /etc/rc.d:" + catiffile "/bin/ls /etc/rc.d/rc*.d/" + +elif [ $os = "debian" ]; then + for level in 0 1 2 3 4 5 6 S; do + echo "Level: $level" >> $sysreportfile + for f in /etc/rc${level}.d/*; do + # Remove /etc/Knn or Snn from beginning + ff=$(echo $f | @SED@ 's_/etc/rc..d/[KS][0-9][0-9]__') + if [ $f != $ff ]; then + echo $ff >> $sysreportfile + fi + done + echo "" >> $sysreportfile + done +fi + +STATUS="Getting bootloader information:" +catifexec "/bin/ls -alR /boot" + +# This covers sparc, alpha, and intel (respectively) +# updated for grub -mpg +if [ -f /etc/silo.conf ]; then + STATUS="Collecting information about the boot process (silo):" + catiffile "/etc/silo.conf" +fi +if [ -f /etc/milo.conf ]; then + STATUS="Collecting information about the boot process (milo):" + catiffile "/etc/milo.conf" +fi +if [ -f /etc/lilo.conf ]; then + STATUS="Collecting information about the boot process (lilo):" + catiffile "/etc/lilo.conf" + catifexec "/sbin/lilo -q" +fi +if [ -d /boot/grub -a -f /boot/grub/grub.conf -a -f /boot/grub/device.map ]; then + STATUS="Collecting information about the boot process (grub.conf):" + catiffile "/boot/grub/grub.conf" + STATUS="Collecting information about the boot process (grub.map):" + catiffile "/boot/grub/device.map" +fi +if [ -f /etc/cluster.conf -o -f /etc/cluster.xml ] ; then + STATUS="Gathering information on cluster setup" + # 2.1 AS + if [ -f /etc/cluster.conf ] ; then + catiffile "/etc/cluster.conf" + fi + # Taroon + if [ -f /etc/cluster.xml ] ; then + catiffile "/etc/cluster.xml" + fi +fi + +STATUS="Gathering sysctl information (sysctl -a):" +catiffile "sysctl -a 2>/dev/null" +STATUS="Gathering sysctl information (/etc/sysctl.conf):" +catiffile "/etc/sysctl.conf" + +STATUS="Gathering IP information (/sbin/ifconfig):" +catifexec "/sbin/ifconfig -a" + +STATUS="Gathering additional IP information (/bin/ip addr list):" +catifexec "/bin/ip addr list" + +STATUS="Checking network routes:" +catifexec "/sbin/route -n" + +STATUS="Collecting Name Service Switch config information:" +catiffile "/etc/nsswitch.conf" + +STATUS="Collecting information about system authentication (pam):" +catiffile "/etc/pam.conf" +catiffile "/etc/pam.d" + +echo +echo "Getting information about the kernel." +echo +STATUS="Getting kernel version:" +catifexec "/bin/uname" "-a" +STATUS="Checking module information:" +catifexec "/sbin/lsmod" +for x in $(/sbin/lsmod | /bin/cut -f1 -d" " 2>/dev/null | /bin/grep -v Module 2>/dev/null +) ; do + STATUS="Checking module information $x:" + catifexec "/sbin/modinfo $x" +done + +STATUS="Currently getting ksysms information:" +catifexec "/sbin/ksyms" + +STATUS="Gathering information about your filesystems:" +catiffile "/proc/filesystems" + +STATUS="Gathering information about your system stat:" +catiffile "/proc/stat" + +STATUS="Gathering information about your partitions:" +catiffile "/proc/partitions" + +STATUS="Gathering information about your ksyms:" +catiffile "/proc/ksyms" + +STATUS="Gathering information about slabinfo:" +catiffile "/proc/slabinfo" + +# Added support to cover for the new modules.conf layout in Red Hat 7 +STATUS="Collecting information regarding kernel modules" +VER=`uname -r` +catiffile "/lib/modules/$VER/modules.dep" +if [ -f /etc/conf.modules ]; then + STATUS="Collecting information regarding kernel modules (conf.modules)" + catiffile "/etc/conf.modules" +fi +if [ -f /etc/modules.conf ]; then + STATUS="Collecting information regarding kernel modules (modules.conf)" + catiffile "/etc/modules.conf" +fi +if [ -f /etc/modprobe.conf ]; then + STATUS="Collecting information regarding kernel modules (modeprobe.conf)" + catiffile "/etc/modprobe.conf" +fi + +# dkms status +if [ -x /usr/sbin/dkms ] ; then + STATUS="Gathering current status of modules, versions and kernels (dkms):" + catifexec "/usr/sbin/dkms" "status" +fi + +if [ -f /etc/sysconfig/isdncard ] ; then + STATUS="Gathering information about ISDN:" + catiffile "/etc/sysconfig/isdncard" +fi + +STATUS="Collecting information from the proc directory:" +catiffile "/proc/pci" + +STATUS="Getting kernel command line" +catiffile "/proc/cmdline" + +STATUS="Gathering information about your CPU:" +catiffile "/proc/cpuinfo" + +STATUS="Gathering information about your Ram:" +catiffile "/proc/meminfo" + +STATUS="Gathering information about your ioports:" +catiffile "/proc/ioports" + +STATUS="Gathering information about your interrupts:" +catiffile "/proc/interrupts" + +STATUS="Gathering information about your scsi devices:" +catiffile "/proc/scsi" + +STATUS="Gathering information about your dma:" +catiffile "/proc/dma" + +STATUS="Gathering information about your devices (/proc/devices):" +catiffile "/proc/devices" + +STATUS="Gathering information about your rtc:" +catiffile "/proc/rtc" + +STATUS="Gathering information about your ide drivers:" +catiffile "/proc/ide" + +STATUS="Gathering information about your bus:" +catifexec lspci +catiffile "/proc/bus" + +echo +echo "Getting disk and filesystem information." +echo + +STATUS="Collecting information from /etc/fstab:" +catiffile "/etc/fstab" + +STATUS="Collecting disk partition information:" +catifexec "fdisk -l" + +STATUS="Checking mounted file systems (mount) " +catifexec "/bin/mount" + +STATUS="Checking mounted file systems (/proc/mounts)" +catiffile "/proc/mounts" + +STATUS="Collecting Software RAID information (/proc/mdstat)" +catiffile "/proc/mdstat" + +STATUS="Collecting Software RAID information (/etc/raidtab)" +catiffile "/etc/raidtab" + +STATUS="Collecting Software RAID information (/etc/mdadm.conf)" +catiffile "/etc/mdadm.conf" + +STATUS="Collecting Automount information (auto.master)" +catiffile "/etc/auto.master" + +STATUS="Collecting Automount information (auto.misc)" +catiffile "/etc/auto.misc" + +STATUS="Collecting Automount information (auto.net)" +catiffile "/etc/auto.net" + +STATUS="Collecting LVM information:" +if [ $os = "redhat" ]; then + catifexec "/usr/sbin/vgdisplay" "-vv" +elif [ $os = "debian" ]; then + catifexec "/sbin/vgdisplay" "-vv" +fi + +STATUS="Collecting SCSI Tape information (/etc/stinit.def)" +catiffile "/etc/stinit.def" + +if [ -x /sbin/lsusb ] ; then + STATUS="Collecting USB devices list (lsusb):" + catifexec "/sbin/lsusb" +fi + +if [ -x /usr/bin/lshal ] ; then + STATUS="Collecting global devices list (lshal):" + catifexec "/usr/bin/lshal" +fi + + +STATUS="Gathering information on SELinux setup" +catifexec "/usr/bin/selinuxconfig" +catifexec "/usr/sbin/sestatus" +if [ $os = "redhat" ]; then + catifexec "rpm" "-q -V selinux-policy-targeted" + catifexec "rpm" "-q -V selinux-policy-strict" +fi + +if [ $usevserver = yes ]; then + STATUS="Gathering vserver information" + catiffile "/proc/virtual" +fi + +if [ "$partitions" == "yes" ]; then + if [ "$dosfdisk" == "yes" ]; then + if [ ! -x "$SFDISK" ]; then + warning "can't find sfdisk, skipping sfdisk report." + partitions="no" + fi + fi + if [ "$dohwinfo" == "yes" ]; then + if [ ! -x "$HWINFO" ]; then + warning "can't find hwinfo, skipping partition report." + partitions="no" + fi + fi +fi + +if [ "$hardware" == "yes" ]; then + if [ ! -x "$HWINFO" ]; then + warning "can't find hwinfo, skipping hardware report." + hardware="no" + fi +fi + +## HARDWARE ############################# + +# +# here we use hwinfo to dump a table listing all the +# information we can find on the hardware of this machine +# + +if [ "$hardware" == "yes" ]; then + if [ "dohwinfo" == "yes" ]; then + if [ -f $hardwarefile ]; then + rm $hardwarefile + fi + touch $hardwarefile + echo -e "\n\n====================== summary ======================\n" >> $hardwarefile + debug "$HWINFO --short --cpu --network --disk --pci >> $hardwarefile" + $HWINFO --short --cpu --network --disk --pci >> $hardwarefile + for flag in cpu network bios pci; do + echo -e "\n\n====================== $flag ======================\n" >> $hardwarefile + $HWINFO --$flag >> $hardwarefile + done + fi +fi + + +## PARTITIONS ############################# + +# here we use sfdisk to dump a listing of all the partitions. +# these files can be used to directly partition a disk of the same size. + +if [ "$partitions" == "yes" ]; then + if [ "$dosfdisk" == "yes" ]; then + devices=`LC_ALL=C $SFDISK -l 2>/dev/null | grep "^Disk /dev" | @AWK@ '{print $2}' | cut -d: -f1` + if [ "$devices" == "" ]; then + warning "No harddisks found" + fi + for dev in $devices; do + debug "$SFDISK will try to backup partition tables for device $dev" + [ -b $dev ] || continue + label=${dev#/dev/} + label=${label//\//-} + outputfile=${partitionsfile//__star__/$label} + debug "$SFDISK $sfdisk_options -d $dev > $outputfile 2>/dev/null" + $SFDISK $sfdisk_options -d $dev > $outputfile 2>/dev/null + if [ $? -ne 0 ]; then + warning "The partition table for $dev could not be saved." + fi + done + fi + if [ "$dohwinfo" == "yes" ]; then + debug "Using $HWINFO to get all available disk information" + echo -e "\n\n====================== $disk ======================\n" >> $hardwarefile + $HWINFO --disk >> $hardwarefile + fi +fi diff --git a/handlers/tar b/handlers/tar deleted file mode 100644 index 7f0d147..0000000 --- a/handlers/tar +++ /dev/null @@ -1,79 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- -# -# tar handler script for backupninja - -getconf backupname `hostname --fqdn` -getconf backupdir /var/backups/`hostname --fqdn` -getconf compress bzip -getconf includes "/etc /home /usr/local" -getconf excludes "/tmp /proc /dev /sys /net /misc /media /srv /selinux" - -getconf TAR `which tar` -getconf EXTENSION tar -getconf DATE `which date` -getconf DATEFORMAT "%Y.%m.%d-%H%M" - -# See if vservers are configured -if [ "$vservers" = "yes" ] -then - warning "vservers enabled, but tar does not support it!" -fi - -if [ ! -d "$backupdir" ] -then - mkdir -p "$backupdir" || fatal "Can not make directory $backupdir" -fi - -if [ ! -w "$backupdir" ] -then - fatal "Directory $backupdir is not writable" -fi - -## DO IT ################################################# -# -# here we grab a list of the packages installed and removed. -# - -case $compress in - "compress") - compress_option="-Z" - EXTENSION="tar.compress" - ;; - "gzip") - compress_option="-z" - EXTENSION="tgz" - ;; - "bzip") - compress_option="-j" - EXTENSION="tar.bz2" - ;; - "none") - compress_option="" - ;; - *) - warning "Unknown compress filter ($tar_compress)" - compress_option="" - EXTENSION="tgz" - ;; -esac - -exclude_options="" -for i in $excludes -do - exclude_options="$exclude_options --exclude $i" -done - -debug "Running backup: " $TAR -c -p -v $compress_option $exclude_options \ - -f "$backupdir/$backupname-"`$DATE "+$DATEFORMAT"`".$EXTENSION" \ - $includes - -$TAR -c -p -v $compress_option $exclude_options \ - -f "$backupdir/$backupname-"`$DATE "+$DATEFORMAT"`".$EXTENSION" \ - $includes \ - > "$backupdir/$backupname-"`$DATE "+$DATEFORMAT"`.list \ - 2> "$backupdir/$backupname-"`$DATE "+$DATEFORMAT"`.err - -[ $? -ne 0 ] && fatal "Tar backup failed" - - - diff --git a/handlers/tar.helper b/handlers/tar.helper deleted file mode 100644 index cc9a89b..0000000 --- a/handlers/tar.helper +++ /dev/null @@ -1,94 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- - -HELPERS="$HELPERS tar:tar_backup" - -tar_wizard() { - tar_title="Tar action wizard" - - backupname=`hostname --fqdn` - - inputBox "$tar_title" "When to run this action?" "everyday at 01" - [ $? = 1 ] && return - tar_when_run="when = $REPLY" - - inputBox "$tar_title" "\"Name\" of backups" "$backupname" - [ $? = 1 ] && return - tar_backupname="backupname = $REPLY" - backupname="$REPLY" - - inputBox "$tar_title" "Directory where to store the backups" "/net/backups/$backupname" - [ $? = 1 ] && return - tar_backupdir="backupdir = $REPLY" - - radioBox "$tar_title" "Compression" \ - "none" "do not filter trough" off \ - "compress" "filter trough compress" off \ - "gzip" "filter trough gzip" off \ - "bzip" "filter trough bzip" on - [ $? = 1 ] && return; - result="$REPLY" - tar_compress="compress = $REPLY " - - REPLY= - while [ -z "$REPLY" ]; do - formBegin "$tar_title: Includes" - formItem "Include:" /etc - formItem "Include:" /home - formItem "Include:" /usr/local - formItem "Include:" - formItem "Include:" - formItem "Include:" - formItem "Include:" - formItem "Include:" - formItem "Include:" - formItem "Include:" - formItem "Include:" - formDisplay - [ $? = 0 ] || return 1 - tar_includes="includes = " - for i in $REPLY; do - [ -n "$i" ] && tar_includes="$tar_includes $i" - done - done - - REPLY= - while [ -z "$REPLY" ]; do - formBegin "$tar_title: Excludes" - formItem "Exclude:" /tmp - formItem "Exclude:" /proc - formItem "Exclude:" /sys - formItem "Exclude:" /dev - formItem "Exclude:" /srv - formItem "Exclude:" /media - formItem "Exclude:" /misc - formItem "Exclude:" /net - formItem "Exclude:" /selinux - formItem "Exclude:" - formItem "Exclude:" - formDisplay - [ $? = 0 ] || return 1 - tar_excludes="excludes = " - for i in $REPLY; do - [ -n "$i" ] && tar_excludes="$tar_excludes $i" - done - done - -# Save the config - get_next_filename $configdirectory/10.tar - cat > $next_filename < $next_filename < "$backupdir/$backupname-"`$DATE "+$DATEFORMAT"`.list \ + 2> "$backupdir/$backupname-"`$DATE "+$DATEFORMAT"`.err + +[ $? -ne 0 ] && fatal "Tar backup failed" + + + diff --git a/handlers/trac b/handlers/trac deleted file mode 100644 index 0460c9f..0000000 --- a/handlers/trac +++ /dev/null @@ -1,58 +0,0 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- -# -# this handler will backup trac environments (based on the svn handler) -# -# http://trac.edgewall.com/ -# - -getconf src /var/lib/trac -getconf dest /var/backups/trac -getconf tmp /var/backups/trac.tmp - -error=0 -cd $src -for repo in `find . -name VERSION` -do - - repo=`dirname $repo` - if [ "$repo" == "." ] - then - repo="" - fi - - # Just make the parent directory for $tmp/$repo - parentdir=`dirname $tmp/$repo` - ret=`mkdir -p $parentdir 2>&1` - code=$? - if [ "$ret" ]; then - debug "$ret" - fi - if [ $code != 0 ]; then - error "command failed mkdir -p $parentdir" - fi - - ret=`trac-admin $src/$repo hotcopy $tmp/$repo 2>&1` - code=$? - if [ "$ret" ]; then - debug "$ret" - fi - if [ $code != 0 ]; then - error "command failed -- trac-admin $src/$repo hotcopy $tmp/$repo" - error=1 - fi -done - -if [ $error -eq 1 ]; then - echo "Error: because of earlier errors, we are leaving trac backups in $tmp instead of $dest" -else - if [ -d $dest -a -d $tmp ]; then - rm -rf $dest - fi - if [ -d $tmp ]; then - mv $tmp $dest - fi -fi - -exit 0 - -# vim: filetype=sh diff --git a/handlers/trac.in b/handlers/trac.in new file mode 100644 index 0000000..0460c9f --- /dev/null +++ b/handlers/trac.in @@ -0,0 +1,58 @@ +# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- +# +# this handler will backup trac environments (based on the svn handler) +# +# http://trac.edgewall.com/ +# + +getconf src /var/lib/trac +getconf dest /var/backups/trac +getconf tmp /var/backups/trac.tmp + +error=0 +cd $src +for repo in `find . -name VERSION` +do + + repo=`dirname $repo` + if [ "$repo" == "." ] + then + repo="" + fi + + # Just make the parent directory for $tmp/$repo + parentdir=`dirname $tmp/$repo` + ret=`mkdir -p $parentdir 2>&1` + code=$? + if [ "$ret" ]; then + debug "$ret" + fi + if [ $code != 0 ]; then + error "command failed mkdir -p $parentdir" + fi + + ret=`trac-admin $src/$repo hotcopy $tmp/$repo 2>&1` + code=$? + if [ "$ret" ]; then + debug "$ret" + fi + if [ $code != 0 ]; then + error "command failed -- trac-admin $src/$repo hotcopy $tmp/$repo" + error=1 + fi +done + +if [ $error -eq 1 ]; then + echo "Error: because of earlier errors, we are leaving trac backups in $tmp instead of $dest" +else + if [ -d $dest -a -d $tmp ]; then + rm -rf $dest + fi + if [ -d $tmp ]; then + mv $tmp $dest + fi +fi + +exit 0 + +# vim: filetype=sh