1 # -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
2 # vim: set filetype=sh sw=3 sts=3 expandtab autoindent:
4 HELPERS="$HELPERS rdiff:incremental_remote_filesystem_backup"
6 declare -a rdiff_includes
7 declare -a rdiff_excludes
8 declare -a rdiff_vsincludes
9 declare -a rdiff_vsexcludes
13 do_rdiff_host_includes() {
15 # choose the files to backup
17 while [ -z "$REPLY" ]; do
18 formBegin "$rdiff_title - host system: includes"
19 for ((i=0; i < ${#rdiff_includes[@]} ; i++)); do
20 formItem include ${rdiff_includes[$i]}
28 rdiff_includes=($REPLY)
34 # choose the vservers to backup (into $selected_vservers)
35 choose_one_or_more_vservers "$rdiff_title"
36 [ $? = 0 ] || return 1
39 # choose the files to backup
42 while [ -z "$REPLY" ]; do
43 formBegin "$rdiff_title - vsincludes (backup these directories from every vserver)"
44 [ -z "$rdiff_vsincludes" ] && rdiff_vsincludes="$rdiff_default_includes"
46 for i in $rdiff_vsincludes; do
53 [ $? = 0 ] || return 1
54 rdiff_vsincludes=($REPLY)
62 formBegin "$rdiff_title: excludes"
63 for ((i=0; i < ${#rdiff_excludes[@]} ; i++))
65 formItem exclude ${rdiff_excludes[$i]}
72 rdiff_excludes=($REPLY)
77 choose_host_or_vservers_or_both "$rdiff_title"
78 [ $? = 0 ] || return 1
79 case $host_or_vservers in
81 do_rdiff_host_includes
82 [ $? = 0 ] || return 1
86 [ $? = 0 ] || return 1
89 do_rdiff_host_includes
90 [ $? = 0 ] || return 1
92 [ $? = 0 ] || return 1
99 [ $? = 0 ] || return 1
109 while [ -z "$REPLY" -o -z "$rdiff_directory" -o -z "$rdiff_host" -o -z "$rdiff_user" ]
111 formBegin "$rdiff_title - destination: last three items are required"
112 formItem "keep" "$rdiff_keep"
113 formItem "dest_directory" "$rdiff_directory"
114 formItem "dest_host" "$rdiff_host"
115 formItem "dest_user" "$rdiff_user"
116 formItem "dest_type" "$rdiff_type"
120 rdiff_keep=${tmp_array[0]}
121 rdiff_directory=${tmp_array[1]}
122 rdiff_host=${tmp_array[2]}
123 rdiff_user=${tmp_array[3]}
124 rdiff_type=${tmp_array[4]}
133 local remote_status="ok"
136 if [ "$_dest_done" = "" ]; then
137 msgBox "$rdiff_title: error" "You must first configure the destination."
139 elif [ "$rdiff_type" = "" ]; then
140 msgBox "$rdiff_title: error" "You must first configure the destination backup type."
142 elif [ "$rdiff_user" = "" ]; then
143 msgBox "$rdiff_title: error" "You must first configure the destination user."
145 elif [ "$rdiff_host" = "" ]; then
146 msgBox "$rdiff_title: error" "You must first configure the destination host."
149 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?"
153 if [ ! -f /root/.ssh/id_dsa.pub -a ! -f /root/.ssh/id_rsa.pub ]; then
154 echo "Creating local root's ssh key"
155 ssh-keygen -t dsa -f /root/.ssh/id_dsa -N ""
156 echo "Done. hit return to continue"
160 ssh -o PreferredAuthentications=publickey $rdiff_host -l $rdiff_user "exit" 2> /dev/null
161 if [ $? -ne 0 ]; then
162 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."
163 ssh-copy-id -i /root/.ssh/id_[rd]sa.pub $rdiff_user@$rdiff_host
164 if [ $? -ne 0 ]; then
165 echo "FAILED: Couldn't copy root's public ssh key to authorized_keys of $rdiff_user@$rdiff_host."
166 ssh $rdiff_user@$rdiff_host 'test -w .ssh || test -w .'
168 echo "Hit return to continue."
171 0 ) msgBox "$rdiff_title: error" "Directories are writable: Probably just a typo the first time." ;;
172 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." ;;
173 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." ;;
174 * ) msgBox "$rdiff_title: error" "Unexpected error." ;;
178 echo "Done. hit return to continue"
182 echo "root@localhost is already in authorized_keys of $rdiff_user@$rdiff_host."
183 echo "Hit return to continue."
187 # test to see if the remote rdiff backup directory exists and is writable
188 echo "Testing to see if remote rdiff backup directory exists and is writable"
189 ssh $rdiff_user@$rdiff_host "test -d ${rdiff_directory}"
191 ssh $rdiff_user@$rdiff_host "test -w $rdiff_directory"
193 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."
197 booleanBox "Remote directory does not exist" "The destination backup directory does not exist, do you want me to create it for you?"
199 ssh $rdiff_user@$rdiff_host "mkdir -p ${rdiff_directory}"
202 0) msgBox "$rdiff_title: success" "Creation of the remote destination directory was a success!";;
203 1) msgBox "$rdiff_title: error" "Connected successfully to $rdiff_user@$rdiff_host, but was unable to create the destination directory, check the directory permissions."
204 remote_status=failed;;
205 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."
206 remote_status=failed;;
207 *) msgBox "$rdiff_title: error" "Unexpected error."
208 remote_status=failed;;
213 if [ "$remote_status" = "ok" ]; then
219 echo "Checking for local install of rdiff-backup"
220 require_packages rdiff-backup
222 echo "Testing to make sure destination has rdiff-backup installed and is compatible."
223 remote_result=`/usr/bin/rdiff-backup --test-server $rdiff_user@$rdiff_host::/ 2>&1 >&-`
224 if [ $? -ne 0 ]; then
225 echo $remote_result | grep -q "command not found"
226 if [ $? -eq 0 ]; then
227 if [ "$rdiff_user" = "root" ]; then
228 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?"
230 ssh $rdiff_user@$rdiff_host 'apt-get install rdiff-backup'
232 echo "Hit return to continue."
235 0) msgBox "$rdiff_title: success" "Installation of rdiff-backup was a success!"
237 1) msgBox "$rdiff_title: error" "Connected successfully to $rdiff_user@$rdiff_host, but was unable to install the package for some reason.";;
238 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.";;
239 *) msgBox "$rdiff_title: error" "Unexpected error.";;
244 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?"
252 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?"
260 echo "SUCCESS: Everything looks good!"
261 echo "Hit return to continue."
270 get_next_filename $configdirectory/90.rdiff
271 cat > $next_filename <<EOF
273 # when = everyday at 02
279 # A few notes about includes and excludes:
280 # 1. include, exclude and vsinclude statements support globbing with '*'
281 # 2. Symlinks are not dereferenced. Moreover, an include line whose path
282 # contains, at any level, a symlink to a directory, will only have the
283 # symlink backed-up, not the target directory's content. Yes, you have to
284 # dereference yourself the symlinks, or to use 'mount --bind' instead.
285 # Example: let's say /home is a symlink to /mnt/crypt/home ; the following
286 # line will only backup a "/home" symlink ; neither /home/user nor
287 # /home/user/Mail will be backed-up :
288 # include = /home/user/Mail
289 # A workaround is to 'mount --bind /mnt/crypt/home /home' ; another one is to
291 # include = /mnt/crypt/home/user/Mail
292 # 3. All the excludes come after all the includes. The order is not otherwise
293 # taken into account.
295 # files to include in the backup
298 if [ "$host_or_vservers" == host -o "$host_or_vservers" == both ]; then
300 for ((i=0; i < ${#rdiff_includes[@]} ; i++)); do
301 echo "include = ${rdiff_includes[$i]}" >> $next_filename
306 if [ "$host_or_vservers" == vservers -o "$host_or_vservers" == both ]; then
307 cat >> $next_filename <<EOF
309 # If vservers = yes in /etc/backupninja.conf then the following variables can
311 # vsnames = all | <vserver1> <vserver2> ... (default = all)
315 # Any path specified in vsinclude is added to the include list for each vserver
316 # listed in vsnames (or all if vsnames = all, which is the default).
318 # For example, vsinclude = /home will backup the /home directory in every
319 # vserver listed in vsnames. If you have 'vsnames = foo bar baz', this
320 # vsinclude will add to the include list /vservers/foo/home, /vservers/bar/home
321 # and /vservers/baz/home.
322 # Vservers paths are derived from $VROOTDIR.
326 echo -e "vsnames = $selected_vservers\n" >> $next_filename
327 for i in $rdiff_vsincludes; do
328 echo "vsinclude = $i" >> $next_filename
335 for ((i=0; i < ${#rdiff_excludes[@]} ; i++)); do
336 echo exclude = ${rdiff_excludes[$i]} >> $next_filename
339 cat >> $next_filename <<EOF
341 ######################################################
342 ## destination section
343 ## (where the files are copied to)
347 directory = $rdiff_directory
352 chmod 600 $next_filename
357 srcitem="choose files to include & exclude $_src_done"
358 destitem="configure backup destination $_dest_done"
359 conitem="set up ssh keys and test remote connection $_con_done"
360 advitem="edit advanced settings $_adv_done"
361 menuBox "$rdiff_title" "choose a step:" \
365 finish "finish and create config file"
369 "src") do_rdiff_src;;
370 "dest") do_rdiff_dest;;
371 "conn") do_rdiff_ssh_con;;
372 "adv") do_rdiff_adv;;
374 if [[ "$_con_done$_dest_done$_src_done" != "(DONE)(DONE)(DONE)" ]]; then
375 msgBox "$rdiff_title" "You cannot create the configuration file until the other steps are completed."
388 rdiff_title="rdiff-backup action wizard"
394 rdiff_directory=/backup/`hostname`
399 # Global variables whose '*' shall not be expanded
401 rdiff_includes=(/var/spool/cron/crontabs /var/backups /etc /root /home /usr/local/*bin /var/lib/dpkg/status*)
402 rdiff_excludes=(/home/*/.gnupg /home/*/.local/share/Trash /home/*/.Trash /home/*/.thumbnails /home/*/.beagle /home/*/.aMule /home/*/gtk-gnutella-downloads)