From 6617bace74321350ce7328a43c93c786014ae880 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Wed, 16 Jul 2025 13:23:12 +0200 Subject: [PATCH] refs #2468 add python init scripts --- CHANGELOG.md | 6 + ogclient/etc/init.py | 49 +++++ ogclient/etc/preinit.py | 43 ++++ ogclient/etc/preinit/default.sh | 7 + ogclient/lib/python3/DiskLib.py | 4 +- ogclient/lib/python3/ImageLib.py | 2 +- ogclient/lib/python3/InitLib.py | 352 ++++++++++++++++++++++++++++++ ogclient/lib/python3/NetLib.py | 7 +- ogclient/lib/python3/SystemLib.py | 2 +- ogclient/lib/python3/ogGlobals.py | 2 +- ogclient/scripts/poweroff | 81 +++++-- ogclient/scripts/reboot | 55 +---- ogclient/scripts/runhttplog.py | 38 ---- 13 files changed, 523 insertions(+), 125 deletions(-) create mode 100755 ogclient/etc/init.py create mode 100755 ogclient/etc/preinit.py create mode 100644 ogclient/lib/python3/InitLib.py mode change 100755 => 120000 ogclient/scripts/reboot delete mode 100755 ogclient/scripts/runhttplog.py diff --git a/CHANGELOG.md b/CHANGELOG.md index b3a81da..a3e7dbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.27.0] - 2025-07-16 + +### Added + +- Add python init scripts + ## [0.26.1] - 2025-07-14 ### Changed diff --git a/ogclient/etc/init.py b/ogclient/etc/init.py new file mode 100755 index 0000000..1a0597e --- /dev/null +++ b/ogclient/etc/init.py @@ -0,0 +1,49 @@ +#!/usr/bin/python3 +# Proceso general de arranque de OpenGnsys Client. + +import os +import re +import subprocess + +import ogGlobals +from NetLib import ogGetIpAddress + +ogstatus = os.environ.get ('ogstatus', '') +ogcore = os.environ.get ('ogcore', '') +oglog = os.environ.get ('oglog', '') +oggroup = os.environ.get ('OGGROUP', '') +ogactiveadmin = os.environ.get ('ogactiveadmin', '') +LANG = os.environ.get ('LANG', 'es_ES') +LANG = LANG[0:LANG.index('_')] + +LOGLEVEL=5 + +# Matando plymount para inicir browser o shell +subprocess.run (['pkill', '-9', 'plymouthd']) + +# Arranque de OpenGnsys Client daemon (socket). +print (ogGlobals.lang.MSG_LAUNCHCLIENT) +# Indicar fichero de teclado de Qt para el idioma especificado (tipo "es.qmap"). +if os.path.exists (f'/usr/local/etc/{LANG}.qmap'): + os.environ['QWS_KEYBOARD'] = f'TTY:keymap=/usr/local/etc/{LANG}.qmap' + +if os.path.exists ('/usr/share/OGAgent/opengnsys/linux/OGAgentService.py') and ogstatus != 'offline': + os.chdir ('/usr/share/OGAgent') + os.environ['OGAGENTCFG_OGCORE_IP'] = ogcore + os.environ['OGAGENTCFG_OGLOG_IP'] = oglog + os.environ['OGAGENTCFG_URLMENU_SCHEME'] = 'http' + os.environ['OGAGENTCFG_URLMENU_IP'] = '127.0.0.1' + os.environ['OGAGENTCFG_URLMENU_PORT'] = '81' + subprocess.run (['python3', '-m', 'opengnsys.linux.OGAgentService', 'fg']) +else: + ip = ogGetIpAddress() + OGMENU = '' + for FILE in [index, oggroup, ip]: + if not FILE: continue + m = f'{ogGlobals.OGCAC}/menus/{FILE}.html' + if os.path.exists (m): OGMENU = m + subprocess.run ([f'{ogGlobals.OPENGNSYS}/bin/launch_browser', m]) + +# Si fallo en cliente y modo "admin", cargar shell; si no, salir. +if ogactiveadmin == 'true': + subprocess.run (['bash']) diff --git a/ogclient/etc/preinit.py b/ogclient/etc/preinit.py new file mode 100755 index 0000000..d2b7e12 --- /dev/null +++ b/ogclient/etc/preinit.py @@ -0,0 +1,43 @@ +#!/usr/bin/python3 + +## early init +import os +import sys +OPENGNSYS = os.environ.get ('OPENGNSYS', '/opt/opengnsys') +os.environ['PYTHONPATH'] = f'{OPENGNSYS}/lib/python3' +sys.path.insert (0, os.environ['PYTHONPATH']) +## end + +import subprocess + +import ogGlobals +from InitLib import loadenviron, write_profile, clean_esp, fileslinks, loadmodules, metadevs, mountrepo, poweroff, filebeat, stunnel, dbus, otherservices, runhttplog + +IPV4ADDR = os.environ.get ('IPV4ADDR', '') +OG_IP = os.environ.get ('OG_IP', '') + +loadenviron() +write_profile() + +# Funciones de inicio. +clean_esp() +fileslinks() +loadmodules() +metadevs() +mountrepo() +poweroff() +filebeat() +stunnel() +dbus() +otherservices() +runhttplog() + +if IPV4ADDR and os.path.exists (f'{ogGlobals.OGETC}/init/{IPV4ADDR}.sh'): + if OG_IP: subprocess.run ([f'{ogGlobals.OGETC}/init/{OG_IP}.sh']) + +elif os.path.exists (f'{ogGlobals.OGETC}/init.py'): + subprocess.run ([f'{ogGlobals.OGETC}/init.py']) + +else: + print ('No se ha encontrado script de inicio') + subprocess.run (['halt']) diff --git a/ogclient/etc/preinit/default.sh b/ogclient/etc/preinit/default.sh index 3740c30..1c19da4 100755 --- a/ogclient/etc/preinit/default.sh +++ b/ogclient/etc/preinit/default.sh @@ -1,5 +1,12 @@ #!/bin/bash +if grep -q pyinit=true /proc/cmdline; then + echo "python init" + exec /opt/opengnsys/etc/preinit/default.py +else + echo "shell init" +fi + # Cargar entorno de OpenGnsys set -a source /opt/opengnsys/etc/preinit/loadenviron.sh diff --git a/ogclient/lib/python3/DiskLib.py b/ogclient/lib/python3/DiskLib.py index f1130af..bdd27ac 100644 --- a/ogclient/lib/python3/DiskLib.py +++ b/ogclient/lib/python3/DiskLib.py @@ -737,9 +737,9 @@ def ogGetPartitionActive (disk): break if lang is None: - del os.environ['LANG'] + if 'LANG' in os.environ: del os.environ['LANG'] else: - os.environ['LAMG'] = lang + os.environ['LANG'] = lang return ret diff --git a/ogclient/lib/python3/ImageLib.py b/ogclient/lib/python3/ImageLib.py index f590e38..07eb212 100644 --- a/ogclient/lib/python3/ImageLib.py +++ b/ogclient/lib/python3/ImageLib.py @@ -635,7 +635,7 @@ def ogGetImageInfo (imgfile): if lc_all is not None: os.environ["LC_ALL"] = lc_all else: - del os.environ["LC_ALL"] + if "LC_ALL" in os.environ: del os.environ["LC_ALL"] if 'size' in partclone_info: tools = 'PARTCLONE' diff --git a/ogclient/lib/python3/InitLib.py b/ogclient/lib/python3/InitLib.py new file mode 100644 index 0000000..b891dd0 --- /dev/null +++ b/ogclient/lib/python3/InitLib.py @@ -0,0 +1,352 @@ +#!/usr/bin/python3 + +import os +import glob +import stat +import shutil +import re +import subprocess + +import ogGlobals +from InventoryLib import ogIsEfiActive +from DiskLib import ogGetEsp +from FileSystemLib import ogMount, ogUnmount + +## sets envvar and writes to /etc/environment +def env_export (k, v): + os.environ[k] = str (v) + already_present = False + with open ('/etc/environment', 'r') as env_fd: + for line in env_fd: + if re.search (f'^{k}=', line): + already_present = True + break + if not already_present: + with open ('/etc/environment', 'a') as env_fd: + env_fd.write (f'{k}={v}\n') + return v + +def loadenviron(): + # Idioma por defecto. + LANG = os.environ.get ('LANG', 'es_ES') + env_export ('LANG', 'es_ES') + + # Directorios del proyecto OpenGnsys. + OPENGNSYS = os.environ.get ('OPENGNSYS', '/opt/opengnsys') + env_export ('OPENGNSYS', OPENGNSYS) + + OGBIN = env_export ('OGBIN', f'{OPENGNSYS}/bin') + OGETC = env_export ('OGETC', f'{OPENGNSYS}/etc') + OGLIB = env_export ('OGLIB', f'{OPENGNSYS}/lib') + OGAPI = env_export ('OGAPI', f'{OGLIB}/engine/bin') + OGPYFUNCS = env_export ('OGPYFUNCS', f'{OPENGNSYS}/functions') + OGSCRIPTS = env_export ('OGSCRIPTS', f'{OPENGNSYS}/scripts') + OGIMG = env_export ('OGIMG', f'{OPENGNSYS}/images') + OGCAC = env_export ('OGCAC', f'{OPENGNSYS}/cache') + OGLOG = env_export ('OGLOG', f'{OPENGNSYS}/log') + + # Exportar parámetros del kernel. + with open ('/proc/cmdline', 'r') as fd: cmdline = fd.read() + kvars = cmdline.split() + for kvar in kvars: + if '=' not in kvar: continue + k, v = kvar.split ('=') + env_export (k, v) + + OGSERVERIMAGES = os.environ.get ('OGSERVERIMAGES', '') + if 'ROOTREPO' not in os.environ or not os.environ.get ('ROOTREPO'): + env_export ('ROOTREPO', OGSERVERIMAGES) + + # Compatibilidad para usar proxy en clientes ogLive. + http_proxy = os.environ.get ('http_proxy', '') + ogproxy = os.environ.get ('ogproxy', '') + if not http_proxy and ogproxy: + env_export ('http_proxy', ogproxy) + +def write_profile(): + ## si estos accesos a os.environ fallan, es porque loadenviron() no se ejecutó + OGSCRIPTS = os.environ['OGSCRIPTS'] + OGPYFUNCS = os.environ['OGPYFUNCS'] + OGBIN = os.environ['OGBIN'] + PYTHONPATH = os.environ['PYTHONPATH'] + LANG = os.environ['LANG'] + + PATH = os.environ.get ('PATH', '') + + L = LANG[0:LANG.index('_')] + with open ('/etc/profile.d/ogprofile.sh', 'w') as fd: + fd.write (f''' +(locale-gen {LANG} &>/dev/null &) +export PATH={OGSCRIPTS}:{OGPYFUNCS}:{OGBIN}:{PATH}:/opt/oglive/rootfs/opt/drbl/sbin +export PYTHONPATH={PYTHONPATH} +sysctl -p &>/dev/null +loadkeys {L} >/dev/null +if [ ! -f /run/resolvconf/resolv.conf -a -n "$ogdns" ]; then + mkdir -p /run/resolvconf + echo "nameserver $ogdns" > /run/resolvconf/resolv.conf +fi + '''.strip() + '\n') + +def clean_esp(): + ## BootLib.bootOs() makes a copy of grub.cfg in /boot/grub within the ESP + ## clean it up + if ogIsEfiActive(): + esp = ogGetEsp() + if esp: + esp_disk, esp_par = esp.split() + mntpt = ogMount (esp_disk, esp_par) + os.unlink (f'{mntpt}/boot/grub/grub.cfg') + ogUnmount (esp_disk, esp_par) + +def fileslinks(): + print (ogGlobals.lang.MSG_MAKELINKS) + + # Shell BASH por defecto (para usar "runtest") + if os.path.exists ('/bin/sh'): os.unlink ('/bin/sh') + os.symlink ('/bin/bash', '/bin/sh') + + # Crear directorio de bloqueos + ## for some reason we need try/catch even when using 'exist_ok=True' + try: os.makedirs ('/var/lock', exist_ok=True) + except FileExistsError: pass + try: os.makedirs ('/run/lock', exist_ok=True) + except FileExistsError: pass + + # Crear ficheros temporales. + for f in [ogGlobals.OGLOGCOMMAND, ogGlobals.OGLOGCOMMAND + '.tmp', ogGlobals.OGLOGSESSION, '/tmp/menu.tmp']: + open (f, 'w').close() + os.chmod (f, 0o777) + + # Enlaces para Qt Embeded. + # son cosas de QT4, ya no aplica + + # Autenticación con clave pública para SSH + if os.path.exists ('/scripts/ssl/authorized_keys'): + for f in glob.glob ('/scripts/ssl/*'): + shutil.copy2 (f, '/root/.ssh/') + +def loadmodules(): + print (ogGlobals.lang.MSG_LOADMODULES) + + # Módulo del ratón. + subprocess.run (['modprobe', 'psmouse'], stderr=subprocess.DEVNULL) + + # Cargar módulos específicos del kernel del cliente. + uname_r = os.uname()[2] + for m in glob.glob (f'{ogGlobals.OGLIB}/modules/{uname_r}/*.ko'): + subprocess.run (['insmod', m], capture_output=True) + +def metadevs(): + print (ogGlobals.lang.MSG_DETECTLVMRAID) + subprocess.run (['vgchange', '-ay'], capture_output=True) # Detectar metadispositivos LVM. + subprocess.run (['dmraid', '-ay'], capture_output=True) # Detectar metadispositivos RAID. + +def mountrepo(): + ## si estos accesos a os.environ fallan, es porque loadenviron() no se ejecutó + ROOTREPO = os.environ['ROOTREPO'] + + ROOTSERVER = os.environ.get ('ROOTSERVER', '') + ogactiveadmin = os.environ.get ('ogactiveadmin', '') + ogprotocol = os.environ.get ('ogprotocol', '') + ogstatus = os.environ.get ('ogstatus', '') + SERVER = os.environ.get ('SERVER', '') + if not ROOTREPO: ROOTREPO = ROOTSERVER + + # TODO Revisar proceso de arranque para no montar 2 veces el repositorio. + if 'true' == ogactiveadmin: + os.environ['boot'] = 'admin' # ATENCIÓN: siempre en modo "admin". + subprocess.run (['umount', ogGlobals.OGIMG], stderr=subprocess.DEVNULL) + + if 'nfs' == ogprotocol: + subprocess.run (['mount.nfs', f'{ROOTREPO}:{ogGlobals.OGIMG}', ogGlobals.OGIMG, '-o', 'rw,nolock']) + + elif 'smb' == ogprotocol: + PASS = subprocess.run ('grep "^[ \t]*\\(export \\)\\?OPTIONS=" /scripts/ogfunctions 2>&1 | sed "s/\\(.*\\)pass=\\(\\w*\\)\\(.*\\)/\\2/"', shell=True, capture_output=True, text=True).stdout.strip() + if not PASS: PASS = 'og' + subprocess.run (['mount.cifs', f'//{ROOTREPO}/ogimages', ogGlobals.OGIMG, '-o', f'rw,serverino,acl,username=opengnsys,password={PASS}']) + + elif 'local' == ogprotocol: # TODO: hacer funcion dentro de este script que monte smb + # Comprobamos que estatus sea online. + if 'offline' == ogstatus or '' == SERVER: + # Si estatus es offline buscamos un dispositivo con etiqueta repo + # y si no existe montamos la cache como repo (si existe). + TYPE = subprocess.run ('blkid | grep REPO | awk -F"TYPE=" \'{print $2}\' | tr -d \\"', shell=True, capture_output=True, text=True).stdout.strip() + if '' == TYPE: + cac_img = f'{ogGlobals.OGCAC}/{ogGlobals.OGIMG}' + if os.path.isdir (cac_img): + subprocess.run (['mount', '--bind', cac_img, ogGlobals.OGIMG]) + else: + subprocess.run (['mount', '-t', TYPE, 'LABEL=REPO', ogGlobals.OGIMG]) + else: + # Comprobamos que existe un servicio de samba. + rc = subprocess.run (['smbclient', '-L', SERVER, '-N'], capture_output=True, text=True).returncode + if not rc: ## success + PASS = subprocess.run ('grep "^[ \t]*\\(export \\)\\?OPTIONS=" /scripts/ogfunctions 2>&1 | sed "s/\\(.*\\)pass=\\(\\w*\\)\\(.*\\)/\\2/"', shell=True, capture_output=True, text=True).stdout.strip() + if not PASS: PASS = 'og' + subprocess.run (['mount.cifs', f'//{ROOTREPO}/ogimages', ogGlobals.OGIMG, '-o', f'rw,serverino,acl,username=opengnsys,password={PASS}']) + +def poweroff(): + ogntp = os.environ.get ('ogntp', '') + status = os.environ.get ('status', '') + + print (ogGlobals.lang.MSG_POWEROFFCONF) + # Sincronización horaria con servidor NTP. + if ogntp and 'offline' != status: + subprocess.run (['ntpdate', ogntp]) + + # Crear fichero de configuración por defecto (30 min. de espera). + POWEROFFCONF = '/etc/poweroff.conf' + with open (POWEROFFCONF, 'w') as fd: + fd.write (f''' +POWEROFFSLEEP=30 +POWEROFFTIME= + '''.strip() + '\n') + # Incluir zona horaria en el fichero de configuración. + awk_out = subprocess.run (['awk', 'BEGIN {RS=" "} /^TZ=/ {print}', '/proc/cmdline'], capture_output=True, text=True).stdout.strip() + with open (POWEROFFCONF, 'a') as fd: + fd.write (awk_out + '\n') + + # Lanzar el proceso "cron". + subprocess.run (['cron', '-l']) + + # Definir la "crontab" lanzando el proceso de comprobación cada minuto. + crontab_entry = f'* * * * * [ -x {ogGlobals.OGBIN}/poweroffconf ] && {ogGlobals.OGBIN}/poweroffconf\n' + subprocess.run (['crontab', '-'], input=crontab_entry, text=True) + +def filebeat(): + oglog = os.environ.get ('oglog', '') + F = '/etc/filebeat/filebeat.yml' + OPENSEARCH_PORT = '9200' + + if not os.path.exists (F): return + + PASS = subprocess.run ('grep "^[ \t]*\\(export \\)\\?OPTIONS=" /scripts/ogfunctions 2>&1 | sed "s/\\(.*\\)pass=\\(\\w*\\)\\(.*\\)/\\2/"', shell=True, capture_output=True, text=True).stdout.strip() ## taken from a sibling script + if not PASS: PASS = 'og' + ogkdf = subprocess.run (f'echo -n {PASS} |sha256sum |cut -c1-12', shell=True, capture_output=True, text=True).stdout.strip() + PASS = 'OG+' + ogkdf + + os.chmod (F, 0o600) + subprocess.run (['sed', '-i', + '-e', f's/__OGLOG_IP/{oglog}/g', + '-e', f's/__OGLOG_PORT__/{OPENSEARCH_PORT}/g', + '-e', f's/__OPENSEARCH_PASSWORD__/{PASS}/g', + F + ]) + + os.makedirs ('/var/log/filebeat', exist_ok=True) + subprocess.Popen (['/usr/bin/filebeat', '-c', F, '--path.home', '/usr/share/filebeat', '--path.config', '/etc/filebeat', '--path.data', '/var/lib/filebeat', '--path.logs', '/var/log/filebeat']) + +def stunnel(): + ogcore = os.environ.get ('ogcore', '') + ogusetls = os.environ.get ('ogusetls', '') + ogverifytls = os.environ.get ('ogverifytls', '') + + with open ('/etc/stunnel/menu.conf', 'w') as fd: fd.write (f''' +setuid = stunnel4 +setgid = stunnel4 +pid = /var/run/stunnel4/menu.pid +foreground = yes +debug = info + +[menu] +client = yes +accept = 127.0.0.1:81 +connect = {ogcore}:8443 + '''.strip() + '\n') + if 'true' == ogusetls: + if 'true' == ogverifytls: + ## use tls and verify + with open ('/etc/stunnel/menu.conf', 'a') as fd: fd.write (f''' +cert = /opt/opengnsys/etc/ogagent.crt +key = /opt/opengnsys/etc/ogagent.key +CAfile = /opt/opengnsys/etc/ca.crt +requireCert = yes +verifyChain = yes + '''.strip() + '\n') + else: + ## use tls but not verify + with open ('/etc/stunnel/menu.conf', 'a') as fd: fd.write (f''' +cert = /opt/opengnsys/etc/ogagent.crt +key = /opt/opengnsys/etc/ogagent.key +CAfile = /opt/opengnsys/etc/ca.crt +requireCert = no +verifyChain = no + '''.strip() + '\n') + else: + ## don't use tls + with open ('/etc/stunnel/menu.conf', 'a') as fd: fd.write (f''' +requireCert = no +verifyChain = no + '''.strip() + '\n') + + os.makedirs ('/var/run/stunnel4', exist_ok=True) + shutil.chown ('/var/run/stunnel4', 'stunnel4', 'stunnel4') + with open ('/var/log/stunnel4/menu.log', 'a') as stunnel_log_fd: + subprocess.Popen (['stunnel', '/etc/stunnel/menu.conf'], stdout=stunnel_log_fd, stderr=subprocess.STDOUT) + +def dbus(): + if os.path.exists ('/etc/dbus-1/system.d/ogbrowser.conf'): + os.makedirs ('/run/dbus', exist_ok=True) + dbus_addr = subprocess.run (['dbus-daemon', '--print-address', '--system', '--nosyslog'], capture_output=True, text=True).stdout.strip() + env_export ('DBUS_SESSION_BUS_ADDRESS', dbus_addr) + with open ('/var/log/dbus-monitor.log', 'w') as dbus_mon_fd: + subprocess.Popen (['dbus-monitor', '--system'], stdout=dbus_mon_fd, stderr=subprocess.STDOUT) + +def otherservices(): + DEVICE = os.environ.get ('DEVICE', '') + + if ogIsEfiActive(): + subprocess.run (['mount', '-t', 'efivarfs', 'none', '/sys/firmware/efi/efivars']) + + print (ogGlobals.lang.MSG_OTHERSERVICES) + + if os.path.exists ('/dev/log') and not stat.S_ISSOCK (os.stat ('/dev/log').st_mode): + subprocess.run (['service', 'rsyslog', 'start']) + + # root password + PASS = subprocess.run ('grep "^[ \t]*\\(export \\)\\?OPTIONS=" /scripts/ogfunctions 2>&1 | sed "s/\\(.*\\)pass=\\(\\w*\\)\\(.*\\)/\\2/"', shell=True, capture_output=True, text=True).stdout.strip() + if not PASS: PASS = 'og' + subprocess.run (['passwd', 'root'], input=f'{PASS}\n{PASS}\n', stderr=subprocess.DEVNULL, text=True) + + subprocess.run (['/etc/init.d/ssh', 'start'], capture_output=True, text=True) + + #setterm -blank 0 -powersave off -powerdown 0 < /dev/console > /dev/console 2>&1 ## apagado de monitor + subprocess.run (['ethtool', '-s', DEVICE, 'wol', 'g'], stderr=subprocess.DEVNULL) ## Activado WOL en la interfaz usada en arranque PXE. + +def runhttplog(): + ## si estos accesos a os.environ fallan, es porque loadenviron() no se ejecutó + OPENGNSYS = os.environ['OPENGNSYS'] + + try: + shutil.copy2 ('/etc/lighttpd/lighttpd.conf', '/etc/lighttpd/lighttpd.conf.back') + shutil.copy2 ('/etc/lighttpd/conf-enabled/10-cgi.conf', '/etc/lighttpd/conf-enabled/10-cgi.conf.back') + except FileNotFoundError: + pass + + shutil.copy2 (f'{OPENGNSYS}/lib/httpd/lighttpd.conf', '/etc/lighttpd/') + shutil.copy2 (f'{OPENGNSYS}/lib/httpd/10-cgi.conf', '/etc/lighttpd/conf-enabled/') + + subprocess.run (['/etc/init.d/lighttpd', 'start'], capture_output=True) + + o = OPENGNSYS + while '/' != o: + os.chmod (o, 0o755) + o = os.path.dirname (o) + os.makedirs ('/usr/lib/cgi-bin', exist_ok=True) + + for filename in os.listdir (f'{OPENGNSYS}/lib/httpd/'): + full_file_name = os.path.join (f'{OPENGNSYS}/lib/httpd/', filename) + if os.path.isfile (full_file_name): + shutil.copy2 (full_file_name, '/usr/lib/cgi-bin') + + ## dstat fails because /var/lib/pcp/pmns/root does not exist. + ## we work around that by starting/stopping pmcd once. When it starts, it creates the missing file. + if not os.path.exists ('/var/lib/pcp/pmns/root'): + subprocess.run (['/etc/init.d/pmcd', 'start'], capture_output=True) + subprocess.run (['/etc/init.d/pmcd', 'stop'], capture_output=True) + + with open ('/tmp/bandwidth', 'w') as f: + subprocess.Popen (['dstat', '-dn', '10'], stdout=f) + + with open (ogGlobals.OGLOGSESSION, 'a') as fd: + fd.write ('WAITING\n') diff --git a/ogclient/lib/python3/NetLib.py b/ogclient/lib/python3/NetLib.py index 0223a18..f36d342 100644 --- a/ogclient/lib/python3/NetLib.py +++ b/ogclient/lib/python3/NetLib.py @@ -255,7 +255,7 @@ def ogGetRepoIp(): #@note Comprobacion segun protocolo de conexion al Repo #*/ ## def ogGetServerIp(): - return os.environ['ogcore'] + return os.environ.get ('ogcore', '') #/** # ogGetServerPort @@ -263,10 +263,7 @@ def ogGetServerIp(): #@return str_port - Puerto #*/ ## def ogGetServerPort(): - if 'ogcore_port' in os.environ: - return os.environ['ogcore_port'] - else: - return '8443' + return os.environ.get ('ogcore_port', '8443') #/** diff --git a/ogclient/lib/python3/SystemLib.py b/ogclient/lib/python3/SystemLib.py index 29884e2..da2da5e 100644 --- a/ogclient/lib/python3/SystemLib.py +++ b/ogclient/lib/python3/SystemLib.py @@ -178,7 +178,7 @@ def ogGetCaller(): caller = words[0].lstrip("-") if cols is None: - del (os.environ['COLUMNS']) + if 'COLUMNS' in os.environ: del os.environ['COLUMNS'] else: os.environ['COLUMNS'] = cols diff --git a/ogclient/lib/python3/ogGlobals.py b/ogclient/lib/python3/ogGlobals.py index 5278c5b..5ead1e5 100644 --- a/ogclient/lib/python3/ogGlobals.py +++ b/ogclient/lib/python3/ogGlobals.py @@ -45,7 +45,7 @@ MCASTWAIT=30 # timeout (segundos) para abortar la la tran #FACTORSYNC=120 # Factor de compresion para las imagenes (windos en ext4). #BACKUP=False # Realizar copia de seguridad antes de crear la imagen. #IMGFS='EXT4' # Sistema de archivo de la imagenes sincronizadas. EXT4 o BTRFS -#OGSLEEP=20 # Tiempo de sleep antes de realizar el reboot +OGSLEEP=4 # Tiempo de sleep antes de realizar el reboot NODEBUGFUNCTIONS=['ogCreateImageSyntax', 'ogGetHivePath', 'ogGetOsType', 'ogRestoreImageSyntax', 'ogUnmountAll', 'ogUnmountCache'] # Funciones que no deben mostrar salida de avisos si son llamadas por otras funciones. #DEFAULTSPEED='' ## /engine.cfg diff --git a/ogclient/scripts/poweroff b/ogclient/scripts/poweroff index 4233058..eb6cc12 100755 --- a/ogclient/scripts/poweroff +++ b/ogclient/scripts/poweroff @@ -1,39 +1,74 @@ -#!/bin/bash -# Scirpt de ejemplo para apagar un ordenador -# Nota: se usa como base para el programa de apagado de OpenGnsys Admin. +#!/usr/bin/python3 +import os +import sys +import shutil +import time +import subprocess -# Registrar ejecución manual de script. -case "$(ogGetCaller)" in - browser|bash) ogEcho log info "Script: $0" ;; -esac +import ogGlobals +from SystemLib import ogGetCaller, ogEcho +from DiskLib import ogDiskToDev +from FileSystemLib import ogUnmountAll +from CacheLib import ogUnmountCache + +DEVICE = os.environ.get ('DEVICE', '') +ogstatus = os.environ.get ('ogstatus', '') + +PROG = os.path.basename (sys.argv[0]) +is_reboot = 'reboot'==PROG + +TIME = None +try: + TIME = int (sys.argv[1]) +except: + pass + +# Registrar ejecución manual de script. +c = ogGetCaller() +if c in ['browser', 'OGBrowser', 'bash']: + ogEcho ('log', 'info', f'Script: {PROG}') + +# Cargamos el valor por defecto del tiempo de sleep +if TIME: + print (f'[5] Se ha introducido un retardo de {TIME} segundos para reiniciar') +else: + TIME = ogGlobals.OGSLEEP + print (f'[5] No se ha introducido un retardo, {TIME} segundos para reiniciar') # No registrar errores. -export DEBUG="no" +#DEBUG=no # Desmontar los sistemas de archivos y la caché local. -echo "[10] Desmontar todos los sistemas de archivos." -sync -for (( i=1; i <= $(ogDiskToDev | wc -w); i++ )); do - ogUnmountAll $i &>/dev/null -done -echo "[50] Desmontar cache local." -ogUnmountCache &>/dev/null +print ('[10] Desmontar todos los sistemas de archivos.') +subprocess.run (['sync']) +ndisks = len (ogDiskToDev()) +for d in range (1, ndisks+1): + ogUnmountAll (d) +print ('[50] Desmontar cache local.') +ogUnmountCache() # Volver a registrar errores. -unset DEBUG +#DEBUG=yes -echo "[70] Apagando el equipo." +if is_reboot: + print ('[90] Reiniciar el equipo.') +else: + print ('[70] Apagando el equipo.') # Estado correcto de Wake-On-Lan antes de apagar. -ethtool -s $DEVICE wol g 2>/dev/null +subprocess.run (['ethtool', '-s', DEVICE, 'wol', 'g'], stderr=subprocess.DEVNULL) # Detectar Busybox. -BUSYBOX=$(which busyboxOLD) -BUSYBOX=${BUSYBOX:-"busybox"} +BUSYBOX = shutil.which ('busyboxOLD') +if not BUSYBOX: BUSYBOX = shutil.which ('busybox') # Retardo para dar lugar al registro en cola de acciones. -sleep 5 +time.sleep (TIME) # Parar Browser para evitar "cuelgues". -[ "$ogstatus" == "offline" ] || pkill browser +if 'offline' != ogstatus: + subprocess.run (['killall', 'QtWebEngineProcess', 'OGBrowser', 'i3', 'sway', 'Xorg', 'startx'], stderr=subprocess.DEVNULL) # Apagar. -$BUSYBOX poweroff +if is_reboot: + subprocess.run ([BUSYBOX, 'reboot']) +else: + subprocess.run ([BUSYBOX, 'poweroff']) diff --git a/ogclient/scripts/reboot b/ogclient/scripts/reboot deleted file mode 100755 index 689da67..0000000 --- a/ogclient/scripts/reboot +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash -# Script de ejemplo para reiniciar un ordenador -# Nota: se usa como base para el programa de reinicio de OpenGnsys Admin. - - -# Registrar ejecución manual de script. -case "$(ogGetCaller)" in - browser|bash) ogEcho log info "Script: $0" ;; -esac - -# Cargamos el valor por defecto del tiempo de sleep -[ -z $OGSLEEP ] && source /opt/opengnsys/etc/engine.cfg - -# Si se recibe un parametro sera el tiempo de sleep antes de realizar el reboot -if [ $# == 1 ] && [ "${1//[^0-9]/}" == "$1" ] -then - TIME=$1 - echo "[5] Se ha introducido un retardo de $TIME segundos para reiniciar" -else - # Sin parámetros, o el parámetro introducido no es un número - TIME=${OGSLEEP:-5} - echo "[5] No se ha introducido un retardo, $TIME segundos para reiniciar" -fi - -# No registrar errores. -export DEBUG="no" - -# Desmontar los sistemas de archivos y la caché local. -echo "[10] Desmontar todos los sistemas de archivos." -sync -for (( i=1; i <= $(ogDiskToDev | wc -w); i++ )); do - ogUnmountAll $i &>/dev/null -done -echo "[50] Desmontar cache local." -ogUnmountCache &>/dev/null - -# Volver a registrar errores. -unset DEBUG - -echo "[90] Reiniciar el equipo." -# Estado correcto de Wake-On-Lan antes de reiniciar. -ethtool -s $DEVICE wol g 2>/dev/null -# Detectar Busybox. -BUSYBOX=$(which busyboxOLD) -BUSYBOX=${BUSYBOX:-"busybox"} - -# Retardo para dar lugar al registro en cola de acciones. -sleep $TIME -# Parar Browser para evitar "cuelgues". -[ "$ogstatus" == "offline" ] || pkill browser -# Reiniciar. -$BUSYBOX reboot - - diff --git a/ogclient/scripts/reboot b/ogclient/scripts/reboot new file mode 120000 index 0000000..a112e69 --- /dev/null +++ b/ogclient/scripts/reboot @@ -0,0 +1 @@ +poweroff \ No newline at end of file diff --git a/ogclient/scripts/runhttplog.py b/ogclient/scripts/runhttplog.py deleted file mode 100755 index 97c9900..0000000 --- a/ogclient/scripts/runhttplog.py +++ /dev/null @@ -1,38 +0,0 @@ -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()