From 7165dd552a548ac35bfa6529861761383cf661d0 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Wed, 12 Mar 2025 11:32:26 +0100 Subject: [PATCH] refs #1672 add interfaceAdm/CrearImagen.py --- ogclient/functions/ogChangeRepo | 3 +- ogclient/interfaceAdm/CambiarAcceso.py | 100 +++++++++-------- ogclient/interfaceAdm/CrearImagen.py | 147 +++++++++++++++---------- ogclient/lib/python3/ImageLib.py | 2 +- ogclient/lib/python3/NetLib.py | 30 ++--- 5 files changed, 154 insertions(+), 128 deletions(-) diff --git a/ogclient/functions/ogChangeRepo b/ogclient/functions/ogChangeRepo index 0a65304..78d08e9 100755 --- a/ogclient/functions/ogChangeRepo +++ b/ogclient/functions/ogChangeRepo @@ -7,7 +7,6 @@ from NetLib import ogChangeRepo parser = argparse.ArgumentParser (add_help=False) parser.add_argument ('ip_repo') -parser.add_argument ('og_unit', nargs='?', default=None) if 2 == len (sys.argv) and 'help' == sys.argv[1]: #parser.print_help() sale en inglés aunque la locale indique otra cosa @@ -16,7 +15,7 @@ if 2 == len (sys.argv) and 'help' == sys.argv[1]: args = parser.parse_args() -ret = ogChangeRepo (args.ip_repo, args.og_unit) +ret = ogChangeRepo (args.ip_repo) if ret is not None: if ret == True: sys.exit (0) elif ret == False: sys.exit (1) diff --git a/ogclient/interfaceAdm/CambiarAcceso.py b/ogclient/interfaceAdm/CambiarAcceso.py index 61fea66..ae8f944 100755 --- a/ogclient/interfaceAdm/CambiarAcceso.py +++ b/ogclient/interfaceAdm/CambiarAcceso.py @@ -1,54 +1,62 @@ -#!/usr/bin/env python3 +#!/usr/bin/python3 + +#______________________________________ +# +# PARAMETROS RECIBIDOS DESDE EL CLIENTE +# $1 modo (admin, user) +#______________________________________ + import os import sys +import re import subprocess -import NetLib -import SystemLib -def main(): - if len(sys.argv) != 2: - print("Usage: CambiarAcceso.py ") - sys.exit(1) +import ogGlobals +from SystemLib import ogEcho, ogRaiseError, ogIsRepoLocked +from NetLib import ogGetRepoIp - mode = sys.argv[1] - repo_ip = NetLib.ogGetRepoIp() +# Error si llamada no se realliza desde OpenGnsys Client. +prog = sys.argv[0] +if len (sys.argv) != 2: + print (f'Usage: {prog} ') + sys.exit (1) - if not repo_ip: - SystemLib.ogRaiseError("OG_ERR_NOTFOUND", "repo no montado") +# Salir si el repositorio está bloquedo (tiene ficheros abiertos). +mode = sys.argv[1] +repoip = ogGetRepoIp() +if not repoip: + ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, 'repo no montado') + sys.exit (1) +if ogIsRepoLocked(): + ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'repo {repoip}') + sys.exit (1) - if SystemLib.ogIsRepoLocked(): - SystemLib.ogRaiseError("OG_ERR_LOCKED", f"repo {repo_ip}") +# Comprobar protocolo y modo de acceso. +proto = os.getenv ('ogprotocol', 'smb') +if proto not in ['nfs', 'smb']: + ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'protocolo desconocido {proto}') + sys.exit (1) +if 'admin' == mode: mount_mode = 'rw' +elif 'user' == mode: mount_mode = 'ro' +else: + ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'modo desconocido {mode}') + sys.exit (1) - proto = os.getenv("ogprotocol", "smb") - if proto not in ["nfs", "smb"]: - SystemLib.ogRaiseError("OG_ERR_FORMAT", f"protocolo desconocido {proto}") - - if mode == "admin": - mount_mode = "rw" - elif mode == "user": - mount_mode = "ro" - else: - SystemLib.ogRaiseError("OG_ERR_FORMAT", f"modo desconocido {mode}") - - OGIMG = os.getenv("OGIMG", "/mnt/OGIMG") - OGUNIT = os.getenv("OGUNIT", "") - if OGUNIT: - OGUNIT = f"/{OGUNIT}" - - subprocess.run(["umount", OGIMG], check=True) - SystemLib.ogEcho("info", f"Montar repositorio {repo_ip} por {proto} en modo {mode}") - - if proto == "nfs": - subprocess.run(["mount", "-t", "nfs", f"{repo_ip}:{OGIMG}{OGUNIT}", OGIMG, "-o", mount_mode], check=True) - elif proto == "smb": - with open("/scripts/ogfunctions", "r") as f: - for line in f: - if "OPTIONS=" in line: - pass_option = line.split("pass=")[1].split()[0] - break - else: - pass_option = "og" - subprocess.run(["mount.cifs", f"//{repo_ip}/ogimages{OGUNIT}", OGIMG, "-o", f"{mount_mode},serverino,acl,username=opengnsys,password={pass_option}"], check=True) - -if __name__ == "__main__": - main() +# Desmontar repositorio y volver a montarlo con el modo adecuado. +subprocess.run (['umount', ogGlobals.OGIMG]) +ogEcho ([], 'info', f'Montar repositorio {repoip} por {proto} en modo {mode}') +if 'nfs' == proto: + subprocess.run (['mount', '-t', 'nfs', f'{repoip}:{ogGlobals.OGIMG}', ogGlobals.OGIMG, '-o', mount_mode]) +elif 'smb' == proto: + pass_option = '' + with open ('/scripts/ogfunctions', 'r') as fd: + while True: + line = fd.readline() + if not line: break + if not re.search ('^[\t ]*(export )?OPTIONS=', line): continue + m = re.search (r'pass=(\w*)', line) + if m: + pass_option = m.groups (0)[0] + break + if not pass_option: pass_option = 'og' + subprocess.run (['mount.cifs', f'//{repoip}/ogimages', ogGlobals.OGIMG, '-o', f'{mount_mode},serverino,acl,username=opengnsys,password={pass_option}']) diff --git a/ogclient/interfaceAdm/CrearImagen.py b/ogclient/interfaceAdm/CrearImagen.py index 29628e0..ea2b096 100755 --- a/ogclient/interfaceAdm/CrearImagen.py +++ b/ogclient/interfaceAdm/CrearImagen.py @@ -1,74 +1,109 @@ -#!/usr/bin/env python3 +#!/usr/bin/python3 + +#___________________________________________________ +# +# PARAMETROS RECIBIDOS DESDE EL CLIENTE: +# $1 Número de disco +# $2 Número de particion +# $3 Nombre canónico de la imagen (sin extensión) +# $4 Dirección del repositorio (REPO, por defecto) +#___________________________________________________ + + +#$OG_ERR_NOTEXEC Si no es llamada por OG client +#$OG_ERR_LOCKED=4 Si la particion está bloqueada. + + +#Codigos de error del scripts createImage +#@exception OG_ERR_FORMAT # 1 formato incorrecto. +#@exception OG_ERR_PARTITION # 3 Error en partición de disco o en su sistema de archivos +#@exception OG_ERR_IMAGE # 5 Error en funcion ogCreateImage o ogRestoreImage. +#@exception OG_ERR_NOTWRITE # 14 error de escritura +#@exception OG_ERR_NOTCACHE # 15 si cache no existe 15 +#@exception OG_ERR_CACHESIZE # 16 si espacio de la cache local o remota no tiene espacio 16 +#@exception OG_ERR_REDUCEFS # 17 error al reducir sistema de archivos. +#@exception OG_ERR_EXTENDFS # 18 Errror al expandir el sistema de archivos. + + +#Códigos de error de la funcion ogCreateImage + import os import subprocess import sys import time -import NetLib + import ogGlobals +from SystemLib import ogEcho, ogRaiseError +from NetLib import ogGetIpAddress, ogChangeRepo +from StringLib import ogCheckIpAddress -def load_engine_config(): - engine_config_path = "/opt/opengnsys/etc/engine.cfg" - if os.path.exists(engine_config_path): - with open(engine_config_path) as f: - exec(f.read(), globals()) +prog = sys.argv[0] +if len (sys.argv) < 4: + ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'Incorrect number of arguments') + sys.exit (1) +disk, par, imgname, *other = sys.argv[1:] +arg_repo = other[0] if len (other) > 0 else 'REPO' +dirname = os.path.dirname (prog) -def clear_temp_logs(): - open(os.getenv('OGLOGSESSION'), 'w').close() - open(os.getenv('OGLOGCOMMAND'), 'w').close() - open(f"{os.getenv('OGLOGCOMMAND')}.tmp", 'w').close() +start_time = time.time() +env_boot = os.getenv ('boot') -def log_session_start(script_name, args): - SystemLib.ogEcho("log session", f"{os.getenv('MSG_INTERFACE_START')} {script_name} {' '.join(args)}") +#Load engine configurator from engine.cfg file. +#Carga el configurador del engine desde el fichero engine.cfg +## (ogGlobals se encarga) -def log_session_end(retval): - SystemLib.ogEcho("log session", f"{os.getenv('MSG_INTERFACE_END')} {retval}") +# Clear temporary file used as log track by httpdlog +# Limpia los ficheros temporales usados como log de seguimiento para httpdlog +open (ogGlobals.OGLOGSESSION, 'w').close() +open (ogGlobals.OGLOGCOMMAND, 'w').close() +open (f"{ogGlobals.OGLOGCOMMAND}.tmp", 'w').close() -def ogCheckIpAddress(ip): - try: - subprocess.check_call(["ping", "-c", "1", ip]) - return 0 - except subprocess.CalledProcessError: - return 1 +# Registro de inicio de ejecución +ogEcho (['log', 'session'], None, f'{ogGlobals.lang.MSG_INTERFACE_START} {prog} {disk} {par} {imgname} {arg_repo}') -def create_image(disk_num, partition_num, repo, image_name): - if subprocess.call(["which", "createImageCustom"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0: - return subprocess.call(["createImageCustom", disk_num, partition_num, repo, f"/{image_name}"]) - else: - return subprocess.call(["createImage", disk_num, partition_num, repo, f"/{image_name}"]) +# Valor por defecto para el repositorio. +repo = arg_repo +if not repo: repo = 'REPO' +if repo == ogGetIpAddress(): repo = 'CACHE' +# Si es una ip y es distinta a la del recurso samba cambiamos de REPO. +if 'REPO' == repo or StringLib.ogCheckIpAddress (repo): + # Si falla el cambio -> salimos con error repositorio no valido + if not ogChangeRepo (repo): + ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, repo) + sys.exit (1) -def main(): - if len(sys.argv) != 5: - sys.exit(SystemLib.ogRaiseError(OG_ERR_FORMAT, "Incorrect number of arguments")) +# Si el destino es REPO y el cliente no está en modo "admin"; activar repositorio para escritura, +if 'REPO' == repo and 'admin' != env_boot: + retval = subprocess.run ([f'{dirname}/CambiarAcceso.py', 'admin']).returncode + if retval: + sys.exit (retval) - disk_num, partition_num, image_name, repo = sys.argv[1:5] +ogEcho ([], None, f'createImage "{disk}" "{par}" "{arg_repo}" /"{imgname}"') +# Si existe, ejecuta script personalizado "createImageCustom"; si no, llama al genérico "createImage". +if os.path.exists ('{ogGlobals.OGSCRIPTS}/createImageCustom.py'): + script = f'{ogGlobals.OGSCRIPTS}/createImageCustom.py' +else: + script = f'{ogGlobals.OGSCRIPTS}/createImage.py' - start_time = time.time() +with open (ogGlobals.OGLOGCOMMAND, 'a') as fd: + p = subprocess.Popen ([script, disk, par, arg_repo, f'/{imgname}'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + while p.poll() is None: + for l in iter (p.stdout.readline, b''): + partial = l.decode ('utf-8', 'ignore') + fd.write (partial) + print (partial, end='') ## so that the agent captures out output and reports progress to ogcore + for l in iter (p.stderr.readline, b''): + partial = l.decode ('utf-8', 'ignore') + fd.write (partial) + print (partial, end='') +retval = p.returncode - load_engine_config() - clear_temp_logs() - log_session_start(sys.argv[0], sys.argv[1:]) +# Cambiar acceso a modo usuario, si es necesario. +if 'REPO' == repo and 'admin' != env_boot: + subprocess.run ([f'{dirname}/CambiarAcceso.py', 'user']) - repo = repo if repo else "REPO" - if repo == NetLib.ogGetIpAddress(): - repo = "CACHE" +# Registro de fin de ejecución +ogEcho (['log', 'session'], None, f'{ogGlobals.lang.MSG_INTERFACE_END} {retval}') - if ogCheckIpAddress(repo) == 0 or repo == "REPO": - OGUNIT = os.getenv('OGUNIT', "") - if not NetLib.ogChangeRepo(repo, OGUNIT): - sys.exit(SystemLib.ogRaiseError(OG_ERR_NOTFOUND, f"{repo}")) +sys.exit (retval) - if repo == "REPO" and os.getenv('boot') != "admin": - retval = CambiarAcceso("admin") - if retval > 0: - sys.exit(retval) - - retval = create_image(disk_num, partition_num, repo, image_name) - - if repo == "REPO" and os.getenv('boot') != "admin": - CambiarAcceso("user") - - log_session_end(retval) - sys.exit(retval) - -if __name__ == "__main__": - main() diff --git a/ogclient/lib/python3/ImageLib.py b/ogclient/lib/python3/ImageLib.py index 2b5fc8c..647b341 100644 --- a/ogclient/lib/python3/ImageLib.py +++ b/ogclient/lib/python3/ImageLib.py @@ -233,7 +233,7 @@ def ogCreateImage (disk, par, container, imgfile, tool='partclone', level='gzip' bn = os.path.basename (imgfile) IMGFILE = f'{imgdir}/{bn}.{imgtype}' - if ogIsImageLocked (IMGFILE): + if ogIsImageLocked (container=None, imgfile=IMGFILE): SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{ogGlobals.lang.MSG_IMAGE} {container}, {imgfile}') return None diff --git a/ogclient/lib/python3/NetLib.py b/ogclient/lib/python3/NetLib.py index e36f863..5bd7cc5 100644 --- a/ogclient/lib/python3/NetLib.py +++ b/ogclient/lib/python3/NetLib.py @@ -39,48 +39,32 @@ def _ogConnect (server, protocol, src, dst, options, readonly): #@param 2 Abreviatura Unidad Organizativa #@return Cambio recurso remoto en OGIMG. #*/ -def ogChangeRepo(ip_repo, og_unit=None): - ogprotocol = os.environ['ogprotocol'] or 'smb' - - if og_unit: - SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, 'the og_unit parameter became unsupported') - return None +def ogChangeRepo (ip_repo): + ogprotocol = os.environ.get ('ogprotocol', 'smb') try: mount = subprocess.run (['mount'], capture_output=True, text=True).stdout ro = bool (list (filter (lambda line: re.search (r'ogimages.*\bro,', line), mount.splitlines()))) current_repo = ogGetRepoIp() - new_repo = current_repo if ip_repo.upper() == "REPO" else ip_repo + new_repo = current_repo if ip_repo.upper() == 'REPO' else ip_repo if new_repo == current_repo: return True - subprocess.run(["umount", ogGlobals.OGIMG], check=True) + subprocess.run (['umount', ogGlobals.OGIMG], check=True) SystemLib.ogEcho (['session', 'log'], None, f'{ogGlobals.lang.MSG_HELP_ogChangeRepo} {new_repo}') options = _ogConnect_options() if not _ogConnect (new_repo, ogprotocol, 'ogimages', ogGlobals.OGIMG, options, ro): _ogConnect (current_repo, ogprotocol, 'ogimages', ogGlobals.OGIMG, options, ro) - SystemLib.ogRaiseError( - "session", - ogGlobals.OG_ERR_REPO, - f"Error connecting to the new repository: {new_repo}", - ) + SystemLib.ogRaiseError ('session', ogGlobals.OG_ERR_REPO, f'Error connecting to the new repository: {new_repo}') return False - SystemLib.ogEcho( - ["session", "log"], - None, - f"Repository successfully changed to {new_repo}".strip(), - ) + SystemLib.ogEcho (['session', 'log'], None, f'Repository successfully changed to {new_repo}'.strip()) return True except Exception as e: - SystemLib.ogRaiseError( - "session", - ogGlobals.OG_ERR_GENERIC, - f"Error executing ogChangeRepo: {e}", - ) + SystemLib.ogRaiseError ('session', ogGlobals.OG_ERR_GENERIC, f'Error executing ogChangeRepo: {e}') return None #/**