Make all indentation consistent.
[matthijs/upstream/backupninja.git] / handlers / mysql.in
1 # -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
2 #
3 # mysql handler script for backupninja
4 #
5
6 getconf backupdir /var/backups/mysql
7 getconf databases all
8 getconf ignores
9 getconf nodata
10 getconf dbhost localhost
11 getconf hotcopy no
12 getconf sqldump no
13 getconf sqldumpoptions "--lock-tables --complete-insert --add-drop-table --quick --quote-names"
14 getconf compress yes
15 getconf vsname
16
17 # authentication:
18 getconf user
19 getconf dbusername
20 getconf dbpassword
21 getconf configfile /etc/mysql/debian.cnf
22
23
24 # Decide if the handler should operate on a vserver or on the host.
25 # In the former case, check that $vsname exists and is running.
26 local usevserver=no
27 local vroot
28 if [ $vservers_are_available = yes ]; then
29    if [ -n "$vsname" ]; then
30       # does it exist ?
31       if ! vservers_exist "$vsname" ; then
32          fatal "The vserver given in vsname ($vsname) does not exist."
33       fi
34       # is it running ?
35       vservers_running $vsname || fatal "The vserver $vsname is not running."
36       # everything ok
37       info "Using vserver '$vsname'."
38       usevserver=yes
39       vroot="$VROOTDIR/$vsname"
40    else
41       info "No vserver name specified, actions will be performed on the host."
42    fi
43 fi
44
45 ## Prepare ignore part of the command
46 ## This only works for mysqldump at the moment
47
48 ignore=''
49 for i in $ignores $nodata; do
50    ignore="$ignore --ignore-table=$i"
51 done
52
53 # create backup dirs, $vroot will be empty if no vsname was specified
54 # and we will instead proceed to operate on the host
55 [ -d $vroot$backupdir ] || mkdir -p $vroot$backupdir
56 [ -d $vroot$backupdir ] || fatal "Backup directory '$vroot$backupdir'"
57 hotdir="$backupdir/hotcopy"
58 dumpdir="$backupdir/sqldump"
59
60 if [ $usevserver = yes ]
61 then
62    [ "$sqldump" == "no" -o -d $vroot$dumpdir ] || $VSERVER $vsname exec mkdir -p $dumpdir
63    [ "$hotcopy" == "no" -o -d $vroot$hotdir ] || $VSERVER $vsname exec mkdir -p $hotdir
64 else
65    [ "$sqldump" == "no" -o -d $dumpdir ] || mkdir -p $dumpdir
66    [ "$hotcopy" == "no" -o -d $hotdir ] || mkdir -p $hotdir
67 fi
68
69 #######################################################################
70 ## AUTHENTICATION
71
72 #
73 # one of three authentication methods:
74 # 1. setting the user, so that /home/user/.my.cnf is used.
75 # 2. specifying the user and password in the handler config,
76 #    which generates a temporary .my.cnf in /root/.my.cnf
77 # 3. specify the config file with --defaults-extra-file
78 #    (this option DOESN'T WORK WITH MYSQLHOTCOPY)
79 #
80
81 # create .my.cnf
82 # only if dbusername and dbpassword specified.
83 # we create a tmp file because we don't want to
84 # specify the password on the command line.
85
86 defaultsfile=""
87
88 if [ "$dbusername" != "" -a "$dbpassword" != "" ]
89 then
90    if [ $usevserver = yes ]
91    then
92       vhome=`$VSERVER $vsname exec getent passwd "root" | @AWK@ -F: '{print $6}'`
93    home="$vroot$vhome"
94    else
95       home=`getent passwd "root" | @AWK@ -F: '{print $6}'`
96    fi
97
98    [ -d $home ] || fatal "Can't find root's home directory ($home)."
99
100    mycnf="$home/.my.cnf"
101
102    if [ -f $mycnf ]
103    then
104    # rename temporarily
105    tmpcnf="$home/my.cnf.disable"
106    debug "mv $mycnf $tmpcnf"
107    mv $mycnf $tmpcnf
108    fi
109
110    oldmask=`umask`
111    umask 077
112    cat > $mycnf <<EOF
113 # auto generated backupninja mysql conf
114 [mysql]
115 host=$dbhost
116 user=$dbusername
117 password="$dbpassword"
118
119 [mysqldump]
120 host=$dbhost
121 user=$dbusername
122 password="$dbpassword"
123
124 [mysqlhotcopy]
125 host=$dbhost
126 user=$dbusername
127 password="$dbpassword"
128 EOF
129    umask $oldmask
130    if [ $usevserver = yes ]
131    then
132       defaultsfile="--defaults-extra-file=$vhome/.my.cnf"
133    else
134       defaultsfile="--defaults-extra-file=$mycnf"
135    fi
136 fi
137
138 # if a user is not set, use $configfile, otherwise use $mycnf
139 if [ "$user" == "" ]; then
140    user=root;
141    defaultsfile="--defaults-extra-file=$configfile"
142 else
143    userset=true;
144    if [ $usevserver = yes ]
145    then
146       vuserhome=`$VSERVER $vsname exec getent passwd "$user" | @AWK@ -F: '{print $6}'`
147       if [ $? -eq 2 ]
148       then
149          fatal "User $user not found in /etc/passwd"
150       fi
151          userhome="$vroot$vuserhome"
152    else
153       userhome=`getent passwd "$user" | @AWK@ -F: '{print $6}'`
154       if [ $? -eq 2 ]
155       then
156          fatal "User $user not found in /etc/passwd"
157       fi
158          fi
159
160    debug "User home set to: $userhome"
161    [ -f $userhome/.my.cnf ] || fatal "Can't find config file in $userhome/.my.cnf"
162    defaultsfile="--defaults-extra-file=$userhome/.my.cnf"
163    debug "using $defaultsfile"
164 fi
165
166 #######################################################################
167 ## HOT COPY
168
169 if [ "$hotcopy" == "yes" ]
170 then
171    info "Initializing hotcopy method"
172    if [ "$databases" == "all" ]
173    then
174       if [ $usevserver = yes ]
175       then
176          info "dbhost: $dbhost"
177          execstr="$VSERVER $vsname exec $MYSQLHOTCOPY -h $dbhost --quiet --allowold --regexp /.\*/./.\*/ $hotdir"
178       else
179          execstr="$MYSQLHOTCOPY --quiet --allowold --regexp /.\*/./.\*/ $hotdir"
180       fi
181       debug "su $user -c \"$execstr\""
182       if [ ! $test ]
183       then
184          output=`su $user -c "$execstr" 2>&1`
185          code=$?
186          if [ "$code" == "0" ]
187          then
188             debug $output
189             info "Successfully finished hotcopy of all mysql databases"
190          else
191             warning $output
192             warning "Failed to hotcopy all mysql databases"
193          fi
194       fi
195    else
196       for db in $databases
197       do
198          if [ $usevserver = yes ]
199          then
200             execstr="$VSERVER $vsname exec $MYSQLHOTCOPY --allowold $db $hotdir"
201          else
202             execstr="$MYSQLHOTCOPY --allowold $db $hotdir"
203          fi
204          debug 'su $user -c \"$execstr\"'
205          if [ ! $test ]
206          then
207             output=`su $user -c "$execstr" 2>&1`
208             code=$?
209             if [ "$code" == "0" ]
210             then
211                debug $output
212                info "Successfully finished hotcopy of mysql database $db"
213             else
214                warning $output
215                warning "Failed to hotcopy mysql database $db"
216             fi
217          fi
218       done
219    fi
220 fi
221
222 ##########################################################################
223 ## SQL DUMP
224
225 if [ "$sqldump" == "yes" ]
226 then
227    info "Initializing SQL dump method"
228    if [ "$databases" == "all" ]
229    then
230       if [ $usevserver = yes ]
231       then
232          debug 'echo show databases | $VSERVER $vsname exec su $user -c \"$MYSQL $defaultsfile\" | grep -v Database'
233          databases=`echo 'show databases' | $VSERVER $vsname exec su $user -c "$MYSQL $defaultsfile" | grep -v Database`
234          if [ $? -ne 0 ]
235          then
236             fatal "Authentication problem, maybe user/password is wrong or mysqld is not running?"
237          fi
238       else
239          databases=$(su $user -c "$MYSQL $defaultsfile -N -B -e 'show databases'" | sed 's/|//g;/\+----/d')
240          if [ $? -ne 0 ]
241          then
242             fatal "Authentication problem, maybe user/password is wrong or mysqld is not running?"
243          fi
244       fi
245    fi
246
247    for db in $databases
248    do
249       DUMP_BASE="$MYSQLDUMP $defaultsfile $sqldumpoptions"
250
251       # Dumping structure and data
252       DUMP="$DUMP_BASE $ignore $db"
253
254       # If requested, dump only the table structure for this database
255       if echo "$nodata" | grep -E '(^|[[:space:]])'"$db\." >/dev/null
256       then
257          # Get the structure of the tables, without data
258          DUMP_STRUCT="$DUMP_BASE --no-data $db"
259          for qualified_table in $nodata
260          do
261             table=$( expr match "$qualified_table" "$db\.\([^\w]*\)" )
262             DUMP_STRUCT="$DUMP_STRUCT $table"
263          done
264          DUMP="( $DUMP; $DUMP_STRUCT )"
265       fi
266       if [ $usevserver = yes ]
267       then
268          # Test to make sure mysqld is running, if it is not sqldump will not work
269          $VSERVER $vsname exec su $user -c "$MYSQLADMIN $defaultsfile ping 2>&1 >/dev/null"
270          if [ $? -ne 0 ]; then
271             fatal "mysqld doesn't appear to be running!"
272          fi
273          if [ "$compress" == "yes" ]; then
274             execstr="$VSERVER $vsname exec $DUMP | $GZIP > $vroot$dumpdir/${db}.sql.gz"
275          else
276             execstr="$VSERVER $vsname exec $DUMP -r $vroot$dumpdir/${db}.sql"
277          fi
278       else
279          # Test to make sure mysqld is running, if it is not sqldump will not work
280          su $user -c "$MYSQLADMIN $defaultsfile ping 2>&1 >/dev/null"
281          if [ $? -ne 0 ]; then
282             fatal "mysqld doesn't appear to be running!"
283          fi
284          if [ "$compress" == "yes" ]; then
285             execstr="$DUMP | $GZIP > $dumpdir/${db}.sql.gz"
286          else
287             execstr="$DUMP -r $dumpdir/${db}.sql"
288          fi
289       fi
290       debug "su $user -c \"$execstr\""
291       if [ ! $test ]
292       then
293          output=`su $user -c "$execstr" 2>&1`
294          code=$?
295          if [ "$code" == "0" ]
296          then
297             debug $output
298             info "Successfully finished dump of mysql database $db"
299          else
300             warning $output
301             warning "Failed to dump mysql databases $db"
302          fi
303       fi
304    done
305 fi
306
307 # clean up tmp config file
308 if [ "$dbusername" != "" -a "$dbpassword" != "" ]
309 then
310    ## clean up tmp config file
311    debug "rm $mycnf"
312    rm $mycnf
313    if [ -f "$tmpcnf" ]
314    then
315       debug "mv $tmpcnf $mycnf"
316       mv $tmpcnf $mycnf
317    fi
318 fi
319
320 return 0