User Tools

Site Tools


linux:restore_menu

Differences

This shows you the differences between two versions of the page.


Previous revision
linux:restore_menu [2024/03/25 07:55] (current) – old revision restored (2022/02/11 11:36) dodger
Line 1: Line 1:
 +====== [SCRIPT] RestoreMenu ======
 +
 +====== Descripcion ======
 +Ver el post del blog: http://blog.ciberterminal.net/index.php/2012/01/20/script-de-copia-y-restauracion-de-un-sistema-windows
 +
 +====== Acciones a realizar ======
 +Instalar un sistema linux base con las siguientes dependencias:
 +  * bash >= 4.0
 +  * sudo
 +  * dd
 +  * gzip/gunzip
 +  * [[http://www.tuxera.com/community/ntfs-3g-download/|ntfsprogs]]
 +  * acpi (comprobación de batería en portátil)
 +  * dmidecode (revisamos el serial, el script hay que configurarlo cada vez)
 +  * pigz (para proceso en paralelo)
 +
 +
 +===== Pasos generales =====
 +  * Se particiona el disco.
 +  * Instalamos windows
 +  * Instalamos un linux "minimal", y dependencias necesarias para que el script funcione
 +  * Añadimos nuestro script.
 +  * Modificamos los parámetros de configuración necesarios en el mismo
 +  * Creamos un usuario de sistema sin privilegios, modificamos //~/.bashrc// para lanzar automáticamente el script cuando se logue el usuario.
 +  * Deshabilitamos la posibilidad de salir del script (//trap//) para evitar problemas.
 +  * Nos guardamos el pass de root ;-)
 +  * Modificamos grub para que el menú diga algo como Restore or similar y el usuario no se asuste viendo //GNU/Linux//
 +  * Informar al usuario de como funciona el entorno, aunque es muy muy sencillo)
 +
 +
 +===== Script =====
 +==== Codigo ====
 +<file bash restore_menu.sh>
 +#!/bin/bash
 +
 +# Coded by dodger
 +# More information on
 +# http://blog.ciberterminal.net/index.php/2012/01/20/script-de-copia-y-restauracion-de-un-sistema-windows
 +
 +
 +SNAPSHOTDIR=/home/snapshots
 +WINDOWSDEV=/dev/sda1
 +SERIAL="serialnumber"
 +HOST="hostname"
 +INITIAL_IMAGE="INITIAL-IMAGE_20120119-115923_mar-eee.img.gz"
 +COMPRESSOR=/usr/bin/pigz
 +COMPRESSOPTIONS="-9fc"
 +UNCOMPRESSOR=/bin/gunzip
 +UNCOMPRESSOPTIONS="-dc"
 +NTFSCLONE="/root/ntfs-3g_ntfsprogs-2011.4.12/ntfsprogs/ntfsclone"
 +NTFSRESIZE="/root/ntfs-3g_ntfsprogs-2011.4.12/ntfsprogs/ntfsresize"
 +
 +
 +# AUTOCONFIG
 +unset IMAGELIST
 +unset IMAGESIZE
 +
 +[ ! -d ${SNAPSHOTDIR} ] && mkdir $SNAPSHOTDIR
 +
 +
 +trap_it()
 +{
 + [[ "$(kill -l | tail -1 | tr '+' '-')" =~ ([0-9]{1,})\)[[:space:]]{1,}[A-Z0-9\-]{3,15}(.|)$ ]]
 + local TRAPIT=$(eval echo {1..${BASH_REMATCH[1]}})
 + trap 'echo "NO PERMITIDO"' ${TRAPIT}
 +}
 +
 +print_main_menu()
 +{
 +
 + local let OPTION=0
 + clear
 +cat > /dev/stdout <<EOF
 +##################################################
 +Menu de restauracion y copia de sistema
 +1) Restauracion de imagen
 +2) Generacion de Imagen
 +3) Borrar imagen
 +4) Lista las imagenes existentes y su tamanyo
 +5) Ayuda
 +99) Reinicio del sistema
 +##################################################
 +EOF
 + while [[ ! $OPTION =~ ^([1-5]|99)$ ]]
 + do
 + [ ${OPTION:-0} -ne 0 ] && echo "Seleccion erronea"
 + printf "%s" "->  "
 + read OPTION
 + OPTION=${OPTION:-98}
 + [[ ! ${OPTION} =~ ^[0-9]{1,}$ ]] && OPTION=0
 + done
 + return ${BASH_REMATCH[0]}
 +}
 +
 +test()
 +{
 +
 + local MENU=$1
 + local let OPTION=0
 + case $MENU in
 + "main" )
 +
 + ;;
 + "restore" )
 + ;;
 + "clone" )
 + ;;
 + * )
 + ;;
 + esac
 +}
 +
 +help()
 +{
 +clear
 +cat > /dev/stdout <<EOF
 +Este menu permite la restauracion de una copia de sistema anterior o
 +la generacion de una nueva copia.
 +Lo que se realiza es una copia integral del sistema windows o bien, 
 +una restauracion de 0 del mismo tal como estaba en el momento de la copia.
 +Ya que el espacio es limitado, deberian revisarse las imágenes de sistema 
 +existentes y eliminar las que no sean necesarias.
 +
 +
 +Las opciones de menu son las siguientes:
 +Opcion 1, dara opciones para la restauracion.
 +Opcion 2, dara opciones para la copia/clonado.
 +Opcion 3, dara opciones para el borrado de imagenes existentes.
 +Opcion 99, reinicia el equipo.
 +
 +Recuerde que la opcion 1 elimina todos los datos actuales del sistema windows, dejándolo como cuando se realizó la copia.
 +
 +
 +
 +Presiona ENTER para continuar
 +EOF
 +read
 +}
 +
 +reboot_machine()
 +{
 + echo "Reiniciando..."
 + sleep 2
 + #exit 0
 + shutdown -r now
 +}
 +
 +list_images()
 +{
 + let x=0
 + unset IMAGELIST
 + for i in ${SNAPSHOTDIR}/*img.gz ; do
 + IMAGELIST[$x]="$(basename $i)"
 + let x++
 + done
 +}
 +
 +list_image_size()
 +{
 + let x=0
 + unset IMAGESIZE
 + for ((x=0; x<${#IMAGELIST[@]} ; x++)) ; do
 + IMAGESIZE[$x]="$(($(stat --format=%s ${SNAPSHOTDIR}/${IMAGELIST[$x]})/1024/1024))"
 + done
 +}
 +
 +check_cable()
 +{
 + while [[ "$(acpi | egrep -i "Discharging")" ]] ; do
 + echo "Este proceso tardara MUCHO, es necesario conexion a la red electrica"
 + echo "Presione ENTER cuando este conectado"
 + read
 + done
 +}
 +
 +show_agree()
 +{
 + local YN=N
 + echo "##################################################"
 + echo "Este proceso no se puede parar, Estas seguro?"
 + printf "%s" "(y/N)->  "
 + read YN
 + [[ ! ${YN} =~ ^[yY]$ ]] && return 1
 + return 0
 +}
 +
 +
 +restore_clone_main()
 +{
 + local ACTION=$1
 + local IMAGEFILE=$2
 + local DDPID=0
 + check_cable
 + show_agree
 + [ ! $? -eq 0 ] && return 1
 + case "$ACTION" in
 + "clone")
 + ${NTFSCLONE} --save-image --output - ${WINDOWSDEV} | $COMPRESSOR $COMPRESSOPTIONS > ${IMAGEFILE}
 + ;;
 + "restore")
 + $UNCOMPRESSOR $UNCOMPRESSOPTIONS $IMAGEFILE | ${NTFSCLONE} --restore-image --overwrite ${WINDOWSDEV} - 
 + ;;
 + *)
 + echo "Error, REPORT"
 + return 1
 + ;;
 + esac
 +
 + echo "Completado, Pulse ENTER para continuar"
 + read
 + return 0
 +}
 +
 +restore_menu()
 +{
 + local let OPTION=99
 + local YN=n
 + clear
 + echo "##################################################"
 + echo "Menu de restauracion"
 + echo "Paso 1: Elegir imagen:"
 + list_images
 + for ((x=0; x<${#IMAGELIST[*]} ; x++)) ; do
 + echo "${x} ) ${IMAGELIST[$x]}"
 + done
 + echo -e "\nIntroduce el numero de imagen a restaurar"
 + while [ ${OPTION} = 99 ]
 + do
 + printf "%s" "->  "
 + read OPTION
 + OPTION=${OPTION:-99}
 + [ ${OPTION} -lt 0 ]  || [ ${OPTION} -ge ${#IMAGELIST[*]} ] || [[ ! ${OPTION} =~ ^[0-9]{1,}$ ]] && OPTION=99
 + done
 + echo "##################################################"
 + echo "Paso 2: Restaurar imagen: ${IMAGELIST[$OPTION]}"
 + echo "La descripcion de la imagen es:"
 + cat ${SNAPSHOTDIR}/$(basename ${IMAGELIST[$OPTION]} .img.gz).description
 + echo "Estas seguro?"
 + printf "%s" "(y/N)->  "
 + read YN
 + [[ ${YN} =~ ^[yY]$ ]] && restore_clone_main restore "${SNAPSHOTDIR}/${IMAGELIST[$OPTION]}"
 + if [ $? -eq 0 ] ; then
 + echo "Es necesario reiniciar el Ordenador..."
 + sleep 2
 + reboot_machine
 + fi
 +}
 +
 +
 +clone_menu()
 +{
 + MYDATE="$(date +%Y%m%d-%H%M%S)"
 + local let OPTION=99
 + local YN=n
 + local DESCRIPTION=""
 + local USEDSPACE="$(${NTFSRESIZE} -i --no-action ${WINDOWSDEV} 2>&1 | grep "freeing" | awk '{print $5}')"
 + USEDSPACE=$(($USEDSPACE/1024/2))
 + local FREESPACE="$(df -P ${SNAPSHOTDIR} | grep "%" | awk '{print $4}')"
 + clear
 + echo "##################################################"
 + echo "Menu de Clonado"
 + [ $USEDSPACE -gt $FREESPACE ] && echo "El espacio necesario es mayor que el libre, es necesario hacer espacio (borrar imagenes)" && return 1
 + while [[ ! $DESCRIPTION ]] ; do
 + echo "Introduce una descripcion para la imagen y pulsa ENTER"
 + printf "%s" "->  "
 + read DESCRIPTION
 + echo "${DESCRIPTION}" > "${SNAPSHOTDIR}/${MYDATE}_${HOST}.description"
 + done
 + restore_clone_main clone "${SNAPSHOTDIR}/${MYDATE}_${HOST}.img.gz"
 + return 0
 +}
 +
 +delete_menu()
 +{
 + local let OPTION=98
 + local YN=n
 + clear
 + list_images
 + list_image_size
 + [ ${#IMAGELIST[@]} -eq 1 ] && echo -e "No hay imagenes que borrar,\nPresione ENTER" && read && return 0
 + echo "##################################################"
 + echo "Menu de Borrado"
 + echo "Paso 1: Elegir imagen para borrar:"
 + for ((x=0; x<${#IMAGELIST[@]} ; x++)) ; do
 + [[ ! "${IMAGELIST[$x]}" =~ ^${INITIAL_IMAGE}$ ]] && echo "$x ) \"${IMAGELIST[$x]}\" , Tamaño : ${IMAGESIZE[$x]} MB"
 + done
 + echo -e "\nIntroduce el numero de imagen a eliminar o 99 para salir"
 + while [ ${OPTION:-98} = 98 ]
 + do
 + printf "%s" "->  "
 + read OPTION
 + OPTION=${OPTION:-98}
 + [ ${OPTION} -eq 99 ] && return 1
 + [ ${OPTION} -lt 0 ]  || [ ${OPTION} -gt ${#IMAGELIST[*]} ] || [[ ! ${OPTION} =~ ^[0-9]{1,}$ ]] && OPTION=98
 + done
 + echo "Estas seguro?"
 + printf "%s" "(y/N)->  "
 + read YN
 + if [[ ${YN} =~ ^[yY]$ ]]
 + then 
 + echo "Borrando ${IMAGELIST[$OPTION]}"
 + if [[ ! "${IMAGELIST[$OPTION]}" =~ ^${INITIAL_IMAGE}$ ]]
 + then
 + rm -fv "${SNAPSHOTDIR}/${IMAGELIST[$OPTION]}"
 + rm -fv "${SNAPSHOTDIR}/$(basename ${IMAGELIST[$OPTION]} .img.gz).description"
 + fi
 + fi
 +}
 +
 +list_menu()
 +{
 + local let OPTION=98
 + local YN=n
 + clear
 + list_images
 + list_image_size
 + echo "##################################################"
 + echo "Lista de imagenes"
 + for ((x=0; x<${#IMAGELIST[@]} ; x++)) ; do
 + echo "$x ) Nombre: \"${IMAGELIST[$x]}\" , Tamaño : ${IMAGESIZE[$x]} MB"
 + done
 + echo "##################################################"
 + echo "Presiona ENTER para continuar"
 + read
 +}
 +
 +
 +main()
 +{
 + trap_it
 + while true ; do
 + local let OPTION=0
 + print_main_menu
 + OPTION=$?
 + case $OPTION in
 + 1)
 + restore_menu
 + ;;
 + 2)
 + clone_menu
 + ;;
 + 3)
 + delete_menu
 + ;;
 + 4)
 + list_menu
 + ;;
 + 5)
 + help
 + ;;
 + 99)
 + reboot_machine
 + ;;
 + *)
 + ;;
 + esac
 + done
 +}
 +
 +main
 +</file>
 +==== Variables ====
 +^ Variable     ^ Valor por defecto ^ Descripcion ^
 +| ''SNAPSHOTDIR'' | ''/home/snapshots'' | Directorio donde se almacenarán los snapshots y descripciones |
 +| ''WINDOWSDEV'' | ''/dev/sda1'' | Partición que contiene Windows |
 +| ''SERIAL'' | ''"8BOAAQ256174"'' | El nº de serie del equipo, se puede ver con la dependencia ''dmidecode'' |
 +| ''HOST'' | ''"my-hostname"'' | Nombre del host, únicamente se usa para generar un nombre de imagen |
 +| ''COMPRESSOR'' | ''/usr/bin/pigz'' | Comando usado para comprimir, en este caso [[http://blog.ciberterminal.net/index.php/2011/11/15/ciclo-herramientas-gnulinux-v-pbzip2/|pigz]] para aprovechar los procesadores multi-core. |
 +| ''COMPRESSOPTIONS'' | ''"-9fc"'' | Opciones para la compresión |
 +| ''UNCOMPRESSOR'' | ''/bin/gunzip'' | Ídem pero para descomprimir |
 +| ''UNCOMPRESSOPTIONS'' | ''"-dc"'' | Opciones para la descompresión |
 +| ''NTFSCLONE'' | ''"/root/ntfs-3g_ntfsprogs-2011.4.12/ntfsprogs/ntfsclone"'' | Donde está el binario de ntfsclone, a veces puede ser necesario compilar (ver [[restore_menu#Troubleshooting|Troubleshooting]]) |
 +| ''NTFSRESIZE'' | ''"/root/ntfs-3g_ntfsprogs-2011.4.12/ntfsprogs/ntfsresize"'' | Ídem que antes, si hemos compilado |
 +
 +==== Ejemplo de Configuración restante ====
 +=== grub ===
 +<file config menu.lst>
 +# general configuration:
 +timeout   2
 +default   0
 +color light-blue/black light-cyan/blue
 +
 +# (0) Windows
 +title Windows
 +rootnoverify (hd0,0)
 +makeactive
 +chainloader +1
 +
 +
 +# (1) Arch Linux
 +title  Recovery Mode
 +root   (hd0,1)
 +kernel /boot/vmlinuz-linux root=/dev/sda2 ro
 +initrd /boot/initramfs-linux.img
 +</file>
 +=== .bashrc ===
 +<file bash .bashrc>
 +#
 +# ~/.bashrc
 +#
 +sudo /root/restore_menu.sh
 +</file>
 +=== sudoers ===
 +<file config sudoers>
 +username     ALL=(ALL) NOPASSWD: /root/restore_menu.sh
 +</file>
 +
 +
 +====== Troubleshooting ======
 +===== ntfsclone =====
 +<code>
 +ERROR: $Bitmap size is smaller than expected
 +</code>
 +Solución:
 +http://www.tuxera.com/forum/viewtopic.php?f=2&t=27527