diff options
Diffstat (limited to 'handlers')
| -rw-r--r-- | handlers/easydialog.sh | 7 | ||||
| -rw-r--r-- | handlers/rdiff | 147 | ||||
| -rw-r--r-- | handlers/rdiff.helper | 141 | 
3 files changed, 190 insertions, 105 deletions
| diff --git a/handlers/easydialog.sh b/handlers/easydialog.sh index 5d70653..18cb7c3 100644 --- a/handlers/easydialog.sh +++ b/handlers/easydialog.sh @@ -237,7 +237,12 @@ formDisplay() {        done     ) | xargs $DIALOG 2> $temp     local status=$? -   [ $status = 0 ] && REPLY=`cat $temp` +    +   if [ $status = 0 ]; then +      IFS=$'' +      REPLY=`cat $temp` +      IFS=$' \t\n' +   fi     rm -f $temp     return $status  } diff --git a/handlers/rdiff b/handlers/rdiff index 40ad52d..9de8650 100644 --- a/handlers/rdiff +++ b/handlers/rdiff @@ -3,20 +3,83 @@  # 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 -o PasswordAuthentication=no $host -l $user 'echo -n 1'" +	local ret=`ssh -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` +	else +		local user=$1 +		local host=$2 +		debug "ssh $host -l $user '$RDIFFBACKUP -V'" +		echo `ssh $host -l $user "$RDIFFBACKUP -V | grep rdiff-backup"` +	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 +} + +### GET CONFIG ### +  getconf options  getconf testconnect yes  getconf nicelevel 0  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 vsinclude  getconf exclude -### DESTINATION ### -  setsection dest  getconf directory; destdir=$directory  # strip trailing / @@ -24,6 +87,9 @@ destdir=${destdir%/}  getconf type; desttype=$type  getconf user; destuser=$user  getconf host; desthost=$host +check_consistency "destination" "$type" "$user" "$host" + +### CHECK CONFIG ###  # See if vservers are configured  if [ "$vservers" = "yes" ] @@ -37,47 +103,44 @@ then  	fi  fi -[ "$destdir" != "" ] || fatal "Destination directory not set" - -if [ "$desttype" == "remote" ]; then -	# see if we can login -	if [ "$testconnect" == "yes" ]; then -		hostalive=0 -	    debug "ssh -o PreferredAuthentications=publickey $desthost -l $destuser 'echo -n 1'" -		ret=`ssh -o PreferredAuthentications=publickey $desthost -l $destuser 'echo -n host is alive'` -		if echo $ret | grep "host is alive"; then -			debug "Connected to $desthost as $destuser successfully" -		else -			fatal "Can't connect to $desthost as $destuser." -		fi -	fi -	# see that rdiff-backup has the same version as here -	debug "ssh -o PreferredAuthentications=publickey $desthost -l $destuser '$RDIFFBACKUP -V'\"" -	remoteversion=`ssh -o PreferredAuthentications=publickey $desthost -l $destuser "$RDIFFBACKUP -V | grep rdiff-backup"` -	localversion=`$RDIFFBACKUP -V` -	if [ "$remoteversion" != "$localversion" ]; then -		fatal "rdiff-backup does not have the same version on this computer and the backup server." -	fi -	execstr_serverpart="$destuser@$desthost::$destdir/$label" -else -	execstr_serverpart="$destdir/$label" +# check the connection at the source and destination +if [ "$testconnect" == "yes" -o $test ]; then +	test_connection $sourceuser $sourcehost +	test_connection $destuser $desthost  fi -### SOURCE ### +# 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 -[ "$sourcetype" == "local" ] || fatal "Only local source type supported" +# source specific checks  [ "$include" != "" -o "$vsinclude" != "" ] || fatal "No source includes specified"  #TODO should I test for vsinclude if usevservers=1? +case $sourcetype in  +	remote ) execstr_sourcepart="$sourceuser@$sourcehost::/" ;; +	local  ) execstr_sourcepart="/" ;; +	*      ) fatal "sourcetype '$sourcetype' is neither local nor remote" ;; +esac -execstr_clientpart="/" +# 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 +### REMOVE OLD BACKUPS ###  if [ "`echo $keep | tr -d 0-9`" == "" ]; then +	# add D if no other date unit is specified  	keep="${keep}D"  fi -removestr="rdiff-backup --force --remove-older-than $keep " +removestr="$RDIFFBACKUP --force --remove-older-than $keep "  if [ "$desttype" == "remote" ]; then  	removestr="${removestr}${destuser}@${desthost}::"  fi @@ -86,8 +149,7 @@ removestr="${removestr}${destdir}/${label}";  debug "$removestr"  if [ ! $test ]; then  	output=`$removestr 2>&1` -	code=$? -	if [ "$code" == "0" ]; then +	if [ $? = 0 ]; then  		debug $output  		info "Removing backups older than $keep days succeeded."  	else @@ -96,31 +158,27 @@ if [ ! $test ]; then  	fi  fi -## EXECUTE ## +### EXECUTE ###  execstr="$RDIFFBACKUP $options --print-statistics "  # 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 ]  -then -	for vserver in `ls $VROOTDIR | grep -E -v "lost+found|ARCHIVES"` -	do -		for vi in $vsinclude -		do +if [ $usevserver ]; then +	for vserver in `ls $VROOTDIR|grep -v lost+found`; do +		for vi in $vsinclude; do  			str="${vi//__star__/*}"  			execstr="${execstr}--include '$VROOTDIR/$vserver$str' "  		done @@ -131,13 +189,12 @@ fi  execstr="${execstr}--exclude '/*' "  # include client-part and server-part -execstr="${execstr}$execstr_clientpart $execstr_serverpart" +execstr="${execstr}$execstr_sourcepart $execstr_destpart"  debug "$execstr"  if [ ! $test ]; then  	output=`nice -n $nicelevel su -c "$execstr" 2>&1` -	code=$? -	if [ "$code" == "0" ]; then +	if [ $? = 0 ]; then  		debug $output  		info "Successfully finished backing up source $label"  	else diff --git a/handlers/rdiff.helper b/handlers/rdiff.helper index 8be68ac..066d53a 100644 --- a/handlers/rdiff.helper +++ b/handlers/rdiff.helper @@ -1,68 +1,78 @@  HELPERS="$HELPERS rdiff:incremental_remote_filesystem_backup" +declare -a rdiff_includes +declare -a rdiff_excludes +  do_rdiff_dest() { -   formBegin "rdiff action wizard" -     formItem "keep" "$rdiff_keep" -     formItem "dest_directory" "$rdiff_directory" -     formItem "dest_host" "$rdiff_host" -     formItem "dest_user" "$rdiff_user" -   formDisplay -   [ $? = 1 ] && return; -        -   set -- $REPLY -	rdiff_keep=$1 -	rdiff_directory=$2 -	rdiff_host=$3 -	rdiff_user=$4 +  set -o noglob +  formBegin "rdiff action wizard" +    formItem "keep" "$rdiff_keep" +    formItem "dest_directory" "$rdiff_directory" +    formItem "dest_host" "$rdiff_host" +    formItem "dest_user" "$rdiff_user" +  formDisplay +  [ $? = 1 ] && return; + +  IFS=$'' +  replyconverted=`echo $REPLY | tr '\n' :` +  IFS=$':' +  thereply=($replyconverted) +  IFS=$' \t\n' +   +  rdiff_keep=${thereply[0]} +  rdiff_directory=${thereply[1]} +  rdiff_host=${thereply[2]} +  rdiff_user=${thereply[3]}    _dest_done="(DONE)"    setDefault conn +  set +o noglob  }  do_rdiff_src() { -   formBegin "rdiff action wizard: includes" -     formItem include /var/spool/cron/crontabs -     formItem include /var/backups -     formItem include /etc -     formItem include /root -     formItem include /home -     formItem include '/usr/local/*bin' -     formItem include '/var/lib/dpkg/status*' -     formItem include  -     formItem include  -     formItem include  -   formDisplay -   [ $? = 1 ] && return; - -   rdiff_includes=    -   set -o noglob -   for i in $REPLY; do -      [ "$i" != "" ] && rdiff_includes="$rdiff_includes\ninclude = $i" -   done -   set +o noglob - -   formBegin "rdiff action wizard: excludes"  -     formItem exclude '/home/*/.gnupg' -     formItem exclude  -     formItem exclude  -   formDisplay -   [ $? = 1 ] && return; - -   rdiff_excludes= -   set -o noglob -   for i in $REPLY; do -      [ "$i" != "" ] && rdiff_excludes="$rdiff_excludes\nexclude = $i" -   done -   set +o noglob +  #echo ${rdiff_includes[@]} +  set -o noglob +  formBegin "rdiff action wizard: includes" +    for ((i=0; i < ${#rdiff_includes[@]} ; i++)); do +       formItem include ${rdiff_includes[$i]} +    done +    formItem include  +    formItem include  +    formItem include  +  formDisplay +  [ $? = 1 ] && return; + +  unset rdiff_includes +  rdiff_includes=($REPLY) + +  formBegin "rdiff action wizard: excludes"  +    for ((i=0; i < ${#rdiff_excludes[@]} ; i++)); do +       formItem exclude ${rdiff_excludes[$i]} +    done +    formItem exclude  +    formItem exclude  +  formDisplay +  [ $? = 1 ] && return; + +  unset rdiff_excludes +  rdiff_excludes=($REPLY) -   _src_done="(DONE)" -   setDefault dest +  _src_done="(DONE)" +  setDefault dest +  set +o noglob  }  do_rdiff_con() { +  IFS=$' \t\n'    if [ "$_dest_done" = "" ]; then -    msgBox "rdiff action wizard: error" "You must first configure the destination" +    msgBox "rdiff action wizard: error" "You must first configure the destination." +    return +  elif [ "$rdiff_user" = "" ]; then +    msgBox "rdiff action wizard: error" "You must first configure the destination user." +    return +  elif [ "$rdiff_host" = "" ]; then +    msgBox "rdiff action wizard: error" "You must first configure the destination host."      return    else      booleanBox "rdiff action wizard" "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. Are you sure you want to continue?" @@ -78,15 +88,18 @@ do_rdiff_con() {    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. Specify the password for user $rdiff_user@$rdiff_host." +    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 "Couldn't copy root's public ssh key to authorized_keys of $rdiff_user@$rdiff_host. This time, testing whether directory is writable." +      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 .' -      case $? in +      result=$? +      echo "Hit return to continue." +      read +      case $result in          0 )   msgBox "rdiff action wizard: error" "Directories are writable: Probably just a typo the first time." ;;          1 )   msgBox "rdiff action wizard: 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 action wizard: error" "Failed to connect to $rdiff_user@$rdiff_host. Check hostname, username, and password." ;; +        255 ) msgBox "rdiff action wizard: 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 action wizard: error" "Unexpected error." ;;        esac         return @@ -112,9 +125,15 @@ do_rdiff_finish() {  type = local  keep = $rdiff_keep  EOF -   echo -n -e "$rdiff_includes" >> $next_filename -   echo -e "$rdiff_excludes" >> $next_filename -   cat >> $next_filename <<EOF +    set -o noglob +    for ((i=0; i < ${#rdiff_includes[@]} ; i++)); do +        echo include = ${rdiff_includes[$i]} +    done +    for ((i=0; i < ${#rdiff_includes[@]} ; i++)); do +        echo exclude = ${rdiff_excludes[$i]} +    done +    set +o noglob +    cat >> $next_filename <<EOF  [dest]  type = remote @@ -126,6 +145,7 @@ EOF  }  rdiff_main_menu() { +    while true; do      srcitem="choose files to include & exclude $_src_done"      destitem="configure backup destination $_dest_done" @@ -138,6 +158,7 @@ rdiff_main_menu() {          finish "finish and create config file"      [ $? = 1 ] && return;      result="$REPLY" +      case "$result" in         "src") do_rdiff_src;;         "dest") do_rdiff_dest;; @@ -152,12 +173,12 @@ rdiff_main_menu() {            fi            ;;      esac -     +    done  }  rdiff_wizard() { -#   require_packages rdiff-backup +  require_packages rdiff-backup    _src_done=    _dest_done=    _con_done= @@ -166,6 +187,8 @@ rdiff_wizard() {    rdiff_directory=/backup/`hostname`    rdiff_user=    rdiff_host= +  rdiff_includes=(/var/spool/cron/crontabs /var/backups /etc /root /home /usr/local/*bin /var/lib/dpkg/status*) +  rdiff_excludes=(/home/*/.gnupg)    rdiff_main_menu  } | 
