From 10745c1ca1d50ef456f57ab9489f08dc59b51924 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Fri, 28 Feb 2025 13:30:59 +0100 Subject: [PATCH 01/30] refs #1629 add ogGrubOgliveDefaultEntry --- .../functions/ogBootLoaderOgliveDefaultEntry | 24 +++ ogclient/functions/ogGrubOgliveDefaultEntry | 23 +++ ogclient/lib/python3/BootLib.py | 155 ++++++------------ ogclient/lib/python3/SystemLib.py | 10 +- 4 files changed, 99 insertions(+), 113 deletions(-) create mode 100755 ogclient/functions/ogBootLoaderOgliveDefaultEntry create mode 100755 ogclient/functions/ogGrubOgliveDefaultEntry diff --git a/ogclient/functions/ogBootLoaderOgliveDefaultEntry b/ogclient/functions/ogBootLoaderOgliveDefaultEntry new file mode 100755 index 0000000..17866ae --- /dev/null +++ b/ogclient/functions/ogBootLoaderOgliveDefaultEntry @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +import ogGlobals +from SystemLib import ogHelp +from BootLib import ogBootLoaderOgliveDefaultEntry + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogBootLoaderOgliveDefaultEntry', ogGlobals.lang.MSG_SEE+' ogGrubOgliveDefaultEntry', []) + sys.exit (0) + +args = parser.parse_args() +ret = ogBootLoaderOgliveDefaultEntry (args.disk, args.par) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/functions/ogGrubOgliveDefaultEntry b/ogclient/functions/ogGrubOgliveDefaultEntry new file mode 100755 index 0000000..bd4c6b7 --- /dev/null +++ b/ogclient/functions/ogGrubOgliveDefaultEntry @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogGrubOgliveDefaultEntry + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGrubOgliveDefaultEntry', 'ogGrubOgliveDefaultEntry int_ndiskSecondStage int_partitionSecondStage', ['ogGrubOgliveDefaultEntry 1 6']) + sys.exit (0) + +args = parser.parse_args() +ret = ogGrubOgliveDefaultEntry (args.disk, args.par) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index bf6f0b9..1a8577a 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -12,6 +12,7 @@ import tempfile import subprocess import shutil import glob +import inspect import ogGlobals import SystemLib @@ -713,12 +714,6 @@ def ogCleanLinuxDevices (disk, par): #@see ogBootLoaderHidePartitions #*/ ## -#/** -# ogBurgHidePartitions num_disk num_part -#@brief ver ogBootLoaderHidePartitions -#@see ogBootLoaderHidePartitions -#*/ ## - #/** # ogBootLoaderHidePartitions num_disk num_part #@brief Configura el grub/burg para que oculte las particiones de windows que no se esten iniciando. @@ -737,18 +732,6 @@ def ogCleanLinuxDevices (disk, par): #@see ogBootLoaderDeleteEntry #*/ -#/** -# ogBurgDeleteEntry num_disk num_part num_disk_delete num_part_delete -#@brief ver ogBootLoaderDeleteEntry -#@see ogBootLoaderDeleteEntry -#*/ - -#/** -# ogRefindDeleteEntry num_disk_delete num_part_delete -#@brief ver ogBootLoaderDeleteEntry -#@see ogBootLoaderDeleteEntry -#*/ - #/** # ogBootLoaderDeleteEntry num_disk num_part num_part_delete #@brief Borra en el grub las entradas para el inicio en una particion. @@ -756,44 +739,19 @@ def ogCleanLinuxDevices (disk, par): #@param 2 Numero de particion donde esta el grub #@param 3 Numero del disco del que borramos las entradas #@param 4 Numero de la particion de la que borramos las entradas -#@note Tiene que ser llamada desde ogGrubDeleteEntry, ogBurgDeleteEntry o ogRefindDeleteEntry +#@note Tiene que ser llamada desde ogGrubDeleteEntry #@return (nada) -#@exception OG_ERR_FORMAT Use ogGrubDeleteEntry or ogBurgDeleteEntry. +#@exception OG_ERR_FORMAT Use ogGrubDeleteEntry #@exception OG_ERR_FORMAT Formato incorrecto. #@exception OG_ERR_NOTFOUND No existe archivo de configuracion del grub. #*/ ## -#/** -# ogBurgInstallMbr int_disk_GRUBCFG int_partition_GRUBCFG -#@param bolean_Check_Os_installed_and_Configure_2ndStage true | false[default] -#@brief Instala y actualiza el gestor grub en el MBR del disco duro donde se encuentra el fichero grub.cfg. Admite sistemas Windows. -#@param int_disk_SecondStage -#@param int_part_SecondStage -#@param bolean_Check_Os_installed_and_Configure_2ndStage true | false[default] -#@return -#@exception OG_ERR_FORMAT Formato incorrecto. -#@exception OG_ERR_PARTITION Partición no soportada -#*/ ## - #/** # ogGrubDefaultEntry int_disk_GRUGCFG int_partition_GRUBCFG int_disk_default_entry int_npartition_default_entry #@brief ver ogBootLoaderDefaultEntry #@see ogBootLoaderDefaultEntry #*/ ## -#/** -# ogBurgDefaultEntry int_disk_BURGCFG int_partition_BURGCFG int_disk_default_entry int_npartition_default_entry -#@brief ver ogBootLoaderDefaultEntry -#@see ogBootLoaderDefaultEntry -#*/ ## - - -#/** -# ogRefindDefaultEntry int_disk_default_entry int_npartition_default_entry -#@brief ver ogBootLoaderDefaultEntry -#@see ogBootLoaderDefaultEntry -#*/ ## - #/** # ogBootLoaderDefaultEntry int_disk_CFG int_partition_CFG int_disk_default_entry int_npartition_default_entry #@brief Configura la entrada por defecto de Burg @@ -813,19 +771,8 @@ def ogCleanLinuxDevices (disk, par): #@brief ver ogBootLoaderOgliveDefaultEntry #@see ogBootLoaderOgliveDefaultEntry #*/ ## - -#/** -# ogBurgOgliveDefaultEntry num_disk num_part -#@brief ver ogBootLoaderOgliveDefaultEntry -#@see ogBootLoaderOgliveDefaultEntry -#*/ ## - - -#/** -# ogRefindOgliveDefaultEntry -#@brief ver ogBootLoaderOgliveDefaultEntry -#@see ogBootLoaderOgliveDefaultEntry -#*/ ## +def ogGrubOgliveDefaultEntry (disk, par): + return ogBootLoaderOgliveDefaultEntry (disk, par) #/** @@ -839,6 +786,48 @@ def ogCleanLinuxDevices (disk, par): #@exception OG_ERR_NOTFOUND Fichero de configuración no encontrado: burg.cfg. #@exception OG_ERR_NOTFOUND Entrada de OgLive no encontrada en burg.cfg. #*/ ## +def ogBootLoaderOgliveDefaultEntry (disk, par): + func = inspect.stack()[1][3] + print (f'nati func ({func})') + + PART = FileSystemLib.ogMount (disk, par) + if not PART: return None + + if 'ogGrubOgliveDefaultEntry' == func: + cfgfile = f'{PART}/boot/grubMBR/boot/grub/grub.cfg' + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Use ogGrubOgliveDefaultEntry') + return None + + print (f'nati cfgfile ({cfgfile})') + if not os.path.exists (cfgfile): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, cfgfile) + return None + + numentry = 0 + with open (cfgfile, 'r') as fd: + while True: + l = fd.readline() + if not l: break + if l.startswith ('menuentry'): + numentry += 1 + if 'OpenGnsys Live' in l: break + + print (f'nati numentry ({numentry})') + if not numentry: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'menuentry OpenGnsys Live in {cfgfile}') + return None + + numentry -= 1 + subprocess.run (['sed', '--regexp-extended', '-i', f's/"set default=\"?[0-9]+\"?"/"set default=\"{numentry}\""/g', cfgfile]) + + MSG = f'ogGlobals.lang.MSG_HELP_{func}' + try: MSG = eval (MSG) + except: MSG = '' + if '.' == MSG[-1]: MSG=MSG[0:-1] + + print (f'{MSG}: {disk} {par}') + return True #/** @@ -861,19 +850,6 @@ def ogCleanLinuxDevices (disk, par): #@see ogBootLoaderSetTheme #*/ ## -#/** -# ogBurgSetTheme num_disk num_part str_theme -#@brief ver ogBootLoaderSetTheme -#@see ogBootLoaderSetTheme -#*/ ## - - -#/** -# ogRefindSetTheme str_theme -#@brief ver ogBootLoaderSetTheme -#@see ogBootLoaderSetTheme -#*/ ## - #/** # ogBootLoaderSetTheme @@ -896,12 +872,6 @@ def ogCleanLinuxDevices (disk, par): #@see ogBootLoaderSetTheme #*/ ## -#/** -# ogBurgSetAdminKeys num_disk num_part str_bolean -#@brief ver ogBootLoaderSetAdminKeys -#@see ogBootLoaderSetAdminKeys -#*/ ## - #/** @@ -925,19 +895,6 @@ def ogCleanLinuxDevices (disk, par): #@see ogBootLoaderSetTimeOut #*/ ## -#/** -# ogBurgSetTimeOut num_disk num_part str_bolean -#@brief ver ogBootLoaderSetTimeOut -#@see ogBootLoaderSetTimeOut -#*/ ## - - -#/** -# ogRefindSetTimeOut int_timeout_second -#@brief ver ogBootLoaderSetTimeOut -#@see ogBootLoaderSetTimeOut -#*/ ## - #/** # ogBootLoaderSetTimeOut #@brief Define el tiempo (segundos) que se muestran las opciones de inicio @@ -958,12 +915,6 @@ def ogCleanLinuxDevices (disk, par): #@see ogBootLoaderSetResolution #*/ ## -#/** -# ogBurgSetResolution num_disk num_part str_bolean -#@brief ver ogBootLoaderSetResolution -#@see ogBootLoaderSetResolution -#*/ ## - #/** @@ -992,18 +943,6 @@ def ogCleanLinuxDevices (disk, par): #@exception OG_ERR_NOTFOUND Fichero de configuración no encontrado: grub.cfg burg.cfg. #*/ ## -# ogRefindInstall bool_autoconfig -#@brief Instala y actualiza el gestor rEFInd en la particion EFI -#@param bolean_Check__auto_config true | false[default] -#@return -#@exception OG_ERR_FORMAT Formato incorrecto. -#@exception OG_ERR_NOTFOUND No se encuentra la partición ESP. -#@exception OG_ERR_NOTFOUND No se encuentra shimx64.efi.signed. -#@exception OG_ERR_NOTFOUND No se encuentra refind-install o refind en OGLIB -#@exception OG_ERR_PARTITION No se puede montar la partición ESP. -#@note Refind debe estar instalado en el ogLive o compartido en OGLIB -#*/ ## - #/** # ogGrub4dosInstallMbr int_ndisk #@brief Genera un nuevo Codigo de arranque en el MBR del disco indicado, compatible con los SO tipo Windows, Linux. diff --git a/ogclient/lib/python3/SystemLib.py b/ogclient/lib/python3/SystemLib.py index fffd2cb..86491a3 100644 --- a/ogclient/lib/python3/SystemLib.py +++ b/ogclient/lib/python3/SystemLib.py @@ -66,11 +66,11 @@ def ogEcho (logtypes, loglevel, msg): #@return Salida de ejecución del comando. #@note str_logfile = { LOG, SESSION, COMMAND } #*/ -#ogHelp (str_logfile ... str_command ...", -#ogHelp ([], ogMyLib.ogSomeMethod, *args, **kwargs) -#ogHelp ('command', ogMyLib.ogSomeMethod, *args, **kwargs) -#ogHelp (['command'], ogMyLib.ogSomeMethod, *args, **kwargs) -#ogHelp (['log', 'command'], ogMyLib.ogSomeMethod, *args, **kwargs) +#ogExecAndLog (str_logfile ... str_command ...", +#ogExecAndLog ([], ogMyLib.ogSomeMethod, *args, **kwargs) +#ogExecAndLog ('command', ogMyLib.ogSomeMethod, *args, **kwargs) +#ogExecAndLog (['command'], ogMyLib.ogSomeMethod, *args, **kwargs) +#ogExecAndLog (['log', 'command'], ogMyLib.ogSomeMethod, *args, **kwargs) def ogExecAndLog (logtypes, fun, *args, **kwargs): logfiles = ['/dev/stdout'] if type (logtypes) is list: From 3639dc1931fa616307d1bdbb04bd87b1e5e5c40d Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Mon, 3 Mar 2025 14:24:19 +0100 Subject: [PATCH 02/30] refs #1630 add ogGrubHidePartitions, fix bugs --- ogclient/functions/ogBootLoaderHidePartitions | 33 ++++++++ ogclient/functions/ogGrubHidePartitions | 33 ++++++++ ogclient/lib/python3/BootLib.py | 81 ++++++++++++++++++- ogclient/lib/python3/CacheLib.py | 6 +- ogclient/lib/python3/FileSystemLib.py | 1 - ogclient/lib/python3/SystemLib.py | 1 - ogclient/scripts/updateBootCache.py | 22 +++-- 7 files changed, 161 insertions(+), 16 deletions(-) create mode 100755 ogclient/functions/ogBootLoaderHidePartitions create mode 100755 ogclient/functions/ogGrubHidePartitions diff --git a/ogclient/functions/ogBootLoaderHidePartitions b/ogclient/functions/ogBootLoaderHidePartitions new file mode 100755 index 0000000..57a4fda --- /dev/null +++ b/ogclient/functions/ogBootLoaderHidePartitions @@ -0,0 +1,33 @@ +#!/usr/bin/python3 + +import sys +import argparse +import ogGlobals +from SystemLib import ogHelp +from BootLib import ogBootLoaderHidePartitions + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogBootLoaderHidePartitions', ogGlobals.lang.MSG_SEE+' ogGrubHidePartitions', []) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 3 == len (sys.argv): + parser.add_argument ('disk') + parser.add_argument ('par') +elif 5 == len (sys.argv): + parser.add_argument ('disk') + parser.add_argument ('par') + parser.add_argument ('datadisk') + parser.add_argument ('datapar') + +args = parser.parse_args() +if 3 == len (sys.argv): + ret = ogBootLoaderHidePartitions (args.disk, args.par) +elif 5 == len (sys.argv): + ret = ogBootLoaderHidePartitions (args.disk, args.par, args.datadisk, args.datapar) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/functions/ogGrubHidePartitions b/ogclient/functions/ogGrubHidePartitions new file mode 100755 index 0000000..6fa7202 --- /dev/null +++ b/ogclient/functions/ogGrubHidePartitions @@ -0,0 +1,33 @@ +#!/usr/bin/python3 + +import sys +import argparse +import ogGlobals +from SystemLib import ogHelp +from BootLib import ogGrubHidePartitions + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGrubHidePartitions', 'ogGrubHidePartitions int_ndisk int_npartition [ num_disk_partdata num_partdata ]', ['ogGrubHidePartitions 1 2', 'ogGrubHidePartitions 1 2 1 3']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 3 == len (sys.argv): + parser.add_argument ('disk') + parser.add_argument ('par') +elif 5 == len (sys.argv): + parser.add_argument ('disk') + parser.add_argument ('par') + parser.add_argument ('datadisk') + parser.add_argument ('datapar') + +args = parser.parse_args() +if 3 == len (sys.argv): + ret = ogGrubHidePartitions (args.disk, args.par) +elif 5 == len (sys.argv): + ret = ogGrubHidePartitions (args.disk, args.par, args.datadisk, args.datapar) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index 1a8577a..9f2e7f0 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -440,7 +440,7 @@ def ogGrubInstallMbr (disk, par, checkos='FALSE', kernelparam=''): 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 ([f'{ogGlobals.OGSCRIPTS}/updateBootCache.py'], check=True) ## TODO: check that this works + subprocess.run ([f'{ogGlobals.OGSCRIPTS}/updateBootCache.py'], check=True) if InventoryLib.ogIsEfiActive(): # UEFI: grubSintax necesita grub.cfg para detectar los kernels: si no existe recupero backup. @@ -713,6 +713,8 @@ def ogCleanLinuxDevices (disk, par): #@brief ver ogBootLoaderHidePartitions #@see ogBootLoaderHidePartitions #*/ ## +def ogGrubHidePartitions (disk, par, datadisk=None, datapar=None): + return ogBootLoaderHidePartitions (disk, par, datadisk, datapar) #/** # ogBootLoaderHidePartitions num_disk num_part @@ -726,6 +728,82 @@ def ogCleanLinuxDevices (disk, par): #@exception No existe archivo de configuracion del grub/burg. #*/ +def ogBootLoaderHidePartitions (disk, par, datadisk=None, datapar=None): + # Nombre de la función que llama a esta. + func = inspect.stack()[1][3] + + # Si no existe $4 pongo un valor imposible para la partición de datos + if datapar: + partdata = DiskLib.ogDiskToDev (datadisk, datapar) + else: + partdata = '0' + + # Archivo de configuracion del grub + DIRMOUNT = FileSystemLib.ogMount (disk, par) + # La función debe ser llamanda desde ogGrubHidePartitions or ogBurgHidePartitions. + if 'ogGrubHidePartitions' == func: + cfgfile = f'{DIRMOUNT}/boot/grubMBR/boot/grub/grub.cfg' + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Use ogGrubHidePartitions') + return None + + # Error si no existe archivo del grub + if not os.path.exists (cfgfile): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, cfgfile) + return None + + # Si solo hay una particion de Windows me salgo + num_ntfs = 0 + disks = DiskLib.ogDiskToDev() + fdisk_out = subprocess.run (['fdisk', '-l']+disks, capture_output=True, text=True).stdout + for l in fdisk_out.splitlines(): + if 'NTFS' in l: num_ntfs += 1 + if 1 == num_ntfs: return True + + # Elimino llamadas a parttool, se han incluido en otras ejecuciones de esta funcion. + subprocess.run (['sed', '-i', '/parttool/d', cfgfile]) + + parttabletype = DiskLib.ogGetPartitionTableType (disk) + parttabletype = parttabletype.lower() + + # Entradas de Windows: numero de linea y particion. De mayor a menor. + #1:/dev/sda2 + #2:/dev/sda3 + awk_out = subprocess.run (f''' + awk '/menuentry.*Windows/ {{gsub(/\\)"/, ""); gsub(/^.*dev/,""); print NR":/dev"$1}} ' {cfgfile} + ''', shell=True, text=True).stdout + if awk_out: + winentry = awk_out.splitlines() + winentry.reverse() + else: + winentry = [] + + # Particiones de Windows, pueden no estar en el grub. + winpart = [] + for l in fdisk_out.splitlines(): ## aprovechamos la variable fdisk_out de antes + if 'NTFS' not in l: continue + items = l.split (' ') + winpart.append (items[0]) + winpart.reverse() + + # Modifico todas las entradas de Windows. + for entry in winentry: + line, part = entry.split (':') + # En cada entrada, oculto o muestro cada particion. + TEXT = '' + for parthidden in winpart: + # Muestro la particion de la entrada actual y la de datos. + if parthidden == part or parthidden == partdata: + HIDDEN = '-' + else: + HIDDEN = '+' + numdisk, numpart = DiskLib.ogDevToDisk (parthidden).split() + numdisk = int (numdisk) + numpart = int (numpart) + TEXT = f'\tparttool (hd{numdisk-1},{parttabletype}{numpart}) hidden{hidden} \n{text}' + subprocess.run (['sed', '-i', f'{line}a\\ {text}', cfgfile]) + # Activamos la particion que se inicia en todas las entradas de windows. + subprocess.run (['sed', '-i', '/chainloader/i\\\tparttool ${root} boot+', cfgfile]) #/** # ogGrubDeleteEntry num_disk num_part num_disk_delete num_part_delete #@brief ver ogBootLoaderDeleteEntry @@ -788,7 +866,6 @@ def ogGrubOgliveDefaultEntry (disk, par): #*/ ## def ogBootLoaderOgliveDefaultEntry (disk, par): func = inspect.stack()[1][3] - print (f'nati func ({func})') PART = FileSystemLib.ogMount (disk, par) if not PART: return None diff --git a/ogclient/lib/python3/CacheLib.py b/ogclient/lib/python3/CacheLib.py index 1c4357c..bb4a3ce 100644 --- a/ogclient/lib/python3/CacheLib.py +++ b/ogclient/lib/python3/CacheLib.py @@ -9,7 +9,6 @@ import ogGlobals import SystemLib import DiskLib import FileSystemLib -import CacheLib #/** # ogCreateCache [int_ndisk] int_partsize @@ -240,8 +239,7 @@ def ogFormatCache(): os.makedirs (j, exist_ok=True) # Incluir kernel e Initrd del ogLive - ## como lo llamo sin especificar el path entero? - #subprocess.run (['scripts/updateBootCache.py']) ## TODO + subprocess.run ([f'{ogGlobals.OGSCRIPTS}/updateBootCache.py']) #/** @@ -365,5 +363,5 @@ def ogUnmountCache(): #@return lo mismo que devuelve initCache #*/ ## def initCache (*args): - p = subprocess.run (['/opt/opengnsys/images/nati/client/shared/scripts/initCache.py'] + list(args)) + p = subprocess.run ([f'{ogGlobals.OGSCRIPTS}/initCache.py'] + list(args)) return p.returncode diff --git a/ogclient/lib/python3/FileSystemLib.py b/ogclient/lib/python3/FileSystemLib.py index 15139f3..1d8e954 100644 --- a/ogclient/lib/python3/FileSystemLib.py +++ b/ogclient/lib/python3/FileSystemLib.py @@ -14,7 +14,6 @@ import ogGlobals import SystemLib import DiskLib import CacheLib -import FileSystemLib #/** diff --git a/ogclient/lib/python3/SystemLib.py b/ogclient/lib/python3/SystemLib.py index 86491a3..dca5232 100644 --- a/ogclient/lib/python3/SystemLib.py +++ b/ogclient/lib/python3/SystemLib.py @@ -13,7 +13,6 @@ from contextlib import redirect_stdout, redirect_stderr import ogGlobals import StringLib -import SystemLib #NODEBUGFUNCTIONS, OGIMG, OG_ERR_CACHESIZE, OG_ERR_NOTCACHE, OG_ERR_NOTWRITE, OG_ERR_FILESYS #OG_ERR_REPO, OG_ERR_NOTOS, OG_ERR_NOGPT, OG_ERR_OUTOFLIMIT, OG_ERR_IMAGE, OG_ERR_CACHE diff --git a/ogclient/scripts/updateBootCache.py b/ogclient/scripts/updateBootCache.py index 854b9c9..e698b90 100755 --- a/ogclient/scripts/updateBootCache.py +++ b/ogclient/scripts/updateBootCache.py @@ -1,6 +1,7 @@ #!/usr/bin/python3 import os +import sys import shutil import ogGlobals @@ -34,29 +35,34 @@ if not CacheLib.ogMountCache(): os.makedirs (ogbcache, exist_ok=True) +servervmlinuz = serverinitrd = cachevmlinuz = cacheinitrd = '' # 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() +if os.path.exists (f'{ogbtftp}/ogvmlinuz.sum'): + with open (f'{ogbtftp}/ogvmlinuz.sum', 'r') as fd: servervmlinuz = fd.read().strip() +if os.path.exists (f'{ogbtftp}/oginitrd.img.sum'): + with open (f'{ogbtftp}/oginitrd.img.sum', 'r') as fd: serverinitrd = fd.read().strip() #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() +if os.path.exists (f'{ogbcache}/ogvmlinuz.sum'): + with open (f'{ogbcache}/ogvmlinuz.sum', 'r') as fd: cachevmlinuz = fd.read().strip() +if os.path.exists (f'{ogbcache}/oginitrd.img.sum'): + with open (f'{ogbcache}/oginitrd.img.sum', 'r') as fd: cacheinitrd = fd.read().strip() print (f'MD5 on SERVER: {servervmlinuz} {serverinitrd}') print (f'MD5 on CACHE: {cachevmlinuz} {cacheinitrd}') -do_reboot = '0' +do_reboot = '' 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' + do_reboot = 'true' 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' + do_reboot = 'true' print (do_reboot) -os.exit (0) +sys.exit (0) From c4f786d1709afa066e3d393dcbc4bd6343bb032d Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Tue, 4 Mar 2025 12:55:05 +0100 Subject: [PATCH 03/30] refs #1623 add ogGrubAddOgLive, fix a bug --- ogclient/functions/ogGrubAddOgLive | 25 ++++++++++ ogclient/lib/python3/BootLib.py | 79 +++++++++++++++++++++++++++++- 2 files changed, 103 insertions(+), 1 deletion(-) create mode 100755 ogclient/functions/ogGrubAddOgLive diff --git a/ogclient/functions/ogGrubAddOgLive b/ogclient/functions/ogGrubAddOgLive new file mode 100755 index 0000000..7b50aa7 --- /dev/null +++ b/ogclient/functions/ogGrubAddOgLive @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogGrubAddOgLive + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('timeout', nargs='?') +parser.add_argument ('offline', nargs='?') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGrubAddOgLive', 'ogGrubAddOgLive int_ndisk int_npartition [ time_out ] [ offline|online ]', ['ogGrubAddOgLive 1 1', 'ogGrubAddOgLive 1 6 15 offline']) + sys.exit (0) + +args = parser.parse_args() +ret = ogGrubAddOgLive (args.disk, args.par, args.timeout, args.offline) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index 9f2e7f0..03277cc 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -22,6 +22,7 @@ import DiskLib import InventoryLib import FileLib import UEFILib +import CacheLib #/** # ogBoot int_ndisk int_nfilesys [ NVRAMPERM ] [str_kernel str_initrd str_krnlparams] @@ -454,7 +455,7 @@ def ogGrubInstallMbr (disk, par, checkos='FALSE', kernelparam=''): 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 + os.makedirs (f'{secondstage}{prefixsecondstage}/boot/grub/', exist_ok=True) #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', r'/grub-mkconfig_lib/i\pkgdatadir=${pkgdatadir:-"${datarootdir}/grub"}', '/etc/grub.d/00_header']) @@ -708,6 +709,82 @@ def ogCleanLinuxDevices (disk, par): # /// FIXME: Solo para el grub instalado en MBR por Opengnsys, ampliar para más casos. #*/ ## + +def ogGrubAddOgLive (disk, par, timeout=None, offline=''): + oglivedir = os.environ.get ('oglivedir', 'ogLive') + # Error si no existe el kernel y el initrd en la cache. + # Falta crear nuevo codigo de error. + if not os.path.exists (f'{ogGlobals.OGCAC}/boot/{oglivedir}/ogvmlinuz') or not os.path.exists (f'{ogGlobals.OGCAC}/boot/{oglivedir}/oginitrd.img'): + SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_NOTFOUND, 'CACHE: ogvmlinuz, oginitrd.img') + return None + + # Archivo de configuracion del grub + dirmount = FileSystemLib.ogMount (disk, par) + grubcfg = f'{dirmount}/boot/grubMBR/boot/grub/grub.cfg' + + # Error si no existe archivo del grub + if not os.path.exists (grubcfg): + SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_NOTFOUND, grubcfg) + return None + + # Si existe la entrada de opengnsys, se borra + grubcfg_contents = '' + with open (grubcfg, 'r') as fd: + grubcfg_contents = fd.read() + if 'menuentry Opengnsys' in grubcfg_contents: + subprocess.run (['sed', '-ie', '/menuentry Opengnsys/,+6d', grubcfg]) + + # Tipo de tabla de particiones + parttabletype = DiskLib.ogGetPartitionTableType (disk) + parttabletype = parttabletype.lower() + + # Localizacion de la cache + cachepart = CacheLib.ogFindCache() + if not cachepart: + SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_NOTCACHE, '') + return None + numdisk, numpart = cachepart.split() + numdisk = int (numdisk) - 1 + # kernel y sus opciones. Pasamos a modo usuario + proc_cmdline = '' + with open ('/proc/cmdline', 'r') as fd: + proc_cmdline = fd.read().strip() + proc_cmdline = re.sub ('^.*linuz', '', proc_cmdline) + proc_cmdline = re.sub ('ogactiveadmin=[a-z]*', '', proc_cmdline) + kernel = f'/boot/{oglivedir}/ogvmlinuz {proc_cmdline}' + + # Configuracion offline si existe parametro + STATUS = '' + if not offline: offline = '' + if 'offline' in offline: STATUS = 'offline' + if 'online' in offline: STATUS = 'online' + if STATUS: + kernel = re.sub ('ogprotocol=[a-z]* ', 'ogprotocol=local ', kernel) + kernel += f' ogstatus={STATUS}' + + # Numero de línea de la primera entrada del grub. + grep_out = subprocess.run (['grep', '--line-number', '--max-count', '1', '^menuentry', grubcfg], capture_output=True, text=True).stdout + numline, _ = grep_out.split (':', maxsplit=1) + # Texto de la entrada de opengnsys + menuentry = f'''menuentry "OpenGnsys" --class opengnsys --class gnu --class os {{ \\ +\tinsmod part_{parttabletype} \\ +\tinsmod ext2 \\ +\tset root='(hd{numdisk},{parttabletype}{numpart})' \\ +\tlinux {kernel} \\ +\tinitrd /boot/{oglivedir}/oginitrd.img \\ +}}''' + + + # Insertamos la entrada de opengnsys antes de la primera entrada existente. + subprocess.run (['sed', '-i', f'{numline}i\\ {menuentry}', grubcfg]) + + # Ponemos que la entrada por defecto sea la primera. + subprocess.run (['sed', '-i', f's/set.*default.*$/set default="0"/g', grubcfg]) + + # Si me dan valor para timeout lo cambio en el grub. + if timeout: + subprocess.run (['sed', '-i', f's/timeout=.*$/timeout={timeout}/g', grubcfg]) + #/** # ogGrubHidePartitions num_disk num_part #@brief ver ogBootLoaderHidePartitions From cd81c16afbdeeb7dba8748f1e696f84457575aa7 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Wed, 5 Mar 2025 10:43:12 +0100 Subject: [PATCH 04/30] refs #1631 add ogGrubDeleteEntry, fix a bug --- ogclient/functions/ogBootLoaderDeleteEntry | 26 ++++++++++ ogclient/functions/ogGrubDeleteEntry | 25 ++++++++++ ogclient/lib/python3/BootLib.py | 57 +++++++++++++++++++++- 3 files changed, 107 insertions(+), 1 deletion(-) create mode 100755 ogclient/functions/ogBootLoaderDeleteEntry create mode 100755 ogclient/functions/ogGrubDeleteEntry diff --git a/ogclient/functions/ogBootLoaderDeleteEntry b/ogclient/functions/ogBootLoaderDeleteEntry new file mode 100755 index 0000000..1d1c21d --- /dev/null +++ b/ogclient/functions/ogBootLoaderDeleteEntry @@ -0,0 +1,26 @@ +#!/usr/bin/python3 + +import sys +import argparse +import ogGlobals +from SystemLib import ogHelp +from BootLib import ogBootLoaderDeleteEntry + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('diskdel') +parser.add_argument ('pardel') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogBootLoaderDeleteEntry', ogGlobals.lang.MSG_SEE+' ogGrubDeleteEntry', []) + sys.exit (0) + +args = parser.parse_args() +ret = ogBootLoaderDeleteEntry (args.disk, args.par, args.diskdel, args.pardel) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/functions/ogGrubDeleteEntry b/ogclient/functions/ogGrubDeleteEntry new file mode 100755 index 0000000..d10f764 --- /dev/null +++ b/ogclient/functions/ogGrubDeleteEntry @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogGrubDeleteEntry + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('diskdel') +parser.add_argument ('pardel') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGrubDeleteEntry', 'ogGrubDeleteEntry int_ndisk int_npartition int_disk_delete int_npartition_delete', ['ogGrubDeleteEntry 1 6 2 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogGrubDeleteEntry (args.disk, args.par, args.diskdel, args.pardel) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index 03277cc..32955f1 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -886,6 +886,8 @@ def ogBootLoaderHidePartitions (disk, par, datadisk=None, datapar=None): #@brief ver ogBootLoaderDeleteEntry #@see ogBootLoaderDeleteEntry #*/ +def ogGrubDeleteEntry (disk, par, diskdel, pardel): + return ogBootLoaderDeleteEntry (disk, par, diskdel, pardel) #/** # ogBootLoaderDeleteEntry num_disk num_part num_part_delete @@ -901,6 +903,59 @@ def ogBootLoaderHidePartitions (disk, par, datadisk=None, datapar=None): #@exception OG_ERR_NOTFOUND No existe archivo de configuracion del grub. #*/ ## +def ogBootLoaderDeleteEntry (disk, par, diskdel, pardel): + # Nombre de la función que llama a esta. + func = inspect.stack()[1][3] + + # Archivo de configuracion del grub + dirmount = FileSystemLib.ogMount (disk, par) + # La función debe ser llamanda desde ogGrubDeleteEntry, ogBurgDeleteEntry or ogRefindDeleteEntry. + if 'ogGrubDeleteEntry' == func: + cfgfile = f'{dirmount}/boot/grubMBR/boot/grub/grub.cfg' + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Use ogGrubDeleteEntry') + return None + + # Dispositivo + label = DiskLib.ogDiskToDev (diskdel, pardel) + + # Error si no existe archivo de configuración + if not os.path.exists (cfgfile): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, cfgfile) + return None + + # Numero de linea de cada entrada. + menuentry = [] + grep_out = subprocess.run (['grep', '-n', '-e', 'menuentry', cfgfile], capture_output=True, text=True).stdout + if grep_out: + for l in grep_out.splitlines(): + lineno, _ = l.split (':', maxsplit=1) + menuentry.append (lineno) + menuentry.reverse() + + # Entradas que hay que borrar. + deleteentry = [] + grep_out = subprocess.run (['grep', '-n', f'menuentry.*{label}', cfgfile], capture_output=True, text=True).stdout + if grep_out: + for l in grep_out.splitlines(): + lineno, _ = l.split (':', maxsplit=1) + deleteentry.append (lineno) + + # Si no hay entradas para borrar me salgo con aviso + if not deleteentry: + SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_NOTFOUND, f'Menuentry {label}') + return None + + # Recorremos el fichero del final hacia el principio. + with open (cfgfile, 'r') as fd: + endentry = len (fd.read().splitlines()) + for entry in menuentry: + # Comprobamos si hay que borrar la entrada. + if entry in deleteentry: + endentry -= 1 + subprocess.run (['sed', '-i', '-e', f'{entry},{endentry}d', cfgfile]) + # Guardamos el número de línea de la entrada, que sera el final de la siguiente. + endentry = entry #/** # ogGrubDefaultEntry int_disk_GRUGCFG int_partition_GRUBCFG int_disk_default_entry int_npartition_default_entry #@brief ver ogBootLoaderDefaultEntry @@ -973,7 +1028,7 @@ def ogBootLoaderOgliveDefaultEntry (disk, par): return None numentry -= 1 - subprocess.run (['sed', '--regexp-extended', '-i', f's/"set default=\"?[0-9]+\"?"/"set default=\"{numentry}\""/g', cfgfile]) + subprocess.run (['sed', '--regexp-extended', '-i', f's/set default="?[0-9]+"?/set default="{numentry}"/g', cfgfile]) MSG = f'ogGlobals.lang.MSG_HELP_{func}' try: MSG = eval (MSG) From 4e1a188e5381c300f27f00b51d5d711f5d7ea096 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Wed, 5 Mar 2025 11:58:38 +0100 Subject: [PATCH 05/30] refs #1625 add ogGrubSetTimeOut --- ogclient/functions/ogBootLoaderSetTimeOut | 25 +++++++++++++++++ ogclient/functions/ogGrubSetTimeOut | 24 ++++++++++++++++ ogclient/lib/python3/BootLib.py | 34 +++++++++++++++++++++-- 3 files changed, 80 insertions(+), 3 deletions(-) create mode 100755 ogclient/functions/ogBootLoaderSetTimeOut create mode 100755 ogclient/functions/ogGrubSetTimeOut diff --git a/ogclient/functions/ogBootLoaderSetTimeOut b/ogclient/functions/ogBootLoaderSetTimeOut new file mode 100755 index 0000000..b2782e8 --- /dev/null +++ b/ogclient/functions/ogBootLoaderSetTimeOut @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +import sys +import argparse +import ogGlobals +from SystemLib import ogHelp +from BootLib import ogBootLoaderSetTimeOut + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('timeout') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogBootLoaderSetTimeOut', ogGlobals.lang.MSG_SEE+' ogGrubSetTimeOut', []) + sys.exit (0) + +args = parser.parse_args() +ret = ogBootLoaderSetTimeOut (args.disk, args.par, args.timeout) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/functions/ogGrubSetTimeOut b/ogclient/functions/ogGrubSetTimeOut new file mode 100755 index 0000000..73a3629 --- /dev/null +++ b/ogclient/functions/ogGrubSetTimeOut @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogGrubSetTimeOut + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('timeout') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGrubSetTimeOut', 'ogGrubSetTimeOut int_ndiskSecondStage int_partitionSecondStage int_timeout_seconds', ['ogGrubSetTimeOut 1 4 50']) + sys.exit (0) + +args = parser.parse_args() +ret = ogGrubSetTimeOut (args.disk, args.par, args.timeout) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index 32955f1..6f0a1ca 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -997,22 +997,25 @@ def ogGrubOgliveDefaultEntry (disk, par): #@exception OG_ERR_NOTFOUND Entrada de OgLive no encontrada en burg.cfg. #*/ ## def ogBootLoaderOgliveDefaultEntry (disk, par): +# Nombre de la función que llama a esta. func = inspect.stack()[1][3] +# Error si no puede montar sistema de archivos. PART = FileSystemLib.ogMount (disk, par) if not PART: return None - +# La función debe ser llamanda desde ogGrubOgliveDefaultEntry, ogBurgOgliveDefaultEntry or ogRefindOgliveDefaultEntry. if 'ogGrubOgliveDefaultEntry' == func: cfgfile = f'{PART}/boot/grubMBR/boot/grub/grub.cfg' else: SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Use ogGrubOgliveDefaultEntry') return None - print (f'nati cfgfile ({cfgfile})') +# Comprobamos que exista fichero de configuración if not os.path.exists (cfgfile): SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, cfgfile) return None +# Detectamos cual es la entrada de ogLive numentry = 0 with open (cfgfile, 'r') as fd: while True: @@ -1022,7 +1025,7 @@ def ogBootLoaderOgliveDefaultEntry (disk, par): numentry += 1 if 'OpenGnsys Live' in l: break - print (f'nati numentry ({numentry})') +# Si no existe entrada de ogLive nos salimos if not numentry: SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'menuentry OpenGnsys Live in {cfgfile}') return None @@ -1103,6 +1106,8 @@ def ogBootLoaderOgliveDefaultEntry (disk, par): #@brief ver ogBootLoaderSetTimeOut #@see ogBootLoaderSetTimeOut #*/ ## +def ogGrubSetTimeOut (disk, par, timeout): + return ogBootLoaderSetTimeOut (disk, par, timeout) #/** # ogBootLoaderSetTimeOut @@ -1116,6 +1121,29 @@ def ogBootLoaderOgliveDefaultEntry (disk, par): #@exception OG_ERR_NOTFOUND Fichero de configuración no encontrado: grub.cfg burg.cfg. #@exception OG_ERR_NOTFOUND Entrada deltema no encontrada en burg.cfg. #*/ ## +def ogBootLoaderSetTimeOut (disk, par, timeout): +# Nombre de la función que llama a esta. + func = inspect.stack()[1][3] + +# Error si no puede montar sistema de archivos. + PART = FileSystemLib.ogMount (disk, par) + if not PART: return None +# La función debe ser llamanda desde ogGrubSetTimeOut, ogBurgSetTimeOut or ogRefindSetTimeOut. + if 'ogGrubSetTimeOut' == func: + bootloader = 'grub' + bootloaderdir = 'boot/grubMBR' + cfgfile = f'{PART}/boot/grubMBR/boot/grub/grub.cfg' + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Use ogGrubSetTimeOut') + return None + +# Comprobamos que exista fichero de configuración + if not os.path.exists (cfgfile): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, cfgfile) + return None + +# Asignamos el timeOut. + subprocess.run (['sed', '-i', f's/timeout=.*$/timeout={timeout}/g', cfgfile]) #/** From 298ed3a80c9f81764d57c526a8a0d981d861b9e7 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Wed, 5 Mar 2025 13:22:19 +0100 Subject: [PATCH 06/30] refs #1626 add ogGrubSetTheme --- ogclient/functions/ogBootLoaderSetTheme | 25 +++++++++++++++++++++++++ ogclient/functions/ogGrubSetTheme | 24 ++++++++++++++++++++++++ ogclient/lib/python3/BootLib.py | 19 +++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100755 ogclient/functions/ogBootLoaderSetTheme create mode 100755 ogclient/functions/ogGrubSetTheme diff --git a/ogclient/functions/ogBootLoaderSetTheme b/ogclient/functions/ogBootLoaderSetTheme new file mode 100755 index 0000000..09df864 --- /dev/null +++ b/ogclient/functions/ogBootLoaderSetTheme @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +import sys +import argparse +import ogGlobals +from SystemLib import ogHelp +from BootLib import ogBootLoaderSetTheme + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('theme') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogBootLoaderSetTheme', ogGlobals.lang.MSG_SEE+' ogGrubSetTheme', []) + sys.exit (0) + +args = parser.parse_args() +ret = ogBootLoaderSetTheme (args.disk, args.par, args.theme) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/functions/ogGrubSetTheme b/ogclient/functions/ogGrubSetTheme new file mode 100755 index 0000000..86c0590 --- /dev/null +++ b/ogclient/functions/ogGrubSetTheme @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogGrubSetTheme + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('theme') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGrubSetTheme', 'ogGrubSetTheme int_ndiskSecondStage int_partitionSecondStage str_themeName', ['ogGrubSetTheme 1 4 ThemeBasic']) + sys.exit (0) + +args = parser.parse_args() +ret = ogGrubSetTheme (args.disk, args.par, args.theme) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index 6f0a1ca..9a9c5b8 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -1061,6 +1061,8 @@ def ogBootLoaderOgliveDefaultEntry (disk, par): #@brief ver ogBootLoaderSetTheme #@see ogBootLoaderSetTheme #*/ ## +def ogGrubSetTheme (disk, par, theme): + return ogBootLoaderSetTheme (disk, par, theme) #/** @@ -1077,6 +1079,23 @@ def ogBootLoaderOgliveDefaultEntry (disk, par): #@exception OG_ERR_NOTFOUND Fichero de configuración del tema no encontrado: theme.conf (sólo refind). #@note El tema debe situarse en OGLIB/BOOTLOADER/themes #*/ ## +def ogBootLoaderSetTheme (disk, par, theme): +# Nombre de la función que llama a esta. + func = inspect.stack()[1][3] + +# Error si no puede montar sistema de archivos. + PART = FileSystemLib.ogMount (disk, par) + if not PART: return None +# La función debe ser llamanda desde ogGrubSetTheme, ogBurgSetTheme or ogRefindSetTheme. + if 'ogGrubSetTheme' == func: + bootloader = 'grub' + bootloaderdir = 'boot/grubMBR' + cfgfile = f'{PART}/boot/grubMBR/boot/grub/grub.cfg' + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'ogGrubSetTheme not sopported') + return None + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Use ogGrubOgliveDefaultEntry') + return None #/** # ogGrubSetAdminKeys num_disk num_part str_theme From 5eb4c5d3948138acc9dcc79273124c1dd2e73df4 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Wed, 5 Mar 2025 13:29:33 +0100 Subject: [PATCH 07/30] Revert "refs #1626 add ogGrubSetTheme" This reverts commit 298ed3a80c9f81764d57c526a8a0d981d861b9e7. --- ogclient/functions/ogBootLoaderSetTheme | 25 ------------------------- ogclient/functions/ogGrubSetTheme | 24 ------------------------ ogclient/lib/python3/BootLib.py | 19 ------------------- 3 files changed, 68 deletions(-) delete mode 100755 ogclient/functions/ogBootLoaderSetTheme delete mode 100755 ogclient/functions/ogGrubSetTheme diff --git a/ogclient/functions/ogBootLoaderSetTheme b/ogclient/functions/ogBootLoaderSetTheme deleted file mode 100755 index 09df864..0000000 --- a/ogclient/functions/ogBootLoaderSetTheme +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/python3 - -import sys -import argparse -import ogGlobals -from SystemLib import ogHelp -from BootLib import ogBootLoaderSetTheme - -parser = argparse.ArgumentParser (add_help=False) -parser.add_argument ('disk') -parser.add_argument ('par') -parser.add_argument ('theme') - -if 2 == len (sys.argv) and 'help' == sys.argv[1]: - #parser.print_help() sale en inglés aunque la locale indique otra cosa - ogHelp ('ogBootLoaderSetTheme', ogGlobals.lang.MSG_SEE+' ogGrubSetTheme', []) - sys.exit (0) - -args = parser.parse_args() -ret = ogBootLoaderSetTheme (args.disk, args.par, args.theme) - -if ret is not None: - if ret == True: sys.exit (0) - elif ret == False: sys.exit (1) - else: print (ret) diff --git a/ogclient/functions/ogGrubSetTheme b/ogclient/functions/ogGrubSetTheme deleted file mode 100755 index 86c0590..0000000 --- a/ogclient/functions/ogGrubSetTheme +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/python3 - -import sys -import argparse -from SystemLib import ogHelp -from BootLib import ogGrubSetTheme - -parser = argparse.ArgumentParser (add_help=False) -parser.add_argument ('disk') -parser.add_argument ('par') -parser.add_argument ('theme') - -if 2 == len (sys.argv) and 'help' == sys.argv[1]: - #parser.print_help() sale en inglés aunque la locale indique otra cosa - ogHelp ('ogGrubSetTheme', 'ogGrubSetTheme int_ndiskSecondStage int_partitionSecondStage str_themeName', ['ogGrubSetTheme 1 4 ThemeBasic']) - sys.exit (0) - -args = parser.parse_args() -ret = ogGrubSetTheme (args.disk, args.par, args.theme) - -if ret is not None: - if ret == True: sys.exit (0) - elif ret == False: sys.exit (1) - else: print (ret) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index 9a9c5b8..6f0a1ca 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -1061,8 +1061,6 @@ def ogBootLoaderOgliveDefaultEntry (disk, par): #@brief ver ogBootLoaderSetTheme #@see ogBootLoaderSetTheme #*/ ## -def ogGrubSetTheme (disk, par, theme): - return ogBootLoaderSetTheme (disk, par, theme) #/** @@ -1079,23 +1077,6 @@ def ogGrubSetTheme (disk, par, theme): #@exception OG_ERR_NOTFOUND Fichero de configuración del tema no encontrado: theme.conf (sólo refind). #@note El tema debe situarse en OGLIB/BOOTLOADER/themes #*/ ## -def ogBootLoaderSetTheme (disk, par, theme): -# Nombre de la función que llama a esta. - func = inspect.stack()[1][3] - -# Error si no puede montar sistema de archivos. - PART = FileSystemLib.ogMount (disk, par) - if not PART: return None -# La función debe ser llamanda desde ogGrubSetTheme, ogBurgSetTheme or ogRefindSetTheme. - if 'ogGrubSetTheme' == func: - bootloader = 'grub' - bootloaderdir = 'boot/grubMBR' - cfgfile = f'{PART}/boot/grubMBR/boot/grub/grub.cfg' - SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'ogGrubSetTheme not sopported') - return None - else: - SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Use ogGrubOgliveDefaultEntry') - return None #/** # ogGrubSetAdminKeys num_disk num_part str_theme From 0022537bb37c7c4d85d2da1a29091f4de727a9e5 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Wed, 5 Mar 2025 14:21:08 +0100 Subject: [PATCH 08/30] refs #1624 add ogGrubSecurity --- ogclient/functions/ogGrubSecurity | 25 ++++++++++++++++++++ ogclient/lib/python3/BootLib.py | 39 +++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100755 ogclient/functions/ogGrubSecurity diff --git a/ogclient/functions/ogGrubSecurity b/ogclient/functions/ogGrubSecurity new file mode 100755 index 0000000..7895ea9 --- /dev/null +++ b/ogclient/functions/ogGrubSecurity @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogGrubSecurity + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('user', nargs='?', default='root') +parser.add_argument ('passwd', nargs='?', default='') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGrubSecurity', 'ogGrubSecurity int_ndiskSecondStage int_partitionSecondStage [USER] [PASSWORD]', ['ogGrubSecurity 1 1', 'ogGrubSecurity 1 2 user clave']) + sys.exit (0) + +args = parser.parse_args() +ret = ogGrubSecurity (args.disk, args.par, args.user, args.passwd) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index 6f0a1ca..7dfe45d 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -1054,6 +1054,45 @@ def ogBootLoaderOgliveDefaultEntry (disk, par): #@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar (ogMount). #@exception OG_ERR_NOTFOUND No encuentra archivo de configuración del grub. #*/ ## +def ogGrubSecurity (disk, par, user='root', passwd=''): +#localizar disco segunda etapa del grub + secondstage = FileSystemLib.ogMount (disk, par) + if not secondstage: return None + + ## original bash code: + ## $SECONDSTAGE/{,boot/}{{grubMBR,grubPARTITION}/boot/,}{grub{,2},{,efi/}EFI/*}/{menu.lst,grub.cfg,grub.cfg.backup.og} + grubcfg = [] + for _uno in ['', 'boot']: + for _dos in ['grubMBR/boot', 'grubPARTITION/boot', '']: + for _tres in ['grub', 'grub2', 'EFI/*', 'efi/EFI/*']: + for _cuatro in ['menu.lst', 'grub.cfg', 'grub.cfg.backup.og']: + path = '/'.join ([secondstage, _uno, _dos, _tres, _cuatro]) + grubcfg += glob.glob (path) + print (f'nati grubcfg ({grubcfg})') + +# comprobamos que exista el archivo de configuración. + if not grubcfg: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, 'grub.cfg') + return None + + if passwd: + encryptpasswd = subprocess.run (['grub-mkpasswd-pbkdf2'], input=f'{passwd}\n{passwd}', text=True, capture_output=True).stdout + if encryptpasswd: + lines = encryptpasswd.strip().splitlines() + encryptpasswd = lines[-1] + encryptpasswd = re.sub ('^.*grub', 'grub', encryptpasswd) + + for file in grubcfg: + # Eliminamos configuración anterior + subprocess.run (['sed', '-i', '-e', '/superusers/d', '-e', '/password_pbkdf2/d', file]) + + # Configuramos grub.cfg para que sólo permita editar o entrar en línea de comandos al usuario especificado + if passwd: + subprocess.run (['sed', '-i', f'1i\\password_pbkdf2 {user} {encryptpasswd}', file]) + subprocess.run (['sed', '-i', f'1i\\set superusers="{user}"', file]) + + # Permitimos que se seleccionen las entradas + subprocess.run (['sed', '-i', '/menuentry /s/{/--unrestricted {/', file]) #/** From 842b4a395b69e65b33958bf79fb91960fabf1a35 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Wed, 5 Mar 2025 14:53:46 +0100 Subject: [PATCH 09/30] refs #1632 add ogGrubDefaultEntry --- ogclient/functions/ogBootLoaderDefaultEntry | 26 ++++++++++ ogclient/functions/ogGrubDefaultEntry | 25 ++++++++++ ogclient/lib/python3/BootLib.py | 53 ++++++++++++++++++++- 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100755 ogclient/functions/ogBootLoaderDefaultEntry create mode 100755 ogclient/functions/ogGrubDefaultEntry diff --git a/ogclient/functions/ogBootLoaderDefaultEntry b/ogclient/functions/ogBootLoaderDefaultEntry new file mode 100755 index 0000000..fc99085 --- /dev/null +++ b/ogclient/functions/ogBootLoaderDefaultEntry @@ -0,0 +1,26 @@ +#!/usr/bin/python3 + +import sys +import argparse +import ogGlobals +from SystemLib import ogHelp +from BootLib import ogBootLoaderDefaultEntry + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('diskdefault') +parser.add_argument ('pardefault') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogBootLoaderDefaultEntry', ogGlobals.lang.MSG_SEE+' ogGrubDefaultEntry', []) + sys.exit (0) + +args = parser.parse_args() +ret = ogBootLoaderDefaultEntry (args.disk, args.par, args.diskdefault, args.pardefault) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/functions/ogGrubDefaultEntry b/ogclient/functions/ogGrubDefaultEntry new file mode 100755 index 0000000..e006e74 --- /dev/null +++ b/ogclient/functions/ogGrubDefaultEntry @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogGrubDefaultEntry + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('diskdefault') +parser.add_argument ('pardefault') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGrubDefaultEntry', 'ogGrubDefaultEntry int_ndisk int_npartition int_disk_default_entry int_npartition_default_entry', ['ogGrubDefaultEntry 1 6 1 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogGrubDefaultEntry (args.disk, args.par, args.diskdefault, args.pardefault) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index 7dfe45d..2e26fa7 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -961,6 +961,8 @@ def ogBootLoaderDeleteEntry (disk, par, diskdel, pardel): #@brief ver ogBootLoaderDefaultEntry #@see ogBootLoaderDefaultEntry #*/ ## +def ogGrubDefaultEntry (disk, par, diskdefault, pardefault): + return ogBootLoaderDefaultEntry (disk, par, diskdefault, pardefault) #/** # ogBootLoaderDefaultEntry int_disk_CFG int_partition_CFG int_disk_default_entry int_npartition_default_entry @@ -975,6 +977,56 @@ def ogBootLoaderDeleteEntry (disk, par, diskdel, pardel): #@exception OG_ERR_OUTOFLIMIT Param $3 no es entero. #@exception OG_ERR_NOTFOUND Fichero de configuración no encontrado: burg.cfg. #*/ ## +def ogBootLoaderDefaultEntry (disk, par, diskdefault, pardefault): +# Nombre de la función que llama a esta. + func = inspect.stack()[1][3] + +# Error si no puede montar sistema de archivos. + dirmount = FileSystemLib.ogMount (disk, par) + if not dirmount: return None + +# Comprobamos que exista fichero de configuración +# La función debe ser llamanda desde ogGrubDefaultEntry, ogBurgDefaultEntry or ogRefindDefaultEntry. + if 'ogGrubDefaultEntry' == func: + cfgfile = f'{dirmount}/boot/grubMBR/boot/grub/grub.cfg' + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Use ogGrubDefaultEntry') + return None + +# Error si no existe archivo de configuración + if not os.path.exists (cfgfile): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, cfgfile) + return None + +# Dispositivo + label = DiskLib.ogDiskToDev (diskdefault, pardefault) + +# Número de línea de la entrada por defecto en CFGFILE (primera de la partición). + grep_out = subprocess.run (['grep', '--line-number', '--max-count', '1', f'menuentry.*{label}', cfgfile], capture_output=True, text=True).stdout + if not grep_out: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'menuentry {label}') + return None + defaultentry, _ = grep_out.split (':', maxsplit=1) + +# Si no hay entradas para borrar me salgo con aviso + if not defaultentry: + SystemLib.ogRaiseError (['session', 'log'], ogGlobals.OG_ERR_NOTFOUND, f'No menuentry {label}') + return None + +# Número de la de linea por defecto en el menú de usuario + menuentry = subprocess.run (f'grep -n -e menuentry {cfgfile}| cut -d: -f1 | grep -n {defaultentry} |cut -d: -f1', shell=True, text=True, capture_output=True).stdout + if not menuentry: return None + menuentry = int (menuentry) + # En grub y burg las líneas empiezan a contar desde cero + menuentry -= 1 + subprocess.run (['sed', '--regexp-extended', '-i', f's/set default="?[0-9]*"?$/set default="{menuentry}"/g', cfgfile]) + + MSG = f'ogGlobals.lang.MSG_HELP_{func}' + try: MSG = eval (MSG) + except: MSG = '' + if '.' == MSG[-1]: MSG=MSG[0:-1] + print (f'{MSG}: {disk} {par} {diskdefault} {pardefault}') + return True #/** # ogGrubOgliveDefaultEntry num_disk num_part @@ -1037,7 +1089,6 @@ def ogBootLoaderOgliveDefaultEntry (disk, par): try: MSG = eval (MSG) except: MSG = '' if '.' == MSG[-1]: MSG=MSG[0:-1] - print (f'{MSG}: {disk} {par}') return True From 7e255b6c521c9f6635ed5ab3e32a890e00eeb3fa Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Thu, 6 Mar 2025 09:47:04 +0100 Subject: [PATCH 10/30] refs #1622 add ogGrub4dosInstallMbr --- ogclient/functions/ogGrub4dosInstallMbr | 23 +++++++++++ ogclient/lib/python3/BootLib.py | 51 +++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100755 ogclient/functions/ogGrub4dosInstallMbr diff --git a/ogclient/functions/ogGrub4dosInstallMbr b/ogclient/functions/ogGrub4dosInstallMbr new file mode 100755 index 0000000..b76ebb3 --- /dev/null +++ b/ogclient/functions/ogGrub4dosInstallMbr @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogGrub4dosInstallMbr + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGrub4dosInstallMbr', 'ogGrub4dosInstallMbr int_ndisk int_part', ['ogGrub4dosInstallMbr 1 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogGrub4dosInstallMbr (args.disk, args.par) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index 2e26fa7..5adb853 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -1282,3 +1282,54 @@ def ogBootLoaderSetTimeOut (disk, par, timeout): #@exception OG_ERR_NOMSDOS Disco duro no particioniado en modo msdos #@exception OG_ERR_NOTWRITE Particion no modificable. #*/ ## + +def ogGrub4dosInstallMbr (disk, par): +#Controlar existencia de disco y particion + DEVICE = DiskLib.ogDiskToDev (disk) + if not DEVICE: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, '') + return None + MOUNTDISK = FileSystemLib.ogMount (disk, par) + if not MOUNTDISK: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_ERROR) + return None +#Controlar acceso de escritura a la particion + if FileSystemLib.ogIsReadonly (disk, par): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTWRITE, f': {disk} {par}') + return None +#Controlar disco no uefi + if InventoryLib.ogIsEfiActive(): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTBIOS, ' : grub4dos solo soporta PC con bios legacy') + return None +#Controlar particionado tipo msdos + ptt = DiskLib.ogGetPartitionTableType (disk) + if 'MSDOS' != ptt: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOMSDOS, ': grub2dos requiere particionado tipo MSDOS') + return None +#Controlar la existencia del grub4dos con acceso a ntfs + BINDIR = f'{ogGlobals.OGLIB}/grub4dos/grub4dos-0.4.6a' + if not os.path.exists (f'{BINDIR}/bootlace.com'): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f': {BINDIR}/bootlace.com') + return None + +#instalar el bootloader de grlrd en el MBR + subprocess.run ([f'{BINDIR}/bootlace64.com', DEVICE], capture_output=True) +#copiar grld a la particion + shutil.copy2 (f'{BINDIR}/grldr', MOUNTDISK) +#Instalar y configurar grub4dos + if os.path.exists (f'{MOUNTDISK}/boot/grub/menu.lst'): + os.unlink (f'{MOUNTDISK}/boot/grub/menu.lst') + os.rmdir (f'/{MOUNTDISK}/boot/grub') + if not os.path.exists (f'{MOUNTDISK}/boot/grub/menu.lst'): + os.makedirs (f'/{MOUNTDISK}/boot/grub', exist_ok=True) + open (f'/{MOUNTDISK}/boot/grub/menu.lst', 'w').close() + GRUBDISK = int (disk) - 1 + with open (f'/{MOUNTDISK}/boot/grub/menu.lst', 'w') as fd: + fd.write ('##NO-TOCAR-ESTA-LINEA MBR\n') + fd.write ('timeout 0\n') + fd.write ('title MBR\n') + fd.write (f'root (hd{GRUBDISK},0)\n') + fd.write (f'chainloader (hd{GRUBDISK},0)+1\n') + fd.write ('boot\n') + fd.write ('EOT\n') + fd.write ('\n') From 41aa2c3a5f05393fa344efcfea0d398fb2b87fce Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Thu, 6 Mar 2025 10:13:35 +0100 Subject: [PATCH 11/30] refs #1630 fix bugs in ogGrubHidePartitions --- ogclient/lib/python3/BootLib.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index 5adb853..de349a1 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -848,7 +848,7 @@ def ogBootLoaderHidePartitions (disk, par, datadisk=None, datapar=None): #2:/dev/sda3 awk_out = subprocess.run (f''' awk '/menuentry.*Windows/ {{gsub(/\\)"/, ""); gsub(/^.*dev/,""); print NR":/dev"$1}} ' {cfgfile} - ''', shell=True, text=True).stdout + ''', shell=True, text=True, capture_output=True).stdout if awk_out: winentry = awk_out.splitlines() winentry.reverse() @@ -867,17 +867,17 @@ def ogBootLoaderHidePartitions (disk, par, datadisk=None, datapar=None): for entry in winentry: line, part = entry.split (':') # En cada entrada, oculto o muestro cada particion. - TEXT = '' + text = '' for parthidden in winpart: # Muestro la particion de la entrada actual y la de datos. if parthidden == part or parthidden == partdata: - HIDDEN = '-' + hidden = '-' else: - HIDDEN = '+' + hidden = '+' numdisk, numpart = DiskLib.ogDevToDisk (parthidden).split() numdisk = int (numdisk) numpart = int (numpart) - TEXT = f'\tparttool (hd{numdisk-1},{parttabletype}{numpart}) hidden{hidden} \n{text}' + text = f'\tparttool (hd{numdisk-1},{parttabletype}{numpart}) hidden{hidden} \n{text}' subprocess.run (['sed', '-i', f'{line}a\\ {text}', cfgfile]) # Activamos la particion que se inicia en todas las entradas de windows. subprocess.run (['sed', '-i', '/chainloader/i\\\tparttool ${root} boot+', cfgfile]) From 59b702047ddb649e2bc0b987b3c0b05cea757247 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Thu, 6 Mar 2025 10:17:10 +0100 Subject: [PATCH 12/30] refs #1622 add ogGrub4dosInstallMbr --- ogclient/lib/python3/BootLib.py | 38 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index de349a1..8eb00b2 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -1285,12 +1285,12 @@ def ogBootLoaderSetTimeOut (disk, par, timeout): def ogGrub4dosInstallMbr (disk, par): #Controlar existencia de disco y particion - DEVICE = DiskLib.ogDiskToDev (disk) - if not DEVICE: + device = DiskLib.ogDiskToDev (disk) + if not device: SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, '') return None - MOUNTDISK = FileSystemLib.ogMount (disk, par) - if not MOUNTDISK: + mountdisk = FileSystemLib.ogMount (disk, par) + if not mountdisk: SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_ERROR) return None #Controlar acceso de escritura a la particion @@ -1307,29 +1307,29 @@ def ogGrub4dosInstallMbr (disk, par): SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOMSDOS, ': grub2dos requiere particionado tipo MSDOS') return None #Controlar la existencia del grub4dos con acceso a ntfs - BINDIR = f'{ogGlobals.OGLIB}/grub4dos/grub4dos-0.4.6a' - if not os.path.exists (f'{BINDIR}/bootlace.com'): - SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f': {BINDIR}/bootlace.com') + bindir = f'{ogGlobals.OGLIB}/grub4dos/grub4dos-0.4.6a' + if not os.path.exists (f'{bindir}/bootlace.com'): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f': {bindir}/bootlace.com') return None #instalar el bootloader de grlrd en el MBR - subprocess.run ([f'{BINDIR}/bootlace64.com', DEVICE], capture_output=True) + subprocess.run ([f'{bindir}/bootlace64.com', device], capture_output=True) #copiar grld a la particion - shutil.copy2 (f'{BINDIR}/grldr', MOUNTDISK) + shutil.copy2 (f'{bindir}/grldr', mountdisk) #Instalar y configurar grub4dos - if os.path.exists (f'{MOUNTDISK}/boot/grub/menu.lst'): - os.unlink (f'{MOUNTDISK}/boot/grub/menu.lst') - os.rmdir (f'/{MOUNTDISK}/boot/grub') - if not os.path.exists (f'{MOUNTDISK}/boot/grub/menu.lst'): - os.makedirs (f'/{MOUNTDISK}/boot/grub', exist_ok=True) - open (f'/{MOUNTDISK}/boot/grub/menu.lst', 'w').close() - GRUBDISK = int (disk) - 1 - with open (f'/{MOUNTDISK}/boot/grub/menu.lst', 'w') as fd: + if os.path.exists (f'{mountdisk}/boot/grub/menu.lst'): + os.unlink (f'{mountdisk}/boot/grub/menu.lst') + os.rmdir (f'/{mountdisk}/boot/grub') + if not os.path.exists (f'{mountdisk}/boot/grub/menu.lst'): + os.makedirs (f'/{mountdisk}/boot/grub', exist_ok=True) + open (f'/{mountdisk}/boot/grub/menu.lst', 'w').close() + grubdisk = int (disk) - 1 + with open (f'/{mountdisk}/boot/grub/menu.lst', 'w') as fd: fd.write ('##NO-TOCAR-ESTA-LINEA MBR\n') fd.write ('timeout 0\n') fd.write ('title MBR\n') - fd.write (f'root (hd{GRUBDISK},0)\n') - fd.write (f'chainloader (hd{GRUBDISK},0)+1\n') + fd.write (f'root (hd{grubdisk},0)\n') + fd.write (f'chainloader (hd{grubdisk},0)+1\n') fd.write ('boot\n') fd.write ('EOT\n') fd.write ('\n') From fb0d52073900bcdb0b7ef41ae666fb3ac888ff01 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Thu, 6 Mar 2025 11:07:53 +0100 Subject: [PATCH 13/30] refs #1633 unhardcode IP address in OGLOGFILE --- ogclient/lib/python3/ogGlobals.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ogclient/lib/python3/ogGlobals.py b/ogclient/lib/python3/ogGlobals.py index 29eea03..c744b2c 100644 --- a/ogclient/lib/python3/ogGlobals.py +++ b/ogclient/lib/python3/ogGlobals.py @@ -6,6 +6,10 @@ import os.path import locale import importlib.util +## required for defining OGLOGFILE +import NetLib +ip = NetLib.ogGetIpAddress() + def load_lang (name): global lang if name in sys.modules: @@ -57,11 +61,12 @@ OGBIN = os.path.join (OPENGNSYS, 'bin') OGETC = os.path.join (OPENGNSYS, 'etc') OGLIB = os.path.join (OPENGNSYS, 'lib') OGAPI = os.path.join (OGLIB, 'engine', 'bin') +OGPYFUNCS = os.path.join (OPENGNSYS, 'functions') OGSCRIPTS = os.path.join (OPENGNSYS, 'scripts') OGIMG = os.path.join (OPENGNSYS, 'images') OGCAC = os.path.join (OPENGNSYS, 'cache') OGLOG = os.path.join (OPENGNSYS, 'log') -OGLOGFILE = f'{OGLOG}/192.168.42.42' ## TODO import NetLib; OGLOGFILE = f'$OGLOG/{NetLib.ogGetIpAddress()}.log' +OGLOGFILE = f'{OGLOG}/{ip}.log' DEBUG = 'yes' _path = os.environ['PATH'] + ':/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin:/opt/oglive/rootfs/opt/drbl/sbin' os.environ['PATH'] = ':'.join ([OGSCRIPTS, _path, OGAPI, OGBIN]) From ec4f1f8642c9496e7b22e2a1327d3333ee0dc217 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Thu, 6 Mar 2025 13:55:25 +0100 Subject: [PATCH 14/30] refs #1646 add ogSetLinuxName --- ogclient/functions/ogSetLinuxName | 37 +++++++++++++++++++++++++++++++ ogclient/lib/python3/BootLib.py | 24 ++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100755 ogclient/functions/ogSetLinuxName diff --git a/ogclient/functions/ogSetLinuxName b/ogclient/functions/ogSetLinuxName new file mode 100755 index 0000000..0c66e0e --- /dev/null +++ b/ogclient/functions/ogSetLinuxName @@ -0,0 +1,37 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogSetLinuxName +from NetLib import ogGetHostname + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogSetLinuxName', 'ogSetLinuxName int_ndisk int_nfilesys [str_name]', ['ogSetLinuxName 1 1 practica-pc']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 3 == len (sys.argv): + parser.add_argument ('disk') + parser.add_argument ('par') +elif 4 == len (sys.argv): + parser.add_argument ('disk') + parser.add_argument ('par') + parser.add_argument ('hostname') + +args = parser.parse_args() + +if 3 == len (sys.argv): + h = ogGetHostname() + if h: + ret = ogSetLinuxName (args.disk, args.par, h) + else: + ret = ogSetLinuxName (args.disk, args.par) +elif 4 == len (sys.argv): + ret = ogSetLinuxName (args.disk, args.par, args.hostname) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index 8eb00b2..b520326 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -670,6 +670,30 @@ def ogConfigureFstab (disk, par): #@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar. #@note Si no se indica nombre, se asigna un valor por defecto. #*/ ## +def ogSetLinuxName (disk, par, hostname='pc'): +# Montar el sistema de archivos. + mntdir = FileSystemLib.ogMount (disk, par) + if not mntdir: return None + + etc = FileLib.ogGetPath (src=f'{disk} {par}', file='/etc') + + if os.path.isdir (etc): + #cambio de nombre en hostname + with open (f'{etc}/hostname', 'w') as fd: + fd.write (f'{hostname}\n') + #Opcion A para cambio de nombre en hosts + #sed "/127.0.1.1/ c\127.0.1.1 \t $HOSTNAME" $ETC/hosts > /tmp/hosts && cp /tmp/hosts $ETC/ && rm /tmp/hosts + #Opcion B componer fichero de hosts + with open (f'{etc}/hosts', 'w') as fd: + fd.write ('127.0.0.1 localhost\n') + fd.write (f'127.0.1.1 {hostname}\n') + fd.write ('\n') + fd.write ('# The following lines are desirable for IPv6 capable hosts\n') + fd.write ('::1 ip6-localhost ip6-loopback\n') + fd.write ('fe00::0 ip6-localnet\n') + fd.write ('ff00::0 ip6-mcastprefix\n') + fd.write ('ff02::1 ip6-allnodes\n') + fd.write ('ff02::2 ip6-allrouters\n') From 08cff2ce0d88e16f07446c949f5ecb6f1914886b Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Thu, 6 Mar 2025 14:00:10 +0100 Subject: [PATCH 15/30] refs #1647 add ogBootMbrXP --- ogclient/functions/ogBootMbrXP | 22 ++++++++++++++++++++++ ogclient/lib/python3/BootLib.py | 5 +++++ 2 files changed, 27 insertions(+) create mode 100755 ogclient/functions/ogBootMbrXP diff --git a/ogclient/functions/ogBootMbrXP b/ogclient/functions/ogBootMbrXP new file mode 100755 index 0000000..8a15f08 --- /dev/null +++ b/ogclient/functions/ogBootMbrXP @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogBootMbrXP + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogBootMbrXP', 'ogBootMbrXP int_ndisk', ['ogBootMbrXP 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogBootMbrXP (args.disk) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index b520326..66cd379 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -118,6 +118,11 @@ def ogSetWindowsName (disk, par, name): #@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar. #*/ ## +def ogBootMbrXP (disk): + DISK = DiskLib.ogDiskToDev (disk) + if not DISK: return None + subprocess.run (['ms-sys', '-z', '-f', DISK]) + subprocess.run (['ms-sys', '-m', '-f', DISK]) #/** # ogBootMbrGeneric int_ndisk From 370915fc01a7d33ffd069683aef22d8b44993c15 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Thu, 6 Mar 2025 14:05:52 +0100 Subject: [PATCH 16/30] refs #1652 add ogBootMbrGeneric --- ogclient/functions/ogBootMbrGeneric | 22 ++++++++++++++++++++++ ogclient/lib/python3/BootLib.py | 11 +++++++++++ 2 files changed, 33 insertions(+) create mode 100755 ogclient/functions/ogBootMbrGeneric diff --git a/ogclient/functions/ogBootMbrGeneric b/ogclient/functions/ogBootMbrGeneric new file mode 100755 index 0000000..48cde7f --- /dev/null +++ b/ogclient/functions/ogBootMbrGeneric @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogBootMbrGeneric + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogBootMbrGeneric', 'ogBootMbrGeneric int_ndisk', ['ogBootMbrGeneric 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogBootMbrGeneric (args.disk) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index 66cd379..a75442d 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -133,6 +133,17 @@ def ogBootMbrXP (disk): #@exception OG_ERR_NOTFOUND Tipo de partición desconocido o no se puede montar. #*/ ## +def ogBootMbrGeneric (disk): + DISK = DiskLib.ogDiskToDev (disk) + if not DISK: return None + subprocess.run (['ms-sys', '-z', '-f', DISK]) + subprocess.run (['ms-sys', '-s', '-f', DISK]) + +# Firma necesaria para Windows equipos UEFI + with open ('/proc/sys/kernel/random/uuid', 'r') as fd: + kernel_random_uuid = fd.read().split ('-')[0] + signature = f'0x{kernel_random_uuid}' + subprocess.run (['ms-sys', '-S', signature, DISK]) From bb2e4a4e7ff921bb6b8ffd9fd6e7a2e4ec4e0a62 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Thu, 6 Mar 2025 14:27:54 +0100 Subject: [PATCH 17/30] refs #1651 add ogGetBootMbr --- ogclient/functions/ogGetBootMbr | 22 ++++++++++++++++++++++ ogclient/lib/python3/BootLib.py | 4 ++++ 2 files changed, 26 insertions(+) create mode 100755 ogclient/functions/ogGetBootMbr diff --git a/ogclient/functions/ogGetBootMbr b/ogclient/functions/ogGetBootMbr new file mode 100755 index 0000000..5c3c887 --- /dev/null +++ b/ogclient/functions/ogGetBootMbr @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogGetBootMbr + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetBootMbr', 'ogGetBootMbr int_ndisk', ['ogGetBootMbr 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogGetBootMbr (args.disk) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index a75442d..a13b050 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -187,6 +187,10 @@ fix_first_sector=yes #@exception OG_ERR_FORMAT Formato incorrecto. #@exception OG_ERR_NOTFOUND Dispositivo de disco no encontrado. #*/ ## +def ogGetBootMbr (disk): + DISK = DiskLib.ogDiskToDev (disk) + if not DISK: return None + subprocess.run (['ms-sys', '-f', DISK]) #/** # ogWindowsBootParameters int_ndisk int_parition From 9704d21d206e5f4e1bb569580d0116a2a95e797d Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Thu, 6 Mar 2025 14:31:28 +0100 Subject: [PATCH 18/30] refs #1650 add ogGetWindowsName --- ogclient/functions/ogGetWindowsName | 23 +++++++++++++++++++++++ ogclient/lib/python3/BootLib.py | 6 ++++++ 2 files changed, 29 insertions(+) create mode 100755 ogclient/functions/ogGetWindowsName diff --git a/ogclient/functions/ogGetWindowsName b/ogclient/functions/ogGetWindowsName new file mode 100755 index 0000000..a0de62f --- /dev/null +++ b/ogclient/functions/ogGetWindowsName @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogGetWindowsName + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetWindowsName', 'ogGetWindowsName int_ndisk int_npartition', ['ogGetWindowsName 1 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogGetWindowsName (args.disk, args.par) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index a13b050..1a23c75 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -51,6 +51,12 @@ import CacheLib #@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. #@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar. #*/ ## +def ogGetWindowsName (disk, par): + mntdir = FileSystemLib.ogMount (disk, par) + if not mntdir: return None + +# Obtener dato del valor de registro. + return RegistryLib.ogGetRegistryValue (mntdir, 'system', r'\ControlSet001\Control\ComputerName\ComputerName\ComputerName') #/** From fc69e23984695b0146514f41f562cca328b10090 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Thu, 6 Mar 2025 15:00:06 +0100 Subject: [PATCH 19/30] refs #1649 add ogLinuxBootParameters --- ogclient/functions/ogLinuxBootParameters | 23 ++++++++++++ ogclient/lib/python3/BootLib.py | 46 ++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100755 ogclient/functions/ogLinuxBootParameters diff --git a/ogclient/functions/ogLinuxBootParameters b/ogclient/functions/ogLinuxBootParameters new file mode 100755 index 0000000..6da5133 --- /dev/null +++ b/ogclient/functions/ogLinuxBootParameters @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogLinuxBootParameters + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogLinuxBootParameters', 'ogLinuxBootParameters int_ndisk int_nfilesys', ['ogLinuxBootParameters 1 2']) + sys.exit (0) + +args = parser.parse_args() +ret = ogLinuxBootParameters (args.disk, args.par) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index 1a23c75..467aaa4 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -70,6 +70,52 @@ def ogGetWindowsName (disk, par): #@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar. #@warning Función básica usada por \c ogBoot #*/ ## +def ogLinuxBootParameters (disk, par): +# Detectar id. de tipo de partición y codificar al mnemonico. + mntdir = FileSystemLib.ogMount (disk, par) + if not mntdir: return None + +# Fichero de configuración de GRUB. + confdir = mntdir # Sistema de archivos de arranque (/boot). + if os.path.isdir (f'{mntdir}/boot'): + confdir = f'{mntdir}/boot' # Sist. archivos raíz con directorio boot. + ## original bash code: + ## $MNTDIR/{,boot/}{{grubMBR,grubPARTITION}/boot/,}{grub{2,},{,efi/}EFI/*}/{menu.lst,grub.cfg}; do + conffile = None + for _uno in ['', 'boot']: + for _dos in ['grubMBR/boot', 'grubPARTITION/boot', '']: + for _tres in ['grub', 'grub2', 'EFI/*', 'efi/EFI/*']: + for _cuatro in ['menu.lst', 'grub.cfg']: + path = '/'.join ([mntdir, _uno, _dos, _tres, _cuatro]) + if os.path.exists (path): + conffile = path + if not conffile: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, 'grub.cfg') + return None + +# Toma del fichero de configuracion los valores del kernel, initrd +# y parámetros de arranque usando las cláusulas por defecto +# ("default" en GRUB1, "set default" en GRUB2) +# y los formatea para que sean compatibles con \c kexec . */ + awk_script = '''BEGIN {cont=-1;} + $1~/^default$/ {sub(/=/," "); def=$2;} + $1~/^set$/ && $2~/^default/ { gsub(/[="]/," "); def=$3; + if (def ~ /saved_entry/) def=0; + } + $1~/^(title|menuentry)$/ {cont++} + $1~/^set$/ && $2~/^root=.\\(hd__DISK__,(msdos|gpt)__PAR__\\).$/ { if (def==0) def=cont; } + $1~/^(kernel|linux(16|efi)?)$/ { if (def==cont) { + kern=$2; + sub($1,""); sub($1,""); sub(/^[ \\t]*/,""); app=$0 + } + } + $1~/^initrd(16|efi)?$/ {if (def==cont) init=$2} + END {if (kern!="") printf("%s %s %s", kern,init,app)} + ''' + awk_script = awk_script.replace ('__DISK__', str (int (disk) - 1)) + awk_script = awk_script.replace ('__PAR__', par) + awk_out = subprocess.run (['awk', awk_script, conffile], capture_output=True, text=True).stdout + return awk_out #/** From 7ef88ab48681059d7ec9db088ff7f968e5e6735a Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Thu, 6 Mar 2025 15:04:16 +0100 Subject: [PATCH 20/30] refs #1648 add ogSetWinlogonUser --- ogclient/functions/ogSetWinlogonUser | 24 ++++++++++++++++++++++++ ogclient/lib/python3/BootLib.py | 4 ++++ 2 files changed, 28 insertions(+) create mode 100755 ogclient/functions/ogSetWinlogonUser diff --git a/ogclient/functions/ogSetWinlogonUser b/ogclient/functions/ogSetWinlogonUser new file mode 100755 index 0000000..60c82e3 --- /dev/null +++ b/ogclient/functions/ogSetWinlogonUser @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogSetWinlogonUser + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('username') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogSetWinlogonUser', 'ogSetWinlogonUser int_ndisk int_npartition str_username', ['ogSetWinlogonUser 1 1 USUARIO']) + sys.exit (0) + +args = parser.parse_args() +ret = ogSetWinlogonUser (args.disk, args.par, args.username) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index 467aaa4..468f8e2 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -159,6 +159,10 @@ def ogSetWindowsName (disk, par, name): #@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. #@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar. #*/ ## +def ogSetWinlogonUser (disk, par, username): + mntdir = FileSystemLib.ogMount (disk, par) + if not mntdir: return None + RegistryLib.ogSetRegistryValue (mntdir, 'SOFTWARE', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultUserName', username) #/** From ca23788600b5fd199d8d386229eacbc9125af48b Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Fri, 7 Mar 2025 14:22:15 +0100 Subject: [PATCH 21/30] refs #1674 add interfaceAdm/RestaurarImagen.py --- ogclient/interfaceAdm/RestaurarImagen.py | 38 +++++++++++++++--------- ogclient/lib/python3/BootLib.py | 7 +++-- ogclient/lib/python3/FileSystemLib.py | 4 +-- ogclient/lib/python3/SystemLib.py | 4 +-- ogclient/lib/python3/UEFILib.py | 2 +- 5 files changed, 34 insertions(+), 21 deletions(-) diff --git a/ogclient/interfaceAdm/RestaurarImagen.py b/ogclient/interfaceAdm/RestaurarImagen.py index a5fda6c..efde3af 100755 --- a/ogclient/interfaceAdm/RestaurarImagen.py +++ b/ogclient/interfaceAdm/RestaurarImagen.py @@ -1,19 +1,29 @@ -#!/usr/bin/env python3 +#!/usr/bin/python3 +#_______________________________________________________________________________________________________________________________ +# +# PARAMETROS RECIBIDOS DESDE EL CLIENTE: +# $1 disco +# $2 par=Número de particion +# $3 Nombre canónico de la imagen +# $4 Dirección IP del repositorio +# $5 Protocolo UNICAST MULTICAST TORRENT +# $6 Opciones del protocolo +#_______________________________________________________________________________________________________________________________ + +# Llamar al script de despliegue "deployImage". + import sys import subprocess -if __name__ == "__main__": - if len(sys.argv) < 7: - print("Usage: python RestaurarImagen.py [additional_args...]") - sys.exit(1) +import ogGlobals - disk = sys.argv[1] - partition = sys.argv[2] - image_name = sys.argv[3] - ip = sys.argv[4] - protocol = sys.argv[5] - protocol_options = sys.argv[6] - additional_args = sys.argv[7:] +if __name__ == '__main__': + prog = sys.argv[0] + if len (sys.argv) < 7: + print (f'Usage: {prog} [additional_args...]') + sys.exit (1) - exit_code = deploy_image(ip, image_name, disk, partition, protocol, protocol_options, *additional_args) - sys.exit(exit_code) + disk, par, imgname, repo, proto, protoopt, *extra = sys.argv[1:] + + rc = subprocess.run ([f'{ogGlobals.OGSCRIPTS}/deployImage.py', repo, imgname, disk, par, proto, protoopt] + extra).returncode + sys.exit (rc) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index 468f8e2..dd1da9a 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -653,11 +653,14 @@ def ogGrubInstallPartition (disk, par, checkos='FALSE', kernelparam=''): with open (f'{secondstage}{prefixsecondstage}/boot/grub/grub.cfg', 'a') as fd: fd.write (out + '\n') +#Instalar el grub eval = subprocess.run (['grub-install', '--force'] + efioptgrub + [f'--root-directory={secondstage}{prefixsecondstage}', firststage]).returncode - if InventoryLib.ogIsEfiActive(): # Movemos el grubx64.efi +# Movemos el grubx64.efi + if InventoryLib.ogIsEfiActive(): 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}') + bn = os.path.basename (b) + os.rename (f'{efisecondstage}/EFI/{efisubdir}/EFI/BOOT/{bn}', f'{efisecondstage}/EFI/{efisubdir}/Boot/{bn}') 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 diff --git a/ogclient/lib/python3/FileSystemLib.py b/ogclient/lib/python3/FileSystemLib.py index 1d8e954..987ec7e 100644 --- a/ogclient/lib/python3/FileSystemLib.py +++ b/ogclient/lib/python3/FileSystemLib.py @@ -294,7 +294,7 @@ def ogGetFsSize (disk, par, unit='KB'): return # Obtener el tamaño del sistema de archivo (si no está formateado; tamaño = 0). - mnt = FileSystemLib.ogMount (disk, par) + mnt = ogMount (disk, par) if mnt: result = subprocess.run(["df", "-BK", mnt], capture_output=True, text=True) val = result.stdout.split("\n")[1].split()[1] @@ -894,7 +894,7 @@ def ogGetFreeSize(disk, part, unit='KB'): kk factor = unit2factor[unit.lower()] - particion = FileSystemLib.ogMount (disk, part) + particion = ogMount (disk, part) if not particion: kk df = subprocess.run (['df'], capture_output=True, text=True).stdout diff --git a/ogclient/lib/python3/SystemLib.py b/ogclient/lib/python3/SystemLib.py index dca5232..9bf67dd 100644 --- a/ogclient/lib/python3/SystemLib.py +++ b/ogclient/lib/python3/SystemLib.py @@ -295,11 +295,11 @@ def ogIsRepoLocked(): # FUNCNAME = ogCheckProgram.__name__ # # if not program or not isinstance(program, str): -# SystemLib.ogRaiseError ("session", ogGlobals.OG_ERR_FORMAT, f"Error: {ogGlobals.lang.MSG_ERR_FORMAT} {FUNCNAME} \"program\"") +# ogRaiseError ("session", ogGlobals.OG_ERR_FORMAT, f"Error: {ogGlobals.lang.MSG_ERR_FORMAT} {FUNCNAME} \"program\"") # return # # if not shutil.which(program): -# SystemLib.ogRaiseError ( "session", ogGlobals.OG_ERR_NOTEXEC, f"Error: The program '{program}' is not available on the system.") +# ogRaiseError ( "session", ogGlobals.OG_ERR_NOTEXEC, f"Error: The program '{program}' is not available on the system.") # return # # return 0 diff --git a/ogclient/lib/python3/UEFILib.py b/ogclient/lib/python3/UEFILib.py index a70b5a7..94eebf2 100644 --- a/ogclient/lib/python3/UEFILib.py +++ b/ogclient/lib/python3/UEFILib.py @@ -428,7 +428,7 @@ def ogRestoreEfiBootLoader (disk, par): return osversion = InventoryLib.ogGetOsVersion (disk, par) - if 'Windows 1' in osversion: + if osversion and 'Windows 1' in osversion: bootlabel = f'Part-{int(disk):02d}-{int(par):02d}' loader = FileLib.ogGetPath (file=f'{mntdir}/ogBoot/bootmgfw.efi') if not loader: From 20d50900ad1ab01f66eca0fd9dcd55a023d24805 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Fri, 7 Mar 2025 14:23:36 +0100 Subject: [PATCH 22/30] refs #1674 rename files --- ogclient/interfaceAdm/RestaurarImagen | 18 ++++++++++++++++-- .../{RestaurarImagen.py => RestaurarImagen.sh} | 18 ++---------------- 2 files changed, 18 insertions(+), 18 deletions(-) rename ogclient/interfaceAdm/{RestaurarImagen.py => RestaurarImagen.sh} (51%) diff --git a/ogclient/interfaceAdm/RestaurarImagen b/ogclient/interfaceAdm/RestaurarImagen index 6f9ae24..efde3af 100755 --- a/ogclient/interfaceAdm/RestaurarImagen +++ b/ogclient/interfaceAdm/RestaurarImagen @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/python3 #_______________________________________________________________________________________________________________________________ # # PARAMETROS RECIBIDOS DESDE EL CLIENTE: @@ -11,5 +11,19 @@ #_______________________________________________________________________________________________________________________________ # Llamar al script de despliegue "deployImage". -deployImage "$4" "$3" "$1" "$2" "$5" "$6" "$7" "$8" || exit $? +import sys +import subprocess + +import ogGlobals + +if __name__ == '__main__': + prog = sys.argv[0] + if len (sys.argv) < 7: + print (f'Usage: {prog} [additional_args...]') + sys.exit (1) + + disk, par, imgname, repo, proto, protoopt, *extra = sys.argv[1:] + + rc = subprocess.run ([f'{ogGlobals.OGSCRIPTS}/deployImage.py', repo, imgname, disk, par, proto, protoopt] + extra).returncode + sys.exit (rc) diff --git a/ogclient/interfaceAdm/RestaurarImagen.py b/ogclient/interfaceAdm/RestaurarImagen.sh similarity index 51% rename from ogclient/interfaceAdm/RestaurarImagen.py rename to ogclient/interfaceAdm/RestaurarImagen.sh index efde3af..6f9ae24 100755 --- a/ogclient/interfaceAdm/RestaurarImagen.py +++ b/ogclient/interfaceAdm/RestaurarImagen.sh @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/bin/bash #_______________________________________________________________________________________________________________________________ # # PARAMETROS RECIBIDOS DESDE EL CLIENTE: @@ -11,19 +11,5 @@ #_______________________________________________________________________________________________________________________________ # Llamar al script de despliegue "deployImage". +deployImage "$4" "$3" "$1" "$2" "$5" "$6" "$7" "$8" || exit $? -import sys -import subprocess - -import ogGlobals - -if __name__ == '__main__': - prog = sys.argv[0] - if len (sys.argv) < 7: - print (f'Usage: {prog} [additional_args...]') - sys.exit (1) - - disk, par, imgname, repo, proto, protoopt, *extra = sys.argv[1:] - - rc = subprocess.run ([f'{ogGlobals.OGSCRIPTS}/deployImage.py', repo, imgname, disk, par, proto, protoopt] + extra).returncode - sys.exit (rc) From 2d0c77b07381b1e3b1ff5532ef7b9cff6fa5a845 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Mon, 10 Mar 2025 11:40:49 +0100 Subject: [PATCH 23/30] Revert "refs #1674 rename files" This reverts commit 20d50900ad1ab01f66eca0fd9dcd55a023d24805. --- ogclient/interfaceAdm/RestaurarImagen | 18 ++---------------- .../{RestaurarImagen.sh => RestaurarImagen.py} | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 18 deletions(-) rename ogclient/interfaceAdm/{RestaurarImagen.sh => RestaurarImagen.py} (51%) diff --git a/ogclient/interfaceAdm/RestaurarImagen b/ogclient/interfaceAdm/RestaurarImagen index efde3af..6f9ae24 100755 --- a/ogclient/interfaceAdm/RestaurarImagen +++ b/ogclient/interfaceAdm/RestaurarImagen @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/bin/bash #_______________________________________________________________________________________________________________________________ # # PARAMETROS RECIBIDOS DESDE EL CLIENTE: @@ -11,19 +11,5 @@ #_______________________________________________________________________________________________________________________________ # Llamar al script de despliegue "deployImage". +deployImage "$4" "$3" "$1" "$2" "$5" "$6" "$7" "$8" || exit $? -import sys -import subprocess - -import ogGlobals - -if __name__ == '__main__': - prog = sys.argv[0] - if len (sys.argv) < 7: - print (f'Usage: {prog} [additional_args...]') - sys.exit (1) - - disk, par, imgname, repo, proto, protoopt, *extra = sys.argv[1:] - - rc = subprocess.run ([f'{ogGlobals.OGSCRIPTS}/deployImage.py', repo, imgname, disk, par, proto, protoopt] + extra).returncode - sys.exit (rc) diff --git a/ogclient/interfaceAdm/RestaurarImagen.sh b/ogclient/interfaceAdm/RestaurarImagen.py similarity index 51% rename from ogclient/interfaceAdm/RestaurarImagen.sh rename to ogclient/interfaceAdm/RestaurarImagen.py index 6f9ae24..efde3af 100755 --- a/ogclient/interfaceAdm/RestaurarImagen.sh +++ b/ogclient/interfaceAdm/RestaurarImagen.py @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/python3 #_______________________________________________________________________________________________________________________________ # # PARAMETROS RECIBIDOS DESDE EL CLIENTE: @@ -11,5 +11,19 @@ #_______________________________________________________________________________________________________________________________ # Llamar al script de despliegue "deployImage". -deployImage "$4" "$3" "$1" "$2" "$5" "$6" "$7" "$8" || exit $? +import sys +import subprocess + +import ogGlobals + +if __name__ == '__main__': + prog = sys.argv[0] + if len (sys.argv) < 7: + print (f'Usage: {prog} [additional_args...]') + sys.exit (1) + + disk, par, imgname, repo, proto, protoopt, *extra = sys.argv[1:] + + rc = subprocess.run ([f'{ogGlobals.OGSCRIPTS}/deployImage.py', repo, imgname, disk, par, proto, protoopt] + extra).returncode + sys.exit (rc) From e89143bab22f2f7c3bd35b7b59bf0f95b2e70fe1 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Mon, 10 Mar 2025 11:43:02 +0100 Subject: [PATCH 24/30] refs #1678 add interfaceAdm/InventarioHardware.py --- ogclient/interfaceAdm/InventarioHardware.py | 50 ++++++++---------- ogclient/lib/python3/InventoryLib.py | 1 - ogclient/scripts/listHardwareInfo.py | 57 ++++++++------------- 3 files changed, 42 insertions(+), 66 deletions(-) diff --git a/ogclient/interfaceAdm/InventarioHardware.py b/ogclient/interfaceAdm/InventarioHardware.py index bb1188d..de35025 100755 --- a/ogclient/interfaceAdm/InventarioHardware.py +++ b/ogclient/interfaceAdm/InventarioHardware.py @@ -1,33 +1,25 @@ -#!/usr/bin/env python3 -import subprocess +#!/usr/bin/python3 +# Script de interfaz para guardar en un fichero el inventario de hardware de un cliente. + import sys +import subprocess -def main(output_file): - # Ejecutar el comando `listHardwareInfo.py` y capturar el resultado - try: - print(f"------------------------------------------ loading listHardwareInfo.py") - result = subprocess.run( - ["python3", "/opt/opengnsys/scripts/listHardwareInfo.py"], - capture_output=True, text=True, check=True - ) - output_lines = result.stdout.strip().split('\n') - file_path = output_lines[-1] # Obtener la última línea como la ruta del archivo de salida - print(f"------------------------------------------ archivo:{file_path}") - - # Leer desde la segunda línea del archivo y escribir en el archivo de salida especificado - with open(file_path, 'r') as input_file, open(output_file, 'w') as output: - lines = input_file.readlines()[1:] # Saltar la primera línea - output.writelines(lines) +import ogGlobals +from SystemLib import ogRaiseError - except subprocess.CalledProcessError as e: - print("Error ejecutando listHardwareInfo.py:", e.stderr, file=sys.stderr) - sys.exit(e.returncode) - except FileNotFoundError as e: - print(f"Archivo no encontrado: {e.filename}", file=sys.stderr) - sys.exit(1) +prog = sys.argv[0] +if len (sys.argv) != 2: + print (f'Usage: {prog} ') + sys.exit (1) +output_file = sys.argv[1] -if __name__ == "__main__": - if len(sys.argv) != 2: - print("Uso: python3 InventarioHardware.py ") - sys.exit(1) - main(sys.argv[1]) +listhi_out = subprocess.run ( [f'{ogGlobals.OGSCRIPTS}/listHardwareInfo.py'], capture_output=True, text=True).stdout +if listhi_out: + inventory_path = listhi_out.splitlines()[0] +else: + ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, 'listHardwareInfo.py failed') + sys.exit (1) + +with open (inventory_path, 'r') as fdin, open (output_file, 'w') as fdout: + lines = fdin.readlines()[1:] # 'tail -n +2' + fdout.writelines (lines) diff --git a/ogclient/lib/python3/InventoryLib.py b/ogclient/lib/python3/InventoryLib.py index 2269af3..0d0ac6f 100644 --- a/ogclient/lib/python3/InventoryLib.py +++ b/ogclient/lib/python3/InventoryLib.py @@ -115,7 +115,6 @@ def ogIsEfiActive(): def ogListHardwareInfo(): ret = '' - SystemLib.ogEcho ([], 'info', ogGlobals.lang.MSG_HARDWAREINVENTORY) # Ejecutar dmidecode y obtener tipo de chasis dmi_out = subprocess.run (['dmidecode', '-s', 'chassis-type'], capture_output=True, text=True).stdout dmi_out = '\n'.join ([ x for x in dmi_out.splitlines() if 'Other' not in x ]) diff --git a/ogclient/scripts/listHardwareInfo.py b/ogclient/scripts/listHardwareInfo.py index 9f633b1..d702212 100755 --- a/ogclient/scripts/listHardwareInfo.py +++ b/ogclient/scripts/listHardwareInfo.py @@ -1,43 +1,28 @@ -import subprocess +#!/usr/bin/python3 +# Scirpt de ejemplo para almacenear en fichero temporal el listado de hardware. +# Nota: se usa como base para el programa de recogida de listado de hardware de OpenGnsys Admin. +# Formato: listHardwareInfo + import os import sys -sys.path.append('/opt/opengnsys/lib/engine/bin') +import subprocess + +import ogGlobals +from SystemLib import ogRaiseError from NetLib import ogGetIpAddress -sys.path.append('/opt/opengnsys/lib/engine/bin') from InventoryLib import ogListHardwareInfo -def get_server_log_dir(): - # Obtener el directorio de logs del servidor - oglog = os.getenv("OGLOG") - if not oglog: - return "" - result = subprocess.run(["mount"], capture_output=True, text=True) - for line in result.stdout.splitlines(): - parts = line.split() - if len(parts) >= 4 and parts[3] == oglog: - return parts[1] - return "" +prog = sys.argv[0] +if len (sys.argv) > 1: + ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'{ogGlobals.lang.MSG_FORMAT} {prog}') + sys.exit (1) -def list_hardware_info(): - oglog = os.getenv("OGLOG", "/tmp") # Usar /tmp como valor por defecto para OGLOG - ip_address = ogGetIpAddress() - # Fichero de listado de hardware basado en la IP obtenida - hardfile = f"hard-{ogGetIpAddress()}" - print(f"hardfile:{hardfile}") - # Ejecutar ogListHardwareInfo y redirigir al archivo de listado - hardware_info_path = os.path.join(oglog, hardfile) - with open(hardware_info_path, 'w') as output_file: - output_file.write(ogListHardwareInfo()) - - return hardware_info_path - -if __name__ == "__main__": - # Obtener el directorio del servidor donde se exportan los ficheros de registro - server_log_dir = get_server_log_dir() - - # Generar el archivo de listado de hardware y obtener su ruta - hardware_info_path = list_hardware_info() - - # Imprimir la ruta del archivo generado - print(hardware_info_path) +# Directorio del servidor donde se exportan los ficheros de registro. +#SERVERLOGDIR = unused +# Fichero de listado: hard-IP +HARDFILE = f'{ogGlobals.OGLOG}/hard-{ogGetIpAddress()}' +out = ogListHardwareInfo() +with open (HARDFILE, 'w') as fd: + fd.write (out) +print (HARDFILE) From dd19d43c146a910a2e90deec2f77338d2e969c51 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Mon, 10 Mar 2025 11:55:58 +0100 Subject: [PATCH 25/30] refs #1673 add interfaceAdm/InventarioSoftware.py --- ogclient/interfaceAdm/InventarioSoftware.py | 73 +++++++++------------ 1 file changed, 30 insertions(+), 43 deletions(-) diff --git a/ogclient/interfaceAdm/InventarioSoftware.py b/ogclient/interfaceAdm/InventarioSoftware.py index 29f3420..e5185b5 100755 --- a/ogclient/interfaceAdm/InventarioSoftware.py +++ b/ogclient/interfaceAdm/InventarioSoftware.py @@ -1,53 +1,40 @@ #!/usr/bin/env python3 + import os import time import shutil import subprocess import sys -sys.path.append('/opt/opengnsys/lib/engine/bin') import ogGlobals -import SystemLib - -def main(arg1, arg2, dest_file): - start_time = time.time() - - og_log_session = os.getenv(ogGlobals.OGLOGSESSION) - og_log_command = os.getenv(ogGlobals.OGLOGCOMMAND) - if og_log_session and og_log_command: - with open(og_log_session, 'w') as f: - f.write(" ") - with open(og_log_command, 'w') as f: - f.write(" ") - with open(f"{og_log_command}.tmp", 'w') as f: - f.write(" ") - - msg_interface_start = os.getenv(ogGlobals.lang.MSG_INTERFACE_START) - if msg_interface_start: - SystemLib.ogEcho("log", "session", f"{msg_interface_start} {__file__} {arg1} {arg2}") - - try: - result = subprocess.run( - ["python3", "/opt/opengnsys/scripts/listSoftwareInfo.py", arg1, arg2], - capture_output=True, - text=True, - check=True - ) - file = result.stdout.strip().splitlines()[-1] - except subprocess.CalledProcessError as e: - print(f"Error al ejecutar listSoftwareInfo: {e.stderr}") - sys.exit(e.returncode) - - print(f"Copying:( {file} to {dest_file} )") - shutil.copy(file, dest_file) - - elapsed_time = time.time() - start_time - msg_scripts_time_partial = os.getenv(ogGlobals.lang.MSG_SCRIPTS_TIME_PARTIAL) - if msg_scripts_time_partial: - SystemLib.ogEcho("log", "session", f" [ ] {msg_scripts_time_partial} : {int(elapsed_time // 60)}m {int(elapsed_time % 60)}s") +from SystemLib import ogEcho, ogRaiseError if __name__ == "__main__": - if len(sys.argv) != 4: - print("Usage: python InventarioSoftware.py ") - sys.exit(1) - main(sys.argv[1], sys.argv[2], sys.argv[3]) + prog = sys.argv[0] + if len (sys.argv) != 4: + print (f'Usage: {prog} ') + sys.exit (1) + + disk, par, dest_file = sys.argv[1:] + + TIME1 = time.time() + +# Limpia los ficheros temporales usados como log de seguimiento para httpdlog + open (ogGlobals.OGLOGSESSION, 'w').close() + open (ogGlobals.OGLOGCOMMAND, 'w').close() + open (f"{ogGlobals.OGLOGCOMMAND}.tmp", 'w').close() + +# Registro de inicio de ejecución + ogEcho (['log', 'session'], None, f'{ogGlobals.lang.MSG_INTERFACE_START} {prog} {disk} {par} {dest_file}') + + listsi_out = subprocess.run ([f'{ogGlobals.OGSCRIPTS}/listSoftwareInfo.py', disk, par], capture_output=True, text=True).stdout + if listsi_out: + file = listsi_out.splitlines()[0] + else: + ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, 'listSoftwareInfo.py failed') + sys.exit (1) + + shutil.copy (file, dest_file) + + TIME = time.time() - TIME1 + ogEcho(['log', 'session'], None, f' [ ] {ogGlobals.lang.MSG_SCRIPTS_TIME_PARTIAL} : {int(TIME // 60)}m {int(TIME % 60)}s') From c5f30a9dee4b13a0c9314b85049ea10736878f26 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Mon, 10 Mar 2025 11:58:21 +0100 Subject: [PATCH 26/30] refs #1676 add interfaceAdm/Apagar.py --- ogclient/interfaceAdm/Apagar.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/ogclient/interfaceAdm/Apagar.py b/ogclient/interfaceAdm/Apagar.py index eafc875..25545f3 100755 --- a/ogclient/interfaceAdm/Apagar.py +++ b/ogclient/interfaceAdm/Apagar.py @@ -1,10 +1,7 @@ -#!/usr/bin/env python3 +#!/usr/bin/python3 + import os import sys -def main(): - os.system('poweroff') - sys.exit(0) - -if __name__ == "__main__": - main() +os.system ('poweroff') +sys.exit (0) From d7fc4fde408af697fd56b50f5479190e7533503a Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Mon, 10 Mar 2025 12:00:30 +0100 Subject: [PATCH 27/30] refs #1677 add interfaceAdm/Reiniciar.py --- ogclient/interfaceAdm/Reiniciar.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ogclient/interfaceAdm/Reiniciar.py b/ogclient/interfaceAdm/Reiniciar.py index f1b0e25..0cbeedc 100755 --- a/ogclient/interfaceAdm/Reiniciar.py +++ b/ogclient/interfaceAdm/Reiniciar.py @@ -1,8 +1,7 @@ -#!/usr/bin/env python3 +#!/usr/bin/python3 + import os +import sys -def reboot_system(): - os.system('reboot') - -if __name__ == "__main__": - reboot_system() +os.system ('reboot') +sys.exit (0) From f8eaf8859aac694920032e7cf1071941c34b3864 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Mon, 10 Mar 2025 12:49:24 +0100 Subject: [PATCH 28/30] refs #1675 add interfaceAdm/EjecutarScript.py --- ogclient/interfaceAdm/EjecutarScript.py | 78 +++++++++++-------------- 1 file changed, 33 insertions(+), 45 deletions(-) diff --git a/ogclient/interfaceAdm/EjecutarScript.py b/ogclient/interfaceAdm/EjecutarScript.py index 35dde8d..d7b415c 100755 --- a/ogclient/interfaceAdm/EjecutarScript.py +++ b/ogclient/interfaceAdm/EjecutarScript.py @@ -1,62 +1,50 @@ -#!/usr/bin/env python3 +#!/usr/bin/python3 + import os import time import subprocess import sys -import SystemLib + import ogGlobals +from SystemLib import ogEcho, ogRaiseError -#sys.path.append('/opt/opengnsys/lib/engine/bin') -def main(script_path): - start_time = time.time() - print(f"Ejecutando:",script_path) +prog = sys.argv[0] +if len (sys.argv) != 2: + print (f'Usage: {prog} ') + sys.exit (1) - # Load engine configurator from engine.cfg file. - engine_config_path = '/opt/opengnsys/etc/engine.cfg' -# if 'OGENGINECONFIGURATE' not in os.environ: -# with open(engine_config_path) as f: -# exec(f.read(), globals()) +TIME1 = time.time() +script_path = sys.argv[1] - # Clear temporary file used as log track by httpdlog - with open(os.environ['OGLOGSESSION'], 'w') as f: - f.write("") - with open(os.environ['OGLOGCOMMAND'], 'w') as f: - f.write("") +# Clear temporary file used as log track by httpdlog +# Limpia los ficheros temporales usados como log de seguimiento para httpdlog +open (ogGlobals.OGLOGSESSION, 'w').close() +open (ogGlobals.OGLOGCOMMAND, 'w').close() - # Registro de inicio de ejecución - SystemLib.ogEcho('log session', f"{os.environ['MSG_INTERFACE_START']} {sys.argv[0]} {' '.join(sys.argv[1:])}") +# Registro de inicio de ejecución +ogEcho (['log', 'session'], None, f'{ogGlobals.lang.MSG_INTERFACE_START} {prog} {script_path}') - with open(os.environ['OGLOGFILE'], 'a') as log_file: - log_file.write("\n Instrucciones a ejecutar: *****************************\n" - with open(script_path.split()[1]) as script_file: # Obtener solo el nombre del script - log_file.write(script_file.read()) ) +with open (ogGlobals.OGLOGFILE, 'a') as logfd: + with open (script_path) as scriptfd: + logfd.write ('\n Instrucciones a ejecutar: *****************************\n') + logfd.write (scriptfd.read()) - log_file.write("\n Salida de las instrucciones: *****************************\n") + logfd.write ('\n Salida de las instrucciones: *****************************\n') - # Cambiar permisos y ejecutar el script - os.chmod(script_path.split()[1], 0o755) - result = subprocess.run([sys.executable] + script_path.split(), capture_output=True, text=True) - ret_val = result.returncode +os.chmod (script_path, 0o755) +# Si mandamos la salida a OGLOGCOMMAND reescribimos lo que manda el comando. +RETVAL = subprocess.run (script_path, capture_output=True, text=True).returncode - with open(os.environ['OGLOGCOMMAND'], 'a') as log_command_file: - log_command_file.write(result.stdout) - log_command_file.write(result.stderr) - elapsed_time = time.time() - start_time - if ret_val == 0: - SystemLib.ogEcho('log session', f"[100] Duracion de la operacion {int(elapsed_time // 60)}m {int(elapsed_time % 60)}s") - else: - SystemLib.ogRaiseError('log session', ret_val) - SystemLib.ogEcho('log session', 'error "Operacion no realizada"') +TIME = time.time() - TIME1 +if 0 == RETVAL: + ogEcho (['log', 'session'], None, f'[100] Duracion de la operacion {int(TIME // 60)}m {int(TIME % 60)}s') +else: + ogRaiseError (['log', 'session'], RETVAL, '') + ogEcho (['log', 'session'], 'error', 'Operacion no realizada') - # Registro de fin de ejecución - SystemLib.ogEcho('log session', f"{os.environ['MSG_INTERFACE_END']} {ret_val}") +# Registro de fin de ejecución +ogEcho (['log', 'session'], None, f'{ogGlobals.lang.MSG_INTERFACE_END} {RETVAL}') - sys.exit(ret_val) - -if __name__ == "__main__": - if len(sys.argv) != 2: - print("Usage: python EjecutarScript.py ") - sys.exit(1) - main(sys.argv[1]) +sys.exit (RETVAL) From 7165dd552a548ac35bfa6529861761383cf661d0 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Wed, 12 Mar 2025 11:32:26 +0100 Subject: [PATCH 29/30] refs #1672 add interfaceAdm/CrearImagen.py --- ogclient/functions/ogChangeRepo | 3 +- ogclient/interfaceAdm/CambiarAcceso.py | 100 +++++++++-------- ogclient/interfaceAdm/CrearImagen.py | 147 +++++++++++++++---------- ogclient/lib/python3/ImageLib.py | 2 +- ogclient/lib/python3/NetLib.py | 30 ++--- 5 files changed, 154 insertions(+), 128 deletions(-) diff --git a/ogclient/functions/ogChangeRepo b/ogclient/functions/ogChangeRepo index 0a65304..78d08e9 100755 --- a/ogclient/functions/ogChangeRepo +++ b/ogclient/functions/ogChangeRepo @@ -7,7 +7,6 @@ from NetLib import ogChangeRepo parser = argparse.ArgumentParser (add_help=False) parser.add_argument ('ip_repo') -parser.add_argument ('og_unit', nargs='?', default=None) if 2 == len (sys.argv) and 'help' == sys.argv[1]: #parser.print_help() sale en inglés aunque la locale indique otra cosa @@ -16,7 +15,7 @@ if 2 == len (sys.argv) and 'help' == sys.argv[1]: args = parser.parse_args() -ret = ogChangeRepo (args.ip_repo, args.og_unit) +ret = ogChangeRepo (args.ip_repo) if ret is not None: if ret == True: sys.exit (0) elif ret == False: sys.exit (1) diff --git a/ogclient/interfaceAdm/CambiarAcceso.py b/ogclient/interfaceAdm/CambiarAcceso.py index 61fea66..ae8f944 100755 --- a/ogclient/interfaceAdm/CambiarAcceso.py +++ b/ogclient/interfaceAdm/CambiarAcceso.py @@ -1,54 +1,62 @@ -#!/usr/bin/env python3 +#!/usr/bin/python3 + +#______________________________________ +# +# PARAMETROS RECIBIDOS DESDE EL CLIENTE +# $1 modo (admin, user) +#______________________________________ + import os import sys +import re import subprocess -import NetLib -import SystemLib -def main(): - if len(sys.argv) != 2: - print("Usage: CambiarAcceso.py ") - sys.exit(1) +import ogGlobals +from SystemLib import ogEcho, ogRaiseError, ogIsRepoLocked +from NetLib import ogGetRepoIp - mode = sys.argv[1] - repo_ip = NetLib.ogGetRepoIp() +# Error si llamada no se realliza desde OpenGnsys Client. +prog = sys.argv[0] +if len (sys.argv) != 2: + print (f'Usage: {prog} ') + sys.exit (1) - if not repo_ip: - SystemLib.ogRaiseError("OG_ERR_NOTFOUND", "repo no montado") +# Salir si el repositorio está bloquedo (tiene ficheros abiertos). +mode = sys.argv[1] +repoip = ogGetRepoIp() +if not repoip: + ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, 'repo no montado') + sys.exit (1) +if ogIsRepoLocked(): + ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'repo {repoip}') + sys.exit (1) - if SystemLib.ogIsRepoLocked(): - SystemLib.ogRaiseError("OG_ERR_LOCKED", f"repo {repo_ip}") +# Comprobar protocolo y modo de acceso. +proto = os.getenv ('ogprotocol', 'smb') +if proto not in ['nfs', 'smb']: + ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'protocolo desconocido {proto}') + sys.exit (1) +if 'admin' == mode: mount_mode = 'rw' +elif 'user' == mode: mount_mode = 'ro' +else: + ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'modo desconocido {mode}') + sys.exit (1) - proto = os.getenv("ogprotocol", "smb") - if proto not in ["nfs", "smb"]: - SystemLib.ogRaiseError("OG_ERR_FORMAT", f"protocolo desconocido {proto}") - - if mode == "admin": - mount_mode = "rw" - elif mode == "user": - mount_mode = "ro" - else: - SystemLib.ogRaiseError("OG_ERR_FORMAT", f"modo desconocido {mode}") - - OGIMG = os.getenv("OGIMG", "/mnt/OGIMG") - OGUNIT = os.getenv("OGUNIT", "") - if OGUNIT: - OGUNIT = f"/{OGUNIT}" - - subprocess.run(["umount", OGIMG], check=True) - SystemLib.ogEcho("info", f"Montar repositorio {repo_ip} por {proto} en modo {mode}") - - if proto == "nfs": - subprocess.run(["mount", "-t", "nfs", f"{repo_ip}:{OGIMG}{OGUNIT}", OGIMG, "-o", mount_mode], check=True) - elif proto == "smb": - with open("/scripts/ogfunctions", "r") as f: - for line in f: - if "OPTIONS=" in line: - pass_option = line.split("pass=")[1].split()[0] - break - else: - pass_option = "og" - subprocess.run(["mount.cifs", f"//{repo_ip}/ogimages{OGUNIT}", OGIMG, "-o", f"{mount_mode},serverino,acl,username=opengnsys,password={pass_option}"], check=True) - -if __name__ == "__main__": - main() +# Desmontar repositorio y volver a montarlo con el modo adecuado. +subprocess.run (['umount', ogGlobals.OGIMG]) +ogEcho ([], 'info', f'Montar repositorio {repoip} por {proto} en modo {mode}') +if 'nfs' == proto: + subprocess.run (['mount', '-t', 'nfs', f'{repoip}:{ogGlobals.OGIMG}', ogGlobals.OGIMG, '-o', mount_mode]) +elif 'smb' == proto: + pass_option = '' + with open ('/scripts/ogfunctions', 'r') as fd: + while True: + line = fd.readline() + if not line: break + if not re.search ('^[\t ]*(export )?OPTIONS=', line): continue + m = re.search (r'pass=(\w*)', line) + if m: + pass_option = m.groups (0)[0] + break + if not pass_option: pass_option = 'og' + subprocess.run (['mount.cifs', f'//{repoip}/ogimages', ogGlobals.OGIMG, '-o', f'{mount_mode},serverino,acl,username=opengnsys,password={pass_option}']) diff --git a/ogclient/interfaceAdm/CrearImagen.py b/ogclient/interfaceAdm/CrearImagen.py index 29628e0..ea2b096 100755 --- a/ogclient/interfaceAdm/CrearImagen.py +++ b/ogclient/interfaceAdm/CrearImagen.py @@ -1,74 +1,109 @@ -#!/usr/bin/env python3 +#!/usr/bin/python3 + +#___________________________________________________ +# +# PARAMETROS RECIBIDOS DESDE EL CLIENTE: +# $1 Número de disco +# $2 Número de particion +# $3 Nombre canónico de la imagen (sin extensión) +# $4 Dirección del repositorio (REPO, por defecto) +#___________________________________________________ + + +#$OG_ERR_NOTEXEC Si no es llamada por OG client +#$OG_ERR_LOCKED=4 Si la particion está bloqueada. + + +#Codigos de error del scripts createImage +#@exception OG_ERR_FORMAT # 1 formato incorrecto. +#@exception OG_ERR_PARTITION # 3 Error en partición de disco o en su sistema de archivos +#@exception OG_ERR_IMAGE # 5 Error en funcion ogCreateImage o ogRestoreImage. +#@exception OG_ERR_NOTWRITE # 14 error de escritura +#@exception OG_ERR_NOTCACHE # 15 si cache no existe 15 +#@exception OG_ERR_CACHESIZE # 16 si espacio de la cache local o remota no tiene espacio 16 +#@exception OG_ERR_REDUCEFS # 17 error al reducir sistema de archivos. +#@exception OG_ERR_EXTENDFS # 18 Errror al expandir el sistema de archivos. + + +#Códigos de error de la funcion ogCreateImage + import os import subprocess import sys import time -import NetLib + import ogGlobals +from SystemLib import ogEcho, ogRaiseError +from NetLib import ogGetIpAddress, ogChangeRepo +from StringLib import ogCheckIpAddress -def load_engine_config(): - engine_config_path = "/opt/opengnsys/etc/engine.cfg" - if os.path.exists(engine_config_path): - with open(engine_config_path) as f: - exec(f.read(), globals()) +prog = sys.argv[0] +if len (sys.argv) < 4: + ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'Incorrect number of arguments') + sys.exit (1) +disk, par, imgname, *other = sys.argv[1:] +arg_repo = other[0] if len (other) > 0 else 'REPO' +dirname = os.path.dirname (prog) -def clear_temp_logs(): - open(os.getenv('OGLOGSESSION'), 'w').close() - open(os.getenv('OGLOGCOMMAND'), 'w').close() - open(f"{os.getenv('OGLOGCOMMAND')}.tmp", 'w').close() +start_time = time.time() +env_boot = os.getenv ('boot') -def log_session_start(script_name, args): - SystemLib.ogEcho("log session", f"{os.getenv('MSG_INTERFACE_START')} {script_name} {' '.join(args)}") +#Load engine configurator from engine.cfg file. +#Carga el configurador del engine desde el fichero engine.cfg +## (ogGlobals se encarga) -def log_session_end(retval): - SystemLib.ogEcho("log session", f"{os.getenv('MSG_INTERFACE_END')} {retval}") +# Clear temporary file used as log track by httpdlog +# Limpia los ficheros temporales usados como log de seguimiento para httpdlog +open (ogGlobals.OGLOGSESSION, 'w').close() +open (ogGlobals.OGLOGCOMMAND, 'w').close() +open (f"{ogGlobals.OGLOGCOMMAND}.tmp", 'w').close() -def ogCheckIpAddress(ip): - try: - subprocess.check_call(["ping", "-c", "1", ip]) - return 0 - except subprocess.CalledProcessError: - return 1 +# Registro de inicio de ejecución +ogEcho (['log', 'session'], None, f'{ogGlobals.lang.MSG_INTERFACE_START} {prog} {disk} {par} {imgname} {arg_repo}') -def create_image(disk_num, partition_num, repo, image_name): - if subprocess.call(["which", "createImageCustom"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0: - return subprocess.call(["createImageCustom", disk_num, partition_num, repo, f"/{image_name}"]) - else: - return subprocess.call(["createImage", disk_num, partition_num, repo, f"/{image_name}"]) +# Valor por defecto para el repositorio. +repo = arg_repo +if not repo: repo = 'REPO' +if repo == ogGetIpAddress(): repo = 'CACHE' +# Si es una ip y es distinta a la del recurso samba cambiamos de REPO. +if 'REPO' == repo or StringLib.ogCheckIpAddress (repo): + # Si falla el cambio -> salimos con error repositorio no valido + if not ogChangeRepo (repo): + ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, repo) + sys.exit (1) -def main(): - if len(sys.argv) != 5: - sys.exit(SystemLib.ogRaiseError(OG_ERR_FORMAT, "Incorrect number of arguments")) +# Si el destino es REPO y el cliente no está en modo "admin"; activar repositorio para escritura, +if 'REPO' == repo and 'admin' != env_boot: + retval = subprocess.run ([f'{dirname}/CambiarAcceso.py', 'admin']).returncode + if retval: + sys.exit (retval) - disk_num, partition_num, image_name, repo = sys.argv[1:5] +ogEcho ([], None, f'createImage "{disk}" "{par}" "{arg_repo}" /"{imgname}"') +# Si existe, ejecuta script personalizado "createImageCustom"; si no, llama al genérico "createImage". +if os.path.exists ('{ogGlobals.OGSCRIPTS}/createImageCustom.py'): + script = f'{ogGlobals.OGSCRIPTS}/createImageCustom.py' +else: + script = f'{ogGlobals.OGSCRIPTS}/createImage.py' - start_time = time.time() +with open (ogGlobals.OGLOGCOMMAND, 'a') as fd: + p = subprocess.Popen ([script, disk, par, arg_repo, f'/{imgname}'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + while p.poll() is None: + for l in iter (p.stdout.readline, b''): + partial = l.decode ('utf-8', 'ignore') + fd.write (partial) + print (partial, end='') ## so that the agent captures out output and reports progress to ogcore + for l in iter (p.stderr.readline, b''): + partial = l.decode ('utf-8', 'ignore') + fd.write (partial) + print (partial, end='') +retval = p.returncode - load_engine_config() - clear_temp_logs() - log_session_start(sys.argv[0], sys.argv[1:]) +# Cambiar acceso a modo usuario, si es necesario. +if 'REPO' == repo and 'admin' != env_boot: + subprocess.run ([f'{dirname}/CambiarAcceso.py', 'user']) - repo = repo if repo else "REPO" - if repo == NetLib.ogGetIpAddress(): - repo = "CACHE" +# Registro de fin de ejecución +ogEcho (['log', 'session'], None, f'{ogGlobals.lang.MSG_INTERFACE_END} {retval}') - if ogCheckIpAddress(repo) == 0 or repo == "REPO": - OGUNIT = os.getenv('OGUNIT', "") - if not NetLib.ogChangeRepo(repo, OGUNIT): - sys.exit(SystemLib.ogRaiseError(OG_ERR_NOTFOUND, f"{repo}")) +sys.exit (retval) - if repo == "REPO" and os.getenv('boot') != "admin": - retval = CambiarAcceso("admin") - if retval > 0: - sys.exit(retval) - - retval = create_image(disk_num, partition_num, repo, image_name) - - if repo == "REPO" and os.getenv('boot') != "admin": - CambiarAcceso("user") - - log_session_end(retval) - sys.exit(retval) - -if __name__ == "__main__": - main() diff --git a/ogclient/lib/python3/ImageLib.py b/ogclient/lib/python3/ImageLib.py index 2b5fc8c..647b341 100644 --- a/ogclient/lib/python3/ImageLib.py +++ b/ogclient/lib/python3/ImageLib.py @@ -233,7 +233,7 @@ def ogCreateImage (disk, par, container, imgfile, tool='partclone', level='gzip' bn = os.path.basename (imgfile) IMGFILE = f'{imgdir}/{bn}.{imgtype}' - if ogIsImageLocked (IMGFILE): + if ogIsImageLocked (container=None, imgfile=IMGFILE): SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{ogGlobals.lang.MSG_IMAGE} {container}, {imgfile}') return None diff --git a/ogclient/lib/python3/NetLib.py b/ogclient/lib/python3/NetLib.py index e36f863..5bd7cc5 100644 --- a/ogclient/lib/python3/NetLib.py +++ b/ogclient/lib/python3/NetLib.py @@ -39,48 +39,32 @@ def _ogConnect (server, protocol, src, dst, options, readonly): #@param 2 Abreviatura Unidad Organizativa #@return Cambio recurso remoto en OGIMG. #*/ -def ogChangeRepo(ip_repo, og_unit=None): - ogprotocol = os.environ['ogprotocol'] or 'smb' - - if og_unit: - SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, 'the og_unit parameter became unsupported') - return None +def ogChangeRepo (ip_repo): + ogprotocol = os.environ.get ('ogprotocol', 'smb') try: mount = subprocess.run (['mount'], capture_output=True, text=True).stdout ro = bool (list (filter (lambda line: re.search (r'ogimages.*\bro,', line), mount.splitlines()))) current_repo = ogGetRepoIp() - new_repo = current_repo if ip_repo.upper() == "REPO" else ip_repo + new_repo = current_repo if ip_repo.upper() == 'REPO' else ip_repo if new_repo == current_repo: return True - subprocess.run(["umount", ogGlobals.OGIMG], check=True) + subprocess.run (['umount', ogGlobals.OGIMG], check=True) SystemLib.ogEcho (['session', 'log'], None, f'{ogGlobals.lang.MSG_HELP_ogChangeRepo} {new_repo}') options = _ogConnect_options() if not _ogConnect (new_repo, ogprotocol, 'ogimages', ogGlobals.OGIMG, options, ro): _ogConnect (current_repo, ogprotocol, 'ogimages', ogGlobals.OGIMG, options, ro) - SystemLib.ogRaiseError( - "session", - ogGlobals.OG_ERR_REPO, - f"Error connecting to the new repository: {new_repo}", - ) + SystemLib.ogRaiseError ('session', ogGlobals.OG_ERR_REPO, f'Error connecting to the new repository: {new_repo}') return False - SystemLib.ogEcho( - ["session", "log"], - None, - f"Repository successfully changed to {new_repo}".strip(), - ) + SystemLib.ogEcho (['session', 'log'], None, f'Repository successfully changed to {new_repo}'.strip()) return True except Exception as e: - SystemLib.ogRaiseError( - "session", - ogGlobals.OG_ERR_GENERIC, - f"Error executing ogChangeRepo: {e}", - ) + SystemLib.ogRaiseError ('session', ogGlobals.OG_ERR_GENERIC, f'Error executing ogChangeRepo: {e}') return None #/** From caec7bfc0856c2c047d953f86b2b9546fa53b60a Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Wed, 19 Mar 2025 11:30:19 +0100 Subject: [PATCH 30/30] refs #1699 add ogBoot --- ogclient/functions/ogBoot | 45 +++++++++ ogclient/lib/python3/BootLib.py | 165 ++++++++++++++++++++++++++++++++ ogclient/lib/python3/UEFILib.py | 20 ++-- 3 files changed, 219 insertions(+), 11 deletions(-) create mode 100755 ogclient/functions/ogBoot diff --git a/ogclient/functions/ogBoot b/ogclient/functions/ogBoot new file mode 100755 index 0000000..23756c1 --- /dev/null +++ b/ogclient/functions/ogBoot @@ -0,0 +1,45 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogBoot + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogBoot', 'ogBoot int_ndisk int_nfilesys [ NVRAMPERM ] [str_kernel str_initrd str_kernelparams]', ['ogBoot 1 2 "/boot/vmlinuz /boot/initrd.img root=/dev/sda2 ro"', 'ogBoot 1 2 NVRAMPERM']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 3 == len (sys.argv): + parser.add_argument ('disk') + parser.add_argument ('par') +elif 4 == len (sys.argv): + parser.add_argument ('disk') + parser.add_argument ('par') + parser.add_argument ('nvramperm_or_params') +elif 5 == len (sys.argv): + parser.add_argument ('disk') + parser.add_argument ('par') + parser.add_argument ('nvramperm') + parser.add_argument ('params') + +args = parser.parse_args() + +if 3 == len (sys.argv): + ret = ogBoot (args.disk, args.par) +elif 4 == len (sys.argv): + if 'NVRAMPERM' == args.nvramperm_or_params.upper(): + nvramperm = True + params = '' + else: + nvramperm = False + params = args.nvramperm_or_params + ret = ogBoot (args.disk, args.par, nvramperm, params) +elif 5 == len (sys.argv): + ret = ogBoot (args.disk, args.par, not not args.nvramperm, args.params) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/ogclient/lib/python3/BootLib.py b/ogclient/lib/python3/BootLib.py index dd1da9a..7bf91b6 100644 --- a/ogclient/lib/python3/BootLib.py +++ b/ogclient/lib/python3/BootLib.py @@ -39,6 +39,168 @@ import CacheLib #@note En Linux, si no se indican los parámetros de arranque se detectan de la opción por defecto del cargador GRUB. #@note En Linux, debe arrancarse la partición del directorio \c /boot #*/ ## +def ogBoot (disk, par, nvramperm=False, params=''): +# Detectar tipo de sistema de archivos y montarlo. + part = DiskLib.ogDiskToDev (disk, par) + if not part: return None + type = InventoryLib.ogGetOsType (disk, par) + if not type: return None +# Error si no puede montar sistema de archivos. + mntdir = FileSystemLib.ogMount (disk, par) + if not mntdir: return None + #params = None + #if 'NVRAMPERM' == nvramperm.upper(): + # nvramperm = True + #else: + # params = nvramperm + # nvramperm = False + + if 'Linux' == type or 'Android' == type: + # Si no se indican, obtiene los parámetros de arranque para Linux. + if not params: + params = ogLinuxBootParameters (disk, par) + # Si no existe y el UEFI buscar en particion ESP + if not params and InventoryLib.ogIsEfiActive(): + esp = DiskLib.ogGetEsp() + efidisk, efipart = esp.split() + params = ogLinuxBootParameters (efidisk, efipart) + params += ' ' + esp + # Si no existe, buscar sistema de archivo /boot en /etc/fstab. + if not params and os.path.exists (f'{mntdir}/etc/fstab'): + # Localizar S.F. /boot en /etc/fstab del S.F. actual. + dev = None + with open (f'{mntdir}/etc/fstab', 'r') as fd: + while True: + l = fd.readline() + if not l: break + parts = l.split() + if '#' != parts[0] and '/boot' == parts[1]: + dev = parts[0] + break + if dev: + fstab_part = DiskLib.ogDevToDisk (dev) + else: + return None + # Montar S.F. de /boot. + fstab_disk, fstab_par = fstab_part.split() + mntdir = FileSystemLib.ogMount (fstab_disk, fstab_par) + if not mntdir: return None + # Buscar los datos de arranque. + params = ogLinuxBootParameters (fstab_disk, fstab_par) + kernel = initrd = append = None + if params: + kernel, initrd, append = params.split (maxsplit=2) + # Si no hay kernel, no hay sistema operativo. + if not kernel or not os.path.exists (f'{mntdir}/{kernel}'): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, f'{disk} {par} ({type})') + return None + # Arrancar de partición distinta a la original. + if os.path.exists (f'{mntdir}/etc'): + append = re.sub ('root=[-+=_/a-zA-Z0-9]* ', f'root={part} ', append) + # Comprobar tipo de sistema. + if InventoryLib.ogIsEfiActive(): + # Comprobar si el Kernel está firmado. + file_out = subprocess.run (['file', '-k', f'{mntdir}/{kernel}'], capture_output=True, text=True).stdout + if not file_out or not 'EFI app' in file_out: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, f'{disk} {par} ({type}, EFI)') + return None + + bootlabel = f'Part-{int(disk):02d}-{int(par):02d}' + bootloader = 'shimx64.efi' + # Obtener parcición EFI. + esp = DiskLib.ogGetEsp() + #efidisk, efipart = esp.split() + # TODO: Comprobamos que existe la BOOTLABEL, si no buscamos por sistema operativo + if '' == FileLib.ogGetPath (src=esp, file=f'EFI/{bootlabel}'): + osversion = InventoryLib.ogGetOsVersion (disk, par) + if 'SUSE' in osversion: + bootlabel = 'opensuse' + elif 'Fedora' in osversion: + bootlabel = 'fedora' + elif 'Ubuntu' in osversion: + bootlabel = 'ubuntu' + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{esp} Boot loader') + return None + + # Crear orden de arranque (con unos valores por defecto). + UEFILib.ogNvramAddEntry (bootlabel, f'/EFI/{bootlabel}/Boot/{bootloader}', nvramperm) + # Marcar próximo arranque y reiniciar. + UEFILib.ogNvramSetNext (bootlabel) + subprocess.run (['reboot']) + else: + # Arranque BIOS: configurar kernel Linux con los parámetros leídos de su GRUB. + subprocess.run (['kexec', '-l', f'{mntdir}{kernel}', f'--append={append}', f'--initrd={mntdir}{initrd}']) + subprocess.Popen (['kexec', '-e']) + elif 'Windows' == type: + # Comprobar tipo de sistema. + if InventoryLib.ogIsEfiActive(): + bootlabel = f'Part-{int(disk):02d}-{int(par):02d}' + # Obtener parcición EFI. + esp = DiskLib.ogGetEsp() + efidisk, efipart = esp.split() + if not efipart: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'ESP') + return None + efidir = FileSystemLib.ogMount (efidisk, efipart) + if not efidir: return None + # Comprobar cargador (si no existe buscar por defecto en ESP). + loader = FileLib.ogGetPath (file=f'{efidir}/EFI/{bootlabel}/Boot/bootmgfw.efi') + if not loader: + bootlabel = 'Microsoft' + loader = FileLib.ogGetPath (file=f'{efidir}/EFI/Microsoft/Boot/bootmgfw.efi') + if not loader: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, f'{disk} {par} ({type}, EFI)') + return None + + # Crear orden de arranque (con unos valores por defecto). + l = re.sub ('^.*EFI(.*)$', r'\1', loader) + UEFILib.ogNvramAddEntry (bootlabel, l, nvramperm) + # Marcar próximo arranque y reiniciar. + UEFILib.ogNvramSetNext (bootlabel) + subprocess.run (['reboot']) + else: + # Arranque BIOS: comprueba si hay un cargador de Windows. + for f in ['io.sys', 'ntldr', 'bootmgr']: + file = FileLib.ogGetPath (src=f'{disk} {par}', file=f) + if file: loader=f + if not loader: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, f'{disk} {par} ({type})') + return None + winboot = os.environ.get ('winboot', '') + if 'kexec' == winboot: + # Modo de arranque en caliente (con kexec). + for f in glob.glob (f'{ogGlobals.OGLIB}/grub4dos/*'): + shutil.copy2 (f, mntdir) + disk0 = int(disk)-1 + par0 = int(par)-1 + subprocess.run (['kexec', '-l', f'{mntdir}/grub.exe', '--append=--config-file=root (hd{disk0},{par0}); chainloader (hd{disk0},{par0})/{loader}; tpm --init']) + subprocess.Popen (['kexec', '-e']) + else: + # Modo de arranque por reinicio (con reboot). + subprocess.run (['dd', 'if=/dev/zero', f'of={mntdir}/ogboot.me', 'bs=1024', 'count=3']) + subprocess.run (['dd', 'if=/dev/zero', f'of={mntdir}/ogboot.firstboot', 'bs=1024', 'count=3']) + subprocess.run (['dd', 'if=/dev/zero', f'of={mntdir}/ogboot.secondboot', 'bs=1024', 'count=3']) + v = RegistryLib.ogGetRegistryValue (mntdir, 'SOFTWARE', r'\Microsoft\Windows\CurrentVersion\Run\ogcleannboot') + if not v: + RegistryLib.ogAddRegistryValue (mntdir, 'SOFTWARE', r'\Microsoft\Windows\CurrentVersion\Run\ogcleanboot') + RegistryLib.ogSetRegistryValue (mntdir, 'SOFTWARE', r'\Microsoft\Windows\CurrentVersion\Run\ogcleanboot', r'cmd /c del c:\ogboot.*') + # Activar la partición. + DiskLib.ogSetPartitionActive (disk, par) + subprocess.run (['reboot']) + elif 'MacOS' == type: + # Modo de arranque por reinicio. + # Nota: el cliente tiene que tener configurado correctamente Grub. + if not os.path.exists (f'{mntdir}/boot.mac'): + open (f'{mntdir}/boot.mac', 'w').close() + subprocess.run (['reboot']) + elif 'GrubLoader' == type: + # Reiniciar. + #subprocess.run (['reboot']) + pass + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, f'{disk} {par} ({type})') + return None #/** @@ -492,6 +654,9 @@ def ogGrubInstallMbr (disk, par, checkos='FALSE', kernelparam=''): if InventoryLib.ogIsEfiActive(): esp = DiskLib.ogGetEsp() + if not esp: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'ESP') + return None efidisk, efipart = esp.split() # Comprobamos que exista ESP y el directorio para ubuntu efisecondstage = FileSystemLib.ogMount (efidisk, efipart) diff --git a/ogclient/lib/python3/UEFILib.py b/ogclient/lib/python3/UEFILib.py index 94eebf2..3e61486 100644 --- a/ogclient/lib/python3/UEFILib.py +++ b/ogclient/lib/python3/UEFILib.py @@ -42,8 +42,8 @@ def ogNvramActiveEntry (entry): numentries.append (words[0][4:8]) except ValueError: for l in efibootmgr_out.splitlines(): - words = l.split (maxsplit=1) - if len(words) < 2: continue + words = l.split (maxsplit=2) + if len(words) < 3: continue if words[1] == entry: numentries.append (words[0][4:8]) @@ -135,8 +135,6 @@ def ogCopyEfiBootLoader (disk, par): bootlabel = f'Part-{int(disk):02d}-{int(par):02d}' osversion = InventoryLib.ogGetOsVersion (disk, par) - print (f'bootlabel ({bootlabel})') - print (f'osversion ({osversion})') if 'Windows 1' in osversion: loader = None for i in f'{efidir}/EFI/Microsoft/Boot/bootmgfw.efi', f'{efidir}/EFI/{bootlabel}/Boot/bootmgfw.efi': @@ -180,8 +178,8 @@ def ogNvramDeleteEntry (entry): numentries.append (words[0][4:8]) except ValueError: for l in efibootmgr_out.splitlines(): - words = l.split (maxsplit=1) - if len(words) < 2: continue + words = l.split (maxsplit=2) + if len(words) < 3: continue if words[1] == entry: numentries.append (words[0][4:8]) @@ -325,8 +323,8 @@ def ogNvramInactiveEntry (entry): numentries.append (words[0][4:8]) except ValueError: for l in efibootmgr_out.splitlines(): - words = l.split (maxsplit=1) - if len(words) < 2: continue + words = l.split (maxsplit=2) + if len(words) < 3: continue if words[1] == entry: numentries.append (words[0][4:8]) @@ -487,8 +485,8 @@ def ogNvramSetNext (entry): numentries.append (words[0][4:8]) except ValueError: for l in efibootmgr_out.splitlines(): - words = l.split (maxsplit=1) - if len(words) < 2: continue + words = l.split (maxsplit=2) + if len(words) < 3: continue if words[1] == entry: numentries.append (words[0][4:8]) @@ -496,7 +494,7 @@ def ogNvramSetNext (entry): SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'NVRAM entry "{entry}"') return - if 1 != len(numentries): + if 1 != len (numentries): SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, f'more than one entry found') return