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]}
33 rdiff_includes=($REPLY)
39 # choose the vservers to backup (into $selected_vservers)
40 choose_one_or_more_vservers "$rdiff_title"
41 [ $? = 0 ] || return 1
44 # choose the files to backup
47 while [ -z "$REPLY" ]; do
48 formBegin "$rdiff_title - vsincludes (backup these directories from every vserver)"
49 [ -z "$rdiff_vsincludes" ] && rdiff_vsincludes="$rdiff_default_includes"
51 for i in $rdiff_vsincludes; do
63 [ $? = 0 ] || return 1
64 rdiff_vsincludes=($REPLY)
72 formBegin "$rdiff_title: excludes"
73 for ((i=0; i < ${#rdiff_excludes[@]} ; i++))
75 formItem exclude ${rdiff_excludes[$i]}
88 rdiff_excludes=($REPLY)
93 choose_host_or_vservers_or_both "$rdiff_title"
94 [ $? = 0 ] || return 1
95 case $host_or_vservers in
97 do_rdiff_host_includes
98 [ $? = 0 ] || return 1
102 [ $? = 0 ] || return 1
105 do_rdiff_host_includes
106 [ $? = 0 ] || return 1
108 [ $? = 0 ] || return 1
115 [ $? = 0 ] || return 1
125 while [ -z "$REPLY" -o -z "$rdiff_directory" -o -z "$rdiff_host" -o -z "$rdiff_user" ]
127 formBegin "$rdiff_title - destination: last three items are required"
128 formItem "keep" "$rdiff_keep"
129 formItem "dest_directory" "$rdiff_directory"
130 formItem "dest_host" "$rdiff_host"
131 formItem "dest_user" "$rdiff_user"
132 formItem "dest_type" "$rdiff_type"
136 rdiff_keep=${tmp_array[0]}
137 rdiff_directory=${tmp_array[1]}
138 rdiff_host=${tmp_array[2]}
139 rdiff_user=${tmp_array[3]}
140 rdiff_type=${tmp_array[4]}
149 local remote_status="ok"
152 if [ "$_dest_done" = "" ]; then
153 msgBox "$rdiff_title: error" "You must first configure the destination."
155 elif [ "$rdiff_type" = "" ]; then
156 msgBox "$rdiff_title: error" "You must first configure the destination backup type."
158 elif [ "$rdiff_user" = "" ]; then
159 msgBox "$rdiff_title: error" "You must first configure the destination user."
161 elif [ "$rdiff_host" = "" ]; then
162 msgBox "$rdiff_title: error" "You must first configure the destination host."
165 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?"
169 if [ ! -f /root/.ssh/id_dsa.pub -a ! -f /root/.ssh/id_rsa.pub ]; then
170 echo "Creating local root's ssh key"
171 ssh-keygen -t dsa -f /root/.ssh/id_dsa -N ""
172 echo "Done. hit return to continue"
176 ssh -o PreferredAuthentications=publickey $rdiff_host -l $rdiff_user "exit" 2> /dev/null
177 if [ $? -ne 0 ]; then
178 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."
179 ssh-copy-id -i /root/.ssh/id_[rd]sa.pub $rdiff_user@$rdiff_host
180 if [ $? -ne 0 ]; then
181 echo "FAILED: Couldn't copy root's public ssh key to authorized_keys of $rdiff_user@$rdiff_host."
182 ssh $rdiff_user@$rdiff_host 'test -w .ssh || test -w .'
184 echo "Hit return to continue."
187 0 ) msgBox "$rdiff_title: error" "Directories are writable: Probably just a typo the first time." ;;
188 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." ;;
189 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." ;;
190 * ) msgBox "$rdiff_title: error" "Unexpected error." ;;
194 echo "Done. hit return to continue"
198 echo "root@localhost is already in authorized_keys of $rdiff_user@$rdiff_host."
199 echo "Hit return to continue."
203 # test to see if the remote rdiff backup directory exists and is writable
204 echo "Testing to see if remote rdiff backup directory exists and is writable"
205 ssh $rdiff_user@$rdiff_host "test -d ${rdiff_directory}"
207 ssh $rdiff_user@$rdiff_host "test -w $rdiff_directory"
209 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."
213 booleanBox "Remote directory does not exist" "The destination backup directory does not exist, do you want me to create it for you?"
215 ssh $rdiff_user@$rdiff_host "mkdir -p ${rdiff_directory}"
218 0) msgBox "$rdiff_title: success" "Creation of the remote destination directory was a success!";;
219 1) msgBox "$rdiff_title: error" "Connected successfully to $rdiff_user@$rdiff_host, but was unable to create the destination directory, check the directory permissions."
220 remote_status=failed;;
221 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."
222 remote_status=failed;;
223 *) msgBox "$rdiff_title: error" "Unexpected error."
224 remote_status=failed;;
229 if [ "$remote_status" = "ok" ]; then
235 echo "Checking for local install of rdiff-backup"
236 require_packages rdiff-backup
238 echo "Testing to make sure destination has rdiff-backup installed and is compatible."
239 remote_result=`/usr/bin/rdiff-backup --test-server $rdiff_user@$rdiff_host::/ 2>&1 >&-`
240 if [ $? -ne 0 ]; then
241 echo $remote_result | grep -q "command not found"
242 if [ $? -eq 0 ]; then
243 if [ "$rdiff_user" = "root" ]; then
244 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?"
246 ssh $rdiff_user@$rdiff_host 'apt-get install rdiff-backup'
248 echo "Hit return to continue."
251 0) msgBox "$rdiff_title: success" "Installation of rdiff-backup was a success!"
253 1) msgBox "$rdiff_title: error" "Connected successfully to $rdiff_user@$rdiff_host, but was unable to install the package for some reason.";;
254 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.";;
255 *) msgBox "$rdiff_title: error" "Unexpected error.";;
260 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?"
268 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?"
276 echo "SUCCESS: Everything looks good!"
277 echo "Hit return to continue."
286 get_next_filename $configdirectory/90.rdiff
287 cat > $next_filename <<EOF
289 # when = everyday at 02
295 # A few notes about includes and excludes:
296 # 1. include, exclude and vsinclude statements support globbing with '*'
297 # 2. Symlinks are not dereferenced. Moreover, an include line whose path
298 # contains, at any level, a symlink to a directory, will only have the
299 # symlink backed-up, not the target directory's content. Yes, you have to
300 # dereference yourself the symlinks, or to use 'mount --bind' instead.
301 # Example: let's say /home is a symlink to /mnt/crypt/home ; the following
302 # line will only backup a "/home" symlink ; neither /home/user nor
303 # /home/user/Mail will be backed-up :
304 # include = /home/user/Mail
305 # A workaround is to 'mount --bind /mnt/crypt/home /home' ; another one is to
307 # include = /mnt/crypt/home/user/Mail
308 # 3. All the excludes come after all the includes. The order is not otherwise
309 # taken into account.
311 # files to include in the backup
314 if [ "$host_or_vservers" == host -o "$host_or_vservers" == both ]; then
316 for ((i=0; i < ${#rdiff_includes[@]} ; i++)); do
317 echo "include = ${rdiff_includes[$i]}" >> $next_filename
322 if [ "$host_or_vservers" == vservers -o "$host_or_vservers" == both ]; then
323 cat >> $next_filename <<EOF
325 # If vservers = yes in /etc/backupninja.conf then the following variables can
327 # vsnames = all | <vserver1> <vserver2> ... (default = all)
331 # Any path specified in vsinclude is added to the include list for each vserver
332 # listed in vsnames (or all if vsnames = all, which is the default).
334 # For example, vsinclude = /home will backup the /home directory in every
335 # vserver listed in vsnames. If you have 'vsnames = foo bar baz', this
336 # vsinclude will add to the include list /vservers/foo/home, /vservers/bar/home
337 # and /vservers/baz/home.
338 # Vservers paths are derived from $VROOTDIR.
342 echo -e "vsnames = $selected_vservers\n" >> $next_filename
343 for i in $rdiff_vsincludes; do
344 echo "vsinclude = $i" >> $next_filename
351 for ((i=0; i < ${#rdiff_excludes[@]} ; i++)); do
352 echo exclude = ${rdiff_excludes[$i]} >> $next_filename
355 cat >> $next_filename <<EOF
357 ######################################################
358 ## destination section
359 ## (where the files are copied to)
363 directory = $rdiff_directory
368 chmod 600 $next_filename
373 srcitem="choose files to include & exclude $_src_done"
374 destitem="configure backup destination $_dest_done"
375 conitem="set up ssh keys and test remote connection $_con_done"
376 advitem="edit advanced settings $_adv_done"
377 menuBox "$rdiff_title" "choose a step:" \
381 finish "finish and create config file"
385 "src") do_rdiff_src;;
386 "dest") do_rdiff_dest;;
387 "conn") do_rdiff_ssh_con;;
388 "adv") do_rdiff_adv;;
390 if [[ "$_con_done$_dest_done$_src_done" != "(DONE)(DONE)(DONE)" ]]; then
391 msgBox "$rdiff_title" "You cannot create the configuration file until the other steps are completed."
404 rdiff_title="rdiff-backup action wizard"
410 rdiff_directory=/backup/`hostname`
415 # Global variables whose '*' shall not be expanded
417 rdiff_includes=(/var/spool/cron/crontabs /var/backups /etc /root /home /usr/local/*bin /var/lib/dpkg/status*)
418 rdiff_excludes=(/home/*/.gnupg /home/*/.local/share/Trash /home/*/.Trash /home/*/.thumbnails /home/*/.beagle /home/*/.aMule /home/*/gtk-gnutella-downloads)