#!/bin/bash # Libreria provisional para uso de UEFI # Las funciones se incluirán las librerías ya existentes #/** # ogGrubUefiConf int_ndisk int_part str_dir_grub #@brief Genera el fichero grub.cfg de la ESP #@param int_ndisk nº de orden del disco #@param int_part nº de partición #@param str_dir_grub prefijo del directorio de grub en la partición de sistema. ej: /boot/grubPARTITION #@return (nada, por determinar) #@exception OG_ERR_FORMAT formato incorrecto. #@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado. #@TODO Confirmar si el fichero "$EFIDIR/EFI/$BOOTLABEL/grub.cfg" es necesario. #*/ ## function ogGrubUefiConf () { local EFIDIR BOOTLABEL GRUBEFI UUID DEVICE PREFIXSECONDSTAGE EFIGRUBDIR # Si se solicita, mostrar ayuda. if [ "$*" == "help" ]; then ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_part [ str_dir_grub ]" \ "$FUNCNAME 1 2" \ "$FUNCNAME 1 3 /boot/grubPARTITION" return fi # Error si no se reciben al menos 2 parámetros. [ $# -ge 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_part [ str_dir_grub ]" || return $? # Directorio del grub en la partición de sistema PREFIXSECONDSTAGE="$3" EFIDIR=$(ogMount $(ogGetEsp)) || ogRaiseError $OG_ERR_PARTITION "ESP" || return $? BOOTLABEL=$(printf "Part-%02d-%02d" $1 $2) EFIGRUBDIR="$EFIDIR/EFI/$BOOTLABEL/boot/grub" # Comprobamos que existe directorio [ -d "$EFIGRUBDIR" ] || mkdir -p "$EFIGRUBDIR" # Parcheamos uuid y particion en grub.cfg UUID=$(blkid -o value -s UUID $(ogDiskToDev $1 $2)) DEVICE="hd$(expr $1 - 1 ),gpt$2" cat << EOT > $EFIGRUBDIR/grub.cfg set root='$DEVICE' set prefix=(\$root)'${PREFIXSECONDSTAGE}/boot/grub' configfile \$prefix/grub.cfg EOT # Provisional: confirmar si el segundo archivo se utiliza #cp $EFIGRUBDIR/grub.cfg "$EFIDIR/EFI/$BOOTLABEL/grub.cfg" } #/** # ogUuidChange int_ndisk str_repo #@brief Reemplaza el UUID de un sistema de ficheros. #@param int_ndisk nº de orden del disco #@param int_part nº de partición #@return (nada, por determinar) #@exception OG_ERR_FORMAT formato incorrecto. #@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado. #*/ ## function ogUuidChange () { local MNTDIR DEVICE UUID NEWUUID f # Si se solicita, mostrar ayuda. if [ "$*" == "help" ]; then ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_part" \ "$FUNCNAME 1 2" return fi # Error si no se reciben al menos 2 parámetros. [ $# -eq 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_part" || return $? # Comprobamos que exista la partición MNTDIR=$(ogMount $1 $2) || ogRaiseError $OG_ERR_NOTFOUND "Device $1 $2" || return $? DEVICE=$(ogDiskToDev $1 $2) UUID=$(blkid -o value -s UUID $DEVICE) NEWUUID=$(cat /proc/sys/kernel/random/uuid) # Cambiamos UUID a la partición ogUnmount $1 $2 tune2fs $DEVICE -U $NEWUUID # Cambiamos UUID en la configuración (fstab y grub) ogMount $1 $2 for f in $MNTDIR/etc/fstab $MNTDIR/{,boot/}{{grubMBR,grubPARTITION}/boot/,}{grub{,2},{,efi/}EFI/*}/{menu.lst,grub.cfg}; do [ -r $f ] && sed -i s/$UUID/$NEWUUID/g $f done } #/** # ogCopyEfiBootLoader int_ndisk str_repo path_image #@brief Copia el cargador de arranque desde la partición EFI a la de sistema. #@param int_ndisk nº de orden del disco #@param int_part nº de partición #@return (nada, por determinar) #@exception OG_ERR_FORMAT formato incorrecto. #@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado. #@note Si existe el cargador en la partición de sistema no es válido #*/ ## function ogCopyEfiBootLoader () { # Variables locales local MNTDIR EFIDIR BOOTLABEL OSVERSION LOADER f # Si se solicita, mostrar ayuda. if [ "$*" == "help" ]; then ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_part" \ "$FUNCNAME 1 2" return fi # Error si no se reciben 2 arámetros. [ $# == 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_part" || return $? # Comprobamos que exista partición de sistema y la ESP MNTDIR=$(ogMount $1 $2) || ogRaiseError $OG_ERR_PARTITION "$DISK $PART" || return $? EFIDIR=$(ogMount $(ogGetEsp)) || ogRaiseError $OG_ERR_PARTITION "ESP" || return $? # Comprobamos que exista el cargador BOOTLABEL=$(printf "Part-%02d-%02d" $1 $2) OSVERSION=$(ogGetOsVersion $1 $2) case $OSVERSION in *Windows\ 10*) for f in $EFIDIR/EFI/{$BOOTLABEL,Microsoft}/Boot/bootmgfw.efi; do [ -r $f ] && LOADER=$f done [ -n "$LOADER" ] || ogRaiseError $OG_ERR_NOTOS "$1 $2 ($OSVERSION, EFI)" || return $? # Si existe el directorio Boot lo borramos [ -d $MNTDIR/Boot ] && rm -rf $MNTDIR/Boot DIRLOADER=$(realpath "${LOADER%/*}/..") cp -r ${DIRLOADER}/Boot $MNTDIR ;; esac } #/** # ogRestoreEfiBootLoader int_ndisk str_repo #@brief Copia el cargador de arranque de la partición de sistema a la partición EFI. #@param int_ndisk nº de orden del disco #@param int_part nº de partición #@return (nada, por determinar) #@exception OG_ERR_FORMAT formato incorrecto. #@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado (partición de sistema o EFI). #@exception OG_ERR_NOTOS sin sistema operativo. #*/ ## function ogRestoreEfiBootLoader () { # Variables locales local MNTDIR EFIDIR BOOTLABEL OSVERSION LOADER f UUID DEVICE # Si se solicita, mostrar ayuda. if [ "$*" == "help" ]; then ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_part" \ "$FUNCNAME 1 2" return fi # Error si no se reciben 2 arámetros. [ $# == 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_part" || return $? # Comprobamos que exista partición de sistema y la ESP MNTDIR=$(ogMount $1 $2) || ogRaiseError $OG_ERR_PARTITION "$DISK $PART" || return $? EFIDIR=$(ogMount $(ogGetEsp)) if [ "$EFIDIR" == "" ]; then ogFormat $(ogGetEsp) FAT32 EFIDIR=$(ogMount $(ogGetEsp)) || ogRaiseError $OG_ERR_PARTITION "ESP" || return $? fi # Comprobamos que exista el cargador #BOOTLABEL=$(printf "Part-%02d-%02d" $1 $2) OSVERSION=$(ogGetOsVersion $1 $2) case $OSVERSION in *Windows\ 10*) BOOTLABEL=$(printf "Part-%02d-%02d" $1 $2) LOADER=$(ogGetPath $MNTDIR/Boot/bootmgfw.efi) [ -n "$LOADER" ] || ogRaiseError $OG_ERR_NOTOS "$1 $2 ($OSVERSION, EFI)" || return $? [ -r $EFIDIR/$BOOTLABEL ] && rm -rf $EFIDIR/$BOOTLABEL mkdir -p $EFIDIR/EFI/$BOOTLABEL cp -r "${LOADER%/*}" $EFIDIR/EFI/$BOOTLABEL ;; esac } # ogRestoreUuidPartitions #@brief Restaura los uuid de las particiones y la tabla de particiones #@param int_ndisk nº de orden del disco #@param int_nfilesys nº de orden del sistema de archivos #@param REPO|CACHE repositorio #@param str_imgname nombre de la imagen #@exception OG_ERR_FORMAT Formato incorrecto. #@exception OG_ERR_NOTFOUND No encontrado fichero de información de la imagen (con uuid) function ogRestoreUuidPartitions () { local DISK PART IMGNAME INFOFILE DEVICE DATA GUID UUID IMGGUID local EFIDEVICE EFIDATA EFIGUID EFIUUID EFIUUID IMGEFIGUID # Si se solicita, mostrar ayuda. if [ "$*" == "help" ]; then ogHelp "$FUNCNAME" "$FUNCNAME REPO|CACHE str_imgname int_ndisk int_npart" \ "$FUNCNAME REPO Windows 1 2" return fi # Error si no se reciben 4 parámetros. [ $# -eq 4 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME REPO|CACHE str_imgname int_ndisk int_npart" || return $? # Sólo se ejecuta si es UEFI [ ogIsEfiActive ] || return # Parámetros de entrada IMGNAME="$2" INFOFILE="$OGIMG/.$IMGNAME.img.json" [ "${1^^}" == "CACHE" ] && INFOFILE="$OGCAC$INFOFILE" # TODO: que la función getPath soporte archivos ocultos ls $INFOFILE &>/dev/null || ogRaiseError $OG_ERR_NOTFOUND "$INFOFILE" || return $? DISK=$3 PART=$4 DEVICE=$(ogDiskToDev $DISK) read -e EFIDISK EFIPART <<<"$(ogGetEsp)" # Datos de la imagen IMGGUID=$(jq .guid $INFOFILE|tr -d \") IMGEFIGUID=$(jq .espguid $INFOFILE|tr -d \") # Datos actuales DATA=$(sfdisk -J $DEVICE) GUID=$(echo $DATA|jq ".partitiontable|.id"|tr -d \") if [ "$IMGGUID" != "$GUID" ]; then echo sgdisk -U "$IMGGUID" "$DEVICE" sgdisk -U "$IMGGUID" "$DEVICE" partprobe fi if [ $DISK -eq $EFIDISK ]; then EFIDATA=$DATA EFIDEVICE=$DEVICE else EFIDEVICE=$(ogDiskToDev $EFIDISK) || return $? EFIDATA=$(sfdisk -J $EFIDEVICE) EFIGUID=$(echo $EFIDATA|jq ".partitiontable|.id"|tr -d \") if [ "$IMGEFIGUID" != "$EFIGUID" ]; then echo sgdisk -U "$IMGEFIGUID" "$EFIDEVICE" sgdisk -U "$IMGEFIGUID" "$EFIDEVICE" partprobe fi fi } # ogSaveImageInfo #@brief Crea un fichero con la información de la imagen. #@param int_ndisk nº de orden del disco #@param int_nfilesys nº de orden del sistema de archivos #@param REPO|CACHE repositorio #@param str_imgname nombre de la imagen #@exception OG_ERR_FORMAT formato incorrecto. #@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado. function ogSaveImageInfo () { local DISK PART IMGDIR IMGNAME INFO INFOFILE DEVICE DATA GUID local EFIPARTDEVICE EFIDEVICE EFIDATA EFIGUID # Si se solicita, mostrar ayuda. if [ "$*" == "help" ]; then ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_nfilesys REPO|CACHE str_imgname" \ "$FUNCNAME 1 2 REPO Windows" return fi # Error si no se reciben 4 parámetros. [ $# -eq 4 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_nfilesys REPO|CACHE str_imgname" || return $? DISK=$1 PART=$2 IMGDIR="$(ogGetParentPath "$3" "/$4")" # Si no existe el directorio de la imagen me salgo [ "$IMGDIR" != "" ] || ogRaiseError $OG_ERR_NOTFOUND "$3 $(dirname $4)" || return $? IMGNAME="$(basename "$4")" INFOFILE="$IMGDIR/.$IMGNAME.img.json" DEVICE=$(ogDiskToDev $DISK) || return $? DATA=$(sfdisk -J $DEVICE) GUID=$(echo $DATA|jq ".partitiontable|.id"|tr -d \") # Información de la imagen. Valor inicial de efi: false INFO=$(cat << EOT | jq . {"name":"$IMGNAME","efi":"false","guid":"$GUID"} EOT ) if ogIsEfiActive; then # Cambio valor de efi a true INFO=$(echo $INFO| jq --arg aux true '. + {efi: $aux}') # Obtener partición EFI. read -e EFIDISK EFIPART <<<"$(ogGetEsp)" EFIPARTDEVICE=$(ogDiskToDev $EFIDISK $EFIPART) || return $? if [ $DISK -eq $EFIDISK ]; then EFIDEVICE=$DEVICE EFIDATA=$DATA EFIGUID=$GUID else EFIDEVICE=$(ogDiskToDev $EFIDISK) EFIDATA=$(sfdisk -J $EFIDEVICE) EFIGUID=$(echo $EFIDATA|jq ".partitiontable|.id"|tr -d \") fi # Incluyo valor de EFIGUID (por si partición EFI en distinto disco que la de sistema) INFO=$(echo $INFO| jq --arg aux $EFIGUID '. + {espguid: $aux}') fi cat << EOT | jq . > $INFOFILE $INFO EOT }