#!/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.1 - Integracion para Opengnsys - HIDRA:CrearImagen{EXT3, NTFS}.sh; EAC: CreateImageFromPartition () en Deploy.lib #@author Ramon Gomez, ETSII Universidad de Sevilla #@Date 2008/05/13 #@author Antonio J. Doblas Viso. Universidad de Malaga #@date 2008/10/27 #@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 PROGRAM 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. [ $# -ne 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").pgz" 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]) PROGRAM=partclone.extfs ;; REISERFS|XFS|JFS) PROGRAM=partclone.dd ;; NTFS|HNTFS) PROGRAM=partclone.ntfs ;; FAT16|FAT32|HFAT16|HFAT32) PROGRAM=partclone.fat ;; HFS|HFS+) PROGRAM=partclone.hfsp ;; *) ogRaiseError $OG_ERR_PARTITION "$1 $2 $TYPE" return $? ;; esac $PROGRAM -c -C -F -s $PART | mbuffer -q -m 70% | gzip -c > "$IMGFILE" # 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 } #/** # ogGetImageFs str_repo path_image #@brief Devuelve el tipo de 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 str_imgtype - mnemónico del tipo de sistema de archivos #@exception OG_ERR_FORMAT formato incorrecto. #@exception OG_ERR_NOTFOUND fichero de imagen no encontrado. #@todo Comprobar salidas para todos los tipos de sistemas de archivos. #/** function ogGetImageFs () { local IMGFILE IMGTYPE IMGTYPE=$(ogGetImageType "$1" "$2") IMGFILE=$(ogGetPath "$1" "$2.$IMGTYPE") || return $? [ -r "$IMGFILE" ] || ogRaiseError OG_ERR_NOTFOUND "$IMGFILE" || return $? case "$IMGTYPE" in img) # Partimage. partimage -B gui=no imginfo "$IMGFILE" 2>&1 | \ awk '/^Filesystem/ {sub(/\.\.+/," "); if ($2=="ntfs") print NTFS; else { sub(/fs$/,""); print toupper($2);} }' ;; pgz) # Partclone / GZip gzip -dc "$IMGFILE" | partclone.chkimg -C -s - 2>&1 | \ awk '/^File system/ {if ($2=="EXTFS") print "EXT3"; else print $3;}' ;; *) # Error si el fichero de imagen no es accesible. ogRaiseError OG_ERR_NOTFOUND "$IMGFILE" return $? ;; esac } # 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 int_size - 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 IMGTYPE # 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. [ $# -ne 2 ] && ogRaiseError $OG_ERR_FORMAT && return $? # Devuelve el tamaño de la imagen en KB. IMGTYPE=$(ogGetImageType "$1" "$2") IMGFILE=$(ogGetPath "$1" "$2.$IMGTYPE") case "$IMGTYPE" in img) # Partimage. partimage -B gui=no imginfo "$IMGFILE" 2>&1 | \ awk '/Partition size/ {sub(/\.\.+/," "); ps=$3} END {print ps*1024*1024;}' ;; pgz) # Partclone / GZip gzip -dc "$IMGFILE" | partclone.chkimg -C -s - 2>&1 | \ awk -F: '/Block size/ {bs=$2} /Used block/ {ub=$2} END {print bs*ub/1024}' ;; *) # Error si el fichero de imagen no es accesible. ogRaiseError OG_ERR_NOTFOUND "$IMGFILE" return $? ;; esac } #### PRUEBAS # Obtener tipo de imagen function ogGetImageType () { local IMGFILE IMGTYPE EXT for EXT in img pgz; do IMGFILE=$(ogGetPath "$1" "$2.$EXT") [ -r "$IMGFILE" ] && IMGTYPE="$EXT" done echo $IMGTYPE } #/** # 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. #@todo Comprobar incongruencias partición-imagen, control de errores, definir parámetros, caché/repositorio, etc. #@version 0.1 - Integracion para Opengnsys - HIDRA:RestaurarImagen{EXT3, NTFS}.sh; EAC: RestorePartitionFromImage() en Deploy.lib #@author Ramon Gomez, ETSII Universidad de Sevilla #@Date 2008/05/13 #@author Antonio J. Doblas Viso. Universidad de Malaga #@date 2008/10/27 #@version 0.9 - Primera version muy en pruebas para OpenGnSys #@author Ramon Gomez, ETSII Universidad de Sevilla #@date 2009/09/10 #*/ ## function ogRestoreImage () { # Variables locales local PART PARTSIZE IMGFILE IMGTYPE IMGSIZE FSTYPE # 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 $? IMGTYPE=$(ogGetImageType "$1" "$2") IMGFILE=$(ogGetPath "$1" "$2.$IMGTYPE") [ -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 imagen. # Atención: no se comprueba el tipo de sistema de archivos. # Atención: no se comprueba incongruencia entre partición e imagen. #FSTYPE="$(ogGetFsType $3 $4)" case "$IMGTYPE" in img) # Partimage partimage -M -f3 -o -d -V0 -B gui=no -c -z1 --volume=0 restore $PART "$IMGFILE" ;; pgz) # Partclone / GZip gzip -dc "$IMGFILE" | mbuffer -q -m 70% | partclone.restore -C -F -o "$PART" ;; *) # Error si imagen no accesible o de tipo desconocido. 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 }