source: client/engine/UEFI.lib @ f028c36

918-git-images-111dconfigfileconfigure-oglivegit-imageslgromero-new-oglivemainmaint-cronmount-efivarfsmultivmmultivm-ogboot-installerogClonningEngineogboot-installer-jenkinsoglive-ipv6test-python-scriptsticket-301ticket-50ticket-50-oldticket-577ticket-585ticket-611ticket-612ticket-693ticket-700ubu24tplunification2use-local-agent-oglivevarios-instalacion
Last change on this file since f028c36 was 30238ab, checked in by Irina Gómez <irinagomez@…>, 6 years ago

#802 UEFI Windows compatibility: necessary functions for create and restore images.

  • Property mode set to 100644
File size: 11.7 KB
Line 
1#!/bin/bash
2# Libreria provisional para uso de UEFI
3# Las funciones se incluirán las librerías ya existentes
4
5#/**
6#         ogGrubUefiConf int_ndisk int_part str_dir_grub
7#@brief   Genera el fichero grub.cfg de la ESP
8#@param   int_ndisk    nº de orden del disco
9#@param   int_part     nº de partición
10#@param   str_dir_grub nombre del directorio de grub en la partición de sistema. ej: grubPARTITION
11#@return  (nada, por determinar)
12#@exception OG_ERR_FORMAT    formato incorrecto.
13#@exception OG_ERR_NOTFOUND  fichero o dispositivo no encontrado.
14#@TODO    Confirmar si el fichero "$EFIDIR/EFI/$BOOTLABEL/grub.cfg" es necesario.
15#*/ ##
16function ogGrubUefiConf () {
17local EFIDIR BOOTLABEL GRUBEFI UUID DEVICE DIRGRUB
18
19# Si se solicita, mostrar ayuda.
20if [ "$*" == "help" ]; then
21    ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_part [ str_dir_grub ]" \
22           "$FUNCNAME 1 2" \
23           "$FUNCNAME 1 3 grubPARTITION/boot/grub"
24    return
25fi
26
27# Error si no se reciben al menos 2 parámetros.
28[ $# -ge 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_part [ str_dir_grub ]" || return $?
29
30# Directorio del grub en la partición de sistema
31DIRGRUB="${3:-boot/grub}"
32
33EFIDIR=$(ogMount $(ogGetEsp)) || ogRaiseError $OG_ERR_PARTITION "ESP" || return $?
34BOOTLABEL=$(printf "Part-%02d-%02d" $1 $2)
35GRUBDIR="$EFIDIR/EFI/$BOOTLABEL/boot/grub"
36# Comprobamos que existe directorio
37[ -d "$GRUBDIR" ] || mkdir -p "$GRUBDIR"
38# Parcheamos uuid y particion en grub.cfg
39UUID=$(blkid -o value -s UUID $(ogDiskToDev $1 $2))
40DEVICE="hd$(expr $1 - 1 ),gpt$2"
41
42cat << EOT > $GRUBDIR/grub.cfg
43set root='$DEVICE'
44set prefix=(\$root)'/$DIRGRUB'
45configfile \$prefix/grub.cfg
46EOT
47
48# Provisional: confirmar si el segundo archivo se utiliza
49cp $GRUBDIR/grub.cfg "$EFIDIR/EFI/$BOOTLABEL/grub.cfg"
50}
51
52#/**
53#         ogUuidChange int_ndisk str_repo
54#@brief   Reemplaza el UUID de un sistema de ficheros.
55#@param   int_ndisk    nº de orden del disco
56#@param   int_part     nº de partición
57#@return  (nada, por determinar)
58#@exception OG_ERR_FORMAT    formato incorrecto.
59#@exception OG_ERR_NOTFOUND  fichero o dispositivo no encontrado.
60#@TODO    Se utiliza el comando uuidgen que no existe en el ogLive
61#*/ ##
62function ogUuidChange () {
63local MNTDIR DEVICE UUID NEWUUID f
64
65# Si se solicita, mostrar ayuda.
66if [ "$*" == "help" ]; then
67    ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_part" \
68           "$FUNCNAME 1 2"
69    return
70fi
71
72# Error si no se reciben al menos 2 parámetros.
73[ $# -eq 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_part" || return $?
74
75# Comprobamos que exista la partición
76MNTDIR=$(ogMount $1 $2) || ogRaiseError $OG_ERR_NOTFOUND "Device $1 $2" || return $?
77DEVICE=$(ogDiskToDev $1 $2)
78UUID=$(blkid -o value -s UUID $DEVICE)
79NEWUUID=$(uuidgen)
80
81# Cambiamos UUID a la partición
82ogUnmount $1 $2
83tune2fs $DEVICE -U $NEWUUID
84
85# Cambiamos UUID en la configuración (fstab y grub)
86ogMount $1 $2
87for f in $MNTDIR/etc/fstab $MNTDIR/{,boot/}{{grubMBR,grubPARTITION}/boot/,}{grub{,2},{,efi/}EFI/*}/{menu.lst,grub.cfg}; do
88        [ -r $f ] && echo sed -i s/$UUID/$NEWUUID/g $f
89        [ -r $f ] && sed -i s/$UUID/$NEWUUID/g $f
90done
91}
92
93#/**
94#         ogCopyEfiBootLoader int_ndisk str_repo path_image
95#@brief   Copia el cargador de arranque desde la partición EFI a la de sistema.
96#@param   int_ndisk    nº de orden del disco
97#@param   int_part     nº de partición
98#@return  (nada, por determinar)
99#@exception OG_ERR_FORMAT    formato incorrecto.
100#@exception OG_ERR_NOTFOUND  fichero o dispositivo no encontrado.
101#@note    Si existe el cargador en la partición de sistema no es válido
102#*/ ##
103function ogCopyEfiBootLoader () {
104# Variables locales
105local MNTDIR EFIDIR BOOTLABEL OSVERSION LOADER f
106
107# Si se solicita, mostrar ayuda.
108if [ "$*" == "help" ]; then
109    ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_part" \
110           "$FUNCNAME 1 2"
111    return
112fi
113
114# Error si no se reciben 2 arámetros.
115[ $# == 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_part" || return $?
116
117# Comprobamos que exista partición de sistema y la  ESP
118MNTDIR=$(ogMount $1 $2) || ogRaiseError $OG_ERR_PARTITION "$DISK $PART" || return $?
119EFIDIR=$(ogMount $(ogGetEsp)) || ogRaiseError $OG_ERR_PARTITION "ESP" || return $?
120
121# Comprobamos que exista el cargador
122BOOTLABEL=$(printf "Part-%02d-%02d" $1 $2)
123OSVERSION=$(ogGetOsVersion $1 $2)
124case $OSVERSION in
125    *Windows\ 10*)
126        for f in $EFIDIR/EFI/{$BOOTLABEL,Microsoft}/Boot/bootmgfw.efi; do
127            [ -r $f ] && LOADER=$f
128        done
129        [ -n "$LOADER" ] || ogRaiseError $OG_ERR_NOTOS "$1 $2 ($OSVERSION, EFI)" || return $?
130        # Si existe el directorio Boot lo borramos
131        [ -d $MNTDIR/Boot ] && rm -rf $MNTDIR/Boot
132        DIRLOADER=$(realpath "${LOADER%/*}/..")
133        cp -r ${DIRLOADER}/Boot $MNTDIR
134        ;;
135esac
136}
137
138#/**
139#         ogRestoreEfiBootLoader int_ndisk str_repo
140#@brief   Copia el cargador de arranque de la partición de sistema a la partición EFI.
141#@param   int_ndisk    nº de orden del disco
142#@param   int_part     nº de partición
143#@return  (nada, por determinar)
144#@exception OG_ERR_FORMAT    formato incorrecto.
145#@exception OG_ERR_NOTFOUND  fichero o dispositivo no encontrado (partición de sistema o EFI).
146#@exception OG_ERR_NOTOS     sin sistema operativo.
147#@note    Si existe el cargador en la partición de sistema puede no ser válido
148#*/ ##
149function ogRestoreEfiBootLoader () {
150# Variables locales
151local MNTDIR EFIDIR BOOTLABEL OSVERSION LOADER f UUID DEVICE
152
153# Si se solicita, mostrar ayuda.
154if [ "$*" == "help" ]; then
155    ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_part" \
156           "$FUNCNAME 1 2"
157    return
158fi
159
160# Error si no se reciben 2 arámetros.
161[ $# == 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_part" || return $?
162
163# Comprobamos que exista partición de sistema y la  ESP
164MNTDIR=$(ogMount $1 $2) || ogRaiseError $OG_ERR_PARTITION "$DISK $PART" || return $?
165EFIDIR=$(ogMount $(ogGetEsp)) || ogRaiseError $OG_ERR_PARTITION "ESP" || return $?
166
167# Comprobamos que exista el cargador
168#BOOTLABEL=$(printf "Part-%02d-%02d" $1 $2)
169OSVERSION=$(ogGetOsVersion $1 $2)
170case $OSVERSION in
171    *Windows\ 10*)
172        BOOTLABEL=$(printf "Part-%02d-%02d" $1 $2)
173        LOADER=$(ogGetPath $MNTDIR/Boot/bootmgfw.efi)
174        [ -n "$LOADER" ] || ogRaiseError $OG_ERR_NOTOS "$1 $2 ($OSVERSION, EFI)" || return $?
175        [ -r $EFIDIR/$BOOTLABEL ] && rm -rf $EFIDIR/$BOOTLABEL
176        mkdir -p $EFIDIR/EFI/$BOOTLABEL
177        cp -r "${LOADER%/*}" $EFIDIR/EFI/$BOOTLABEL
178        ;;
179esac
180}
181
182
183#         ogRestoreUuidPartitions
184#@brief   Restaura los uuid de las particiones y la tabla de particiones
185#@param   int_ndisk      nº de orden del disco
186#@param   int_nfilesys   nº de orden del sistema de archivos
187#@param   REPO|CACHE     repositorio
188#@param   str_imgname    nombre de la imagen
189#@exception OG_ERR_FORMAT    Formato incorrecto.
190#@exception OG_ERR_NOTFOUND  No encontrado fichero de información de la imagen (con uuid)
191function ogRestoreUuidPartitions () {
192local DISK PART IMGNAME INFOFILE DEVICE PARTDEVICE DATA GUID UUID IMGGUID IMGUUID
193local EFIPARTDEVICE EFIDEVICE EFIDATA EFIGUID EFIUUID EFIUUID IMGEFIGUID IMGEFIUUID
194
195# Si se solicita, mostrar ayuda.
196if [ "$*" == "help" ]; then
197    ogHelp "$FUNCNAME" "$FUNCNAME REPO|CACHE str_imgname int_ndisk int_npart" \
198           "$FUNCNAME REPO Windows 1 2"
199    return
200fi
201# Error si no se reciben 4 parámetros.
202[ $# -eq 4 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME REPO|CACHE str_imgname int_ndisk int_npart" || return $?
203
204# Sólo se ejecuta si es UEFI
205[ ogIsEfiActive ] || return
206
207# Parámetros de entrada
208IMGNAME="$2"
209INFOFILE="$OGIMG/.$IMGNAME.img.json"
210[ "${1^^}" == "CACHE" ] && INFOFILE="$OGCAC$INFOFILE"
211# TODO: que la función getPath soporte archivos ocultos
212ls $INFOFILE &>/dev/null || ogRaiseError $OG_ERR_NOTFOUND "$INFOFILE" || return $?
213DISK=$3
214PART=$4
215
216DEVICE=$(ogDiskToDev $DISK)
217PARTDEVICE=$(ogDiskToDev $DISK $PART) || return $?
218read -e EFIDISK EFIPART <<<"$(ogGetEsp)"
219EFIPARTDEVICE=$(ogDiskToDev $EFIDISK $EFIPART) || return $?
220
221# Datos de la imagen
222IMGGUID=$(jq .guid $INFOFILE|tr -d \")
223IMGUUID=$(jq .uuid $INFOFILE|tr -d \")
224IMGEFIGUID=$(jq .espguid $INFOFILE|tr -d \")
225IMGEFIUUID=$(jq .espuuid $INFOFILE|tr -d \")
226
227# Datos actuales
228DATA=$(sfdisk -J $DEVICE)
229GUID=$(echo $DATA|jq ".partitiontable|.id"|tr -d \")
230UUID=$(echo $DATA|jq ".partitiontable.partitions[]|select(.node==\"$PARTDEVICE\").uuid"|tr -d \")
231
232if [ "$IMGGUID" != "$GUID" ]; then
233    echo sgdisk -U "$IMGGUID"  "$DEVICE"
234    sgdisk -U "$IMGGUID"  "$DEVICE"
235    partprobe
236fi
237
238if [ "$IMGUUID" != "$UUID" ]; then
239    NUMPART="${PARTDEVICE##$DEVICE}"
240    echo sgdisk -u "${NUMPART}:$IMGUUID"  "$DEVICE"
241    sgdisk -u "${NUMPART}:$IMGUUID"  "$DEVICE"
242    partprobe
243fi
244
245if [ $DISK -eq $EFIDISK ]; then
246    EFIDATA=$DATA
247    EFIDEVICE=$DEVICE
248else
249    EFIDEVICE=$(ogDiskToDev $EFIDISK) || return $?
250    EFIDATA=$(sfdisk -J $EFIDEVICE)
251    EFIGUID=$(echo $EFIDATA|jq ".partitiontable|.id"|tr -d \")
252    if [ "$IMGEFIGUID" != "$EFIGUID" ]; then
253echo         sgdisk -U "$IMGEFIGUID"  "$EFIDEVICE"
254       sgdisk -U "$IMGEFIGUID"  "$EFIDEVICE"
255       partprobe
256   fi
257fi
258
259EFIUUID=$(echo $EFIDATA|jq ".partitiontable.partitions[]|select(.node==\"$EFIPARTDEVICE\").uuid"|tr -d \")
260if [ "$IMGEFIUUID" != "$EFIUUID" ]; then
261    EFINUMPART="${EFIPARTDEVICE##$EFIDEVICE}"
262    echo sgdisk -u "${EFINUMPART}:$IMGEFIUUID"  "$EFIDEVICE"
263    sgdisk -u "${EFINUMPART}:$IMGEFIUUID"  "$EFIDEVICE"
264    partprobe
265fi
266}
267
268#         ogSaveImageInfo
269#@brief   Crea un fichero con la información de la imagen.
270#@param   int_ndisk      nº de orden del disco
271#@param   int_nfilesys   nº de orden del sistema de archivos
272#@param   REPO|CACHE     repositorio
273#@param   str_imgname    nombre de la imagen
274#@exception OG_ERR_FORMAT    formato incorrecto.
275#@exception OG_ERR_NOTFOUND  fichero o dispositivo no encontrado.
276function ogSaveImageInfo () {
277local DISK PART IMGDIR IMGNAME INFO INFOFILE DEVICE PARTDEVICE DATA GUID UUID
278local EFIPARTDEVICE EFIDEVICE EFIDATA EFIUUID EFIGUID
279
280# Si se solicita, mostrar ayuda.
281if [ "$*" == "help" ]; then
282    ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_nfilesys REPO|CACHE str_imgname" \
283           "$FUNCNAME 1 2 REPO Windows"
284    return
285fi
286# Error si no se reciben 4 parámetros.
287[ $# -eq 4 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_nfilesys REPO|CACHE str_imgname" || return $?
288
289DISK=$1
290PART=$2
291IMGDIR="$(ogGetParentPath "$3" "/$4")"
292# Si no existe el directorio de la imagen me salgo
293[ "$IMGDIR" != "" ] || ogRaiseError $OG_ERR_NOTFOUND "$3 $(dirname $4)" || return $?
294IMGNAME="$(basename "$4")"
295INFOFILE="$IMGDIR/.$IMGNAME.img.json"
296
297DEVICE=$(ogDiskToDev $DISK) || return $?
298PARTDEVICE=$(ogDiskToDev $DISK $PART) || return $?
299DATA=$(sfdisk -J $DEVICE)
300GUID=$(echo $DATA|jq ".partitiontable|.id"|tr -d \")
301UUID=$(echo $DATA|jq ".partitiontable.partitions[]|select(.node==\"$PARTDEVICE\").uuid"|tr -d \")
302
303# Información de la imagen. Valor inicial de efi: false
304INFO=$(cat << EOT | jq .
305{"name":"$IMGNAME","efi":"false","guid":"$GUID","uuid":"$UUID"}
306EOT
307     )
308
309if ogIsEfiActive; then
310    # Cambio valor de efi a true
311    INFO=$(echo $INFO|  jq --arg aux true '. + {efi: $aux}')
312
313    # Obtener partición EFI.
314    read -e EFIDISK EFIPART <<<"$(ogGetEsp)"
315    EFIPARTDEVICE=$(ogDiskToDev $EFIDISK $EFIPART) || return $?
316    if [ $DISK -eq $EFIDISK ]; then
317        EFIDEVICE=$DEVICE
318        EFIDATA=$DATA
319        EFIGUID=$GUID
320    else
321        EFIDEVICE=$(ogDiskToDev $EFIDISK) || return $?
322        EFIDATA=$(sfdisk -J $EFIDEVICE)
323        EFIGUID=$(echo $EFIDATA|jq ".partitiontable|.id"|tr -d \")
324    fi
325    EFIUUID=$(echo $EFIDATA|jq ".partitiontable.partitions[]|select(.node==\"$EFIPARTDEVICE\").uuid"|tr -d \")
326
327    # Incluyo valor de EFIGUID (por si partición EFI en distinto disco que la de sistema)
328    INFO=$(echo $INFO|  jq --arg aux $EFIGUID '. + {espguid: $aux}')
329    # Incluyo valor de EFIUUID
330    INFO=$(echo $INFO|  jq --arg aux $EFIUUID '. + {espuuid: $aux}')
331fi
332
333cat << EOT | jq . > $INFOFILE
334$INFO
335EOT
336}
Note: See TracBrowser for help on using the repository browser.