import subprocess import datetime import sys import os import shutil from DiskLib import * from CacheLib import * from StringLib import * print (">>>>>>>>>>>>>>>>>>>> Load ", __name__, " <<<<<<<<<<<<<<<<<<<<<<") #NODEBUGFUNCTIONS, OGIMG, OG_ERR_CACHESIZE, OG_ERR_NOTCACHE, OG_ERR_NOTWRITE, OG_ERR_FILESYS #OG_ERR_REPO, OG_ERR_NOTOS, OG_ERR_NOGPT, OG_ERR_OUTOFLIMIT, OG_ERR_IMAGE, OG_ERR_CACHE #OGLOGSESSION, OGLOGCOMMAND, OGLOGFILE, OG_ERR_LOCKED, OG_ERR_PARTITION, OG_ERR_FORMAT, OG_ERR_NOTEXEC, OG_ERR_NOTFOUND def ogEcho(*args): # Variables locales CONT = 1 LOGS = "" LOGLEVEL = "" DATETIME = "" # Selección de ficheros de registro de incidencias. while CONT: arg = args.pop(0).lower() if arg == "log": LOGS += " " + OGLOGFILE elif arg == "command": LOGS += " " + OGLOGCOMMAND elif arg == "session": LOGS += " " + OGLOGSESSION else: CONT = 0 # Selección del nivel de registro (opcional). arg = args.pop(0).lower() if arg == "help": pass elif arg == "info" or arg == "warning" or arg == "error": LOGLEVEL = arg if LOGLEVEL: DATETIME = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") # Registrar mensajes en fichero de log si la depuración no está desactivada. if DEBUG.lower() != "no": LOGS += " " + OGLOGFILE subprocess.call(f"logger -t OpenGnsys {LOGLEVEL} {DATETIME} {' '.join(args)}", shell=True) else: print(' '.join(args)) def ogExecAndLog(*args): # Variables locales ISCOMMAND = False ISLOG = False ISSESSION = False COMMAND = "" CONTINUE = 1 FILES = "" REDIREC = "" FUNCNAME = ogExecAndLog.__name__ # Si se solicita, mostrar ayuda. if len(args) > 0 and args[0] == "help": ogHelp(f"{FUNCNAME} str_logfile ... str_command ...", f"{FUNCNAME} COMMAND ls -al /") return # Procesar parámetros. while CONTINUE: arg = args.pop(0).lower() if arg == "command": ISCOMMAND = True continue elif arg == "log": ISLOG = True continue elif arg == "session": ISSESSION = True continue else: COMMAND = " ".join(args) CONTINUE = 0 # Error si no se recibe un comando que ejecutar. if not COMMAND: ogRaiseError(OG_ERR_FORMAT) return # Componer lista de ficheros de registro. if ISCOMMAND: FILES = OGLOGCOMMAND open(FILES, "w").close() REDIREC = "2>&1" if ISLOG: FILES += " " + OGLOGFILE if ISSESSION: FILES += " " + OGLOGSESSION # Ejecutar comando. subprocess.call(f"{COMMAND} {REDIREC} | tee -a {FILES}", shell=True) # Salida de error del comando ejecutado. return subprocess.PIPESTATUS[0] def ogGetCaller(): # Obtener el nombre del programa o del script que ha llamado al proceso actual. output = subprocess.check_output(["ps", "hp", str(os.getppid()), "-o", "args"]).decode("utf-8") lines = output.split("\n") caller = "" for line in lines: if "bash" in line and line.split()[1] != "": caller = line.split()[1] else: caller = line.split()[0].lstrip("-") return os.path.basename(caller) def ogHelp(*args): # Variables locales FUNC = "" MSG = "" FUNCNAME = ogHelp.__name__ # Mostrar función, descripción y formato. FUNC = args[0] if len(args) > 0 else FUNCNAME[-1] MSG = f"MSG_HELP_{FUNC}" ogEcho("help", f"{MSG_FUNCTION} {FUNC}: {globals()[MSG]}") if len(args) > 1: ogEcho("help", f" {MSG_FORMAT}: {args[1]}") # Mostrar ejemplos (si existen). for example in args[2:]: ogEcho("help", f" {MSG_EXAMPLE}: {example}") def ogRaiseError(*args): # Variables locales CONT = 1 LOGS = "" MSG = "" CODE = "" FUNCS = "" FUNCNAME = ogRaiseError.__name__ # Si se solicita, mostrar ayuda. if len(args) > 0 and args[0] == "help": ogHelp(f"{FUNCNAME}", f"{FUNCNAME} [str_logfile ...] int_errorcode str_errormessage") return # Selección de registros de incidencias. while CONT: arg = args.pop(0).lower() if arg == "log" or arg == "command" or arg == "session": LOGS += " " + arg else: CONT = 0 # Obtener código y mensaje de error. CODE = args.pop(0) if CODE == OG_ERR_FORMAT: MSG = f"{MSG_ERR_FORMAT} \"{args.pop(0)}\"" elif CODE == OG_ERR_NOTFOUND: MSG = f"{MSG_ERR_NOTFOUND} \"{args.pop(0)}\"" elif CODE == OG_ERR_OUTOFLIMIT: MSG = f"{MSG_ERR_OUTOFLIMIT} \"{args.pop(0)}\"" elif CODE == OG_ERR_PARTITION: MSG = f"{MSG_ERR_PARTITION} \"{args.pop(0)}\"" elif CODE == OG_ERR_LOCKED: MSG = f"{MSG_ERR_LOCKED} \"{args.pop(0)}\"" elif CODE == OG_ERR_CACHE: MSG = f"{MSG_ERR_CACHE} \"{args.pop(0)}\"" elif CODE == OG_ERR_NOGPT: MSG = f"{MSG_ERR_NOGPT} \"{args.pop(0)}\"" elif CODE == OG_ERR_REPO: MSG = f"{MSG_ERR_REPO} \"{args.pop(0)}\"" elif CODE == OG_ERR_FILESYS: MSG = f"{MSG_ERR_FILESYS} \"{args.pop(0)}\"" elif CODE == OG_ERR_IMAGE: MSG = f"{MSG_ERR_IMAGE} \"{args.pop(0)}\"" elif CODE == OG_ERR_NOTOS: MSG = f"{MSG_ERR_NOTOS} \"{args.pop(0)}\"" elif CODE == OG_ERR_NOTEXEC: MSG = f"{MSG_ERR_NOTEXEC} \"{args.pop(0)}\"" elif CODE == OG_ERR_NOTWRITE: MSG = f"{MSG_ERR_NOTWRITE} \"{args.pop(0)}\"" elif CODE == OG_ERR_NOTCACHE: MSG = f"{MSG_ERR_NOTCACHE} \"{args.pop(0)}\"" elif CODE == OG_ERR_CACHESIZE: MSG = f"{MSG_ERR_CACHESIZE} \"{args.pop(0)}\"" elif CODE == OG_ERR_REDUCEFS: MSG = f"{MSG_ERR_REDUCEFS} \"{args.pop(0)}\"" elif CODE == OG_ERR_EXTENDFS: MSG = f"{MSG_ERR_EXTENDFS} \"{args.pop(0)}\"" elif CODE == OG_ERR_IMGSIZEPARTITION: MSG = f"{MSG_ERR_IMGSIZEPARTITION} \"{args.pop(0)}\"" elif CODE == OG_ERR_UPDATECACHE: MSG = f"{MSG_ERR_UPDATECACHE} \"{args.pop(0)}\"" elif CODE == OG_ERR_DONTFORMAT: MSG = f"{MSG_ERR_DONTFORMAT} \"{args.pop(0)}\"" elif CODE == OG_ERR_IMAGEFILE: MSG = f"{MSG_ERR_IMAGEFILE} \"{args.pop(0)}\"" elif CODE == OG_ERR_UCASTSYNTAXT: MSG = f"{MSG_ERR_UCASTSYNTAXT} \"{args.pop(0)}\"" elif CODE == OG_ERR_UCASTSENDPARTITION: MSG = f"{MSG_ERR_UCASTSENDPARTITION} \"{args.pop(0)}\"" elif CODE == OG_ERR_UCASTSENDFILE: MSG = f"{MSG_ERR_UCASTSENDFILE} \"{args.pop(0)}\"" elif CODE == OG_ERR_UCASTRECEIVERPARTITION: MSG = f"{MSG_ERR_UCASTRECEIVERPARTITION} \"{args.pop(0)}\"" elif CODE == OG_ERR_UCASTRECEIVERFILE: MSG = f"{MSG_ERR_UCASTRECEIVERFILE} \"{args.pop(0)}\"" elif CODE == OG_ERR_MCASTSYNTAXT: MSG = f"{MSG_ERR_MCASTSYNTAXT} \"{args.pop(0)}\"" elif CODE == OG_ERR_MCASTSENDFILE: MSG = f"{MSG_ERR_MCASTSENDFILE} \"{args.pop(0)}\"" elif CODE == OG_ERR_MCASTRECEIVERFILE: MSG = f"{MSG_ERR_MCASTRECEIVERFILE} \"{args.pop(0)}\"" elif CODE == OG_ERR_MCASTSENDPARTITION: MSG = f"{MSG_ERR_MCASTSENDPARTITION} \"{args.pop(0)}\"" elif CODE == OG_ERR_MCASTRECEIVERPARTITION: MSG = f"{MSG_ERR_MCASTRECEIVERPARTITION} \"{args.pop(0)}\"" elif CODE == OG_ERR_PROTOCOLJOINMASTER: MSG = f"{MSG_ERR_PROTOCOLJOINMASTER} \"{args.pop(0)}\"" elif CODE == OG_ERR_DONTMOUNT_IMAGE: MSG = f"{MSG_ERR_DONTMOUNT_IMAGE} \"{args.pop(0)}\"" elif CODE == OG_ERR_DONTUNMOUNT_IMAGE: MSG = f"{MSG_ERR_DONTUNMOUNT_IMAGE} \"{args.pop(0)}\"" elif CODE == OG_ERR_DONTSYNC_IMAGE: MSG = f"{MSG_ERR_DONTSYNC_IMAGE} \"{args.pop(0)}\"" elif CODE == OG_ERR_NOTDIFFERENT: MSG = f"{MSG_ERR_NOTDIFFERENT} \"{args.pop(0)}\"" elif CODE == OG_ERR_SYNCHRONIZING: MSG = f"{MSG_ERR_SYNCHRONIZING} \"{args.pop(0)}\"" elif CODE == OG_ERR_NOTUEFI: MSG = f"{MSG_ERR_NOTUEFI} \"{args.pop(0)}\"" elif CODE == OG_ERR_NOMSDOS: MSG = f"{MSG_ERR_NOMSDOS} \"{args.pop(0)}\"" elif CODE == OG_ERR_NOTBIOS: MSG = f"{MSG_ERR_NOTBIOS} \"{args.pop(0)}\"" else: MSG = MSG_ERR_GENERIC CODE = OG_ERR_GENERIC # Obtener lista de funciones afectadas, incluyendo el script que las llama. FUNCS = " ".join(FUNCNAME[1:]) FUNCS = FUNCS.replace("main", os.path.basename(sys.argv[0])) # Mostrar mensaje de error si es función depurable y salir con el código indicado. if CODE == OG_ERR_FORMAT or ogCheckStringInGroup(FUNCS, NODEBUGFUNCTIONS) or not ogCheckStringInGroup(FUNCS.split()[0], NODEBUGFUNCTIONS): ogEcho(LOGS, "error", f"{FUNCS.replace(' ', '<-')}: {MSG}", file=sys.stderr) return CODE def ogIsRepoLocked(): # Variables locales FILES = "" FUNCNAME = ogIsRepoLocked.__name__ # Si se solicita, mostrar ayuda. if len(sys.argv) > 1 and sys.argv[1] == "help": ogHelp(f"{FUNCNAME}", f"{FUNCNAME}", f"if {FUNCNAME}(): ...") # No hacer nada, si no está definido el punto de montaje del repositorio. if not OGIMG: return 1 # Comprobar si alguno de los ficheros abiertos por los procesos activos está en el # punto de montaje del repositorio de imágenes. FILES = subprocess.check_output(["find", "/proc", "-maxdepth", "2", "-type", "f", "-lname", f"{OGIMG}/*"]).decode("utf-8") return bool(FILES) def ogCheckProgram(*args): FUNCNAME = ogCheckProgram.__name__ # Si se solicita, mostrar ayuda. if len(args) > 0 and args[0] == "help": ogHelp(f"{FUNCNAME} \"str_program ...\"", f"{FUNCNAME} \"partimage partclone mbuffer\"") return # Error si no se recibe 1 parámetro. if len(args) != 1: ogRaiseError(OG_ERR_FORMAT) return PERROR = 0 PLOG = " " for i in args[0].split(): if not shutil.which(i): PERROR = 1 PLOG += f" {i}" if PERROR == 1: ogRaiseError(OG_ERR_NOTEXEC, PLOG) return else: return 0 def ogIsVirtualMachine(): output = subprocess.check_output(["dmidecode", "-s", "system-product-name"]).decode("utf-8") if "KVM" in output or "VirtualBox" in output: return 1 else: return 0