Merge branch 'devel'
ogagent/pipeline/head There was a failure building this commit Details
ogagent/pipeline/tag There was a failure building this commit Details

main
Juan Manuel Bardallo 2026-09-30 14:22:04 +02:00
commit e62d217fa2
3 changed files with 342 additions and 88 deletions

View File

@ -5,6 +5,11 @@ 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).
## [8.5.10] - 2026-09-30
### Fixed
- **ogLive**: Resuelta una condicin de carrera que provocaba fallos de inicializacin del servidor grfico X al recibir peticiones concurrentes o ultra-rpidas de carga de navegador desde ogCore. Se ha implementado un semforo/control de estado del proceso del navegador para ignorar peticiones duplicadas redundantes.
## [8.5.9] - 2026-07-23
### Fixed
@ -585,3 +590,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Initial release for OpenGnsys Agent

238
ogagent.nsi Normal file
View File

@ -0,0 +1,238 @@
# We need http://nsis.sourceforge.net/NSIS_Simple_Firewall_Plugin
# Copy inside the two x86_xxxxx folders inside nsis plugins folder
Name "OpenGnsys Agent"
# OpenGnsys Agent version
!define /file OGA_VERSION "src\VERSION"
!define /file OGA_WINVERSION "windows\VERSION"
# General Symbol Definitions
!define REGKEY "SOFTWARE\OGAgent"
!if ${OGA_VERSION} == ${OGA_WINVERSION}
!define VERSION ${OGA_WINVERSION}.0
!else
!define VERSION ${OGA_WINVERSION}.1
!endif
!define COMPANY "OpenGnsys Project"
!define URL https://opengnsys.es
!define CONFIGFILE "cfg\ogagent.cfg"
# MultiUser Symbol Definitions
!define MULTIUSER_EXECUTIONLEVEL Admin
!define MULTIUSER_INSTALLMODE_COMMANDLINE
!define MULTIUSER_INSTALLMODE_INSTDIR OGAgent
!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "${REGKEY}"
!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUE "Path"
# MUI Symbol Definitions
!define MUI_ICON "src\img\oga.ico"
!define MUI_FINISHPAGE_NOAUTOCLOSE
!define MUI_UNICON "src\img\oga.ico"
!define MUI_UNFINISHPAGE_NOAUTOCLOSE
!define MUI_LANGDLL_REGISTRY_ROOT HKLM
!define MUI_LANGDLL_REGISTRY_KEY ${REGKEY}
!define MUI_LANGDLL_REGISTRY_VALUENAME InstallerLanguage
# Included files
!include MultiUser.nsh
!include Sections.nsh
!include MUI2.nsh
!include nsDialogs.nsh
!include LogicLib.nsh
!include Filefunc.nsh
# Reserved Files
!insertmacro MUI_RESERVEFILE_LANGDLL
# Variables
Var StartMenuGroup
Var SERVERIP
Var SERVERIP_VALUE
# Installer pages
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE src\license.txt
Page custom "ParamsPage" "ParamsPageLeave"
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
# Installer languages
!insertmacro MUI_LANGUAGE English
!insertmacro MUI_LANGUAGE Spanish
!insertmacro MUI_LANGUAGE French
!insertmacro MUI_LANGUAGE German
# Installer attributes
BrandingText "OpenGnsys"
OutFile OGAgentSetup-${OGA_VERSION}.exe
InstallDir OGAgent
CRCCheck on
XPStyle on
ShowInstDetails hide
VIProductVersion "${VERSION}.0.0"
VIAddVersionKey /LANG=${LANG_ENGLISH} ProductName "OGAgent"
VIAddVersionKey /LANG=${LANG_ENGLISH} ProductVersion "${VERSION}"
VIAddVersionKey /LANG=${LANG_ENGLISH} CompanyName "${COMPANY}"
VIAddVersionKey /LANG=${LANG_ENGLISH} CompanyWebsite "${URL}"
VIAddVersionKey /LANG=${LANG_ENGLISH} FileVersion "${VERSION}"
VIAddVersionKey /LANG=${LANG_ENGLISH} FileDescription "OpenGnsys Agent installer"
VIAddVersionKey /LANG=${LANG_ENGLISH} LegalCopyright "(c) 2015 Virtual Cable S.L.U."
InstallDirRegKey HKLM "${REGKEY}" Path
ShowUninstDetails show
# Installer sections
Section -Main SEC0000
SetShellVarContext all
SetOutPath $INSTDIR
SetOverwrite on
File /r src\dist\OGAgent\*.*
File windows\VC_redist.x64.exe
File src\VERSION
WriteRegStr HKLM "${REGKEY}\Components" Main 1
SectionEnd
Section -post SEC0001
WriteIniStr $INSTDIR\${CONFIGFILE} "opengnsys" "remote" "https://$SERVERIP_VALUE/opengnsys/rest"
SetShellVarContext current
WriteRegStr HKLM "${REGKEY}" Path $INSTDIR
SetOutPath $INSTDIR
WriteUninstaller $INSTDIR\OGAgentUninstaller.exe
SetOutPath $SMPROGRAMS\$StartMenuGroup
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\$(^UninstallLink).lnk" $INSTDIR\OGAgentUninstaller.exe
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)"
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayVersion "${VERSION}"
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Publisher "${COMPANY}"
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" URLInfoAbout "${URL}"
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\OGAgentUninstaller.exe
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\OGAgentUninstaller.exe
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Run" OGAgentTool $INSTDIR\OGAgentUser.exe
WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1
WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1
ExecWait '"$INSTDIR\VC_redist.x64.exe" /passive /norestart'
# Add the application to the firewall exception list - All Networks - All IP Version - Enabled
# SimpleFC::AddApplication "OpenGnsys Agent Service" "$INSTDIR\OGAgentService.exe" 0 2 "" 1
# SimpleFC::AdvAddRule [name] [description] [protocol] [direction]
# [status] [profile] [action] [application] [service_name] [icmp_types_and_codes]
# [group] [local_ports] [remote_ports] [local_address] [remote_address]
#
SimpleFC::AdvAddRule "OpenGnsys Agent Firewall rules" "Firewall rules for OpenGnsys Agent interaction with broker." "6" "1" \
"1" "7" "1" "$INSTDIR\OGAgentService.exe" "" "" \
"" "" "" "" ""
Pop $0 ; return error(1)/success(0)
# Disable fast boot on Windows 10, if registry key exists.
ReadRegDWORD $0 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Power" HiberbootEnabled
IfErrors 0 +2
WriteRegDWORD HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Power" HiberbootEnabled 0
# Install service
nsExec::Exec /OEM "$INSTDIR\OGAgentService.exe --startup auto install" # Add service after installation
Exec "net start ogagent"
Exec "$INSTDIR\OGAgentUser.exe"
SectionEnd
# Macro for selecting uninstaller sections
!macro SELECT_UNSECTION SECTION_NAME UNSECTION_ID
Push $R0
ReadRegStr $R0 HKLM "${REGKEY}\Components" "${SECTION_NAME}"
StrCmp $R0 1 0 next${UNSECTION_ID}
!insertmacro SelectSection "${UNSECTION_ID}"
GoTo done${UNSECTION_ID}
next${UNSECTION_ID}:
!insertmacro UnselectSection "${UNSECTION_ID}"
done${UNSECTION_ID}:
Pop $R0
!macroend
# Uninstaller sections
Section /o -un.Main UNSEC0000
nsExec::Exec "taskkill /F /IM OGAgentUser.exe /T"
nsExec::Exec /OEM "$INSTDIR\OGAgentService.exe stop" # Stops the service prior uninstall
nsExec::Exec /OEM "$INSTDIR\OGAgentService.exe remove" # Removes the service prior uninstall
nsExec::Exec "taskkill /F /IM OGAgentService.exe /T"
Delete /REBOOTOK "$INSTDIR\*.*"
DeleteRegValue HKLM "${REGKEY}\Components" Main
DeleteRegValue HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Run" OGAgentTool
SectionEnd
Section -un.post UNSEC0001
# Remove application from the firewall exception list
# SimpleFC::RemoveApplication "$INSTDIR\OGAgentService.exe"
SimpleFC::AdvRemoveRule "OpenGnsys Agent Firewall rules"
Pop $0 ; return error(1)/success(0)
SetShellVarContext current
StrCpy $StartMenuGroup "OpenGnsys Agent"
DeleteRegKey HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)"
Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\$(^UninstallLink).lnk"
Delete /REBOOTOK $INSTDIR\OGAgentUninstaller.exe
DeleteRegValue HKLM "${REGKEY}" Path
DeleteRegKey /IfEmpty HKLM "${REGKEY}\Components"
DeleteRegKey /IfEmpty HKLM "${REGKEY}"
RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup
SetShellVarContext all
RmDir /r /REBOOTOK $INSTDIR
SectionEnd
# Installer functions
Function .onInit
InitPluginsDir
Call GetParameters
StrCpy $StartMenuGroup "OpenGnsys Agent"
!insertmacro MUI_LANGDLL_DISPLAY
!insertmacro MULTIUSER_INIT
FunctionEnd
# Uninstaller functions
Function un.onInit
StrCpy $StartMenuGroup "OpenGnsys Agent"
!insertmacro MUI_UNGETLANGUAGE
!insertmacro MULTIUSER_UNINIT
!insertmacro SELECT_UNSECTION Main ${UNSEC0000}
FunctionEnd
# Parameters dialog box
Function ParamsPage
!insertmacro MUI_HEADER_TEXT "$(PARAMS_TITLE)" ""
nsDialogs::Create /NOUNLOAD 1018
Pop $0
${If} $0 == error
Abort
${EndIf}
${NSD_CreateLabel} 0 0 100% 12u "$(SERVER_LABEL):"
Pop $0
${NSD_CreateText} 10% 20u 80% 12u "$SERVERIP_VALUE"
Pop $SERVERIP
nsDialogs::Show
FunctionEnd
# Get parameters from the dialog
Function ParamsPageLeave
${NSD_GetText} $SERVERIP $SERVERIP_VALUE
FunctionEnd
# Assign input parameters or default values to variables
Function GetParameters
${GetOptions} $CMDLINE "/server" $SERVERIP_VALUE
${If} $SERVERIP_VALUE == ""
StrCpy $SERVERIP_VALUE "192.168.2.1:8443"
${EndIf}
FunctionEnd
# Installer Language Strings
LangString PARAMS_TITLE ${LANG_ENGLISH} "Setup parameters"
LangString PARAMS_TITLE ${LANG_SPANISH} "Parametros de configuracion"
LangString PARAMS_TITLE ${LANG_FRENCH} "Parametres de configuration"
LangString PARAMS_TITLE ${LANG_GERMAN} "Setup-Parameter"
LangString SERVER_LABEL ${LANG_ENGLISH} "OpenGnsys Server IP Address and port (eg. 192.168.98.99:8443)"
LangString SERVER_LABEL ${LANG_SPANISH} "Direccion IP y puerto del Servidor OpenGnsys (p. ej. 192.168.98.99:8443)"
LangString SERVER_LABEL ${LANG_FRENCH} "Adresse IP et port du Serveur OpenGnsys (ex. 192.168.98.99:8443)"
LangString SERVER_LABEL ${LANG_GERMAN} "OpenGnsys Server IP-Adresse und Port (z. B. 192.168.98.99:8443)"
LangString ^UninstallLink ${LANG_ENGLISH} "Uninstall $(^Name)"
LangString ^UninstallLink ${LANG_SPANISH} "Desinstalar $(^Name)"
LangString ^UninstallLink ${LANG_FRENCH} "D<>sinstaller $(^Name)"
LangString ^UninstallLink ${LANG_GERMAN} "deinstallieren $(^Name)"

View File

@ -70,82 +70,82 @@ class ogLiveWorker(ServerWorker):
tbErroresScripts = [
"Se han generado errores desconocidos. No se puede continuar la ejecución de este módulo", ## 0
"001-Formato de ejecución incorrecto.",
"002-Fichero o dispositivo no encontrado",
"003-Error en partición de disco",
"004-Partición o fichero bloqueado",
"005-Error al crear o restaurar una imagen",
"006-Sin sistema operativo",
"007-Programa o función BOOLEAN no ejecutable",
"008-Error en la creación del archivo de eco para consola remota",
"009-Error en la lectura del archivo temporal de intercambio",
"010-Error al ejecutar la llamada a la interface de administración",
"011-La información retornada por la interface de administración excede de la longitud permitida",
"012-Error en el envío de fichero por la red",
"013-Error en la creación del proceso hijo",
"014-Error de escritura en destino",
"015-Sin Cache en el Cliente",
"016-No hay espacio en la cache para almacenar fichero-imagen",
"017-Error al Reducir el Sistema Archivos",
"018-Error al Expandir el Sistema Archivos",
"019-Valor fuera de rango o no válido.",
"020-Sistema de archivos desconocido o no se puede montar",
"021-Error en partición de caché local",
"022-El disco indicado no contiene una particion GPT",
"023-Error no definido",
"024-Error no definido",
"025-Error no definido",
"026-Error no definido",
"027-Error no definido",
"028-Error no definido",
"029-Error no definido",
"030-Error al restaurar imagen - Imagen mas grande que particion",
"031-Error al realizar el comando updateCache",
"032-Error al formatear",
"033-Archivo de imagen corrupto o de otra versión de partclone",
"034-Error no definido",
"035-Error no definido",
"036-Error no definido",
"037-Error no definido",
"038-Error no definido",
"039-Error no definido",
"040-Error imprevisto no definido",
"041-Error no definido",
"042-Error no definido",
"043-Error no definido",
"044-Error no definido",
"045-Error no definido",
"046-Error no definido",
"047-Error no definido",
"048-Error no definido",
"049-Error no definido",
"050-Error en la generación de sintaxis de transferenica unicast",
"051-Error en envio UNICAST de una particion",
"052-Error en envio UNICAST de un fichero",
"053-Error en la recepcion UNICAST de una particion",
"054-Error en la recepcion UNICAST de un fichero",
"055-Error en la generacion de sintaxis de transferenica Multicast",
"056-Error en envio MULTICAST de un fichero",
"057-Error en la recepcion MULTICAST de un fichero",
"058-Error en envio MULTICAST de una particion",
"059-Error en la recepcion MULTICAST de una particion",
"060-Error en la conexion de una sesion UNICAST|MULTICAST con el MASTER",
"061-Error no definido",
"062-Error no definido",
"063-Error no definido",
"064-Error no definido",
"065-Error no definido",
"066-Error no definido",
"067-Error no definido",
"068-Error no definido",
"069-Error no definido",
"070-Error al montar una imagen sincronizada.",
"071-Imagen no sincronizable (es monolitica).",
"072-Error al desmontar la imagen.",
"073-No se detectan diferencias entre la imagen basica y la particion.",
"074-Error al sincronizar, puede afectar la creacion/restauracion de la imagen.",
"Error desconocido",
]
"001-Formato de ejecución incorrecto.",
"002-Fichero o dispositivo no encontrado",
"003-Error en partición de disco",
"004-Partición o fichero bloqueado",
"005-Error al crear o restaurar una imagen",
"006-Sin sistema operativo",
"007-Programa o función BOOLEAN no ejecutable",
"008-Error en la creación del archivo de eco para consola remota",
"009-Error en la lectura del archivo temporal de intercambio",
"010-Error al ejecutar la llamada a la interface de administración",
"011-La información retornada por la interface de administración excede de la longitud permitida",
"012-Error en el envío de fichero por la red",
"013-Error en la creación del proceso hijo",
"014-Error de escritura en destino",
"015-Sin Cache en el Cliente",
"016-No hay espacio en la cache para almacenar fichero-imagen",
"017-Error al Reducir el Sistema Archivos",
"018-Error al Expandir el Sistema Archivos",
"019-Valor fuera de rango o no válido.",
"020-Sistema de archivos desconocido o no se puede montar",
"021-Error en partición de caché local",
"022-El disco indicado no contiene una particion GPT",
"023-Error no definido",
"024-Error no definido",
"025-Error no definido",
"026-Error no definido",
"027-Error no definido",
"028-Error no definido",
"029-Error no definido",
"030-Error al restaurar imagen - Imagen mas grande que particion",
"031-Error al realizar el comando updateCache",
"032-Error al formatear",
"033-Archivo de imagen corrupto o de otra versión de partclone",
"034-Error no definido",
"035-Error no definido",
"036-Error no definido",
"037-Error no definido",
"038-Error no definido",
"039-Error no definido",
"040-Error imprevisto no definido",
"041-Error no definido",
"042-Error no definido",
"043-Error no definido",
"044-Error no definido",
"045-Error no definido",
"046-Error no definido",
"047-Error no definido",
"048-Error no definido",
"049-Error no definido",
"050-Error en la generación de sintaxis de transferenica unicast",
"051-Error en envio UNICAST de una particion",
"052-Error en envio UNICAST de un fichero",
"053-Error en la recepcion UNICAST de una particion",
"054-Error en la recepcion UNICAST de un fichero",
"055-Error en la generacion de sintaxis de transferenica Multicast",
"056-Error en envio MULTICAST de un fichero",
"057-Error en la recepcion MULTICAST de un fichero",
"058-Error en envio MULTICAST de una particion",
"059-Error en la recepcion MULTICAST de una particion",
"060-Error en la conexion de una sesion UNICAST|MULTICAST con el MASTER",
"061-Error no definido",
"062-Error no definido",
"063-Error no definido",
"064-Error no definido",
"065-Error no definido",
"066-Error no definido",
"067-Error no definido",
"068-Error no definido",
"069-Error no definido",
"070-Error al montar una imagen sincronizada.",
"071-Imagen no sincronizable (es monolitica).",
"072-Error al desmontar la imagen.",
"073-No se detectan diferencias entre la imagen basica y la particion.",
"074-Error al sincronizar, puede afectar la creacion/restauracion de la imagen.",
"Error desconocido",
]
def notifier (self, job_id, result):
result['job_id'] = job_id
@ -427,23 +427,33 @@ class ogLiveWorker(ServerWorker):
dbus_address = os.environ.get ('DBUS_SESSION_BUS_ADDRESS')
if not dbus_address: logger.warning ('env var DBUS_SESSION_BUS_ADDRESS not set, cargaPaginaWeb() will likely not work')
b = dbus.SystemBus()
dest = 'es.opengnsys.OGBrowser.browser'
path = '/'
interface = None
method = 'setURL'
signature = 's'
try:
b = dbus.SystemBus()
dest = 'es.opengnsys.OGBrowser.browser'
path = '/'
interface = None
method = 'setURL'
b.call_blocking (dest, path, interface, method, 's', [url])
except Exception as e:
if 'ServiceUnknown' in str(e):
logger.warning ('browser is not running, launching a new one')
browser_log_fd = open ('/var/log/launch_browser.log', 'a')
self.browser_process = subprocess.Popen (['/usr/bin/launch_browser', url], stdout=browser_log_fd, stderr=subprocess.STDOUT)
browser_log_fd.close()
# Capturamos ServiceUnknown y también NameHasNoOwner que salta a veces por condiciones de carrera
if 'ServiceUnknown' in str(e) or 'NameHasNoOwner' in str(e):
if getattr(self, 'browser_process', None) is None or self.browser_process.poll() is not None:
logger.warning (f'browser is not running ({e}), launching a new one')
browser_log_fd = open ('/var/log/launch_browser.log', 'a')
self.browser_process = subprocess.Popen (['/usr/bin/launch_browser', url], stdout=browser_log_fd, stderr=subprocess.STDOUT)
browser_log_fd.close()
else:
logger.warning ('browser is already launching, ignoring duplicate launch request')
else:
logger.error (f'Error al cambiar URL: ({e})')
return False
# Como medida de contingencia, si falla por cualquier otro error de DBus y no hay proceso, lo lanzamos
if getattr(self, 'browser_process', None) is None or self.browser_process.poll() is not None:
logger.warning ('Fallback: launching browser despite unknown DBus error')
browser_log_fd = open ('/var/log/launch_browser.log', 'a')
self.browser_process = subprocess.Popen (['/usr/bin/launch_browser', url], stdout=browser_log_fd, stderr=subprocess.STDOUT)
browser_log_fd.close()
else:
return False
return True