Added RPM patches submitted by Robert Napier
[matthijs/upstream/backupninja.git] / handlers / mysql
index 49f80a8545816fedb760fe1d148745f5bc8526eb..cd72fc9087bb7033e009f0c8125c0e75ef80b9a4 100644 (file)
@@ -1,3 +1,4 @@
+# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
 #
 # mysql handler script for backupninja
 #
@@ -18,42 +19,28 @@ getconf dbpassword
 getconf configfile /etc/mysql/debian.cnf
 
 
-# If vservers are configured, decide if the handler should
-# use them or if it should just operate on the host
-
-if [ "$vservers" = "yes" ]
-then
-       if [ ! -z $vsname ]
-       then            
-               info "Using vserver '$vsname'"
-               usevserver=1
-       else
-               info "No vserver name specified, actions will be performed on the host"
-       fi
-fi
-
-# If needed, make sure that the specified vserver exists and is running.
-if [ $usevserver ]
-then
-       info "Examining vserver '$vsname'"
-       # does it exist ?
-       vroot="$VROOTDIR/$vsname"
-       [ -d $vroot ] || fatal "vserver '$vsname' does not exist at '$vroot'"
-       # is it running ?
-       $VSERVERINFO -q $vsname RUNNING
-       if [ $? -ne 0 ]
-       then
-               fatal "vserver $vsname is not running."
-       fi
-fi
-
-if [ "$user" == "" ]; then
-       userset=false;
-       user=root;
-else
-       userset=true;
-       userhome=`getent passwd "$user" | awk -F: '{print $6}'`
-       [ -f $userhome/.my.cnf ] || fatal "Can't find config file in $userhome/.my.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
@@ -64,14 +51,14 @@ for i in $ignores; do
        ignore="$ignore --ignore-table=$i"
 done
        
-# create backup dirs, vroot variable will be empty if no vsname was specified
-# and will proceed to operate on the host
+# 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 ]
+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
@@ -88,7 +75,7 @@ fi
 # 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-file
+# 3. specify the config file with --defaults-extra-file
 #    (this option DOESN'T WORK WITH MYSQLHOTCOPY)
 #
 
@@ -98,16 +85,21 @@ fi
 # specify the password on the command line.
 
 defaultsfile=""
+
 if [ "$dbusername" != "" -a "$dbpassword" != "" ]
 then
-    if [ $usevserver ]
+    if [ $usevserver = yes ]
     then
-       home=`$VSERVER $vsname exec getent passwd "root" | awk -F: '{print $6}'`
+       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
@@ -115,109 +107,167 @@ then
        debug "mv $mycnf $tmpcnf"
        mv $mycnf $tmpcnf
     fi
+    
     oldmask=`umask`
     umask 077
     cat > $mycnf <<EOF
 # auto generated backupninja mysql conf
 [mysql]
+host=$dbhost
 user=$dbusername
 password="$dbpassword"
 
 [mysqldump]
+host=$dbhost
 user=$dbusername
 password="$dbpassword"
 
 [mysqlhotcopy]
+host=$dbhost
 user=$dbusername
 password="$dbpassword"
 EOF
        umask $oldmask
-       defaultsfile="--defaults-file=$mycnf"
-elif [ "$userset" == "false" ]; then
-       # if user is set, don't use $configfile
-       defaultsfile="--defaults-file=$configfile"
+       if [ $usevserver = yes ] 
+       then
+           defaultsfile="--defaults-extra-file=$vhome/.my.cnf"
+       else
+           defaultsfile="--defaults-extra-file=$mycnf"
+       fi
+fi
+
+# if a user is not set, use $configfile, otherwise use $mycnf
+if [ "$user" == "" ]; then
+       user=root;
+       defaultsfile="--defaults-extra-file=$configfile"
+else
+       userset=true;
+       if [ $usevserver = yes ]
+       then
+           vuserhome=`$VSERVER $vsname exec getent passwd "$user" | awk -F: '{print $6}'`
+           if [ $? -eq 2 ]
+           then
+               fatal "User $user not found in /etc/passwd"
+           fi
+           userhome="$vroot$vuserhome"
+       else
+           userhome=`getent passwd "$user" | awk -F: '{print $6}'`
+           if [ $? -eq 2 ]
+           then
+               fatal "User $user not found in /etc/passwd"
+           fi
+               fi
+       
+       debug "User home set to: $userhome"
+       [ -f $userhome/.my.cnf ] || fatal "Can't find config file in $userhome/.my.cnf"
+       defaultsfile="--defaults-extra-file=$userhome/.my.cnf"
+       debug "using $defaultsfile"
 fi
 
 #######################################################################
 ## HOT COPY
 
-if [ "$hotcopy" == "yes" ]; then 
-       if [ "$databases" == "all" ]; then
-               if [ $usevserver ]
+if [ "$hotcopy" == "yes" ]
+then
+    info "Initializing hotcopy method"
+    if [ "$databases" == "all" ]
+    then
+       if [ $usevserver = yes ]
+       then
+               info "dbhost: $dbhost"
+               execstr="$VSERVER $vsname exec $MYSQLHOTCOPY -h $dbhost --quiet --allowold --regexp /.\*/./.\*/ $hotdir"
+       else
+               execstr="$MYSQLHOTCOPY --quiet --allowold --regexp /.\*/./.\*/ $hotdir"
+       fi
+       debug "su $user -c \"$execstr\""
+       if [ ! $test ]
+       then
+               output=`su $user -c "$execstr" 2>&1`
+               code=$?
+               if [ "$code" == "0" ]
                then
-                       execstr="$VSERVER $vsname exec $MYSQLHOTCOPY --quiet --allowold --regexp /.\*/./.\*/ $hotdir"
+                       debug $output
+                       info "Successfully finished hotcopy of all mysql databases"
                else
-                       execstr="$MYSQLHOTCOPY --quiet --allowold --regexp /.\*/./.\*/ $hotdir"
+                       warning $output
+                       warning "Failed to hotcopy all mysql databases"
                fi
-               debug "su $user -c '$execstr'"
-               if [ ! $test ]; then
+       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
+                       if [ "$code" == "0" ]
+                       then
                                debug $output
-                               info "Successfully finished hotcopy of all mysql databases"
+                               info "Successfully finished hotcopy of mysql database $db"
                        else
                                warning $output
-                               warning "Failed to hotcopy all mysql databases"
+                               warning "Failed to hotcopy mysql database $db"
                        fi
                fi
-       else    
-               for db in $databases; do
-                       if [ $usevserver ]
-                       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
+       done
+     fi
 fi
 
 ##########################################################################
 ## SQL DUMP
 
-if [ "$sqldump" == "yes" ]; then
-       if [ "$databases" == "all" ]; then
-               if [ $usevserver ]
+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"
+           fi
+       else
+               databases=`echo 'show databases' | su $user -c "$MYSQL $defaultsfile" | grep -v Database`
+               if [ $? -ne 0 ]
                then
-                       databases=`echo 'show databases' | $VSERVER $vsname exec su $user -c "$MYSQL $defaultsfile" | grep -v Database`
-                       if [ $? -ne 0 ]
-                       then
-                           fatal "Something unexpected happened, the defaults file may have gone missing or is corrupt"
-                       fi
-               else
-                       databases=`echo 'show databases' | su $user -c "$MYSQL $defaultsfile" | grep -v Database`
-                       if [ $? -ne 0 ]
-                       then
-                           fatal "Something unexpected happened, the defaults file may have gone missing or is corrupt"
-                       fi
+                   fatal "Authentication problem, maybe user/password is wrong"
                fi
        fi
+fi
 
-       for db in $databases; do
-               if [ $usevserver ]
+       for db in $databases
+       do
+               if [ $usevserver = yes ]
                then
-                       execstr="$VSERVER $vsname exec $MYSQLDUMP $defaultsfile --lock-tables --complete-insert --add-drop-table --quick --quote-names $ignore $db > $vroot$dumpdir/${db}.sql"
+                   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 > $vroot$dumpdir/${db}.sql"
+                   fi
                else
-                       execstr="$MYSQLDUMP $defaultsfile --lock-tables --complete-insert --add-drop-table --quick --quote-names $ignore $db > $dumpdir/${db}.sql"
+                   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 > $dumpdir/${db}.sql"
+                   fi
                fi
-               debug "su $user -c '$execstr'"
-               if [ ! $test ]; then
+               debug "su $user -c \"$execstr\""
+               if [ ! $test ]
+               then
                        output=`su $user -c "$execstr" 2>&1`
                        code=$?
-                       if [ "$code" == "0" ]; then
+                       if [ "$code" == "0" ]
+                       then
                                debug $output
                                info "Successfully finished dump of mysql database $db"
                        else
@@ -226,19 +276,16 @@ if [ "$sqldump" == "yes" ]; then
                        fi
                fi
        done
-       
-       if [ "$compress" == "yes" ]; then
-               output=`$GZIP -f $vroot$dumpdir/*.sql 2>&1`
-               debug $output
-       fi
 fi
 
 # clean up tmp config file
-if [ "$dbusername" != "" ]; then
+if [ "$dbusername" != "" -a "$dbpassword" != "" ]
+then
        ## clean up tmp config file
        debug "rm $mycnf"
        rm $mycnf
-       if [ -f "$tmpcnf" ]; then
+       if [ -f "$tmpcnf" ]
+       then
                debug "mv $tmpcnf $mycnf"
                mv $tmpcnf $mycnf
        fi