Reafactor of xtrabackup scripts
Fix authorized_keys file

Related: PROD-26996(PROD-26996)

(cherry picked from commit 92b8ff4c93103a07d0855820aca03e6d383975e7)
(cherry picked from commit e72102718205baad49fdf569a582fc211fffc071)

Change-Id: I882785b84220cff39667f879ff9ba964dbe47808
diff --git a/xtrabackup/files/innobackupex-client-restore-call.sh b/xtrabackup/files/innobackupex-client-restore-call.sh
index b6798f3..3adafd5 100644
--- a/xtrabackup/files/innobackupex-client-restore-call.sh
+++ b/xtrabackup/files/innobackupex-client-restore-call.sh
@@ -1,52 +1,66 @@
 {%- from "xtrabackup/map.jinja" import client with context %}
-#!/bin/sh
-
+#!/bin/bash
+set -eo pipefail
 # Purpuse of this script is to locally prepare appropriate backup to restore from local or remote location
-
+# Variables, initiated via salt-formulas/xtrabackup
 {%- if client.restore_from == 'remote' %}
-LOGDIR=/var/log/backups
-mkdir -p $LOGDIR
-scpLog=/var/log/backups/innobackupex-restore-scp.log
-echo "Adding ssh-key of remote host to known_hosts"
-ssh-keygen -R {{ client.target.host }} 2>&1 | > $scpLog
-ssh-keyscan {{ client.target.host }} >> ~/.ssh/known_hosts  2>&1 | >> $scpLog
-REMOTEBACKUPPATH=`ssh xtrabackup@{{ client.target.host }} "/usr/local/bin/innobackupex-restore-call.sh {{ client.restore_full_latest }}"`
-echo "Calling /usr/local/bin/innobackupex-restore.sh $REMOTEBACKUPPATH and getting the backup files from remote host"
-/usr/local/bin/innobackupex-restore.sh $REMOTEBACKUPPATH
-
+RESTORE_FROM_MODE="remote"
+CLIENT_TARGET_HOST="{{ client.target.host }}"
+CLIENT_RESTORE_FULL_LATEST="{{ client.restore_full_latest }}"
 {%- else %}
+RESTORE_FROM_MODE="local"
+BACKUPDIR="{{ client.backup_dir }}" # Backups base directory
+{%- endif %}
 
-BACKUPDIR={{ client.backup_dir }} # Backups base directory
-FULL=`find $BACKUPDIR/full -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -{{ client.restore_full_latest }} | tail -1`
-FULL_INCR=`find $BACKUPDIR/incr -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -{{ client.restore_full_latest }} | tail -1`
-BEFORE_NEXT_FULL_INCR=`find $BACKUPDIR/incr -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -$(( {{ client.restore_full_latest }} - 1 )) | tail -1`
+function backup_remote(){
+  local LOGDIR="/var/log/backups"
+  local scpLog="/var/log/backups/innobackupex-restore-scp.log"
+  mkdir -p $LOGDIR
+  echo "Adding ssh-key of remote host to known_hosts"
+  ssh-keyscan ${CLIENT_TARGET_HOST} >> ~/.ssh/known_hosts  2>&1 | >> $scpLog
+  echo "Calling /usr/local/bin/innobackupex-restore.sh $REMOTEBACKUPPATH and getting the backup files from remote host"
+  REMOTEBACKUPPATH="$(ssh xtrabackup@${CLIENT_TARGET_HOST} "/bin/bash /usr/local/bin/innobackupex-restore-call.sh ${CLIENT_RESTORE_FULL_LATEST}")"
+  /usr/local/bin/innobackupex-restore.sh $REMOTEBACKUPPATH
+  ssh-keygen -R ${CLIENT_TARGET_HOST} 2>&1 | > $scpLog
+}
 
-if [ -z "$FULL" ]; then
+function backup_local(){
+  local FULL="$(find $BACKUPDIR/full -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -${CLIENT_RESTORE_FULL_LATEST}| tail -1)"
+  local FULL_INCR="$(find $BACKUPDIR/incr -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -${CLIENT_RESTORE_FULL_LATEST} | tail -1)"
+  local BEFORE_NEXT_FULL_INCR="$(find $BACKUPDIR/incr -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -$(( ${CLIENT_RESTORE_FULL_LATEST} - 1 )) | tail -1)"
+
+  if [ -z "$FULL" ]; then
     echo "Error: No local backup found in $BACKUPDIR/full" >&2
     exit 1
-fi
+  fi
 
-if [ -z "$BEFORE_NEXT_FULL_INCR" ]; then
+  if [ -z "$BEFORE_NEXT_FULL_INCR" ]; then
     BEFORE_NEXT_FULL_INCR="Empty"
-fi
+  fi
 
-if [ "$FULL" = "$FULL_INCR" ]; then
-  LATEST_FULL_INCR=`find $BACKUPDIR/incr/$FULL_INCR -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -1 | tail -1`
-  echo "Restoring full backup $FULL starting from its latest incremental $LATEST_FULL_INCR"
-  echo "Calling /usr/local/bin/innobackupex-restore.sh $BACKUPDIR/incr/$FULL/$LATEST_FULL_INCR"
-  echo
-  /usr/local/bin/innobackupex-restore.sh $BACKUPDIR/incr/$FULL_INCR/$LATEST_FULL_INCR
-elif [ "$FULL" = "$BEFORE_NEXT_FULL_INCR" ]; then
-  LATEST_FULL_INCR=`find $BACKUPDIR/incr/$BEFORE_NEXT_FULL_INCR -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -1 | tail -1`
-  echo "Restoring full backup $FULL starting from its latest incremental $LATEST_FULL_INCR"
-  echo "Calling /usr/local/bin/innobackupex-restore.sh $BACKUPDIR/incr/$FULL/$LATEST_FULL_INCR"
-  echo
-  /usr/local/bin/innobackupex-restore.sh $BACKUPDIR/incr/$FULL/$LATEST_FULL_INCR
-else
-  echo "Restoring full backup $FULL"
-  echo "Calling /usr/local/bin/innobackupex-restore.sh $BACKUPDIR/full/$FULL"
-  echo
-  /usr/local/bin/innobackupex-restore.sh $BACKUPDIR/full/$FULL
-fi
+  if [ "$FULL" = "$FULL_INCR" ]; then
+    LATEST_FULL_INCR=$(find $BACKUPDIR/incr/$FULL_INCR -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -1 | tail -1)
+    echo "Restoring full backup $FULL starting from its latest incremental $LATEST_FULL_INCR"
+    echo "Calling /usr/local/bin/innobackupex-restore.sh $BACKUPDIR/incr/$FULL/$LATEST_FULL_INCR"
+    echo
+    /usr/local/bin/innobackupex-restore.sh $BACKUPDIR/incr/$FULL_INCR/$LATEST_FULL_INCR
+    elif [ "$FULL" = "$BEFORE_NEXT_FULL_INCR" ]; then
+    LATEST_FULL_INCR="$(find $BACKUPDIR/incr/$BEFORE_NEXT_FULL_INCR -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -1 | tail -1)"
+    echo "Restoring full backup $FULL starting from its latest incremental $LATEST_FULL_INCR"
+    echo "Calling /usr/local/bin/innobackupex-restore.sh $BACKUPDIR/incr/$FULL/$LATEST_FULL_INCR"
+    echo
+    /usr/local/bin/innobackupex-restore.sh $BACKUPDIR/incr/$FULL/$LATEST_FULL_INCR
+  else
+    echo "Restoring full backup $FULL"
+    echo "Calling /usr/local/bin/innobackupex-restore.sh $BACKUPDIR/full/$FULL"
+    echo
+    /usr/local/bin/innobackupex-restore.sh $BACKUPDIR/full/$FULL
+  fi
+}
 
-{%- endif %}
+# Body ########################################################################
+if [[ ${RESTORE_FROM_MODE} == "remote" ]]; then
+  backup_remote
+  elif [[ ${RESTORE_FROM_MODE} == "local" ]]; then
+  backup_local
+fi
diff --git a/xtrabackup/files/innobackupex-client-restore.sh b/xtrabackup/files/innobackupex-client-restore.sh
index abd08c2..5d8bc4b 100644
--- a/xtrabackup/files/innobackupex-client-restore.sh
+++ b/xtrabackup/files/innobackupex-client-restore.sh
@@ -1,219 +1,220 @@
 {%- from "xtrabackup/map.jinja" import client with context %}
 {%- from "xtrabackup/map.jinja" import server with context %}
-#!/bin/sh
+#!/bin/bash
 #
 # Script to prepare and restore full and incremental backups created with innobackupex-runner.
 #
 # usage example for incr backup restore: ./restore.sh /var/backups/mysql/xtrabackup/incr/2017-05-24_19-48-10/2017-05-24_19-55-35/
-
+set -eo pipefail
 #TMPFILE="/var/log/backups/innobackupex-restore.$$.tmp"
+BACKUPDIR="{{ client.backup_dir }}" # Backups base directory
+{%- if client.restore_from == 'remote' %}
+RESTORE_FROM_MODE="remote"
+{%- endif %}
+QPRESS_URL="{{ client.qpress.name }}"
+CLIENT_TARGET_HOST="{{ client.target.host }}"
+SERVERBACKUPDIR="{{ server.backup_dir }}"
 TMPFILE="/var/log/backups/innobackupex-restore.log"
-MYCNF=/etc/mysql/my.cnf
-BACKUPDIR={{ client.backup_dir }} # Backups base directory
-FULLBACKUPDIR=$BACKUPDIR/full # Full backups directory
-INCRBACKUPDIR=$BACKUPDIR/incr # Incremental backups directory
-MEMORY=1024M # Amount of memory to use when preparing the backup
-DBALREADYRESTORED=$BACKUPDIR/dbrestored
-scpLog=/var/log/backups/innobackupex-restore-scp.log
-decompressionLog=/var/log/backups/innobackupex-decompression.log
-compression=false
-LOGDIR=/var/log/backups
-
+MYCNF="/etc/mysql/my.cnf"
+FULLBACKUPDIR="$BACKUPDIR/full" # Full backups directory
+INCRBACKUPDIR="$BACKUPDIR/incr" # Incremental backups directory
+MEMORY="1024M" # Amount of memory to use when preparing the backup
+DBALREADYRESTORED="$BACKUPDIR/dbrestored"
+scpLog="/var/log/backups/innobackupex-restore-scp.log"
+decompressionLog="/var/log/backups/innobackupex-decompression.log"
+compression="false"
+LOGDIR="/var/log/backups"
 mkdir -p $LOGDIR
+REMOTE_PARENT_DIR="$(dirname $1)"
+BACKUPPATH="$1"
 
 #############################################################################
 # Display error message and exit
 #############################################################################
-error()
-{
-	echo "$1" 1>&2
-	exit 1
+error(){
+  echo "$1" 1>&2
+  exit 1
 }
 
 #############################################################################
 # Check for errors in innobackupex output
 #############################################################################
-check_innobackupex_error()
-{
-	if [ -z "`tail -1 $TMPFILE | grep 'completed OK!'`" ] ; then
+check_innobackupex_error(){
+  if [ -z "$(tail -1 $TMPFILE | grep 'completed OK!')" ] ; then
     echo "$INNOBACKUPEX failed:"; echo
     echo "---------- ERROR OUTPUT from $INNOBACKUPEX ----------"
     cat $TMPFILE
-    #rm -f $TMPFILE
     exit 1
   fi
 }
 
-# Check options before proceeding
-if [ -e $DBALREADYRESTORED ]; then
-  error "Databases already restored. If you want to restore again delete $DBALREADYRESTORED file and run the script again."
-fi
 
-if [ ! -d $BACKUPDIR ]; then
-  error "Backup destination folder: $BACKUPDIR does not exist."
-fi
+function install_qpress(){
+  wget -O qpress.tar ${QPRESS_TAR} > $decompressionLog 2>&1 || true
+  tar -xvf qpress.tar
+  cp qpress  /usr/bin/qpress
+  chmod 755 /usr/bin/qpress
+  chown root:root /usr/bin/qpress
+}
 
-if [ $# != 1 ] ; then
-  error "Usage: $0 /absolute/path/to/backup/to/restore"
-fi
 
-{%- if client.restore_from != 'remote' %}
-
-if [ ! -d $1 ]; then
-  error "Backup to restore: $1 does not exist."
-fi
-
-{%- endif %}
-
-# Some info output
-echo "----------------------------"
-echo
-echo "$0: MySQL backup script"
-echo "started: `date`"
-echo
-
-{%- if client.restore_from == 'remote' %}
-#get files from remote and change variables to local restore dir
-
-LOCALRESTOREDIR=/var/backups/restoreMysql
-REMOTE_PARENT_DIR=`dirname $1`
-BACKUPPATH=$1
-FULLBACKUPDIR=$LOCALRESTOREDIR/full
-INCRBACKUPDIR=$LOCALRESTOREDIR/incr
-
-mkdir -p $LOCALRESTOREDIR
-rm -rf $LOCALRESTOREDIR/*
-
-echo "Getting files from remote host"
-
-case "$BACKUPPATH" in
-  *incr*) echo "SCP getting full and incr backup files";
-          FULL=`basename $REMOTE_PARENT_DIR`;
-          mkdir -p $FULLBACKUPDIR;
-          mkdir -p $INCRBACKUPDIR;
-          PARENT_DIR=$INCRBACKUPDIR/$FULL;
-          `scp -rp xtrabackup@{{ client.target.host }}:$REMOTE_PARENT_DIR/ $INCRBACKUPDIR/ >> $scpLog 2>&1`;
-          `scp -rp xtrabackup@{{ client.target.host }}:{{ server.backup_dir }}/full/$FULL/ $FULLBACKUPDIR/$FULL/ >> $scpLog 2>&1`;;
-  *full*) echo "SCP getting full backup files";
-          FULL=`basename $1`;
-          mkdir -p $FULLBACKUPDIR;
-          PARENT_DIR=$FULLBACKUPDIR;
-          `scp -rp xtrabackup@{{ client.target.host }}:{{ server.backup_dir }}/full/$FULL/ $FULLBACKUPDIR/$FULL/  >> $scpLog 2>&1`;;
-  *)      echo "Unable to scp backup files from remote host"; exit 1 ;;
-esac
-
-# Check if the scp succeeded or failed
-if ! grep -q "No such file or directory" $scpLog; then
-        echo "SCP from remote host completed OK"
-else
-        echo "SCP from remote host FAILED"
-        exit 1
-fi
-
-{%- else %}
-
-PARENT_DIR=`dirname $1`
-
-{%- endif %}
-
-if [ $PARENT_DIR = $FULLBACKUPDIR ]; then
-{%- if client.restore_from == 'remote' %}
-  FULLBACKUP=$FULLBACKUPDIR/$FULL
-{%- else %}
-  FULLBACKUP=$1
-{%- endif %}
-
-  for bf in `find . $FULLBACKUP -iname "*\.qp"`; do compression=True; break; done
-
-  if [ "$compression" = True ]; then
-    if hash qpress 2>>$TMPFILE;  then
-        echo "qpress already installed" >> $TMPFILE
-    else
-{%- if client.qpress.source == 'tar' %}
-        wget {{ client.qpress.name }} > $decompressionLog 2>&1
-        tar -xvf qpress-11-linux-x64.tar
-        cp qpress  /usr/bin/qpress
-        chmod 755 /usr/bin/qpress
-        chown root:root /usr/bin/qpress
-{%- endif %}
-    fi
-    echo "Uncompressing $FULLBACKUP"
-    for bf in `find . $FULLBACKUP -iname "*\.qp"`; do qpress -d $bf $(dirname $bf) && rm $bf; done > $decompressionLog 2>&1
+function prerequisites(){
+  # Check options before proceeding
+  if [ -e $DBALREADYRESTORED ]; then
+    error "Databases already restored. If you want to restore again delete $DBALREADYRESTORED file and run the script again."
   fi
 
-  echo "Restore `basename $FULLBACKUP`"
+  if [ ! -d $BACKUPDIR ]; then
+    error "Backup destination folder: $BACKUPDIR does not exist."
+  fi
+
+  if [ $1 != 1 ] ; then
+    error "Usage: $2 /absolute/path/to/backup/to/restore"
+  fi
+
+  if [[ ${RESTORE_FROM_MODE} != "remote" ]]; then
+    if [ ! -d $BACKUPPATH ]; then
+      error "Backup to restore: $BACKUPPATH does not exist."
+    fi
+  fi
+}
+
+function scp_data(){
+  # Some info output
+  echo "----------------------------"
   echo
-else
-  if [ `dirname $PARENT_DIR` = $INCRBACKUPDIR ]; then
-    INCR=`basename $1`
-    FULL=`basename $PARENT_DIR`
-    FULLBACKUP=$FULLBACKUPDIR/$FULL
+  echo "$0: MySQL backup script"
+  echo "started: $(date)"
+  echo
+  if [[ ${RESTORE_FROM_MODE} == "remote" ]]; then
+    #get files from remote and change variables to local restore dir
 
+    LOCALRESTOREDIR="/var/backups/restoreMysql"
+    FULLBACKUPDIR="$LOCALRESTOREDIR/full"
+    INCRBACKUPDIR="$LOCALRESTOREDIR/incr"
 
-    if [ ! -d $FULLBACKUP ]; then
-      error "Full backup: $FULLBACKUP does not exist."
+    mkdir -p $LOCALRESTOREDIR
+    rm -rf $LOCALRESTOREDIR/*
+
+    echo "Getting files from remote host"
+
+    case "$BACKUPPATH" in
+      *incr*) echo "SCP getting full and incr backup files";
+        FULL=$(basename $REMOTE_PARENT_DIR);
+        mkdir -p $FULLBACKUPDIR;
+        mkdir -p $INCRBACKUPDIR;
+        PARENT_DIR="$INCRBACKUPDIR/$FULL";
+        $(scp -rp xtrabackup@$CLIENT_TARGET_HOST:$REMOTE_PARENT_DIR/ $INCRBACKUPDIR/ >> $scpLog 2>&1);
+      $(scp -rp xtrabackup@$CLIENT_TARGET_HOST:$SERVERBACKUPDIR/full/$FULL/ $FULLBACKUPDIR/$FULL/ >> $scpLog 2>&1);;
+      *full*) echo "SCP getting full backup files";
+        FULL=$(basename $BACKUPPATH);
+        mkdir -p $FULLBACKUPDIR;
+        PARENT_DIR=$FULLBACKUPDIR;
+      $(scp -rp xtrabackup@$CLIENT_TARGET_HOST:$SERVERBACKUPDIR/full/$FULL/ $FULLBACKUPDIR/$FULL/  >> $scpLog 2>&1);;
+      *)      echo "Unable to scp backup files from remote host"; exit 1 ;;
+    esac
+
+    # Check if the scp succeeded or failed
+    if ! grep -q "No such file or directory" $scpLog; then
+      echo "SCP from remote host completed OK"
+    else
+      echo "SCP from remote host FAILED"
+      exit 1
     fi
 
-    for bf in `find . $FULLBACKUP -iname "*\.qp"`; do compression=True; break; done
+  else
+    PARENT_DIR="$(dirname $BACKUPPATH)"
+  fi
+
+}
+
+function restore_preperation(){
+  if [ $PARENT_DIR = $FULLBACKUPDIR ]; then
+    if [[ ${RESTORE_FROM_MODE} == "remote" ]]; then
+      FULLBACKUP=$FULLBACKUPDIR/$FULL
+    else
+      FULLBACKUP=$BACKUPPATH
+    fi
+    for bf in $(find . $FULLBACKUP -iname "*\.qp"); do compression=True; break; done
 
     if [ "$compression" = True ]; then
-      if hash qpress 2>>$decompressionLog;  then
-          echo "qpress already installed" >> $decompressionLog
+      if hash qpress 2>>$TMPFILE;  then
+        echo "qpress already installed" >> $TMPFILE
       else
-{%- if client.qpress.source == 'tar' %}
-          wget {{ client.qpress.name }} > $decompressionLog 2>&1
-          tar -xvf qpress-11-linux-x64.tar
-          cp qpress  /usr/bin/qpress
-          chmod 755 /usr/bin/qpress
-          chown root:root /usr/bin/qpress
-{%- endif %}
+        install_qpress
       fi
       echo "Uncompressing $FULLBACKUP"
-      for bf in `find . $FULLBACKUP -iname "*\.qp"`; do qpress -d $bf $(dirname $bf) && rm $bf; done > $decompressionLog 2>&1
-      echo "Uncompressing $PARENT_DIR"
-      for bf in `find . $PARENT_DIR -iname "*\.qp"`; do qpress -d $bf $(dirname $bf) && rm $bf; done >> $decompressionLog 2>&1
+      for bf in $(find . $FULLBACKUP -iname "*\.qp"); do qpress -d $bf $(dirname $bf) && rm $bf; done > $decompressionLog 2>&1
     fi
 
+    echo "Restore $(basename $FULLBACKUP)"
     echo
-    echo "Restore $FULL up to incremental $INCR"
-    echo
+  else
+    if [ $(dirname $PARENT_DIR) = $INCRBACKUPDIR ]; then
+      INCR="$(basename $BACKUPPATH)"
+      FULL="$(basename $PARENT_DIR)"
+      FULLBACKUP="$FULLBACKUPDIR/$FULL"
 
-    echo "Replay committed transactions on full backup"
-    innobackupex --defaults-file=$MYCNF --apply-log --redo-only --use-memory=$MEMORY $FULLBACKUP > $TMPFILE 2>&1
-    check_innobackupex_error
 
-    # Apply incrementals to base backup
-    for i in `find $PARENT_DIR -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -n`; do
-      echo "Applying $i to full ..."
-      innobackupex --defaults-file=$MYCNF --apply-log --redo-only --use-memory=$MEMORY $FULLBACKUP --incremental-dir=$PARENT_DIR/$i > $TMPFILE 2>&1
+      if [ ! -d $FULLBACKUP ]; then
+        error "Full backup: $FULLBACKUP does not exist."
+      fi
+
+      for bf in $(find . $FULLBACKUP -iname "*\.qp"); do compression=True; break; done
+
+      if [ "$compression" = True ]; then
+        if hash qpress 2>>$decompressionLog;  then
+          echo "qpress already installed" >> $decompressionLog
+        else
+          install_qpress
+        fi
+        echo "Uncompressing $FULLBACKUP"
+        for bf in $(find . $FULLBACKUP -iname "*\.qp"); do qpress -d $bf $(dirname $bf) && rm $bf; done > $decompressionLog 2>&1
+        echo "Uncompressing $PARENT_DIR"
+        for bf in $(find . $PARENT_DIR -iname "*\.qp"); do qpress -d $bf $(dirname $bf) && rm $bf; done >> $decompressionLog 2>&1
+      fi
+
+      echo
+      echo "Restore $FULL up to incremental $INCR"
+
+      echo "Replay committed transactions on full backup"
+      innobackupex --defaults-file="$MYCNF" --apply-log --redo-only --use-memory="$MEMORY" $FULLBACKUP > $TMPFILE 2>&1 || true
       check_innobackupex_error
 
-      if [ $INCR = $i ]; then
-        break # break. we are restoring up to this incremental.
-      fi
-    done
-  else
-    error "unknown backup type"
+      # Apply incrementals to base backup
+      for i in $(find $PARENT_DIR -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -n); do
+        echo "Applying $i to full ..."
+        innobackupex --defaults-file=$MYCNF --apply-log --redo-only --use-memory=$MEMORY $FULLBACKUP --incremental-dir=$PARENT_DIR/$i > $TMPFILE 2>&1 || true
+        check_innobackupex_error
+
+        if [ $INCR = $i ]; then
+          break # break. we are restoring up to this incremental.
+        fi
+      done
+    else
+      error "unknown backup type"
+    fi
   fi
-fi
+}
+function restore(){
+  echo "Preparing ..."
+  innobackupex --defaults-file=$MYCNF --apply-log --use-memory=$MEMORY $FULLBACKUP > $TMPFILE 2>&1 || true
+  check_innobackupex_error
 
-echo "Preparing ..."
-innobackupex --defaults-file=$MYCNF --apply-log --use-memory=$MEMORY $FULLBACKUP > $TMPFILE 2>&1
-check_innobackupex_error
+  echo "Restoring ..."
+  innobackupex --defaults-file=$MYCNF --copy-back $FULLBACKUP > $TMPFILE 2>&1 || true
+  check_innobackupex_error
+  chown -R mysql:mysql /var/lib/mysql
+  #rm -f $TMPFILE
+  touch $DBALREADYRESTORED
+  echo "Backup restored successfully. You are able to start mysql now."
+  echo "Verify files ownership in mysql data dir."
+  #echo "Run 'chown -R mysql:mysql /path/to/data/dir' if necessary."
+  echo "completed: $(date)"
+  exit 0
+}
 
-echo
-echo "Restoring ..."
-innobackupex --defaults-file=$MYCNF --copy-back $FULLBACKUP > $TMPFILE 2>&1
-check_innobackupex_error
-chown -R mysql:mysql /var/lib/mysql
-#rm -f $TMPFILE
-touch $DBALREADYRESTORED
-echo "Backup restored successfully. You are able to start mysql now."
-echo "Verify files ownership in mysql data dir."
-#echo "Run 'chown -R mysql:mysql /path/to/data/dir' if necessary."
-echo
-echo "completed: `date`"
-exit 0
-{#
-# vim: ft=jinja
-#}
+prerequisites "$#" "$0"
+scp_data
+restore_preperation
+restore
diff --git a/xtrabackup/files/innobackupex-client-runner.sh b/xtrabackup/files/innobackupex-client-runner.sh
index fb20ac4..a0ae1ac 100644
--- a/xtrabackup/files/innobackupex-client-runner.sh
+++ b/xtrabackup/files/innobackupex-client-runner.sh
@@ -1,15 +1,14 @@
-{%- from "xtrabackup/map.jinja" import client with context %}
 {%- from "xtrabackup/map.jinja" import server with context %}
-#!/bin/sh -eo pipefile
+{%- from "xtrabackup/map.jinja" import client with context %}
+
+#!/bin/bash
 #
 # Script to create full and incremental backups (for all databases on server) using innobackupex from Percona.
 # http://www.percona.com/doc/percona-xtrabackup/innobackupex/innobackupex_script.html
 #
 # Every time it runs will generate an incremental backup except for the first time (full backup).
 # FULLBACKUPLIFE variable will define your full backups schedule.
-
-SKIPCLEANUP=false
-FORCEFULL=false
+set -eo pipefail
 
 usage () {
   echo ""
@@ -20,238 +19,256 @@
   echo "     -h shows this help"
 }
 
+SKIPCLEANUP="false"
+FORCEFULL="false"
 while getopts ":sfh" opt; do
-    case $opt in
-        s)
-            echo "Cleanup will be skipped" >&2
-            SKIPCLEANUP=true
-        ;;
-        f)
-            echo "Full backup will be force triggered"
-            FORCEFULL=true
-        ;;
-        h)
-            usage
-            exit 0
-        ;;
-        \?)
-            echo "Invalid option: -$OPTARG" >&2
-            usage
-            exit 1
-        ;;
-    esac
+  case $opt in
+    s)
+      echo "Cleanup will be skipped" >&2
+      SKIPCLEANUP="true"
+    ;;
+    f)
+      echo "Full backup will be force triggered"
+      FORCEFULL="true"
+    ;;
+    h)
+      usage
+      exit 0
+    ;;
+    \?)
+      echo "Invalid option: -$OPTARG" >&2
+      usage
+      exit 1
+    ;;
+  esac
 done
 USEROPTIONS="--user={{ client.database.user }} --password={{ client.database.password }}{%- if client.database.host is defined %} --host {{ client.database.host }} --port {{ client.database.get('port', '3306') }}{%- else %} --socket=/var/run/mysqld/mysqld.sock{%- endif %}"
 #TMPFILE="/var/log/backups/innobackupex-runner.$$.tmp"
-LOGDIR=/var/log/backups
+LOGDIR="/var/log/backups"
 TMPFILE="/var/log/backups/innobackupex-runner.log"
-MYCNF=/etc/mysql/my.cnf
-MYSQL=/usr/bin/mysql
-MYSQLADMIN=/usr/bin/mysqladmin
-BACKUPDIR={{ client.backup_dir }} # Client side backups base directory
-SERVERBACKUPDIR={{ server.backup_dir }} # Server side backups base directory
-FULLBACKUPDIR=$BACKUPDIR/full # Full backups directory
-INCRBACKUPDIR=$BACKUPDIR/incr # Incremental backups directory
-KEEP={{ client.full_backups_to_keep }} # Number of full backups (and its incrementals) to keep
+MYCNF="/etc/mysql/my.cnf"
+MYSQL="/usr/bin/mysql"
+MYSQLADMIN="/usr/bin/mysqladmin"
+BACKUPDIR="{{ client.backup_dir }}" # Client side backups base directory
+SERVERBACKUPDIR="{{ server.backup_dir }}" # Server side backups base directory
+SERVERBACKUPHOST="{{ client.target.host }}"
+FULLBACKUPDIR="$BACKUPDIR/full" # Full backups directory
+INCRBACKUPDIR="$BACKUPDIR/incr" # Incremental backups directory
+KEEP="{{ client.full_backups_to_keep }}" # Number of full backups (and its incrementals) to keep
 {%- if client.backup_times is defined %}
-INCRBEFOREFULL={{ client.incr_before_full }}
+INCRBEFOREFULL="{{ client.incr_before_full }}"
 {%- else %}
-HOURSFULLBACKUPLIFE={{ client.hours_before_full }} # Lifetime of the latest full backup in hours
-FULLBACKUPLIFE=$(( $HOURSFULLBACKUPLIFE * 60 * 60 ))
+HOURSFULLBACKUPLIFE="{{ client.hours_before_full }}" # Lifetime of the latest full backup in hours
+FULLBACKUPLIFE="$(( $HOURSFULLBACKUPLIFE * 60 * 60 ))"
 {%- endif %}
-
-rsyncLog=/var/log/backups/innobackupex-rsync.log
-
+rsyncLog="/var/log/backups/innobackupex-rsync.log"
 {%- if client.compression is defined %}
-compression={{ client.compression }}
+compression="{{ client.compression }}"
 {%- else %}
-compression=false
+compression="false"
 {%- endif %}
-
 {%- if client.compression_threads is defined %}
-compression_threads={{ client.compression_threads }}
+compression_threads="{{ client.compression_threads }}"
 {%- else %}
-compression_threads=1
+compression_threads="1"
 {%- endif %}
-
-mkdir -p $LOGDIR
+{%- if client.throttle is defined %}
+throttle="--throttle {{ client.get('throttle', 20) }}"
+{%- else %}
+throttle=""
+{%- endif %}
+{%- if client.backup_times is defined %}
+BACKUPTIME="true"
+{%- endif %}
 
 # Grab start time
-STARTED_AT=`date +%s`
+STARTED_AT="$(date +%s)"
 
 #############################################################################
 # Display error message and exit
 #############################################################################
 error()
 {
-	echo "$1" 1>&2
-	exit 1
+  echo "$1" 1>&2
+  exit 1
 }
 
-# Check prerequisites before proceeding
-if [ ! -d $BACKUPDIR ]; then
-  error "Backup destination folder: $BACKUPDIR does not exist."
-fi
+function prerequisites()
+{
+  # Check prerequisites before proceeding
+  if [ ! -d $BACKUPDIR ]; then
+    error "Backup destination directory: $BACKUPDIR does not exist."
+  fi
 
-if [ -z "`$MYSQLADMIN $USEROPTIONS status | grep 'Uptime'`" ] ; then
- error "HALTED: MySQL does not appear to be running."
-fi
+  if [ -z "$($MYSQLADMIN $USEROPTIONS status | grep 'Uptime')" ] ; then
+    error "HALTED: MySQL does not appear to be running."
+  fi
 
-if ! `echo 'exit' | $MYSQL -s $USEROPTIONS` ; then
- error "HALTED: Supplied mysql username or password appears to be incorrect (not copied here for security, see script)."
-fi
+  if ! $(echo 'exit' | $MYSQL -s $USEROPTIONS) ; then
+    error "HALTED: Supplied mysql username or password appears to be incorrect (not copied here for security, see script)."
+  fi
 
-# Some info output
-echo "----------------------------"
-echo
-echo "$0: MySQL backup script"
-echo "started: `date`"
-echo
-
-# Create full and incr backup directories if they not exist.
-mkdir -p $FULLBACKUPDIR
-mkdir -p $INCRBACKUPDIR
-
-# Find latest full backup
-LATEST_FULL=`find $FULLBACKUPDIR -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -1`
-
-# Get latest backup last modification time
-LATEST_FULL_CREATED_AT=`stat -c %Y $FULLBACKUPDIR/$LATEST_FULL`
-
-# If compression is enabled, pass it on to the backup command
-if [ "$compression" = True ]; then
-  compress="--compress"
-  compression_threads="--compress-threads=$compression_threads"
-  echo "Setting compression to True"
+  # Some info output
+  echo "----------------------------"
+  echo "$0: MySQL backup script"
+  echo "started: $(date)"
   echo
-else
-  compress=
-  compression_threads=
-fi
 
-# If throttling is enabled, pass it on to the backup command
-{%- if client.throttle is defined %}
-echo "Setting throttling to True, IO limit is {{ client.get('throttle', '20') }}MB"
-throttle="--throttle {{ client.get('throttle', 20) }}"
-{%- else %}
-throttle=""
-{%- endif %}
-
-{%- if client.backup_times is not defined %}
-# Run an incremental backup if latest full is still valid. Otherwise, run a new full one.
-if [ "$LATEST_FULL" -a `expr $LATEST_FULL_CREATED_AT + $FULLBACKUPLIFE + 5` -ge $STARTED_AT ] ; then
-  # Create incremental backups dir if not exists.
-  TMPINCRDIR=$INCRBACKUPDIR/$LATEST_FULL
-  mkdir -p $TMPINCRDIR
-
-  # Find latest incremental backup.
-  LATEST_INCR=`find $TMPINCRDIR -mindepth 1 -maxdepth 1 -type d | sort -nr | head -1`
-
-  # If this is the first incremental, use the full as base. Otherwise, use the latest incremental as base.
-  if [ ! $LATEST_INCR ] ; then
-    INCRBASEDIR=$FULLBACKUPDIR/$LATEST_FULL
-  else
-    INCRBASEDIR=$LATEST_INCR
+  if [ ! -d $LOGDIR ]; then
+    echo "Creating destination directory $LOGDIR."
+    mkdir -p $LOGDIR
+  fi
+  if [ ! -d $FULLBACKUPDIR ]; then
+    echo "Creating destination directory $FULLBACKUPDIR".
+    mkdir -p $FULLBACKUPDIR
+  fi
+  if [ ! -d $INCRBACKUPDIR ]; then
+    echo "Creating destination directory $INCRBACKUPDIR".
+    mkdir -p $INCRBACKUPDIR
   fi
 
-  echo "Running new incremental backup using $INCRBASEDIR as base."
-  innobackupex --defaults-file=$MYCNF $USEROPTIONS $throttle $compress $compression_threads --incremental $TMPINCRDIR --incremental-basedir $INCRBASEDIR > $TMPFILE 2>&1
-else
-  echo "Running new full backup."
-  innobackupex --defaults-file=$MYCNF $USEROPTIONS $throttle $compress $compression_threads $FULLBACKUPDIR > $TMPFILE 2>&1
-fi
-{%- else %}
-# Get number of full and incremental backups
-NUMBER_OF_FULL=`find $FULLBACKUPDIR -maxdepth 1 -mindepth 1 -type d -print| wc -l`
-NUMBER_OF_INCR=`find $INCRBACKUPDIR -maxdepth 2 -mindepth 2 -type d -print| wc -l`
-echo "Number of Full backups stored: " $NUMBER_OF_FULL
-echo "Number of Incremental backups stored: " $NUMBER_OF_INCR
-echo "----------------------------"
-#If number of incremental mod number of full backups to keep equals 1, run full backup, otherwise run incremental
-if [ $(( ($NUMBER_OF_INCR + $NUMBER_OF_FULL) % ($INCRBEFOREFULL + 1) )) -eq 0 || FORCEFULL=true ] ; then
-  echo "Running new full backup."
-  innobackupex --defaults-file=$MYCNF $USEROPTIONS $compress $compression_threads $FULLBACKUPDIR > $TMPFILE 2>&1
-else
-  # Create incremental backups dir if not exists.
-  TMPINCRDIR=$INCRBACKUPDIR/$LATEST_FULL
-  mkdir -p $TMPINCRDIR
-
-  # Find latest incremental backup.
-  LATEST_INCR=`find $TMPINCRDIR -mindepth 1 -maxdepth 1 -type d | sort -nr | head -1`
-
-  # If this is the first incremental, use the full as base. Otherwise, use the latest incremental as base.
-  if [ ! $LATEST_INCR ] ; then
-    INCRBASEDIR=$FULLBACKUPDIR/$LATEST_FULL
-  else
-    INCRBASEDIR=$LATEST_INCR
+  # Space check
+  if [ $(df $BACKUPDIR | awk '{ print $5 }' | tail -n1 | cut -d '%' -f1) -gt 95 ]; then
+    error "There is not enough space on disk."
   fi
 
-  echo "Running new incremental backup using $INCRBASEDIR as base."
-  innobackupex --defaults-file=$MYCNF $USEROPTIONS $compress $compression_threads --incremental $TMPINCRDIR --incremental-basedir $INCRBASEDIR > $TMPFILE 2>&1
-fi
-{%- endif %}
+}
 
+function backup()
+{
+  # Find latest full backup
+  LATEST_FULL="$(find $FULLBACKUPDIR -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -1)"
 
+  # Get latest backup last modification time
+  LATEST_FULL_CREATED_AT="$(stat -c %Y $FULLBACKUPDIR/$LATEST_FULL)"
 
-if [ -z "`tail -1 $TMPFILE | grep 'completed OK!'`" ] ; then
- echo "$INNOBACKUPEX failed:"; echo
- echo "---------- ERROR OUTPUT from $INNOBACKUPEX ----------"
- cat $TMPFILE
- #rm -f $TMPFILE
- exit 1
-fi
+  # If compression is enabled, pass it on to the backup command
+  if [ "$compression" = True ]; then
+    compress="--compress"
+    compression_threads="--compress-threads=$compression_threads"
+    echo "Setting compression to True"
+    echo
+  else
+    compress=
+    compression_threads=
+  fi
 
-THISBACKUP=`awk -- "/Backup created in directory/ { split( \\\$0, p, \"'\" ) ; print p[2] }" $TMPFILE`
-#rm -f $TMPFILE
+  if [ "$BACKUPTIME"==false ]; then
+    # Run an incremental backup if latest full is still valid. Otherwise, run a new full one.
+    if [ "$LATEST_FULL" -a $(expr $LATEST_FULL_CREATED_AT + $FULLBACKUPLIFE + 5) -ge $STARTED_AT ] ; then
+      # Create incremental backups dir if not exists.
+      TMPINCRDIR="$INCRBACKUPDIR/$LATEST_FULL"
+      mkdir -p $TMPINCRDIR
 
-echo "Databases backed up successfully to: $THISBACKUP"
-echo
+      # Find latest incremental backup.
+      LATEST_INCR=$(find $TMPINCRDIR -mindepth 1 -maxdepth 1 -type d | sort -nr | head -1)
 
-# rsync just the new or modified backup files
-{%- if client.target is defined %}
-echo "Adding ssh-key of remote host to known_hosts"
-ssh-keygen -R {{ client.target.host }} 2>&1 | > $rsyncLog
-ssh-keyscan {{ client.target.host }} >> ~/.ssh/known_hosts  2>&1 | >> $rsyncLog
-echo "Rsyncing files to remote host"
-/usr/bin/rsync -rhtPv --rsync-path=rsync --progress $BACKUPDIR/* -e ssh xtrabackup@{{ client.target.host }}:$SERVERBACKUPDIR >> $rsyncLog
+      # If this is the first incremental, use the full as base. Otherwise, use the latest incremental as base.
+      if [ ! $LATEST_INCR ] ; then
+        INCRBASEDIR=$FULLBACKUPDIR/$LATEST_FULL
+      else
+        INCRBASEDIR=$LATEST_INCR
+      fi
 
-# Check if the rsync succeeded or failed
-if ! grep -q "rsync error: " $rsyncLog; then
-        echo "Rsync to remote host completed OK"
-else
-        echo "Rsync to remote host FAILED"
-        exit 1
-fi
-{%- endif %}
+      echo "Running new incremental backup using $INCRBASEDIR as base."
+      innobackupex --defaults-file=$MYCNF $USEROPTIONS $throttle $compress $compression_threads --incremental $TMPINCRDIR --incremental-basedir $INCRBASEDIR 2>&1 | tee $TMPFILE
+    else
+      echo "Running new full backup."
+      innobackupex --defaults-file=$MYCNF $USEROPTIONS $throttle $compress $compression_threads $FULLBACKUPDIR 2>&1 | tee $TMPFILE
+    fi
+  else
+    # Get number of full and incremental backups
+    NUMBER_OF_FULL="$(find $FULLBACKUPDIR -maxdepth 1 -mindepth 1 -type d -print| wc -l)"
+    NUMBER_OF_INCR="$(find $INCRBACKUPDIR -maxdepth 2 -mindepth 2 -type d -print| wc -l)"
+    echo "Number of Full backups stored: " $NUMBER_OF_FULL
+    echo "Number of Incremental backups stored: " $NUMBER_OF_INCR
+    echo "----------------------------"
+    #If number of incremental mod number of full backups to keep equals 1, run full backup, otherwise run incremental
+    if [ $(( ($NUMBER_OF_INCR + $NUMBER_OF_FULL) % ($INCRBEFOREFULL + 1) )) -eq 0 || FORCEFULL=true ] ; then
+      echo "Running new full backup."
+      innobackupex --defaults-file=$MYCNF $USEROPTIONS $compress $compression_threads $FULLBACKUPDIR 2>&1 | tee $TMPFILE
+    else
+      # Create incremental backups dir if not exists.
+      TMPINCRDIR=$INCRBACKUPDIR/$LATEST_FULL
+      mkdir -p $TMPINCRDIR
 
+      # Find latest incremental backup.
+      LATEST_INCR=$(find $TMPINCRDIR -mindepth 1 -maxdepth 1 -type d | sort -nr | head -1)
 
-# Cleanup
-if [ $SKIPCLEANUP=false ] ; then
-  {%- if client.backup_times is not defined %}
-  echo "----------------------------"
-  echo "Cleanup. Keeping only $KEEP full backups and its incrementals."
-  AGE=$(($FULLBACKUPLIFE * $KEEP / 60))
-  find $FULLBACKUPDIR -maxdepth 1 -type d -mmin +$AGE -execdir echo "removing: "$FULLBACKUPDIR/{} \; -execdir rm -rf $FULLBACKUPDIR/{} \; -execdir echo "removing: "$INCRBACKUPDIR/{} \; -execdir rm -rf $INCRBACKUPDIR/{} \;
+      # If this is the first incremental, use the full as base. Otherwise, use the latest incremental as base.
+      if [ ! $LATEST_INCR ] ; then
+        INCRBASEDIR=$FULLBACKUPDIR/$LATEST_FULL
+      else
+        INCRBASEDIR=$LATEST_INCR
+      fi
 
+      echo "Running new incremental backup using $INCRBASEDIR as base."
+      innobackupex --defaults-file=$MYCNF $USEROPTIONS $compress $compression_threads --incremental $TMPINCRDIR --incremental-basedir $INCRBASEDIR 2>&1 | tee $TMPFILE
+    fi
+  fi
+  if [ -z "$(tail -1 $TMPFILE | grep 'completed OK!')" ] ; then
+    echo "$INNOBACKUPEX failed:"; echo
+    echo "---------- ERROR OUTPUT from $INNOBACKUPEX ----------"
+    cat $TMPFILE
+    exit 1
+  fi
+  THISBACKUP="$(awk -- "/Backup created in directory/ { split( \$0, p, \"'\" ) ; print p[2] }" $TMPFILE)"
+
+  echo "Databases backed up successfully to: $THISBACKUP"
   echo
-  echo "completed: `date`"
-  exit 0
-  {%- else %}
-  echo "----------------------------"
-  echo "Cleanup. Keeping only $KEEP full backups and its incrementals."
-  NUMBER_OF_FULL=$(( `find $FULLBACKUPDIR -maxdepth 1 -type d -print| wc -l` - 1))
-  FULL_TO_DELETE=$(( $NUMBER_OF_FULL - $KEEP ))
-  echo "Found $NUMBER_OF_FULL full backups and $KEEP should be kept. Thus $FULL_TO_DELETE will be deleted"
-  if [ $FULL_TO_DELETE -gt 0 ] ; then
-    cd $INCRBACKUPDIR
-    ls -t $FULLBACKUPDIR | tail -n -$FULL_TO_DELETE | xargs -d '\n' rm -rf
-    cd $FULLBACKUPDIR
-    ls -t | tail -n -$FULL_TO_DELETE | xargs -d '\n' rm -rf
-  else
-    echo "There are less full backups than required, not deleting anything."
+
+  # rsync just the new or modified backup files
+  if [ ! -z "$SERVERBACKUPHOST" ]; then
+    echo "Adding ssh-key of remote host to known_hosts"
+    ssh-keygen -R $SERVERBACKUPHOST 2>&1 | tee $rsyncLog
+    ssh-keyscan $SERVERBACKUPHOST >> ~/.ssh/known_hosts  2>&1 | tee $rsyncLog
+    echo "Rsyncing files to remote host"
+    /usr/bin/rsync -rhtPpv --rsync-path=rsync --progress $BACKUPDIR/* -e ssh xtrabackup@$SERVERBACKUPHOST:$SERVERBACKUPDIR 2>&1 | tee $rsyncLog
+
+    # Check if the rsync succeeded or failed
+    if ! grep -q "rsync error: " $rsyncLog; then
+      echo "Rsync to remote host completed OK"
+    else
+      echo "Rsync to remote host FAILED"
+      exit 1
+    fi
   fi
-  {%- endif %}
-else
-  echo "----------------------------"
-  echo "--skip-cleanup parameter passed. Cleanup was not triggered"
-fi
+}
+function cleanup_backup()
+{
+  # Cleanup
+  if [ "$SKIPCLEANUP"==false ] ; then
+    if [ "$BACKUPTIME"==false ]; then
+      echo "----------------------------"
+      echo "Cleanup. Keeping only $KEEP full backups and its incrementals."
+      AGE=$(($FULLBACKUPLIFE * $KEEP / 60))
+      find $FULLBACKUPDIR -maxdepth 1 -type d -mmin +$AGE -execdir echo "removing: "$FULLBACKUPDIR/{} \; -execdir rm -rf $FULLBACKUPDIR/{} \; -execdir echo "removing: "$INCRBACKUPDIR/{} \; -execdir rm -rf $INCRBACKUPDIR/{} \;
+
+      echo
+      echo "completed: $(date)"
+      exit 0
+    else
+      echo "----------------------------"
+      echo "Cleanup. Keeping only $KEEP full backups and its incrementals."
+
+      NUMBER_OF_FULL="$(( $(find $FULLBACKUPDIR -maxdepth 1 -type d -print| wc -l) - 1))"
+      FULL_TO_DELETE="$(( $NUMBER_OF_FULL - $KEEP ))"
+      echo "Found $NUMBER_OF_FULL full backups and $KEEP should be kept. This $FULL_TO_DELETE will be deleted."
+      if [ $FULL_TO_DELETE -gt 0 ] ; then
+        cd $INCRBACKUPDIR
+        ls -t $FULLBACKUPDIR | tail -n -$FULL_TO_DELETE | xargs -d '\n' rm -rf
+        cd $FULLBACKUPDIR
+        ls -t | tail -n -$FULL_TO_DELETE | xargs -d '\n' rm -rf
+      else
+        echo "There are less full backups than required, not deleting anything."
+      fi
+    fi
+  else
+    echo "----------------------------"
+    echo "--skip-cleanup parameter passed. Cleanup was not triggered"
+  fi
+}
+
+prerequisites
+backup
+cleanup_backup
diff --git a/xtrabackup/files/innobackupex-server-restore-call.sh b/xtrabackup/files/innobackupex-server-restore-call.sh
index c12fed5..72fa8e3 100644
--- a/xtrabackup/files/innobackupex-server-restore-call.sh
+++ b/xtrabackup/files/innobackupex-server-restore-call.sh
@@ -1,34 +1,41 @@
 {%- from "xtrabackup/map.jinja" import server with context %}
-#!/bin/sh
+#!/bin/bash
 
 # This script returns appropriate backup that client will restore
+set -eo pipefail
 
-if [ $# -eq 0 ]; then
+BACKUPDIR="{{ server.backup_dir }}" # Backups base directory
+FULL="$(find $BACKUPDIR/full -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -$1 | tail -1)"
+FULL_INCR="$(find $BACKUPDIR/incr -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -$1 | tail -1)"
+BEFORE_NEXT_FULL_INCR="$(find $BACKUPDIR/incr -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -$(( $1 - 1 )) | tail -1 || true)"
+
+function prerequisites(){
+  if [ $1 -eq 0 ]; then
     echo "No arguments provided"
     exit 1
-fi
+  fi
 
-# if arg is not an integer
-case $1 in
+  # if arg is not an integer
+  case $2 in
     ''|*[!0-9]*) echo "Argument must be integer"; exit 1 ;;
     *) ;;
-esac
+  esac
+}
 
-BACKUPDIR={{ server.backup_dir }} # Backups base directory
-FULL=`find $BACKUPDIR/full -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -$1 | tail -1`
-FULL_INCR=`find $BACKUPDIR/incr -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -$1 | tail -1`
-BEFORE_NEXT_FULL_INCR=`find $BACKUPDIR/incr -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -$(( $1 - 1 )) | tail -1`
-
-if [ -z "$BEFORE_NEXT_FULL_INCR" ]; then
+function return_backup(){
+  if [ -z "$BEFORE_NEXT_FULL_INCR" ]; then
     BEFORE_NEXT_FULL_INCR="Empty"
-fi
+  fi
+  if [ $FULL = $FULL_INCR ]; then
+    LATEST_FULL_INCR=$(find $BACKUPDIR/incr/$FULL_INCR -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -1 | tail -1)
+    echo "$BACKUPDIR/incr/$FULL/$LATEST_FULL_INCR"
+    elif [ $FULL = $BEFORE_NEXT_FULL_INCR ]; then
+    LATEST_FULL_INCR=$(find $BACKUPDIR/incr/$BEFORE_NEXT_FULL_INCR -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -1 | tail -1)
+    echo "$BACKUPDIR/incr/$FULL/$LATEST_FULL_INCR"
+  else
+    echo "$BACKUPDIR/full/$FULL"
+  fi
+}
 
-if [ $FULL = $FULL_INCR ]; then
-  LATEST_FULL_INCR=`find $BACKUPDIR/incr/$FULL_INCR -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -1 | tail -1`
-  echo "$BACKUPDIR/incr/$FULL/$LATEST_FULL_INCR"
-elif [ $FULL = $BEFORE_NEXT_FULL_INCR ]; then
-  LATEST_FULL_INCR=`find $BACKUPDIR/incr/$BEFORE_NEXT_FULL_INCR -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -1 | tail -1`
-  echo "$BACKUPDIR/incr/$FULL/$LATEST_FULL_INCR"
-else
-  echo "$BACKUPDIR/full/$FULL"
-fi
+prerequisites "$#" "$1"
+return_backup
diff --git a/xtrabackup/files/innobackupex-server-runner.sh b/xtrabackup/files/innobackupex-server-runner.sh
index 3ff538a..5f9893d 100644
--- a/xtrabackup/files/innobackupex-server-runner.sh
+++ b/xtrabackup/files/innobackupex-server-runner.sh
@@ -1,47 +1,54 @@
 {%- from "xtrabackup/map.jinja" import server with context %}
-#!/bin/sh
+#!/bin/bash
 
 # The purpose of this script is to clean up unnecesary backups on a backup storage node (on xtrabackup server node)
 
-BACKUPDIR={{ server.backup_dir }} # Backups base directory
-FULLBACKUPDIR=$BACKUPDIR/full # Full backups directory
-INCRBACKUPDIR=$BACKUPDIR/incr # Incremental backups directory
-KEEP={{ server.full_backups_to_keep }} # Number of full backups (and its incrementals) to keep
+set -eo pipefail
+
+BACKUPDIR="{{ server.backup_dir }}" # Backups base directory
+KEEP="{{ server.full_backups_to_keep }}" # Number of full backups (and its incrementals) to keep
 {%- if server.backup_times is defined %}
-INCRBEFOREFULL={{ server.incr_before_full }}
-KEEPINCR=$(( $INCRBEFOREFULL * KEEP ))
+INCRBEFOREFULL="{{ server.incr_before_full }}"
+KEEPINCR="$(( $INCRBEFOREFULL * KEEP ))"
 {%- else %}
-HOURSFULLBACKUPLIFE={{ server.hours_before_full }} # Lifetime of the latest full backup in hours
-FULLBACKUPLIFE=$(( $HOURSFULLBACKUPLIFE * 60 * 60 ))
+HOURSFULLBACKUPLIFE="{{ server.hours_before_full }}" # Lifetime of the latest full backup in hours
+FULLBACKUPLIFE="$(( $HOURSFULLBACKUPLIFE * 60 * 60 ))"
 {%- endif %}
+{%- if server.backup_times is defined %}
+BACKUPTIME="true"
+{%- endif %}
+FULLBACKUPDIR="$BACKUPDIR/full" # Full backups directory
+INCRBACKUPDIR="$BACKUPDIR/incr" # Incremental backups directory
 
 # Cleanup
-{%- if server.backup_times is not defined %}
-echo "Cleanup. Keeping only $KEEP full backups and its incrementals."
-AGE=$(($FULLBACKUPLIFE * $KEEP / 60))
-find $FULLBACKUPDIR -maxdepth 1 -type d -mmin +$AGE -execdir echo "removing: "$FULLBACKUPDIR/{} \; -execdir rm -rf $FULLBACKUPDIR/{} \; -execdir echo "removing: "$INCRBACKUPDIR/{} \; -execdir rm -rf $INCRBACKUPDIR/{} \;
+function cleanup(){
+  if [ $BACKUPTIME==false ]; then
+    echo "Cleanup. Keeping only $KEEP full backups and its incrementals."
+    AGE=$(($FULLBACKUPLIFE * $KEEP / 60))
+    find $FULLBACKUPDIR -maxdepth 1 -type d -mmin +$AGE -execdir echo "removing: "$FULLBACKUPDIR/{} \; -execdir rm -rf $FULLBACKUPDIR/{} \; -execdir echo "removing: "$INCRBACKUPDIR/{} \; -execdir rm -rf $INCRBACKUPDIR/{} \;
+    echo "completed: $(date)"
+    exit 0
+  else
+    echo "Cleanup. Keeping only $KEEP full backups and its incrementals."
+    NUMBER_OF_FULL=$(( $(find $FULLBACKUPDIR -maxdepth 1 -type d -print| wc -l) - 1))
+    NUMBER_OF_INCR=$(( $(find $INCRBACKUPDIR -maxdepth 2 -type d -print| wc -l) - 1))
+    FULL_TO_DELETE=$(( $NUMBER_OF_FULL - $KEEP ))
+    INCR_TO_DELETE=$(( $NUMBER_OF_INCR - $KEEPINCR ))
+    echo "Found $NUMBER_OF_FULL full backups and $KEEP should be kept. Thus $FULL_TO_DELETE will be deleted"
+    echo "Found $NUMBER_OF_INCR full backups and $KEEPINCR should be kept. Thus $INCR_TO_DELETE will be deleted"
+    if [ $FULL_TO_DELETE -gt 0 ] ; then
+      cd $FULLBACKUPDIR
+      ls -t | tail -n -$FULL_TO_DELETE | xargs -d '\n' rm -rf
+    else
+      echo "There are less full backups than required, not deleting anything."
+    fi
+    if [ $INCR_TO_DELETE -gt 0 ] ; then
+      cd $INCRBACKUPDIR
+      ls -t | tail -n -$INCR_TO_DELETE | xargs -d '\n' rm -rf
+    else
+      echo "There are less incremental backups than required, not deleting anything."
+    fi
+  fi
+}
 
-echo
-echo "completed: `date`"
-exit 0
-{%- else %}
-echo "Cleanup. Keeping only $KEEP full backups and its incrementals."
-NUMBER_OF_FULL=$(( `find $FULLBACKUPDIR -maxdepth 1 -type d -print| wc -l` - 1))
-NUMBER_OF_INCR=$(( `find $INCRBACKUPDIR -maxdepth 2 -type d -print| wc -l` - 1))
-FULL_TO_DELETE=$(( $NUMBER_OF_FULL - $KEEP ))
-INCR_TO_DELETE=$(( $NUMBER_OF_INCR - $KEEPINCR ))
-echo "Found $NUMBER_OF_FULL full backups and $KEEP should be kept. Thus $FULL_TO_DELETE will be deleted"
-echo "Found $NUMBER_OF_INCR full backups and $KEEPINCR should be kept. Thus $INCR_TO_DELETE will be deleted"
-if [ $FULL_TO_DELETE -gt 0 ] ; then
-cd $FULLBACKUPDIR
-ls -t | tail -n -$FULL_TO_DELETE | xargs -d '\n' rm -rf
-else
-echo "There are less full backups than required, not deleting anything."
-fi
-if [ $INCR_TO_DELETE -gt 0 ] ; then
-cd $INCRBACKUPDIR
-ls -t | tail -n -$INCR_TO_DELETE | xargs -d '\n' rm -rf
-else
-echo "There are less incremental backups than required, not deleting anything."
-fi
-{%- endif %}
\ No newline at end of file
+cleanup