refs #708 move duplicated code into its own parent class
parent
4b46827d17
commit
1864995066
|
@ -32,15 +32,12 @@
|
|||
|
||||
import base64
|
||||
import os
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from configparser import NoOptionError
|
||||
from opengnsys import REST
|
||||
from opengnsys.log import logger
|
||||
from opengnsys.workers import ServerWorker
|
||||
from opengnsys.workers import ogLiveWorker
|
||||
|
||||
class CloningEngineWorker (ServerWorker):
|
||||
class CloningEngineWorker (ogLiveWorker):
|
||||
name = 'CloningEngine' # Module name
|
||||
REST = None # REST object
|
||||
|
||||
|
@ -50,105 +47,8 @@ class CloningEngineWorker (ServerWorker):
|
|||
def process_status (self, path, get_params, post_params, server):
|
||||
return {self.name: 'in process_status'} ## XXX
|
||||
|
||||
def interfaceAdmin (self, method, parametros=[]):
|
||||
exe = '{}/{}'.format (self.pathinterface, method)
|
||||
## for development only. Will be removed when the referenced bash code (/opt/opengnsys/lib/engine/bin/*.lib) is translated into python
|
||||
devel_bash_prefix = '''
|
||||
PATH=/opt/opengnsys/scripts/:$PATH;
|
||||
for I in /opt/opengnsys/lib/engine/bin/*.lib; do source $I; done;
|
||||
for i in $(declare -F |cut -f3 -d" "); do export -f $i; done;
|
||||
'''
|
||||
|
||||
if parametros:
|
||||
proc = ['bash', '-c', '{} {} {}'.format (devel_bash_prefix, exe, ' '.join (parametros))]
|
||||
else:
|
||||
proc = ['bash', '-c', '{} {}'.format (devel_bash_prefix, exe)]
|
||||
logger.debug ('subprocess.run ("{}", capture_output=True)'.format (proc))
|
||||
p = subprocess.run (proc, capture_output=True)
|
||||
if 0 != p.returncode:
|
||||
cmd_txt = ' '.join (proc)
|
||||
logger.error (f'command ({cmd_txt}) failed, stderr follows:')
|
||||
for l in p.stderr.strip().decode ('utf-8').splitlines():
|
||||
logger.error (f' {l}')
|
||||
raise Exception (f'command ({cmd_txt}) failed, see log for details')
|
||||
return p.stdout.strip().decode ('utf-8')
|
||||
|
||||
def tomaIPlocal (self):
|
||||
try:
|
||||
self.IPlocal = self.interfaceAdmin ('getIpAddress')
|
||||
except Exception as e:
|
||||
logger.error (e)
|
||||
logger.error ('No se ha podido recuperar la dirección IP del cliente')
|
||||
return False
|
||||
logger.info ('local IP is "{}"'.format (self.IPlocal))
|
||||
return True
|
||||
|
||||
def enviaMensajeServidor (self, path, obj={}):
|
||||
obj['iph'] = self.IPlocal ## Ip del ordenador
|
||||
obj['ido'] = self.idordenador ## Identificador del ordenador
|
||||
obj['npc'] = self.nombreordenador ## Nombre del ordenador
|
||||
obj['idc'] = self.idcentro ## Identificador del centro
|
||||
obj['ida'] = self.idaula ## Identificador del aula
|
||||
|
||||
res = self.REST.sendMessage ('/'.join (self.name, path), obj)
|
||||
|
||||
if (type (res) is not dict):
|
||||
#logger.error ('No se ha podido establecer conexión con el Servidor de Administración') ## Error de conexión con el servidor
|
||||
logger.debug (f'res ({res})')
|
||||
logger.error ('Error al enviar trama ***send() fallo')
|
||||
return False
|
||||
|
||||
return res
|
||||
|
||||
def cargaPaginaWeb (self, url=None):
|
||||
if (not url): url = self.urlMenu
|
||||
os.system ('pkill -9 browser')
|
||||
|
||||
p = subprocess.Popen (['/opt/opengnsys/bin/browser', '-qws', url])
|
||||
try:
|
||||
p.wait (2) ## if the process dies before 2 seconds...
|
||||
logger.error ('Error al ejecutar la llamada a la interface de administración')
|
||||
logger.error ('Error en la creación del proceso hijo')
|
||||
logger.error ('return code "{}"'.format (p.returncode))
|
||||
return False
|
||||
except subprocess.TimeoutExpired:
|
||||
pass
|
||||
|
||||
return True
|
||||
|
||||
def muestraMenu (self):
|
||||
self.cargaPaginaWeb()
|
||||
|
||||
def muestraMensaje (self, idx):
|
||||
self.cargaPaginaWeb (f'{self.urlMsg}?idx={idx}')
|
||||
|
||||
def onActivation (self):
|
||||
if not os.path.exists ('/scripts/oginit'):
|
||||
## no estamos en oglive, este modulo no debe cargarse
|
||||
## esta lógica la saco de src/opengnsys/linux/operations.py, donde hay un if similar
|
||||
raise Exception ('Refusing to load within an operating system')
|
||||
|
||||
self.pathinterface = None
|
||||
self.IPlocal = None ## Ip del ordenador
|
||||
self.idordenador = None ## Identificador del ordenador
|
||||
self.nombreordenador = None ## Nombre del ordenador
|
||||
self.cache = None
|
||||
self.idproautoexec = None
|
||||
self.idcentro = None ## Identificador del centro
|
||||
self.idaula = None ## Identificador del aula
|
||||
|
||||
try:
|
||||
url = self.service.config.get (self.name, 'remote')
|
||||
loglevel = self.service.config.get (self.name, 'log')
|
||||
self.pathinterface = self.service.config.get (self.name, 'pathinterface')
|
||||
self.urlMenu = self.service.config.get (self.name, 'urlMenu')
|
||||
self.urlMsg = self.service.config.get (self.name, 'urlMsg')
|
||||
except NoOptionError as e:
|
||||
logger.error ("Configuration error: {}".format (e))
|
||||
raise e
|
||||
logger.setLevel (loglevel)
|
||||
self.REST = REST (url)
|
||||
|
||||
super().onActivation()
|
||||
logger.info ('onActivation ok')
|
||||
|
||||
## en C, esto envia una trama de respuesta al servidor. Devuelve un boolean
|
||||
|
|
|
@ -189,6 +189,8 @@ class OpenGnSysWorker(ServerWorker):
|
|||
if os.path.isfile(new_hosts_file):
|
||||
shutil.copyfile(new_hosts_file, hosts_file)
|
||||
|
||||
logger.info ('onActivation ok')
|
||||
|
||||
def onDeactivation(self):
|
||||
"""
|
||||
Sends OGAgent stopping notification to OpenGnsys server
|
||||
|
|
|
@ -32,18 +32,14 @@
|
|||
@author: Natalia Serrano, nserrano at qindel dot com
|
||||
"""
|
||||
|
||||
|
||||
import base64
|
||||
import os
|
||||
#import threading
|
||||
#import time
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from configparser import NoOptionError
|
||||
from opengnsys import REST, operations
|
||||
#from opengnsys import operations
|
||||
from opengnsys.log import logger
|
||||
from opengnsys.workers import ServerWorker
|
||||
from opengnsys.workers import ogLiveWorker
|
||||
|
||||
# Check authorization header decorator
|
||||
def check_secret (fnc):
|
||||
|
@ -67,7 +63,7 @@ def check_secret (fnc):
|
|||
|
||||
return wrapper
|
||||
|
||||
class ogAdmClientWorker (ServerWorker):
|
||||
class ogAdmClientWorker (ogLiveWorker):
|
||||
name = 'ogAdmClient' # Module name
|
||||
#interface = None # Bound interface for OpenGnsys (el otro modulo lo usa para obtener .ip y .mac
|
||||
REST = None # REST object
|
||||
|
@ -228,65 +224,6 @@ class ogAdmClientWorker (ServerWorker):
|
|||
## process_* are invoked from opengnsys/httpserver.py:99 "data = module.processServerMessage (path, get_params, post_params, self)" (via opengnsys/workers/server_worker.py)
|
||||
## process_client_* are invoked from opengnsys/service.py:123 "v.processClientMessage (message, json.loads (data))" (via opengnsys/workers/server_worker.py)
|
||||
|
||||
def interfaceAdmin (self, method, parametros=[]):
|
||||
exe = '{}/{}'.format (self.pathinterface, method)
|
||||
## for development only. Will be removed when the referenced bash code (/opt/opengnsys/lib/engine/bin/*.lib) is translated into python
|
||||
devel_bash_prefix = '''
|
||||
PATH=/opt/opengnsys/scripts/:$PATH;
|
||||
for I in /opt/opengnsys/lib/engine/bin/*.lib; do source $I; done;
|
||||
for i in $(declare -F |cut -f3 -d" "); do export -f $i; done;
|
||||
'''
|
||||
if parametros:
|
||||
proc = ['bash', '-c', '{} {} {}'.format (devel_bash_prefix, exe, ' '.join (parametros))]
|
||||
else:
|
||||
proc = ['bash', '-c', '{} {}'.format (devel_bash_prefix, exe)]
|
||||
logger.debug ('subprocess.run ("{}", capture_output=True)'.format (proc))
|
||||
p = subprocess.run (proc, capture_output=True)
|
||||
if 0 != p.returncode:
|
||||
cmd_txt = ' '.join (proc)
|
||||
logger.error (f'command ({cmd_txt}) failed, stderr follows:')
|
||||
for l in p.stderr.strip().decode ('utf-8').splitlines():
|
||||
logger.error (f' {l}')
|
||||
raise Exception (f'command ({cmd_txt}) failed, see log for details')
|
||||
return p.stdout.strip().decode ('utf-8')
|
||||
|
||||
def tomaIPlocal (self):
|
||||
try:
|
||||
self.IPlocal = self.interfaceAdmin ('getIpAddress')
|
||||
except Exception as e:
|
||||
logger.error (e)
|
||||
logger.error ('No se ha podido recuperar la dirección IP del cliente')
|
||||
return False
|
||||
logger.info ('local IP is "{}"'.format (self.IPlocal))
|
||||
return True
|
||||
|
||||
def LeeConfiguracion (self):
|
||||
try:
|
||||
parametroscfg = self.interfaceAdmin ('getConfiguration') ## Configuración de los Sistemas Operativos del cliente
|
||||
except Exception as e:
|
||||
logger.error (e)
|
||||
logger.error ('No se ha podido recuperar la dirección IP del cliente')
|
||||
return None
|
||||
logger.debug ('parametroscfg ({})'.format (parametroscfg))
|
||||
return parametroscfg
|
||||
|
||||
def enviaMensajeServidor (self, path, obj={}):
|
||||
obj['iph'] = self.IPlocal ## Ip del ordenador
|
||||
obj['ido'] = self.idordenador ## Identificador del ordenador
|
||||
obj['npc'] = self.nombreordenador ## Nombre del ordenador
|
||||
obj['idc'] = self.idcentro ## Identificador del centro
|
||||
obj['ida'] = self.idaula ## Identificador del aula
|
||||
|
||||
res = self.REST.sendMessage ('/'.join (self.name, path), obj)
|
||||
|
||||
if (type (res) is not dict):
|
||||
#logger.error ('No se ha podido establecer conexión con el Servidor de Administración') ## Error de conexión con el servidor
|
||||
logger.debug (f'res ({res})')
|
||||
logger.error ('Error al enviar trama ***send() fallo')
|
||||
return False
|
||||
|
||||
return res
|
||||
|
||||
def ejecutaArchivo (self,fn):
|
||||
logger.debug ('fn ({})'.format (fn))
|
||||
|
||||
|
@ -402,25 +339,6 @@ class ogAdmClientWorker (ServerWorker):
|
|||
|
||||
return True
|
||||
|
||||
def cargaPaginaWeb (self, url=None):
|
||||
if (not url): url = self.urlMenu
|
||||
os.system ('pkill -9 browser')
|
||||
|
||||
p = subprocess.Popen (['/opt/opengnsys/bin/browser', '-qws', url])
|
||||
try:
|
||||
p.wait (2) ## if the process dies before 2 seconds...
|
||||
logger.error ('Error al ejecutar la llamada a la interface de administración')
|
||||
logger.error ('Error en la creación del proceso hijo')
|
||||
logger.error ('return code "{}"'.format (p.returncode))
|
||||
return False
|
||||
except subprocess.TimeoutExpired:
|
||||
pass
|
||||
|
||||
return True
|
||||
|
||||
def muestraMenu (self):
|
||||
self.cargaPaginaWeb()
|
||||
|
||||
def procesaComandos (self):
|
||||
res = self.enviaMensajeServidor ('DisponibilidadComandos', { 'tpc': 'OPG' }) ## Activar disponibilidad
|
||||
logger.debug ('res ({})'.format (res))
|
||||
|
@ -449,38 +367,7 @@ class ogAdmClientWorker (ServerWorker):
|
|||
#}
|
||||
|
||||
def onActivation (self):
|
||||
"""
|
||||
Sends OGAgent activation notification to OpenGnsys server
|
||||
"""
|
||||
if not os.path.exists ('/scripts/oginit'):
|
||||
## no estamos en oglive, este modulo no debe cargarse
|
||||
## esta lógica la saco de src/opengnsys/linux/operations.py, donde hay un if similar
|
||||
raise Exception ('Refusing to load within an operating system')
|
||||
|
||||
self.pathinterface = None
|
||||
self.IPlocal = None ## Ip del ordenador
|
||||
self.idordenador = None ## Identificador del ordenador
|
||||
self.nombreordenador = None ## Nombre del ordenador
|
||||
self.cache = None
|
||||
self.idproautoexec = None
|
||||
self.idcentro = None ## Identificador del centro
|
||||
self.idaula = None ## Identificador del aula
|
||||
|
||||
try:
|
||||
url = self.service.config.get (self.name, 'remote')
|
||||
loglevel = self.service.config.get (self.name, 'log')
|
||||
self.pathinterface = self.service.config.get (self.name, 'pathinterface')
|
||||
self.urlMenu = self.service.config.get (self.name, 'urlMenu')
|
||||
self.urlMsg = self.service.config.get (self.name, 'urlMsg')
|
||||
except NoOptionError as e:
|
||||
logger.error ("Configuration error: {}".format (e))
|
||||
raise e
|
||||
logger.setLevel (loglevel)
|
||||
self.REST = REST (url)
|
||||
|
||||
if not self.tomaIPlocal():
|
||||
raise Exception ('Se han generado errores. No se puede continuar la ejecución de este módulo')
|
||||
|
||||
super().onActivation()
|
||||
logger.info ('Inicio de sesion')
|
||||
logger.info ('Abriendo sesión en el servidor de Administración')
|
||||
if (not self.inclusionCliente()):
|
||||
|
@ -505,6 +392,8 @@ class ogAdmClientWorker (ServerWorker):
|
|||
self.muestraMenu()
|
||||
self.procesaComandos()
|
||||
|
||||
logger.info ('onActivation ok')
|
||||
|
||||
## curl --insecure https://192.168.1.249:8000/ogAdmClient/Actualizar
|
||||
def process_Actualizar (self, path, get_params, post_params, server):
|
||||
logger.warning ('in process_Actualizar')
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
from .server_worker import ServerWorker
|
||||
from .client_worker import ClientWorker
|
||||
from .oglive_worker import ogLiveWorker
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2024 Qindel Formación y Servicios S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
"""
|
||||
@author: Natalia Serrano, nserrano at qindel dot com
|
||||
"""
|
||||
# pylint: disable=unused-wildcard-import,wildcard-import
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from configparser import NoOptionError
|
||||
from opengnsys import REST
|
||||
from opengnsys.log import logger
|
||||
from .server_worker import ServerWorker
|
||||
|
||||
class ogLiveWorker(ServerWorker):
|
||||
def interfaceAdmin (self, method, parametros=[]):
|
||||
exe = '{}/{}'.format (self.pathinterface, method)
|
||||
## for development only. Will be removed when the referenced bash code (/opt/opengnsys/lib/engine/bin/*.lib) is translated into python
|
||||
devel_bash_prefix = '''
|
||||
PATH=/opt/opengnsys/scripts/:$PATH;
|
||||
for I in /opt/opengnsys/lib/engine/bin/*.lib; do source $I; done;
|
||||
for i in $(declare -F |cut -f3 -d" "); do export -f $i; done;
|
||||
'''
|
||||
|
||||
if parametros:
|
||||
proc = ['bash', '-c', '{} set -x; bash -x {} {}; set +x'.format (devel_bash_prefix, exe, ' '.join (parametros))]
|
||||
else:
|
||||
proc = ['bash', '-c', '{} set -x; bash -x {}; set +x'.format (devel_bash_prefix, exe)]
|
||||
logger.debug ('subprocess.run ("{}", capture_output=True)'.format (proc))
|
||||
p = subprocess.run (proc, capture_output=True)
|
||||
## DEBUG
|
||||
logger.info (f'stdout follows:')
|
||||
for l in p.stdout.strip().decode ('utf-8').splitlines():
|
||||
logger.info (f' {l}')
|
||||
logger.info (f'stderr follows:')
|
||||
for l in p.stderr.strip().decode ('utf-8').splitlines():
|
||||
logger.info (f' {l}')
|
||||
## /DEBUG
|
||||
if 0 != p.returncode:
|
||||
cmd_txt = ' '.join (proc)
|
||||
logger.error (f'command ({cmd_txt}) failed, stderr follows:')
|
||||
for l in p.stderr.strip().decode ('utf-8').splitlines():
|
||||
logger.error (f' {l}')
|
||||
raise Exception (f'command ({cmd_txt}) failed, see log for details')
|
||||
return p.stdout.strip().decode ('utf-8')
|
||||
|
||||
def tomaIPlocal (self):
|
||||
try:
|
||||
self.IPlocal = self.interfaceAdmin ('getIpAddress')
|
||||
except Exception as e:
|
||||
logger.error (e)
|
||||
logger.error ('No se ha podido recuperar la dirección IP del cliente')
|
||||
return False
|
||||
logger.info ('local IP is "{}"'.format (self.IPlocal))
|
||||
return True
|
||||
|
||||
def enviaMensajeServidor (self, path, obj={}):
|
||||
obj['iph'] = self.IPlocal ## Ip del ordenador
|
||||
obj['ido'] = self.idordenador ## Identificador del ordenador
|
||||
obj['npc'] = self.nombreordenador ## Nombre del ordenador
|
||||
obj['idc'] = self.idcentro ## Identificador del centro
|
||||
obj['ida'] = self.idaula ## Identificador del aula
|
||||
|
||||
res = self.REST.sendMessage ('/'.join ([self.name, path]), obj)
|
||||
|
||||
if (type (res) is not dict):
|
||||
#logger.error ('No se ha podido establecer conexión con el Servidor de Administración') ## Error de conexión con el servidor
|
||||
logger.debug (f'res ({res})')
|
||||
logger.error ('Error al enviar trama ***send() fallo')
|
||||
return False
|
||||
|
||||
return res
|
||||
|
||||
def cargaPaginaWeb (self, url=None):
|
||||
if (not url): url = self.urlMenu
|
||||
os.system ('pkill -9 browser')
|
||||
|
||||
p = subprocess.Popen (['/opt/opengnsys/bin/browser', '-qws', url])
|
||||
try:
|
||||
p.wait (2) ## if the process dies before 2 seconds...
|
||||
logger.error ('Error al ejecutar la llamada a la interface de administración')
|
||||
logger.error ('Error en la creación del proceso hijo')
|
||||
logger.error ('return code "{}"'.format (p.returncode))
|
||||
return False
|
||||
except subprocess.TimeoutExpired:
|
||||
pass
|
||||
|
||||
return True
|
||||
|
||||
def muestraMenu (self):
|
||||
self.cargaPaginaWeb()
|
||||
|
||||
def muestraMensaje (self, idx):
|
||||
self.cargaPaginaWeb (f'{self.urlMsg}?idx={idx}')
|
||||
|
||||
def LeeConfiguracion (self):
|
||||
try:
|
||||
parametroscfg = self.interfaceAdmin ('getConfiguration') ## Configuración de los Sistemas Operativos del cliente
|
||||
except Exception as e:
|
||||
logger.error (e)
|
||||
logger.error ('No se ha podido recuperar la dirección IP del cliente')
|
||||
return None
|
||||
logger.debug ('parametroscfg ({})'.format (parametroscfg))
|
||||
return parametroscfg
|
||||
|
||||
def onActivation (self):
|
||||
if not os.path.exists ('/scripts/oginit'):
|
||||
## no estamos en oglive, este modulo no debe cargarse
|
||||
## esta lógica la saco de src/opengnsys/linux/operations.py, donde hay un if similar
|
||||
raise Exception ('Refusing to load within an operating system')
|
||||
|
||||
self.pathinterface = None
|
||||
self.IPlocal = None ## Ip del ordenador
|
||||
self.idordenador = None ## Identificador del ordenador
|
||||
self.nombreordenador = None ## Nombre del ordenador
|
||||
self.cache = None
|
||||
self.idproautoexec = None
|
||||
self.idcentro = None ## Identificador del centro
|
||||
self.idaula = None ## Identificador del aula
|
||||
|
||||
try:
|
||||
url = self.service.config.get (self.name, 'remote')
|
||||
loglevel = self.service.config.get (self.name, 'log')
|
||||
self.pathinterface = self.service.config.get (self.name, 'pathinterface')
|
||||
self.urlMenu = self.service.config.get (self.name, 'urlMenu')
|
||||
self.urlMsg = self.service.config.get (self.name, 'urlMsg')
|
||||
except NoOptionError as e:
|
||||
logger.error ("Configuration error: {}".format (e))
|
||||
raise e
|
||||
logger.setLevel (loglevel)
|
||||
self.REST = REST (url)
|
||||
|
||||
if not self.tomaIPlocal():
|
||||
raise Exception ('Se han generado errores. No se puede continuar la ejecución de este módulo')
|
Loading…
Reference in New Issue