Script para restaurar várias versões de um arquivo de uma única vez

Há um tempo atrás precisei restaurar um determinado arquivo, porém não sabia exatamente em qual Job estava a versão que eu precisava. Então tive que restaurar uma dezena de Jobs manualmente até achar o arquivo que eu precisava. Para facilitar esse tipo de restauração, desenvolvi um script que lista os JobId’s que contém este arquivo e o usuário pode informar quais os JobId’s que ele deseja restaurar e o bacula restaura todos os jobs em um diretório específico, separando em subdiretórios com o número do JobId e data  do backup.

Exemplo do script sendo executado:

_restore_multiples_version.sh
List Jobs where a given File is saved
Defined Clients:
    1:wanderlei-fd
    2:srv_bacula-fd
    3:srv_dados-fd
Select the Client (1-3): 3

Client selected: srv_dados-fd

Defined Restore Clients:
    1:wanderlei-fd
    2:srv_bacula-fd
    3:srv_dados-fd
Select the Restore Client (1-3): 2

Restore Client selected: srv_bacula-fd

Type filename without path: "Arq Teste.xls"

Type part or full path: wanderlei

+------+-------------------------+---------------------+---+---+--------+-------------+
| 3479 |  k:/dados/Arq Teste.xls | 2016-02-26 19:30:00 | B | T | 190068 | 18126166353 |
| 3403 |  k:/dados/Arq Teste.xls | 2016-02-19 21:30:01 | B | T | 189588 | 18083873748 |
| 3326 |  k:/dados/Arq Teste.xls | 2016-02-12 21:30:01 | B | T | 189084 | 18034641147 |
| 3244 |  k:/dados/Arq Teste.xls | 2016-02-05 21:30:01 | B | T | 186689 | 16869782088 |
| 3167 |  k:/dados/Arq Teste.xls | 2016-01-29 21:30:01 | B | T | 186270 | 16778430398 |
| 3152 |  k:/dados/Arq Teste.xls | 2016-01-28 21:30:01 | B | T |    962 | 110699256   |
| 2861 |  k:/dados/Arq Teste.xls | 2016-01-01 21:30:01 | B | T | 185827 | 17880625571 |
| 2582 |  k:/dados/Arq Teste.xls | 2015-12-04 21:30:01 | B | T | 184299 | 17654848561 |
| 2275 |  k:/dados/Arq Teste.xls | 2015-11-06 21:30:01 | B | T | 185313 | 17440507519 |
| 1891 |  k:/dados/Arq Teste.xls | 2015-10-02 21:30:00 | B | T | 182355 | 16980054957 |
| 1577 |  k:/dados/Arq Teste.xls | 2015-09-04 21:30:00 | B | T | 178919 | 15342913152 |
| 1341 |  k:/dados/Arq Teste.xls | 2015-08-07 21:30:00 | B | T | 176627 | 14797152103 |
| 1086 |  k:/dados/Arq Teste.xls | 2015-07-03 22:09:19 | B | T | 173994 | 15850148514 |
|  852 |  k:/dados/Arq Teste.xls | 2015-06-05 23:05:00 | B | T | 172276 | 15451143508 |
+------+-------------------------+---------------------+---+---+--------+-------------+

Enter JobId(s), comma separated, to restore: 3479,3403,3326,3244,3167,3152,2861,2582,2275,1891,1577,1341,1086,852

ls -1 /tmp/bacula_restore
1086_20150703_220919
1341_20150807_213000
1577_20150904_213000
1891_20151002_213000
2275_20151106_213001
2582_20151204_213001
2861_20160101_213001
3152_20160128_213001
3167_20160129_213001
3244_20160205_213001
3326_20160212_213001
3403_20160219_213001
3479_20160226_193000
852_20150605_230500
bsr

Passos de de execução:
1 – escolher cliente
2 – escolher cliente de restauração
3 – digitar nome do arquivo
4  – digitar parte do caminho do arquivo ou deixar em branco
5 – digitar os JobId’s para restaurar

Script de Restauração:
(É preciso configurar as variáveis no inicio do script para funcionar corretamente)

#!/bin/bash
# /etc/bacula/scripts/_restore_multiples_version.sh
# Config
DBUSER="bacula"
DBPASSWORD="bacula"
DBNAME="bacula"

RESTOREDIR="/tmp/bacula_restore"
BSRDIR="${RESTOREDIR}/bsr"
SDCONF="/etc/bacula/bacula-sd.conf"
BCONSOLE="/sbin/bconsole"


# Create folders
if [ ! -d "${RESTOREDIR}" ]; then
   echo -ne "Directory \"${RESTOREDIR}\" not found! Will be created...\n"
   mkdir "${RESTOREDIR}"
fi

if [ ! -d "${BSRDIR}" ]; then
   echo -ne "Directory \"${BSRDIR}\" not found! Will be created...\n"
   mkdir "${BSRDIR}"
fi


# Exlude all bootstrapfiles
rm -Rf ${BSRDIR}/*.bsr


# List clients from bconsole
echo -ne "List Jobs where a given File is saved\n"
echo -ne "Defined Clients:\n"
CLIENTS=(`echo ".clients" | bconsole | sed '1,4d' | grep -v "You have messages"`)
count=0
for i in ${CLIENTS[@]}; do count=`expr $count + 1`; printf "%5s:%s\n" $count $i; done

echo -ne "Select the Client (1-$count): "
read CLIENTID


# Read client
while [ ${CLIENTID} -eq 0 ] || [ ${CLIENTID} -gt ${#CLIENTS[@]} ]; do
   if [ ${CLIENTID} -eq 0 ] || [ ${CLIENTID} -gt ${#CLIENTS[@]} ]; then
      echo -ne "Select the Client (1-$count): ";
      read CLIENTID
   else
     break
   fi
done
CLIENTNAME=${CLIENTS[$CLIENTID-1]};
echo -ne "\nClient selected: ${CLIENTNAME}\n"

# List restore clients from bconsole
echo -ne "\nDefined Restore Clients:\n"
count=0
for i in ${CLIENTS[@]}; do count=`expr $count + 1`; printf "%5s:%s\n" $count $i; done
echo -ne "Select the Restore Client (1-$count): "
read RESTORECLIENTID

# Read client
while [ ${RESTORECLIENTID} -eq 0 ] || [ ${RESTORECLIENTID} -gt ${#CLIENTS[@]} ]; do
   if [ ${RESTORECLIENTID} -eq 0 ] || [ ${RESTORECLIENTID} -gt ${#CLIENTS[@]} ]; then
      echo -ne "Select the Client (1-$count): ";
      read RESTORECLIENTID
   else
     break
   fi
done
RESTORECLIENTNAME=${CLIENTS[$RESTORECLIENTID-1]};
echo -ne "\nRestore Client selected: ${RESTORECLIENTNAME}\n"


# Read filename
echo -ne "\nType filename without path: "
read FILENAME
FILENAME=`echo ${FILENAME} | sed 's/^"\(.*\)"$/\1/'`
echo -ne "\n"

# Read filepth
echo -ne "Type part or full path: "
read FILEPATH
FILEPATH=`echo ${FILEPATH} | sed 's/^"\(.*\)"$/\1/'`
echo -ne "\n"


# Query SQL get JobId's where file is
sql_query="SELECT Job.JobId as JobId,cast(CONCAT(Path.Path,Filename.Name) as char) as Name, StartTime,cast(Type as char) as JobType, cast(JobStatus as char) as JobStatus,JobFiles,JobBytes 
FROM Client,Job,File,Filename,Path
WHERE Client.Name='${CLIENTNAME}' AND Client.ClientId=Job.ClientId AND Job.JobId=File.JobId 
AND File.FileIndex > 0 AND Path.PathId=File.PathId AND Filename.FilenameId=File.FilenameId
AND Filename.Name='${FILENAME}' and Path.Path like '%${FILEPATH}%'
ORDER BY StartTime DESC limit 20"
query=`mysql -u ${DBUSER} -p${DBPASSWORD} -D ${DBNAME} -t -N -e "$sql_query"`

if [ `echo -ne "$query" | wc -l` -eq 0 ]; then
  echo "No files were found! Try again!"
  exit
fi 

echo -ne "$query\n\n"

echo -ne "Enter JobId(s), comma separated, to restore: "
read JOBIDS

if [ "${JOBIDS}" == "" ]; then
  echo "No JobId's selected!"
  exit
fi 

# Start restore
JOBIDS=`echo ${JOBIDS} | tr "," " "`
for j in ${JOBIDS}; do 
   echo -ne "$query" | sed '1d;$d' | while read i; do
     JOBID=`echo $i | cut -d"|" -f2 | sed 's/^ \(.*\) $/\1/'`;
     FILENAME=`echo $i | cut -d"|" -f3 | sed 's/^ \(.*\) $/\1/'`;
     STARTTIME=`echo $i | cut -d"|" -f4 | sed 's/^ \(.*\) $/\1/' | sed 's/ /_/g' | sed 's/[^0-9_]//g'`;
     if [ ${JOBID} -eq $j ]; then
        
        # Check if directory not exists and create
        if [ ! -d "$RESTOREDIR/${JOBID}_${STARTTIME}" ]; then
           echo -ne "\nDirectory \"$RESTOREDIR/${JOBID}_${STARTTIME}\" not found! Will be created...\n"
           mkdir "$RESTOREDIR/${JOBID}_${STARTTIME}"
        else
           echo -ne "\nDirectory already \"$RESTOREDIR/${JOBID}_${STARTTIME}\" exists!\n"
        fi
        # restore with bconsole
        echo -ne "restore jobid=${JOBID} client=${CLIENTNAME} restoreclient=${RESTORECLIENTNAME} file=\"${FILENAME}\" where=${RESTOREDIR}/${JOBID}_${STARTTIME} bootstrap=${BSRDIR}/${JOBID}_${STARTTIME}.bsr\nyes\n" | ${BCONSOLE}       
     fi
   done
done
echo "All files were restored!"

Se um arquivo com o mesmo nome for encontrado no cliente em outros diretórios, ambos serão restaurados.

FacebooktwitterlinkedinFacebooktwitterlinkedinby feather