refs #1218 add ogGrubInstallMbr()

code-review
Natalia Serrano 2024-12-12 10:54:45 +01:00
parent 3e64d7377c
commit d082bcf916
3 changed files with 174 additions and 9 deletions

View File

@ -20,6 +20,7 @@ import RegistryLib
import DiskLib import DiskLib
import InventoryLib import InventoryLib
import FileLib import FileLib
import UEFILib
#/** #/**
# ogBoot int_ndisk int_nfilesys [ NVRAMPERM ] [str_kernel str_initrd str_krnlparams] # ogBoot int_ndisk int_nfilesys [ NVRAMPERM ] [str_kernel str_initrd str_krnlparams]
@ -393,6 +394,106 @@ part_letter={registered_vol}
#@exception OG_ERR_FORMAT Formato incorrecto. #@exception OG_ERR_FORMAT Formato incorrecto.
#*/ ## #*/ ##
#ogGrubInstallMbr ('1', '1', 'FALSE')
#ogGrubInstallMbr ('1', '1', 'TRUE', 'nomodeset irqpoll pci=noacpi quiet splash')
def ogGrubInstallMbr (disk, par, checkos='FALSE', kernelparam=''):
backupname = '.backup.og'
#error si no es linux.
#version = InventoryLib.ogGetOsVersion (disk, par)
#if not version or 'Linux' not in version:
# SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, 'no es linux')
# return
firststage = DiskLib.ogDiskToDev ('1') #La primera etapa del grub se fija en el primer disco duro
secondstage = FileSystemLib.ogMount (disk, par) #localizar disco segunda etapa del grub
if not secondstage: return
os.makedirs (f'{secondstage}/boot/grub/', exist_ok=True)
prefixsecondstage = '/boot/grubMBR' #Localizar directorio segunda etapa del grub
efioptgrub = []
if InventoryLib.ogIsEfiActive():
esp = DiskLib.ogGetEsp()
efidisk, efipart = esp.split()
# Comprobamos que exista ESP y el directorio para ubuntu
efisecondstage = FileSystemLib.ogMount (efidisk, efipart)
if not efisecondstage:
FileSystemLib.ogFormat (efidisk, efipart, 'FAT32')
efisecondstage = FileSystemLib.ogMount (efidisk, efipart)
if not efisecondstage:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'ESP')
return
efisubdir = 'grub'
if os.path.isdir (f'{efisecondstage}/EFI/{efisubdir}'): # Borramos la configuración anterior
shutil.rmtree (f'{efisecondstage}/EFI/{efisubdir}')
os.makedirs (f'{efisecondstage}/EFI/{efisubdir}/Boot')
arch = InventoryLib.ogGetArch()
efioptgrub = ['--removable', '--no-nvram', '--uefi-secure-boot', '--target', f'{arch}-efi', f'--efi-directory={efisecondstage}/EFI/{efisubdir}']
# Si Reconfigurar segunda etapa (grub.cfg) == FALSE
if 'FALSE' == checkos.upper() and (os.path.exists (f'{secondstage}/boot/grub/grub.cfg') or os.path.exists (f'{secondstage}/boot/grub/grub.cfg{backupname}')):
if os.path.exists (f'{secondstage}/boot/grub/grub.cfg{backupname}'):
os.rename (f'{secondstage}/boot/grub/grub.cfg{backupname}', f'{secondstage}/boot/grub/grub.cfg')
if os.path.isdir (f'{secondstage}{prefixsecondstage}'):
shutil.rmtree (f'{secondstage}{prefixsecondstage}')
prefixsecondstage = '' # Reactivamos el grub con el grub.cfg original.
else: # SI Reconfigurar segunda etapa (grub.cfg) == TRUE
#llamada a updateBootCache para que aloje la primera fase del ogLive
subprocess.run (['scripts/updateBootCache.py'], check=True) ## nati: TODO: ver el path
if InventoryLib.ogIsEfiActive():
# UEFI: grubSintax necesita grub.cfg para detectar los kernels: si no existe recupero backup.
if not os.path.exists (f'{secondstage}/boot/grub/grub.cfg'):
if os.path.exists (f'{secondstage}/boot/grub/grub.cfg{backupname}'):
os.rename (f'{secondstage}/boot/grub/grub.cfg{backupname}', f'{secondstage}/boot/grub/grub.cfg')
else:
os.rename (f'{secondstage}/boot/grub/grub.cfg', f'{secondstage}/boot/grub/grub.cfg{backupname}')
with open ('/etc/default/grub', 'a') as fd: #Configur la sintaxis grub para evitar menus de "recovery" en el OGLive
fd.write ('GRUB_DISABLE_RECOVERY="true"\n')
fd.write ('GRUB_DISABLE_LINUX_UUID="true"\n')
os.makedirs (f'{secondstage}{prefixsecondstage}/boot/grub/') #Preparar configuración segunda etapa: crear ubicacion
subprocess.run (['sed', '-i', 's/^set -e/#set -e/', '/etc/grub.d/00_header']) #Preparar configuración segunda etapa: crear cabecera del fichero (ingnorar errores)
# (ogLive 5.0) Si 'pkgdatadir' está vacía ponemos valor de otros ogLive
subprocess.run (['sed', '-i', '/grub-mkconfig_lib/i\pkgdatadir=${pkgdatadir:-"${datarootdir}/grub"}', '/etc/grub.d/00_header'])
out = subprocess.run (['/etc/grub.d/00_header'], capture_output=True, text=True).stdout
with open (f'{secondstage}{prefixsecondstage}/boot/grub/grub.cfg', 'w') as fd:
fd.write (out + '\n')
#Preparar configuración segunda etapa: crear entrada del sistema operativo
out = subprocess.run (['grubSyntax', kernelparam], capture_output=True, text=True).stdout
with open (f'{secondstage}{prefixsecondstage}/boot/grub/grub.cfg', 'a') as fd:
fd.write (out + '\n')
# Renombramos la configuración de grub antigua
if os.path.exists (f'{secondstage}/boot/grub/grub.cfg'):
os.rename (f'{secondstage}/boot/grub/grub.cfg', f'{secondstage}/boot/grub/grub.cfg{backupname}')
eval = subprocess.run (['grub-install', '--force'] + efioptgrub + [f'--root-directory={secondstage}{prefixsecondstage}', firststage]).returncode
if InventoryLib.ogIsEfiActive(): # Movemos el grubx64.efi
for b in (glob.glob (f'{efisecondstage}/EFI/{efisubdir}/EFI/BOOT/*')):
os.rename (f'{efisecondstage}/EFI/{efisubdir}/EFI/BOOT/{b}', f'{efisecondstage}/EFI/{efisubdir}/Boot/{b}')
shutil.rmtree (f'{efisecondstage}/EFI/{efisubdir}/EFI')
shutil.copy2 ('/usr/lib/shim/shimx64.efi.signed', f'{efisecondstage}/EFI/{efisubdir}/Boot/shimx64.efi')
# Nombre OpenGnsys para cargador
shutil.copy2 (f'{efisecondstage}/EFI/{efisubdir}/Boot/grubx64.efi', f'{efisecondstage}/EFI/{efisubdir}/Boot/ogloader.efi')
# Creamos entrada NVRAM y la ponemos en segundo lugar
UEFILib.ogNvramAddEntry ('grub', '/EFI/grub/Boot/shimx64.efi')
grubentry = UEFILib.ogNvramList()
for l in grubentry.splitlines():
words = l.split (maxsplit=1)
if len(words) < 2: continue
if 'grub' == words[1]:
grubentry = words[0]
neworder = UEFILib.ogNvramGetOrder()
neworder = neworder[0:1] + [grubentry] + neworder[1:] ## la ponemos en segundo lugar
UEFILib.ogNvramSetOrder (neworder)
return eval
#/** #/**
# ogGrubInstallPartition int_disk_SECONDSTAGE int_partition_SECONDSTAGE bolean_Check_Os_installed_and_Configure_2ndStage # ogGrubInstallPartition int_disk_SECONDSTAGE int_partition_SECONDSTAGE bolean_Check_Os_installed_and_Configure_2ndStage
@ -405,9 +506,12 @@ part_letter={registered_vol}
#@exception OG_ERR_FORMAT Formato incorrecto. #@exception OG_ERR_FORMAT Formato incorrecto.
#*/ ## #*/ ##
#ogGrubInstallPartition ('1', '1', 'FALSE')
#ogGrubInstallPartition ('1', '1', 'TRUE', 'nomodeset irqpoll pci=noacpi quiet splash')
def ogGrubInstallPartition (disk, par, checkos='FALSE', kernelparam=''): def ogGrubInstallPartition (disk, par, checkos='FALSE', kernelparam=''):
backupname = '.backup.og' backupname = '.backup.og'
#error si no es linux.
version = InventoryLib.ogGetOsVersion (disk, par) version = InventoryLib.ogGetOsVersion (disk, par)
if not version or 'Linux' not in version: if not version or 'Linux' not in version:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, 'no es linux') SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, 'no es linux')
@ -416,12 +520,12 @@ def ogGrubInstallPartition (disk, par, checkos='FALSE', kernelparam=''):
firststage = DiskLib.ogDiskToDev (disk, par) #Localizar primera etapa del grub firststage = DiskLib.ogDiskToDev (disk, par) #Localizar primera etapa del grub
secondstage = FileSystemLib.ogMount (disk, par) #localizar disco segunda etapa del grub secondstage = FileSystemLib.ogMount (disk, par) #localizar disco segunda etapa del grub
prefixsecondstage = '/boot/grubPARTITION' #Localizar directorio segunda etapa del grub prefixsecondstage = '/boot/grubPARTITION' #Localizar directorio segunda etapa del grub
efioptgrub = [] # Si es EFI instalamos el grub en la ESP efioptgrub = []
#efibootdir = '' # Desde el bootdir uefi y bios buscan el grub.cfg en subdirectorios distintos.
if InventoryLib.ogIsEfiActive(): if InventoryLib.ogIsEfiActive():
esp = DiskLib.ogGetEsp() esp = DiskLib.ogGetEsp()
efidisk, efipart = esp.split() efidisk, efipart = esp.split()
# Comprobamos que exista ESP y el directorio para ubuntu
efisecondstage = FileSystemLib.ogMount (efidisk, efipart) efisecondstage = FileSystemLib.ogMount (efidisk, efipart)
if not efisecondstage: if not efisecondstage:
FileSystemLib.ogFormat (efidisk, efipart, 'FAT32') FileSystemLib.ogFormat (efidisk, efipart, 'FAT32')
@ -435,7 +539,6 @@ def ogGrubInstallPartition (disk, par, checkos='FALSE', kernelparam=''):
os.makedirs (f'{efisecondstage}/EFI/{efisubdir}/Boot') os.makedirs (f'{efisecondstage}/EFI/{efisubdir}/Boot')
arch = InventoryLib.ogGetArch() arch = InventoryLib.ogGetArch()
efioptgrub = ['--removable', '--no-nvram', '--uefi-secure-boot', '--target', f'{arch}-efi', f'--efi-directory={efisecondstage}/EFI/{efisubdir}'] efioptgrub = ['--removable', '--no-nvram', '--uefi-secure-boot', '--target', f'{arch}-efi', f'--efi-directory={efisecondstage}/EFI/{efisubdir}']
#efibootdir = '/boot'
# Si Reconfigurar segunda etapa (grub.cfg) == FALSE # Si Reconfigurar segunda etapa (grub.cfg) == FALSE
if 'FALSE' == checkos.upper() and (os.path.exists (f'{secondstage}/boot/grub/grub.cfg') or os.path.exists (f'{secondstage}/boot/grub/grub.cfg{backupname}')): if 'FALSE' == checkos.upper() and (os.path.exists (f'{secondstage}/boot/grub/grub.cfg') or os.path.exists (f'{secondstage}/boot/grub/grub.cfg{backupname}')):

View File

@ -210,7 +210,7 @@ def ogNvramGetNext():
# ogNvramGetOrder # ogNvramGetOrder
#@brief Muestra el orden de las entradas del gestor de arranque (NVRAM) #@brief Muestra el orden de las entradas del gestor de arranque (NVRAM)
#@return Orden de las entradas #@return Array, orden de las entradas
#@exception OG_ERR_NOTUEFI UEFI no activa. #@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ## #*/ ##
def ogNvramGetOrder(): def ogNvramGetOrder():
@ -309,10 +309,10 @@ def ogNvramInactiveEntry (entry):
#/** #/**
# ogNvramList # ogNvramList
#@brief Lista las entradas de la NVRAN (sólo equipos UEFI) #@brief Lista las entradas de la NVRAN (sólo equipos UEFI)
#@return Entradas de la NVRAM con el formato: orden etiqueta [* (si está activa) ] #@return Multiline string: entradas de la NVRAM con el formato: orden etiqueta [* (si está activa) ]
#@exception OG_ERR_NOTUEFI UEFI no activa. #@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ## #*/ ##
def ogNvramList (): def ogNvramList():
if not InventoryLib.ogIsEfiActive(): if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '') SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return return
@ -325,7 +325,7 @@ def ogNvramList ():
if re.search ('Boot[0-9]', words[0]): if re.search ('Boot[0-9]', words[0]):
active = '*' if '*' in words[0] else '' active = '*' if '*' in words[0] else ''
num = words[0][4:8].strip ('0') or '0' num = words[0][4:8].strip ('0') or '0'
ret += '{:>4s} {} {}'.format (num, words[1], active) ret += '{:>4s} {} {}\n'.format (num, words[1], active)
return ret return ret
@ -520,7 +520,7 @@ def ogNvramSetOrder (order):
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado. #@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ## #*/ ##
#ogNvramSetTimeout ('2') #ogNvramSetTimeout ('2')
def ogNvramSetTimeout (t) { def ogNvramSetTimeout (t):
if not InventoryLib.ogIsEfiActive(): if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '') SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return return
@ -528,7 +528,7 @@ def ogNvramSetTimeout (t) {
try: try:
num = int (t) ## raises ValueError if t doesn't look like a number num = int (t) ## raises ValueError if t doesn't look like a number
except ValueError: except ValueError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'ogNvramSetTimeout (timeout)' SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'ogNvramSetTimeout (timeout)')
return return
subprocess.run (['efibootmgr', '-t', t]) subprocess.run (['efibootmgr', '-t', t])

View File

@ -0,0 +1,62 @@
#!/usr/bin/python3
import os
import shutil
import ogGlobals
import SystemLib
import CacheLib
#/**
# updateBootCache
#@brief acelerador arranque pxe. incorpora a la cache el initrd y el kernel.
#@param 1
#@param ejemplo:
#@return
#@exception OG_ERR_NOTCACHE # 15 si cache no existe 15
#@exception OG_ERR_NOTFOUND=2 # Fichero o dispositivo no encontrado.
#@note
#@todo:
#*/ ##
oglivedir = os.environ.get ('oglivedir', 'ogLive')
ogbtftp = f'/opt/oglive/tftpboot/{oglivedir}'
ogbcache = f'{ogGlobals.OGCAC}/boot/{oglivedir}'
#control de errores
if not os.path.isdir (ogbtftp):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, ogbtftp)
os.exit (1)
if not CacheLib.ogMountCache():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTCACHE, 'CACHE')
os.exit (1)
os.makedirs (ogbcache, exist_ok=True)
# comparamos los del server
with open (f'{ogbtftp}/ogvmlinuz.sum', 'rb') as fd: servervmlinuz = fd.read()
with open (f'{ogbtftp}/oginitrd.img.sum', 'rb') as fd: serverinitrd = fd.read()
#comparamos los de la cache
with open (f'{ogbcache}/ogvmlinuz.sum', 'rb') as fd: cachevmlinuz = fd.read()
with open (f'{ogbcache}/oginitrd.img.sum', 'rb') as fd: cacheinitrd = fd.read()
print (f'MD5 on SERVER: {servervmlinuz} {serverinitrd}')
print (f'MD5 on CACHE: {cachevmlinuz} {cacheinitrd}')
do_reboot = '0'
if cachevmlinuz != servervmlinuz:
print ('ogvmlinuz updating')
shutil.copy2 (f'{ogbtftp}/ogvmlinuz', f'{ogbcache}/ogvmlinuz')
shutil.copy2 (f'{ogbtftp}/ogvmlinuz.sum', f'{ogbcache}/ogvmlinuz.sum')
do_reboot = '1'
if cacheinitrd != serverinitrd:
print ('oginitrd updating')
shutil.copy2 (f'{ogbtftp}/oginitrd.img', f'{ogbcache}/oginitrd.img')
shutil.copy2 (f'{ogbtftp}/oginitrd.img.sum', f'{ogbcache}/oginitrd.img.sum')
do_reboot = '1'
print (do_reboot)
os.exit (0)