From 76f373af779e4306086d7e6818d1811e273f3597 Mon Sep 17 00:00:00 2001 From: Antonio Emmanuel Guerrero Silva Date: Sun, 27 Oct 2024 20:32:42 -0600 Subject: [PATCH] refs #1051 Revision and correction of errors in the GetConfiguration.py file --- client/interfaceAdm/Apagar.py | 6 +- client/interfaceAdm/EjecutarScript.py | 68 +++--- client/interfaceAdm/GetConfiguration.py | 88 ++++++++ client/interfaceAdm/GetIpAddress.py | 11 + client/interfaceAdm/Reiniciar.py | 2 +- client/shared/scripts/bootOS.py | 58 ++++++ client/shared/scripts/bootOSCustomTemplate.py | 101 +++++++++ client/shared/scripts/buildToOrder.py | 65 ++++++ .../scripts/configureOSCustomTemplate.py | 78 +++++++ .../scripts/createImageCustomTemplate..py | 27 +++ .../shared/scripts/createLogicalPartitions.py | 1 + .../shared/scripts/createPrimaryPartitions.py | 5 + client/shared/scripts/deployImage.py | 139 +++++++++++++ client/shared/scripts/formatFs.py | 30 +++ client/shared/scripts/generateMenuDefault.py | 92 ++++++++ client/shared/scripts/getFsType.py | 5 + client/shared/scripts/getIpAddress.py | 6 + client/shared/scripts/getOsVersion.py | 12 ++ client/shared/scripts/grubSyntax.py | 196 ++++++++++++++++++ client/shared/scripts/initCache.py | 90 ++++++++ client/shared/scripts/installOfflineMode.py | 80 +++++++ .../shared/scripts/launchOgagentInstaller.py | 147 +++++++++++++ client/shared/scripts/listHardwareInfo.py | 36 ++++ client/shared/scripts/listPartitions.py | 11 + .../shared/scripts/listPrimaryPartitions.py | 13 ++ client/shared/scripts/listSoftwareInfo.py | 56 +++++ client/shared/scripts/menuBrowser.py | 16 ++ .../scripts/restoreImageCustomTemplate.py | 34 +++ client/shared/scripts/runApplicationX.py | 18 ++ client/shared/scripts/runhttplog.py | 38 ++++ 30 files changed, 1494 insertions(+), 35 deletions(-) create mode 100644 client/interfaceAdm/GetConfiguration.py create mode 100644 client/interfaceAdm/GetIpAddress.py create mode 100644 client/shared/scripts/bootOS.py create mode 100644 client/shared/scripts/bootOSCustomTemplate.py create mode 100644 client/shared/scripts/buildToOrder.py create mode 100644 client/shared/scripts/configureOSCustomTemplate.py create mode 100644 client/shared/scripts/createImageCustomTemplate..py create mode 100644 client/shared/scripts/createLogicalPartitions.py create mode 100644 client/shared/scripts/createPrimaryPartitions.py create mode 100644 client/shared/scripts/deployImage.py create mode 100644 client/shared/scripts/formatFs.py create mode 100644 client/shared/scripts/generateMenuDefault.py create mode 100644 client/shared/scripts/getFsType.py create mode 100644 client/shared/scripts/getIpAddress.py create mode 100644 client/shared/scripts/getOsVersion.py create mode 100644 client/shared/scripts/grubSyntax.py create mode 100644 client/shared/scripts/initCache.py create mode 100644 client/shared/scripts/installOfflineMode.py create mode 100644 client/shared/scripts/launchOgagentInstaller.py create mode 100644 client/shared/scripts/listHardwareInfo.py create mode 100644 client/shared/scripts/listPartitions.py create mode 100644 client/shared/scripts/listPrimaryPartitions.py create mode 100644 client/shared/scripts/listSoftwareInfo.py create mode 100644 client/shared/scripts/menuBrowser.py create mode 100644 client/shared/scripts/restoreImageCustomTemplate.py create mode 100644 client/shared/scripts/runApplicationX.py create mode 100644 client/shared/scripts/runhttplog.py diff --git a/client/interfaceAdm/Apagar.py b/client/interfaceAdm/Apagar.py index da009dc..2d1598f 100644 --- a/client/interfaceAdm/Apagar.py +++ b/client/interfaceAdm/Apagar.py @@ -1,9 +1,9 @@ import os import sys -def poweroff(): +def main(): os.system('poweroff') + sys.exit(0) if __name__ == "__main__": - poweroff() - sys.exit(0) \ No newline at end of file + main() diff --git a/client/interfaceAdm/EjecutarScript.py b/client/interfaceAdm/EjecutarScript.py index 0bf56ca..ad517fe 100644 --- a/client/interfaceAdm/EjecutarScript.py +++ b/client/interfaceAdm/EjecutarScript.py @@ -3,54 +3,60 @@ import time import subprocess import sys +os.environ.setdefault('MSG_INTERFACE_START', 'Inicio de la interfaz') + +sys.path.append('/opt/opengnsys/lib/engine/bin') +from SystemLib import ogEcho + def main(script_path): start_time = time.time() + print(f"Ejecutando:",script_path) - # Load engine configurator from engine.cfg file - og_engine_configurate = os.getenv('OGENGINECONFIGURATE') - if not og_engine_configurate: - with open('/opt/opengnsys/etc/engine.cfg') as f: - exec(f.read()) + # 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()) # Clear temporary file used as log track by httpdlog - og_log_session = os.getenv('OGLOGSESSION') - og_log_command = os.getenv('OGLOGCOMMAND') - if og_log_session: - open(og_log_session, 'w').close() - if og_log_command: - open(og_log_command, 'w').close() + with open(os.environ['OGLOGSESSION'], 'w') as f: + f.write("") + with open(os.environ['OGLOGCOMMAND'], 'w') as f: + f.write("") # Registro de inicio de ejecución - msg_interface_start = os.getenv('MSG_INTERFACE_START') - og_echo('log session', f"{msg_interface_start} {sys.argv[0]} {' '.join(sys.argv[1:])}") + ogEcho('log session', f"{os.environ['MSG_INTERFACE_START']} {sys.argv[0]} {' '.join(sys.argv[1:])}") - og_log_file = os.getenv('OGLOGFILE') - if og_log_file: - with open(og_log_file, 'a') as log_file: - log_file.write("\n Instrucciones a ejecutar: *****************************\n") - with open(script_path) as script_file: - log_file.write(script_file.read()) - log_file.write("\n Salida de las instrucciones: *****************************\n") + 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()) ) - # Execute the script - os.chmod(script_path, 0o755) - retval = subprocess.call([script_path]) + log_file.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 + + 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 retval == 0: - og_echo('log session', f"[100] Duracion de la operacion {int(elapsed_time // 60)}m {int(elapsed_time % 60)}s") + if ret_val == 0: + ogEcho('log session', f"[100] Duracion de la operacion {int(elapsed_time // 60)}m {int(elapsed_time % 60)}s") else: - og_raise_error('log session', retval) - og_echo('log session error', "Operacion no realizada") + ogRaiseError('log session', ret_val) + ogEcho('log session', 'error "Operacion no realizada"') # Registro de fin de ejecución - msg_interface_end = os.getenv('MSG_INTERFACE_END') - og_echo('log session', f"{msg_interface_end} {retval}") + ogEcho('log session', f"{os.environ['MSG_INTERFACE_END']} {ret_val}") - sys.exit(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]) \ No newline at end of file + main(sys.argv[1]) diff --git a/client/interfaceAdm/GetConfiguration.py b/client/interfaceAdm/GetConfiguration.py new file mode 100644 index 0000000..7e64850 --- /dev/null +++ b/client/interfaceAdm/GetConfiguration.py @@ -0,0 +1,88 @@ +import os +import subprocess +import sys +#sys.path.append('/opt/opengnsys/lib/engine/bin') +#from DiskLib import ogDiskToDev +#from InventoryLib import ogGetSerialNumber +#!/usr/bin/env python3 + +# No registrar los errores +os.environ["DEBUG"] = "no" + +# Obtener el número de serie y configuración inicial +ser = subprocess.getoutput("ogGetSerialNumber") +cfg = "" + +# Obtener el número de discos +disks = len(subprocess.getoutput("ogDiskToDev").split()) + +# Recorrer discos +for dsk in range(1, disks + 1): + # Número de particiones + particiones = subprocess.getoutput(f"ogGetPartitionsNumber {dsk}") or "0" + particiones = int(particiones) + + # Tipo de tabla de particiones + ptt = subprocess.getoutput(f"ogGetPartitionTableType {dsk}") + ptt_mapping = {"MSDOS": 1, "GPT": 2, "LVM": 3, "ZPOOL": 4} + ptt = ptt_mapping.get(ptt, 0) + + # Información de disco (partición 0) + cfg += f"{dsk}:0:{ptt}:::{subprocess.getoutput(f'ogGetDiskSize {dsk}')}:0;" + + # Recorrer particiones + for par in range(1, particiones + 1): + # Código del identificador de tipo de partición + cod = subprocess.getoutput(f"ogGetPartitionId {dsk} {par} 2>/dev/null") + + # Tipo del sistema de ficheros + fsi = subprocess.getoutput(f"getFsType {dsk} {par} 2>/dev/null") or "EMPTY" + + # Tamaño de la partición + tam = subprocess.getoutput(f"ogGetPartitionSize {dsk} {par} 2>/dev/null") or "0" + + # Sistema operativo instalado + soi = "" + uso = 0 + if fsi not in ["", "EMPTY", "LINUX-SWAP", "LINUX-LVM", "ZVOL"]: + if subprocess.getoutput(f"ogMount {dsk} {par} 2>/dev/null"): + soi = subprocess.getoutput(f"getOsVersion {dsk} {par} 2>/dev/null | cut -f2 -d:") + if not soi and fsi not in ["EMPTY", "CACHE"]: + soi = "DATA" + uso = int(subprocess.getoutput(f"df $(ogGetMountPoint {dsk} {par}) | awk '{{getline; printf \"%d\",$5}}'") or "0") + + cfg += f"{dsk}:{par}:{cod}:{fsi}:{soi}:{tam}:{uso};" + +# 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: + f.write(f"{ser + ';' if ser else ''}{cfg}") + +# Crear el menú por defecto desde el archivo generado +subprocess.run(["generateMenuDefault"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + +# Componer salida formateada +formatted_output = [] +with open(cfgfile, 'r') as f: + content = f.read().strip().split(";") + for item in content: + fields = item.split(":") + if len(fields) == 1: + formatted_output.append(f"ser={fields[0]}") + else: + formatted_output.append( + f"disk={fields[0]}\tpar={fields[1]}\tcpt={fields[2]}\tfsi={fields[3]}\tsoi={fields[4]}\ttam={fields[5]}\tuso={fields[6]}" + ) + +# Mostrar la salida formateada +print("\n".join(formatted_output)) + +# Borrar marcas de arranque de Windows +subprocess.run(["rm", "-f", "/mnt/*/ogboot.*", "/mnt/*/*/ogboot.*"]) + +# Volver a registrar los errores +os.environ.pop("DEBUG", None) diff --git a/client/interfaceAdm/GetIpAddress.py b/client/interfaceAdm/GetIpAddress.py new file mode 100644 index 0000000..7549c60 --- /dev/null +++ b/client/interfaceAdm/GetIpAddress.py @@ -0,0 +1,11 @@ +import socket + +#!/usr/bin/env python3 + +def get_ip_address(): + hostname = socket.gethostname() + ip_address = socket.gethostbyname(hostname) + return ip_address + +if __name__ == "__main__": + print(get_ip_address()) diff --git a/client/interfaceAdm/Reiniciar.py b/client/interfaceAdm/Reiniciar.py index d77f9cb..53e9ce1 100644 --- a/client/interfaceAdm/Reiniciar.py +++ b/client/interfaceAdm/Reiniciar.py @@ -4,4 +4,4 @@ def reboot_system(): os.system('reboot') if __name__ == "__main__": - reboot_system() \ No newline at end of file + reboot_system() diff --git a/client/shared/scripts/bootOS.py b/client/shared/scripts/bootOS.py new file mode 100644 index 0000000..9950a20 --- /dev/null +++ b/client/shared/scripts/bootOS.py @@ -0,0 +1,58 @@ +import sys +import os +import subprocess + +#!/usr/bin/env python3 +# Script de ejemplo para arrancar un sistema operativo instalado. +# Nota: se usa como base para el programa de arranque de OpenGnsys Admin. + +def main(): + prog = os.path.basename(__file__) + if len(sys.argv) < 3 or len(sys.argv) > 6: + og_raise_error(1, f"Formato: {prog} ndisco nfilesys [str_kernel str_initrd str_kernelparams]") + + disk = sys.argv[1] + filesystem = sys.argv[2] + + try: + part = og_disk_to_dev(disk, filesystem) + except Exception as e: + sys.exit(1) + + try: + mntdir = og_mount(disk, filesystem) + except Exception as e: + sys.exit(1) + + print("[0] Inicio del proceso de arranque.") + + mount_output = subprocess.getoutput(f"mount | grep -q '{mntdir}.*(rw'") + if mount_output: + og_echo("log", "session", "MSG_WARNING: MSG_MOUNTREADONLY") + og_unmount(disk, filesystem) + og_check_fs(disk, filesystem) + + part = og_disk_to_dev(disk, filesystem) + os.makedirs(mntdir, exist_ok=True) + subprocess.run(["ntfs-3g", "-o", "remove_hiberfile", part, mntdir]) + og_echo("log", "session", "Particion desbloqueada") + + og_unmount(disk, filesystem) + og_mount(disk, filesystem) + + if subprocess.call("which bootOsCustom", shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0: + print("[10] Configuración personalizada del inicio.") + subprocess.run(["bootOsCustom"] + sys.argv[1:]) + + print("[70] Desmontar todos los sistemas de archivos.") + subprocess.run(["sync"]) + for i in range(1, len(og_disk_to_dev(disk, filesystem).split())): + og_unmount_all(i) + + print("[80] Desmontar cache local.") + og_unmount_cache() + print("[90] Arrancar sistema operativo.") + og_boot(sys.argv[1:]) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/client/shared/scripts/bootOSCustomTemplate.py b/client/shared/scripts/bootOSCustomTemplate.py new file mode 100644 index 0000000..1f5f0a1 --- /dev/null +++ b/client/shared/scripts/bootOSCustomTemplate.py @@ -0,0 +1,101 @@ +import sys +import os + +#!/usr/bin/env python3 +""" +bootOsCustom +@brief Plantilla para script de configuración personalizada de sistema operativo restaurado. +@param $1 nº de disco +@param $2 nº de partición +@warning Renombrar este fichero como "bootOsCustom" para personalizar el script estándar "bootOs". +@note La partición a inicializar debe estar montada +@version 1.1.1 Soporta varios discos +""" + + +# CONFIGURAR: Partición de datos de Windows que no queremos ocultar (valor por defecto '0' no oculta nada) +DISKDATA = 0 +PARTDATA = 0 + +PROG = os.path.basename(__file__) + +# Control de errores +if len(sys.argv) < 3: + ogRaiseError(OG_ERR_FORMAT, f"Formato: {PROG} ndisco nparticion") + sys.exit(1) + +# Parámetros obligatorios. +DISK = sys.argv[1] # Nº de disco. +PART = sys.argv[2] # Nº de partición. + +# Paso 0: Añadir código para realizar control de errores de los parámetros de entrada (recomendado). +DEVICE = ogDiskToDev(DISK, PART) +if not DEVICE: + sys.exit(1) + +# Paso 1: Adaptar el código de ejemplo para arranque personalizado. +# Nota: el script "bootOs" llama al script "bootOsCustom" después de realizar la operaciones de inicio estándar y antes de desmontar las particiones e iniciar el sistema operativo. + +MNTDIR = ogMount(DISK, PART) +if not MNTDIR: + sys.exit(1) + +NAME = ogGetHostname() +NAME = NAME if NAME else "pc" +OSTYPE = ogGetOsType(DISK, PART) + +if OSTYPE == "Windows": + # Mostrar las particiones NTFS de sistema (dos opciones) + # Opción 1: SIN ocultar las demás. + # ogEcho log session "[40] Mostrar y activar particion de Windows {PART}." + # if ogGetPartitionType(DISK, PART) in ["HNTFS", "WIN-RESERV"]: + # ogUnhidePartition(DISK, PART) + + # Recorremos los distintos discos + # for DEVICE in ogDiskToDev(): + # d = ogDevToDisk(DEVICE) + + # # Mostrar las particiones NTFS de sistema (dos opciones) + # # Opción 2: Ocultamos las demás. + # ogEcho log session "[40] Activar particion de Windows {PART} y ocultar las demás." + # for i in range(1, ogGetPartitionsNumber(d) + 1): + # if (d == DISK and i == PART) or (d == DISKDATA and i == PARTDATA): + # if ogGetPartitionType(d, i) in ["HNTFS", "WIN-RESERV"]: + # ogUnhidePartition(d, i) + # else: + # if ogGetPartitionType(d, i) in ["NTFS", "WINDOWS"]: + # ogHidePartition(d, i) + + # # Borrar marcas de arrranque de todos los Windows instalados en el disco. + # ogEcho log session "[30] Borrar marcas de arrranque de todos los Windows instalados en el disco." + # for i in range(1, ogGetPartitionsNumber(d) + 1): + # if ogGetOsType(d, i) == "Windows": + # ogMount(d, i) + # os.system("rm -f /mnt/*/ogboot.*") + +elif OSTYPE == "Linux": + # Modificar el nombre del equipo + # ogEcho log session "[30] Asignar nombre Linux \"{NAME}\"." + # ETC = ogGetPath(DISK, PART, "/etc") + # if os.path.isdir(ETC): + # with open(os.path.join(ETC, "hostname"), "w") as f: + # f.write(NAME) + + # Sustituir UUID o LABEL por su dispositivo en definición de sistema de archivo raíz. + # if os.path.isfile(os.path.join(ETC, "fstab")): + # ogEcho log session "[40] Actualizar fstab con particion raíz \"{PART}\"." + # with open(os.path.join(ETC, "fstab"), "r") as f: + # lines = f.readlines() + # with open("/tmp/fstab", "w") as f: + # for line in lines: + # if line.split()[1] == "/" and not line.startswith("#"): + # line = line.replace(line.split()[0], PART) + # f.write(line) + # os.replace("/tmp/fstab", os.path.join(ETC, "fstab")) + + # Cambiar claves usuarios, copiando fichero /etc/passwd + # En el servidor el nuevo fichero debe situarse en el directorio del grupo: + # /opt/opengnsys/images/groups/nombre_aula + # if os.path.isfile(os.path.join(ogGetGroupDir(), "passwd")): + # ogEcho log session "[65] Cambiar claves de usuarios." + # os.system(f"cp {os.path.join(ogGetGroupDir(), 'passwd')} {os.path.join(MNTDIR, 'etc')}") \ No newline at end of file diff --git a/client/shared/scripts/buildToOrder.py b/client/shared/scripts/buildToOrder.py new file mode 100644 index 0000000..0dc5721 --- /dev/null +++ b/client/shared/scripts/buildToOrder.py @@ -0,0 +1,65 @@ +import sys + +#!/usr/bin/env python3 + +""" +BuildToOrder +@brief Script de ejemplo para realizar una configuracion del sistema operativo antes de generar imagen o de restaurado. +@brief Activa el uso de los contralodres de disco más usados en windows 7. +@brief (puede usarse como complemento para el programa de creación de imágenes o de restauración). +@param 1 disco +@param 2 particion +@return +@TODO +@exception +@version 1.0.4 - Discos ide + SATA. +@date 2012-10-05 +@version 1.1.1b - Funciona para Windows8 y Windows 10. Si la clave no existe (tiene valor vacío) se crea. +@date 2020-05-04 +""" + +def main(): + PROG = sys.argv[0] + if len(sys.argv) != 3: + ogRaiseError("OG_ERR_FORMAT", f"Formato: {PROG} ndisco nparticion") + + disk = sys.argv[1] + partition = sys.argv[2] + + MNTDIR = ogMount(disk, partition) + OSTYPE = ogGetOsType(disk, partition) + + if OSTYPE == "Windows": + print("Filtro versión de sistema operativo windows.") + TYPE = ogGetOsVersion(disk, partition) + if "Windows XP" in TYPE: + print("Versión de sistema operativo Windows XP no soportado") + sys.exit() + elif "Windows 7" in TYPE: + KEYS = ["intelide", "pciide", "msahci", "iaStorV", "iaStor", "LSI_SAS"] + elif "Windows 8" in TYPE or "Windows 10" in TYPE: + KEYS = ["intelide", "pciide", "storahci", "iaStorV", "iaStorAC", "iaStorAVC", "LSI_SAS"] + else: + KEYS = [] + + print(TYPE) + CONTROLSET = ["ControlSet001", "ControlSet002"] + for C in CONTROLSET: + if ogListRegistryKeys(MNTDIR, "SYSTEM", f'\\{C}') == "": + continue + + for K in KEYS: + FULLK = f'\\{C}\\Services\\{K}\\Start' + VALUE = ogGetRegistryValue(MNTDIR, "SYSTEM", FULLK) + if VALUE == "": + ogDeleteRegistryValue(MNTDIR, "SYSTEM", FULLK) + ogAddRegistryValue(MNTDIR, "SYSTEM", FULLK, "DWORD") + ogSetRegistryValue(MNTDIR, "SYSTEM", FULLK, '0') + print(f" * {C} {K} enabled") + elif OSTYPE == "Linux": + print("Versión de Sistema Operativo GNU/Linux no soportado") + else: + print("Sistema Operativo no soportado") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/client/shared/scripts/configureOSCustomTemplate.py b/client/shared/scripts/configureOSCustomTemplate.py new file mode 100644 index 0000000..62c2cde --- /dev/null +++ b/client/shared/scripts/configureOSCustomTemplate.py @@ -0,0 +1,78 @@ +import sys +import subprocess + +#!/usr/bin/env python3 +""" +configureOsCustom +@brief Plantilla para script de configuración personalizada de sistema operativo restaurado. +@param $1 nº de disco +@param $2 nº de partición +@param $3 Repositorio: CACHE, REPO o dirección IP (opcional) +@param $4 Nombre canónico de la imagen sin extensión (opcional) +@warning Renombrar este fichero como "configureOsCustom" para sustituir al script estándar "configureOs". +@note Los parámetros disco y partición son obligatorios y opcionalmente puede recibir también el repositorio y la imagen usada para en el despliegue. +""" + +def main(): + if len(sys.argv) not in [3, 5]: + og_raise_error("OG_ERR_FORMAT", "Usage: configureOsCustom int_ndisc int_npart [str_repo str_imgname]") + + disk = sys.argv[1] + part = sys.argv[2] + repo = sys.argv[3].upper() if len(sys.argv) > 3 else None + imgname = sys.argv[4] if len(sys.argv) > 4 else None + + # Paso 0: Añadir código para realizar control de errores de los parámetros de entrada (recomendado). + + # Paso 1: Adaptar el código de ejemplo para postconfiguración personalizada. + configure_os(disk, part) + + ostype = og_get_os_type(disk, part) + if ostype == "Windows": + # Postconfiguración de Windows. + pass + # Descomentar la siguiente línea para cambiar usuario de inicio. + # subprocess.run(["ogSetWinlogonUser", disk, part, " "], check=True) + # OPCIONAL: desactivar el chkdisk de windows tras la restauracion. Requiere configuracion previa en el engine.cfg + # subprocess.run(["ogLoadHiveWindows", disk, part], check=True) + # subprocess.run(["ogSetWindowsChkdisk", "OGWINCHKDISK"], check=True) + # subprocess.run(["ogUpdateHiveWindows"], check=True) + elif ostype == "Linux": + # Postconfiguración de GNU/Linux. + pass + # OPCIONAL Para UEFI: cambia el UUID de la partición (para tener dos linux en un equipo) + # subprocess.run(["ogUuidChange", disk, part], check=True) + # OPCIONAL Limpiar dispositivos reconocidos previamente + # subprocess.run(["ogCleanLinuxDevices", disk, part], check=True) + # Instala (no configura) el codigo de arranque del Grub en la partición (no lo configura, se mantiene el original de la imagen) + # subprocess.run(["ogGrubInstallPartition", disk, part], check=True) + # OPCIONAL: instala y configura el codigo de arranque del Grub en el MBR (no lo configura, se mantiene el original de la imagen) + # subprocess.run(["ogGrubInstallMbr", disk, part], check=True) + # OPCIONAL: Instala y configura el Grub en el MBR y lo autoconfigura, entradas para los sistemas operativos, además al linux restaurado le añade los parámetros indicados. + # subprocess.run(["ogGrubInstallMbr", disk, part, "TRUE", "irqpoll pci=noacpi noresume quiet splash"], check=True) + elif ostype == "MacOS": + # Postconfiguración de Mac OS X. + with open(f"/mnt/{disk}/{part}/var/root/postconfd.sh", "a") as f: + f.write(""" +### NOTA: descomentar las opciones deseadas. +# Activar Journaling en HFS+ (no usar si el cliente continua en OpenGnsys). +#diskutil enableJournal disk$[$1-1]s$2 +# Pedir usuario y clave en pantalla de conexión. +#defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME -bool yes +# No mostrar botón de cambio rápido de usuario. +#defaults write /Library/Preferences/.GlobalPreferences MultipleSessionEnabled -bool NO +# Bloquear escritorio, fondo, dock, etc del usuario "usuario". +#chflags uchange /Users/usuario/Library/Preferences/com.apple.desktop.plist +#chflags uchange /Users/usuario/Library/Preferences/com.apple.dock.plist +#chflags uchange /Users/usuario/Desktop +# Añadir usuario "usuario" a la lista de desarrolladores de Xcode. +#DevToolsSecurity --enable +#dscl . -append /Groups/_developer GroupMembership usuario +# Bajar volumen (valor entre 0 y 7). +#osascript -e 'set volume 1' +""") + + # Paso 2: Incluir código genérico de postconfiguración. + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/client/shared/scripts/createImageCustomTemplate..py b/client/shared/scripts/createImageCustomTemplate..py new file mode 100644 index 0000000..f47efbc --- /dev/null +++ b/client/shared/scripts/createImageCustomTemplate..py @@ -0,0 +1,27 @@ +import sys +import os + +#!/usr/bin/env python3 + +def main(): + # Control de parámetros. + if len(sys.argv) != 5: + ogRaiseError(os.getenv('OG_ERR_FORMAT', 1), "createImageCustom int_ndisc int_npart str_repo str_imgname") + + # Toma de parámetros. + DISK = sys.argv[1] # Nº de disco. + PART = sys.argv[2] # Nº de partición. + REPO = sys.argv[3].upper() # Repositorio (en mayúsculas). + IMGNAME = sys.argv[4] # Nombre canónico de imagen (sin extensión). + + # Paso 0: Añadir código para realizar control de errores de los parámetros de entrada (recomendado). + + # Paso 1: Añadir aquí el código para el proceso previo antes de la creación de la imagen en el equipo modelo (opcional). + + # Paso 2: Sustituir, si se desea, la llamada al proceso estándar de creación de imagen por código personalizado. + createImage(DISK, PART, REPO, IMGNAME) + + # Paso 3: Añadir aquí el código para el proceso posterior tras la creación de la imagen (opcional). + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/client/shared/scripts/createLogicalPartitions.py b/client/shared/scripts/createLogicalPartitions.py new file mode 100644 index 0000000..5f7ce86 --- /dev/null +++ b/client/shared/scripts/createLogicalPartitions.py @@ -0,0 +1 @@ +#!/usr/bin/env python3 \ No newline at end of file diff --git a/client/shared/scripts/createPrimaryPartitions.py b/client/shared/scripts/createPrimaryPartitions.py new file mode 100644 index 0000000..9cd5fe9 --- /dev/null +++ b/client/shared/scripts/createPrimaryPartitions.py @@ -0,0 +1,5 @@ +import sys + +if __name__ == "__main__": + result = og_create_partitions(sys.argv[1:]) + sys.exit(result.returncode) \ No newline at end of file diff --git a/client/shared/scripts/deployImage.py b/client/shared/scripts/deployImage.py new file mode 100644 index 0000000..8891c6e --- /dev/null +++ b/client/shared/scripts/deployImage.py @@ -0,0 +1,139 @@ +import os +import sys +import time + +#!/usr/bin/env python3 + +def main(): + PROG = os.path.basename(__file__) + if len(sys.argv) < 5: + ogRaiseError("session", OG_ERR_FORMAT, f"{MSG_FORMAT}: {PROG} REPO imagen ndisco nparticion [ UNICAST-DIRECT|UNICAST|UNICAST-CACHE|MULTICAST-DIRECT|MULTICAST|MULTICAST-CACHE|TORRENT [opciones protocolo] ]") + sys.exit(1) + + TIME1 = time.time() + REPO = sys.argv[1].upper() or "REPO" + IMGNAME = sys.argv[2] + DISK = sys.argv[3] + PART = sys.argv[4] + PROTO = (sys.argv[5].upper() if len(sys.argv) > 5 else "UNICAST") + PROTOOPT = sys.argv[6] if len(sys.argv) > 6 else "" + OGUNIT = os.getenv("ogunit", "") + + if not OGENGINECONFIGURATE: + exec(open("/opt/opengnsys/etc/engine.cfg").read()) + + with open(OGLOGCOMMAND, 'w') as f: + f.write(" ") + if ogGetCaller() != "EjecutarScript": + with open(OGLOGSESSION, 'w') as f: + f.write("") + + ogEcho("log", "session", f"[1] {MSG_SCRIPTS_START} {PROG} {' '.join(sys.argv)}") + + if ogIsLocked(DISK, PART): + sys.exit(ogRaiseError("session", OG_ERR_LOCKED, f"{MSG_PARTITION}, {DISK} {PART}")) + + ogEcho("log", "session", f"{MSG_HELP_ogUnmount} {DISK} {PART}") + ogUnmount(DISK, PART) + + if REPO == ogGetIpAddress() or REPO == "CACHE": + MODE = "CACHE" + else: + if ogCheckIpAddress(REPO) == 0 or REPO == "REPO": + if not ogChangeRepo(REPO, OGUNIT): + sys.exit(ogRaiseError(OG_ERR_NOTFOUND, f"{REPO} {OGUNIT}")) + MODE = "REPO" + + IMGOS = ogGetImageInfo(ogGetPath(MODE, f"{IMGNAME}.img")) + if IMGOS == 1: + sys.exit(ogRaiseError("session", OG_ERR_NOTFOUND, f"{REPO} {IMGNAME}")) + elif IMGOS == 5: + sys.exit(ogRaiseError("session", OG_ERR_IMAGEFILE, f"{REPO} {IMGNAME}")) + elif IMGOS != 0: + sys.exit(ogRaiseError("session", OG_ERR_GENERIC)) + + IMGSIZE = os.path.getsize(ogGetPath(MODE, f"{IMGNAME}.img")) // 1024 + ogEcho("log", "session", f"[1] REPO={REPO} IMG-FILE={IMGNAME}.img SIZE={IMGSIZE} (KB) METADATA={IMGOS}") + + if MODE == "CACHE": + NEXTOPERATION = "CACHE" + elif MODE == "REPO": + if PROTO in ["MULTICAST-DIRECT", "UNICAST-DIRECT"]: + NEXTOPERATION = PROTO.split('-')[0] + elif PROTO in ["TORRENT", "TORRENT-CACHE", "MULTICAST", "MULTICAST-CACHE", "UNICAST", "UNICAST-CACHE"]: + PROTO = PROTO.split('-')[0] + ogEcho("log", "session", f"[2] updateCache {REPO} /{IMGNAME}.img {PROTO} {PROTOOPT}") + TIME2 = time.time() + RETVAL = updateCache(REPO, f"/{IMGNAME}.img", PROTO, PROTOOPT) + TIME2 = time.time() - TIME2 + ogEcho("log", "session", f" [ ] {MSG_SCRIPTS_TIME_PARTIAL} updateCache {TIME2 // 60}m {TIME2 % 60}s") + if RETVAL == 0: + ogEcho("log", "session", "[50] updateCache (OK)") + NEXTOPERATION = "CACHE" + elif RETVAL in [15, 16]: + ogEcho("log", "session", f"[50] {MSG_ERR_NOTCACHE} ; {MSG_ERR_CACHESIZE}") + ogEcho("log", "session", f"[50] {MSG_SCRIPTS_CHECK_ENGINE}: RESTOREPROTOCOLNOTCACHE={RESTOREPROTOCOLNOTCACHE}") + if RESTOREPROTOCOLNOTCACHE == "MULTICAST": + NEXTOPERATION = "MULTICAST" if PROTO == "MULTICAST" else "UNICAST" + elif RESTOREPROTOCOLNOTCACHE == "UNICAST": + NEXTOPERATION = "UNICAST" + elif RESTOREPROTOCOLNOTCACHE == "NONE": + if RETVAL == 15: + ogEcho("log", "session", f"[100] {MSG_ERR_NOTCACHE}") + sys.exit(ogRaiseError("session", OG_ERR_NOTCACHE, "NOT CACHE")) + elif RETVAL == 16: + ogEcho("log", "session", f"[100] {MSG_ERR_CACHESIZE}") + sys.exit(ogRaiseError("session", OG_ERR_CACHESIZE, "CACHE FULL")) + elif RETVAL in [57, 60]: + sys.exit(RETVAL) + else: + sys.exit(RETVAL) + else: + sys.exit(ogRaiseError("session", OG_ERR_FORMAT, f"{MSG_ERR_FORMAT}, {PROTO}")) + else: + sys.exit(ogRaiseError("session", OG_ERR_FORMAT, f"{MSG_ERR_FORMAT}, {REPO}")) + + TIME3 = time.time() + + if NEXTOPERATION == "CACHE": + PARAMS = f"CACHE {IMGNAME} {DISK} {PART}" + elif NEXTOPERATION == "UNICAST": + PARAMS = f"{REPO} {IMGNAME} {DISK} {PART}" + elif NEXTOPERATION == "MULTICAST": + PARAMS = f"{REPO} {IMGNAME} {DISK} {PART} {PROTO} {PROTOOPT}" + + if os.system("which restoreImageCustom") == 0: + ogEcho("log", "session", f"[55] {MSG_HELP_ogRestoreImage}: restoreImageCustom {PARAMS}") + os.system(f"restoreImageCustom {PARAMS}") + else: + ogEcho("log", "session", f"[55] {MSG_HELP_ogRestoreImage}: restoreImage {PARAMS}") + os.system(f"restoreImage {PARAMS}") + RETVAL = os.system(f"restoreImage {PARAMS}") + + RESUMERESTOREIMAGE = os.popen(f"grep -m 1 'Total Time:' {OGLOGCOMMAND}").read() + ogEcho("log", "session", f" [ ] {RESUMERESTOREIMAGE}") + if RETVAL != 0: + ogRaiseError("session", OG_ERR_IMAGE, f"{REPO} {IMGNAME}") + if ogGetCaller() != "EjecutarScript": + ogEcho("log", "session", f"{MSG_INTERFACE_END} {OG_ERR_IMAGE}") + sys.exit(OG_ERR_IMAGE) + + TIME3 = time.time() - TIME3 + ogEcho("log", "session", f" [ ] {MSG_SCRIPTS_TIME_PARTIAL} : {TIME3 // 60}m {TIME3 % 60}s") + + if os.system("which configureOsCustom") == 0: + ogEcho("log", "session", "[90] configureOsCustom") + os.system(f"configureOsCustom {DISK} {PART} {REPO} {IMGNAME}") + else: + ogEcho("log", "session", f"[90] {MSG_SCRIPTS_OS_CONFIGURE}") + os.system(f"configureOs {DISK} {PART}") + + TIME = time.time() - TIME1 + ogEcho("log", "session", f"[100] {MSG_SCRIPTS_TIME_TOTAL} {TIME // 60}m {TIME % 60}s") + + if ogGetCaller() != "EjecutarScript": + ogEcho("log", "session", f"{MSG_INTERFACE_END} {RETVAL}") + sys.exit(RETVAL) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/client/shared/scripts/formatFs.py b/client/shared/scripts/formatFs.py new file mode 100644 index 0000000..ee8fec9 --- /dev/null +++ b/client/shared/scripts/formatFs.py @@ -0,0 +1,30 @@ +import sys +import time +import subprocess + +#!/usr/bin/env python3 +# Script de ejemplo para formatear un sistema de archivos. +# Nota: se usa como base para el programa de formateo de OpenGnsys Admin. + +def main(): + start_time = time.time() + prog = sys.argv[0] + + if len(sys.argv) != 3: + ogRaiseError(1, f"{prog} ndisco nparticion") + + disk = sys.argv[1] + partition = sys.argv[2] + + # Desmontar y formatear el sistema de archivos. + print("[5] Desmontando sistema de archivos") + ogUnmountFs(disk, partition) + print("[20] Formateando sistema de archivos") + ogFormatFs(disk, partition) + + elapsed_time = time.time() - start_time + minutes, seconds = divmod(int(elapsed_time), 60) + print(f"[100] Duración de la operación {minutes}m {seconds}s") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/client/shared/scripts/generateMenuDefault.py b/client/shared/scripts/generateMenuDefault.py new file mode 100644 index 0000000..7f30baf --- /dev/null +++ b/client/shared/scripts/generateMenuDefault.py @@ -0,0 +1,92 @@ +import os +import subprocess + +#!/usr/bin/env python3 +# generateMenuDefault - Crea fichero con la página web de inicio del cliente +# con información de red y de los sistemas operativos instalados, +# crea fichero con información del contenido de la caché local. + + +DEVICE = os.getenv('DEVICE', 'eth0') +with open(f'/tmp/net-{DEVICE}.conf') as f: + exec(f.read()) + +FILEINFOHTML = f"{os.getenv('OGLOG')}/{subprocess.getoutput('ogGetIpAddress')}.info.html" +FILEINFOCACHE = f"{os.getenv('OGLOG')}/{subprocess.getoutput('ogGetIpAddress')}.cache.txt" +subprocess.run(['ogMountCache'], stderr=subprocess.DEVNULL) +CACHECONTENIDO = f"ls -m {os.getenv('OGCAC')}/{os.getenv('OGIMG')} 2>/dev/null" + +SPEED = subprocess.getoutput(f"LANG=C ethtool {DEVICE} 2>/dev/null | awk '$1~/Speed/ {{print $2}}'") +SPEED = SPEED.lower() +if SPEED == "1000mb/s": + pass +elif SPEED == "100mb/s": + SPEED = f"{SPEED}" +elif SPEED == "10mb/s": + SPEED = f"{SPEED}" +else: + SPEED = f"{SPEED}" + +DUPLEX = subprocess.getoutput(f"LANG=C ethtool {DEVICE} 2>/dev/null | awk '$1~/Duplex/ {{print $2}}'") +DUPLEX = DUPLEX.lower() +if DUPLEX == "full": + pass +else: + DUPLEX = f"{DUPLEX}" + +CACHESIZEFREE = int(subprocess.getoutput('ogGetFreeSize $(ogFindCache)')) +with open(FILEINFOCACHE, 'w') as f: + if CACHESIZEFREE == 0: + f.write('0.MB,') + else: + f.write(f"{CACHESIZEFREE // 1024}.MB,") + +# Crear menú por defecto. +with open(FILEINFOHTML, 'w') as f: + f.write(f""" +
+

+ + + + + + +

{os.getenv('MSG_HOSTNAME')} {os.getenv('MSG_IPADDR')} {os.getenv('MSG_MACADDR')} {os.getenv('MSG_SPEED')} {os.getenv('MSG_DUPLEX')}
{os.getenv('HOSTNAME')} {subprocess.getoutput('ogGetIpAddress')} {subprocess.getoutput('ogGetMacAddress')} {SPEED} {DUPLEX}
+

+ +

{os.getenv('MSG_MENUTITLE')}

+""") + +# Si existe el fichero de configuración creado por el script getConfiguration, ... +cfgfile = '/tmp/getconfig' +if os.path.isfile(cfgfile): + # Tomar los datos del fichero. + with open(cfgfile) as f_cfg, open(FILEINFOHTML, 'a') as f_html: + for line in f_cfg: + sep = line.split(';') + for item in sep: + dua = item.split(':') + if len(dua) > 4 and dua[4] and dua[4] != "DATA": + f_html.write(f"

{os.getenv('MSG_BOOT')} {dua[4]} ({dua[0]}, {dua[1]})

\n") +else: + # Si no, obtener los datos de los discos. + num_disks = int(subprocess.getoutput('ogDiskToDev | wc -w')) + with open(FILEINFOHTML, 'a') as f_html: + for d in range(1, num_disks + 1): + num_partitions = int(subprocess.getoutput(f'ogGetPartitionsNumber {d}')) + for p in range(1, num_partitions + 1): + version = subprocess.getoutput(f'ogGetOsVersion {d} {p} 2>/dev/null').split(':')[1] + if version: + f_html.write(f"

{os.getenv('MSG_BOOT')} {version} ({d}, {p})

\n") + +# Añadir opción de apagado. +with open(FILEINFOHTML, 'a') as f: + f.write(f""" +

{os.getenv('MSG_POWEROFF')}

+
+""") + +# Crear contenido de la caché. +with open(FILEINFOCACHE, 'a') as f: + f.write(subprocess.getoutput(CACHECONTENIDO)) \ No newline at end of file diff --git a/client/shared/scripts/getFsType.py b/client/shared/scripts/getFsType.py new file mode 100644 index 0000000..d9fcf54 --- /dev/null +++ b/client/shared/scripts/getFsType.py @@ -0,0 +1,5 @@ +import sys + +if __name__ == "__main__": + output = ogGetFsType(sys.argv[1:]) + print(output) \ No newline at end of file diff --git a/client/shared/scripts/getIpAddress.py b/client/shared/scripts/getIpAddress.py new file mode 100644 index 0000000..1694bdd --- /dev/null +++ b/client/shared/scripts/getIpAddress.py @@ -0,0 +1,6 @@ +import sys + +if __name__ == "__main__": + args = sys.argv[1:] + output = ogGetIpAddress(args) + print(output) \ No newline at end of file diff --git a/client/shared/scripts/getOsVersion.py b/client/shared/scripts/getOsVersion.py new file mode 100644 index 0000000..b8637da --- /dev/null +++ b/client/shared/scripts/getOsVersion.py @@ -0,0 +1,12 @@ +import subprocess +import sys + +def main(): + try: + subprocess.run(["ogGetOsVersion"] + sys.argv[1:], check=True) + except subprocess.CalledProcessError as e: + print(f"An error occurred: {e}", file=sys.stderr) + sys.exit(e.returncode) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/client/shared/scripts/grubSyntax.py b/client/shared/scripts/grubSyntax.py new file mode 100644 index 0000000..6699b90 --- /dev/null +++ b/client/shared/scripts/grubSyntax.py @@ -0,0 +1,196 @@ +import os +import subprocess +import sys + +#!/usr/bin/env python3 + +def run_command(command): + result = subprocess.run(command, shell=True, capture_output=True, text=True) + return result.stdout.strip() + +def copy_files(src, dest): + if os.path.exists(src): + subprocess.run(f"cp -r {src} {dest}", shell=True) + +def prepare_grub_to_access_device(device): + loop_file = None + if device.startswith("/dev/loop"): + grub_loop_device = device.split('/')[-1] + loop_file = run_command(f"losetup {device} | sed -e 's/^[^(]*(\\([^)]\\+\\)).*/\\1/'") + if not loop_file.startswith("/dev"): + loop_device = device + device = run_command(f"{grub_probe} --target=device {loop_file}") + + if "crypt" in run_command(f"dmsetup status {device}"): + print(f"{device} is a crypto device, which GRUB cannot read directly.") + return + + abstraction = run_command(f"{grub_probe} --device {device} --target=abstraction") + for module in abstraction.split(): + print(f"insmod {module}") + + partmap = run_command(f"{grub_probe} --device {device} --target=partmap") + for module in partmap.split(): + if module in ["netbsd", "openbsd"]: + print("insmod part_bsd") + else: + print(f"insmod part_{module}") + + fs = run_command(f"{grub_probe} --device {device} --target=fs") + for module in fs.split(): + print(f"insmod {module}") + + if "nvme" in device: + d, p = ogDevToDisk(device) + if ogGetPartitionTableType(d) == "GPT": + nvme_device = f"hd{d-1},gpt{p}" + else: + nvme_device = f"hd{d-1},{p-1}" + print(f"set root='{nvme_device}'") + else: + print(f"set root='{run_command(f'{grub_probe} --device {device} --target=drive')}'") + + if loop_file: + loop_mountpoint = run_command(f"awk '{loop_file} ~ \"^\"$2 && $2 != \"/\" {{ print $2 }}' /proc/mounts | tail -n1") + if loop_mountpoint: + print(f"loopback {grub_loop_device} {loop_file[len(loop_mountpoint):]}") + print(f"set root=({grub_loop_device})") + +def main(): + disk = part = kernel_param = None + if len(sys.argv) == 4: + disk, part, kernel_param = sys.argv[1:4] + elif len(sys.argv) == 3: + disk, part = sys.argv[1:3] + elif len(sys.argv) == 2: + kernel_param = sys.argv[1] + + grub_probe = os.getenv("grub_probe", f"{os.getenv('OGBIN')}/grub-probe1.99_{os.uname().machine}") + + if "1.99" in run_command("grub-install --version"): + copy_files("/opt/opengnsys/lib/os-probes/*", "/usr/lib/os-probes/") + else: + osprobe_ms_part = "/opt/opengnsys/lib/os-probes/mounted/efi/31part-x-y" + if os.path.isfile(osprobe_ms_part): + copy_files(osprobe_ms_part, "/usr/lib/os-probes/mounted/efi") + + if os.path.exists(f"/opt/opengnsys/cache/boot/{oglivedir}/ogvmlinuz"): + subprocess.run(f"sed -i 's|/boot/{{oglivedir}}/ogvmlinuz |/vmlinuz |i' /usr/lib/linux-boot-probes/mounted/90fallback", shell=True) + subprocess.run(f"sed -i 's|/vmlinuz |/vmlinuz /boot/{{oglivedir}}/ogvmlinuz |1' /usr/lib/linux-boot-probes/mounted/90fallback", shell=True) + os.makedirs("/opt/opengnsys/cache/etc/", exist_ok=True) + with open("/opt/opengnsys/cache/etc/lsb-release", "w") as f: + f.write("DISTRIB_ID=Ubuntu\n") + f.write("DISTRIB_RELEASE= \n") + f.write(f"DISTRIB_CODENAME={oglivedir.split('-')[1]}\n") + f.write("DISTRIB_DESCRIPTION=OpenGnsys Live\n") + + if disk: + os_search = ogDiskToDev(disk, part) + os_probed = run_command(f"os-prober | grep {os_search} | tr ' ' '^' | paste -s -d ' '") + else: + os_probed = run_command("os-prober | tr ' ' '^' | paste -s -d ' '") + + if not os_probed: + adjust_timeout() + sys.exit(0) + + for os_entry in os_probed.split(): + device, longname, label, boot = os_entry.split(':') + longname = longname.replace('^', ' ') + label = label.replace('^', ' ') + if not longname: + longname = label + + print(f"Found {longname} on {device}", file=sys.stderr) + + if boot == "chain": + if "Windows" in longname: + if not wubi: + if os.path.exists("/usr/share/lupin-support/grub-mkimage") and run_command("/usr/share/lupin-support/grub-mkimage --test"): + wubi = "yes" + else: + wubi = "no" + if wubi == "yes": + print(f"Skipping {longname} on Wubi system", file=sys.stderr) + continue + + label_class = ''.join(longname.lower().split()[:2]) + print(f"menuentry \"{longname} (on {device})\" --class {label_class} --class windows {{") + save_default_entry() + prepare_grub_to_access_device(device) + if "Windows Vista" in longname or "Windows 7" in longname or "Windows Server 2008" in longname: + pass + else: + pass + print("chainloader +1") + print("}") + + elif boot == "efi": + efipath = device.split('@')[1] + device = device.split('@')[0] + onstr = f"(on {device})" + print(f"menuentry '{longname} {onstr}' --class windows --class os {{") + save_default_entry() + prepare_grub_to_access_device(device) + print(f"chainloader {efipath}") + print("}") + + elif boot == "linux": + linux_probed = run_command(f"linux-boot-prober {device} 2> /dev/null | tr ' ' '^' | paste -s -d ' '") + linux_probed = linux_probed.split()[0] + prepare_boot_cache = None + for linux_entry in linux_probed.split(): + lroot, lboot, llabel, lkernel, linitrd, lparams = linux_entry.split(':') + llabel = llabel.replace('^', ' ') + lparams = lparams.replace('^', ' ') + uuid = run_command(f"blkid -s UUID -o value {lroot}") + lparams = lparams.replace(f"UUID={uuid}", lroot) + if not llabel: + llabel = longname + if lroot != lboot: + lkernel = lkernel.replace('/boot', '') + linitrd = linitrd.replace('/boot', '') + label_class = llabel.split()[0].lower() + print(f"menuentry \"{llabel} (on {device})\" --class {label_class} --class linux --class os {{") + save_default_entry() + if not prepare_boot_cache: + prepare_boot_cache = prepare_grub_to_access_device(lboot) + print(prepare_boot_cache) + if label_class == "opengnsys": + kernel_param = run_command("cat /proc/cmdline") + print(f"linux {lkernel} {lparams} {kernel_param}") + if linitrd: + print(f"initrd {linitrd}") + print("}") + + elif boot == "macosx": + osx_uuid = run_command(f"grub-probe --target=fs_uuid --device {device} 2> /dev/null") + osx_entry("xnu_kernel", 32, device, longname, osx_uuid) + osx_entry("xnu_kernel64", 64, device, longname, osx_uuid) + + elif boot == "hurd": + print(f"menuentry \"{longname} (on {device})\" --class hurd --class gnu --class os {{") + save_default_entry() + prepare_grub_to_access_device(device) + grub_device = run_command(f"{grub_probe} --device {device} --target=drive") + mach_device = grub_device.replace("(hd", "").replace(",msdos", "s") + grub_fs = run_command(f"{grub_probe} --device {device} --target=fs") + hurd_fs = grub_fs if grub_fs.endswith("fs") else f"{grub_fs}fs" + print(f"multiboot /boot/gnumach.gz root=device:{mach_device}") + print(f"module /hurd/{hurd_fs}.static {hurd_fs} --readonly \\") + print(f" --multiboot-command-line='{{kernel-command-line}}' \\") + print(f" --host-priv-port='{{host-port}}' \\") + print(f" --device-master-port='{{device-port}}' \\") + print(f" --exec-server-task='{{exec-task}}' -T typed '{{root}}' \\") + print(f" '{{task-create}}' '{{task-resume}}'") + print(f"module /lib/ld.so.1 exec /hurd/exec '{{exec-task=task-create}}'") + print("}") + + else: + print(f" {longname} is not yet supported by grub-mkconfig.", file=sys.stderr) + + adjust_timeout() + os.remove("/opt/opengnsys/cache/etc/lsb-release") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/client/shared/scripts/initCache.py b/client/shared/scripts/initCache.py new file mode 100644 index 0000000..886a53e --- /dev/null +++ b/client/shared/scripts/initCache.py @@ -0,0 +1,90 @@ +import sys +import time +import subprocess + +#!/usr/bin/env python3 + +def main(): + TIME1 = time.time() + PROG = sys.argv[0] + EXECFORMAT = f"{PROG} [int_ndisk [int_npart]] {{-1 | 0 | int_size}} [NOMOUNT]" + + args = sys.argv[1:] + if args and args[-1].upper() == "NOMOUNT": + MOUNT = 0 + args = args[:-1] + else: + MOUNT = 1 + + PARAMS = len(args) + if PARAMS == 1: + NDISK = 1 + NPART = 4 + SIZE = int(args[0]) + elif PARAMS == 2: + NDISK = int(args[0]) + NPART = 4 + SIZE = int(args[1]) + elif PARAMS == 3: + NDISK = int(args[0]) + NPART = int(args[1]) + SIZE = int(args[2]) + else: + ogRaiseError("OG_ERR_FORMAT", f"{EXECFORMAT}") + + if NDISK < 1 or NPART < 1: + ogRaiseError("OG_ERR_FORMAT", f"{EXECFORMAT}") + + if SIZE < -1: + ogRaiseError("OG_ERR_FORMAT", f"{EXECFORMAT}") + + if SIZE == 0: + print("No modificar la caché local.") + return + + if SIZE == -1: + print("[10] Trabajar sin caché local.") + ogUnmountCache() + ogDeleteCache() + else: + current_cache = ogFindCache() + if current_cache and f"{NDISK} {NPART}" != current_cache: + print("[10] Detectada otra caché, eliminarla") + ogUnmountCache() + ogDeleteCache() + + try: + OLDSIZE = ogGetCacheSize() + except ValueError: + OLDSIZE = 0 + + if SIZE <= 0: + ogRaiseError("OG_ERR_FORMAT", f"!({SIZE}>0)") + + if SIZE != OLDSIZE: + print("[10] Crear partición de caché local.") + ogUnmountCache() + ogCreateCache(NDISK, NPART, SIZE) + ogUpdatePartitionTable(NDISK) + + cache = ogFindCache() + if not ogIsFormated(cache) or SIZE != OLDSIZE: + print("[50] Formatear caché local.") + ogFormatCache() + + print("[70] Comprobar montaje de caché local.") + if ogMountCache() != 0: + print("[80] Comprobar consistencia y volver a montar caché local.") + ogCheckFs(cache) + if ogMountCache() != 0: + sys.exit(1) + + if MOUNT == 0: + print("[90] Dejar desmontada la caché local.") + ogUnmountCache() + + TIME = time.time() - TIME1 + print(f"[100] Duración de la operación {int(TIME // 60)}m {int(TIME % 60)}s") + +if __name__ == "__main__": + main() diff --git a/client/shared/scripts/installOfflineMode.py b/client/shared/scripts/installOfflineMode.py new file mode 100644 index 0000000..041d1af --- /dev/null +++ b/client/shared/scripts/installOfflineMode.py @@ -0,0 +1,80 @@ +import os +import subprocess +import sys + +#!/usr/bin/env python3 + +""" +installOfflineMode +Prepara el equipo cliente para el modo offline. + +@exception OG_ERR_NOTFOUND Fichero o dispositivo no encontrado. +@exception OG_ERR_NOTCACHE No existe cache. +@author Irina Gomez. ETSII. Universidad de Sevilla +@date 2013/12/5 +""" + + +PROG = os.path.basename(__file__) + +if len(sys.argv) > 1 and sys.argv[1] == "help": + og_help() + +og_echo("log", "session $MSG_HELP_installOfflineMode") + +# Cargamos las variables de entorno. +OGENGINECONFIGURATE = os.getenv('OGENGINECONFIGURATE') +if not OGENGINECONFIGURATE: + exec(open('/opt/opengnsys/etc/engine.cfg').read()) + +DIRTFTP = "/opt/oglive/tftpboot" +DIROGCLIENT = os.path.join(DIRTFTP, "ogclient") + +# Comprobamos que el DIROGCLIENT esta montado desde repo +repo_ip = og_get_repo_ip() +result = subprocess.run(['df'], capture_output=True, text=True) +if f"{repo_ip} {DIRTFTP}" not in result.stdout: + og_raise_error("OG_ERR_NOTFOUND", "REPO OGclient") + +# Copiamos el kernel y el initrd. +og_echo("log", "session [10] updateBootCache") +if not update_boot_cache(): + og_raise_error("OG_ERR_NOTCACHE", "") + +# Creamos los dir necesarios. +OGCAC = "/path/to/ogcac" # Placeholder for OGCAC path +og_echo("log", f"session [40] mkdir -p {OGCAC}/{{ogclient, menus, log}}.") +os.makedirs(os.path.join(OGCAC, "menus/images/iconos"), exist_ok=True) +os.makedirs(os.path.join(OGCAC, "ogclient"), exist_ok=True) +os.makedirs(os.path.join(OGCAC, "log"), exist_ok=True) +os.makedirs(os.path.join(OGCAC, "opt/opengnsys/images"), exist_ok=True) + +# Comparamos el cliente en el server y en cache +og_echo("log", f"session [60] cp {DIROGCLIENT}/ogclient.sqfs {OGCAC}/ogclient/") +try: + with open(os.path.join(DIROGCLIENT, "ogclient.sqfs.sum"), 'r') as f: + SERVEROGCLIENT = f.read().strip() +except FileNotFoundError: + SERVEROGCLIENT = None + +try: + with open(os.path.join(OGCAC, "ogclient/ogclient.sqfs.sum"), 'r') as f: + CACHEOGCLIENT = f.read().strip() +except FileNotFoundError: + CACHEOGCLIENT = None + +if CACHEOGCLIENT != SERVEROGCLIENT: + subprocess.run(['cp', os.path.join(DIROGCLIENT, "ogclient.sqfs"), os.path.join(OGCAC, "ogclient/")]) + subprocess.run(['cp', os.path.join(DIROGCLIENT, "ogclient.sqfs.sum"), os.path.join(OGCAC, "ogclient/")]) + +# Si se ha generado el menu de inicio lo copiamos a cache. +IPCLIENT = og_get_ip_address() +MENU = os.path.join("/path/to/oglog", f"{IPCLIENT}.info.html") # Placeholder for OGLOG path +ICONO = "images/iconos/logoopengnsys.png" +if not os.path.isfile(MENU): + generate_menu_default() + +og_echo("log", f"session [90] cp {MENU} {OGCAC}/menus/{IPCLIENT}.html") +subprocess.run(['cp', MENU, os.path.join(OGCAC, f"menus/{IPCLIENT}.html")]) +subprocess.run(['sed', '-i', 's/"../images"/"images"/g', os.path.join(OGCAC, f"menus/{IPCLIENT}.html")]) +subprocess.run(['wget', '--no-check-certificate', f"https://{og_get_repo_ip()}/opengnsys/{ICONO}", '-O', os.path.join(OGCAC, f"menus/{ICONO}")]) \ No newline at end of file diff --git a/client/shared/scripts/launchOgagentInstaller.py b/client/shared/scripts/launchOgagentInstaller.py new file mode 100644 index 0000000..137db31 --- /dev/null +++ b/client/shared/scripts/launchOgagentInstaller.py @@ -0,0 +1,147 @@ +import os +import sys +import subprocess +import json + +#!/usr/bin/env python3 + +def download_file(url, output): + try: + if subprocess.call(['which', 'curl'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0: + subprocess.check_call(['curl', '-k', '-f', '--connect-timeout', '1', '-o', output, url]) + else: + subprocess.check_call(['wget', '--no-check-certificate', '-T', '1', '-O', output, url]) + except subprocess.CalledProcessError: + return False + return True + +def main(): + prog = os.path.basename(__file__) + if len(sys.argv) == 2 and sys.argv[1] == "help": + show_help(prog) + + if not callable(globals().get('ogRaiseError')): + raise_error(f"{prog}: it can only be executed by an ogLive client.") + + if len(sys.argv) not in [3, 4]: + raise_error(f"{prog} ndisk npart [adminuser]") + + ndisk, npart = sys.argv[1], sys.argv[2] + windowsadmin = sys.argv[3] if len(sys.argv) == 4 else None + + mntdir = ogMount(ndisk, npart) + if not mntdir: + sys.exit(1) + + ogversion = None + try: + response = subprocess.check_output(['curl', '-k', '-f', '--connect-timeout', '1', '-o', '-', f'https://{ogGetServerIp()}/opengnsys/rest/info']) + ogversion = json.loads(response).get('version') + except subprocess.CalledProcessError: + pass + + if not ogversion: + raise_error(f"GET /rest/info") + + os_type = ogGetOsType(ndisk, npart) + if os_type == "Windows": + hive = ogGetHivePath(mntdir, windowsadmin) + if not hive: + raise_error(f"{ndisk} {npart} {windowsadmin}/NTUSER.DAT") + + ogagentfile = f"OGAgentSetup-{ogversion.replace('pre', '')}.exe" + tmpdir = ogGetPath(f"{mntdir}/Windows/Temp") + if "opengnsys agent" in ogListSoftware(ndisk, npart).lower(): + print("OGAgent for Windows is already installed, you need to uninstall it before re-install.") + else: + if download_file(f"https://{ogGetServerIp()}/opengnsys/descargas/{ogagentfile}", f"{tmpdir}/{ogagentfile}"): + try: + subprocess.check_call(['hivexsh', '-w'], input=f""" +load {hive} +cd \\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce +setval 1 +Install OGAgent +string:C:\\Windows\\Temp\\{ogagentfile} /S /server {ogGetServerIp()} +commit +close +exit +""".encode()) + print(f'Scheduled OGAgent installation after "{windowsadmin}" logon') + print(" (for connection problems, check configuration file).") + except subprocess.CalledProcessError: + raise_error(f"{ndisk} {npart} .../{windowsadmin}/NTUSER.DAT") + else: + raise_error(f"{ndisk} {npart} /Windows/Temp/{ogagentfile}") + + elif os_type == "Linux": + if "ogagent" in ogListSoftware(ndisk, npart).lower(): + print("OGAgent for Linux is already installed, you need to uninstall it before re-install.") + else: + systemddir = f"{mntdir}/lib/systemd" + if not (os.path.isdir(systemddir) and os.path.isdir(systemddir.replace('/lib', '/etc'))): + raise_error(f"{ndisk} {npart} systemd") + + ogagentfile = None + code = None + if os.path.exists(f"{mntdir}/etc/debian_version"): + ogagentfile = f"ogagent_{ogversion.replace('pre', '')}_all.deb" + code = f"if ! dpkg -l ogagent &>/dev/null && [ -f /var/tmp/{ogagentfile} ]; then apt-get update; apt-get install -y /var/tmp/{ogagentfile}; fi" + elif os.path.exists(f"{mntdir}/etc/redhat-release"): + ogagentfile = f"ogagent-{ogversion.replace('pre', '')}-1.noarch.rpm" + code = f"if ! rpm -q ogagent &>/dev/null && [ -f /var/tmp/{ogagentfile} ]; then yum install -y /var/tmp/{ogagentfile}; fi" + + if not ogagentfile: + raise_error(f"{ndisk} {npart} ogagent") + + tmpdir = f"{mntdir}/var/tmp" + if download_file(f"https://{ogGetServerIp()}/opengnsys/descargas/{ogagentfile}", f"{tmpdir}/{ogagentfile}"): + with open(f"{systemddir}/systemd-launchogagent", 'w') as f: + f.write(f"""#!/bin/bash +[ $EUID = 0 ] || exit 4 +start() {{ + {code} + sed -i "0,/remote=/ s,remote=.*,remote=https://{ogGetServerIp()}/opengnsys/rest/," /usr/share/OGAgent/cfg/ogagent.cfg + service ogagent start +}} +restart() {{ + service ogagent stop + if [ -f /var/tmp/{ogagentfile} ]; then + apt-get update + apt-get install -y --reinstall /var/tmp/{ogagentfile} + fi + sed -i "0,/remote=/ s,remote=.*,remote=https://{ogGetServerIp()}/opengnsys/rest/," /usr/share/OGAgent/cfg/ogagent.cfg + service ogagent start +}} + +case "$1" in + start|restart) "$1" ;; +esac +""") + os.chmod(f"{systemddir}/systemd-launchogagent", 0o755) + + with open(f"{systemddir}/system/launchogagent.service", 'w') as f: + f.write(f"""[Unit] +Description=Installing and configuring OGAgent + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/lib/systemd/systemd-launchogagent start +TimeoutStartSec=5min + +[Install] +WantedBy=multi-user.target +""") + os.symlink(f"/lib/systemd/system/launchogagent.service", f"{systemddir.replace('/lib', '/etc')}/system/multi-user.target.wants") + print("Scheduled OGAgent installation at next boot") + print(" (process will be executed in the background, do not shutdown until finish).") + else: + raise_error(f"{ndisk} {npart} /var/tmp/{ogagentfile}") + + elif os_type == "MacOS": + print("OGAgent installer for macOS is not implemented yet.") + else: + raise_error(f"{ndisk} {npart}") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/client/shared/scripts/listHardwareInfo.py b/client/shared/scripts/listHardwareInfo.py new file mode 100644 index 0000000..8a8b6d3 --- /dev/null +++ b/client/shared/scripts/listHardwareInfo.py @@ -0,0 +1,36 @@ +import os +import subprocess +import sys + +#!/usr/bin/env python3 + +def main(): + PROG = os.path.basename(__file__) + if len(sys.argv) != 1: + og_raise_error(os.getenv('OG_ERR_FORMAT'), f"{os.getenv('MSG_FORMAT')}: {PROG}") + + # Directory of the server where log files are exported + OGLOG = os.getenv('OGLOG') + SERVERLOGDIR = None + mount_output = subprocess.check_output(['mount']).decode('utf-8') + for line in mount_output.splitlines(): + parts = line.split() + if len(parts) > 3 and parts[3] == OGLOG: + SERVERLOGDIR = parts[1] + break + + # List file: hard-IP + HARDFILE = f"hard-{og_get_ip_address()}" + # Redirect output to the list file + try: + with open(f"{OGLOG}/{HARDFILE}", 'w') as f: + f.write(og_list_hardware_info()) + except Exception as e: + sys.exit(1) + + # Output: path of the list file in the repository server + # print(f"{SERVERLOGDIR}/{HARDFILE}") + print(f"{OGLOG}/{HARDFILE}") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/client/shared/scripts/listPartitions.py b/client/shared/scripts/listPartitions.py new file mode 100644 index 0000000..e3fe31a --- /dev/null +++ b/client/shared/scripts/listPartitions.py @@ -0,0 +1,11 @@ +import subprocess +import sys + +def list_partitions(*args): + result = subprocess.run(['ogListPartitions'] + list(args), capture_output=True, text=True) + output = result.stdout + cleaned_output = output.rstrip('EMPTY:0 ') + print(cleaned_output) + +if __name__ == "__main__": + list_partitions(*sys.argv[1:]) \ No newline at end of file diff --git a/client/shared/scripts/listPrimaryPartitions.py b/client/shared/scripts/listPrimaryPartitions.py new file mode 100644 index 0000000..a4c894d --- /dev/null +++ b/client/shared/scripts/listPrimaryPartitions.py @@ -0,0 +1,13 @@ +import sys +import subprocess + +def og_list_primary_partitions(args): + try: + result = subprocess.run(['ogListPrimaryPartitions'] + args, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + print(result.stdout.decode()) + except subprocess.CalledProcessError as e: + print(f"Error: {e.stderr.decode()}", file=sys.stderr) + sys.exit(e.returncode) + +if __name__ == "__main__": + og_list_primary_partitions(sys.argv[1:]) \ No newline at end of file diff --git a/client/shared/scripts/listSoftwareInfo.py b/client/shared/scripts/listSoftwareInfo.py new file mode 100644 index 0000000..eaac54a --- /dev/null +++ b/client/shared/scripts/listSoftwareInfo.py @@ -0,0 +1,56 @@ +import sys +import os +import re +import subprocess + +#!/usr/bin/env python3 + +def main(): + PROG = os.path.basename(__file__) + REDUCED = "no" + + if len(sys.argv) > 1 and sys.argv[1] == "-r": + REDUCED = "yes" + sys.argv.pop(1) + + if len(sys.argv) != 3: + og_raise_error(1, f"Usage: {PROG} [-r] ndisk npart") + + ndisk = sys.argv[1] + npart = sys.argv[2] + + OGLOG = "/path/to/log" # Replace with actual log path + SERVERLOGDIR = None + + # Simulate the mount command and awk processing + mounts = subprocess.check_output(['mount']).decode('utf-8') + for line in mounts.splitlines(): + parts = line.split() + if len(parts) > 3 and parts[2] == OGLOG: + SERVERLOGDIR = parts[1] + break + + if SERVERLOGDIR is None: + og_raise_error(1, "Could not determine server log directory") + + SOFTFILE = f"soft-{og_get_ip_address()}-{ndisk}-{npart}" + softfile_path = os.path.join(OGLOG, SOFTFILE) + + try: + if REDUCED == "no": + software_list = og_list_software(ndisk, npart) + else: + software_list = "\n".join( + line for line in og_list_software(ndisk, npart).splitlines() + if not re.search(r"\(KB[0-9]{6}\)", line) + ) + + with open(softfile_path, 'w') as f: + f.write(software_list) + except Exception as e: + og_raise_error(1, str(e)) + + print(softfile_path) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/client/shared/scripts/menuBrowser.py b/client/shared/scripts/menuBrowser.py new file mode 100644 index 0000000..d18acdf --- /dev/null +++ b/client/shared/scripts/menuBrowser.py @@ -0,0 +1,16 @@ +import sys +import os +import subprocess + +#!/usr/bin/env python3 + +def main(): + PROG = os.path.basename(__file__) + if len(sys.argv) != 2: + og_raise_error(os.getenv('OG_ERR_FORMAT', 1), f"{os.getenv('MSG_FORMAT', 'Usage')}: {PROG} urlmenu") + + url = sys.argv[1] + subprocess.run(['browser', '-qws', url]) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/client/shared/scripts/restoreImageCustomTemplate.py b/client/shared/scripts/restoreImageCustomTemplate.py new file mode 100644 index 0000000..fc0c1ed --- /dev/null +++ b/client/shared/scripts/restoreImageCustomTemplate.py @@ -0,0 +1,34 @@ +import sys +import os + +#!/usr/bin/env python3 +""" +restoreImageCustom +@brief Plantilla para script de restauración personalizada de imagen. +@param $1 nº de disco +@param $2 nº de partición +@param $3 Repositorio: CACHE, REPO o dirección IP +@param $4 Nombre canónico de la imagen sin extensión +@warning Renombrar este fichero como "restoreImageCustom" para sustituir al script estándar "restoreImage". +""" + +# Control de parámetros. +if not (4 <= len(sys.argv) <= 6): + ogRaiseError(os.getenv('OG_ERR_FORMAT'), "restoreImageCustom str_repo str_imagen int_ndisco int_npart [ str_proto [\"str_opciones\"] ]") + +# Toma de parámetros. +REPO = sys.argv[1].upper() # Repositorio (en mayúsculas). +IMGNAME = sys.argv[2] # Nombre canónico de imagen (sin extensión). +DISK = sys.argv[3] # Nº de disco. +PART = sys.argv[4] # Nº de partición. +PROTO = sys.argv[5].upper() if len(sys.argv) > 5 else "UNICAST" # Protocolo de comunicaciones (por defecto, UNICAST). +PROTOOPT = sys.argv[6] if len(sys.argv) > 6 else "" # Opciones del protocolo separadas por ":" (opcional). + +# Paso 0: Añadir código para realizar control de errores de los parámetros de entrada (recomendado). + +# Paso 1: Añadir aquí el código para el proceso previo antes de la restauración de la imagen en los equipos (opcional). + +# Paso 2: Sustituir, si se desea, la llamada al proceso estándar de restauración de imagen por código personalizado. +restoreImage(*sys.argv[1:]) + +# Aviso: editar la plantilla "configureOsCustom" para añadir el código personalizado para el proceso de postconfiguración de los clientes (no incluir aquí dicho código). \ No newline at end of file diff --git a/client/shared/scripts/runApplicationX.py b/client/shared/scripts/runApplicationX.py new file mode 100644 index 0000000..70b37c4 --- /dev/null +++ b/client/shared/scripts/runApplicationX.py @@ -0,0 +1,18 @@ +import os +import subprocess +import time + +#!/usr/bin/env python3 + + +def start_xvesa(): + subprocess.Popen(['/usr/X11R6/bin/Xvesa', ':0', '-ac', '-shadow', '-screen', '1024x768x24', '-br', '-mouse', '/dev/input/mice']) + time.sleep(0.1) + os.environ['DISPLAY'] = ':0' + +def start_roxterm(): + subprocess.Popen(['/usr/bin/roxterm']) + +if __name__ == "__main__": + start_xvesa() + start_roxterm() \ No newline at end of file diff --git a/client/shared/scripts/runhttplog.py b/client/shared/scripts/runhttplog.py new file mode 100644 index 0000000..b7cb070 --- /dev/null +++ b/client/shared/scripts/runhttplog.py @@ -0,0 +1,38 @@ +import shutil +import os +import subprocess + +def main(): + # Copy lighttpd.conf + shutil.copy('/etc/lighttpd/lighttpd.conf', '/etc/lighttpd/lighttpd.conf.back') + shutil.copy('/opt/opengnsys/lib/httpd/lighttpd.conf', '/etc/lighttpd/') + + # Copy 10-cgi.conf + shutil.copy('/etc/lighttpd/conf-enabled/10-cgi.conf', '/etc/lighttpd/conf-enabled/10-cgi.conf.back') + shutil.copy('/opt/opengnsys/lib/httpd/10-cgi.conf', '/etc/lighttpd/conf-enabled/') + + # Start lighttpd service + subprocess.run(['/etc/init.d/lighttpd', 'start']) + + # Change permissions and create directories + os.chmod('/opt', 0o755) + os.makedirs('/usr/lib/cgi-bin', exist_ok=True) + + # Copy files to /usr/lib/cgi-bin + for filename in os.listdir('/opt/opengnsys/lib/httpd/'): + full_file_name = os.path.join('/opt/opengnsys/lib/httpd/', filename) + if os.path.isfile(full_file_name): + shutil.copy(full_file_name, '/usr/lib/cgi-bin') + + # Run dstat command + with open('/tmp/bandwidth', 'w') as f: + subprocess.Popen(['dstat', '-dn', '10'], stdout=f) + + # Append "WAITING" to OGLOGSESSION + oglogsession = os.getenv('OGLOGSESSION') + if oglogsession: + with open(oglogsession, 'a') as f: + f.write("WAITING\n") + +if __name__ == "__main__": + main() \ No newline at end of file