#!/bin/bash #/** #@file Image.lib #@brief Librería o clase Image #@class Image #@brief Funciones para creación, restauración y clonación de imágenes de sistemas. #@version 0.9 #@warning License: GNU GPLv3+ #*/ #/** # ogCreateImage int_ndisk int_npartition str_repo path_image #@brief Crea una imagen a partir de una partición. #@param int_ndisk nº de orden del disco #@param int_npartition nº de orden de la partición #@param str_repo repositorio de imágenes (remoto o caché local) #@param path_image camino de la imagen (sin extensión) #@return (nada, por determinar) #@note repo = { REPO, CACHE } #@exception OG_ERR_FORMAT formato incorrecto. #@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado. #@exception OG_ERR_PARTITION partición no accesible o no soportada. #@exception OG_ERR_LOCKED particion bloqueada por otra operación. #@exception OG_ERR_IMAGE error al crear la imagen del sistema. #@warning En pruebas iniciales #@todo Comprobaciones, control de errores, definir parámetros, etc. #@version 0.9 - Versión en pruebas para OpenGNSys #@author Ramon Gomez, ETSII Universidad de Sevilla #@date 2009/10/07 #*/ ## function ogCreateImage () { # Variables locales local PART IMGDIR IMGFILE ERRCODE # Si se solicita, mostrar ayuda. if [ "$*" == "help" ]; then ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_npart path_dir str_image" \ "$FUNCNAME 1 1 REPO /aula1/winxp" return fi # Error si no se reciben 4 parámetros. [ $# -lt 4 ] && ogRaiseError $OG_ERR_FORMAT && return $? PART="$(ogDiskToDev $1 $2)" || return $? if ogIsLocked $1 $2; then ogRaiseError $OG_ERR_LOCKED "$1,$2" return $? fi IMGDIR=$(ogGetParentPath "$3" "$4") [ -n "$IMGDIR" ] || ogRaiseError $OG_ERR_NOTFOUND "$3 $(dirname $4)" || return $? IMGFILE="$IMGDIR/$(basename "$4").img" ogUnmount $1 $2 2>/dev/null ogLock $1 $2 || return $? trap "ogUnlock $1 $2; rm -f $IMGFILE" 1 2 3 6 9 TYPE="$(ogGetFsType $1 $2)" case "$TYPE" in EXT[234]|REISERFS|XFS|JFS) partimage -M -f3 -o -d -V0 -B gui=no -c -z1 save $PART "$IMGFILE" ;; NTFS|HNTFS) partimage -M -f3 -o -d -V0 -B gui=no -c -z1 save $PART "$IMGFILE" ;; FAT16|FAT32|HFAT16|HFAT32) partimage -M -f3 -o -d -V0 -B gui=no -c -z1 save $PART "$IMGFILE" ;; *) ogRaiseError $OG_ERR_PARTITION "$1 $2 $TYPE" return $? ;; esac # Controlar salida de error y desbloquear partición. ERRCODE=$? if [ $ERRCODE != 0 ]; then ogRaiseError $OG_ERR_IMAGE "$1 $2 $IMGFILE" rm -f "$IMGFILE" fi ogUnlock $1 $2 return $ERRCODE } #/** # ogGetImageSize str_repo path_image #@brief Devuelve el tamaño del sistema de archivos almacenado en un fichero de imagen. #@param str_repo repositorio de imágenes o caché local #@param path_image camino de la imagen #@return tamaño (en KB) #@exception OG_ERR_FORMAT formato incorrecto. #@exception OG_ERR_NOTFOUND fichero de imagen no encontrado. #*/ #@warning En pruebas iniciales #@todo Definición de parámetros y salidas. #@version 0.1 - Primera versión muy en pruebas para OpenGNSys #@author Ramon Gomez, ETSII Universidad de Sevilla #@date 2009/09/11 #*/ ## function ogGetImageSize () { # Variables locales local IMGFILE # Si se solicita, mostrar ayuda. if [ "$*" == "help" ]; then ogHelp "$FUNCNAME" "$FUNCNAME path_dir str_image int_ndisk int_npart" \ "$FUNCNAME 1 1 REPO /aula1/winxp ==> 5642158" return fi # Error si no se reciben menos de 2 parámetros. [ $# -lt 2 ] && ogRaiseError $OG_ERR_FORMAT && return $? # Error si el fichero de imagen no es accesible. IMGFILE=$(ogGetPath "$1" "$2.img") || return $? [ -r "$IMGFILE" ] || ogRaiseError OG_ERR_NOTFOUND "$IMGFILE" || return $? # Devuelve el tamaño de la imagen en KB. partimage -B gui=no imginfo "$IMGFILE" 2>&1 | \ awk '/Partition size/ {sub(/\.\.+/," "); printf "%d\n",$3*1024*1024;}' } #### PRUEBAS # Obtener tipo de imagen function ogGetImageType () { local IMGFILE IMGFILE=$(ogGetPath "$1" "$2.img") || return $? [ -r "$IMGFILE" ] || ogRaiseError OG_ERR_NOTFOUND "$IMGFILE" || return $? partimage -B gui=no imginfo "$IMGFILE" 2>&1 | \ awk '/^Filesystem/ {sub(/\.\.+/," "); sub(/fs$/,""); print toupper($2);}' } #/** # ogRestoreImage str_repo path_image int_ndisk int_npartition #@brief Restaura una imagen de sistema de archivos en una partición. #@param str_repo repositorio de imágenes o caché local #@param path_image camino de la imagen #@param int_ndisk nº de orden del disco #@param int_npartition nº de orden de la partición #@return (por determinar) #@exception OG_ERR_FORMAT formato incorrecto. #@exception OG_ERR_NOTFOUND fichero de imagen o partición no detectados. #@exception OG_ERR_LOCKED partición bloqueada por otra operación. #@exception OG_ERR_IMAGE error al restaurar la imagen del sistema. #@warning En pruebas iniciales #@todo Comprobar incongruencias partición-imagen, control de errores, definir parámetros, caché/repositorio, etc. #@version 0.1 - Primera versión muy en pruebas para OpenGNSys #@author Ramon Gomez, ETSII Universidad de Sevilla #@date 2009/09/10 #*/ ## function ogRestoreImage () { # Variables locales local PART PARTSIZE IMGFILE IMGSIZE # Si se solicita, mostrar ayuda. if [ "$*" == "help" ]; then ogHelp "$FUNCNAME" "$FUNCNAME path_dir str_image int_ndisk int_npart" \ "$FUNCNAME REPO /aula1/winxp 1 1" return fi # Error si no se reciben 4 parámetros. [ $# -lt 4 ] && ogRaiseError $OG_ERR_FORMAT && return $? # Procesar parámetros. PART="$(ogDiskToDev "$3" "$4")" || return $? IMGFILE=$(ogGetPath "$1" "$2.img") || return $? [ -r "$IMGFILE" ] || ogRaiseError OG_ERR_NOTFOUND "$IMGFILE" || return $? # Error si la imagen no cabe en la particion. IMGSIZE=$(ogGetImageSize "$1" "$2") PARTSIZE=$(ogGetPartitionSize $3 $4) if [ $IMGSIZE -gt $PARTSIZE ]; then ogRaiseError $OG_ERR_PARTITION "$IMGSIZE > $PARTSIZE" return $? fi # Comprobar el bloqueo de la partición, desmontarla y bloquearla. if ogIsLocked $3 $4; then ogRaiseError $OG_ERR_LOCKED "$3,$4" return $? fi ogUnmount $3 $4 2>/dev/null || return $? ogLock $3 $4 || return $? trap "ogUnlock $3 $4" 1 2 3 6 9 # Restaurar según el tipo de sistema de archivos. # Atención: no se comprueba incongruencia entre partición e imagen. TYPE="$(ogGetFsType $3 $4)" case "$TYPE" in EXT[234]|REISERFS|XFS|JFS) partimage -M -f3 -o -d -V0 -B gui=no -c -z1 --volume=0 restore $PART "$IMGFILE" ;; NTFS|HNTFS) partimage -M -f3 -o -d -V0 -B gui=no -c -z1 --volume=0 restore $PART "$IMGFILE" ;; FAT16|FAT32|HFAT16|HFAT32) partimage -M -f3 -o -d -V0 -B gui=no -c -z1 --volume=0 restore $PART "$IMGFILE" ;; *) ogRaiseError $OG_ERR_FORMAT return $? ;; esac ERRCODE=$? if [ $ERRCODE != 0 ]; then ogRaiseError $OG_ERR_IMAGE "$IMGFILE, $3, $4" fi ogUnlock $3 $4 return $ERRCODE } function ogCreateImageFromPartition () { #/** @function CreateImageFromPartition: @brief Crea una imagen de la particion indicada, utilizando el programa definido en las variable $CloneImageNTFS y $CloneImageEXT23 #@param $1 int DiskEAC #@param $2 int_PartitionEAC #@param $3 str_Repositorio ......... parametro pasado a ConectToRepo, admite $REPO $CACHE str_IP_servidorAlterno #@param $4 str_pathbase .............. Pathbase, directorio relativo, de la imagen, en EAC, se ha definido que todo repositorio comience por hdimages, pero puede variar, para adaparse a usb, o cualquier otro almacenamiento. #@param $5 str_NameImage.str_compresion .......... (como compresion admite gzip y lzop) #@param ejemplo: CreateImageFromPartition 1 1 $IP hdimages/pruebas/ base.gzip #@return la propia de la herramienta de clonacion partimage o ntfsclone #@return genera la imagen con el nombre (imagen.compresion), y se le a?ade un guion y el numero de particion(parametro $2). #@return Tambien se solicita al servidor EAC, la creaci?n del fichero meta torrent, que tendra el nombre tal base.gzip-1.torrent, #@return Tambien se crea el fichero base.gzip-1.mcast con informacion para su uso con multicast, tal base.gzip-1.mcast #@warning Salidas de errores no determinada #@attention #@note Pendiente: que admita como segundo parametro el valor 0 (para que identifique el MBR del disco) #@version 0.1 Date: 27/10/2008 Author Antonio J. Doblas Viso. Universidad de Malaga #*/ if [ $# != 5 ] then echo "sintaxis: CreateImageFromPartition " echo "ejemplo: CreateImageFromPartition 1 1 \$IP images/pruebas/ base.gzip" echo " en iprepositorio admite cualquier ip de un servdior EAC, se llama a la funcion MountRepo ip" fi if [ $# = 5 ] then CloneImageNTFS="${CLONETOOLSNTFS:-partimage}" CloneImageEXT23="${CLONETOOLSEXT:-partimage}" CompresionImage="${CLONETOOLSCOMPRESSOR:-gzip}" disco=`ogDiskToDev $1 $2` ogUnmountPartition $1 $2 fs=`ogGetFsType $1 $2` echo determinando tipo de Sistema Operativo y consulando la variable global CloneImageNTFS: $fs case $fs in "NTFS") case $CloneImageNTFS in "ntfsclone") #imaged="ntfsclone --force --save-image -O - $disco | " imaged="ntfsclone --force --save-image -O - $disco" program=ntfsclone ;; "partimage") #imaged="partimage -M -f3 -o -d -B gui=no -c -z0 --volume=0 save $disco stdout |" imaged="partimage -M -f3 -o -d -B gui=no -c -z0 --volume=0 save $disco stdout" program=partimage ;; "partimage-ng") #echo "partimage-ng" #imaged="partimage-ng save $disco stdout" program=partimage-ng ;; "partclone") #echo "partclone" #imaged="partclone.ntfs -c -F -s $disco | " imaged="partclone.ntfs -c -F -s $disco" program=partclone.ntfs #zcat ~/image_sda1.pcl.gz | partclone.ext4 -r -o /dev/sda1 ;; esac ;; EXT[234]|REISERFS) case $CloneImageEXT23 in "partimage") imaged="partimage -M -f3 -o -d -B gui=no -c -z0 --volume=0 save $disco stdout" program=partimage ;; "partimage-ng") #echo "partimage-ng" imaged="partimage-ng save $disco stdout" program=partimage-ng ;; "partclone") echo "partclone" imaged="partclone.ext3 -c -F -C -s $disco" program=partclone.ext3 #zcat ~/image_sda1.pcl.gz | partclone.ext4 -r -o /dev/sda1 ;; esac ;; esac # utilizando mbuffer para reducir posibles errores de acceso a discos imaged="$imaged | mbuffer -m 70%" #metodo de compresion. case $CompresionImage in "gzip") comando="$imaged | gzip -c >" ;; "lzop") comando="$imaged | lzop >" ;; esac #. determnamos el fichero donde se almacenar? la image #camino=`ConnectToRepo $3 $4 $5` #MkdirPath $camino firstcamino=`ogNewPath $3 $4` camino=$firstcamino$5 echo $camino sleep 1 #preparamos y ejecutamos el comanod a realizar echo "Creando imagen particion $disco programa $program compresion $CompresionImage en el repositorio $3 como $4 $5 - $2" comando="$comando ${camino}-$2" echo "comando: $comando" echo $comando > /tmp/run.sh sh /tmp/run.sh unset comando #iniciamos la creacion del torrent echo "Iniciando la creacion del punto torrent con CreateTorrentFromImage ip=$3 path=$4 image=$5-$2" echo #CreateTorrentFromImage $3 $4 $5-$2 # iniciacmos el putno mcast echo "creando un punto mcast ${camino}-$2.mcast" echo "program;$program" > ${camino}.mcast echo "compresion;$CompresionImage" >> ${camino}.mcast echo "fsimage;$fs" >> ${camino}.mcast #UmountRepo $3 fi }