From a5a0b2bdb7ff2340d35b4394b26693913239f9e3 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Wed, 19 Mar 2025 13:14:35 +0100 Subject: [PATCH 1/3] refs #1728 move ogGetIpAddress around --- ogclient/interfaceAdm/getIpAddress.py | 11 +++-------- ogclient/lib/python3/NetLib.py | 24 +----------------------- ogclient/lib/python3/ogGlobals.py | 27 +++++++++++++++++++++++++-- ogclient/scripts/getIpAddress.py | 16 ---------------- 4 files changed, 29 insertions(+), 49 deletions(-) delete mode 100755 ogclient/scripts/getIpAddress.py diff --git a/ogclient/interfaceAdm/getIpAddress.py b/ogclient/interfaceAdm/getIpAddress.py index 0ba1389..cc18939 100755 --- a/ogclient/interfaceAdm/getIpAddress.py +++ b/ogclient/interfaceAdm/getIpAddress.py @@ -1,10 +1,5 @@ -#!/usr/bin/env python3 -import socket +#!/usr/bin/python3 -def get_ip_address(): - hostname = socket.gethostname() - ip_address = socket.gethostbyname(hostname) - return ip_address +from NetLib import ogGetIpAddress -if __name__ == "__main__": - print(get_ip_address()) +ogGetIpAddress() diff --git a/ogclient/lib/python3/NetLib.py b/ogclient/lib/python3/NetLib.py index 5bd7cc5..e356a45 100644 --- a/ogclient/lib/python3/NetLib.py +++ b/ogclient/lib/python3/NetLib.py @@ -142,29 +142,7 @@ def ogGetHostname(): #@note Usa las variables utilizadas por el initrd "/etc/net-ethX.conf #*/ ## def ogGetIpAddress(): - if "IPV4ADDR" in os.environ: - ip = os.environ["IPV4ADDR"] - if '/' in ip: ip = ip.split ('/')[0] - return ip - - extra_args = [] - if "DEVICE" in os.environ: - extra_args = [ "dev", os.environ["DEVICE"] ] - ipas = subprocess.run (['ip', '-json', 'address', 'show', 'up'] + extra_args, capture_output=True, text=True).stdout - - ipasj = json.loads (ipas) - addresses = [] - for e in ipasj: - if 'lo' == e['ifname']: continue - if 'addr_info' not in e: continue - addrs = e['addr_info'] - for a in addrs: - if 'inet' != a['family']: continue - addresses.append ({ 'local': a['local'], 'prefixlen': a['prefixlen'] }) - - if 1 != len (addresses): - raise Exception ('more than one local IP address found') - return addresses[0] + return ogGlobals.ogGetIpAddress() #/** diff --git a/ogclient/lib/python3/ogGlobals.py b/ogclient/lib/python3/ogGlobals.py index c744b2c..7e978fc 100644 --- a/ogclient/lib/python3/ogGlobals.py +++ b/ogclient/lib/python3/ogGlobals.py @@ -7,8 +7,31 @@ import locale import importlib.util ## required for defining OGLOGFILE -import NetLib -ip = NetLib.ogGetIpAddress() +def ogGetIpAddress(): + if "IPV4ADDR" in os.environ: + ip = os.environ["IPV4ADDR"] + if '/' in ip: ip = ip.split ('/')[0] + return ip + + extra_args = [] + if "DEVICE" in os.environ: + extra_args = [ "dev", os.environ["DEVICE"] ] + ipas = subprocess.run (['ip', '-json', 'address', 'show', 'up'] + extra_args, capture_output=True, text=True).stdout + + ipasj = json.loads (ipas) + addresses = [] + for e in ipasj: + if 'lo' == e['ifname']: continue + if 'addr_info' not in e: continue + addrs = e['addr_info'] + for a in addrs: + if 'inet' != a['family']: continue + addresses.append ({ 'local': a['local'], 'prefixlen': a['prefixlen'] }) + + if 1 != len (addresses): + raise Exception ('more than one local IP address found') + return addresses[0] +ip = ogGetIpAddress() def load_lang (name): global lang diff --git a/ogclient/scripts/getIpAddress.py b/ogclient/scripts/getIpAddress.py deleted file mode 100755 index 65f62aa..0000000 --- a/ogclient/scripts/getIpAddress.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python3 -import sys -import NetLib - -def get_ip_address(*args): - try: - # Llama a ogGetIpAddress desde NetLib y captura el resultado - result = NetLib.ogGetIpAddress(*args) - print(result.strip()) - except Exception as e: - print(f"Error ejecutando ogGetIpAddress: {e}", file=sys.stderr) - sys.exit(1) - -if __name__ == "__main__": - get_ip_address(*sys.argv[1:]) - -- 2.40.1 From 5d0f041759c9dd560a73b9a7153ffa4d55f4e6b6 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Wed, 19 Mar 2025 13:16:07 +0100 Subject: [PATCH 2/3] refs #1729 add interfaceAdm/getConfiguration.py --- ogclient/interfaceAdm/getConfiguration.py | 166 +++++++++++++--------- 1 file changed, 96 insertions(+), 70 deletions(-) diff --git a/ogclient/interfaceAdm/getConfiguration.py b/ogclient/interfaceAdm/getConfiguration.py index 89a1b0a..786fc84 100755 --- a/ogclient/interfaceAdm/getConfiguration.py +++ b/ogclient/interfaceAdm/getConfiguration.py @@ -1,80 +1,106 @@ -#!/usr/bin/env python3 +#!/usr/bin/python3 + +#_______________________________________________________________________________________________________________________________ +# +# Formato de salida: +# disk=Número de disco\tpar=Número de particion\tcod=Código de partición\tsfi=Sistema de ficheros\tsoi=Sistema instalado\ttam=Tamaño de la partición\n +#_______________________________________________________________________________________________________________________________ + import os +import glob import subprocess -def run_command(command): - result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - return result.stdout.decode().strip() +from InventoryLib import ogGetSerialNumber, ogGetOsVersion +from DiskLib import ogDiskToDev, ogGetPartitionsNumber, ogGetPartitionTableType, ogGetDiskSize, ogGetPartitionId, ogGetPartitionSize +from FileSystemLib import ogMount, ogGetMountPoint, ogGetFsType -def main(): - # No registrar los errores. - os.environ["DEBUG"] = "no" +# No registrar los errores. +#os.environ['DEBUG'] = 'no' - ser = run_command("ogGetSerialNumber") - cfg = "" - disks = int(run_command("ogDiskToDev | wc -w")) +ser = ogGetSerialNumber() +cfg = '' +disks = len (ogDiskToDev()) - for dsk in range(1, disks + 1): - particiones = run_command(f"ogGetPartitionsNumber {dsk}") - particiones = int(particiones) if particiones else 0 - ptt = run_command(f"ogGetPartitionTableType {dsk}") - - ptt_map = { - "MSDOS": 1, - "GPT": 2, - "LVM": 3, - "ZPOOL": 4 - } - ptt = ptt_map.get(ptt, 0) - - cfg += f"{dsk}:0:{ptt}:::{run_command(f'ogGetDiskSize {dsk}')}:0;" - - for par in range(1, particiones + 1): - cod = run_command(f"ogGetPartitionId {dsk} {par} 2>/dev/null") - fsi = run_command(f"getFsType {dsk} {par} 2>/dev/null") or "EMPTY" - tam = run_command(f"ogGetPartitionSize {dsk} {par} 2>/dev/null") or "0" - soi = "" - uso = 0 - - if fsi not in ["", "EMPTY", "LINUX-SWAP", "LINUX-LVM", "ZVOL"]: - if run_command(f"ogMount {dsk} {par} 2>/dev/null"): - soi = run_command(f"getOsVersion {dsk} {par} 2>/dev/null").split(":")[1] - if not soi: - soi = run_command(f"getOsVersion {dsk} {par} 2>/dev/null").split(":")[1] - if not soi and fsi not in ["EMPTY", "CACHE"]: - soi = "DATA" - uso = int(run_command(f"df $(ogGetMountPoint {dsk} {par}) | awk '{{getline; printf \"%d\",$5}}'") or 0) - else: - soi = "" - uso = 0 - - cfg += f"{dsk}:{par}:{cod}:{fsi}:{soi}:{tam}:{uso};" - - if not cfg: - cfg = "1:0:0:::0;" - - cfgfile = "/tmp/getconfig" - with open(cfgfile, "w") as f: - f.write(f"{ser + ';' if ser else ''}{cfg}") - - run_command("generateMenuDefault &>/dev/null") - - with open(cfgfile, "r") as f: - data = f.read() - - lines = data.split(";") - for line in lines: - if line: - parts = line.split(":") - if len(parts) == 1: - print(f"ser={parts[0]}") +for dsk in range (1, disks+1): + particiones = ogGetPartitionsNumber (dsk) + particiones = int (particiones) if particiones else 0 + # Tipo de tabla de particiones: 1=MSDOS, 2=GPT + ptt = ogGetPartitionTableType (dsk) + ptt_map = { + 'MSDOS': 1, + 'GPT': 2, + 'LVM': 3, + 'ZPOOL': 4, + } + ptt = ptt_map.get (ptt, 0) + # Información de disco (partición 0) + s = ogGetDiskSize (dsk) + cfg += f'{dsk}:0:{ptt}:::{s}:0;' + for par in range (1, particiones+1): + # Código del identificador de tipo de partición + cod = ogGetPartitionId (dsk, par) + # Tipo del sistema de ficheros + fsi = ogGetFsType (dsk, par) + if not fsi: fsi = 'EMPTY' + # Tamaño de la particón + tam = ogGetPartitionSize (dsk, par) + if not tam: tam = '0' + # Sistema operativo instalado + soi = '' + uso = '0' + if fsi not in ['', 'EMPTY', 'LINUX-SWAP', 'LINUX-LVM', 'ZVOL']: + if ogMount (dsk, par): + soi = ogGetOsVersion (dsk, par) + # Hacer un 2º intento para algunos casos especiales. + if not soi: + soi = ogGetOsVersion (dsk, par) + if not soi: soi = '' + if soi: soi = soi.split (':')[1] + # Sistema de archivos para datos (sistema operativo "DATA") + if not soi and fsi not in ['EMPTY', 'CACHE']: + soi = 'DATA' + # Obtener porcentaje de uso. + mntpt = ogGetMountPoint (dsk, par) + uso = subprocess.run (['df', mntpt], capture_output=True, text=True).stdout.splitlines()[-1].split()[4].replace ('%', '') + if not uso: uso = '0' else: - print(f"disk={parts[0]}\tpar={parts[1]}\tcpt={parts[2]}\tfsi={parts[3]}\tsoi={parts[4]}\ttam={parts[5]}\tuso={parts[6]}") + soi = '' + uso = '0' - run_command("rm -f /mnt/*/ogboot.* /mnt/*/*/ogboot.*") + cfg += f'{dsk}:{par}:{cod}:{fsi}:{soi}:{tam}:{uso};' - # Volver a registrar los errores. - os.environ.pop("DEBUG", None) +# Crear configuración por defecto para cliente sin disco. +if not cfg: + cfg = '1:0:0:::0;' + +# Guardar salida en fichero temporal. +cfgfile = '/tmp/getconfig' +with open (cfgfile, 'w') as f: + if ser: f.write (f'{ser};\n') + f.write (cfg + '\n') + +# Crear el menú por defecto a partir del fichero generado (no dar ninguna salida). +#subprocess.run ([f'{ogGlobals.OGSCRIPTS}/generateMenuDefault']) + +# Componer salida formateada. +awk_script = r'''{ n=split($0,sep,";"); + for (i=1; i Date: Thu, 20 Mar 2025 09:58:47 +0100 Subject: [PATCH 3/3] refs #1679 add forgotten script bootOs.py, fix a bug --- CHANGELOG.md | 12 +++-- ogclient/interfaceAdm/getConfiguration.py | 1 - ogclient/interfaceAdm/getIpAddress.py | 2 +- ogclient/scripts/bootOs.py | 58 +++++++++++++++++++++++ 4 files changed, 66 insertions(+), 7 deletions(-) create mode 100755 ogclient/scripts/bootOs.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 627dccd..5796462 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,14 @@ -# Changelog +# Changelog -## [0.1.1] - 2025-02-28 +## [0.1.1] - 2025-03-19 -### Changed - 2025-03-19 +### Added + +- Missing functions in BootLib +- Some interfaceAdm python scripts ## [0.1.0] - 2025-02-28 -### Addded +### Added - Merge pull request 'Include all client files, build debian package' (#2) from deb-package into main - diff --git a/ogclient/interfaceAdm/getConfiguration.py b/ogclient/interfaceAdm/getConfiguration.py index 786fc84..b51d2e9 100755 --- a/ogclient/interfaceAdm/getConfiguration.py +++ b/ogclient/interfaceAdm/getConfiguration.py @@ -94,7 +94,6 @@ awk_script = r'''{ n=split($0,sep,";"); } } ''' -print (f'nati awk_script ({awk_script})') subprocess.run (['awk', awk_script, cfgfile]) # Borramos marcas de arranque de Windows diff --git a/ogclient/interfaceAdm/getIpAddress.py b/ogclient/interfaceAdm/getIpAddress.py index cc18939..18d5150 100755 --- a/ogclient/interfaceAdm/getIpAddress.py +++ b/ogclient/interfaceAdm/getIpAddress.py @@ -2,4 +2,4 @@ from NetLib import ogGetIpAddress -ogGetIpAddress() +print (ogGetIpAddress()) diff --git a/ogclient/scripts/bootOs.py b/ogclient/scripts/bootOs.py new file mode 100755 index 0000000..28357ed --- /dev/null +++ b/ogclient/scripts/bootOs.py @@ -0,0 +1,58 @@ +#!/usr/bin/python3 +# Script de ejemplo para arancar un sistema operativo instalado. +# Nota: se usa como base para el programa de arranque de OpenGnsys Admin. + +import sys +import re +import subprocess +import shutil + +import ogGlobals +from SystemLib import ogRaiseError, ogEcho +from DiskLib import ogDiskToDev +from FileSystemLib import ogMount, ogUnmount, ogCheckFs, ogUnmountAll +from CacheLib import ogUnmountCache +from BootLib import ogBoot + +prog = sys.argv[0] +if len (sys.argv) < 3 or len (sys.argv) > 4: + ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Formato: {prog} ndisco nfilesys [str_kernel str_initrd str_kernelparams]') + sys.exit (1) +disk, par, *other = sys.argv[1:] +params = other[0] if len (other) > 0 else '' + +# Comprobar errores. +part = ogDiskToDev (disk, par) +if not part: sys.exit (1) +mntdir = ogMount (disk, par) +if not mntdir: sys.exit (1) + +print ('[0] Inicio del proceso de arranque.') + +# Si el equipo está hibernado chequeamos el f.s. y borramos el hiberfile (error cod.6) +mount_out = subprocess.run (['mount'], capture_output=True, text=True).stdout +if not mount_out or not re.search (rf'{mntdir}.*\(rw', mount_out): + ogEcho (['log', 'session'], None, f'{ogGlobals.lang.MSG_WARNING}: {ogGlobals.lang.MSG_MOUNTREADONLY}') + ogUnmount (disk, par) + ogCheckFs (disk, par) + + part = ogDiskToDev (disk, par) + os.makedirs (mntdir, exist_ok=True) + subprocess.run (['ntfs-3g', '-o', 'remove_hiberfile', part, mntdir]) + ogEcho (['log', 'session'], None, 'Particion desbloqueada') + + ogUnmount (disk, par) + ogMount (disk, par) + +if shutil.which ('bootOsCustom.py'): + print ('[10] Configuración personalizada del inicio.') + subprocess.run ([f'{ogGlobals.OGSCRIPTS}/bootOsCustom.py']) + +print ('[70] Desmontar todos los sistemas de archivos.') +subprocess.run (['sync']) +for i in range (1, 1+len(ogDiskToDev())): + ogUnmountAll (i) +print ('[80] Desmontar cache local.') +ogUnmountCache() +print (f'[90] Arrancar sistema operativo.') +ogBoot (disk, par, params=params) -- 2.40.1