Merge pull request 'Migración a python' (#1) from code-review into main

Reviewed-on: #1
pull/2/head
Natalia Serrano 2025-02-26 11:26:35 +01:00
commit ef349ec8d3
227 changed files with 15958 additions and 2887 deletions

2
.gitignore vendored 100644
View File

@ -0,0 +1,2 @@
__pycache__/
*.swp

7
client/interfaceAdm/Apagar.py 100644 → 100755
View File

@ -1,9 +1,10 @@
#!/usr/bin/env python3
import os
import sys
def poweroff():
def main():
os.system('poweroff')
sys.exit(0)
if __name__ == "__main__":
poweroff()
sys.exit(0)
main()

View File

@ -1,8 +1,9 @@
#!/usr/bin/env python3
import os
import sys
import subprocess
#!/usr/bin/env python3
import NetLib
import SystemLib
def main():
if len(sys.argv) != 2:
@ -10,35 +11,35 @@ def main():
sys.exit(1)
mode = sys.argv[1]
repo_ip = og_get_repo_ip()
repo_ip = NetLib.ogGetRepoIp()
if not repo_ip:
og_raise_error("OG_ERR_NOTFOUND", "repo no montado")
SystemLib.ogRaiseError("OG_ERR_NOTFOUND", "repo no montado")
if og_is_repo_locked():
og_raise_error("OG_ERR_LOCKED", f"repo {repo_ip}")
if SystemLib.ogIsRepoLocked():
SystemLib.ogRaiseError("OG_ERR_LOCKED", f"repo {repo_ip}")
proto = os.getenv("ogprotocol", "smb")
if proto not in ["nfs", "smb"]:
og_raise_error("OG_ERR_FORMAT", f"protocolo desconocido {proto}")
SystemLib.ogRaiseError("OG_ERR_FORMAT", f"protocolo desconocido {proto}")
if mode == "admin":
mount_mode = "rw"
elif mode == "user":
mount_mode = "ro"
else:
og_raise_error("OG_ERR_FORMAT", f"modo desconocido {mode}")
SystemLib.ogRaiseError("OG_ERR_FORMAT", f"modo desconocido {mode}")
ogimg = os.getenv("OGIMG", "/mnt/ogimg")
ogunit = os.getenv("ogunit", "")
if ogunit:
ogunit = f"/{ogunit}"
OGIMG = os.getenv("OGIMG", "/mnt/OGIMG")
OGUNIT = os.getenv("OGUNIT", "")
if OGUNIT:
OGUNIT = f"/{OGUNIT}"
subprocess.run(["umount", ogimg], check=True)
og_echo("info", f"Montar repositorio {repo_ip} por {proto} en modo {mode}")
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)
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:
@ -47,7 +48,7 @@ def main():
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)
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()
main()

259
client/interfaceAdm/Configurar.py 100644 → 100755
View File

@ -1,146 +1,189 @@
#!/usr/bin/python3
import os
import sys
import subprocess
# Load engine configurator from engine.cfg file.
# Carga el configurador del engine desde el fichero engine.cfg
og_engine_configurate = os.getenv('OGENGINECONFIGURATE')
if not og_engine_configurate:
with open('/opt/opengnsys/client/etc/engine.cfg') as f:
for line in f:
if '=' in line:
key, value = line.strip().split('=', 1)
os.environ[key] = value
print(f"{key}={value}")
import ogGlobals
import SystemLib
import CacheLib
import FileSystemLib
import DiskLib
#Load engine configurator from engine.cfg file.
#Carga el configurador del engine desde el fichero engine.cfg
## (ogGlobals se encarga)
# Clear temporary file used as log track by httpdlog
# Limpia los ficheros temporales usados como log de seguimiento para httpdlog
og_log_session = os.getenv('OGLOGSESSION')
og_log_command = os.getenv('OGLOGCOMMAND')
open (ogGlobals.OGLOGSESSION, 'w').close()
open (ogGlobals.OGLOGCOMMAND, 'w').close()
open (ogGlobals.OGLOGCOMMAND+'.tmp', 'w').close()
if og_log_session:
# Check if the file exists, if not create it
if not os.path.exists(og_log_session):
os.makedirs(os.path.dirname(og_log_session), exist_ok=True)
with open(og_log_session, 'w') as f:
f.write(" ")
else:
with open(og_log_session, 'w') as f:
f.write(" ")
print("og_log_command", og_log_command)
if og_log_command:
with open(og_log_command, 'w') as f:
f.write(" ")
with open(f"{og_log_command}.tmp", 'w') as f:
f.write(" ")
print("og_log_session", og_log_session)
# Registro de inicio de ejecución
def og_echo(log_type, message):
# Implement the logging function here
pass
print("os.getenv('MSG_INTERFACE_START')", os.getenv('MSG_INTERFACE_START'))
msg_interface_start = os.getenv('MSG_INTERFACE_START')
if msg_interface_start:
og_echo('log', f"session {msg_interface_start} {__name__} {' '.join(os.sys.argv[1:])}")
SystemLib.ogEcho (['log', 'session'], None, f'{ogGlobals.lang.MSG_INTERFACE_START} {sys.argv}')
# Solo ejecutable por OpenGnsys Client.
path = os.getenv('PATH')
if path:
os.environ['PATH'] = f"{path}:{os.path.dirname(__name__)}"
#path = os.getenv('PATH')
#if path:
# os.environ['PATH'] = f"{path}:{os.path.dirname(__name__)}"
prog = os.path.basename(__name__)
print("prog", prog)
#____________________________________________________________________
#
# El parámetro $2 es el que aporta toda la información y el $1 se queda obsoleto
# Formato de entrada:
# dis=Número de disco
# *=caracter de separación
# che=Vale 0 o 1
# *=caracter de separación
# $tch=tamaño cache
# != caracter de separación
#
# Y un numero indeterminado de cadenas del tipo siguuenteseparadas por el caracter '$':
# par=Número de particion*cod=Código de partición*sfi=Sistema de ficheros*tam=Tamaño de la partición*ope=Operación
# @= caracter de separación
#____________________________________________________________________
# Captura de parámetros (se ignora el 1er parámetro y se eliminan espacios y tabuladores).
param = ''.join(sys.argv[2:]).replace(' ', '').replace('\t', '')
#param='dis=1*che=0*tch=70000000!par=1*cpt=NTFS*sfi=NTFS*tam=11000000*ope=0%'
#param = ''.join(sys.argv[2:]).replace(' ', '').replace('\t', '')
param = sys.argv[2]
print("param", param)
# Activa navegador para ver progreso
coproc = subprocess.Popen (['/opt/opengnsys/bin/browser', '-qws', 'http://localhost/cgi-bin/httpd-log.sh'])
# Activate browser to see progress
browser_command = ["/opt/opengnsys/bin/browser", "-qws", "http://localhost/cgi-bin/httpd-log.sh"]
coproc = subprocess.Popen(browser_command)
# Read the two blocks of parameters, separated by '!'
tbprm = param.split('!')
# Leer los dos bloques de parámetros, separados por '!'.
tbprm = param.split ('!')
pparam = tbprm[0] # General disk parameters
sparam = tbprm[1] # Partitioning and formatting parameters
# Take disk and cache values, separated by '*'
tbprm = pparam.split('*')
# Toma valores de disco y caché, separados por "*".
# Los valores están en las variables $dis: disco, $che: existe cache (1, 0), $tch: Tamaño de la cache.
tbprm = pparam.split ('*')
dis = ptt = tch = None
for item in tbprm:
if '=' in item:
key, value = item.split('=', 1)
os.environ[key] = value
if '=' not in item: continue
# Error if disk parameter (dis) is not defined
if 'dis' not in os.environ:
sys.exit(int(os.getenv('OG_ERR_FORMAT', 1)))
k, v = item.split ('=', 1)
if k not in ['dis', 'tch', 'ptt']: ## 'ptt' added, unused 'che' removed
print (f'ignoring unknown disk parameter ({k})')
continue
# Take partition distribution values, separated by '%'
cfg = [] # Configuration values
tbp = [] # Partition table
tbf = [] # Formatting table
if 'dis' == k: dis = int (v)
elif 'ptt' == k: ptt = v
elif 'tch' == k: tch = v
# Error si no se define el parámetro de disco (dis).
if dis is None: sys.exit (ogGlobals.OG_ERR_FORMAT)
if ptt is None: ptt = 'MSDOS'
if tch is None: tch = '0'
# Toma valores de distribución de particiones, separados por "%".
tbp = [] # Valores de configuración (parámetros para ogCreatePartitions)
tbf = {} # Tabla de formateo
tbprm = sparam.split('%')
maxp = 0
maxp=0
for item in tbprm:
cfg = item.split('*')
for c in cfg:
if '=' in c:
key, value = c.split('=', 1)
os.environ[key] = value
if os.getenv('cpt') != "CACHE":
tbp.append(f"{os.getenv('cpt')}:{os.getenv('tam')}")
if os.getenv('ope') == '1':
if os.getenv('cpt') not in ["EMPTY", "EXTENDED", "LINUX-LVM", "LVM", "ZPOOL"]:
tbf.append(os.getenv('sfi'))
maxp = max(maxp, int(os.getenv('par', 0)))
if not item: continue ## por si nos pasan un '%' al final de todo
# Leer datos de la partición, separados por "*".
par = cpt = sfi = tam = None
ope = 0
for c in item.split ('*'):
if '=' not in c: continue
# Process
# Current cache size
cache_size = subprocess.check_output(["ogGetCacheSize"]).strip()
k, v = c.split ('=', 1)
if k not in ['par', 'cpt', 'sfi', 'tam', 'ope']:
print (f'ignoring unknown partition parameter ({k})')
continue
# Unmount all partitions and cache
subprocess.run(["ogUnmountAll", os.getenv('dis')], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
subprocess.run(["ogUnmountCache"])
if 'par' == k: par = int (v)
elif 'cpt' == k: cpt = v
elif 'sfi' == k: sfi = v
elif 'tam' == k: tam = v
elif 'ope' == k: ope = int (v)
# Delete partition table if not MSDOS
if subprocess.check_output(["ogGetPartitionTableType", "1"]).strip() != b'MSDOS':
subprocess.run(["ogDeletePartitionTable", os.getenv('dis')])
subprocess.run(["ogExecAndLog", "COMMAND", "ogUpdatePartitionTable", os.getenv('dis')])
subprocess.run(["ogCreatePartitionTable", os.getenv('dis'), "MSDOS"])
missing_params = []
if par is None: missing_params.append ('par')
if cpt is None: missing_params.append ('cpt')
if sfi is None: missing_params.append ('sfi')
if tam is None: missing_params.append ('tam')
if missing_params:
print (f'partition data ({item}) missing required parameters ({' '.join (missing_params)})')
sys.exit (1)
# Initialize cache
if "CACHE" in sparam:
subprocess.run(["ogExecAndLog", "COMMAND", "initCache", os.getenv('tch')])
# Componer datos de particionado.
if 'CACHE' != cpt: tbp.append (f'{cpt}:{tam}')
if ope:
# Si se activa operación de formatear, componer datos de formateo.
if cpt not in ['EMPTY', 'EXTENDED', 'LINUX-LVM', 'LVM', 'ZPOOL']:
tbf[par] = sfi
# Obtener la partición mayor.
if par > maxp: maxp = par
# Define partitioning
subprocess.run(["ogExecAndLog", "COMMAND", "ogCreatePartitions", os.getenv('dis')] + tbp)
if subprocess.run(["ogExecAndLog", "COMMAND", "ogUpdatePartitionTable", os.getenv('dis')]).returncode != 0:
#____________________________________________________
#
# Proceso
#____________________________________________________
# Tamaño actual de la cache
CACHESIZE=CacheLib.ogGetCacheSize()
# Desmonta todas las particiones y la caché
SystemLib.ogEcho (['session', 'log'], None, f'[10] {ogGlobals.lang.MSG_HELP_ogUnmountAll}')
FileSystemLib.ogUnmountAll (dis)
CacheLib.ogUnmountCache()
# Elimina la tabla de particiones
cur_ptt = DiskLib.ogGetPartitionTableType (dis)
if not cur_ptt or ptt != cur_ptt:
DiskLib.ogDeletePartitionTable (dis)
SystemLib.ogExecAndLog ('command', DiskLib.ogUpdatePartitionTable)
# Crea tabla de particiones MSDOS (NOTA: adaptar para tablas GPT).
DiskLib.ogCreatePartitionTable (dis, ptt)
# Inicia la cache.
if 'CACHE' in sparam:
SystemLib.ogEcho (['session', 'log'], None, f'[30] {ogGlobals.lang.MSG_HELP_ogCreateCache}')
SystemLib.ogEcho (['session', 'log'], None, f' initCache {tch}')
SystemLib.ogExecAndLog ('command', CacheLib.initCache, tch)
# Definir particionado.
SystemLib.ogEcho (['session', 'log'], None, f'[50] {ogGlobals.lang.MSG_HELP_ogCreatePartitions}')
SystemLib.ogEcho (['session', 'log'], None, f' ogCreatePartitions {dis} {' '.join (tbp)}')
res = SystemLib.ogExecAndLog ('command', DiskLib.ogCreatePartitions, dis, tbp)
if not res:
coproc.kill()
sys.exit(int(subprocess.check_output(["ogRaiseError", "session", "log", os.getenv('OG_ERR_GENERIC', '1'), f"ogCreatePartitions {os.getenv('dis')} {' '.join(tbp)}"])))
# Format partitions
for par in range(1, maxp + 1):
if tbf[par] == "CACHE":
if cache_size == os.getenv('tch'):
subprocess.run(["ogExecAndLog", "COMMAND", "ogFormatCache"])
elif tbf[par]:
if subprocess.run(["ogExecAndLog", "COMMAND", "ogFormatFs", os.getenv('dis'), str(par), tbf[par]]).returncode != 0:
coproc.kill()
sys.exit(int(subprocess.check_output(["ogRaiseError", "session", "log", os.getenv('OG_ERR_GENERIC', '1'), f"ogFormatFs {os.getenv('dis')} {par} {tbf[par]}"])))
SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_GENERIC, f'ogCreatePartitions {dis} {' '.join (tbp)}')
sys.exit (1)
SystemLib.ogExecAndLog ('command', DiskLib.ogUpdatePartitionTable)
# Formatear particiones
SystemLib.ogEcho (['session', 'log'], None, f'[70] {ogGlobals.lang.MSG_HELP_ogFormat}')
retval = 0
subprocess.run(["ogEcho", "log", "session", f"{os.getenv('MSG_INTERFACE_END')} {retval}"])
for p in range (1, maxp+1):
if p not in tbf: continue
if 'CACHE' == tbf[p]:
if CACHESIZE == tch: # Si el tamaño es distinto ya se ha formateado.
SystemLib.ogEcho (['session', 'log'], None, ' ogFormatCache')
retval = SystemLib.ogExecAndLog ('command', CacheLib.ogFormatCache)
else:
SystemLib.ogEcho (['session', 'log'], None, f' ogFormatFs {dis} {p} {tbf[p]}')
retval = SystemLib.ogExecAndLog ('command', FileSystemLib.ogFormatFs, dis, str(p), tbf[p])
if retval:
coproc.kill()
SystemLib.ogRaiseError (['session', 'log'], ogGlobals.OG_ERR_GENERIC, f'ogFormatFs {dis} {p} {tbf[p]}')
sys.exit (1)
# Registro de fin de ejecución
SystemLib.ogEcho (['session', 'log'], None, f'{ogGlobals.lang.MSG_INTERFACE_END} {retval}')
#___________________________________________________________________
#
# Retorno
#___________________________________________________________________
# Return
coproc.kill()
sys.exit(0)
sys.exit (0)

View File

@ -1,3 +1,4 @@
#!/usr/bin/env python3
import os
import sys
import subprocess
@ -25,4 +26,4 @@ if __name__ == "__main__":
script_path = sys.argv[1]
output_path = sys.argv[2]
main(script_path, output_path)
main(script_path, output_path)

49
client/interfaceAdm/CrearImagen.py 100644 → 100755
View File

@ -1,19 +1,10 @@
#!/usr/bin/env python3
import os
import subprocess
import sys
import time
# Error codes
OG_ERR_NOTEXEC = 1
OG_ERR_LOCKED = 4
OG_ERR_FORMAT = 1
OG_ERR_PARTITION = 3
OG_ERR_IMAGE = 5
OG_ERR_NOTWRITE = 14
OG_ERR_NOTCACHE = 15
OG_ERR_CACHESIZE = 16
OG_ERR_REDUCEFS = 17
OG_ERR_EXTENDFS = 18
import NetLib
import ogGlobals
def load_engine_config():
engine_config_path = "/opt/opengnsys/etc/engine.cfg"
@ -27,20 +18,10 @@ def clear_temp_logs():
open(f"{os.getenv('OGLOGCOMMAND')}.tmp", 'w').close()
def log_session_start(script_name, args):
ogEcho("log session", f"{os.getenv('MSG_INTERFACE_START')} {script_name} {' '.join(args)}")
SystemLib.ogEcho("log session", f"{os.getenv('MSG_INTERFACE_START')} {script_name} {' '.join(args)}")
def log_session_end(retval):
ogEcho("log session", f"{os.getenv('MSG_INTERFACE_END')} {retval}")
def ogEcho(*args):
print(" ".join(args))
def ogRaiseError(error_code, message):
print(f"Error {error_code}: {message}", file=sys.stderr)
return error_code
def ogGetIpAddress():
return subprocess.check_output(["hostname", "-I"]).decode().strip()
SystemLib.ogEcho("log session", f"{os.getenv('MSG_INTERFACE_END')} {retval}")
def ogCheckIpAddress(ip):
try:
@ -49,14 +30,6 @@ def ogCheckIpAddress(ip):
except subprocess.CalledProcessError:
return 1
def ogChangeRepo(repo, unit):
# Placeholder for actual implementation
return True
def CambiarAcceso(mode):
# Placeholder for actual implementation
return 0
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}"])
@ -65,7 +38,7 @@ def create_image(disk_num, partition_num, repo, image_name):
def main():
if len(sys.argv) != 5:
sys.exit(ogRaiseError(OG_ERR_FORMAT, "Incorrect number of arguments"))
sys.exit(SystemLib.ogRaiseError(OG_ERR_FORMAT, "Incorrect number of arguments"))
disk_num, partition_num, image_name, repo = sys.argv[1:5]
@ -76,13 +49,13 @@ def main():
log_session_start(sys.argv[0], sys.argv[1:])
repo = repo if repo else "REPO"
if repo == ogGetIpAddress():
if repo == NetLib.ogGetIpAddress():
repo = "CACHE"
if ogCheckIpAddress(repo) == 0 or repo == "REPO":
ogunit = os.getenv('ogunit', "")
if not ogChangeRepo(repo, ogunit):
sys.exit(ogRaiseError(OG_ERR_NOTFOUND, f"{repo}"))
OGUNIT = os.getenv('OGUNIT', "")
if not NetLib.ogChangeRepo(repo, OGUNIT):
sys.exit(SystemLib.ogRaiseError(OG_ERR_NOTFOUND, f"{repo}"))
if repo == "REPO" and os.getenv('boot') != "admin":
retval = CambiarAcceso("admin")
@ -98,4 +71,4 @@ def main():
sys.exit(retval)
if __name__ == "__main__":
main()
main()

View File

@ -1,56 +1,62 @@
#!/usr/bin/env python3
import os
import time
import subprocess
import sys
import SystemLib
import ogGlobals
#sys.path.append('/opt/opengnsys/lib/engine/bin')
def main(script_path):
start_time = time.time()
print(f"Ejecutando:",script_path)
# Load engine configurator from engine.cfg file
og_engine_configurate = os.getenv('OGENGINECONFIGURATE')
if not og_engine_configurate:
with open('/opt/opengnsys/etc/engine.cfg') as f:
exec(f.read())
# Load engine configurator from engine.cfg file.
engine_config_path = '/opt/opengnsys/etc/engine.cfg'
# if 'OGENGINECONFIGURATE' not in os.environ:
# with open(engine_config_path) as f:
# exec(f.read(), globals())
# Clear temporary file used as log track by httpdlog
og_log_session = os.getenv('OGLOGSESSION')
og_log_command = os.getenv('OGLOGCOMMAND')
if og_log_session:
open(og_log_session, 'w').close()
if og_log_command:
open(og_log_command, 'w').close()
with open(os.environ['OGLOGSESSION'], 'w') as f:
f.write("")
with open(os.environ['OGLOGCOMMAND'], 'w') as f:
f.write("")
# Registro de inicio de ejecución
msg_interface_start = os.getenv('MSG_INTERFACE_START')
og_echo('log session', f"{msg_interface_start} {sys.argv[0]} {' '.join(sys.argv[1:])}")
SystemLib.ogEcho('log session', f"{os.environ['MSG_INTERFACE_START']} {sys.argv[0]} {' '.join(sys.argv[1:])}")
og_log_file = os.getenv('OGLOGFILE')
if og_log_file:
with open(og_log_file, 'a') as log_file:
log_file.write("\n Instrucciones a ejecutar: *****************************\n")
with open(script_path) as script_file:
log_file.write(script_file.read())
log_file.write("\n Salida de las instrucciones: *****************************\n")
with open(os.environ['OGLOGFILE'], 'a') as log_file:
log_file.write("\n Instrucciones a ejecutar: *****************************\n"
with open(script_path.split()[1]) as script_file: # Obtener solo el nombre del script
log_file.write(script_file.read()) )
# Execute the script
os.chmod(script_path, 0o755)
retval = subprocess.call([script_path])
log_file.write("\n Salida de las instrucciones: *****************************\n")
# Cambiar permisos y ejecutar el script
os.chmod(script_path.split()[1], 0o755)
result = subprocess.run([sys.executable] + script_path.split(), capture_output=True, text=True)
ret_val = result.returncode
with open(os.environ['OGLOGCOMMAND'], 'a') as log_command_file:
log_command_file.write(result.stdout)
log_command_file.write(result.stderr)
elapsed_time = time.time() - start_time
if retval == 0:
og_echo('log session', f"[100] Duracion de la operacion {int(elapsed_time // 60)}m {int(elapsed_time % 60)}s")
if ret_val == 0:
SystemLib.ogEcho('log session', f"[100] Duracion de la operacion {int(elapsed_time // 60)}m {int(elapsed_time % 60)}s")
else:
og_raise_error('log session', retval)
og_echo('log session error', "Operacion no realizada")
SystemLib.ogRaiseError('log session', ret_val)
SystemLib.ogEcho('log session', 'error "Operacion no realizada"')
# Registro de fin de ejecución
msg_interface_end = os.getenv('MSG_INTERFACE_END')
og_echo('log session', f"{msg_interface_end} {retval}")
SystemLib.ogEcho('log session', f"{os.environ['MSG_INTERFACE_END']} {ret_val}")
sys.exit(retval)
sys.exit(ret_val)
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python EjecutarScript.py <script_path>")
sys.exit(1)
main(sys.argv[1])
main(sys.argv[1])

View File

@ -0,0 +1,121 @@
#!/usr/bin/env python3
import os
import subprocess
import sys
import FileSystemLib
import DiskLib
os.environ["DEBUG"] = "no"
# Obtener el número de serie y configuración inicial
ser = subprocess.getoutput("ogGetSerialNumber")
cfg = ""
# Obtener el número de discos
disks = len(subprocess.getoutput("ogDiskToDev").split())
for dsk in disk_list:
# Número de particiones
particiones = FileSystemLib.ogGetPartitionsNumber(dsk) or "0"
particiones = int(particiones)
# Tipo de tabla de particiones
ptt = DiskLib.ogGetPartitionTableType(dsk)
ptt_mapping = {"MSDOS": 1, "GPT": 2, "LVM": 3, "ZPOOL": 4}
ptt = ptt_mapping.get(ptt, 0)
# Información de disco (partición 0)
disk_size = DiskLib.ogGetDiskSize(dsk)
cfg += f"{dsk}:0:{ptt}:::{disk_size}:0;"
# Recorrer particiones
for par in range(1, particiones + 1):
# Código del identificador de tipo de partición
cod = DiskLib.ogGetPartitionId(dsk, par)
# Tipo del sistema de ficheros
fsi = FileSystemLib.getFsType(dsk, par) or "EMPTY"
# Tamaño de la partición
tam = DiskLib.ogGetPartitionSize(dsk, par) or "0"
# Sistema operativo instalado
soi = ""
uso = 0
if fsi not in ["", "EMPTY", "LINUX-SWAP", "LINUX-LVM", "ZVOL"]:
mount_point = DiskLib.ogMount(dsk, par)
if mount_point:
# Obtener la versión del sistema operativo instalado
try:
# Asumiendo que getOsVersion es una función disponible
import OsLib # Debes tener OsLib.py disponible con la función getOsVersion
soi_output = OsLib.getOsVersion(dsk, par)
except ImportError:
# Si no está disponible, usar subprocess como alternativa
soi_output = subprocess.getoutput(f"getOsVersion {dsk} {par} 2>/dev/null")
soi = soi_output.split(':')[1] if ':' in soi_output else ''
# Hacer un segundo intento para algunos casos especiales
if not soi:
soi_output = subprocess.getoutput(f"getOsVersion {dsk} {par} 2>/dev/null")
soi = soi_output.split(':')[1] if ':' in soi_output else ''
# Sistema de archivos para datos (sistema operativo "DATA")
if not soi and fsi not in ["EMPTY", "CACHE"]:
soi = "DATA"
# Obtener porcentaje de uso
mount_point = DiskLib.ogGetMountPoint(dsk, par)
df_output = subprocess.getoutput(f"df {mount_point}")
lines = df_output.splitlines()
if len(lines) >= 2:
uso_str = lines[1].split()[4] # Esta debería ser la quinta columna
if uso_str.endswith('%'):
uso = int(uso_str.rstrip('%'))
else:
uso = int(uso_str)
else:
uso = 0
else:
soi = ""
uso = 0
else:
soi = ""
uso = 0
cfg += f"{dsk}:{par}:{cod}:{fsi}:{soi}:{tam}:{uso};"
# Configuración por defecto para cliente sin disco
if not cfg:
cfg = "1:0:0:::0;"
# Guardar salida en fichero temporal
cfgfile = "/tmp/getconfig"
with open(cfgfile, 'w') as f:
f.write(f"{ser + ';' if ser else ''}{cfg}")
# Crear el menú por defecto desde el archivo generado
subprocess.run(["generateMenuDefault"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
# Componer salida formateada
formatted_output = []
with open(cfgfile, 'r') as f:
content = f.read().strip().split(";")
for item in content:
fields = item.split(":")
if len(fields) == 1:
formatted_output.append(f"ser={fields[0]}")
else:
formatted_output.append(
f"disk={fields[0]}\tpar={fields[1]}\tcpt={fields[2]}\tfsi={fields[3]}\tsoi={fields[4]}\ttam={fields[5]}\tuso={fields[6]}"
)
# Mostrar la salida formateada
print("\n".join(formatted_output))
# Borrar marcas de arranque de Windows
subprocess.run(["rm", "-f", "/mnt/*/ogboot.*", "/mnt/*/*/ogboot.*"])
# Volver a registrar los errores
os.environ.pop("DEBUG", None)

View File

@ -1,3 +1,4 @@
#!/usr/bin/env python3
import sys
import subprocess
@ -14,4 +15,4 @@ def main():
boot_os(disk, part)
if __name__ == "__main__":
main()
main()

View File

@ -1,20 +1,33 @@
#!/usr/bin/env python3
import subprocess
import sys
def list_hardware_info():
# Replace this with the actual command to list hardware info
result = subprocess.run(['listHardwareInfo'], capture_output=True, text=True)
return result.stdout
def main(output_file):
# Ejecutar el comando `listHardwareInfo.py` y capturar el resultado
try:
print(f"------------------------------------------ loading listHardwareInfo.py")
result = subprocess.run(
["python3", "/opt/opengnsys/scripts/listHardwareInfo.py"],
capture_output=True, text=True, check=True
)
output_lines = result.stdout.strip().split('\n')
file_path = output_lines[-1] # Obtener la última línea como la ruta del archivo de salida
print(f"------------------------------------------ archivo:{file_path}")
# Leer desde la segunda línea del archivo y escribir en el archivo de salida especificado
with open(file_path, 'r') as input_file, open(output_file, 'w') as output:
lines = input_file.readlines()[1:] # Saltar la primera línea
output.writelines(lines)
def save_hardware_inventory(output_file):
hardware_info = list_hardware_info()
lines = hardware_info.splitlines()
if len(lines) > 1:
with open(output_file, 'w') as f:
f.write('\n'.join(lines[1:]))
except subprocess.CalledProcessError as e:
print("Error ejecutando listHardwareInfo.py:", e.stderr, file=sys.stderr)
sys.exit(e.returncode)
except FileNotFoundError as e:
print(f"Archivo no encontrado: {e.filename}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python InventarioHardware.py <output_file>")
else:
save_hardware_inventory(sys.argv[1])
print("Uso: python3 InventarioHardware.py <archivo_salida>")
sys.exit(1)
main(sys.argv[1])

View File

@ -1,21 +1,19 @@
#!/usr/bin/env python3
import os
import time
import shutil
import subprocess
import sys
sys.path.append('/opt/opengnsys/lib/engine/bin')
import ogGlobals
import SystemLib
def main(arg1, arg2, dest_file):
start_time = time.time()
# Load the engine configurator from the engine.cfg file
og_engine_configurate = os.getenv('OGENGINECONFIGURATE')
if not og_engine_configurate:
with open('/opt/opengnsys/etc/engine.cfg') as f:
exec(f.read())
# Clear the temporary files used as log tracking for httpdlog
og_log_session = os.getenv('OGLOGSESSION')
og_log_command = os.getenv('OGLOGCOMMAND')
og_log_session = os.getenv(ogGlobals.OGLOGSESSION)
og_log_command = os.getenv(ogGlobals.OGLOGCOMMAND)
if og_log_session and og_log_command:
with open(og_log_session, 'w') as f:
f.write(" ")
@ -24,26 +22,32 @@ def main(arg1, arg2, dest_file):
with open(f"{og_log_command}.tmp", 'w') as f:
f.write(" ")
# Log the start of execution
msg_interface_start = os.getenv('MSG_INTERFACE_START')
msg_interface_start = os.getenv(ogGlobals.lang.MSG_INTERFACE_START)
if msg_interface_start:
subprocess.run(['ogEcho', 'log', 'session', f"{msg_interface_start} {__file__} {arg1} {arg2}"])
SystemLib.ogEcho("log", "session", f"{msg_interface_start} {__file__} {arg1} {arg2}")
# Get the software info file and copy it to the destination
# Call the actual listSoftwareInfo function
file = listSoftwareInfo(arg1, arg2)
try:
result = subprocess.run(
["python3", "/opt/opengnsys/scripts/listSoftwareInfo.py", arg1, arg2],
capture_output=True,
text=True,
check=True
)
file = result.stdout.strip().splitlines()[-1]
except subprocess.CalledProcessError as e:
print(f"Error al ejecutar listSoftwareInfo: {e.stderr}")
sys.exit(e.returncode)
print(f"Copying:( {file} to {dest_file} )")
shutil.copy(file, dest_file)
# Log the execution time
elapsed_time = time.time() - start_time
msg_scripts_time_partial = os.getenv('MSG_SCRIPTS_TIME_PARTIAL')
msg_scripts_time_partial = os.getenv(ogGlobals.lang.MSG_SCRIPTS_TIME_PARTIAL)
if msg_scripts_time_partial:
subprocess.run(['ogEcho', 'log', 'session', f" [ ] {msg_scripts_time_partial} : {int(elapsed_time // 60)}m {int(elapsed_time % 60)}s"])
SystemLib.ogEcho("log", "session", f" [ ] {msg_scripts_time_partial} : {int(elapsed_time // 60)}m {int(elapsed_time % 60)}s")
if __name__ == "__main__":
if len(sys.argv) != 4:
print("Usage: python InventarioSoftware.py <arg1> <arg2> <dest_file>")
sys.exit(1)
main(sys.argv[1], sys.argv[2], sys.argv[3])
main(sys.argv[1], sys.argv[2], sys.argv[3])

3
client/interfaceAdm/Reiniciar.py 100644 → 100755
View File

@ -1,7 +1,8 @@
#!/usr/bin/env python3
import os
def reboot_system():
os.system('reboot')
if __name__ == "__main__":
reboot_system()
reboot_system()

View File

@ -1,3 +1,4 @@
#!/usr/bin/env python3
import sys
import subprocess
@ -15,4 +16,4 @@ if __name__ == "__main__":
additional_args = sys.argv[7:]
exit_code = deploy_image(ip, image_name, disk, partition, protocol, protocol_options, *additional_args)
sys.exit(exit_code)
sys.exit(exit_code)

View File

@ -1,3 +1,4 @@
#!/usr/bin/env python3
import os
import subprocess
@ -76,4 +77,4 @@ def main():
os.environ.pop("DEBUG", None)
if __name__ == "__main__":
main()
main()

View File

@ -1,5 +1,10 @@
import socket
#!/usr/bin/env python3
import socket
def get_ip_address():
hostname = socket.gethostname()
ip_address = socket.gethostbyname(hostname)
return ip_address
if __name__ == "__main__":
print("IP Address:", get_ip_address())
print(get_ip_address())

View File

@ -1,3 +1,4 @@
#!/usr/bin/env python3
import sys
if __name__ == "__main__":
@ -5,4 +6,4 @@ if __name__ == "__main__":
print("Usage: python procesaCache.py <arg>")
sys.exit(1)
init_cache(sys.argv[1])
init_cache(sys.argv[1])

File diff suppressed because it is too large Load Diff

459
client/lib/engine/bin/CacheLib.py 100644 → 100755
View File

@ -5,208 +5,357 @@ import shutil
import sys
import platform
from FileSystemLib import *
from SystemLib import *
from DiskLib import *
import ogGlobals
import SystemLib
import DiskLib
import FileSystemLib
import CacheLib
print (">>>>>>>>>>>>>>>>>>>> Load ", __name__, " <<<<<<<<<<<<<<<<<<<<<<")
#/**
# ogCreateCache [int_ndisk] int_partsize
#@brief Define la caché local, por defecto en partición 4 del disco 1.
#@param int_ndisk numero de disco donde crear la cache, si no se indica es el 1 por defecto
#@param int_npart número de partición (opcional, 4 por defecto)
#@param int_partsize tamaño de la partición (en KB)
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@note Requisitos: sfdisk, parted, awk, sed
#@warning El tamaño de caché debe estar entre 50 MB y la mitad del disco.
#@warning La caché no puede solaparse con las particiones de datos.
#*/ ##
def ogCreateCache (ndsk=1, part=4, sizecache=0):
if not sizecache:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '')
return None
sizecache = int (sizecache)
def ogCreateCache(ndisk=1, npart=4, partsize=None):
"""
Define la caché local, por defecto en partición 4 del disco 1.
:param ndisk: número de disco donde crear la caché, por defecto es 1.
:param npart: número de partición (opcional, 4 por defecto).
:param partsize: tamaño de la partición en KB.
:raises ValueError: Si el formato de los parámetros es incorrecto.
:raises RuntimeError: Si ocurre un error durante la creación de la caché.
"""
DISK = DiskLib.ogDiskToDev (ndsk)
if not DISK: return None
if partsize is None:
raise ValueError("El tamaño de la partición debe especificarse.")
# PATCH Para discos nvme la particion debe ser p1, p2, etc...en lugar de 1,2, sino falla sfdisk
NVME_PREFIX = ''
if 'nvme' in DISK:
NVME_PREFIX = 'p'
# Verifica si las herramientas necesarias están instaladas
required_tools = ["sfdisk", "parted", "awk", "sed"]
for tool in required_tools:
if not shutil.which(tool):
raise RuntimeError(f"La herramienta {tool} no está instalada.")
END = DiskLib.ogGetLastSector (ndsk)
SIZE = 2 * sizecache
# Inicio partición cache según el disco tenga sectores de 4k o menores
IOSIZE = 0
fdisk_out = subprocess.run (['fdisk', '-l', DISK], capture_output=True, text=True).stdout
for l in fdisk_out.splitlines():
items = l.split()
if len(items) < 4: continue
if 'I/O' == items[0]:
IOSIZE = int (items[3])
break
START = 0
if 4096 == IOSIZE:
END -= 8192
START = END - SIZE + 2048 - (END-SIZE)%2048
else:
START = END - SIZE + 1
# Preparar los comandos para crear la caché
disk = f"/dev/sd{chr(96 + ndisk)}"
size_in_sectors = partsize * 2 # Asumiendo 512B por sector
try:
# Lógica simplificada para crear la caché en la partición
subprocess.run(["parted", disk, "mkpart", "primary", str(npart), str(partsize)], check=True)
except subprocess.CalledProcessError as e:
raise RuntimeError(f"Error al crear la caché: {e}")
def ogDeleteCache():
"""
Borra la partición utilizada para caché.
:raises RuntimeError: Si ocurre un error durante la eliminación de la partición de caché.
"""
cachepart = ogFindCache()
if cachepart is None:
raise RuntimeError("No se encontró la partición de caché.")
disk = f"/dev/sd{chr(96 + int(cachepart))}"
try:
subprocess.run(["parted", disk, "rm", cachepart], check=True)
except subprocess.CalledProcessError as e:
raise RuntimeError(f"Error al borrar la partición de caché: {e}")
def ogFindCache():
"""
Encuentra la partición que se usa como caché.
:return: El nombre de la partición de caché si se encuentra, de lo contrario None.
"""
try:
for disk in [f"/dev/sd{chr(97 + i)}" for i in range(26)]: # /dev/sda to /dev/sdz
result = subprocess.run(["sfdisk", "-d", disk], capture_output=True, text=True, check=True)
if "CA00" in result.stdout:
cachepart = [line.split()[0] for line in result.stdout.splitlines() if "CA00" in line][0]
return cachepart
except subprocess.CalledProcessError:
ENDPREVPART = None
i = 1
while True:
prev_part = part - i
if prev_part <= 0: break
ENDPREVPART = DiskLib.ogGetLastSector (ndsk, prev_part)
if ENDPREVPART: break
i += 1
if not ENDPREVPART:
ENDPREVPART=0
#SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, ndsk)
#return None
# Error si tamaño no está entre límites permitidos o si se solapa con la partición anterior.
MINSIZE = 25000
MAXSIZE = END
if SIZE < MINSIZE or SIZE > MAXSIZE or START < ENDPREVPART:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, ndsk)
return None
return None
# Desmontar todos los sistemas de archivos del disco.
FileSystemLib.ogUnmountAll (ndsk)
# Definir particiones y notificar al kernel.
# En el caso de ser disco GPT, de momento se borra la particion y se vuelve a crear,
# por lo que se pierden los datos.
pttype = DiskLib.ogGetPartitionTableType (ndsk)
if not pttype:
pttype = 'MSDOS'
DiskLib.ogCreatePartitionTable (ndsk, pttype)
get_ptt = DiskLib.ogGetPartitionTableType (ndsk)
if 'GPT' == get_ptt:
# Si la tabla de particiones no es valida, volver a generarla.
if subprocess.run (['sgdisk', '-p', DISK]).returncode:
subprocess.run (['gdisk', DISK], input='2\nw\nY\n', text=True)
# Si existe la cache se borra previamente
if ogFindCache(): ogDeleteCache()
# Capturamos el codigo de particion GPT para cache
# PATCH - Cuando es GPT, la particion con codigo CACHE (CA00) no existe y no puede crearse, se cambia por LINUX (8300)
ID = DiskLib.ogTypeToId ('LINUX', 'GPT')
subprocess.run (['sgdisk', DISK, f'-n{part}:{START}:{END}', f'-c{part}:CACHE', f'-t{part}:{ID}'])
elif 'MSDOS' == get_ptt:
# Si la tabla de particiones no es valida, volver a generarla.
if subprocess.run (['parted', '-s', DISK, 'print']).returncode:
subprocess.run (['fdisk', DISK], input='w\n', text=True)
# Definir particiones y notificar al kernel.
ID = DiskLib.ogTypeToId ('CACHE', 'MSDOS')
# Salvamos la configuración de las particiones e incluimos la cache.
tmp = subprocess.run (['sfdisk', '--dump', DISK], capture_output=True, text=True).stdout.splitlines()
tmp = [ x for x in tmp if f'{DISK}{part}' not in x ]
tmp.append (f'{DISK}{NVME_PREFIX}{part} : start= {START}, size= {SIZE}, Id={ID}')
# Ordenamos las líneas de los dispositivos
UNIT = [ x for x in tmp if 'unit' in x ][0]
tmp = sorted ([ x for x in tmp if re.match ('^/dev', x) ])
tmp = [UNIT, ''] + tmp
# Guardamos nueva configuración en el disco.
i = '\n'.join(tmp)
subprocess.run (['sfdisk', '--no-reread', DISK], input=i, text=True)
# Actualiza la tabla de particiones en el kernel.
DiskLib.ogUpdatePartitionTable()
#/**
# ogDeleteCache
#@brief Elimina la partición de caché local.
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@note Requisitos: fdisk, sgdisk, partprobe
#*/ ##
def ogDeleteCache():
cachepart = ogFindCache()
if not cachepart:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE)
return None
ndisk, npart = cachepart.split()
disk = DiskLib.ogDiskToDev (ndisk)
# Desmontar todos los sistemas de archivos del disco.
FileSystemLib.ogUnmountAll (ndisk)
ptt = DiskLib.ogGetPartitionTableType (ndisk)
if 'GPT' == ptt:
# Si la tabla de particiones no es valida, volver a generarla.
if subprocess.run (['sgdisk', '-p', disk]).returncode:
subprocess.run (['gdisk', disk], input='2\nw\nY\n', text=True)
subprocess.run (['sgdisk', disk, f'-d{npart}'])
elif 'MSDOS' == ptt:
# Si la tabla de particiones no es valida, volver a generarla.
if subprocess.run (['parted', '-s', disk, 'print']).returncode:
subprocess.run (['fdisk', disk], input='w', text=True)
# Eliminar la partición de caché.
subprocess.run (['fdisk', disk], input=f'd\n{npart}\nw', text=True)
# Borrar etiqueta de la caché.
if os.path.exists ('/dev/disk/by-label/CACHE'):
os.unlink ('/dev/disk/by-label/CACHE')
#Actualiza la tabla de particiones en el kernel.
DiskLib.ogUpdatePartitionTable()
#/**
# ogFindCache
#@brief Detecta la partición caché local.
#@param No requiere parametros
#@return int_ndisk int_npart - devuelve el par nº de disco-nº de partición .
#@warning Si no hay cache no devuelve nada
#*/ ##
def ogFindCache():
# Obtener el dispositivo del sistema de archivos etiquetado como "CACHE".
PART = subprocess.run (['blkid', '-L', 'CACHE'], capture_output=True, text=True).stdout.strip()
# En discos nvme con particiones GPT la partición se detecta usando el tag PARTLABEL
if not PART:
out = subprocess.run (['blkid', '-t', 'PARTLABEL=CACHE'], capture_output=True, text=True).stdout.strip()
PART = out.split (':')[0]
# Si no se detecta, obtener particiones marcadas de tipo caché en discos MSDOS.
if not PART:
out = subprocess.run (['sfdisk', '-l'], capture_output=True, text=True).stdout.splitlines()
for l in out:
elems = l.split (maxsplit=5)
if 6 > len (elems): continue
if 'ca' in elems[5] or 'a7' in elems[5]:
PART=elems[0]
break
# Por último revisar todos los discos GPT y obtener las particiones etiquetadas como caché.
if not PART:
PART = ''
for d in DiskLib.ogDiskToDev():
out = subprocess.run (['sgdisk', '-p', d], capture_output=True, text=True).stdout.splitlines()
for l in out:
elems = l.split (maxsplit=6)
if 7 > len (elems): continue
if 'CACHE' in elems[6]:
p = 'p' if 'nvme' in d else ''
PART += f' {d}{p}{elems[0]}'
if not PART: return
return DiskLib.ogDevToDisk (PART.split()[0]) # usar la 1ª partición encontrada.
#/**
# ogFormatCache
#@brief Formatea el sistema de ficheros para la caché local.
#@return (por determinar)
#@warning Prueba con formato Reiser.
#@attention
#@note El sistema de archivos de la caché se queda montado.
#*/ ##
def ogFormatCache():
"""
Formatea la partición de caché.
:raises RuntimeError: Si ocurre un error durante el formateo de la partición.
"""
# Si se solicita, mostrar ayuda.
if len(sys.argv) > 1 and sys.argv[1] == "help":
ogHelp("ogFormatCache", "ogFormatCache")
return
# Error si no hay definida partición de caché.
cachepart = ogFindCache()
if cachepart is None:
ogRaiseError(OG_ERR_PARTITION, MSG_NOCACHE)
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE)
return
disk = ogDiskToDev(cachepart)
cachepart = cachepart.split()
disk = DiskLib.ogDiskToDev (cachepart[0], cachepart[1])
if not disk: return
# Formatear sistema de ficheros.
ogUnmountCache()
options = "extent,large_file"
if re.match("^5", platform.release()):
options += ",uninit_bg,^metadata_csum,^64bit"
try:
subprocess.run(["mkfs.ext4", "-q", "-F", disk, "-L", "CACHE", "-O", options], check=True)
except subprocess.CalledProcessError as e:
raise RuntimeError(f"Error al formatear la partición de caché: {e}")
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, "CACHE")
return
# Crear estructura básica.
mntdir = ogMountCache()
os.makedirs(os.path.join(mntdir, OGIMG), exist_ok=True)
j = '/'.join ([mntdir, ogGlobals.OGIMG]) ## os.path.join doesn't work: "If a segment […] is an absolute path, all previous segments are ignored"
#print (f'cucu mntdir ({mntdir}) OGIMG ({ogGlobals.OGIMG}) j ({j})')
os.makedirs (j, exist_ok=True)
# Incluir kernel e Initrd del ogLive
updateBootCache()
## como lo llamo sin especificar el path entero?
#subprocess.run (['scripts/updateBootCache.py']) ## TODO
#/**
# ogGetCacheSize
#@brief Devuelve el tamaño definido para la partición de caché.
#@return int_partsize tamaño de la partición (en KB)
#@exception OG_ERR_PARTITION No existe partición de caché.
#*/ ##
def ogGetCacheSize():
"""
Obtiene el tamaño de la partición de caché.
:return: Tamaño de la partición de caché en kilobytes.
:raises RuntimeError: Si ocurre un error al obtener el tamaño de la partición de caché.
"""
# Si se solicita, mostrar ayuda.
if len(sys.argv) > 1 and sys.argv[1] == "help":
ogHelp("ogGetCacheSize", "help", "ogGetCacheSize")
# Error si no se encuentra partición de caché.
cachepart = ogFindCache()
if cachepart is None:
raise RuntimeError(MSG_NOCACHE)
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE)
return None
# Devuelve tamaño de la partición de caché.
return ogGetPartitionSize(cachepart)
disk, par = cachepart.split()
return DiskLib.ogGetPartitionSize (disk, par)
#/**
# ogGetCacheSpace
#@brief Devuelve el espacio de disco disponible para la partición de caché.
#@return int_size tamaño disponible (en KB)
#@note El espacio disponible es el que hay entre el límite superior de la partición 3 del disco 1 y el final de dicho disco, y no puede ser superior a la mitad de dicho disco.
#*/ ##
def ogGetCacheSpace():
"""
Obtiene el espacio libre en la partición de caché en kilobytes.
:return: Espacio libre en kilobytes.
:raises RuntimeError: Si ocurre un error al obtener el espacio libre.
"""
# Si se solicita, mostrar ayuda.
if len(sys.argv) > 1 and sys.argv[1] == "help":
ogHelp("ogGetCacheSpace", "help", "ogGetCacheSpace")
# Error si no se encuentra partición de caché.
cachepart = ogFindCache()
if cachepart is None:
raise RuntimeError(MSG_NOCACHE)
if not cachepart:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE)
return None
cachepart = cachepart.split()
# Obtener el tamaño del disco y el número de sectores.
disk = ogDiskToDev(cachepart)
try:
result = subprocess.run(["sfdisk", "-g", disk], capture_output=True, text=True, check=True)
output = result.stdout
sectors_per_cylinder = int(output.splitlines()[1].split()[1])
total_sectors = int(output.splitlines()[1].split()[0]) * sectors_per_cylinder - 1
except subprocess.CalledProcessError as e:
raise RuntimeError(f"Error al obtener el espacio libre: {e}")
disk = DiskLib.ogDiskToDev (cachepart[0])
if not disk:
return None
# Obtener el último sector de la partición 3.
try:
result = subprocess.run(["sfdisk", "-uS", "-l", disk], capture_output=True, text=True, check=True)
output = result.stdout
end_sector_part3 = int([line.split()[2] for line in output.splitlines() if cachepart + "3" in line][0])
except subprocess.CalledProcessError as e:
raise RuntimeError(f"Error al obtener el espacio libre: {e}")
sectors = 0
disk_bn = os.path.basename (disk)
with open ('/proc/partitions', 'r') as fd:
proc_parts = fd.read()
for l in proc_parts.splitlines():
items = l.split()
if len(items) < 4: continue
if items[3] == disk_bn:
sectors = 2 * int (items[2])
if not sectors: return None
# Calcular el espacio libre en kilobytes.
if end_sector_part3 > total_sectors // 2:
free_space_kb = (total_sectors - end_sector_part3) // 2
sfdisk_out = subprocess.run (['sfdisk', '-g', disk], capture_output=True, text=True).stdout
cyls = int (sfdisk_out.split()[1])
sectors = sectors/cyls * cyls - 1
## the original code has a hard dependency on the existence of a third partition
## if the disk has sda1, sda2 and sda4, the code fails.
## this is an improved version
endpart3 = 0
for trypart in [3, 2, 1]:
sfdisk_out = subprocess.run (['sfdisk', '-uS', '-l', disk], capture_output=True, text=True).stdout
for l in sfdisk_out.splitlines():
items = l.split()
if len(items) < 6: continue
if f'{disk}{trypart}' == items[0]:
endpart3 = int (items[2])
break
if endpart3: break
if not endpart3: return None
# Mostrar espacio libre en KB (1 KB = 2 sectores)
if endpart3 > sectors // 2:
return (sectors - endpart3) // 2
else:
free_space_kb = total_sectors // 4
return sectors // 4
return free_space_kb
#/**
# ogMountCache
#@brief Monta la partición Cache y exporta la variable $OGCAC
#@param sin parametros
#@return path_mountpoint - Punto de montaje del sistema de archivos de cache.
#@warning Salidas de errores no determinada
#*/ ##
def ogMountCache():
"""
Monta la partición de caché en el directorio /mnt/sda4.
c = ogFindCache()
if not c:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE)
return None
:raises RuntimeError: Si ocurre un error durante el montaje de la partición de caché.
"""
# Si se solicita, mostrar ayuda.
if len(sys.argv) > 1 and sys.argv[1] == "help":
ogHelp("ogMountCache", "help", "ogMountCache")
c = c.split()
m = FileSystemLib.ogMountFs (c[0], c[1])
if not m:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE)
return None
return m
# Montar la partición de caché en /mnt/sda4.
try:
subprocess.run(["mount", ogFindCache(), "/mnt/sda4"], check=True)
except subprocess.CalledProcessError as e:
raise RuntimeError(f"Error al montar la partición de caché: {e}")
#/**
# ogUnmountCache
#@brief Desmonta la particion Cache y elimina la variable $OGCAC
#@param sin parametros
#@return nada
#@warning Salidas de errores no determinada
#*/ ##
def ogUnmountCache():
"""
Desmonta la partición de caché.
:raises RuntimeError: Si ocurre un error durante el desmontaje de la partición de caché.
"""
# Si se solicita, mostrar ayuda.
if len(sys.argv) > 1 and sys.argv[1] == "help":
ogHelp("ogUnmountCache", "help", "ogUnmountCache")
# Obtener la partición de caché.
cachepart = ogFindCache()
if cachepart is None:
raise RuntimeError("No se encontró la partición de caché.")
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE)
return
# Desmontar la partición de caché.
try:
subprocess.run(["umount", cachepart], check=True)
except subprocess.CalledProcessError as e:
raise RuntimeError(f"Error al desmontar la partición de caché: {e}")
cachepart = cachepart.split()
if not FileSystemLib.ogIsMounted (cachepart[0], cachepart[1]): return True
FileSystemLib.ogUnmountFs (cachepart[0], cachepart[1])
# Eliminar el enlace simbólico de /mnt/ParticiónCache.
os.remove(f"/mnt/{cachepart}")
dev = DiskLib.ogDiskToDev (cachepart[0], cachepart[1])
dev = dev.replace ('dev', 'mnt')
if os.path.exists (dev): os.remove (dev)
#/**
# initCache
#@brief Simplemente llama al script initCache
#@brief Es necesario tener una función para poder pasársela a ogExecAndLog
#@param los mismos parametros que initCache
#@return lo mismo que devuelve initCache
#*/ ##
def initCache (*args):
p = subprocess.run (['/opt/opengnsys/images/nati/client/shared/scripts/initCache.py'] + list(args))
return p.returncode

2393
client/lib/engine/bin/DiskLib.py 100644 → 100755

File diff suppressed because it is too large Load Diff

576
client/lib/engine/bin/FileLib.py 100644 → 100755
View File

@ -1,33 +1,86 @@
#/**
#@file FileLib.py
#@brief Librería o clase File
#@class File
#@brief Funciones para gestión de archivos y directorios.
#@warning License: GNU GPLv3+
#*/
import subprocess
import os
import shutil
import hashlib
print (">>>>>>>>>>>>>>>>>>>> Load ", __name__, " <<<<<<<<<<<<<<<<<<<<<<")
import ogGlobals
import SystemLib
import CacheLib
import FileSystemLib
def ogCalculateChecksum(*args):
# Check if help is requested
if "help" in args:
print("ogCalculateChecksum [ str_repo | int_ndisk int_npartition ] path_filepath")
print("ogCalculateChecksum REPO ubuntu.img ==> ef899299caf8b517ce36f1157a93d8bf")
#/**
# ogCalculateChecksum [ str_repo | int_ndisk int_npart ] path_filepath
#@brief Devuelve la suma de comprobación (checksum) de un fichero.
#@param path_filepath camino del fichero (independiente de mayúsculas)
#@param str_repo repositorio de ficheros
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return hex_checksum Checksum del fichero
#*/ ##
#ogCalculateChecksum ([ str_repo | int_ndisk int_npartition ] path_filepath")
#ogCalculateChecksum (container='REPO', file='ubuntu.img') ==> ef899299caf8b517ce36f1157a93d8bf
#ogCalculateChecksum (disk=1, par=1, file='ubuntu.img') ==> ef899299caf8b517ce36f1157a93d8bf
def ogCalculateChecksum (disk=None, par=None, container=None, file=None):
if file is None:
raise TypeError ('missing required argument: "file"')
if container is not None:
if disk is None and par is None:
## we were given container=
f = ogGetPath (src=container, file=file)
dev_err = f'{container} {file}'
print (f'ogGetPath (src=({container}), file=({file})) = f ({f})')
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if disk is not None and par is not None:
## we were given disk= par=
f = ogGetPath (src=f'{disk} {par}', file=file)
dev_err = f'{disk} {par} {file}'
print (f'ogGetPath (src=({disk} {par}), file=({file})) = f ({f})')
elif disk is None and par is None:
## we were given nothing
f = ogGetPath (file=file)
dev_err = file
print (f'ogGetPath (file=({file})) = f ({f})')
else:
raise TypeError ('if one of "disk" and "par" are specified, then both must be')
if not f:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, dev_err)
return
# Get the file path
file_path = ogGetPath(*args)
if not file_path:
ogRaiseError(OG_ERR_NOTFOUND, *args)
return
last_n_bytes = 1024*1024
if last_n_bytes >= os.stat (f).st_size:
return ogCalculateFullChecksum (disk, par, container, file)
with open (f, 'rb') as fd:
fd.seek (-last_n_bytes, os.SEEK_END)
data = fd.read()
md5 = hashlib.md5(data).hexdigest()
# Calculate the checksum
result = subprocess.run(["tail", "-c1M", file_path], capture_output=True)
checksum = result.stdout.decode().split()[0]
return md5
return checksum
#/**
# ogCompareChecksumFiles [ str_repo | int_ndisk int_npart ] path_source [ str_repo | int_ndisk int_npart ] path_target
#@brief Metafunción que compara las sumas de comprobación almacenadas de 2 ficheros.
#@return bool_compare Valor de comparación.
#@warning No es necesario especificar la extensión ".sum".
#*/ ##
def ogCompareChecksumFiles(*args):
# Variables locales.
ARGS = args
if "help" in args:
ogHelp("$FUNCNAME", "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_filepath", "if $FUNCNAME REPO ubuntu.img CACHE ubuntu.img; then ...; fi")
SystemLib.ogHelp("$FUNCNAME", "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_filepath", "if $FUNCNAME REPO ubuntu.img CACHE ubuntu.img; then ...; fi")
return
ARGS = args
@ -56,181 +109,305 @@ def ogCompareChecksumFiles(*args):
except FileNotFoundError:
return False
def ogCalculateFullChecksum(*args):
# Variables locales.
FILE = None
if "help" in args:
ogHelp("$FUNCNAME", "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_filepath", "$FUNCNAME REPO ubuntu.img ==> ef899299caf8b517ce36f1157a93d8bf")
return
# Comprobar que existe el fichero y devolver sus datos.
FILE = ogGetPath(*args)
if not FILE:
ogRaiseError(OG_ERR_NOTFOUND, *args)
return
#/**
# ogCalculateFullChecksum [ str_repo | int_ndisk int_npart ] path_filepath
#@brief Devuelve la suma COMPLETA de comprobación (checksum) de un fichero.
#@param path_filepath camino del fichero (independiente de mayúsculas)
#@param str_repo repositorio de ficheros
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return hex_checksum Checksum del fichero
#*/ ##
def ogCalculateFullChecksum (disk=None, par=None, container=None, file=None):
if file is None:
raise TypeError ('missing required argument: "file"')
# Calculate the checksum
result = subprocess.run(["md5sum", FILE, "-b"], capture_output=True)
checksum = result.stdout.decode().split()[0]
if container is not None:
if disk is None and par is None:
## we were given container=
f = ogGetPath (src=container, file=file)
dev_err = f'{container} {file}'
print (f'ogGetPath (src=({container}), file=({file})) = f ({f})')
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
return checksum
def ogCopyFile(*args):
# Variables locales.
ARGS = args
if "help" in args:
ogHelp("$FUNCNAME", "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_source [ str_repo | int_ndisk int_npartition ] path_target", "$FUNCNAME REPO newfile.txt 1 2 /tmp/newfile.txt")
return
ARGS = args
if args[0].startswith("/"):
# Camino completo. */ (Comentrio Doxygen)
SOURCE = ogGetPath(*args[:1])
args = args[1:]
elif args[0].isdigit():
# ndisco npartición.
SOURCE = ogGetPath(*args[:3])
args = args[3:]
else:
# Otros: repo, cache, cdrom (no se permiten caminos relativos).
SOURCE = ogGetPath(*args[:2])
args = args[2:]
if disk is not None and par is not None:
## we were given disk= par=
f = ogGetPath (src=f'{disk} {par}', file=file)
dev_err = f'{disk} {par} {file}'
print (f'ogGetPath (src=({disk} {par}), file=({file})) = f ({f})')
elif disk is None and par is None:
## we were given nothing
f = ogGetPath (file=file)
dev_err = file
print (f'ogGetPath (file=({file})) = f ({f})')
else:
raise TypeError ('if one of "disk" and "par" are specified, then both must be')
TARGET = ogGetPath(*args)
if not f:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, dev_err)
return
md5 = hashlib.md5()
with open (f, 'rb') as fd:
for chunk in iter (lambda: fd.read (64*1024), b''):
md5.update (chunk)
return md5.hexdigest()
#/**
# ogCopyFile [ str_repo | int_ndisk int_npart ] path_source [ str_repo | int_ndisk int_npart ] path_target
#@brief Metafunción para copiar un fichero de sistema OpenGnSys a un directorio.
#@see ogGetPath
#@return Progreso de la copia.
#@warning Deben existir tanto el fichero origen como el directorio destino.
#*/ ##
#ogCopyFile (src, dst)
#ogCopyFile ({container='REPO', file='newfile.txt'}, {disk=1, par=2, file='/tmp/newfile.txt'})
#ogCopyFile ({disk=1, par=2, file='/tmp/newfile.txt'}, {container='REPO', file='newfile.txt'})
def ogCopyFile (src, dst):
for elem in src, dst:
if elem == src: which = 'source'
else: which = 'target'
if 'file' not in elem:
raise TypeError ('missing required argument in {which} dict:: "file"')
if 'container' in elem:
if 'disk' not in elem and 'par' not in elem:
## we were given container=
path = ogGetPath (src=elem['container'], file=elem['file'])
dev_err = f'{elem["container"]} {elem["file"]}'
print (f'ogGetPath {which} (src=({elem["container"]}), file=({elem["file"]})) = path ({path})')
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if 'disk' in elem and 'par' in elem:
## we were given disk= par=
path = ogGetPath (src=f'{elem["disk"]} {elem["par"]}', file=elem['file'])
dev_err = f'{elem["disk"]} {elem["par"]} {elem["file"]}'
print (f'ogGetPath {which} (src=({elem["disk"]} {elem["par"]}), file=({elem["file"]})) = path ({path})')
elif 'disk' not in elem and 'par' not in elem:
## we were given nothing
path = ogGetPath (file=elem['file'])
dev_err = elem['file']
print (f'ogGetPath {which} (file=({elem["file"]})) = path ({path})')
else:
raise TypeError ('if one of "disk" and "par" are specified, then both must be')
if elem == src:
SOURCE = path
src_dev_err = dev_err
else:
TARGET = path
dst_dev_err = dev_err
# Comprobar fichero origen y directorio destino.
if not SOURCE:
ogRaiseError(OG_ERR_NOTFOUND, *args[:-1])
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {src_dev_err} not found')
return
if not TARGET:
ogRaiseError(OG_ERR_NOTFOUND, *args)
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dst_dev_err} not found')
return
print (f'nati: ogCopyFile: SOURCE ({SOURCE}) TARGET ({TARGET})')
# Copiar fichero (para evitar problemas de comunicaciones las copias se hacen con rsync en vez de cp).
result = subprocess.run(["rsync", "--progress", "--inplace", "-avh", SOURCE, TARGET])
print (f'nati: ogCopyFile: rsync --progress --inplace -avh ({SOURCE}) ({TARGET})')
result = subprocess.run(["rsync", "--progress", "--inplace", "-avh", SOURCE, TARGET], capture_output=True, text=True)
return result.returncode
def ogDeleteFile(*args):
# Variables locales.
FILE = None
if "help" in args:
ogHelp("$FUNCNAME", "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_file", "$FUNCNAME 1 2 /tmp/newfile.txt")
return
# Comprobar que existe el fichero y borrarlo.
FILE = ogGetPath(*args)
if not FILE:
ogRaiseError(OG_ERR_NOTFOUND, *args)
return
try:
os.remove(FILE)
except OSError as e:
ogRaiseError(OG_ERR_NOTFOUND, *args)
return
def ogDeleteTree(*args):
# Variables locales.
DIR = None
if "help" in args:
ogHelp("$FUNCNAME", "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_dir", "$FUNCNAME 1 2 /tmp/newdir")
return
#/**
# ogDeleteFile [ str_repo | int_ndisk int_npartition ] path_filepath
#@brief Metafunción que borra un fichero de un dispositivo.
#@see ogGetPath
#@version 0.9 - Pruebas con OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2009-09-29
#*/ ##
#ogDeleteFile ([ str_repo | int_ndisk int_npartition ] path_file)
#ogDeleteFile (container='REPO', file='/tmp/newfile.txt')
#ogDeleteFile (disk=1, par=2, file='/tmp/newfile.txt')
def ogDeleteFile (disk=None, par=None, container=None, file=None):
if file is None:
raise TypeError ('missing required argument: "file"')
# Comprobar que existe el directorio y borrarlo con su contenido.
DIR = ogGetPath(*args)
if not DIR:
ogRaiseError(OG_ERR_NOTFOUND, *args)
return
try:
shutil.rmtree(DIR)
except OSError as e:
ogRaiseError(OG_ERR_NOTFOUND, *args)
return
def ogGetPath(*args):
# Variables locales.
MNTDIR = None
FILE = None
PREVFILE = None
FILEPATH = None
CURRENTDIR = None
# Si se solicita, mostrar ayuda.
if "help" in args:
ogHelp("$FUNCNAME", "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_filepath", "$FUNCNAME \"/mnt/sda1/windows/system32\" ==> /mnt/sda1/WINDOWS/System32", "$FUNCNAME REPO /etc/fstab ==> /opt/opengnsys/images/etc/fstab", "$FUNCNAME 1 1 \"/windows/system32\" ==> /mnt/sda1/WINDOWS/System32")
return
# Procesar camino según el número de parámetros.
if len(args) == 1:
FILE = args[0]
elif len(args) == 2:
if args[0].upper() == "REPO":
FILE = os.path.join(OGIMG, args[1])
elif args[0].upper() == "CACHE":
MNTDIR = ogMountCache()
if not MNTDIR:
return
FILE = os.path.join(MNTDIR, OGIMG, args[1])
elif args[0].upper() == "CDROM":
MNTDIR = ogMountCdrom()
if not MNTDIR:
return
FILE = os.path.join(MNTDIR, args[1])
if container is not None:
if disk is None and par is None:
## we were given container=
src = container
else:
ogRaiseError(OG_ERR_FORMAT)
return
elif len(args) == 3:
MNTDIR = ogMount(args[0], args[1])
if not MNTDIR:
return
FILE = os.path.join(MNTDIR, args[2])
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
ogRaiseError(OG_ERR_FORMAT)
if disk is not None and par is not None:
## we were given disk= par=
src = f'{disk} {par}'
else:
## we were given nothing
raise TypeError ('either "container" or both "disk" and "par" must be specified')
f = ogGetPath (src=src, file=file)
if not f:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{src} {file}')
return
# Eliminar caracteres \c / duplicados y finales.
FILE = os.path.normpath(FILE)
try:
os.remove (f)
except OSError as e:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, str (e))
return
# Comprobar si existe el fichero para reducir tiempos.
if os.path.exists(FILE):
FILEPATH = FILE
#/**
# ogDeleteTree [ str_repo | int_ndisk int_npartition ] path_dirpath
#@brief Metafunción que borra todo un subárbol de directorios de un dispositivo.
#@see ogGetPath
#*/ ##
#ogDeleteTree (container='REPO', file='/tmp/newdir')
#ogDeleteTree (disk=1, par=2, file='/tmp/newdir')
def ogDeleteTree (disk=None, par=None, container=None, file=None):
if file is None:
raise TypeError ('missing required argument: "file"')
if container is not None:
if disk is None and par is None:
## we were given container=
src = container
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if disk is not None and par is not None:
## we were given disk= par=
src = f'{disk} {par}'
else:
## we were given nothing
raise TypeError ('either "container" or both "disk" and "par" must be specified')
f = ogGetPath (src=src, file=file)
if not f:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{src} {file}')
return
try:
shutil.rmtree (f)
except OSError as e:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, e)
return
#/**
# ogGetPath [ str_repo | int_ndisk int_npartition ] path_filepath
#@brief Inicia el proceso de arranque de un sistema de archivos.
#@param path_filepath camino del fichero (independiente de mayúsculas)
#@param str_repo repositorio de ficheros
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return path_file - camino completo real del fichero.
#@note repo = { REPO, CACHE, CDROM }
#@note Requisitos: \c grep \c sed
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero o dispositivo no encontrado.
#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar.
#@warning En caso de error, sólo devuelve el código y no da mensajes.
#@todo Terminar de definir parámetros para acceso a repositorios.
#*/ ##
#ogGetPath (file='/mnt/sda1/windows/system32') ==> '/mnt/sda1/WINDOWS/System32'
#ogGetPath (src='REPO', file='/etc/fstab') ==> '/opt/opengnsys/images/etc/fstab'
#ogGetPath (src='1 1', file='/windows/system32') ==> '/mnt/sda1/WINDOWS/System32'
def ogGetPath (src=None, file=None):
if file is None:
raise TypeError ('missing required argument: "file"')
f = file
if src is not None:
if 'REPO' == src:
f = os.path.join (ogGlobals.OGIMG, file.strip('/'))
elif 'CACHE' == src:
mntdir = CacheLib.ogMountCache()
if not mntdir: return None
f = os.path.join (mntdir, ogGlobals.OGIMG.strip('/'), file.strip('/'))
elif 'CDROM' == src:
mntdir = FileSystemLib.ogMountCdrom()
if not mntdir: return None
f = os.path.join (mntdir, file.strip('/'))
else:
try:
disk, part = src.split()
except ValueError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '')
return
mntdir = FileSystemLib.ogMount (disk, part)
if not mntdir: return None
f = os.path.join (mntdir, file.strip('/'))
f = os.path.normpath (f)
if os.path.exists (f):
filepath = f
#print (f'f ({f}) existe, filepath=f ({filepath})')
else:
# Buscar el nombre correcto en cada subdirectorio del camino.
FILEPATH = "/"
while FILE != PREVFILE:
FILEPATH = os.path.join(FILEPATH.rstrip("/"), FILE.split("/")[0])
PREVFILE = FILE
FILE = "/".join(FILE.split("/")[1:])
prevfile = ''
filepath = '/'
#print (f'f ({f}) prevfile ({prevfile})')
while f != prevfile:
#print ('\nno son iguales, nueva iteracion...')
f_first_component = f.split ('/')[0] ## take 1st component
ls_path = os.path.join (filepath, f_first_component) ## "ls" makes reference to the original bash version
#print (f'f_first_component ({f_first_component}) ls_path ({ls_path})')
if FILEPATH:
return FILEPATH
else:
return None
def ogGetParentPath(*args):
# Variables locales.
PARENT = None
if "help" in args:
ogHelp("$FUNCNAME", "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_filepath", "$FUNCNAME \"/mnt/sda1/windows/system32\" ==> /mnt/sda1/WINDOWS", "$FUNCNAME REPO /etc/fstab ==> /opt/opengnsys/images/etc", "$FUNCNAME 1 1 \"/windows/system32\" ==> /mnt/sda1/WINDOWS")
## build filepath to return
if os.path.exists (ls_path):
filepath = ls_path
#print (f'ls_path existe, filepath ({filepath})')
else:
filepath = subprocess.run (['find', filepath, '-maxdepth', '1', '-iname', f_first_component, '-print'], capture_output=True, text=True).stdout.strip()
#print (f'ls_path no existe, filepath ({filepath})')
prevfile = f
if '/' in f:
f = '/'.join (f.split('/')[1:]) ## remove 1st component
#print (f'f ({f}) prevfile ({prevfile})')
return filepath
#/**
# ogGetParentPath [ str_repo | int_ndisk int_npartition ] path_filepath
#@brief Metafunción que devuelve el camino del directorio padre.
#@see ogGetPath
#*/ ##
#ogGetParentPath ([ str_repo | int_ndisk int_npartition ] path_filepath
#ogGetParentPath ( file='/mnt/sda1/windows/system32') ==> '/mnt/sda1/WINDOWS'
#ogGetParentPath (src='REPO', file='/etc/fstab') ==> '/opt/opengnsys/images/etc'
#ogGetParentPath (src='1 1', file='/windows/system32') ==> '/mnt/sda1/WINDOWS'
def ogGetParentPath (src=None, file=None):
if file is None:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '')
return
# Procesar camino según el número de parámetros.
if len(args) == 1:
PARENT = os.path.dirname(args[0])
elif len(args) == 2:
PARENT = f"{args[0]} {os.path.dirname(f'/{args[1]}')}"
elif len(args) == 3:
PARENT = f"{args[0]} {args[1]} {os.path.dirname(f'/{args[2]}')}"
if src is None:
return ogGetPath (file=os.path.dirname (file))
else:
ogRaiseError(OG_ERR_FORMAT)
return
return ogGetPath(PARENT)
return ogGetPath (src=src, file=os.path.dirname('/'+file))
#/**
# ogIsNewerFile [ str_repo | int_ndisk int_npart ] path_source [ str_repo | int_ndisk int_npart ] path_target
#@brief Metafunción que indica se un fichero es más nuevo que otro.
#@see ogGetPath
#@return Código de salida: 0 - nuevo, 1 - antiguo o error
#@warning Deben existir tanto el fichero origen como el destino.
#*/ ##
def ogIsNewerFile(*args):
# Variables locales.
ARGS = args
if "help" in args:
ogHelp("$FUNCNAME", "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_source [ str_repo | int_ndisk int_npartition ] path_target", "if $FUNCNAME REPO ubuntu.img CACHE ubuntu.img; then ... fi")
SystemLib.ogHelp("$FUNCNAME", "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_source [ str_repo | int_ndisk int_npartition ] path_target", "if $FUNCNAME REPO ubuntu.img CACHE ubuntu.img; then ... fi")
return
ARGS = args
@ -251,43 +428,90 @@ def ogIsNewerFile(*args):
# Comprobar que existen los ficheros origen y destino.
if not SOURCE:
ogRaiseError(OG_ERR_NOTFOUND, *args[:-1])
SystemLib.ogRaiseError(
"session",
ogGlobals.OG_ERR_NOTFOUND,
f"Not found: {args[:-1]}"
)
return
if not TARGET:
ogRaiseError(OG_ERR_NOTFOUND, *args)
SystemLib.ogRaiseError(
"session",
ogGlobals.OG_ERR_NOTFOUND,
f"Not found: {args[-1]}"
)
return
# Devolver si el primer fichero se ha modificado después que el segundo.
return os.path.getmtime(SOURCE) > os.path.getmtime(TARGET)
#/**
# ogMakeChecksumFile [ str_repo | int_ndisk int_npart ] path_filepath
#@brief Metafunción que guarda el valor de comprobación de un fichero.
#@see ogCalculateChecksum
#@warning Genera un fichero con extensión ".sum".
#*/ ##
def ogMakeChecksumFile(*args):
# Variables locales.
FILE = None
if "help" in args:
ogHelp("$FUNCNAME", "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_filepath", "$FUNCNAME REPO ubuntu.img")
SystemLib.ogHelp("$FUNCNAME", "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_filepath", "$FUNCNAME REPO ubuntu.img")
return
# Comprobar que existe el fichero y guardar su checksum.
FILE = ogGetPath(*args)
if not FILE:
ogRaiseError(OG_ERR_NOTFOUND, *args)
SystemLib.ogRaiseError(
"session",
ogGlobals.OG_ERR_NOTFOUND,
f"Not found: {args}"
)
return
checksum = ogCalculateChecksum(FILE)
with open(f"{FILE}.sum", "w") as f:
f.write(checksum)
def ogMakeDir(*args):
# Variables locales.
PARENT = None
DIR = None
if "help" in args:
ogHelp("$FUNCNAME", "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_dir", "$FUNCNAME 1 2 /tmp/newdir")
return
PARENT = ogGetParentPath(*args)
if not PARENT:
ogRaiseError(OG_ERR_NOTFOUND, *args)
return
#/**
# ogMakeDir [ str_repo | int_ndisk int_npartition ] path_dirpath
#@brief Metafunción que crea un subdirectorio vacío en un dispositivo.
#@see ogGetParentPath
#*/ ##
#ogMakeDir (container='REPO', file='/tmp/newdir')
#ogMakeDir (disk='1', par='2', file='/tmp/newdir')
def ogMakeDir (container=None, disk=None, par=None, file=None):
if file is None:
raise TypeError ('missing required argument: "file"')
DIR = os.path.basename(args[-1])
os.makedirs(os.path.join(PARENT, DIR), exist_ok=True)
if container is not None:
if disk is None and par is None:
## we were given container=
parent = ogGetParentPath (src=container, file=file)
dev_err = f'{container} {file}'
print (f'ogGetParentPath (src=({container}), file=({file})) = parent ({parent})')
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if disk is not None and par is not None:
## we were given disk= par=
parent = ogGetParentPath (src=f'{disk} {par}', file=file)
dev_err = f'{disk} {par} {file}'
print (f'ogGetParentPath (src=({disk} {par}), file=({file})) = parent ({parent})')
elif disk is None and par is None:
## we were given nothing
parent = ogGetParentPath (file=file)
dev_err = file
print (f'ogGetParentPath (file=({file})) = parent ({parent})')
else:
raise TypeError ('if one of "disk" and "par" are specified, then both must be')
print (f'nati: ogMakeDir: parent ({parent})')
if not parent:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dev_err} not found')
return None
dst = os.path.basename (file)
print (f'nati: ogMakeDir: dst ({dst})')
os.makedirs (os.path.join (parent, dst), exist_ok=True)
return True

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,836 @@
#!/usr/bin/python3
import shutil
import subprocess
import os
import os.path
import re
from pathlib import Path
import DiskLib
import FileSystemLib
import SystemLib
import ogGlobals
import FileLib
import CacheLib
import NetLib
## ProtocolLib.ogUcastSyntax() calls ogCreateImageSyntax()
## in ogCreateImageSyntax(), param2 may contain a pipe or may be empty
## if param2 is empty, then ogUcastSyntax():
## - does a .split()
## - accesses the third element of the resulting array (ie. does "parts[2]")
## - promptly gets an IndexError exception
##
## param2 in ogCreateImageSyntax() only contains a pipe if 'mbuffer' is installed
## therefore, a hard dependency on mbuffer is created
##
## raise an Exception at import time if mbuffer is not present
if not shutil.which ('mbuffer'):
raise FileNotFoundError ('"mbuffer" utility must be present')
#/**
#@file ImageLib.py
#@brief Librería o clase Image
#@class Image
#@brief Funciones para creación, restauración y clonación de imágenes de sistemas.
#@warning License: GNU GPLv3+
#*/
#/**
# ogCreateImageSyntax path_device path_filename [str_tool] [str_compressionlevel]
#@brief Genera una cadena de texto con la instrucción para crear un fichero imagen
#@param path_device dispositivo Linux del sistema de archivos
#@param path_fileneme path absoluto del fichero imagen
#@param [opcional] str_tool herrmaienta de clonacion [partimage, partclone, ntfsclone]
#@param [opcional] str_compressionlevel nivel de compresion. [0 -none-, 1-lzop-, 2-gzip]
#@return str_command - cadena con el comando que se debe ejecutar.
#@warning Salida nula si se producen errores.
#@TODO introducir las herramientas fsarchiver, dd
#*/ ##
#ogCreateImageSyntax /dev/sda1 /opt/opengnsys/images/prueba.img partclone lzop
#ogCreateImageSyntax /dev/sda1 /opt/opengnsys/images/prueba.img
def ogCreateImageSyntax (dev, imgfile, tool='partclone', level='gzip'):
if 'ntfsclone' == tool:
param1 = f'ntfsclone --force --save-image -O - {dev}'
elif 'partimage' == tool or 'default' == tool:
param1 = f'partimage -M -f3 -o -d -B gui=no -c -z0 --volume=0 save {dev} stdout'
elif 'partclone' == tool:
disk, part = DiskLib.ogDevToDisk (dev).split()
fs = FileSystemLib.ogGetFsType (disk, part)
param1 = {
'EXT2': 'partclone.extfs',
'EXT3': 'partclone.extfs',
'EXT4': 'partclone.extfs',
'BTRFS': 'partclone.btrfs',
'REISERFS': 'partclone.reiserfs',
'REISER4': 'partclone.reiser4',
'JFS': 'partclone.jfs',
'XFS': 'partclone.xfs',
'F2FS': 'partclone.f2fs',
'NILFS2': 'partclone.nilfs2',
'NTFS': 'partclone.ntfs',
'EXFAT': 'partclone.exfat',
'FAT16': 'partclone.fat',
'FAT32': 'partclone.fat',
'HFS': 'partclone.hfsp',
'HFSPLUS': 'partclone.hfsp',
'UFS': 'partclone.ufs',
'VMFS': 'partclone.vmfs',
}.get (fs, 'partclone.imager')
dash_c = '-c'
if not shutil.which (param1):
param1 = 'partclone.dd'
# Algunas versiones de partclone.dd no tienen opción "-c".
out = subprocess.run (['partclone.dd', '--help'], capture_output=True, text=True).stdout
if ' -c' not in out: dash_c = ''
param1=f'{param1} -d0 -F {dash_c} -s {dev}'
else:
raise Exception (f'unknown tool "{tool}"')
param2 = '| mbuffer -q -m 40M ' if shutil.which ('mbuffer') else ' '
param3 = {
0: ' > ',
'none': ' > ',
1: ' | lzop > ',
'lzop': ' | lzop > ',
2: ' | gzip -c > ',
'gzip': ' | gzip -c > ',
3: ' | bzip -c > ',
'bzip': ' | bzip -c > ',
}.get (level, ' > ')
#print (f'param1 ({param1}) param2 ({param2}) param3 ({param3}) imgfile ({imgfile})')
if param1: return f'{param1} {param2} {param3} {imgfile}'
#/**
# ogRestoreImageSyntax path_filename path_device [str_tools] [str_compressionlevel]
#@brief Genera una cadena de texto con la instrucción para crear un fichero imagen
#@param path_device dispositivo Linux del sistema de archivos
#@param path_fileneme path absoluto del fichero imagen
#@param [opcional] str_tools herrmaienta de clonacion [partimage, partclone, ntfsclone]
#@param [opcional] str_compressionlevel nivel de compresion. [0 -none-, 1-lzop-, 2-gzip]
#@return cadena con el comando que se debe ejecutar.
#@exception OG_ERR_FORMAT formato incorrecto.
#@warning En pruebas iniciales
#@TODO introducir las herramientas fsarchiver, dd
#@TODO introducir el nivel de compresion gzip
#*/ ##
#ogRestoreImageSyntax /opt/opengnsys/images/prueba.img /dev/sda1 [partclone] [lzop]
def ogRestoreImageSyntax (imgfile, part, tool=None, level=None):
if not os.path.exists (imgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile)
## original bash code is broken: 'return' is never called
#return
if tool is None or level is None:
infoimg = ogGetImageInfo (imgfile)
if not infoimg:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'no image {imgfile}')
## original bash code is broken: 'return' is never called
#return
try:
tool, level = infoimg.split (':')[0:2]
except:
tool, level = '', ''
return ogRestoreImageSyntax (imgfile, part, tool, level)
tool = tool.lower()
level = level.lower()
compressor = {
0: ' ',
'none': ' ',
1: ' lzop -dc ',
'lzop': ' lzop -dc ',
2: ' gzip -dc ',
'gzip': ' gzip -dc ',
3: ' bzip -dc ',
'bzip': ' bzip -dc ',
}.get (level, '')
#print (f'tool ({tool}) level ({level}) compressor ({compressor})')
if compressor == '':
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'Compressor no valid {level}')
## original bash code is broken: 'return' is never called
#return
mbuffer = '| mbuffer -q -m 40M ' if shutil.which ('mbuffer') else ' '
#print (f'mbuffer ({mbuffer})')
if 'ntfsclone' == tool:
tool = f'| ntfsclone --restore-image --overwrite {part} -'
elif 'partimage' == tool:
tool = f'| partimage -f3 -B gui=no restore {part} stdin'
elif 'partclone' in tool:
# -C para que no compruebe tamaños
tool = f'| partclone.restore -d0 -C -I -o {part}'
elif 'dd' == tool:
tool = f'| pv | dd conv=sync,noerror bs=1M of={part}'
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'Tools imaging no valid {tool}')
## original bash code is broken: 'return' is never called
#return
#print (f'tool ({tool})')
return f'{compressor} {imgfile} {mbuffer} {tool}'.strip()
#/**
# ogCreateDiskImage int_ndisk str_repo path_image [str_tools] [str_compressionlevel]
#@brief Crea una imagen (copia de seguridad) de un disco completo.
#@param int_ndisk nº de orden del disco
#@param str_repo repositorio de imágenes (remoto o caché local)
#@param path_image camino de la imagen (sin extensión)
#@return (nada, por determinar)
#@note repo = { REPO, CACHE }
#@note Esta primera versión crea imágenes con dd comprimidas con gzip.
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@exception OG_ERR_LOCKED particion bloqueada por otra operación.
#@exception OG_ERR_IMAGE error al crear la imagen del sistema.
#@warning En pruebas iniciales
#@todo Gestión de bloqueos de disco
#@todo Comprobar si debe desmontarse la caché local
#@todo Comprobar que no se crea la imagen en el propio disco
#*/ ##
#/**
# ogCreateImage int_ndisk int_npartition str_repo path_image [str_tools] [str_compressionlevel]
#@brief Crea una imagen a partir de una partición.
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@param str_repo repositorio de imágenes (remoto o caché local)
#@param path_image camino de la imagen (sin extensión)
#@param [opcional] str_tools herrmaienta de clonacion [partimage, partclone, ntfsclone]
#@param [opcional] str_compressionlevel nivel de compresion. [0 -none-, 1-lzop-, 2-gzip]
#@return (nada, por determinar)
#@note repo = { REPO, CACHE }
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@exception OG_ERR_PARTITION partición no accesible o no soportada.
#@exception OG_ERR_LOCKED particion bloqueada por otra operación.
#@exception OG_ERR_IMAGE error al crear la imagen del sistema.
#@todo Comprobaciones, control de errores, definir parámetros, etc.
#*/ ##
def ogCreateImage (disk, par, container, imgfile, tool='partclone', level='gzip'):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return None
if FileSystemLib.ogIsLocked (disk, par):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{ogGlobals.lang.MSG_ERR_LOCKED} {disk}, {par}')
return None
imgtype = 'img' # Extensión genérica de imágenes.
imgdir = FileLib.ogGetParentPath (src=container, file=imgfile)
if not imgdir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{container} {imgfile}')
return None
bn = os.path.basename (imgfile)
IMGFILE = f'{imgdir}/{bn}.{imgtype}'
if ogIsImageLocked (IMGFILE):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{ogGlobals.lang.MSG_IMAGE} {container}, {imgfile}')
return None
# Generar la instruccion a ejecutar antes de aplicar los bloqueos.
program = ogCreateImageSyntax (PART, IMGFILE, tool=tool, level=level)
# Desmontar partición, bloquear partición e imagen.
FileSystemLib.ogUnmount (disk, par)
if not FileSystemLib.ogLock (disk, par):
return None
if not ogLockImage (container, f'{imgfile}.{imgtype}'):
return None
# Crear Imagen.
#trap
p = subprocess.run (program, shell=True, check=True)
errcode = p.returncode
if 0 == errcode:
i = ogGetImageInfo (IMGFILE)
h = NetLib.ogGetHostname()
with open (f'{IMGFILE}.info', 'w') as fd:
fd.write (f'{i}:{h}\n')
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f'{disk} {par} {IMGFILE}')
if os.path.exists (IMGFILE):
os.unlink (IMGFILE)
FileSystemLib.ogUnlock (disk, par)
ogUnlockImage (container, f'{imgfile}.{imgtype}')
return not errcode ## reverse to indicate success
#/**
# ogCreateMbrImage int_ndisk str_repo path_image
#@brief Crea una imagen a partir del sector de arranque de un disco.
#@param int_ndisk nº de orden del disco
#@param str_repo repositorio de imágenes (remoto o caché local)
#@param path_image camino de la imagen (sin extensión)
#@return (nada, por determinar)
#@note repo = { REPO, CACHE }
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@exception OG_ERR_IMAGE error al crear la imagen del sistema.
#*/ ##
#/**
# ogCreateBootLoaderImage int_ndisk str_repo path_image
#@brief Crea una imagen del boot loader a partir del sector de arranque de un disco.
#@param int_ndisk nº de orden del disco
#@param str_repo repositorio de imágenes (remoto o caché local)
#@param path_image camino de la imagen (sin extensión)
#@return (nada, por determinar)
#@note repo = { REPO, CACHE }
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@exception OG_ERR_IMAGE error al crear la imagen del sistema.
#*/ ##
#/**
# ogGetSizeParameters int_num_disk int_num_part str_repo [monolit|sync|diff]
#@brief Devuelve el tamaño de los datos de un sistema de ficheros, el espacio necesario para la imagen y si cabe en el repositorio elegido.
#@param int_disk numero de disco
#@param int_part numero de particion
#@param str_repo repositorio de imágenes { REPO, CACHE }
#@param str_imageName Nombre de la imagen
#@param str_imageType Tipo de imagen: monolit (por defecto), sync o diff. (parametro opcional)
#@return SIZEDATA SIZEREQUIRED SIZEFREE ISENOUGHSPACE
#@note si str_imageType= diff necesario /tmp/ogimg.info, que es creado por ogCreateInfoImage.
#@note para el tamaño de la imagen no sigue enlaces simbólicos.
#@exception OG_ERR_FORMAT formato incorrecto.
#*/ ##
#SIZEDATA, SIZEREQUIRED, SIZEFREE, ISENOUGHSPACE = ogGetSizeParameters (1, 1, 'REPO', 'myimg')
def ogGetSizeParameters (disk, par, repo, imgname, imgtype=None):
repo = repo.upper()
## imgtype se soporta como parametro pero se ignora
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par}')
return None
#if [ "$IMGTYPE" == "_DIFF_" ]; then cosas
#else:
sizedata = None
df_out = subprocess.run (['df', '-k'], capture_output=True, text=True).stdout
for l in df_out.splitlines():
if (re.search (f'{mntdir}$', l)):
sizedata = int (l.split()[2])
break
if sizedata is None:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, 'sizedata is None')
return None
#if [ "$IMGTYPE" == "_SYNC_" -o "$IMGTYPE" == "_DIFF_" ]; then cosas
#else:
factorgzip=55/100
factorlzop=65/100
sizerequired = sizedata * factorlzop
#Comprobar espacio libre en el contenedor.
sizefree = None
if 'CACHE' == repo:
CACHEPART = CacheLib.ogFindCache()
if not CACHEPART:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTCACHE, '')
return None
cache_disk, cache_par = CACHEPART.split()
sizefree = FileSystemLib.ogGetFreeSize (cache_disk, cache_par)
if 'REPO' == repo:
df_out = subprocess.run (['df', '-k'], capture_output=True, text=True).stdout
for l in df_out.splitlines():
if (re.search (f'{ogGlobals.OGIMG}', l)):
sizefree = int (l.split()[3])
break
if sizefree is None:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, 'sizefree is None')
return None
# Comprobamos si existe una imagen con el mismo nombre en $REPO
# En sincronizadas restamos tamaño de la imagen y en monoloticas de la .ant
#case "${IMGTYPE}" in blah blah
#*)
imgext = 'img.ant'
imgdir = FileLib.ogGetParentPath (src=repo, file=f'/{imgname}')
bn = os.path.basename (f'/{imgname}')
imgfile = FileLib.ogGetPath (file=f'{imgdir}/{bn}.{imgext}')
if not imgfile:
imgsize = 0
else:
ls_out = subprocess.run (['ls', '-s', imgfile], capture_output=True, text=True).stdout
imgsize = int (ls_out.split()[0])
sizefree = sizefree + imgsize
if sizerequired < sizefree:
isenoughspace = True
else:
isenoughspace = False
return sizedata, sizerequired, sizefree, isenoughspace
#/**
# ogIsImageLocked [str_repo] path_image
#@brief Comprueba si una imagen está bloqueada para uso exclusivo.
#@param str_repo repositorio de imágenes (opcional)
#@param path_image camino de la imagen (sin extensión)
#@return Código de salida: 0 - bloqueado, 1 - sin bloquear o error.
#@note repo = { REPO, CACHE }
#@exception OG_ERR_FORMAT formato incorrecto.
#*/ ##
#ogIsImageLocked ('/opt/opengnsys/images/aula1/win7.img')
#ogIsImageLocked ('REPO', '/aula1/win7.img')
def ogIsImageLocked (container=None, imgfile=None):
if container and imgfile:
p = FileLib.ogGetPath (src=container, file=f'{imgfile}.lock')
elif imgfile:
p = FileLib.ogGetPath (file=f'{imgfile}.lock')
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'{container} {imgfile}')
return
return os.path.exists (p)
#/**
# ogLockImage [str_repo] path_image
#@brief Bloquea una imagen para uso exclusivo.
#@param str_repo repositorio de imágenes (opcional)
#@param path_image camino de la imagen (sin extensión)
#@return Nada.
#@note Se genera un fichero con extensión .lock
#@note repo = { REPO, CACHE }
#@exception OG_ERR_FORMAT formato incorrecto.
#*/ ##
def ogLockImage (container=None, imgfile=None):
if not imgfile:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '')
return None
if container:
imgdir = FileLib.ogGetParentPath (src=container, file=imgfile)
else:
imgdir = FileLib.ogGetParentPath (file=imgfile)
try:
bn = os.path.basename (imgfile)
open (f'{imgdir}/{bn}.lock', 'w').close()
return True
except:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTWRITE, f'{container} {imgfile}')
return None
#/**
# ogRestoreDiskImage str_repo path_image int_npartition
#@brief Restaura (recupera) una imagen de un disco completo.
#@param str_repo repositorio de imágenes o caché local
#@param path_image camino de la imagen
#@param int_ndisk nº de orden del disco
#@return (por determinar)
#@warning Primera versión en pruebas
#@todo Gestionar bloqueos de disco
#@todo Comprobar que no se intenta restaurar de la caché sobre el mismo disco
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero de imagen o partición no detectados.
#@exception OG_ERR_LOCKED partición bloqueada por otra operación.
#@exception OG_ERR_IMAGE error al restaurar la imagen del sistema.
#@exception OG_ERR_IMGSIZEPARTITION Tamaño de la particion es menor al tamaño de la imagen.
#*/ ##
#/**
# ogRestoreImage str_repo path_image int_ndisk int_npartition
#@brief Restaura una imagen de sistema de archivos en una partición.
#@param str_repo repositorio de imágenes o caché local
#@param path_image camino de la imagen
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return (por determinar)
#@exception OG_ERR_FORMAT 1 formato incorrecto.
#@exception OG_ERR_NOTFOUND 2 fichero de imagen o partición no detectados.
#@exception OG_ERR_PARTITION 3 # Error en partición de disco.
#@exception OG_ERR_LOCKED 4 partición bloqueada por otra operación.
#@exception OG_ERR_IMAGE 5 error al restaurar la imagen del sistema.
#@exception OG_ERR_IMGSIZEPARTITION 30 Tamaño de la particion es menor al tamaño de la imagen.
#@todo Comprobar incongruencias partición-imagen, control de errores, definir parámetros, caché/repositorio, etc.
#*/ ##
#ogRestoreImage ('REPO', '/aula1/win7', '1', '1')
def ogRestoreImage (repo, imgpath, disk, par):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f' {disk} {par}')
return None
imgtype = 'img'
imgfile = FileLib.ogGetPath (repo, f'{imgpath}.{imgtype}')
if not os.path.exists (imgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f' {disk} {par}')
return None
if not ogGetImageInfo (imgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f' {repo} {imgpath}')
return None
# Error si la imagen no cabe en la particion.
imgsize = ogGetImageSize (repo, imgpath)
if not imgsize:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f' {repo} {imgpath}')
return None
if not FileSystemLib.ogMount (disk, par):
FileSystemLib.ogFormat (disk, par)
partsize = DiskLib.ogGetPartitionSize (disk, par)
if float (imgsize) > float (partsize):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMGSIZEPARTITION, f' {partsize} < {imgsize}')
return None
if ogIsImageLocked (container=None, imgfile=imgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{ogGlobals.lang.MSG_IMAGE} {repo}, {imgpath}.{imgtype}')
return None
if FileSystemLib.ogIsLocked (disk, par):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{ogGlobals.lang.MSG_PARTITION} {disk}, {par}')
return None
program = ogRestoreImageSyntax (imgfile, PART)
if not FileSystemLib.ogUnmount (disk, par):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f' {disk} {par}')
return None
if not FileSystemLib.ogLock (disk, par):
print (f'not FileSystemLib.ogLock()')
return None
rc = None
try:
p = subprocess.run (program, shell=True, capture_output=True, text=True)
rc = p.returncode
if not rc:
SystemLib.ogRaiseError ([], ogGlobalsOG_ERR_IMAGE, f'{imgfile}, {disk}, {par}')
except:
pass
finally:
FileSystemLib.ogUnlock (disk, par)
return rc
#/**
# ogRestoreMbrImage str_repo path_image int_ndisk
#@brief Restaura la imagen del sector de arranque de un disco.
#@param str_repo repositorio de imágenes o caché local
#@param path_image camino de la imagen
#@param int_ndisk nº de orden del disco
#@return (por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero de imagen o partición no detectados.
#@exception OG_ERR_IMAGE error al restaurar la imagen del sistema.
#*/ ##
#/**
# ogRestoreBootLoaderImage str_repo path_image int_ndisk
#@brief Restaura la imagen del boot loader del sector de arranque de un disco.
#@param str_repo repositorio de imágenes o caché local
#@param path_image camino de la imagen
#@param int_ndisk nº de orden del disco
#@return (por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero de imagen o partición no detectados.
#@exception OG_ERR_IMAGE error al restaurar la imagen del sistema.
#*/ ##
#/**
# ogUnlockImage [str_repo] path_image
#@brief Desbloquea una imagen con uso exclusivo.
#@param str_repo repositorio de imágenes (opcional)
#@param path_image camino de la imagen (sin extensión)
#@return Nada.
#@note repo = { REPO, CACHE }
#@note Se elimina el fichero de bloqueo con extensión .lock
#@exception OG_ERR_FORMAT formato incorrecto.
#*/ ##
#ogUnlockImage REPO /cucu.img
def ogUnlockImage (container=None, imgfile=None):
f = f'{imgfile}.lock'
if container:
p = FileLib.ogGetPath (src=container, file=f)
else:
p = FileLib.ogGetPath (file=f)
if os.path.exists (p):
os.unlink (p)
#/**
# ogGetImageInfo filename
#@brief muestra información sobre la imagen monolitica.
#@param 1 filename path absoluto del fichero imagen
#@return cadena compuesta por clonacion:compresor:sistemaarchivos:tamañoKB
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero no encontrado.
#@exception OG_ERR_IMAGE "Image format is not valid $IMGFILE"
#@warning En pruebas iniciales
#@TODO Definir sintaxis de salida (herramienta y compresor en minuscula)
#@TODO Arreglar loop para ntfsclone
#@TODO insertar parametros entrada tipo OG
#*/ ##
#ogGetImageInfo /opt/opengnsys/images/prueba.img ==> PARTCLONE:LZOP:NTFS:5642158"
def ogGetImageInfo (imgfile):
if not os.path.exists (imgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile)
return
imgdetect = False
filehead = f'/tmp/{os.path.basename (imgfile)}.infohead'
compressor = subprocess.run (['file', imgfile], capture_output=True, text=True).stdout.split()[1]
if compressor not in ['gzip', 'lzop']:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f'Image format is not valid {imgfile}')
return
## original bash idiom is: $($COMPRESSOR -dc $IMGFILE 2>/dev/null | head -n 40 > $FILEHEAD) || ogRaiseError
## the purpose of which I can't fully comprehend
#print (f'shelling out "{compressor} -dc {imgfile} |head -n 40 > {filehead}"')
if subprocess.run (f'{compressor} -dc {imgfile} |head -n 40 > {filehead}', shell=True).returncode:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f'Image format is not valid {imgfile}')
return
tools = fs = size = None
if False == imgdetect:
lc_all = os.getenv ('LC_ALL')
os.environ['LC_ALL'] = 'C'
partclone_info = subprocess.run (['partclone.info', filehead], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True).stdout
#partclone_info = subprocess.run (['cat', '/tmp/foo-partclone'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True).stdout
## sacado de un email de alberto garcía uma.es
#Partclone v0.3.13 http://partclone.org
#Unknown mode
#File system: NTFS
#Device size: 29.2 GB = 7138019 Blocks
#Space in use: 26.6 GB = 6485355 Blocks
#Free Space: 2.7 GB = 652664 Blocks
#Block size: 4096 Byte
#
#image format: 0002
#created on a: 64 bits platform
#with partclone: v0.3.13
#bitmap mode: BIT
#checksum algo: CRC32
#checksum size: 4
#blocks/checksum: 256
if lc_all is not None:
os.environ["LC_ALL"] = lc_all
else:
del os.environ["LC_ALL"]
if 'size' in partclone_info:
tools = 'PARTCLONE'
m = re.search (r'File system *: *(\S+)', partclone_info)
fs = m.group(1) if m else ''
sizefactor = 1000000 if 'GB' in partclone_info else 1024
m = re.search (r'Device size *: *(\S+)', partclone_info)
size = float (m.group(1)) if m else 0
size = int (size * sizefactor)
## why is this?
#if fs in ['HFS', 'HFSPLUS', 'FAT32']:
# #FSPLUS=$(echo $PARTCLONEINFO | awk '{gsub(/\: /,"\n"); print toupper($9);}')
# fsplus = 'PLUS'
# if fsplus: # fs += fsplus ## 'HFS' -> 'HFSPLUS'
imgdetect = True
if False == imgdetect and not os.path.exists ('/dev/loop2'):
filehead_contents = Path (filehead).read_bytes()
if b'ntfsclone-image' in filehead_contents:
#print (f'shelling out "cat {filenead} | ntfsclone --restore --overwrite /dev/loop2 - 2>&1"')
ntfscloneinfo = subprocess.run (f'cat {filenead} | ntfsclone --restore --overwrite /dev/loop2 - 2>&1', shell=True, capture_output=True, text=True).stdout
#ntfscloneinfo = subprocess.run (['cat', '/tmp/foo-ntfsclone'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True).stdout
## sacado de claude 3 haiku
#ntfsclone v2023.4.0 (libntfs-3g)
#NTFS volume version: 3.1
#Cluster size: 4096 bytes
#Image volume size: 104857600 bytes (105 MB)
#Space in use: 52428800 bytes (52 MB)
#Reading and restoring NTFS...
#100.00 percent completed
#Syncing ...
#Successfully cloned image to device '/dev/loop2'.
else:
ntfscloneinfo = ''
if 'ntfsclone' in ntfscloneinfo:
tools = 'NTFSCLONE'
m = re.search (r'Image volume size *: *(\S+)', ntfscloneinfo)
size = float (m.group(1))/1000 if m else 0
fs = 'NTFS'
imgdetect = True
if False == imgdetect:
partimageinfo = subprocess.run (['partimage', '-B', 'gui=no', 'imginfo', filehead], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True).stdout
#partimageinfo = subprocess.run (['cat', '/tmp/foo-partimage'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True).stdout
## sacado de un email de alberto garcía uma.es
#Volume number:.........0
#Volume size:...........1,27 MiB
#Compression level: ....0 -> ninguno
#Identificator:.........12442509728668372730=ACACACACCB9ECEFA
#Filesystem:............ntfs
#Description:...........Sin descripcion
#Original device:......./dev/nvme0n1p2
#Original filepath:.... stdout
#Flags:.................0: Bandera sin activar
#Creation date:.........Mon Nov 11 21:00:22 2024
#Partition size:........476,84 GiB
#Hostname:..............ING-LTR-083
#Compatible Version:....0.6.1
#Encryption algorithm:..0 -> ninguno
#MBR saved count:.......0
partimageinfo = re.sub (r':\s*\.+', ' : ', partimageinfo)
if 'Partition' in partimageinfo:
tools = 'PARTIMAGE'
m = re.search (r'Filesystem *: *(\S+)', partimageinfo)
fs = m.group(1).upper() if m else ''
m = re.search (r'Partition size *: *(\S+)', partimageinfo)
size = m.group(1) if m else ''
size = re.sub (r' [MGT]i?B$', '', size)
size = float (size.replace (',', '.'))
size = int (size*1024*1024)
imgdetect = True
if 'boot sector' in subprocess.run (['file', filehead], capture_output=True, text=True).stdout:
tools = 'partclone.dd'
fs = ''
size = 0
imgdetect = True
if not tools or not compressor or False == imgdetect:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f'Image format is not valid {imgfile}')
return
compressor = compressor.upper()
return ':'.join ([tools, compressor, fs, str (size)])
#/**
# ogGetImageProgram str_REPO str_imagen
#@brief muestra información sobre la imagen monolitica.
#@see ogGetImageInfo
#@param 1 REPO o CACHE contenedor de la imagen
#@param 2 filename nombre de la imagen sin extension
#@return nombre del programa usado para generar la imagen
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero no encontrado.
#@note ogGetImageProgram REPO imagenA -> partclone
#*/ ##
#ogGetImageProgram ('REPO', 'prueba') ==> 'PARTCLONE'
def ogGetImageProgram (container, filename):
imgfile = FileLib.ogGetPath (container, f'{filename}.img')
if not os.path.exists (imgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile)
return None
i = ogGetImageInfo (imgfile)
return i.split (':')[0]
#/**
# ogGetImageCompressor str_REPO str_imagen
#@brief muestra información sobre la imagen monolitica.
#@see ogGetImageInfo
#@param 1 REPO o CACHE contenedor de la imagen
#@param 2 filename nombre de la imagen sin extension
#@return tipo de compresión usada al generar la imagen
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero no encontrado.
#@note ogGetImageCompressor REPO imagenA -> lzop
#*/ ##
#ogGetImageCompressor ('REPO', 'prueba') ==> 'LZOP'
def ogGetImageCompressor (container, filename):
imgfile = FileLib.ogGetPath (container, f'{filename}.img')
if not os.path.exists (imgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile)
return None
i = ogGetImageInfo (imgfile)
return i.split (':')[1]
#/**
# ogGetImageType str_REPO str_imagen
#@brief muestra información sobre el sistema de archivos de imagen monolitica.
#@see ogGetImageInfo
#@param 1 REPO o CACHE contenedor de la imagen
#@param 2 filename nombre de la imagen sin extension
#@return tipo de compresión usada al generar la imagen
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero no encontrado.
#@note ogGetImageType REPO imagenA -> NTFS
#*/ ##
#ogGetImageType ('REPO', 'imgprueba') ==> 'NTFS'
#ogGetImageType ('CACHE', 'testimg') ==> 'EXTFS'
def ogGetImageType (repo, imgname):
imgfile = FileLib.ogGetPath (src=repo, file=f'{imgname}.img')
if not os.path.exists (imgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile)
return None
i = ogGetImageInfo (imgfile)
return i.split (':')[2]
#/**
# ogGetImageSize str_REPO str_imagen
#@brief muestra información sobre el tamaño (KB) del sistema de archivos de imagen monolitica.
#@see ogGetImageInfo
#@param 1 REPO o CACHE contenedor de la imagen
#@param 2 filename nombre de la imagen sin extension
#@return tipo de compresión usada al generar la imagen
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero no encontrado.
#@note ogGetImagesize REPO imagenA -> 56432234 > Kb
#*/ ##
#ogGetImageSize ('REPO', 'prueba') ==> '5642158'
def ogGetImageSize (repo, imgname):
imgfile = FileLib.ogGetPath (src=repo, file=f'{imgname}.img')
if not os.path.exists (imgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile)
return None
i = ogGetImageInfo (imgfile)
return i.split (':')[3]
#/**
# ogCreateGptImage int_ndisk str_repo path_image
#@brief Crea una imagen de la tabla de particiones GPT de un disco.
#@param int_ndisk nº de orden del disco
#@param str_repo repositorio de imágenes (remoto o caché local)
#@param path_image camino de la imagen (sin extensión)
#@return (nada, por determinar)
#@note repo = { REPO, CACHE }
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@exception OG_ERR_IMAGE error al crear la imagen del sistema.
#*/ ##
#/**
# ogRestoreGptImage str_repo path_image int_ndisk
#@brief Restaura la imagen de la tabla de particiones GPT de un disco.
#@param str_repo repositorio de imágenes o caché local
#@param path_image camino de la imagen
#@param int_ndisk nº de orden del disco
#@return (por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero de imagen o partición no detectados.
#@exception OG_ERR_IMAGE error al restaurar la imagen del sistema.
#*/ ##

View File

@ -0,0 +1,531 @@
#/**
#@file InventoryLib.py
#@brief Librería o clase Inventory
#@class Inventory
#@brief Funciones para recogida de datos de inventario de hardware y software de los clientes.
#@warning License: GNU GPLv3+
#*/
import platform
import sys
import os
import subprocess
import re
import json
import shutil
import glob
import plistlib
#import bsddb
import ogGlobals
import SystemLib
import FileSystemLib
import RegistryLib
import FileLib
#/**
# ogGetArch
#@brief Devuelve el tipo de arquitectura del cliente.
#@return str_arch - Arquitectura (i386 para 32 bits, x86_64 para 64 bits).
#*/
def ogGetArch():
if os.path.isdir ('/lib64'):
return 'x86_64'
else:
return 'i386'
#/**
# ogGetOsType int_ndisk int_npartition
#@brief Devuelve el tipo del sistema operativo instalado.
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return OSType - Tipo de sistema operativo.
#@see ogGetOsVersion
#*/ ##
def ogGetOsType(disk, partition):
try:
os_version = ogGetOsVersion(disk, partition)
if os_version:
return os_version.split(":", 1)[0]
else:
return None
except Exception as e:
print(f"Error en ogGetOsType: {e}")
return "Unknown"
#/**
# ogGetOsUuid int_ndisk int_nfilesys
#@brief Devuelve el UUID del sistema operativo instalado en un sistema de archivos.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden de la partición
#@return str_uuid - UUID del sistema operativo.
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o partición no corresponden con un dispositiv
#*/ ##
def ogGetOsUuid (disk, par):
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir: return None
# Obtener UUID según el tipo de sistema operativo.
os_type = ogGetOsType (disk, par)
if 'Linux' == os_type:
# Leer el UUID del sistema de ficheros raíz o el fichero de identificador.
uuid = subprocess.run (['findmnt', '-no', 'UUID', mntdir], capture_output=True, text=True).stdout.strip()
if not uuid:
uuid = open (os.path.join (mntdir, 'etc', 'machine-id')).read().strip()
return uuid
elif 'Windows' == os_type:
# Leer identificador en clave de registro.
uuid = RegistryLib.ogGetRegistryValue (mntdir, 'SOFTWARE', r'\Microsoft\Cryptography\MachineGuid')
return uuid
#/**
# ogGetSerialNumber
#@brief Obtiene el nº de serie del cliente.
#*/ ##
def ogGetSerialNumber():
SERIALNO = subprocess.check_output(["dmidecode", "-s", "system-serial-number"]).decode().strip()
SERIALNO = re.sub(r"(not specified|to be filled|invalid entry|default string)", "", SERIALNO, flags=re.IGNORECASE)
SERIALNO = SERIALNO.replace(" ", "")
SERIALNO = SERIALNO[:25] if len(SERIALNO) > 25 else SERIALNO
if SERIALNO: return SERIALNO
return None
#/**
# ogIsEfiActive
#@brief Comprueba si el sistema tiene activo el arranque EFI.
#*/ ##
def ogIsEfiActive():
return os.path.isdir("/sys/firmware/efi")
#/**
# ogListHardwareInfo
#@brief Lista el inventario de hardware de la máquina cliente.
#@return TipoDispositivo:Modelo (por determinar)
#@warning Se ignoran los parámetros de entrada.
#@note TipoDispositivo = { bio, boa, bus, cha, cdr, cpu, dis, fir, mem, mod, mul, net, sto, usb, vga }
#@note Requisitos: dmidecode, lshw, awk
#*/ ##
def ogListHardwareInfo():
ret = ''
SystemLib.ogEcho ([], 'info', ogGlobals.lang.MSG_HARDWAREINVENTORY)
# Ejecutar dmidecode y obtener tipo de chasis
dmi_out = subprocess.run (['dmidecode', '-s', 'chassis-type'], capture_output=True, text=True).stdout
dmi_out = '\n'.join ([ x for x in dmi_out.splitlines() if 'Other' not in x ])
ret += f'cha={dmi_out}\n'
if os.path.exists ('/sys/firmware/efi'):
ret += f'boo=UEFI\n'
else:
ret += f'boo=BIOS\n'
awk_script = r'''
BEGIN {type="mod";}
/product:/ {sub(/ *product: */,""); prod=$0;}
/vendor:/ {sub(/ *vendor: */,""); vend=$0;}
/version:/ {sub(/ *version: */,"v.");vers=$0;}
/size:/ {size=$2;}
/clock:/ {clock=$2;}
/slot:/ {sub(/ *slot: */,""); slot=$0;}
/\*-/ {if (type=="mem"){
if (size!=""){
numbank++;
print type"="vend,prod,size,clock" ("slot")";}
}else{
if (type=="totalmem"){
if (size!=""){
totalmemory="mem="size;}
}else{
if (type!="" && prod!=""){
if (prod=="v."vers)
vers="";
print type"="vend,prod,size,vers;} }
}
type=prod=vend=vers=size=clock=slot="";}
$1~/-core/ {type="boa";}
$1~/-firmware/ {type="bio";}
$1~/-cpu/ {type="cpu";}
$1~/-bank/ {type="mem";}
$1~/-memory/ {type="totalmem";}
$1~/-ide/ {type="ide";}
$1~/-storage/ {type="sto";}
$1~/-disk/ {type="dis";}
$1~/-cdrom/ {type="cdr";}
$1~/-display/ {type="vga";}
$1~/-network/ {type="net";}
$1~/-multimedia/ {type="mul";}
$1~/-usb/ {type="usb";}
$1~/-firewire/ {type="fir";}
$1~/-serial/ {type="bus";}
END {if (type!="" && prod!="")
print type"="vend,prod,size,vers;
if (length(numbank)==0 && length(totalmemory)>=4)
print totalmemory; }
'''
lshw_out = subprocess.run (['lshw'], capture_output=True, text=True).stdout
awk_out = subprocess.run (['awk', awk_script], input=lshw_out, capture_output=True, text=True).stdout
ret += awk_out
return ret
#/**
# ogListSoftware int_ndisk int_npartition
#@brief Lista el inventario de software instalado en un sistema operativo.
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return programa versión ...
#@warning Se ignoran los parámetros de entrada.
#@note Requisitos: ...
#@todo Detectar software en Linux
#*/ ##
def ogListSoftware (disk, par):
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir: return None
ostype = ogGetOsType (disk, par)
if not ostype: return None
apps = []
if 'Linux' == ostype:
# Procesar paquetes dpkg.
pkgdir = f'{mntdir}/var/lib/dpkg'
if os.path.exists (pkgdir):
status_file = os.path.join(pkgdir, "status")
awk_script = '''
/Package:/ {if (pack!="") print pack,vers;
sub(/-dev$/,"",$2);
pack=$2}
/Version:/ {sub(/^.*:/,"",$2); sub(/-.*$/,"",$2);
vers=$2}
/Status:/ {if ($2!="install") pack=vers=""}
END {if (pack!="") print pack,vers}
'''
awk_out = subprocess.run (['awk', awk_script, status_file], capture_output=True, text=True).stdout
apps = awk_out.splitlines()
# Procesar paquetes RPM.
pkgdir = f'{mntdir}/var/lib/rpm'
if os.path.exists (pkgdir):
if shutil.which ('rpm'):
for f in glob.glob (f'{pkgdir}/__db.*'):
os.unlink (f)
rpm_out = subprocess.run (['rpm', '--dbpath', pkgdir, '-qa', '--qf', '%{NAME} %{VERSION}\n'], capture_output=True, text=True).stdout
for l in rpm_out.splitlines():
words = l.split()
if (not re.search ('-devel$', words[0])):
words[1] = re.sub ('-.*', '', words[1])
apps.append (' '.join (words))
for f in glob.glob (f'{pkgdir}/__db.*'):
os.unlink (f)
else:
pass
#db = bsddb.hashopen (f'{pkgdir}/Name', 'r');
#for k in db.keys():
# apps.append (re.sub ('-devel$', '', k))
# Procesar paquetes pacman.
pkgdir = f'{mntdir}/var/lib/pacman/local'
if os.path.exists (pkgdir):
for f in glob.glob (f'{pkgdir}/*'):
if '-' not in f: continue
idx = f[0:f.rfind ('-')].rfind ('-') ## index of 2nd-to-last dash
apps.append (f[0:idx] + ' ' + f[idx+1:])
# Procesar aplicaciones Snappy.
pkgdir = f'{mntdir}/snap'
out = ''
awk_script = '''
/name:/ {pack=$2}
/version:/ {vers=$2}
END {if (pack!="") print pack,"(snap)",vers}
'''
files = subprocess.run (['find', f'{pkgdir}/*/current/meta', '-name', 'snap.yaml'], capture_output=True, text=True).stdout.splitlines()
for f in files:
awk_out = subprocess.run (['awk', awk_script, f], capture_output=True, text=True).stdout
out += awk_out
apps += out.splitlines()
# Procesar aplicaciones Flatpak.
pkgdir = f'{mntdir}/var/lib/flatpak'
files = glob.glob (f'{pkgdir}/app/*/current/active/deploy/*')
for f in files:
p = open (f.strip()).read().split ('\0')
try:
if (p[0] != 'flathub'): raise ValueError
apps.append ('{} (flatpak) {}'.format (p[p.index('appdata-name') + 4], p[p.index('appdata-version') + 1]))
except ValueError:
pass
elif 'Windows' == ostype:
if shutil.which ('hivexregedit'):
hive = RegistryLib.ogGetHivePath (mntdir, 'software')
if hive:
cmd1_out = subprocess.run (['hivexregedit', '--unsafe-printable-strings', '--export', hive, r'\Microsoft\Windows\CurrentVersion\Uninstall'], capture_output=True, text=True).stdout
cmd1_out += subprocess.run (['hivexregedit', '--unsafe-printable-strings', '--export', hive, r'\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'], capture_output=True, text=True).stdout
out = name = ''
for l in cmd1_out.splitlines():
words = l.split ('"')
if len(words) < 4: continue
if (re.match (r'\[', words[0])): name=''
if (re.search ('DisplayName', words[1])): name=words[3]
if (re.search ('DisplayVersion', words[1])): apps.append (f'{name} {words[3]}')
else:
keys = RegistryLib.ogListRegistryKeys (mntdir, 'software', r'\Microsoft\Windows\CurrentVersion\Uninstall')
keys32 = RegistryLib.ogListRegistryKeys (mntdir, 'software', r'\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall')
for k in keys:
prog = RegistryLib.ogGetRegistryValue (mntdir, 'software', rf'\Microsoft\Windows\CurrentVersion\Uninstall\{k}\DisplayName')
if prog:
vers = RegistryLib.ogGetRegistryValue (mntdir, 'software', rf'\Microsoft\Windows\CurrentVersion\Uninstall\{k}\DisplayVersion')
apps.append (f'{prog} {vers}')
for k in keys32:
prog = RegistryLib.gGetRegistryValue (mntdir, 'software', rf'\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{k}\DisplayName')
if prog:
vers = RegistryLib.ogGetRegistryValue (mntdir, 'software', rf'\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{k}\DisplayVersion')
apps.append (f'{prog} {vers}')
elif 'MacOS' == ostype:
files = subprocess.run (['find', f'{mntdir}/Applications', '-type', 'd', '-name', '*.app', '-prune', '-print'], capture_output=True, text=True).stdout.splitlines()
for k in files:
FILE = f'{k}/Contents/version.plist'
if not os.stat (FILE).st_size:
FILE = f'{k}/Contents/version.plist.uncompress'
if os.stat (FILE).st_size:
VERSION = subprocess.run (['awk', '-F[<>]', '/ShortVersionString/ {getline;v=$3} END {print v}', FILE], capture_output=True, text=True).stdout.strip()
bn = os.path.basename (k)
bn = re.sub ('.app$', '', bn)
apps.append (f'{bn} {VERSION}')
elif 'BSD' == ostype:
sqlite_out = subprocess.run (['sqlite3', f'{mntdir}/var/db/pkg/local.sqlite'], input='SELECT name FROM pkg_search;\n', capture_output=True, text=True).stdout
for l in sqlite_out.splitlines():
apps.append (' '.join (re.search ('(.*)-(.*)', l).groups()))
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, f'{disk}, {par} ({ostype})')
return None
os_version = ogGetOsVersion (disk, par).split (':')[1]
return [os_version] + sorted (set (apps))
## https://stackoverflow.com/questions/2522651/find-a-key-inside-a-deeply-nested-dictionary/2522706#2522706
def _find_key_recursive(plist_dict, key_substr):
for k in plist_dict.keys():
if key_substr in k: return plist_dict[k]
for k, v in plist_dict.items():
if type(v) is dict: # Only recurse if we hit a dict value
value = _find_key_recursive(v, key_substr)
if value:
return value
return ''
#/**
# ogGetOsVersion int_ndisk int_nfilesys
#@brief Devuelve la versión del sistema operativo instalado en un sistema de archivos.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden de la partición
#@return OSType:OSVersion - tipo y versión del sistema operativo.
#@note OSType = { Android, BSD, GrubLoader, Hurd, Linux, MacOS, Solaris, Windows, WinLoader }
#@note Requisitos: awk, head, chroot
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o partición no corresponden con un dispositiv
#@exception OG_ERR_PARTITION Fallo al montar el sistema de archivos.
#*/ ##
#ogGetOsVersion ("1", "2") => "Linux:Ubuntu precise (12.04 LTS) 64 bits"
def ogGetOsVersion(disk, part):
mntdir = FileSystemLib.ogMount (disk, part)
if not mntdir:
return None
type = version = None
is64bit = ''
# Buscar tipo de sistema operativo.
# Para GNU/Linux: leer descripción.
os_release = os.path.join(mntdir, "etc/os-release")
if os.path.isfile(os_release):
type = 'Linux'
with open(os_release, "r") as f:
for line in f:
if line.startswith("PRETTY_NAME"):
version = line.split("=", 1)[1].strip().strip('"')
break
if not version:
lsb_release = os.path.join(mntdir, "etc/lsb-release")
if os.path.isfile(lsb_release):
type = 'Linux'
with open(lsb_release, "r") as f:
for line in f:
if line.startswith("DISTRIB_DESCRIPTION"):
version = line.split("=", 1)[1].strip().strip('"')
break
if not version:
for distrib in ["redhat", "SuSE", "mandrake", "gentoo"]:
distrib_file = os.path.join(mntdir, f"etc/{distrib}-release")
if os.path.isfile(distrib_file):
type = 'Linux'
with open(distrib_file, "r") as f:
version = f.readline().strip()
break
if not version:
arch_release_file = os.path.join(mntdir, "etc/arch-release")
if os.path.isfile(arch_release_file):
type = 'Linux'
version = "Arch Linux"
if not version:
slack_release_file = os.path.join(mntdir, "slackware-version")
if os.path.isfile(slack_release_file):
type = 'Linux'
with open (slack_release_file, 'r') as fd:
c = fd.read()
version = "Slackware {c}"
# Si no se encuentra, intentar ejecutar "lsb_release".
if not version:
out = subprocess.run (['chroot', mntdir, 'lsb_release', '-d'], capture_output=True, text=True).stdout
m = re.search (':\t(.*)', out)
if m:
type = 'Linux'
version = m.group(1)
# Comprobar Linux de 64 bits.
if version and os.path.exists(os.path.join(mntdir, "lib64")):
is64bit = ogGlobals.lang.MSG_64BIT
# Para Android, leer fichero de propiedades.
if not version:
type = 'Android'
files = glob.glob (os.path.join (mntdir, 'android*/system/build.prop'))
if files and os.path.isfile (files[0]):
v = []
with open (files[0], 'r') as f:
for line in f:
if 'product.brand' in line or 'build.version.release' in line:
v.append (line.split('=')[1].strip())
version = ' '.join (v)
if os.path.exists(os.path.join(mntdir, "lib64")):
is64bit = ogGlobals.lang.MSG_64BIT
# Para GNU/Hurd, comprobar fichero de inicio (basado en os-prober).
if not version:
type = 'Hurd'
if os.path.exists(os.path.join(mntdir, "hurd/init")):
version = 'GNU/Hurd'
# Para Windows: leer la version del registro.
if not version:
type = 'Windows'
build = 0
file = RegistryLib.ogGetHivePath (mntdir, 'SOFTWARE')
if file:
# Nuevo método más rápido para acceder al registro de Windows..
i = '\n'.join ([
f'load {file}',
r'cd \Microsoft\Windows NT\CurrentVersion',
'lsval ProductName',
'lsval DisplayVersion',
])
version = subprocess.run (['hivexsh'], input=i, capture_output=True, text=True).stdout
version = version.replace ('\n', ' ')
# Recoge el valor del número de compilación para ver si es Windows 10/11
i = '\n'.join ([
f'load {file}',
r'cd \Microsoft\Windows NT\CurrentVersion',
'lsval CurrentBuildNumber',
])
build = subprocess.run (['hivexsh'], input=i, capture_output=True, text=True).stdout
if subprocess.run (['reglookup', '-H', '-p', 'Microsoft/Windows/CurrentVersion/ProgramW6432Dir', file], capture_output=True, text=True).stdout:
is64bit = ogGlobals.lang.MSG_64BIT
if not version:
# Compatibilidad con métrodo antiguo y más lento de acceder al registro.
version = RegistryLib.ogGetRegistryValue (mntdir, 'software', r'\Microsoft\Windows NT\CurrentVersion\ProductName')
if RegistryLib.ogGetRegistryValue (mntdir, 'software', r'\Microsoft\Windows\CurrentVersion\ProgramW6432Dir'):
is64bit = ogGlobals.lang.MSG_64BIT
# Si la compilación es mayor o igual a 22000 es Windows 11
if int (build) >= 22000:
version = version.replace ('10', '11')
# Para cargador Windows: buscar versión en fichero BCD (basado en os-prober).
if not version:
type = 'WinLoader'
file = FileLib.ogGetPath (file=f'{mntdir}/boot/bcd')
if not file:
file = FileLib.ogGetPath (file=f'{mntdir}/EFI/Microsoft/boot/bcd')
if file:
for distrib in 'Windows Recovery', 'Windows Boot':
with open (file, 'rb') as fd:
contents = fd.read()
distrib_utf16_regex = re.sub (r'(.)', '\\1.', distrib)
distrib_utf16_regex = bytes (distrib_utf16_regex, 'ascii')
if re.search (distrib_utf16_regex, contents):
version = f'{distrib} loader'
# Para macOS: detectar kernel y completar con fichero plist de información del sistema.
if not version:
type = 'MacOS'
# Kernel de Mac OS (no debe ser fichero de texto).
file = f'{mntdir}/mach_kernel'
out = subprocess.run (['file', '--brief', file], capture_output=True, text=True).stdout
if not 'text' in out:
# Obtener tipo de kernel.
if 'Mach-O' in out: version = 'macOS'
if 'Mach-O 64-bit' in out: is64bit = ogGlobals.lang.MSG_64BIT
# Datos de configuración de versión de Mac OS.
file = f'{mntdir}/System/Library/CoreServices/SystemVersion.plist'
if os.path.exists (file):
with open (file, 'rb') as fd:
contents = fd.read()
plist_dict = plistlib.loads (contents)
n = _find_key_recursive (plist_dict, 'ProductName')
v = _find_key_recursive (plist_dict, 'ProductVersion')
version = f'{n} {v}'.strip()
# Datos de recuperación de macOS.
if version and os.path.exists (f'{mntdir}/com.apple.recovery.boot'):
version += ' recovery'
# Para FreeBSD: obtener datos del Kernel.
### TODO Revisar solución.
if not version:
type = 'BSD'
file = f'{mntdir}/boot/kernel/kernel'
if os.path.exists (file):
lines = subprocess.run (['strings', file], capture_output=True, text=True).stdout.splitlines()
release_search = list (filter (lambda x: re.search ('@.*RELEASE', x), lines))
if release_search:
first, second, *rest = release_search[0].split()
first = first.replace ('@(#)', '')
version = f'{first} {second}'
out = subprocess.run (['file', '--brief', file], capture_output=True, text=True).stdout
if 'x86-64' in out: is64bit = ogGlobals.lang.MSG_64BIT
# Para Solaris: leer el fichero de versión.
### TODO Revisar solución.
if not version:
type = 'Solaris'
file = f'{mntdir}/etc/release'
if os.path.exists (file):
with open (file, 'r') as fd:
version = fd.readline().strip
# Para cargador GRUB, comprobar fichero de configuración.
if not version:
type = 'GrubLoader'
for file in f'{mntdir}/grub/menu.lst', f'{mntdir}/boot/grub/menu.lst':
if os.path.exists (file):
VERSION = 'GRUB Loader'
for entry in f'{mntdir}/grub/grub.cfg', f'{mntdir}/grub2/grub.cfg', f'{mntdir}/EFI/*/grub.cfg', f'{mntdir}/boot/grub/grub.cfg', f'{mntdir}/boot/grub2/grub.cfg', f'{mntdir}/boot/EFI/*/grub.cfg':
for file in glob.glob (entry):
if os.path.exists (file):
version = 'GRUB2 Loader'
# Mostrar resultado y salir sin errores.
if version: return f"{type}:{version} {is64bit}"
return None

View File

@ -1,179 +1,242 @@
#/**
#@file NetLib.py
#@brief Librería o clase Net
#@class Net
#@brief Funciones básicas de red.
#@warning License: GNU GPLv3+
#*/
import subprocess
import sys
import os
import json
import re
from FileLib import *
from SystemLib import *
import ogGlobals
import SystemLib
import FileLib
def ogChangeRepo():
SRCIMG = ""
NEWREPO = ""
REPO = ""
OGUNIT = ""
def _ogConnect_options():
## the original bash code does: eval $(grep "OPTIONS=" /scripts/ogfunctions)
## this is highly insecure but we need to keep it for now
opt = subprocess.run (['grep', '-o', 'OPTIONS=.*', '/scripts/ogfunctions'], capture_output=True, text=True).stdout.strip()
exec (opt, globals())
return OPTIONS
if len(sys.argv) < 2:
print("Usage: ogChangeRepo IPREPO [ OgUnit ]")
print("Example: ogChangeRepo 10.1.120.3")
print("Example: ogChangeRepo 10.1.120.3 cdc")
return
## defined in /scripts/ogfunctions. We can't tackle that yet.
## this is a quick implementation just to unblock development
def _ogConnect (server, protocol, src, dst, options, readonly):
if 'smb' != protocol: return None ## only supported value right now
write_option = ',ro' if readonly else ',rw'
options += write_option
return not subprocess.run (['mount.cifs', f'//{server}/{src}', dst] + options.split()).returncode
if sys.argv[1] == "help":
print("Usage: ogChangeRepo IPREPO [ OgUnit ]")
print("Example: ogChangeRepo 10.1.120.3")
print("Example: ogChangeRepo 10.1.120.3 cdc")
return
if len(sys.argv) >= 2:
NEWREPO = sys.argv[1]
#/**
# ogChangeRepo IPREPO [ OgUnit ]
#@brief Cambia el repositorio para el recurso remoto images.
#@param 1 Ip Repositorio
#@param 2 Abreviatura Unidad Organizativa
#@return Cambio recurso remoto en OGIMG.
#*/
def ogChangeRepo(ip_repo, og_unit=None):
ogprotocol = os.environ['ogprotocol'] or 'smb'
# Opciones de montaje: lectura o escritura
subprocess.run(["mount", "|", "grep", "ogimages.*rw,"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
RW = ",rw" if subprocess.returncode == 0 else ",ro"
if og_unit:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, 'the og_unit parameter became unsupported')
return None
# Si REPO tomamos el repositorio y la unidad organizativa actual
REPO = ogGetRepoIp()
OGUNIT = subprocess.run(["df", "|", "awk", "-F", " ", "'/ogimages/ {sub(\"//.*/ogimages\",\"\",$1); sub(\"/\",\"\",$1); print $1}'"], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.decode().strip()
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())))
# Parametros de entrada. Si $1 = "REPO" dejo el repositorio actual
if sys.argv[1].upper() == "REPO":
NEWREPO = REPO
current_repo = ogGetRepoIp()
new_repo = current_repo if ip_repo.upper() == "REPO" else ip_repo
if new_repo == current_repo: return True
# Si $1 y $2 son el repositorio y la OU actual me salgo
if NEWREPO == REPO and sys.argv[2] == OGUNIT:
return 0
subprocess.run(["umount", ogGlobals.OGIMG], check=True)
subprocess.run(["source", "/scripts/functions"], shell=True)
subprocess.run(["source", "/scripts/ogfunctions"], shell=True)
subprocess.run(["umount", OGIMG])
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}",
)
return False
if sys.argv[2] == "":
SRCIMG = "ogimages"
else:
SRCIMG = "ogimages/" + sys.argv[2]
SystemLib.ogEcho(
["session", "log"],
None,
f"Repository successfully changed to {new_repo}".strip(),
)
subprocess.run(["eval", "$(grep \"OPTIONS=\" /scripts/ogfunctions)"])
return True
ogEcho("session", "log", MSG_HELP_ogChangeRepo + " " + NEWREPO + " " + sys.argv[2].rstrip())
ogConnect(NEWREPO, ogprotocol, SRCIMG, OGIMG, RW)
except Exception as e:
SystemLib.ogRaiseError(
"session",
ogGlobals.OG_ERR_GENERIC,
f"Error executing ogChangeRepo: {e}",
)
return None
# Si da error volvemos a montar el inicial
if subprocess.returncode != 0:
ogConnect(REPO, ogprotocol, SRCIMG, OGIMG, RW)
ogRaiseError("session", OG_ERR_REPO, NEWREPO)
return subprocess.returncode
def ogGetGroupDir():
REPO = ""
DIR = ""
GROUP = ""
#/**
# ogGetGroupDir [ str_repo ]
#@brief Devuelve el camino del directorio para el grupo del cliente.
#@param str_repo repositorio de imágenes (opcional)
#@return path_dir - Camino al directorio del grupo.
#@note repo = { REPO, CACHE } REPO por defecto
#@exception OG_ERR_FORMAT formato incorrecto.
#*/
def ogGetGroupDir(repo=None):
try:
repo = repo or "REPO"
if len(sys.argv) < 2:
ogHelp("ogGetGroupDir", "ogGetGroupDir str_repo", "ogGetGroupDir REPO ==> /opt/opengnsys/images/groups/Grupo1")
return
group = ogGetGroupName()
if group:
dir_path = FileLib.ogGetPath(repo, f"/groups/{group}")
if dir_path and os.path.isdir(dir_path):
return dir_path
if len(sys.argv) == 1:
REPO = "REPO"
else:
REPO = sys.argv[1]
return None
GROUP = ogGetGroupName()
if GROUP:
DIR = ogGetPath(REPO, "/groups/" + GROUP, stderr=subprocess.DEVNULL)
if os.path.isdir(DIR):
print(DIR)
return 0
except Exception as e:
SystemLib.ogRaiseError(
"session",
ogGlobals.OG_ERR_FORMAT,
f"Error in ogGetGroupDir: {e}"
)
return None
#/**
# ogGetGroupName
#@brief Devuelve el nombre del grupo al que pertenece el cliente.
#@return str_group - Nombre de grupo.
#*/
def ogGetGroupName():
if len(sys.argv) >= 2 and sys.argv[1] == "help":
ogHelp("ogGetGroupName", "ogGetGroupName", "ogGetGroupName => Grupo1")
return
if "group" in globals() and group:
print(group)
return 0
try:
group = globals().get("group", None)
return group if group else None
except Exception as e:
print(f"Error in ogGetGroupName: {e}")
return None
#/**
# ogGetHostname
#@brief Muestra el nombre del cliente.
#@return str_host - nombre de máquina
#*/ ##
def ogGetHostname():
HOST = ""
# Tomar nombre de la variable HOSTNAME
host = os.getenv("HOSTNAME", "").strip()
if host: return host
if len(sys.argv) >= 2 and sys.argv[1] == "help":
ogHelp("ogGetHostname", "ogGetHostname", "ogGetHostname => pc1")
return
# Tomar nombre de la variable HOSTNAME
HOST = os.getenv("HOSTNAME")
# Si no, tomar del DHCP, opción host-name
if not HOST:
with open("/var/lib/dhcp3/dhclient.leases", "r") as f:
# Si no, tomar del DHCP, opción host-name /* (comentario para Doxygen)
dhcp_file = "/var/lib/dhcp3/dhclient.leases"
if os.path.exists(dhcp_file):
with open(dhcp_file, "r") as f:
for line in f:
if "option host-name" in line:
HOST = line.split('"')[1]
break
if 'option host-name' in line:
return line.split('"')[1].strip(";")
# Si no, leer el parámetro del kernel hostname
if not HOST:
with open("/proc/cmdline", "r") as f:
cmdline = f.read()
HOST = re.search(r"hostname=([^ ]+)", cmdline)
if HOST:
HOST = HOST.group(1)
# Si no, leer el parámetro del kernel hostname (comentario para Doxygen) */
cmdline_file = "/proc/cmdline"
if os.path.exists(cmdline_file):
with open(cmdline_file, "r") as f:
for entry in f.read().split():
if entry.startswith("hostname="):
return entry.split("=")[1].strip()
if HOSTNAME != HOST:
os.environ["HOSTNAME"] = HOST
if HOST:
print(HOST)
#/**
# ogGetIpAddress
#@brief Muestra la dirección IP del sistema
#@return str_ip - Dirección IP
#@note Usa las variables utilizadas por el initrd "/etc/net-ethX.conf
#*/ ##
def ogGetIpAddress():
IP = ""
if len(sys.argv) >= 2 and sys.argv[1] == "help":
ogHelp("ogGetIpAddress", "ogGetIpAddress", "ogGetIpAddress => 192.168.0.10")
return
if "IPV4ADDR" in os.environ:
IP = os.environ["IPV4ADDR"]
else:
# Obtener direcciones IP.
if "DEVICE" in os.environ:
IP = subprocess.run(["ip", "-o", "address", "show", "up", "dev", os.environ["DEVICE"]], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.decode().split()
else:
IP = subprocess.run(["ip", "-o", "address", "show", "up"], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.decode().split()
ip = os.environ["IPV4ADDR"]
if '/' in ip: ip = ip.split ('/')[0]
return ip
IP = [addr.split("/")[0] for addr in IP if "inet" in addr]
# Mostrar solo la primera.
if IP:
print(IP[0])
return 0
def ogGetMacAddress():
MAC = ""
if len(sys.argv) >= 2 and sys.argv[1] == "help":
ogHelp("ogGetMacAddress", "ogGetMacAddress", "ogGetMacAddress => 00:11:22:33:44:55")
return
# Obtener direcciones Ethernet.
extra_args = []
if "DEVICE" in os.environ:
MAC = subprocess.run(["ip", "-o", "link", "show", "up", "dev", os.environ["DEVICE"]], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.decode().split()
MAC = [addr.upper() for addr in MAC if "ether" in addr]
else:
MAC = subprocess.run(["ip", "-o", "link", "show", "up"], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.decode().split()
MAC = [addr.upper() for addr in MAC if "ether" in addr and "lo" not in addr]
extra_args = [ "dev", os.environ["DEVICE"] ]
ipas = subprocess.run (['ip', '-json', 'address', 'show', 'up'] + extra_args, capture_output=True, text=True).stdout
# Mostrar solo la primera.
if MAC:
print(MAC[0])
ipasj = json.loads (ipas)
addresses = []
for e in ipasj:
if 'lo' == e['ifname']: continue
if 'addr_info' not in e: continue
addrs = e['addr_info']
for a in addrs:
if 'inet' != a['family']: continue
addresses.append ({ 'local': a['local'], 'prefixlen': a['prefixlen'] })
return 0
if 1 != len (addresses):
raise Exception ('more than one local IP address found')
return addresses[0]
#/**
# ogGetMacAddress
#@brief Muestra la dirección Ethernet del cliente.
#@return str_ether - Dirección Ethernet
#*/ ##
def ogGetMacAddress():
try:
if "DEVICE" in os.environ:
device = os.environ["DEVICE"]
result = subprocess.run(
["ip", "-o", "link", "show", "up", "dev", device],
capture_output=True,
text=True,
check=True
).stdout
else:
result = subprocess.run(
["ip", "-o", "link", "show", "up"],
capture_output=True,
text=True,
check=True
).stdout
mac_addresses = []
for line in result.splitlines():
if "link/ether" in line:
parts = line.split()
for i, part in enumerate(parts):
if part == "link/ether":
mac_addresses.append(parts[i + 1].upper())
if mac_addresses:
print (f'nati: ogGetMacAddress: {mac_addresses[0]}')
return mac_addresses[0]
else:
print("No active mac address found")
return None
except subprocess.CalledProcessError as e:
print(f"Error executing ip command: {e.stderr}")
return None
except Exception as e:
print(f"Unexpected error: {str(e)}")
return None
#/**
# ogGetNetInterface
#@brief Muestra la interfaz de red del sistema
#@return str_interface - interfaz de red
#@note Usa las variables utilizadas por el initrd "/etc/net-ethX.conf
#*/ ##
def ogGetNetInterface():
if len(sys.argv) >= 2 and sys.argv[1] == "help":
ogHelp("ogGetNetInterface", "ogGetNetInterface", "ogGetNetInterface => eth0")
SystemLib.ogHelp("ogGetNetInterface", "ogGetNetInterface", "ogGetNetInterface => eth0")
return
if "DEVICE" in os.environ:
@ -181,65 +244,63 @@ def ogGetNetInterface():
return 0
#/**
# ogGetRepoIp
#@brief Muestra la dirección IP del repositorio de datos.
#@return str_ip - Dirección IP
#*/ ##
def ogGetRepoIp():
# Variables locales.
SOURCE = ""
FSTYPE = ""
out = subprocess.run (["findmnt", "--json", "--output", "SOURCE,FSTYPE", ogGlobals.OGIMG], capture_output=True, text=True).stdout
try:
j = json.loads (out)
except json.decoder.JSONDecodeError:
return None
# Mostrar ayuda.
if len(sys.argv) >= 2 and sys.argv[1] == "help":
ogHelp("ogGetRepoIp", "ogGetRepoIp", "ogGetRepoIp => 192.168.0.2")
return
if 'filesystems' not in j: return None
source = j['filesystems'][0]['source']
fstype = j['filesystems'][0]['fstype']
# Obtener direcciones IP, según el tipo de montaje.
output = subprocess.run(["findmnt", "-P", "-o", "SOURCE,FSTYPE", OGIMG], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.decode().strip()
lines = output.split("\n")
for line in lines:
fields = line.split()
if len(fields) == 2:
if fields[1] == "nfs":
SOURCE = fields[0].split(":")[0]
elif fields[1] == "cifs":
SOURCE = fields[0].split("/")[2]
if 'nfs' == fstype: return source.split(":")[0]
elif 'cifs' == fstype: return source.split("/")[2]
if SOURCE:
print(SOURCE)
return 0
return None
#/**
# ogGetServerIp
#@brief Muestra la dirección IP del Servidor de OpenGnSys.
#@return str_ip - Dirección IP
#@note Comprobacion segun protocolo de conexion al Repo
#*/ ##
def ogGetServerIp():
# Variables locales.
SOURCE = ""
FSTYPE = ""
return os.environ['ogcore']
# Mostrar ayuda.
if len(sys.argv) >= 2 and sys.argv[1] == "help":
ogHelp("ogGetServerIp", "ogGetServerIp", "ogGetServerIp => 192.168.0.2")
return
#/**
# ogGetServerPort
#@brief Muestra el puerto del Servidor de OpenGnSys.
#@return str_port - Puerto
#*/ ##
def ogGetServerPort():
if 'ogcore_port' in os.environ:
return os.environ['ogcore_port']
else:
return '8443'
# Obtener direcciones IP, según el tipo de montaje.
output = subprocess.run(["findmnt", "-P", "-o", "SOURCE,FSTYPE", OGIMG], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.decode().strip()
lines = output.split("\n")
for line in lines:
fields = line.split()
if len(fields) == 2:
if fields[1] == "nfs":
SOURCE = fields[0].split(":")[0]
elif fields[1] == "cifs":
SOURCE = fields[0].split("/")[2]
if SOURCE:
print(SOURCE)
return 0
#/**
# ogMakeGroupDir [ str_repo ]
#@brief Crea el directorio para el grupo del cliente.
#@param str_repo repositorio de imágenes (opcional)
#@return (nada)
#@note repo = { REPO, CACHE } REPO por defecto
#@exception OG_ERR_FORMAT formato incorrecto.
#*/
def ogMakeGroupDir():
REPO = ""
DIR = ""
GROUP = ""
if len(sys.argv) < 2:
ogHelp("ogMakeGroupDir", "ogMakeGroupDir str_repo", "ogMakeGroupDir", "ogMakeGroupDir REPO")
SystemLib.ogHelp("ogMakeGroupDir", "ogMakeGroupDir str_repo", "ogMakeGroupDir", "ogMakeGroupDir REPO")
return
if len(sys.argv) == 1:
@ -247,7 +308,7 @@ def ogMakeGroupDir():
else:
REPO = sys.argv[1]
DIR = ogGetPath(REPO, "/groups/" + ogGetGroupName(), stderr=subprocess.DEVNULL)
DIR = FileLib.ogGetPath(REPO, "/groups/" + ogGetGroupName(), stderr=subprocess.DEVNULL)
if DIR:
subprocess.run(["mkdir", "-p", DIR], stderr=subprocess.DEVNULL)

View File

@ -0,0 +1,320 @@
#/**
#@file PostConfLib.py
#@brief Librería o clase PostConf
#@class PostConf
#@brief Funciones para la postconfiguración de sistemas operativos.
#@warning License: GNU GPLv3+
#*/
import os
import glob
import subprocess
import ogGlobals
import SystemLib
import FileSystemLib
import FileLib
import NetLib
import RegistryLib
import InventoryLib
import BootLib
#/**
# ogCleanOs int_ndisk int_nfilesys
#@brief Elimina los archivos que no son necesarios en el sistema operativo.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
#@exception OG_ERR_PARTITION Partición desconocida o no accesible.
#@note Antes incluido en la funcion ogReduceFs
#@return (nada)
#*/ ##
#ogCleanOs (1, 1)
def ogCleanOs (disk, par):
t = InventoryLib.ogGetOsType (disk, par)
if 'Linux' == t:
BootLib.ogCleanLinuxDevices (disk, par)
mntdir = FileSystemLib.ogMount (disk, par)
for t in glob.glob ('{mntdir}/tmp/*'):
shutil.rmtree (t)
elif 'Windows' == t:
for f in 'pagefile.sys', 'hiberfil.sys', 'swapfile.sys':
p = FileLib.ogGetPath (src=f'{disk} {par}', file=f)
if p: FileLib.ogDeleteFile (disk=disk, par=par, file=f)
#/**
# ogInstallMiniSetup int_ndisk int_npartition str_filename [str_admuser str_admpassword bool_autologin [str_autouser str_autopassword] ]
#@brief Metafunción para instalar archivo que se ejecutará en el arranque de Windows.
#@see ogInstallFirstBoot ogInstallRunonce
#*/ ##
def ogInstallMiniSetup (disk, par, cmdfile, user=None, pwd=None, autologin=False, userauto=None, pwdauto=None):
if user:
ogInstallRunonce (disk, par, cmdfile, user, pwd, autologin, userauto, pwdauto)
else:
ogInstallFirstBoot (disk, par, cmdfile)
#/**
# ogInstallFirstBoot int_ndisk int_npartition str_filename
#@brief Crea unas claves del registro y el archivo cmd que se ejecutara en el primer arranque estando la maquina en un estado bloqueado
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@param str_filename nombre del archivo .cmd a ejecutar en el arranque
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@note El archivo estará en system32 y será visible por el sistema.
#*/ ##
#ogInstallFirstBoot ('1', '1', 'filename.cmd')
def ogInstallFirstBoot (disk, par, cmdfile):
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir: return
for i in ['winnt', 'windows']:
dir = FileLib.ogGetPath (file=f'{mntdir}/{i}/system32')
if dir: cmddir = dir
if not cmddir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{mntdir}/windows/system32')
return
full_cmdfile = f'{cmddir}/{cmdfile}'
bn = os.path.basename (full_cmdfile)
# Creamos el archivo cmd y creamos un par de comandos para que una vez acabe la
# postconfiguracion resetee el mini setup, sino lo haria en cada arranque.
with open (full_cmdfile, 'w') as fd:
fd.write (r'REG ADD HKLM\System\Setup /v SystemSetupInProgress /t REG_DWORD /d 0 /f' + '\n')
fd.write (r'REG ADD HKLM\System\Setup /v CmdLine /t REG_SZ /d "" /f' + '\n')
# Crear los valores de registro necesarios para que se haga la ejecución del .cmd al aranque.
RegistryLib.ogSetRegistryValue (mntdir, 'SYSTEM', r'\Setup\SystemSetupInProgress', 1)
RegistryLib.ogSetRegistryValue (mntdir, 'SYSTEM', r'\Setup\SetupType', 4)
#RegistryLib.ogDeleteRegistryValue (mntdir, 'SYSTEM', r'\Setup\CmdLine')
RegistryLib.ogAddRegistryValue (mntdir, 'SYSTEM', r'\Setup\CmdLine')
RegistryLib.ogSetRegistryValue (mntdir, 'SYSTEM', r'\Setup\CmdLine', f'cmd.exe /c {bn}')
#/**
# ogInstallRunonce int_ndisk int_npartition str_filename str_adm_user str_adm_password bool_autologin [str_auto_user str_auto_password]
#@brief Crea el archivo cmd que se ejecutara en el runonce de un usuario administrador
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@param str_filename nombre del archivo .cmd a ejecutar en el arranque (estara en system32 y sera visible por el sistema)
#@param str_adm_user usuario administrador para hacer autologin y ejecutar el runonce
#@param str_adm_password password del usuario administrador
#@param bool_autologin si despues de la postconfiguracion queremos que la maquina haga autologin (0 o 1)
#@param str_auto_user Usuario con el que queremos que haga autologin despues de la postconfiguracion
#@param str_auto_password Password del usuario que hara autologin
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#*/ ##
#ogInstallRunonce ('1', '1', 'filename.cmd', 'administrator', 'passadmin', '1', 'userauto', 'pwdauto')
#ogInstallRunonce ('1', '1', 'filename.cmd', 'administrator', 'passadmin', '0')
def ogInstallRunonce (disk, par, cmdfile, user, pwd, autologin, userauto=None, pwdauto=None):
mountpoint = FileLib.ogGetPath (src=f'{disk} {par}', file='/')
for i in ['winnt', 'windows']:
dir = FileLib.ogGetPath (file=f'{mountpoint}/{i}/system32')
if dir: cmddir = dir
if not cmddir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{mountpoint}/Windows/System32')
return
full_cmdfile = f'{cmddir}/{cmdfile}'
if not autologin:
# Si no queremos hacer autologin despues de la postconfiguracion lo indicamos en las claves de registro
with open (full_cmdfile, 'w') as fd:
fd.write (r'DEL C:\ogboot.*' + '\n')
fd.write (r'REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoAdminLogon /t REG_SZ /d 0 /f' + '\n')
fd.write (r'REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultUserName /t REG_SZ /d "" /f' + '\n')
fd.write (r'REG DELETE "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultPassword /f' + '\n')
else:
# Si queremos hacer autologin despues de la postconfiguracion introducimos la informacion en las claves de registro
with open (full_cmdfile, 'w') as fd:
fd.write (r'DEL C:\ogboot.*' + '\n')
fd.write (r'REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoAdminLogon /t REG_SZ /d 1 /f' + '\n')
fd.write (fr'REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultUserName /t REG_SZ /d "{userauto}" /f' + '\n')
fd.write (fr'REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultPassword /t REG_SZ /d "{pwdauto}" /f' + '\n')
#Creamos las claves de registro necesarias para que meter el cmd en el runonce del usuario y este haga autologin
RegistryLib.ogAddRegistryValue (mountpoint, 'software', r'\Microsoft\Windows\CurrentVersion\RunOnce\PostConfiguracion')
RegistryLib.ogSetRegistryValue (mountpoint, 'software', r'\Microsoft\Windows\CurrentVersion\RunOnce\PostConfiguracion', rf'C:\windows\system32\{cmdfile}')
RegistryLib.ogAddRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoAdminLogon')
RegistryLib.ogSetRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoAdminLogon', 1)
RegistryLib.ogAddRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultUserName')
RegistryLib.ogSetRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultUserName', user)
RegistryLib.ogAddRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultDomainName')
RegistryLib.ogSetRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultDomainName', '.\\')
RegistryLib.ogAddRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultPassword')
RegistryLib.ogSetRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultPassword', pwd)
RegistryLib.ogDeleteRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\ForceAutoLockOnLogon')
RegistryLib.ogDeleteRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoLogonCount')
#/**
# ogAddCmd int_ndisk int_npartition str_filename str_commands
#@brief Añade comandos al cmd creado por ogInstalMiniSetup
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@param str_filename nombre del fichero cmd (siempre se guardara en windows\system32\para que sea visible por el sistema
#@param str_commands comando o comandos que se añadiran al fichero
#@return
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar.
#*/ ##
#ogAddCmd ('1', '1', 'filename.cmd', 'command')
def ogAddCmd (disk, par, cmdfile, cmd):
mountpoint = FileSystemLib.ogMount (disk, par)
if not mountpoint: return
full_cmdfile = FileLib.ogGetPath (file=f'{mountpoint}/windows/system32') + '/' + cmdfile
if not full_cmdfile:
ogInstallMiniSetup (disk, par, cmdfile)
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{mountpoint}/windows/system32/{cmdfile}')
return
# Concatenamos el comando en el fichero de comandos
with open (full_cmdfile, 'a') as fd:
fd.write (cmd + '\n')
#/**
# ogDomainScript int_ndisk int_npartition str_domain str_user str_password
#@brief Crea un script .vbs para unir al dominio una maquina windows y el comando adequado en el archivo cmd creado por ogInstallMiniSetup
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@param str_filename nombre del fichero cmd donde deberemos introducir el comando de ejecutar el script vbs
#@param str_domain dominio donde se quiere conectar
#@param str_user usuario con privilegios para unir al dominio
#@param str_password password del usuario con privilegios
#@return
#@exception OG_ERR_FORMAT Formato incorrecto.
#*/ ##
### PRUEBAS.
#/**
# ogConfigureOgagent int_ndisk int_filesys
#@brief Modifica el fichero de configuración del nuevo agente OGAent para sistemas operativos.
#@param int_ndisk nº de orden del disco
#@param int_filesys nº de orden del sistema de archivos
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero o dispositivo no encontrado.
#@exception OG_ERR_LOCKED Sistema de archivos bloqueado.
#*/ ##
def ogConfigureOgagent (disk, par):
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir:
return
for agentdir in ['usr/share/OGAgent', 'Program Files/OGAgent', 'Program Files (x86)/OGAgent', 'Applications/OGAgent.app']:
cfgfile = FileLib.ogGetPath (file=f'{mntdir}/{agentdir}/cfg/ogagent.cfg')
if cfgfile: break
if not cfgfile:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, 'ogagent.cfg')
return
ogcore_scheme = 'https'
ogcore_ip = NetLib.ogGetServerIp()
ogcore_port = NetLib.ogGetServerPort()
cfgfile_patched = cfgfile + '.patched'
in_opengnsys_section = False
with open (cfgfile, 'r') as fdin:
with open (cfgfile_patched, 'w') as fdout:
while True:
lineout = linein = fdin.readline()
if not linein: break
if in_opengnsys_section:
if 'remote' == linein[0:6]:
lineout = f'remote={ogcore_scheme}://{ogcore_ip}:{ogcore_port}/opengnsys/rest/\n'
if '[' == linein[0:1]:
in_opengnsys_section = False
if '[opengnsys]' == linein[0:11]:
in_opengnsys_section = True
fdout.write (lineout)
os.rename (cfgfile_patched, cfgfile)
#/**
# ogInstallLaunchDaemon int_ndisk int_nfilesys str_filename
#@brief Instala archivo que se ejecutará en el arranque de macOS.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@param str_filename nombre del script
#return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero o directorio no encontrado.
#@npte Crea ficheros de configuración /Library/LaunchDaemon/es.opengnsys.Script.plist.
#*/ ##
### PRUEBAS.
#/**
# ogAddToLaunchDaemon int_ndisk int_nfilesys str_filename str_commands
#@brief Añade comandos al script creado por ogInstalLaunchDaemon.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@param str_filename nombre del script (siempre se guardará en /usr/share para que sea visible por el sistema
#@param str_commands comando o comandos que se añadiran al fichero
#return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero o directorio no encontrado.
#*/ ##
#/**
# ogUninstallLinuxClient int_ndisk int_filesys
#@brief Desinstala el cliente OpenGnSys para sistemas operativos GNU/Linux.
#@param int_ndisk nº de orden del disco
#@param int_filesys nº de orden del sistema de archivos
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_PARTITION Paritición o sistema de archivos incorrectos.
#@exception OG_ERR_LOCKED Sistema de archivos bloqueado.
#*/ ##
def ogUninstallLinuxClient (disk, par):
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir:
return
for f in [
f'{mntdir}/usr/sbin/ogAdmLnxClient',
f'{mntdir}/sbin/ogAdmLnxClient',
f'{mntdir}/usr/local/sbin/ogAdmLnxClient',
f'{mntdir}/etc/ogAdmLnxClient.cfg',
f'{mntdir}/usr/local/etc/ogAdmLnxClient.cfg',
]:
try: os.remove (f)
except: pass
for f in [
f'{mntdir}/etc/rc.local',
f'{mntdir}/etc/rc.d/rc.local',
f'{mntdir}/usr/local/etc/rc.local',
f'{mntdir}/usr/local/etc/rc.d/rc.local',
]:
subprocess.run (['sed', '-i', '-e', '/ogAdmLnxClient/ d', f], stderr=subprocess.DEVNULL)
#/**
# ogUninstallWindowsClient int_ndisk int_filesys str_filename
#@brief Desinstala el cliente OpenGnSys para sistemas operativos Windows.
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@param str_filename nombre del fichero cmd donde deberemos introducir el comando de ejecutar el script vbs
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_PARTITION Paritición o sistema de archivos incorrectos.
#@exception OG_ERR_LOCKED Sistema de archivos bloqueado.
#*/ ##
#ogUninstallWindowsClient ('1', '1', 'filename.cmd')
def ogUninstallWindowsClient (disk, par, cmdfile):
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir: return
exe1 = FileLib.ogGetPath (file=f'{mntdir}/windows/ogAdmWinClient.exe')
exe2 = FileLib.ogGetPath (file=f'{mntdir}/winnt/ogAdmWinClient.exe')
if exe1 or exe2:
ogAddCmd (disk, par, cmdfile, 'ogAdmWinClient -remove')
ogAddCmd (disk, par, cmdfile, r'DEL C:\Windows\ogAdmWinClient.exe')
ogAddCmd (disk, par, cmdfile, r'DEL C:\Winnt\ogAdmWinClient.exe')

View File

@ -0,0 +1,915 @@
#!/usr/bin/python3
import subprocess
import re
import json
import os.path
import shutil
import ogGlobals
import SystemLib
import ImageLib
import FileSystemLib
import StringLib
import NetLib
import DiskLib
import FileLib
import CacheLib
#/**
#@file ProtocolLib.py
#@brief Librería o clase Protocol
#@class Protocol
#@brief Funciones para transmisión de datos
#@warning License: GNU GPLv3+
#*/
##################### FUNCIONES UNICAST ################
#/**
# ogUcastSyntax
#@brief Función para generar la instrucción de transferencia de datos unicast
#@param 1 Tipo de operación [ SENDPARTITION RECEIVERPARTITION SENDFILE RECEIVERFILE ]
#@param 2 Sesion Unicast
#@param 3 Dispositivo (opción PARTITION) o fichero(opción FILE) que será enviado.
#@param 4 Tools de clonación (opcion PARTITION)
#@param 5 Tools de compresion (opcion PARTITION)
#@return instrucción para ser ejecutada.
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_UCASTSYNTAXT formato de la sesion unicast incorrecta.
#@note Requisitos: mbuffer
#@todo: controlar que mbuffer esta disponible para los clientes.
#*/ ##
#ogUcastSyntax SENDPARTITION 8000:172.17.36.11:172.17.36.12 device tool level
#ogUcastSyntax RECEIVERPARTITION 8000:172.17.36.249 device tool level
#ogUcastSyntax SENDFILE 8000:172.17.36.11:172.17.36.12 file
#ogUcastSyntax RECEIVERFILE 8000:172.17.36.249 file
def ogUcastSyntax (op, sess, file=None, device=None, tool=None, level=None):
if 'SENDPARTITION' == op or 'RECEIVERPARTITION' == op:
if device is None:
raise TypeError ('missing required argument: "device"')
if tool is None:
raise TypeError ('missing required argument: "tool"')
if tool.lower() not in ['partclone', 'partimage', 'ntfsclone']:
raise TypeError (f'argument "tool" has unsupported value "{tool}"')
if level is None:
raise TypeError ('missing required argument: "level"')
if level.lower() not in ['lzop', 'gzip', '0', '1']:
raise TypeError (f'argument "level" has unsupported value "{level}"')
elif 'SENDFILE' == op or 'RECEIVERFILE' == op:
if file is None:
raise TypeError ('missing required argument: "file"')
else:
raise TypeError ('first parameter should match (SEND|RECEIVER)(PARTITION|FILE), eg. "SENDFILE"')
if 'SEND' in op: mode = 'server'
else: mode = 'client'
session = sess.split (':')
portbase = int (session[0])
if portbase not in range (8000, 8006):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession portbase {portbase}') ## || PERROR=3
return
if 'server' == mode:
address = ''
for i in range (1, len (session)):
address += f' -O {session[i]}:{portbase}'
else:
address = f'{session[1]}:{portbase}'
if 'SENDPARTITION' == op:
syn = ImageLib.ogCreateImageSyntax (device, ' ', tool, level)
## REQUIRES package mbuffer to be installed!!
## otherwise, param2 in ImageLib.ogCreateImageSyntax() is not '| mbuffer' but empty
## and then parts[2] is out of range
parts = syn.split ('|')
prog1 = f'{parts[0]}|{parts[2]}'.strip()
prog1 = prog1.replace ('>', '').strip()
return f'{prog1} | mbuffer {address}'
elif 'RECEIVERPARTITION' == op:
syn = ImageLib.ogRestoreImageSyntax (' ', device, tool, level)
parts = syn.split ('|')
compressor = parts[0].strip()
tools = parts[-1].strip()
return f'mbuffer -I {address} | {compressor} | {tools}'
elif 'SENDFILE' == op:
return f'mbuffer {address} -i {file}'
elif 'RECEIVERFILE' == op:
return f'mbuffer -I {address} -i {file}'
else:
pass ## shouldn't happen
#/**
# ogUcastSendPartition
#@brief Función para enviar el contenido de una partición a multiples particiones remotas usando UNICAST.
#@param 1 disk
#@param 2 partition
#@param 3 sesionUcast
#@param 4 tool image
#@param 5 tool compresor
#@return
#@exception $OG_ERR_FORMAT
#@exception $OG_ERR_UCASTSENDPARTITION
#@note
#@todo: ogIsLocked siempre devuelve 1
#*/ ##
def ogUcastSendPartition (disk, par, sess, tool, level):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return None
FileSystemLib.ogUnmount (disk, par)
cmd = ogUcastSyntax ('SENDPARTITION', sess, device=PART, tool=tool, level=level)
if not cmd: return None
try:
subprocess.run (cmd, shell=True, check=True)
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_UCASTSENDPARTITION, ' ')
return None
#/**
# ogUcastReceiverPartition
#@brief Función para recibir directamente en la partición el contenido de un fichero imagen remoto enviado por UNICAST.
#@param 1 disk
#@param 2 partition
#@param 3 session unicast
#@param 4 tool image
#@param 5 tool compresor
#@return
#@exception OG_ERR_FORMAT
#@exception OG_ERR_UCASTRECEIVERPARTITION
#@note
#@todo:
#*/ ##
def ogUcastReceiverPartition (disk, par, sess, tool, level):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return None
FileSystemLib.ogUnmount (disk, par)
cmd = ogUcastSyntax ('RECEIVERPARTITION', sess, device=PART, tool=tool, level=level)
if not cmd: return None
try:
subprocess.run (cmd, shell=True, check=True)
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_UCASTRECEIVERPARTITION, ' ')
return None
#/**
# ogUcastSendFile [ str_repo | int_ndisk int_npart ] /Relative_path_file sessionMulticast
#@brief Envía un fichero por unicast ORIGEN(fichero) DESTINO(sessionmulticast)
#@param (2 parámetros) $1 path_aboluto_fichero $2 sesionMcast
#@param (3 parámetros) $1 Contenedor REPO|CACHE $2 path_absoluto_fichero $3 sesionMulticast
#@param (4 parámetros) $1 disk $2 particion $3 path_absoluto_fichero $4 sesionMulticast
#@return
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception $OG_ERR_NOTFOUND
#@exception OG_ERR_UCASTSENDFILE
#@note Requisitos:
#*/ ##
#
## TODO esta función es idéntica a ogMcastSendFile pero con s/Ucast/Mcast/;
#ogUcastSendFile ([str_REPOSITORY] [int_ndisk int_npart] /Relative_path_file sesionMcast(puerto:ip:ip:ip)" \
#ogUcastSendFile (disk=1, par=1, file='/aula1/winxp.img', sess='8000:172.17.36.11:172.17.36.12')
#ogUcastSendFile (container='REPO', file='/aula1/ubuntu.iso', sess='sesionUcast')
#ogUcastSendFile (container='CACHE', file='/aula1/winxp.img', sess='sesionUcast')
#ogUcastSendFile ( file='/opt/opengnsys/images/aula1/hd500.vmx', sess='sesionUcast')
def ogUcastSendFile (disk=None, par=None, container=None, file=None, sess=None):
if file is None:
raise TypeError ('missing required argument: "file"')
if sess is None:
raise TypeError ('missing required argument: "sess"')
if container is not None:
if disk is None and par is None:
## we were given container=
source = FileLib.ogGetPath (src=container, file=file)
dev_err = f'{container} {file}'
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if disk is not None and par is not None:
## we were given disk= par=
source = FileLib.ogGetPath (src=f'{disk} {par}', file=file)
dev_err = f'{disk} {par} {file}'
elif disk is None and par is None:
## we were given nothing
source = FileLib.ogGetPath (file=file)
dev_err = file
else:
raise TypeError ('if one of "disk" and "par" are specified, then both must be')
if not source:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dev_err} not found')
return
path2 = FileLib.ogGetPath (file=source)
if not path2:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dev_err} not found')
return
cmd = ogUcastSyntax ('SENDFILE', sess, file=source)
if not cmd: return None
try:
subprocess.run (cmd, shell=True, check=True)
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_UCASTSENDFILE, ' ')
return None
def _clientip():
ipas = subprocess.run (['ip', '-json', 'address', 'show', 'up'], capture_output=True, text=True).stdout
ipasj = json.loads (ipas)
addresses = []
for e in ipasj:
if 'lo' == e['ifname']: continue
if 'addr_info' not in e: continue
addrs = e['addr_info']
for a in addrs:
if 'inet' != a['family']: continue
addresses.append ({ 'local': a['local'], 'prefixlen': a['prefixlen'] })
return addresses
def _binary_ip (ip):
for l in subprocess.run (['ipcalc', '--nocolor', ip ], capture_output=True, text=True).stdout.splitlines():
if 'Address' not in l: continue
match = re.search (r'^(Address:)\s+(\S+)\s+(.*$)', l).group(3).replace (' ', '').replace ('.', '')
break
return match
#/**
# ogMcastSyntax
#@brief Función para generar la instrucción de ejucción la transferencia de datos multicast
#@param 1 Tipo de operación [ SENDPARTITION RECEIVERPARTITION SENDFILE RECEIVERFILE ]
#@param 2 Sesión Mulicast
#@param 3 Dispositivo (opción PARTITION) o fichero(opción FILE) que será enviado.
#@param 4 Tools de clonación (opcion PARTITION)
#@param 5 Tools de compresion (opcion PARTITION)
#@return instrucción para ser ejecutada.
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTEXEC
#@exception OG_ERR_MCASTSYNTAXT
#@note Requisitos: upd-cast 2009 o superior
#@todo localvar check versionudp
#*/ ##
#
#ogMcastSyntax SENDPARTITION 9000:full-duplex|half-duplex|broadcast:239.194.17.36:80M:50:60 device tools level
#ogMcastSyntax RECEIVERPARTITION 9000 device tools level
#ogMcastSyntax RECEIVERPARTITION 9000:172.17.88.161:40:120 device tools level
#ogMcastSyntax SENDFILE 9000:full-duplex|half-duplex|broadcast:239.194.17.36:80M:50:60 file
#ogMcastSyntax RECEIVERFILE 9000 file
#ogMcastSyntax RECEIVERFILE 9000:172.17.88.161:40:120 file
def ogMcastSyntax (op, sess, file=None, device=None, tool=None, level=None):
if 'SENDPARTITION' == op or 'RECEIVERPARTITION' == op:
if device is None:
raise TypeError ('missing required argument: "device"')
if tool is None:
raise TypeError ('missing required argument: "tool"')
if tool.lower() not in ['partclone', 'partimage', 'ntfsclone']:
raise TypeError (f'argument "tool" has unsupported value "{tool}"')
if level is None:
raise TypeError ('missing required argument: "level"')
if level.lower() not in ['lzop', 'gzip', '0', '1']:
raise TypeError (f'argument "level" has unsupported value "{level}"')
elif 'SENDFILE' == op or 'RECEIVERFILE' == op:
if file is None:
raise TypeError ('missing required argument: "file"')
else:
raise TypeError ('first parameter should match (SEND|RECEIVER)(PARTITION|FILE), eg. "SENDFILE"')
if 'SEND' in op: mode = 'server'
else: mode = 'client'
try:
isudpcast = subprocess.run (['udp-receiver', '--help'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True).stdout
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTEXEC, 'upd-cast no existe')
return
session = sess.split (':')
PERROR = 0
if 'server' == mode:
if 6 != len (session):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'parametros session de servidor multicast no completa')
PERROR = 2
elif 'client' == mode:
if 4 < len (session):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'parametros session de cliente multicast no completa')
PERROR = 2
mbuffer = " --pipe 'mbuffer -q -m 20M' "
portbase = int (session[0])
if portbase not in range (9000, 9100, 2):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession portbase {portbase}')
PERROR = 3
if 'server' == mode:
method, address, bitrate, nclients, maxtime = session[1:]
if method.lower() not in ['full-duplex', 'half-duplex', 'broadcast']:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession method {method}')
PERROR = 4
if not StringLib.ogCheckIpAddress (address):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession address {address}')
PERROR = 5
## the original regex has a backslash: ^[0-9]{1,3}\M$
## not sure why
if not re.search (r'^[0-9]{1,3}M$', bitrate):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession bitrate {bitrate}')
PERROR = 6
if not re.search (r'^[0-9]{1,10}$', nclients):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession nclients {nclients}')
PERROR = 7
if not re.search (r'^[0-9]{1,10}$', maxtime):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession maxtime {maxtime}')
PERROR = 8
cerror = '8x8/128'
syntaxserver = f'udp-sender {mbuffer} --nokbd --portbase {portbase} --{method} --mcast-data-address {address} --fec {cerror} --max-bitrate {bitrate} --ttl 16 --min-clients {nclients} --max-wait {maxtime} --autostart {maxtime} --log /tmp/mcast.log'
if PERROR:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_MCASTSYNTAXT, f' {PERROR}')
return
if 'client' == mode:
other = session[1:]
serveraddress = other[0] if len (other) > 0 else ''
starttimeout = other[1] if len (other) > 1 else ''
receivertimeout = other[2] if len (other) > 2 else ''
## serveraddres
if StringLib.ogCheckIpAddress (serveraddress):
serveraddress = f' --mcast-rdv-address {serveraddress}'
else:
repoip = NetLib.ogGetRepoIp()
clientip = _clientip()
if 1 != len (clientip):
raise Exception ('more than one local IP address found')
c = clientip[0]
clientip = c['local']
mascara = c['prefixlen']
ripbt = _binary_ip (repoip)
ipbt = _binary_ip (clientip)
reposubred = ripbt[0:mascara]
clientsubred = ipbt[0:mascara]
if reposubred == clientsubred: serveraddress = ' '
else: serveraddress = f' --mcast-rdv-address {repoip}'
## starttimeout
if re.search (r'^[0-9]{1,10}$', starttimeout):
if 0 == starttimeout: starttimeout = ' '
else: starttimeout = f' --start-timeout {starttimeout}'
else:
starttimeout = f' --start-timeout {ogGlobals.MCASTERRORSESSION}'
if 'start-timeout' not in isudpcast: starttimeout = ' '
## receivertimeout
if re.search (r'^[0-9]{1,10}$', receivertimeout):
if 0 == receivertimeout: receivertimeout = ' '
else: receivertimeout = f' --receive-timeout {receivertimeout}'
else:
receivertimeout = f' --receive-timeout {ogGlobals.MCASTWAIT}'
if 'receive-timeout' not in isudpcast: receivertimeout = ' '
syntaxclient = f'udp-receiver {mbuffer} --portbase {portbase} {serveraddress} {starttimeout} {receivertimeout} --log /tmp/mcast.log'
if 'SENDPARTITION' == op:
syn = ImageLib.ogCreateImageSyntax (device, ' ', tool, level)
## REQUIRES package mbuffer to be installed!!
## otherwise, param2 in ImageLib.ogCreateImageSyntax() is not '| mbuffer' but empty
## and then parts[2] is out of range
parts = syn.split ('|')
prog1 = f'{parts[0]}|{parts[2]}'.strip()
prog1 = prog1.replace ('>', '').strip()
return f'{prog1} | {syntaxserver}'
elif 'RECEIVERPARTITION' == op:
syn = ImageLib.ogRestoreImageSyntax (' ', device, tool, level)
parts = syn.split ('|')
compressor = parts[0].strip()
tools = parts[-1].strip()
return f'{syntaxclient} | {compressor} | {tools} '
elif 'SENDFILE' == op:
return f'{syntaxserver} --file {file}'
elif 'RECEIVERFILE' == op:
return f'{syntaxclient} --file {file}'
else:
raise Exception (f'unknown op ({op})--this should not happen')
#/**
# ogMcastSendFile [ str_repo | int_ndisk int_npart ] /Relative_path_file sessionMulticast
#@brief Envía un fichero por multicast ORIGEN(fichero) DESTINO(sessionmulticast)
#@param (2 parámetros) $1 path_aboluto_fichero $2 sesionMcast
#@param (3 parámetros) $1 Contenedor REPO|CACHE $2 path_absoluto_fichero $3 sesionMulticast
#@param (4 parámetros) $1 disk $2 particion $3 path_absoluto_fichero $4 sesionMulticast
#@return
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception $OG_ERR_NOTFOUND
#@exception OG_ERR_MCASTSENDFILE
#*/ ##
#
#ogMcastSendFile [str_REPOSITORY] [int_ndisk int_npart] /Relative_path_file sesionMcast" \
#ogMcastSendFile (disk=1, par=1, file='/aula1/winxp.img', sess='sesionMcast')
#ogMcastSendFile (container='REPO', file='/aula1/ubuntu.iso', sess='sesionMcast')
#ogMcastSendFile (container='CACHE', file='/aula1/winxp.img', sess='sesionMcast')
#ogMcastSendFile ( file='/opt/opengnsys/images/aula1/hd500.vmx', sess='sesionMcast')
def ogMcastSendFile (disk=None, par=None, container=None, file=None, sess=None):
if file is None:
raise TypeError ('missing required argument: "file"')
if sess is None:
raise TypeError ('missing required argument: "sess"')
if container is not None:
if disk is None and par is None:
## we were given container=
source = FileLib.ogGetPath (src=container, file=file)
dev_err = f'{container} {file}'
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if disk is not None and par is not None:
## we were given disk= par=
source = FileLib.ogGetPath (src=f'{disk} {par}', file=file)
dev_err = f'{disk} {par} {file}'
elif disk is None and par is None:
## we were given nothing
source = FileLib.ogGetPath (file=file)
dev_err = file
else:
raise TypeError ('if one of "disk" and "par" are specified, then both must be')
if not source:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dev_err} not found')
return
path2 = FileLib.ogGetPath (file=source)
if not path2:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dev_err} not found')
return
cmd = ogMcastSyntax ('SENDFILE', sess, file=source)
if not cmd: return None
try:
subprocess.run (cmd, shell=True, check=True)
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_MCASTSENDFILE, ' ')
return None
#/**
# ogMcastReceiverFile sesion Multicast [ str_repo | int_ndisk int_npart ] /Relative_path_file
#@brief Recibe un fichero multicast ORIGEN(sesionmulticast) DESTINO(fichero)
#@param (2 parámetros) $1 sesionMcastCLIENT $2 path_aboluto_fichero_destino
#@param (3 parámetros) $1 sesionMcastCLIENT $2 Contenedor REPO|CACHE $3 path_absoluto_fichero_destino
#@param (4 parámetros) $1 sesionMcastCLIENT $2 disk $3 particion $4 path_absoluto_fichero_destino
#@return
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception $OG_ERR_MCASTRECEIVERFILE
#@note Requisitos:
#*/ ##
#
#ogMcastReceiverFile ([ str_portMcast] [ [Relative_path_file] | [str_REPOSITORY path_file] | [int_ndisk int_npart path_file ] ]" \
#ogMcastReceiverFile ( file='/PS1_PH1.img', sess='9000')
#ogMcastReceiverFile (container='CACHE', file='/aula1/PS2_PH4.img', sess='9000')
#ogMcastReceiverFile (disk=1, par=1, file='/isos/linux.iso', sess='9000')
def ogMcastReceiverFile (disk=None, par=None, container=None, file=None, sess=None):
if file is None:
raise TypeError ('missing required argument: "file"')
if sess is None:
raise TypeError ('missing required argument: "sess"')
if container is not None:
if disk is None and par is None:
## we were given container=
targetdir = FileLib.ogGetParentPath (src=container, file=file)
dev_err = f'{container} {file}'
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if disk is not None and par is not None:
## we were given disk= par=
targetdir = FileLib.ogGetParentPath (src=f'{disk} {par}', file=file)
dev_err = f'{disk} {par} {file}'
elif disk is None and par is None:
## we were given nothing
targetdir = FileLib.ogGetParentPath (file=file)
dev_err = file
else:
raise TypeError ('if one of "disk" and "par" are specified, then both must be')
if not targetdir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'target directory {targetdir} not found')
return
targetfile = os.path.basename (file)
cmd = ogMcastSyntax ('RECEIVERFILE', sess, file=os.path.join (targetdir, targetfile))
if not cmd: return None
try:
subprocess.run (cmd, shell=True, check=True)
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_MCASTRECEIVERFILE, targetfile)
return None
#/**
# ogMcastSendPartition
#@brief Función para enviar el contenido de una partición a multiples particiones remotas.
#@param 1 disk
#@param 2 partition
#@param 3 session multicast
#@param 4 tool clone
#@param 5 tool compressor
#@return
#@exception OG_ERR_FORMAT
#@exception OG_ERR_MCASTSENDPARTITION
#@note
#@todo: ogIsLocked siempre devuelve 1. crear ticket
#*/ ##
#ogMcastSendPartition (disk, par, SessionMulticastSERVER, tools, compresor)
#ogMcastSendPartition (1, 1, '9000:full-duplex:239.194.37.31:50M:20:2', 'partclone', 'lzop')
def ogMcastSendPartition (disk, par, sess, tool, compressor):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return
FileSystemLib.ogUnmount (disk, par)
cmd = ogMcastSyntax ('SENDPARTITION', sess, device=PART, tool=tool, level=compressor)
if not cmd: return None
try:
subprocess.run (cmd, shell=True, check=True)
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_MCASTSENDPARTITION, ' ')
return None
#/**
# ogMcastReceiverPartition
#@brief Función para recibir directamente en la partición el contenido de un fichero imagen remoto enviado por multicast.
#@param 1 disk
#@param 2 partition
#@param 3 session multicast
#@param 4 tool clone
#@param 5 tool compressor
#@return
#@exception $OG_ERR_FORMAT
#*/ ##
def ogMcastReceiverPartition (disk, par, sess, tool, compressor):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return
FileSystemLib.ogUnmount (disk, par)
cmd = ogMcastSyntax ('RECEIVERPARTITION', sess, device=PART, tool=tool, level=compressor)
if not cmd: return None
try:
subprocess.run (cmd, shell=True, check=True)
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_MCASTRECEIVERPARTITION, ' ') ## original code has OG_ERR_MCASTSENDPARTITION
return None
#/**
# ogMcastRequest
#@brief Función temporal para solicitar al ogRepoAux el envio de un fichero por multicast
#@param 1 Fichero a enviar ubicado en el REPO. puede ser ruta absoluta o relatica a /opt/opengnsys/images
#@param 2 PROTOOPT opciones protocolo multicast
#*/ ##
## now ogCore takes this responsibility
def ogMcastRequest (img, proto):
return True
##########################################
############## funciones torrent
#/**
# ogTorrentStart [ str_repo | int_ndisk int_npart ] Relative_path_file.torrent | SessionProtocol
#@brief Función iniciar P2P - requiere un tracker para todos los modos, y un seeder para los modos peer y leecher y los ficheros .torrent.
#@param str_pathDirectory str_Relative_path_file
#@param int_disk int_partition str_Relative_path_file
#@param str_REPOSITORY(CACHE - LOCAL) str_Relative_path_file
#@param (2 parámetros) $1 path_aboluto_fichero_torrent $2 Parametros_Session_Torrent
#@param (3 parámetros) $1 Contenedor CACHE $2 path_absoluto_fichero_Torrent $3 Parametros_Session_Torrent
#@param (4 parámetros) $1 disk $2 particion $3 path_absoluto_fichero_Torrent 4$ Parametros_Session_Torrent
#@return
#@note protocoloTORRENT=mode:time mode=seeder -> Dejar el equipo seedeando hasta que transcurra el tiempo indicado o un kill desde consola, mode=peer -> seedear mientras descarga mode=leecher -> NO seedear mientras descarga time tiempo que una vez descargada la imagen queremos dejar al cliente como seeder.
#*/ ##
#ogTorrentStart ( torrentfile='/opt/opengnsys/cache/linux.iso', torrentsess='peer:60')
#ogTorrentStart (container='CACHE', torrentfile='/PS1_PH1.img.torrent', torrentsess='seeder:10000')
#ogTorrentStart (disk=1, par=1, torrentfile='/linux.iso.torrent', torrentsess='leecher:60')
def ogTorrentStart (disk=None, par=None, container=None, torrentfile=None, torrentsess=None):
if torrentfile is None:
raise TypeError ('missing required argument: "torrentfile"')
if torrentsess is None:
raise TypeError ('missing required argument: "torrentsess"')
if container is not None:
if disk is None and par is None:
## we were given container=
if 'CACHE' != container.upper():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'La descarga torrent solo se hace desde local, copia el torrent a la cache y realiza la operación desde esa ubicación')
return None
source = FileLib.ogGetPath (src=container, file=torrentfile)
dev_err = f'{container} {torrentfile}'
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if disk is not None and par is not None:
## we were given disk= par=
source = FileLib.ogGetPath (src=f'{disk} {par}', file=torrentfile)
dev_err = f'{disk} {par} {torrentfile}'
elif disk is None and par is None:
## we were given nothing
if torrentfile.startswith ('/opt/opengnsys/images'):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'La descarga torrent solo se hace desde local, copia el torrent a la cache y realiza la operación desde esa ubicación')
return None
source = FileLib.ogGetPath (file=torrentfile)
dev_err = torrentfile
else:
raise TypeError ('if one of "disk" and "par" are specified, then both must be')
if not source:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or torrentfile {dev_err} not found')
return
if subprocess.run (['ctorrent', '-x', source]).returncode:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, '')
return None
target = re.sub (r'\.torrent$', '', source)
dirsource = FileLib.ogGetParentPath (file=source)
ERROR = None
sess = torrentsess.split (':')
if 2 != len (sess):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'parametros session Torrent no completa: modo:tiempo')
return None
mode = sess[0].lower()
if mode not in ['seeder', 'peer', 'leecher']:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'valor modo Torrent no valido {sess[0]}')
return None
time = sess[1]
if not re.search (r'^[0-9]{1,10}$', time):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'valor tiempo no valido {sess[1]}')
return None
time = int (time)
OPTION = None
cwd = os.getcwd()
# si No fichero .bf, y Si fichero destino imagen ya descargada y su chequeo fue comprobado en su descarga inicial.
if not os.path.exists (f'{source}.bf') and os.path.exists (target):
print ('imagen ya descargada')
if 'seeder' != mode: return 'success' ## return any true value
print ('MODE seeder ctorrent')
os.chdir (dirsource)
subprocess.run (['timeout', '--signal', 'INT', time, 'ctorrent', '-f', source])
os.chdir (cwd)
return 'success'
#Si no existe bf ni fichero destino descarga inicial.
if not os.path.exists (f'{source}.bf') and not os.path.exists (target):
print ('descarga inicial')
OPTION = 'DOWNLOAD'
# Si fichero bf descarga anterior no completada -.
if os.path.exists (f'{source}.bf') and os.path.exists (target):
print ('Continuar con Descargar inicial no terminada.')
OPTION = 'DOWNLOAD'
if 'DOWNLOAD' != OPTION: return 'success'
os.chdir (dirsource)
if 'peer' == mode:
print ('Donwloading Torrent as peer')
# Creamos el fichero de resumen por defecto
open (f'{source}.bf', 'w').close()
# ctorrent controla otro fichero -b ${SOURCE}.bfog
subprocess.run (['ctorrent', '-f', '-c', '-X', f'sleep {time}; kill -2 $(pidof ctorrent)', '-C', '100', source, '-s', target, '-b', f'{source}.bfog'])
elif 'leecher' == mode:
print ('Donwloading Torrent as leecher')
subprocess.run (['ctorrent', '${SOURCE}', '-X', 'sleep 30; kill -2 $(pidof ctorrent)', '-C', '100', '-U', '0'])
elif 'seeder' == mode:
print ('MODE seeder ctorrent')
# Creamos el fichero de resumen por defecto
open (f'{source}.bf', 'w').close()
# ctorrent controla otro fichero -b ${SOURCE}.bfog
subprocess.run (['ctorrent', '-f', '-c', '-X', f'sleep {time}; kill -2 $(pidof ctorrent)', '-C', '100', source, '-s', target, '-b', f'{source}.bfog'])
else:
print ('this should not happen')
return None
os.chdir (cwd)
#/**
# ogCreateTorrent [ str_repo | int_ndisk int_npart ] Relative_path_file
#@brief Función para crear el fichero torrent.
#@param str_pathDirectory str_Relative_path_file
#@param int_disk int_partition str_Relative_path_file
#@param str_REPOSITORY(CACHE - LOCAL) str_Relative_path_file
#@return
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar.
#@exception OG_ERR_NOTOS La partición no tiene instalado un sistema operativo.
#*/ ##
#ogCreateTorrent ([str_REPOSITORY] [int_ndisk int_npart] Relative_path_file IpBttrack)
#ogCreateTorrent (disk=1, par=1, file='/aula1/winxp', ip_bttrack='10.1.15.23')
#ogCreateTorrent (container='REPO', file='/aula1/winxp', ip_bttrack='10.1.15.45')
#ogCreateTorrent (container='CACHE', file='/aula1/winxp', ip_bttrack='10.1.15.45')
def ogCreateTorrent (disk=None, par=None, container=None, file=None, ip_bttrack=None):
if file is None:
raise TypeError ('missing required argument: "file"')
if ip_bttrack is None:
raise TypeError ('missing required argument: "ip_bttrack"')
from_cache = False
if container is not None:
if disk is None and par is None:
## we were given container=
if 'CACHE' == container: from_cache = True
ext = ImageLib.ogGetImageType (container, file)
if ext is None:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{container} {file}')
return
f = f'{file}.{ext}'
source = FileLib.ogGetPath (src=container, file=f)
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if disk is not None and par is not None:
## we were given disk= par=
f = f'{file}.img'
source = FileLib.ogGetPath (src=f'{disk} {par}', file=f)
elif disk is None and par is None:
## we were given nothing
f = f'{file}.img'
source = FileLib.ogGetPath (file=f)
else:
raise TypeError ('if one of "disk" and "par" are specified, then both must be')
if not source:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, '')
return
if from_cache:
if not CacheLib.ogFindCache():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, "CACHE")
#return None
if os.path.exists (f'{source}.torrent'):
os.rename (f'{source}.torrent', f'{source}.torrent.ant')
print ('Esperamos que se refresque el servidor')
time.sleep (20)
cwd = os.getcwd()
os.chdir (os.path.dirname (source))
print (f'ctorrent -t {os.path.basename (source)} -u http://{ip_bttrack}:6969/announce -s {source}.torrent')
subprocess.run (['ctorrent', '-t', os.path.basename (source), '-u', f'http://{ip_bttrack}:6969/announce', '-s', f'{source}.torrent'])
os.chdir (cwd)
#/**
# ogUpdateCacheIsNecesary [ str_repo ] Relative_path_file_OGIMG_with_/
#@brief Comprueba que el fichero que se desea almacenar en la cache del cliente, no esta.
#@param 1 str_REPO
#@param 2 str_Relative_path_file_OGIMG_with_/
#@param 3 md5 to check: use full to check download image torrent
#@return True cache sin imagen, SI es necesario actualizar el fichero.
#@return False imagen en la cache, NO es necesario actualizar el fichero
#@return None error de sintaxis (TODO)
#@note
#@todo: Proceso en el caso de que el fichero tenga el mismo nombre, pero su contenido sea distinto.
#@todo: Se dejan mensajes mientras se confirma su funcionamiento.
#*/ ##
#ogUpdateCacheIsNecesary ('REPO', '/PS1_PH1.img', 'UNICAST')
#ogUpdateCacheIsNecesary ('REPO', '/ogclient.sqfs', 'FULL')
#ogUpdateCacheIsNecesary ('REPO', '/ogclient.sqfs', 'TORRENT')
def ogUpdateCacheIsNecesary (repo, file, proto):
if not CacheLib.ogFindCache():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTCACHE, '')
return None
if repo.lower() != 'repo':
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f' {repo} {file}')
return None
filesource = FileLib.ogGetPath (src=repo, file=file)
if not filesource:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f' {repo} {file}')
return None
# paso 1. si no existe la imagen, confirmar que es necesario actualizar la cache.
filetarget = FileLib.ogGetPath (src='CACHE', file=file)
if not filetarget:
# borramos el fichero bf del torrent, en el caso de que se hubiese quedado de algun proceso fallido
if FileLib.ogGetPath (src='CACHE', file=f'/{file}.torrent.bf'): ogDeleteFile (container='CACHE', file=f'{file}.torrent.bf')
if FileLib.ogGetPath (src='CACHE', file=f'/{file}.sum'): ogDeleteFile (container='CACHE', file=f'{file}.sum')
if FileLib.ogGetPath (src='CACHE', file=f'/{file}.full.sum'): ogDeleteFile (container='CACHE', file=f'{file}.full.sum')
print ('TRUE(0), es necesario actualizar. Paso 1, la cache no contiene esa imagen ')
return True
# Paso 2. Comprobamos que la imagen no estuviese en un proceso previo torrent
if FileLib.ogGetPath (file=f'{filetarget}.torrent.bf'):
#TODO: comprobar los md5 del fichero .torrent para asegurarnos que la imagen a descarga es la misma.
print ('TRUE(0), es necesario actualizar. Paso 2, la imagen esta en un estado de descarga torrent interrumpido')
return True
## En este punto la imagen en el repo y en la cache se llaman igual,
# paso 4. Obtener los md5 del fichero imagen en la cacha segun PROTOCOLO $3
if proto.lower() in ['full', 'torrent']:
#Buscamos MD5 en el REPO SOURCE
if os.path.exists (f'{filesource}.full.sum'):
with open (f'{filesource}.full.sum', 'r') as fd:
md5source = fd.read().strip()
else:
md5source = FileLib.ogCalculateFullChecksum (file=filesource)
# Generamos el MD5 (full) en la CACHE
if not os.path.exists (f'{filetarget}.full.sum'):
fullck = FileLib.ogCalculateFullChecksum (file=filetarget)
with open (f'{filetarget}.full.sum', 'w') as fd:
fd.write (fullck + '\n')
with open (f'{filetarget}.full.sum', 'r') as fd:
md5target = fd.read().strip()
# Generamos el MD5 (little) en la CACHE para posteriores usos del protocolo MULTICAST
if not os.path.exists (f'{filetarget}.sum'):
ck = FileLib.ogCalculateChecksum (file=filetarget)
with open (f'{filetarget}.sum', 'w') as fd:
fd.write (ck + '\n')
else:
#Buscamos MD5 en el REPO SOURCE
if os.path.exists (f'{filesource}.sum'):
with open (f'{filesource}.sum', 'r') as fd:
md5source = fd.read().strip()
else:
md5source = FileLib.ogCalculateChecksum (file=filesource)
# Generamos el MD5 (little) en la CACHE
if not os.path.exists (f'{filetarget}.sum'):
ck = FileLib.ogCalculateChecksum (file=filetarget)
with open (f'{filetarget}.sum', 'w') as fd:
fd.write (ck + '\n')
with open (f'{filetarget}.sum', 'r') as fd:
md5target = fd.read().strip()
#Generamos o copiamos MD5 (full) en la CACHE para posteriores usos con Torrent
# Si no existe el full.sum y si existe el .sum es porque el upateCACHE multicast o unicast ha sido correcto.
if not os.path.exists (f'{filetarget}.full.sum') and os.path.exists (f'{filetarget}.sum'):
if os.path.exists (f'{filesource}.full.sum'):
#Existe el .full.sum en REPO realizamos COPIA
shutil.copy2 (f'{filesource}.full.sum', f'{filetarget}.full.sum')
else:
#No existe .full.sum no en REPO LO GENERAMOS en la cache: situacion dificil que ocurra
fullck = FileLib.ogCalculateFullChecksum (file=filetarget)
with open (f'{filetarget}.full.sum', 'w') as fd:
fd.write (fullck + '\n')
# Paso 5. comparar los md5
if md5source == md5target:
print ('FALSE (1), No es neceario actualizar. Paso5.A la imagen esta en cache')
return False
else:
print ('imagen en cache distinta, borramos la imagen anterior')
for f in [f'{filetarget}', f'{filetarget}.sum', f'{filetarget}.torrent', f'{filetarget}.full.sum']:
os.unlink (f)
print ('TRUE (0), Si es necesario actualizar.')
return True

View File

@ -0,0 +1,380 @@
#/**
#@file RegistryLib.py
#@brief Librería o clase Registry
#@class Boot
#@brief Funciones para gestión del registro de Windows.
#@warning License: GNU GPLv3+
#*/
import subprocess
import os
import re
import shutil
import tempfile
import ogGlobals
import SystemLib
import FileLib
# Función ficticia para lanzar chntpw con timeout de 5 s., evitando cuelgues del programa.
chntpw_exe = shutil.which ('drbl-chntpw') or shutil.which ('chntpw')
def chntpw (hivefile, input_file):
with open (input_file, 'r') as fd:
input_contents = fd.read()
return subprocess.run ([chntpw_exe, '-e', hivefile], timeout=5, input=input_contents, capture_output=True, text=True).stdout
## en el codigo bash aparecen "${3%\\*}" y "${3##*\\}" varias veces
## ${3%\\*} es el "dirname" de una key del registro
## ${3##*\\} es el "basename"
def _split_k (k):
k_elems = k.split ('\\')
k_dirname = '\\'.join (k_elems[0:-1])
k_basename = k_elems[-1]
return k_dirname, k_basename
#/**
# ogAddRegistryKey path_mountpoint str_hive str_keyname
#@brief Añade una nueva clave al registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_keyname nombre de la clave
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montada previamente.
#*/ ##
def ogAddRegistryKey (mntpt, hive, k):
hivefile = ogGetHivePath (mntpt, hive)
if not hivefile: return
k_dirname, k_basename = _split_k (k)
with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f:
f.write (f'cd {k_dirname}\n')
f.write (f'nk {k_basename}\n')
f.write ('q\ny\n')
f.close()
chntpw (hivefile, f.name)
os.remove (f.name)
#/**
# ogAddRegistryValue path_mountpoint str_hive str_valuename [str_valuetype]
#@brief Añade un nuevo valor al registro de Windows, indicando su tipo de datos.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_valuename nombre del valor
#@param str_valuetype tipo de datos del valor (opcional)
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { DEFAULT, SAM, SECURITY, SOFTWARE, SYSTEM, COMPONENTS }
#@note valuetype = { STRING, BINARY, DWORD }, por defecto: STRING
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montada previamente.
#*/ ##
#ogAddRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Microsoft\NewKey\Value1') ## type STRING by default
#ogAddRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Microsoft\NewKey\Value1', 'STRING')
#ogAddRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Microsoft\NewKey\Value1', 'BINARY')
#ogAddRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Microsoft\NewKey\Value1', 'DWORD')
def ogAddRegistryValue (mntpt, hive, k, vtype='STRING'):
hivefile = ogGetHivePath (mntpt, hive)
if not hivefile: return
k_dirname, k_basename = _split_k (k)
# Determine the value type.
if 'STRING' == vtype.upper(): TYPE = 1
elif 'BINARY' == vtype.upper(): TYPE = 3
elif 'DWORD' == vtype.upper(): TYPE = 4
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_OUTOFLIMIT, vtype)
return
with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f:
f.write (f'cd {k_dirname}\n')
f.write (f'nv {TYPE} {k_basename}\n')
f.write ('q\ny\n')
f.close()
chntpw (hivefile, f.name)
os.remove (f.name)
#/**
# ogDeleteRegistryKey path_mountpoint str_hive str_keyname
#@brief Elimina una clave del registro de Windows con todo su contenido.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_keyname nombre de la clave
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montada previamente.
#@warning La clave debe estar vacía para poder ser borrada.
#*/ ##
def ogDeleteRegistryKey (mntpt, hive, k):
hivefile = ogGetHivePath (mntpt, hive)
if not hivefile: return
k_dirname, k_basename = _split_k (k)
with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f:
f.write (f'cd {k_dirname}\n')
f.write (f'dk {k_basename}\n')
f.write ('q\ny\n')
f.close()
chntpw (hivefile, f.name)
os.remove (f.name)
#/**
# ogDeleteRegistryValue path_mountpoint str_hive str_valuename
#@brief Elimina un valor del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_valuename nombre del valor
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montada previamente.
#*/ ##
#ogDeleteRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Microsoft\NewKey\Value1')
def ogDeleteRegistryValue (mntpt, hive, k):
hivefile = ogGetHivePath (mntpt, hive)
if not hivefile: return
k_dirname, k_basename = _split_k (k)
with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f:
f.write (f'cd {k_dirname}\n')
f.write (f'dv {k_basename}\n')
f.write ('q\ny\n')
f.close()
chntpw (hivefile, f.name)
os.remove(f.name)
#/**
# ogGetHivePath path_mountpoint [str_hive|str_user]
#@brief Función básica que devuelve el camino del fichero con una sección del registro.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@return str_path - camino del fichero de registro
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { DEFAULT, SAM, SECURITY, SOFTWARE, SYSTEM, COMPONENTS, NombreDeUsuario }
#@warning El sistema de archivos de Windows debe estar montada previamente.
#*/ ##
#ogGetHivePath ('/mnt/sda1', 'user1') => /mnt/sda1/Users/user1/NTUSER.DAT
#ogGetHivePath ('/mnt/sda1', 'SYSTEM') => //mnt/sda1/Windows/System32/config/SYSTEM
#ogGetHivePath ('/mnt/sda1', 'IEUser') => //mnt/sda1/Users/IEUser/NTUSER.DAT
def ogGetHivePath(mntpt, hive):
# Camino del fichero de registro de usuario o de sistema (de menor a mayor prioridad).
FILE = FileLib.ogGetPath(file=f"/{mntpt}/Windows/System32/config/{hive}")
if not FILE: FILE = FileLib.ogGetPath(file=f"/{mntpt}/Users/{hive}/NTUSER.DAT")
if not FILE: FILE = FileLib.ogGetPath(file=f"/{mntpt}/winnt/system32/config/{hive}")
if not FILE: FILE = FileLib.ogGetPath(file=f"/{mntpt}/Documents and Settings/{hive}/NTUSER.DAT")
if FILE and os.path.isfile(FILE):
return FILE
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{mntpt} {hive}')
return None
## simulate 'grep --after-context 1'
def _grep_A1 (strings, search_term):
results = []
for i in range (len (strings)):
if search_term in strings[i]:
results.append (strings[i])
if i + 1 < len(strings):
results.append (strings[i + 1])
return results
#/**
# ogGetRegistryValue path_mountpoint str_hive str_valuename
#@brief Devuelve el dato de un valor del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_valuename nombre del valor
#@return str_valuedata - datos del valor.
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw, awk
#@warning El sistema de archivos de Windows debe estar montado previamente.
#*/ ##
def ogGetRegistryValue (mntpt, hive, k):
hivefile = ogGetHivePath(mntpt, hive)
if not hivefile: return
k_dirname, k_basename = _split_k (k)
with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f:
f.write (f'cd {k_dirname}\n')
f.write (f'cat {k_basename}\n')
f.write ('q\n')
f.close()
chntpw_out = chntpw (hivefile, f.name)
os.remove (f.name)
lines = chntpw_out.splitlines()
lines = _grep_A1 (lines, '> Value')
if 2 != len (lines):
return None
ret = None
if 'REG_BINARY' in lines[0]:
if re.search ('^:[0-9A-F]+ ', lines[1]):
ret = lines[1][8:56]
else:
ret = lines[1]
return ret
#/**
# ogListRegistryKeys path_mountpoint str_hive str_key
#@brief Lista los nombres de subclaves de una determinada clave del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_key clave de registro
#@return str_subkey ... - lista de subclaves
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw, awk
#@warning El sistema de archivos de Windows debe estar montado previamente.
#*/ ##
#ogListRegistryKeys ('/mnt/sda1', 'SOFTWARE', '\Microsoft\Windows\CurrentVersion')
def ogListRegistryKeys (mntpt, hive, k):
hivefile = ogGetHivePath(mntpt, hive)
if not hivefile: return
with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f:
f.write (f'ls {k}\n')
f.write ('q\n')
f.close()
chntpw_out = chntpw (hivefile, f.name)
os.remove (f.name)
lines = chntpw_out.splitlines()
ret = []
for l in lines:
elems = re.split ('[<>]', l)
if len(elems) < 2: continue
if ' ' == elems[0]:
ret.append (elems[1])
return ret
#/**
# ogListRegistryValues path_mountpoint str_hive str_key
#@brief Lista los nombres de valores de una determinada clave del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_key clave de registro
#@return str_value ... - lista de valores
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw, awk
#@warning El sistema de archivos de Windows debe estar montado previamente.
#*/ ##
#ogListRegistryValues ('/mnt/sda1', 'SOFTWARE', '\Microsoft\Windows\CurrentVersion')
def ogListRegistryValues (mntpt, hive, k):
hivefile = ogGetHivePath(mntpt, hive)
if not hivefile: return
with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f:
f.write (f'ls {k}\n')
f.write ('q\n')
f.close()
chntpw_out = chntpw (hivefile, f.name)
os.remove (f.name)
lines = chntpw_out.splitlines()
ret = []
for l in lines:
elems = re.split ('[<>]', l)
if len(elems) < 2: continue
if 'REG_' in elems[0]:
ret.append (elems[1])
return ret
def _format_hex (hex_string):
result = []
offset = 0
hex_values = hex_string.strip().split()
result.append (str (len (hex_values)))
while hex_values:
chunk = hex_values[:16]
hex_values = hex_values[16:]
offset_str = f':{offset:05x} '
hex_line = ' '.join (chunk)
result.append (offset_str + hex_line)
offset += 16
return '\n'.join (result)
#/**
# ogSetRegistryValue path_mountpoint str_hive str_valuename str_valuedata
#@brief Establece el dato asociado a un valor del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_valuename nombre del valor de registro
#@param str_valuedata dato del valor de registro
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montado previamente.
#*/ ##
#ogSetRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Key\SubKey\StringValue', 'Abcde Fghij')
#ogSetRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Key\SubKey\DwordValue', 1)
#ogSetRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Key\SubKey\BinaryValue', '04 08 0C 10')
def ogSetRegistryValue (mntpt, hive, k, v):
hivefile = ogGetHivePath (mntpt, hive)
if not hivefile: return
k_dirname, k_basename = _split_k (k)
with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f:
f.write (f"ls {k_dirname}\n")
f.write ('q\n')
f.close()
chntpw_out = chntpw (hivefile, f.name)
os.remove(f.name)
if re.search (f"BINARY.*<{k_basename}>", chntpw_out):
## the entry in the registry is binary. Our input should be a sequence of bytes
if ' ' != v[-1]: v += ' ' ## the regex below requires a trailing space
if not re.match (r'^([0-9A-F]{2} )*$', v.upper()):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'"{v}"')
return
formatted = _format_hex (v.upper())
formatted += '\ns'
else:
formatted = v
with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f:
f.write (f'cd {k_dirname}\n')
f.write (f'ed {k_basename}\n')
f.write (f'{formatted}\n')
f.write ('q\ny\n')
f.close()
chntpw (hivefile, f.name)
os.remove(f.name)

View File

@ -1,31 +1,17 @@
import re
def ogCheckStringInGroup(element, group):
"""
Función para determinar si el elemento pertenece a un conjunto.
:param element: elemento a comprobar
:param group: grupo de elementos para comprobar tipo "valor1 valor2 valor3"
:return: True si pertenece al grupo, False si NO pertenece al grupo
"""
if not isinstance(element, str) or not isinstance(group, str):
raise ValueError("Formato incorrecto, ambos parámetros deben ser cadenas.")
return element in group.split()
def ogCheckStringInReg(element, regex):
"""
Función para determinar si el elemento contiene una "expresión regular".
:param element: elemento a comprobar
:param regex: expresión regular
:return: True si coincide con la expresión, False si NO coincide con la expresión
"""
if not isinstance(element, str) or not isinstance(regex, str):
raise ValueError("Formato incorrecto, ambos parámetros deben ser cadenas.")
return re.match(regex, element) is not None
#/**
# ogCheckIpAddress
#@brief Función para determinar si una cadena es una dirección ipv4 válida
#@param 1 string de la ip a comprobar
#@return 0 si es una dirección válida
#@return 1 si NO es una dirección válida
#@exception OG_ERR_FORMAT formato incorrecto.
#@note
#@todo
#*/ ##
def ogCheckIpAddress(ip):
"""
Función para determinar si una cadena es una dirección ipv4 válida.

512
client/lib/engine/bin/SystemLib.py 100644 → 100755
View File

@ -1,301 +1,291 @@
import subprocess
import datetime
from zoneinfo import ZoneInfo
import sys
import os
import os
import shutil
import inspect
import glob
from DiskLib import *
from CacheLib import *
from StringLib import *
## for ogExecAndLog
from io import StringIO
from contextlib import redirect_stdout, redirect_stderr
print (">>>>>>>>>>>>>>>>>>>> Load ", __name__, " <<<<<<<<<<<<<<<<<<<<<<")
import ogGlobals
import StringLib
import SystemLib
#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 = ""
def _logtype2logfile (t):
if 'log' == t.lower(): return ogGlobals.OGLOGFILE
elif 'command' == t.lower(): return ogGlobals.OGLOGCOMMAND
elif 'session' == t.lower(): return ogGlobals.OGLOGSESSION
else: raise Exception (f'unknown log type ({t})')
#/**
# ogEcho [str_logtype ...] [str_loglevel] "str_message" ...
#@brief Muestra mensajes en consola y lo registra en fichero de incidencias.
#@param str_logtype tipo de registro de incidencias ("log", "command", "session")
#@param str_loglevel nivel de registro de incidencias ("info", "warning", "error")
#@param str_message mensaje (puede recibir más de 1 parámetro.
#@return Mensaje mostrado.
#*/
def ogEcho (logtypes, loglevel, msg):
logfiles = ['/dev/stdout']
if type (logtypes) is list:
for l in logtypes:
logfiles.append (_logtype2logfile (l))
else: ## string
logfiles.append (_logtype2logfile (logtypes))
# 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
if loglevel is None or 'help' == loglevel:
if ogGlobals.DEBUG.lower() != "no":
logfiles.append (ogGlobals.OGLOGFILE)
for f in logfiles:
with open (f, 'a') as fd:
fd.write (msg + '\n')
return
# 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 'info' == loglevel or 'warning' == loglevel or 'error' == loglevel:
DATETIME = datetime.datetime.now(ZoneInfo(ogGlobals.TZ)).strftime("%F %T %Z")
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)
for f in logfiles:
with open (f, 'a') as fd:
fd.write (f"OpenGnsys {loglevel} {DATETIME} {msg}\n")
else:
print(' '.join(args))
raise Exception (f'unknown loglevel ({loglevel})')
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 /")
#/**
# ogExecAndLog str_logfile ... str_command ...
#@brief Ejecuta un comando y guarda su salida en fichero de registro.
#@param str_logfile fichero de registro (pueden ser varios).
#@param str_command comando y comandos a ejecutar.
#@return Salida de ejecución del comando.
#@note str_logfile = { LOG, SESSION, COMMAND }
#*/
#ogHelp (str_logfile ... str_command ...",
#ogHelp ([], ogMyLib.ogSomeMethod, *args, **kwargs)
#ogHelp ('command', ogMyLib.ogSomeMethod, *args, **kwargs)
#ogHelp (['command'], ogMyLib.ogSomeMethod, *args, **kwargs)
#ogHelp (['log', 'command'], ogMyLib.ogSomeMethod, *args, **kwargs)
def ogExecAndLog (logtypes, fun, *args, **kwargs):
logfiles = ['/dev/stdout']
if type (logtypes) is list:
for l in logtypes:
logtypes = list (map (lambda x: x.lower(), logtypes))
logfiles.append (_logtype2logfile (l))
else: ## string
logtypes = logtypes.lower()
logfiles.append (_logtype2logfile (logtypes))
if not fun:
ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'no function provided')
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
## the original bash code does something like this:
#if [ $ISCOMMAND ]; then
# > $OGLOGCOMMAND
# REDIREC="2>&1"
#fi
#eval $COMMAND $REDIREC | tee -a $FILES
# Error si no se recibe un comando que ejecutar.
if not COMMAND:
ogRaiseError(OG_ERR_FORMAT)
return
## a hybrid bash/python pseudocode would end up being like the following:
#if 'command' in logtypes:
# rm $OGLOGCOMMAND
# touch $OGLOGCOMMAND
#
#if 'command' in logtypes:
# ## redirect both stdout and stderr
# eval $COMMAND 2>&1 | tee -a $FILES
#else:
# ## redirect stdout only
# eval $COMMAND | tee -a $FILES
# 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
sout = serr = ''
if 'command' in logtypes:
os.unlink (ogGlobals.OGLOGCOMMAND)
open (ogGlobals.OGLOGCOMMAND, 'w').close()
with redirect_stdout (StringIO()) as r_stdout, redirect_stderr (StringIO()) as r_stderr:
rc = fun (*args, **kwargs)
sout = r_stdout.getvalue()
serr = r_stderr.getvalue()
else:
with redirect_stdout (StringIO()) as r_stdout:
rc = fun (*args, **kwargs)
sout = r_stdout.getvalue()
# Ejecutar comando.
subprocess.call(f"{COMMAND} {REDIREC} | tee -a {FILES}", shell=True)
# Salida de error del comando ejecutado.
return subprocess.PIPESTATUS[0]
rc_str = str (rc)
if sout or serr or ('True' != rc_str and 'False' != rc_str and 'None' != rc_str):
for f in logfiles:
with open (f, 'a') as fd:
if sout: fd.write (f'{sout}\n')
if serr: fd.write (f'{serr}\n')
if rc_str: fd.write (f'{rc_str}\n')
return rc
#/**
# ogGetCaller
#@brief Devuelve nombre del programa o script ejecutor (padre).
#@return str_name - Nombre del programa ejecutor.
#*/
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("-")
if 'COLUMNS' in os.environ:
cols = os.environ['COLUMNS']
else:
cols = None
lines = subprocess.run (["ps", "hp", str(os.getppid()), "-o", "args"], capture_output=True, text=True).stdout.splitlines()
if 0 == len (lines):
return ''
line = lines[0]
words = line.split()
if "bash" in line and len(words)>1:
caller = words[1]
else:
caller = words[0].lstrip("-")
if cols is None:
del (os.environ['COLUMNS'])
else:
os.environ['COLUMNS'] = cols
return os.path.basename(caller)
def ogHelp(*args):
# Variables locales
FUNC = ""
MSG = ""
FUNCNAME = ogHelp.__name__
#/**
# ogHelp ["str_function" ["str_format" ["str_example" ... ]]]
#@brief Muestra mensaje de ayuda para una función determinda.
#@param str_function Nombre de la función.
#@param str_format Formato de ejecución de la función.
#@param str_example Ejemplo de ejecución de la función.
#@return str_help - Salida de ayuda.
#@note Si no se indican parámetros, la función se toma de la variable \c $FUNCNAME
#@note La descripción de la función se toma de la variable compuesta por \c MSG_FUNC_$función incluida en el fichero de idiomas.
#@note Pueden especificarse varios mensajes con ejemplos.
#*/
def ogHelp (fname, fmt=None, examples=[]):
FUNC = fname or inspect.stack()[1][3]
MSG = f'ogGlobals.lang.MSG_HELP_{FUNC}'
try:
MSG = eval (MSG)
except:
MSG = ''
ogEcho ([], "help", f"{ogGlobals.lang.MSG_FUNCTION} {FUNC}: {MSG}")
if fmt:
ogEcho([], "help", f" {ogGlobals.lang.MSG_FORMAT}: {fmt}")
# 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]}")
if type (examples) is list:
for example in examples:
ogEcho([], "help", f" {ogGlobals.lang.MSG_EXAMPLE}: {example}")
else: ## string
ogEcho([], "help", f" {ogGlobals.lang.MSG_EXAMPLE}: {examples}")
# 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)}\""
#/**
# ogRaiseError [str_logtype ...] int_errcode ["str_errmessage" ...]
#@brief Devuelve el mensaje y el código de error correspondiente.
#@param str_logtype tipo de registro de incidencias.
#@param int_errcode código de error.
#@param str_errmessage mensajes complementarios de error.
#@return str_code - código de error
#*/
def ogRaiseError (logtypes, code, msg):
if code == ogGlobals.OG_ERR_FORMAT: MSG = f'{ogGlobals.lang.MSG_ERR_FORMAT} "{msg}"'
elif code == ogGlobals.OG_ERR_NOTFOUND: MSG = f'{ogGlobals.lang.MSG_ERR_NOTFOUND} "{msg}"'
elif code == ogGlobals.OG_ERR_OUTOFLIMIT: MSG = f'{ogGlobals.lang.MSG_ERR_OUTOFLIMIT} "{msg}"'
elif code == ogGlobals.OG_ERR_PARTITION: MSG = f'{ogGlobals.lang.MSG_ERR_PARTITION} "{msg}"'
elif code == ogGlobals.OG_ERR_LOCKED: MSG = f'{ogGlobals.lang.MSG_ERR_LOCKED} "{msg}"'
elif code == ogGlobals.OG_ERR_CACHE: MSG = f'{ogGlobals.lang.MSG_ERR_CACHE} "{msg}"'
elif code == ogGlobals.OG_ERR_NOGPT: MSG = f'{ogGlobals.lang.MSG_ERR_NOGPT} "{msg}"'
elif code == ogGlobals.OG_ERR_REPO: MSG = f'{ogGlobals.lang.MSG_ERR_REPO} "{msg}"'
elif code == ogGlobals.OG_ERR_FILESYS: MSG = f'{ogGlobals.lang.MSG_ERR_FILESYS} "{msg}"'
elif code == ogGlobals.OG_ERR_IMAGE: MSG = f'{ogGlobals.lang.MSG_ERR_IMAGE} "{msg}"'
elif code == ogGlobals.OG_ERR_NOTOS: MSG = f'{ogGlobals.lang.MSG_ERR_NOTOS} "{msg}"'
elif code == ogGlobals.OG_ERR_NOTEXEC: MSG = f'{ogGlobals.lang.MSG_ERR_NOTEXEC} "{msg}"'
elif code == ogGlobals.OG_ERR_NOTWRITE: MSG = f'{ogGlobals.lang.MSG_ERR_NOTWRITE} "{msg}"'
elif code == ogGlobals.OG_ERR_NOTCACHE: MSG = f'{ogGlobals.lang.MSG_ERR_NOTCACHE} "{msg}"'
elif code == ogGlobals.OG_ERR_CACHESIZE: MSG = f'{ogGlobals.lang.MSG_ERR_CACHESIZE} "{msg}"'
elif code == ogGlobals.OG_ERR_REDUCEFS: MSG = f'{ogGlobals.lang.MSG_ERR_REDUCEFS} "{msg}"'
elif code == ogGlobals.OG_ERR_EXTENDFS: MSG = f'{ogGlobals.lang.MSG_ERR_EXTENDFS} "{msg}"'
elif code == ogGlobals.OG_ERR_IMGSIZEPARTITION: MSG = f'{ogGlobals.lang.MSG_ERR_IMGSIZEPARTITION} "{msg}"'
elif code == ogGlobals.OG_ERR_UPDATECACHE: MSG = f'{ogGlobals.lang.MSG_ERR_UPDATECACHE} "{msg}"'
elif code == ogGlobals.OG_ERR_DONTFORMAT: MSG = f'{ogGlobals.lang.MSG_ERR_DONTFORMAT} "{msg}"'
elif code == ogGlobals.OG_ERR_IMAGEFILE: MSG = f'{ogGlobals.lang.MSG_ERR_IMAGEFILE} "{msg}"'
elif code == ogGlobals.OG_ERR_UCASTSYNTAXT: MSG = f'{ogGlobals.lang.MSG_ERR_UCASTSYNTAXT} "{msg}"'
elif code == ogGlobals.OG_ERR_UCASTSENDPARTITION: MSG = f'{ogGlobals.lang.MSG_ERR_UCASTSENDPARTITION} "{msg}"'
elif code == ogGlobals.OG_ERR_UCASTSENDFILE: MSG = f'{ogGlobals.lang.MSG_ERR_UCASTSENDFILE} "{msg}"'
elif code == ogGlobals.OG_ERR_UCASTRECEIVERPARTITION: MSG = f'{ogGlobals.lang.MSG_ERR_UCASTRECEIVERPARTITION} "{msg}"'
elif code == ogGlobals.OG_ERR_UCASTRECEIVERFILE: MSG = f'{ogGlobals.lang.MSG_ERR_UCASTRECEIVERFILE} "{msg}"'
elif code == ogGlobals.OG_ERR_MCASTSYNTAXT: MSG = f'{ogGlobals.lang.MSG_ERR_MCASTSYNTAXT} "{msg}"'
elif code == ogGlobals.OG_ERR_MCASTSENDFILE: MSG = f'{ogGlobals.lang.MSG_ERR_MCASTSENDFILE} "{msg}"'
elif code == ogGlobals.OG_ERR_MCASTRECEIVERFILE: MSG = f'{ogGlobals.lang.MSG_ERR_MCASTRECEIVERFILE} "{msg}"'
elif code == ogGlobals.OG_ERR_MCASTSENDPARTITION: MSG = f'{ogGlobals.lang.MSG_ERR_MCASTSENDPARTITION} "{msg}"'
elif code == ogGlobals.OG_ERR_MCASTRECEIVERPARTITION: MSG = f'{ogGlobals.lang.MSG_ERR_MCASTRECEIVERPARTITION} "{msg}"'
elif code == ogGlobals.OG_ERR_PROTOCOLJOINMASTER: MSG = f'{ogGlobals.lang.MSG_ERR_PROTOCOLJOINMASTER} "{msg}"'
elif code == ogGlobals.OG_ERR_DONTMOUNT_IMAGE: MSG = f'{ogGlobals.lang.MSG_ERR_DONTMOUNT_IMAGE} "{msg}"'
elif code == ogGlobals.OG_ERR_DONTUNMOUNT_IMAGE: MSG = f'{ogGlobals.lang.MSG_ERR_DONTUNMOUNT_IMAGE} "{msg}"'
elif code == ogGlobals.OG_ERR_DONTSYNC_IMAGE: MSG = f'{ogGlobals.lang.MSG_ERR_DONTSYNC_IMAGE} "{msg}"'
elif code == ogGlobals.OG_ERR_NOTDIFFERENT: MSG = f'{ogGlobals.lang.MSG_ERR_NOTDIFFERENT} "{msg}"'
elif code == ogGlobals.OG_ERR_SYNCHRONIZING: MSG = f'{ogGlobals.lang.MSG_ERR_SYNCHRONIZING} "{msg}"'
elif code == ogGlobals.OG_ERR_NOTUEFI: MSG = f'{ogGlobals.lang.MSG_ERR_NOTUEFI} "{msg}"'
elif code == ogGlobals.OG_ERR_NOMSDOS: MSG = f'{ogGlobals.lang.MSG_ERR_NOMSDOS} "{msg}"'
elif code == ogGlobals.OG_ERR_NOTBIOS: MSG = f'{ogGlobals.lang.MSG_ERR_NOTBIOS} "{msg}"'
else:
MSG = MSG_ERR_GENERIC
CODE = OG_ERR_GENERIC
MSG = ogGlobals.lang.MSG_ERR_GENERIC
CODE = ogGlobals.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]))
call_stack = [i[3] for i in inspect.stack()]
if len (call_stack) < 2: return ## shouldn't happen
call_stack.pop() ## remove '<module>'
call_stack.pop(0) ## remove 'ogRaiseError'
str_call_stack = ' '.join (call_stack)
# 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)
if code == ogGlobals.OG_ERR_FORMAT or \
(str_call_stack in ogGlobals.NODEBUGFUNCTIONS) or \
not (len(call_stack)>0 and (call_stack[0] in ogGlobals.NODEBUGFUNCTIONS)):
ogEcho (logtypes, "error", f"{str_call_stack.replace(' ', '<-')}: {MSG}")
return CODE
return code
#/**
# ogIsRepoLocked
#@brief Comprueba si el repositorio está siendo usado (tiene ficheros abiertos).
#@param No.
#@return Código de salida: 0 - bloqueado, 1 - sin bloquear o error.
#*/
def ogIsRepoLocked():
# Variables locales
FILES = ""
FUNCNAME = ogIsRepoLocked.__name__
# No hacer nada, si no está definido el punto de montaje del repositorio.
if not ogGlobals.OGIMG:
return False
# Si se solicita, mostrar ayuda.
if len(sys.argv) > 1 and sys.argv[1] == "help":
ogHelp(f"{FUNCNAME}", f"{FUNCNAME}", f"if {FUNCNAME}(): ...")
# Comprobar si alguno de los ficheros abiertos por los procesos activos está en el
# punto de montaje del repositorio de imágenes.
proc_entries = glob.glob ('/proc/[0-9]*/fd/*')
for e in proc_entries:
p = os.path.realpath (e)
if ogGlobals.OGIMG in p:
return True
return False
# 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
## has no users
#def ogCheckProgram(program):
# FUNCNAME = ogCheckProgram.__name__
#
# if not program or not isinstance(program, str):
# SystemLib.ogRaiseError ("session", ogGlobals.OG_ERR_FORMAT, f"Error: {ogGlobals.lang.MSG_ERR_FORMAT} {FUNCNAME} \"program\"")
# return
#
# if not shutil.which(program):
# SystemLib.ogRaiseError ( "session", ogGlobals.OG_ERR_NOTEXEC, f"Error: The program '{program}' is not available on the system.")
# return
#
# 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
output = subprocess.run (["dmidecode", "-s", "system-product-name"], capture_output=True, text=True).stdout
return "KVM" in output or "VirtualBox" in output

View File

@ -0,0 +1,579 @@
import os.path
import re
import subprocess
import shutil
import ogGlobals
import SystemLib
import FileSystemLib
import DiskLib
import FileLib
import InventoryLib
#!/bin/bash
# Libreria provisional para uso de UEFI
# Las funciones se incluirán las librerías ya existentes
#/**
# ogNvramActiveEntry
#@brief Activa entrada de la NVRAM identificada por la etiqueta o el orden
#@param Num_order_entry | Label_entry Número de orden o la etiqueta de la entrada a borrar.
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##
#ogNvramActiveEntry ('2')
#ogNvramActiveEntry ('Windows Boot Manager')
def ogNvramActiveEntry (entry):
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
numentries = []
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
try:
foo = int (entry, 16) ## raises ValueError if entry doesn't look like hexadecimal
num = f'{foo:04x}'.upper()
for l in efibootmgr_out.splitlines():
words = l.split()
if len(words) < 2: continue
if num in words[0]:
numentries.append (words[0][4:8])
except ValueError:
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=1)
if len(words) < 2: continue
if words[1] == entry:
numentries.append (words[0][4:8])
if not numentries:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'NVRAM entry "{entry}"')
return
if 1 != len(numentries):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, f'more than one entry found')
return
subprocess.run (['efibootmgr', '-a', '-b', numentries[0]], capture_output=True, text=True)
#/**
# ogNvramAddEntry
#@brief Crea nueva entrada en el gestor de arranque (NVRAM), opcionalmente la incluye al final del orden de arranque.
#@param Str_Label_entry Número de disco o etiqueta de la entrada a crear.
#@param Str_BootLoader Número de partición o cargador de arranque.
#@param Bool_Incluir_Arranque Incluir en el orden de arranque (por defecto FALSE) (opcional)
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##
#ogNvramAddEntry ('1', '2', True)
#ogNvramAddEntry ('grub', '/EFI/grub/grubx64.efi', True)
#ogNvramAddEntry ('Windows', '/EFI/Microsoft/Boot/bootmgfw.efi')
def ogNvramAddEntry (bootlbl, bootldr, nvram_set=False):
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
esp = DiskLib.ogGetEsp()
if not esp:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, 'ESP')
return
efidisk, efipar = esp.split()
try:
foo = int(bootlbl) + int(bootldr) ## raises ValueError if bootlbl/bootldr don't look like numbers
bootlabel = f'Part-{int(bootlbl):02d}-{int(bootldr):02d}'
bootloader = f'/EFI/{bootlabel}/Boot/ogloader.efi'
except ValueError:
bootlabel = bootlbl
bootloader = bootldr
ogNvramDeleteEntry (bootlabel)
dev = DiskLib.ogDiskToDev (efidisk)
subprocess.run (['efibootmgr', '-C', '-d', dev, '-p', efipar, '-L', bootlabel, '-l', bootloader])
if nvram_set:
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=1)
if len(words) < 2: continue
if words[1] == bootlabel:
numentry = words[0][4:8]
order = ogNvramGetOrder()
ogNvramSetOrder (order + [numentry])
#/**
# ogCopyEfiBootLoader int_ndisk str_repo path_image
#@brief Copia el cargador de arranque desde la partición EFI a la de sistema.
#@param int_ndisk nº de orden del disco
#@param int_part nº de partición
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@note Si existe el cargador en la partición de sistema no es válido
#*/ ##
def ogCopyEfiBootLoader (disk, par):
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par}')
return None
esp = DiskLib.ogGetEsp()
if not esp:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, 'EFI partition')
return
esp_disk, esp_par = esp.split()
efidir = FileSystemLib.ogMount (esp_disk, esp_par)
if not efidir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'ESP')
return
bootlabel = f'Part-{int(disk):02d}-{int(par):02d}'
osversion = InventoryLib.ogGetOsVersion (disk, par)
print (f'bootlabel ({bootlabel})')
print (f'osversion ({osversion})')
if 'Windows 1' in osversion:
loader = None
for i in f'{efidir}/EFI/Microsoft/Boot/bootmgfw.efi', f'{efidir}/EFI/{bootlabel}/Boot/bootmgfw.efi':
if os.path.exists (i):
loader = i
if not loader:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, f'{disk} {par} ({osversion}, EFI)')
return None
if (os.path.isdir (f'{mntdir}/ogBoot')):
shutil.rmtree (f'{mntdir}/ogBoot')
dirloader = os.path.realpath (os.path.dirname (loader) + '/..')
shutil.copytree (f'{dirloader}/Boot', f'{mntdir}/ogBoot')
#/**
# ogNvramDeleteEntry
#@brief Borra entrada de la NVRAM identificada por la etiqueta o el orden
#@param Num_order_entry | Label_entry Número de orden o la etiqueta de la entrada a borrar.
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado (entrada en NVRAM).
#*/ ##
#ogNvramDeleteEntry ('2')
#ogNvramDeleteEntry ('Windows Boot Manager')
def ogNvramDeleteEntry (entry):
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
numentries = []
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
try:
foo = int (entry, 16) ## raises ValueError if entry doesn't look like hexadecimal
num = f'{foo:04x}'.upper()
for l in efibootmgr_out.splitlines():
words = l.split()
if len(words) < 2: continue
if num in words[0]:
numentries.append (words[0][4:8])
except ValueError:
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=1)
if len(words) < 2: continue
if words[1] == entry:
numentries.append (words[0][4:8])
if not numentries:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'NVRAM entry "{entry}"')
return
if 1 != len(numentries):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, f'more than one entry found')
return
subprocess.run (['efibootmgr', '-B', '-b', numentries[0]], capture_output=True, text=True)
#/**
# ogNvramGetCurrent
#@brief Muestra la entrada del gestor de arranque (NVRAM) que ha iniciado el equipo.
#@return Entrada con la que se ha iniciado el equipo
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
def ogNvramGetCurrent():
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
bootentry = '9999'
ret = None
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=1)
if len(words) < 2: continue
if 'BootCurrent' in words[0]:
bootentry = words[1]
continue
if bootentry in words[0]:
num = words[0][4:8].strip ('0') or '0'
ret = f'{num} {words[1]}'
return ret
# ogNvramGetNext
#@brief Muestra la entrada del gestor de arranque (NVRAM) que se utilizará en el próximo arranque.
#@return Entrada que se utilizará en el próximo arranque
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
def ogNvramGetNext():
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
ret = None
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=1)
if len(words) < 2: continue
if 'BootNext' in words[0]:
ret = words[1]
return ret
# ogNvramGetOrder
#@brief Muestra el orden de las entradas del gestor de arranque (NVRAM)
#@return Array, orden de las entradas
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
def ogNvramGetOrder():
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
ret = []
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
for l in efibootmgr_out.splitlines():
words = l.split()
if len(words) < 2: continue
if 'BootOrder:' == words[0]:
ret = words[1].split (',')
return ret
#/**
# ogNvramGetTimeout
#@brief Muestra el tiempo de espera del gestor de arranque (NVRAM)
#@return Timeout de la NVRAM
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
def ogNvramGetTimeout():
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
ret = None
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=1)
if len(words) < 2: continue
if 'Timeout:' == words[0]:
ret = words[1]
return ret
#/**
# ogGrubUefiConf int_ndisk int_part str_dir_grub
#@brief Genera el fichero grub.cfg de la ESP
#@param int_ndisk nº de orden del disco
#@param int_part nº de partición
#@param str_dir_grub prefijo del directorio de grub en la partición de sistema. ej: /boot/grubPARTITION
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@TODO Confirmar si el fichero "$EFIDIR/EFI/$BOOTLABEL/grub.cfg" es necesario.
#*/ ##
#/**
# ogNvramInactiveEntry
#@brief Inactiva entrada de la NVRAM identificada por la etiqueta o el orden
#@param Num_order_entry | Label_entry Número de orden o la etiqueta de la entrada a borrar.
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
#ogNvramInactiveEntry ('2')
#ogNvramInactiveEntry ('Windows Boot Manager')
def ogNvramInactiveEntry (entry):
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
numentries = []
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
try:
foo = int (entry, 16) ## raises ValueError if entry doesn't look like hexadecimal
num = f'{foo:04x}'.upper()
for l in efibootmgr_out.splitlines():
words = l.split()
if len(words) < 2: continue
if num in words[0]:
numentries.append (words[0][4:8])
except ValueError:
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=1)
if len(words) < 2: continue
if words[1] == entry:
numentries.append (words[0][4:8])
if not numentries:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'NVRAM entry "{entry}"')
return
if 1 != len(numentries):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, f'more than one entry found')
return
subprocess.run (['efibootmgr', '-A', '-b', numentries[0]], capture_output=True, text=True)
#/**
# ogNvramList
#@brief Lista las entradas de la NVRAN (sólo equipos UEFI)
#@return Multiline string: entradas de la NVRAM con el formato: orden etiqueta [* (si está activa) ]
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
def ogNvramList():
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
ret = ''
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=1)
if len(words) < 2: continue
if re.search ('Boot[0-9]', words[0]):
active = '*' if '*' in words[0] else ''
num = words[0][4:8].strip ('0') or '0'
ret += '{:>4s} {} {}\n'.format (num, words[1], active)
return ret
#/**
# ogNvramPxeFirstEntry
#@brief Sitúa la entrada de la tarjeta de red en el primer lugar en la NVRAM.
#@return (nada)
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
def ogNvramPxeFirstEntry():
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
num = ''
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
for l in efibootmgr_out.splitlines():
if re.search ('IP[vV]{0,1}4', l):
num = l[4:8].strip ('0') or '0'
numentry = f'{int(num):04x}'.upper()
o = ogNvramGetOrder()
if not o:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, f'ogNvramGetOrder returned an empty list')
return
# Si la entrada es la primera nos salimos.
if numentry == o[0]:
return True
# Si la entrada ya existe la borramos.
order = [numentry] + list (filter (lambda x: x if x!=numentry else [], o))
ogNvramSetOrder (order)
return True
#/**
# ogRestoreEfiBootLoader int_ndisk str_repo
#@brief Copia el cargador de arranque de la partición de sistema a la partición EFI.
#@param int_ndisk nº de orden del disco
#@param int_part nº de partición
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado (partición de sistema o EFI).
#@exception OG_ERR_NOTOS sin sistema operativo.
#*/ ##
def ogRestoreEfiBootLoader (disk, par):
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par}')
return
esp = DiskLib.ogGetEsp()
if not esp:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, 'EFI partition')
return
esp_disk, esp_par = esp.split()
efidir = FileSystemLib.ogMount (esp_disk, esp_par)
if not efidir:
FileSystemLib.ogFormat (esp_disk, esp_par, 'FAT32')
efidir = FileSystemLib.ogMount (esp_disk, esp_par)
if not efidir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'ESP')
return
osversion = InventoryLib.ogGetOsVersion (disk, par)
if 'Windows 1' in osversion:
bootlabel = f'Part-{int(disk):02d}-{int(par):02d}'
loader = FileLib.ogGetPath (file=f'{mntdir}/ogBoot/bootmgfw.efi')
if not loader:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, f'{disk} {par} ({osversion}, EFI)')
return
efi_bl = f'{efidir}/EFI/{bootlabel}'
if os.path.exists (efi_bl):
shutil.rmtree (efi_bl)
os.makedirs (efi_bl, exist_ok=True)
shutil.copytree (os.path.dirname (loader), f'{efi_bl}/Boot', symlinks=True)
shutil.copy (loader, f'{efi_bl}/Boot/ogloader.efi')
if '' != FileLib.ogGetPath (file=f'{efidir}/EFI/Microsoft'):
os.rename (f'{efidir}/EFI/Microsoft', f'{efidir}/EFI/Microsoft.backup.og')
return
#/**
# ogRestoreUuidPartitions
#@brief Restaura los uuid de las particiones y la tabla de particiones
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@param REPO|CACHE repositorio
#@param str_imgname nombre de la imagen
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND No encontrado fichero de información de la imagen (con uuid)
#*/ ##
#/**
# ogNvramSetNext
#@brief Configura el próximo arranque con la entrada del gestor de arranque (NVRAM) identificada por la etiqueta o el orden.
#@param Num_order_entry | Label_entry Número de orden o la etiqueta de la entrada a borrar.
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##
#ogNvramSetNext ('2')
#ogNvramSetNext ('Windows Boot Manager')
def ogNvramSetNext (entry):
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
numentries = []
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
try:
foo = int (entry, 16) ## raises ValueError if entry doesn't look like hexadecimal
num = f'{foo:04x}'.upper()
for l in efibootmgr_out.splitlines():
words = l.split()
if len(words) < 2: continue
if num in words[0]:
numentries.append (words[0][4:8])
except ValueError:
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=1)
if len(words) < 2: continue
if words[1] == entry:
numentries.append (words[0][4:8])
if not numentries:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'NVRAM entry "{entry}"')
return
if 1 != len(numentries):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, f'more than one entry found')
return
subprocess.run (['efibootmgr', '-n', numentries[0]], capture_output=True, text=True)
#/**
# ogNvramSetOrder
#@brief Configura el orden de las entradas de la NVRAM
#@param Orden de las entradas separadas por espacios
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado (entrada NVRAM).
#*/ ##
#ogNvramSetOrder (['1', '3'])
def ogNvramSetOrder (order):
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
try:
for i in order:
foo = int (i, 16)
except ValueError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'ogNvramSetOrder ([array or hex values])')
return
# Entradas de la NVRAM actuales
numentries = []
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
for l in efibootmgr_out.splitlines():
words = l.split()
if len(words) < 2: continue
if re.search ('Boot[0-9a-fA-F]{4}', words[0]):
numentries.append ('0' + words[0][4:8])
new_order = []
for o in order:
h = f'{int(o,16):05x}'.upper()
if h not in numentries:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'NVRAM entry order "{h}"')
return
new_order.append (h)
subprocess.run (['efibootmgr', '-o', ','.join (new_order)])
#/**
# ogNvramSetTimeout
#@brief Configura el tiempo de espera de la NVRAM
#@param Orden de las entradas separadas por espacios
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##
#ogNvramSetTimeout ('2')
def ogNvramSetTimeout (t):
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
try:
num = int (t) ## raises ValueError if t doesn't look like a number
except ValueError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'ogNvramSetTimeout (timeout)')
return
subprocess.run (['efibootmgr', '-t', t])
#/**
# ogUuidChange int_ndisk str_repo
#@brief Reemplaza el UUID de un sistema de ficheros.
#@param int_ndisk nº de orden del disco
#@param int_part nº de partición
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##

0
client/lib/engine/bin/__init__.py 100644 → 100755
View File

View File

@ -0,0 +1,400 @@
#!/usr/bin/python3
# Fichero de idioma: catalá.
#@version 1.1.1
#@author
# Mensajes de error.
MSG_ERR_GENERIC="Error imprevisto no definido"
MSG_ERR_FORMAT="Formato de ejecución incorrecto"
MSG_ERR_OUTOFLIMIT="Valor fuera de rango o no válido"
MSG_ERR_NOTFOUND="Fichero o dispositivo no encontrado"
MSG_ERR_PARTITION="Partición errónea o desconocida"
MSG_ERR_LOCKED="Recurso bloqueado por operación de uso exclusivo"
MSG_ERR_CACHE="Error en partición de caché local"
MSG_ERR_NOGPT="El disco indicado no contiene una particion GPT"
MSG_ERR_REPO="Error al montar el repositorio de imágenes"
MSG_ERR_NOMSDOS="El disco indicado no contiene una partición MSDOS"
MSG_ERR_FILESYS="Sistema de archivos desconocido o no se puede montar"
MSG_ERR_NOTOS="Sistema operativo no detectado o no se puede iniciar"
MSG_ERR_IMAGE="No se puede crear o restaurar una image de sistema"
MSG_ERR_IMAGEFILE="Archivo de imagen corrupto o de otra versión de partclone"
MSG_ERR_NOTEXEC="Programa o función no ejecutable"
MSG_ERR_NOTWRITE="No hay acceso de escritura"
MSG_ERR_NOTCACHE="No existe particion Cache en el cliente"
MSG_ERR_NOTUEFI="La interfaz UEFI no está activa"
MSG_ERR_NOTBIOS="La interfaz BIOS Legacy no está activa"
MSG_ERR_CACHESIZE="El espacio de la cache local o remota no es suficiente"
MSG_ERR_REDUCEFS="Error al reducir el sistema de archivos"
MSG_ERR_EXTENDFS="Error al expandir el sistema de archivos"
MSG_ERR_IMGSIZEPARTITION="Error al restaurar: Particion mas pequeña que la imagen"
MSG_ERR_UPDATECACHE="Error al realizar el comando updateCache"
MSG_ERR_UCASTSYNTAXT="Error en la generación de sintaxis de transferenica unicast"
MSG_ERR_UCASTSENDPARTITION="Error en envio UNICAST de una particion"
MSG_ERR_UCASTSENDFILE="Error en envio UNICAST de un fichero"
MSG_ERR_UCASTRECEIVERPARTITION="Error en la recepcion UNICAST de una particion"
MSG_ERR_UCASTRECEIVERFILE="Error en la recepcion UNICAST de un fichero"
MSG_ERR_MCASTSYNTAXT="Error en la generación de sintaxis de transferenica multicast"
MSG_ERR_MCASTSENDFILE="Error en envio MULTICAST de un fichero"
MSG_ERR_MCASTRECEIVERFILE="Error en la recepcion MULTICAST de un fichero"
MSG_ERR_MCASTSENDPARTITION="Error en envio MULTICAST de una particion"
MSG_ERR_MCASTRECEIVERPARTITION="Error en la recepcion MULTICAST de un fichero"
MSG_ERR_PROTOCOLJOINMASTER="Error en la conexion de una sesion UNICAST|MULTICAST con el MASTER"
MSG_ERR_DONTFORMAT="Error al formatear"
MSG_ERR_DONTMOUNT_IMAGE="Error al montar/reducir la imagen"
MSG_ERR_DONTUNMOUNT_IMAGE="Error al desmontar la imagen"
MSG_ERR_DONTSYNC_IMAGE="Imagen no sincronizable"
MSG_ERR_NOTDIFFERENT="No se detectan diferencias entre la imagen basica y la particion."
MSG_ERR_SYNCHRONIZING="Error al sincronizar, puede afectar la creacion|restauracion de la imagen"
# Mensajes de avisos.
MSG_DONTUSE="NO USAR"
MSG_DONTMOUNT="Sistema de archivos no montado"
MSG_DONTUNMOUNT="El sistema de archivos no se puede desmontar o no está montado"
MSG_MOUNT="Sistema de archivos montado"
MSG_MOUNTREADONLY="Sistema de archivos montado solo de lectura"
MSG_OBSOLETE="EN DESUSO"
# Mensajes complementarios para las ayudas.
MSG_64BIT="64 bits"
MSG_DISK="disc"
MSG_ERROR="Error"
MSG_EXAMPLE="Exemple"
MSG_FORMAT="Format"
MSG_FUNCTION="Funció"
MSG_HARDWAREINVENTORY="Inventario de maquinari de la màquina"
MSG_IMAGE="imatge"
MSG_INSTALLED="instal-lat"
MSG_NOCACHE="sense caché local"
MSG_NOEXTENDED="sense partició estensa"
MSG_PARTITION="partició"
MSG_PROTOCOL="protocol"
MSG_RESERVEDVALUE="Valor reservat"
MSG_SEE="Veure"
MSG_UNKNOWN="Desconegut"
MSG_WARNING="Avís"
# Mensajes del proceso de arranque.
MSG_DETECTLVMRAID="Detectar metadispositivos LVM y RAID."
MSG_ERRBOOTMODE=f"{MSG_ERROR}: Modo de arranque desconocido."
MSG_LAUNCHCLIENT="Ejecutar cliente."
MSG_LOADAPI="Cargar funciones del motor de clonación."
MSG_LOADMODULES="Cargar módulos del kernel."
MSG_MAKELINKS="Crear enlaces simbólicos."
MSG_MOUNTREPO="Montar repositorio por %s en modo %s."
MSG_OFFLINEMODE="Modo de arranque sin conexión."
MSG_OTHERSERVICES="Iniciar servicios complementarios del cliente."
MSG_POWEROFFCONF="Definir parámetros de ahorro de energía."
# Mensajes del menú por defecto.
MSG_BOOT="Iniciar"
MSG_DUPLEX="D&uacute;plex"
MSG_HOSTNAME="Equipo"
MSG_IPADDR="Direcci&oacute;n IP"
MSG_MACADDR="Direcci&oacute;n MAC"
MSG_MENUTITLE="Men&uacute; de opciones"
MSG_POWEROFF="Apagar el equipo"
MSG_SPEED="Velocidad"
# Mensajes de descripción breve de las funciones de la API.
MSG_HELP_ogAclFilter="Extrae las acl de los ficheros de la diferencial"
MSG_HELP_ogAddCmd="Añade comandos al fichero creado por la función ogInstalMiniSetup."
MSG_HELP_ogAddRegistryKey="Añade una nueva clave al registro de Windows."
MSG_HELP_ogAddRegistryValue="Añade un nuevo valor al registro de Windows."
MSG_HELP_ogAddToLaunchDaemon=""
MSG_HELP_ogBoot="Arranca un sistema operativo instalado."
MSG_HELP_ogBootLoaderDeleteEntry=MSG_DONTUSE
MSG_HELP_ogBootLoaderHidePartitions=MSG_DONTUSE
MSG_HELP_ogBootMbrGeneric=""
MSG_HELP_ogBootMbrXP=""
MSG_HELP_ogBurgDefaultEntry="Configura la entrada por defecto de Burg."
MSG_HELP_ogBurgDeleteEntry="Borra en el Burg del MBR las entradas para el inicio en una particion."
MSG_HELP_ogBurgHidePartitions="Configura el Burg del MBR para que oculte las particiones de windows que no se esten iniciando. Permite definir una partición que no se ocultará (ej: para datos)."
MSG_HELP_ogBurgInstallMbr="Instal·la el carregador d'arrencada BURG al MBR del primer disc dur"
MSG_HELP_ogBurgOgliveDefaultEntry="Configura la entrada de ogLive como la entrada por defecto de Burg."
MSG_HELP_ogCalculateChecksum="Calcula la suma de comprobación (checksum) de un fichero."
MSG_HELP_ogCalculateFullChecksum=""
MSG_HELP_ogChangeRepo="Cambia el repositorio para el recurso remoto images."
MSG_HELP_ogCheckFs="Comprueba la consistencia de un sistema de archivos."
MSG_HELP_ogCheckIpAddress=""
MSG_HELP_ogCheckProgram=""
MSG_HELP_ogCheckStringInGroup=""
MSG_HELP_ogCheckStringInReg=""
MSG_HELP_ogCheckSyncImage="Muestra el contenido de la imagen para comprobarla."
MSG_HELP_ogCleanLinuxDevices=""
MSG_HELP_ogCleanOs="Elimina los archivos que no son necesarios en el sistema operativo."
MSG_HELP_ogCompareChecksumFiles="Compara si coinciden las sumas de comprobación almacenadas de 2 ficheros."
MSG_HELP_ogConfigureFstab=""
MSG_HELP_ogConfigureOgagent="Configura el nuevo agente OGAgent para sistemas ooperativos."
MSG_HELP_ogCopyFile="Copia un fichero a otro almacenamiento."
MSG_HELP_ogCreateBootLoaderImage=""
MSG_HELP_ogCreateCache="Reserva espacio para la partición de caché al final del disco."
MSG_HELP_ogCreateDiskImage="Genera una imagen exacta de un disco completo."
MSG_HELP_ogCreateFileImage="Crea/Redimensiona el archivo de la imagen sincronizada"
MSG_HELP_ogCreateGptPartitions=""
MSG_HELP_ogCreateImage="Genera una imagen exacta de un sistema operativo instalado localmente."
MSG_HELP_ogCreateImageSyntax=""
MSG_HELP_ogCreateInfoImage="Crea informacion del contenido de la imagen"
MSG_HELP_ogCreateMbrImage="Genera una imagen del sector de arranque (MBR)."
MSG_HELP_ogCreatePartitions="Define la estructura de particiones de un disco."
MSG_HELP_ogCreatePartitionTable="Genera una tabla de particiones en caso de que no sea valida."
MSG_HELP_ogCreateTorrent=""
MSG_HELP_ogCopyEfiBootLoader="Copia el cargador de arranque desde la partición EFI a la de sistema."
MSG_HELP_ogDeleteCache="Elimina la partición de caché local."
MSG_HELP_ogDeleteFile="Borra un fichero de un espacio de almacenamiento."
MSG_HELP_ogDeletePartitionTable="Elimina la tabla de particiones del disco"
MSG_HELP_ogDeleteRegistryKey="Borra una clave vacía del registro de Windows."
MSG_HELP_ogDeleteRegistryValue="Borra un valor del registro de Windows."
MSG_HELP_ogDeleteTree="Borra un árbol de directorios de un espacio de almacenamiento."
MSG_HELP_ogDevToDisk="Devuelve el nº de orden de disco o de partición correspondiente al camino del fichero de dispositivo."
MSG_HELP_ogDiskToDev="Devuelve el camino del fichero de dispositivo correspondiente al nº de orden de disco o de partición."
MSG_HELP_ogDomainScript=""
MSG_HELP_ogEcho=""
MSG_HELP_ogExecAndLog=""
MSG_HELP_ogExtendFs="Extiende el tamaño de un sistema de archivo al máximo de su partición."
MSG_HELP_ogFindCache="Indica la partición reservada para caché local."
MSG_HELP_ogFixBootSector=""
MSG_HELP_ogFormatCache="Formatea (inicia) el sistema de caché local."
MSG_HELP_ogFormat="Formatea o reformatea un sistema de archivos."
MSG_HELP_ogFormatFs=MSG_HELP_ogFormat
MSG_HELP_ogGetArch="Devuelve el tipo de arquitectura del cliente."
MSG_HELP_ogGetCacheSize="Devuelve el tamaño de la partición de caché local."
MSG_HELP_ogGetCacheSpace="Devuelve el espacio máximo disponible que puede ser reservado para la partición de caché local."
MSG_HELP_ogGetCaller=""
MSG_HELP_ogGetDiskSize="Devuelve el tamaño del disco."
MSG_HELP_ogGetDiskType="Devuelve el mnemónico de tipo de disco."
MSG_HELP_ogGetFreeSize=""
MSG_HELP_ogGetFsSize="Devuelve el tamaño de un sistema de archivos."
MSG_HELP_ogGetFsType="Devuelve el mnemónico de tipo de sistema de archivos."
MSG_HELP_ogGetGroupDir="Devuelve el camino del directorio por defecto para el grupo del cliente."
MSG_HELP_ogGetGroupName="Devuelve el nombre del grupo al que pertenece el cliente."
MSG_HELP_ogGetHivePath="Devuelve el camino completo del fichero de una sección del registro de Windows."
MSG_HELP_ogGetHostname="Devuelve el nombre de la máquina local."
MSG_HELP_ogGetImageCompressor="Devuelve la herramienta de compresión de la imagen."
MSG_HELP_ogGetImageInfo="Muestra información sobre la imagen monolitica: clonacion:compresor:sistemaarchivos:tamañoKB."
MSG_HELP_ogGetImageProgram="Devuelve el programa usado para crear la imagen."
MSG_HELP_ogGetImageSize="Devuelve el tamaño de una imagen de sistema."
MSG_HELP_ogGetImageType="Devuelve el sistema de ficheros de la imagen."
MSG_HELP_ogGetIpAddress="Devuelve la dirección IP del cliente."
MSG_HELP_ogGetLastSector="Devuelve el último sector usable del disco o de una partición."
MSG_HELP_ogGetMacAddress="Devuelve la dirección Ethernet del cliente."
MSG_HELP_ogGetMountImageDir="Devuelve el directorio de montaje de una imagen."
MSG_HELP_ogGetMountPoint="Devuelve el directorio donde está montado un sistema de archivos local."
MSG_HELP_ogGetNetInterface=""
MSG_HELP_ogGetOsType="Devuelve el tipo de un sistema operativo instalado."
MSG_HELP_ogGetOsUuid=""
MSG_HELP_ogGetOsVersion="Devuelve el tipo y la versión de un sistema operativo instalado."
MSG_HELP_ogGetParentPath="Devuelve el camino completo del directorio padre de un fichero de sistema OpenGnsys."
MSG_HELP_ogGetPartitionActive="Indica cual es la partición marcada como activa en un disco."
MSG_HELP_ogGetPartitionId="Devuelve el identificador de tipo de una partición."
MSG_HELP_ogGetPartitionSize="Devuelve el tamaño de una partición."
MSG_HELP_ogGetPartitionsNumber=""
MSG_HELP_ogGetPartitionTableType="Devuelve el tipo de tabla de particiones del disco"
MSG_HELP_ogGetPartitionType="Devuelve el mnemónico de tipo de una partición."
MSG_HELP_ogGetPath="Devuelve el camino completo de un fichero de sistema OpenGnsys."
MSG_HELP_ogGetRegistryValue="Devuelve el dato de un valor del registro de Windows."
MSG_HELP_ogGetRepoIp="Devuelve la dirección IP del repositorio de datos."
MSG_HELP_ogGetSerialNumber="Devuelve el número de serie del cliente."
MSG_HELP_ogGetServerIp="Devuelve la dirección IP del servidor principal."
MSG_HELP_ogGetSizeParameters="Devuelve el tamaño de los datos de un sistema de ficheros, el espacio necesario para la imagen y si cabe en el repositorio elegido."
MSG_HELP_ogGetWindowsName="Devuelve el nombre del cliente guardado en el registro de Windows."
MSG_HELP_ogGrubAddOgLive="Incluye en el grub del MBR una entrada llamando al cliente de opengnsys."
MSG_HELP_ogGrubDefaultEntry="Configura la entrada por defecto de GRUB."
MSG_HELP_ogGrubDeleteEntry="Borra en el grub del MBR las entradas para el inicio en una particion."
MSG_HELP_ogGrubHidePartitions="Configura el grub del MBR para que oculte las particiones de windows que no se esten iniciando. Permite definir una partición que no se ocultará (ej: para datos)."
MSG_HELP_ogGrubInstallMbr="Instal·la el carregador d'arrencada GRUB al MBR del primer disc dur"
MSG_HELP_ogGrubInstallPartition="Instal·la el carregador d'arrencada BURG al BootSector"
MSG_HELP_ogGrubOgliveDefaultEntry="Configura la entrada de ogLive como la entrada por defecto de GRUB."
MSG_HELP_ogGrubSecurity="Configura usuario y clave para modificar las entradas del menu del Grub."
MSG_HELP_ogGrubUefiConf="Genera el fichero grub.cfg de la partición EFI."
MSG_HELP_ogHelp="Muestra mensajes de ayudas para las funciones."
MSG_HELP_ogHidePartition="Oculta una partición de Windows."
MSG_HELP_ogIdToType="Devuelve el mnemónico asociado al identificador de tipo de partición."
MSG_HELP_ogNvramActiveEntry="Configura a activa entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramAddEntry="Crea nueva entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramDeleteEntry="Borra entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramGetCurrent="Muestra la entrada del gestor de arranque (NVRAM) que ha iniciado el equipo."
MSG_HELP_ogNvramGetNext="Muestra la entrada del gestor de arranque (NVRAM) que se utilizará en el próximo arranque."
MSG_HELP_ogNvramGetOrder="Muestra el orden de las entradas del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramGetTimeout="Muestra el tiempo de espera del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramInactiveEntry="Configura a inactiva entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramList="Lista las entradas del gestor de arranque (NVRAN) marcando con un asterisco las activas"
MSG_HELP_ogNvramSetNext="Configura el próximo arranque con la entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramSetOrder="Configura el orden de las entradas del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramSetTimeout="Configura el tiempo de espera del gestor de arranque (NVRAM)."
MSG_HELP_ogGetOsType="Devuelve el tipo de un sistema operativo instalado."
MSG_HELP_ogInstallFirstBoot="Crea un archivo que se ejecutará en el primer arranque de Windows."
MSG_HELP_ogInstallLaunchDaemon="Instala un archivo que se ejecutará en el arranque de macOS."
MSG_HELP_ogInstallLinuxClient=MSG_OBSOLETE
MSG_HELP_ogInstallMiniSetup="Instala un archivo que se ejecutará en el arranque de Windows."
MSG_HELP_ogInstallRunonce="Crea un archivo que se ejecutará en el inicio de un usuario administrador de Windows."
MSG_HELP_ogInstallWindowsClient=MSG_OBSOLETE
MSG_HELP_ogIsFormated="Comprueba si un sistema de archivos está formateado."
MSG_HELP_ogIsImageLocked="Comprueba si una imagen está bloqueada por una operación de uso exclusivo."
MSG_HELP_ogIsLocked="Comprueba si una partición o su disco están bloqueados por una operación de uso exclusivo."
MSG_HELP_ogIsDiskLocked="Comprueba si un disco está bloqueado por una operación de uso exclusivo."
MSG_HELP_ogIsMounted="Comprueba si un sistema de archivos está montado."
MSG_HELP_ogIsNewerFile="Comprueba si un fichero es más nuevo (se ha modificado después) que otro."
MSG_HELP_ogIsPartitionLocked=MSG_HELP_ogIsLocked
MSG_HELP_ogIsRepoLocked=""
MSG_HELP_ogIsSyncImage="Comprueba si la imagen es sincronizable."
MSG_HELP_ogIsVirtualMachine=""
MSG_HELP_ogIsWritable="Comprueba si un sistema de archivos está montado con permiso de escritura."
MSG_HELP_ogLinuxBootParameters="Devuelve los parámetros de arranque de un sistema operativo Linux instalado."
MSG_HELP_ogListHardwareInfo="Lista el inventario de dispositivos del cliente."
MSG_HELP_ogListLogicalPartitions=""
MSG_HELP_ogListPartitions="Lista la estructura de particiones de un disco."
MSG_HELP_ogListPrimaryPartitions=""
MSG_HELP_ogListRegistryKeys="Lista los nombres de las subclaves incluidas en una clave del registro de Windows."
MSG_HELP_ogListRegistryValues="Lista los nombres de los valores incluidos en una clave del registro de Windows."
MSG_HELP_ogListSoftware="Lista el inventario de programas instalados en un sistema operativo."
MSG_HELP_ogLock="Bloquea una partición para operación de uso exclusivo."
MSG_HELP_ogLockDisk="Bloquea un disco para operación de uso exclusivo."
MSG_HELP_ogLockImage="Bloquea una imagen para operación de uso exclusivo."
MSG_HELP_ogLockPartition=MSG_HELP_ogLock
MSG_HELP_ogMakeChecksumFile="Almacena la suma de comprobación de un fichero."
MSG_HELP_ogMakeDir="Crea un directorio para OpenGnsys."
MSG_HELP_ogMakeGroupDir="Crea el directorio de grupo (aula) en un repositorio."
MSG_HELP_ogMcastReceiverFile=""
MSG_HELP_ogMcastReceiverPartition=""
MSG_HELP_ogMcastRequest=""
MSG_HELP_ogMcastSendFile=""
MSG_HELP_ogMcastSendPartition=""
MSG_HELP_ogMcastSyntax=""
MSG_HELP_ogMountCache="Monta el sistema de archivos dedicado a caché local."
MSG_HELP_ogMountCdrom="Monta dispositivo óptico por defecto."
MSG_HELP_ogMountImage="Monta una imagen sincronizable"
MSG_HELP_ogMount="Monta un sistema de archivos y devuelve el punto de montaje."
MSG_HELP_ogMountFs=MSG_HELP_ogMount
MSG_HELP_ogNvramActiveEntry="Configura a activa entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramAddEntry="Crea nueva entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramDeleteEntry="Borra entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramGetCurrent="Muestra la entrada del gestor de arranque (NVRAM) que ha iniciado el equipo."
MSG_HELP_ogNvramGetNext="Muestra la entrada del gestor de arranque (NVRAM) que se utilizará en el próximo arranque."
MSG_HELP_ogNvramGetOrder="Muestra el orden de las entradas del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramGetTimeout="Muestra el tiempo de espera del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramInactiveEntry="Configura a inactiva entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramList="Lista las entradas del gestor de arranque (NVRAN) marcando con un asterisco las activas"
MSG_HELP_ogNvramPxeFirstEntry="Configura la tarjeta de red como primer arranque en la NVRAM."
MSG_HELP_ogNvramSetNext="Configura el próximo arranque con la entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramSetOrder="Configura el orden de las entradas del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramSetTimeout="Configura el tiempo de espera del gestor de arranque (NVRAM)."
MSG_HELP_ogRaiseError="Muestra y registra mensajes de error y devuelve el código correspondiente."
MSG_HELP_ogReduceFs="Reduce el tamaño del sistema de archivos al mínimo ocupado por sus datos."
MSG_HELP_ogReduceImage="Reduce el tamaño de la imagen"
MSG_HELP_ogRefindDeleteEntry="Borra en rEFInd las entradas para el inicio en una particion."
MSG_HELP_ogRefindDefaultEntry="Configura la entrada por defecto de rEFInd."
MSG_HELP_ogRefindOgliveDefaultEntry="Configura la entrada de ogLive como la entrada por defecto de rEFInd."
MSG_HELP_ogRefindSetTheme="Asigna un tema al rEFInd."
MSG_HELP_ogRefindSetTimeOut="Define el tiempo (segundos) que se muestran las opciones de inicio de rEFInd."
MSG_HELP_ogRefindSetResolution="Define la resolución que usuará el thema del gestor de arranque rEFInd."
MSG_HELP_ogRefindInstall="Instala y configura el gestor rEFInd en la particion EFI"
MSG_HELP_ogRestoreAclImage=""
MSG_HELP_ogRestoreBootLoaderImage=""
MSG_HELP_ogRestoreDiskImage="Restaura una imagen de un disco completo."
MSG_HELP_ogRestoreEfiBootLoader="Copia el cargador de arranque de la partición de sistema a la partición EFI."
MSG_HELP_ogRestoreImage="Restaura una imagen de sistema operativo."
MSG_HELP_ogRestoreInfoImage="Restablece informacion del sistema: acl y enlaces simbolicos"
MSG_HELP_ogRestoreMbrImage="Restaura una imagen del sector de arranque (MBR)."
MSG_HELP_ogRestoreUuidPartitions="Restaura los uuid de las particiones y la tabla de particiones."
MSG_HELP_ogSaveImageInfo="Crea un fichero con la información de la imagen."
MSG_HELP_ogSetLinuxName=""
MSG_HELP_ogSetPartitionActive="Establece el número de partición activa de un disco."
MSG_HELP_ogSetPartitionId="Modifica el tipo de una partición física usando el mnemónico del tipo."
MSG_HELP_ogSetPartitionSize="Establece el tamaño de una partición."
MSG_HELP_ogSetPartitionType="Modifica el identificador de tipo de una partición física."
MSG_HELP_ogSetRegistryValue="Asigna un dato a un valor del registro de Windows."
MSG_HELP_ogSetWindowsName="Asigna el nombre del cliente en el registro de Windows."
MSG_HELP_ogSetWinlogonUser="Asigna el nombre de usuario por defecto para el gestor de entrada de Windows."
MSG_HELP_ogSyncCreate="Sincroniza los datos de la particion a la imagen"
MSG_HELP_ogSyncRestore="Sincroniza los datos de la imagen a la particion"
MSG_HELP_ogTorrentStart=""
MSG_HELP_ogTypeToId="Devuelve el identificador asociado al mnemónico de tipo de partición."
MSG_HELP_ogUcastReceiverPartition=""
MSG_HELP_ogUcastSendFile=""
MSG_HELP_ogUcastSendPartition=""
MSG_HELP_ogUcastSyntax=""
MSG_HELP_ogUnhidePartition="Hace visible una partición de Windows."
MSG_HELP_ogUninstallLinuxClient="Desinstala el cliente OpenGnSys en un sistema operativo Linux."
MSG_HELP_ogUninstallWindowsClient="Desinstala el cliente OpenGnSys en un sistema operativo Windows."
MSG_HELP_ogUnlock="Desbloquea una partición tras finalizar una operación de uso exclusivo."
MSG_HELP_ogUnlockDisk="Desbloquea un disco tras finalizar una operación de uso exclusivo."
MSG_HELP_ogUnlockImage="Desbloquea una imagen tras finalizar una operación de uso exclusivo."
MSG_HELP_ogUnlockPartition=MSG_HELP_ogUnlock
MSG_HELP_ogUnmountAll="Desmonta todos los sistemas de archivos."
MSG_HELP_ogUnmountCache="Desmonta el sistema de archivos de caché local."
MSG_HELP_ogUnmount="Desmonta un sistema de archivos."
MSG_HELP_ogUnmountImage="Desmonta la imagen"
MSG_HELP_ogUnmountFs=MSG_HELP_ogUnmount
MSG_HELP_ogUnsetDirtyBit=""
MSG_HELP_ogUpdateCacheIsNecesary="Comprueba si es necesario actualizar una archivo en la cache local."
MSG_HELP_ogUpdatePartitionTable="Actualiza informacion tabla particiones del disco"
MSG_HELP_ogUuidChange="Reemplaza el UUID de un sistema de ficheros."
MSG_HELP_ogWaitSyncImage=""
MSG_HELP_ogWindowsBootParameters=""
MSG_HELP_ogWindowsRegisterPartition=""
# Scripts
MSG_HELP_configureOs="Post-configura de arranque del sistema"
MSG_HELP_createBaseImage="Genera imagen basica de la particion"
MSG_HELP_createDiffImage="Genera imagen diferencial de la particion respecto a la imagen basica"
MSG_HELP_installOfflineMode="Prepara el equipo cliente para el modo offline."
MSG_HELP_partclone2sync="Convierte imagen de partclone en imagen sincronizable."
MSG_HELP_restoreBaseImage="Restaura una imagen basica en una particion"
MSG_HELP_restoreDiffImage="Restaura una imagen diferencial en una particion"
MSG_HELP_updateCache="Realiza la actualizacion de la cache"
# Mensajes de descripción breve de la interfaz.
MSG_INTERFACE_START="[START Interface] Ejecutar comando: "
MSG_INTERFACE_END="[END Interface] Comando terminado con este código: "
# Mensajes de scripts.
MSG_SCRIPTS_START=" INICIO scripts : "
MSG_SCRIPTS_END=" FIN scripts: "
MSG_SCRIPTS_TASK_END="Fin de la tarea"
MSG_SCRIPTS_TASK_SLEEP="Esperando para iniciar"
MSG_SCRIPTS_TASK_START="Iniciando"
MSG_SCRIPTS_TASK_ERR="Error"
# Script createImage.
MSG_SCRIPTS_FILE_RENAME=" Renombrar fichero-imagen previo: "
MSG_SCRIPTS_CREATE_SIZE=" Calcular espacio (KB) requerido para almacenarlo y el disponible: "
# Script updateCache.
MSG_SCRIPTS_UPDATECACHE_DOUPDATE="comprovar si es necessari actualitzar el fitxer imatge"
MSG_SCRIPTS_UPDATECACHE_CHECKSIZECACHE="Comprobar que el tamaño de la cache es mayor que el fichero a descargar."
# Script updateCache: para las imágenes sincronizadas tipo dir.
MSG_SCRIPTS_UPDATECACHE_CHECKSIZEDIR="Calculamos el tamaño de la imagen."
MSG_SCRIPTS_UPDATECACHE_CHECKSIZEIMG="Comprobamos si hay que la imagen del repositorio es mayor que la de la cache."
MSG_SCRIPTS_UPDATECACHE_IFNOTCACHEDO="Comprobar el espacio libre de la cache y actuar según engine.cfg"
MSG_SCRIPTS_UPDATECACHE_CHECKMCASTSESSION="Comprobando sesion multicast: ServidorMcast:PuertoDatos"
# interface sustituye temporalmente al scritp restore
MSG_SCRIPTS_CHECK_ENGINE="Analizar proceso a realizar según engine.cfg"
MSG_SCRIPTS_MULTICAST_PRECHECK_PORT="Determinar puerto principal y auxiliar multicast."
MSG_SCRIPTS_MULTICAST_CHECK_PORT="Comprobar puertos de sesion y datos"
MSG_SCRIPTS_MULTICAST_REQUEST_PORT="Solicitar la apertura: "
MSG_SCRIPTS_OS_CONFIGURE="Iniciar la configuracion del sistema restaurado"
# TIME MESSAGES
MSG_SCRIPTS_TIME_TOTAL="tiempo total del proceso"
MSG_SCRIPTS_TIME_PARTIAL="tiempo parcial del subproceso"
# HTTPLOG
MSG_HTTPLOG_NOUSE="No apague este ordenador por favor"
# Mensajes sincronizadas
MSG_SYNC_RESIZE="Redimensiona la imagen al tamaño necesario"
MSG_SYNC_RESTORE="Trae el listado ficheros y baja la imagen"
MSG_SYNC_DELETE="Diferencial: Borra archivos antiguos"
MSG_SYNC_SLEEP="Espera que se monte/reduzca la imagen"
# Mensajes sincronizadas complementarios a errores
MSG_SYNC_DIFFERENTFS="El sistema de ficheros de destino no coincide con el de la imagen"
MSG_SYNC_EXTENSION="Las extensiones de la imagenes deben ser img o diff"
MSG_SYNC_NOCHECK="La imagen esta montada por otro proceso, no podemos comprobarla"
MSG_RESTORE="Restaura la imagen en"

View File

@ -0,0 +1,387 @@
#!/usr/bin/python3
# English language file.
#@version 1.1.0
#@author Jose Miguel Hernandez - Universidad de Salamanca
#@date 2018-03-01
# Error messages.
MSG_ERR_GENERIC="Undefined unknown error"
MSG_ERR_FORMAT="Wrong execution format"
MSG_ERR_OUTOFLIMIT="Out of range or invalid value"
MSG_ERR_NOTFOUND="File or device not found"
MSG_ERR_PARTITION="Unknown or wrong partition"
MSG_ERR_LOCKED="Resource locked by exclusive use operation"
MSG_ERR_CACHE="Local cache error"
MSG_ERR_NOGPT="Current disk does not include GPT partition"
MSG_ERR_REPO="Failed when mounting images repository"
MSG_ERR_NOMSDOS="Current disk does not include MSDOS partition"
MSG_ERR_FILESYS="Unknown or unmountable file system"
MSG_ERR_NOTOS="Cannot detect or boot OS"
MSG_ERR_IMAGE="Cannot create or restore a system image"
MSG_ERR_IMAGEFILE="Image file corrupt or of other partclone version"
MSG_ERR_NOTEXEC="Non executable program or function"
MSG_ERR_NOTWRITE="Write access denied"
MSG_ERR_NOTCACHE="No client cache partition"
MSG_ERR_NOTUEFI="UEFI isn't active"
MSG_ERR_NOTBIOS="BIOS legacy isn't active"
MSG_ERR_CACHESIZE="Not enough space in local or remote cache"
MSG_ERR_REDUCEFS="Error when reducing file system"
MSG_ERR_EXTENDFS="Error when expanding file system"
MSG_ERR_IMGSIZEPARTITION="Backup error: Partition smaller than image"
MSG_ERR_UPDATECACHE="Error when running `updateCache´ command"
MSG_ERR_UCASTSYNTAXT="Error when generating Unicast transfer syntax"
MSG_ERR_UCASTSENDPARTITION="Error when sending a Unicast partition"
MSG_ERR_UCASTSENDFILE="Error when sending a Unicast file"
MSG_ERR_UCASTRECEIVERPARTITION="Error when receiving an Unicast partition"
MSG_ERR_UCASTRECEIVERFILE="Error when receiving an Unicast file"
MSG_ERR_MCASTSYNTAXT="Error when generating Multicast transfer syntax"
MSG_ERR_MCASTSENDFILE="Error when sending Multicast file"
MSG_ERR_MCASTRECEIVERFILE="Error when receiving Multicast file"
MSG_ERR_MCASTSENDPARTITION="Error when sending Multicast partition"
MSG_ERR_MCASTRECEIVERPARTITION="Error when receiving Multicast partition "
MSG_ERR_PROTOCOLJOINMASTER="Error when connecting Unicast/Multicast session to Master"
MSG_ERR_DONTFORMAT="Formatting Error"
MSG_ERR_DONTMOUNT_IMAGE="Error when mounting/reducing image"
MSG_ERR_DONTUNMOUNT_IMAGE="Error when unmounting image"
MSG_ERR_DONTSYNC_IMAGE="Unsynchronizable image"
MSG_ERR_NOTDIFFERENT="Basic image identical to partition"
MSG_ERR_SYNCHRONIZING="Synchronizing error, it may affect image creation/restoration process"
# Warning messages.
MSG_DONTUSE="DO NOT USE"
MSG_DONTMOUNT="Unmounted file system"
MSG_DONTUNMOUNT="Cannot unmount file system or it isn't mounted"
MSG_MOUNT="File system already mounted"
MSG_MOUNTREADONLY="Read-only file system mounted"
MSG_OBSOLETE="OBSOLETE"
# Auxiliary help messages.
MSG_64BIT="64-bit"
MSG_DISK="Disk"
MSG_ERROR="Error"
MSG_EXAMPLE="Example"
MSG_FORMAT="Format"
MSG_FUNCTION="Function"
MSG_HARDWAREINVENTORY="Hardware inventory"
MSG_IMAGE="Image"
MSG_INSTALLED="Installed"
MSG_NOCACHE="No local cache"
MSG_NOEXTENDED="No extended partition"
MSG_PARTITION="Partition"
MSG_PROTOCOL="Protocol"
MSG_RESERVEDVALUE="Reserved value"
MSG_SEE="See"
MSG_UNKNOWN="Unknown"
MSG_WARNING="Warning"
# Boot process messages.
MSG_DETECTLVMRAID="Detecting LVM and RAID meta-devices."
MSG_ERRBOOTMODE=f"{MSG_ERROR}: Unknown boot mode."
MSG_LAUNCHCLIENT="Launching client browser."
MSG_LOADAPI="Loading cloning-engine functions."
MSG_LOADMODULES="Loading kernel modules."
MSG_MAKELINKS="Creating symbolic links."
MSG_MOUNTREPO="Mounting repository using %s by %s mode."
MSG_OFFLINEMODE="Off-line boot mode."
MSG_OTHERSERVICES="Starting client complementary services."
MSG_POWEROFFCONF="Defining power-saving parameters."
# Default menu messages.
MSG_BOOT="Boot"
MSG_DUPLEX="Duplex"
MSG_HOSTNAME="Hostname"
MSG_IPADDR="IP Address"
MSG_MACADDR="MAC Address"
MSG_MENUTITLE="Options menu"
MSG_POWEROFF="Shutdown computer"
MSG_SPEED="Speed"
# API functions messages.
MSG_HELP_ogAclFilter="Draws ACL files from differential image."
MSG_HELP_ogAddCmd="Adds commands to file created by ogInstalMiniSetup."
MSG_HELP_ogAddRegistryKey="Adds new Windows registry key."
MSG_HELP_ogAddRegistryValue="Adds new Windows registry value."
MSG_HELP_ogAddToLaunchDaemon=""
MSG_HELP_ogBoot="Boots installed OS."
MSG_HELP_ogBootLoaderDeleteEntry=MSG_DONTUSE
MSG_HELP_ogBootLoaderHidePartitions=MSG_DONTUSE
MSG_HELP_ogBootMbrGeneric=""
MSG_HELP_ogBootMbrXP=""
MSG_HELP_ogBurgDefaultEntry="Sets default Burg entry."
MSG_HELP_ogBurgDeleteEntry="Deletes partition start-entries from MBR BURG."
MSG_HELP_ogBurgHidePartitions="Sets MBR Burg to hide non starting windows partitions. Allows you to select a partition that will not be hidden (e.g. for data)."
MSG_HELP_ogBurgInstallMbr="Installs BURG boot-loader on 1st HD MBR."
MSG_HELP_ogBurgOgliveDefaultEntry="Sets ogLive input as default Burg input."
MSG_HELP_ogCalculateChecksum="Calculates file checksum."
MSG_HELP_ogCalculateFullChecksum="Calculates file full checksum"
MSG_HELP_ogChangeRepo="Changes repository for remote resource: images."
MSG_HELP_ogCheckFs="Checks file system consistence."
MSG_HELP_ogCheckIpAddress=""
MSG_HELP_ogCheckProgram=""
MSG_HELP_ogCheckStringInGroup=""
MSG_HELP_ogCheckStringInReg=""
MSG_HELP_ogCheckSyncImage="Displays image contents to check it."
MSG_HELP_ogCleanLinuxDevices=""
MSG_HELP_ogCleanOs="Deletes OS unnecessary files."
MSG_HELP_ogCompareChecksumFiles="Compares if the checksums match."
MSG_HELP_ogConfigureFstab=""
MSG_HELP_ogConfigureOgagent="Sets OS new agent: OGAgent."
MSG_HELP_ogCopyFile="Copies file to another storage unit ."
MSG_HELP_ogCreateBootLoaderImage=""
MSG_HELP_ogCreateCache="Saves space for cache partition at the end of disk."
MSG_HELP_ogCreateDiskImage="Creates exact image from local disk."
MSG_HELP_ogCreateFileImage="Creates/Resizes synchronized image file."
MSG_HELP_ogCreateGptPartitions=""
MSG_HELP_ogCreateImage="Creates exact image from local installed OS."
MSG_HELP_ogCreateImageSyntax=""
MSG_HELP_ogCreateInfoImage="Creates image content information."
MSG_HELP_ogCreateMbrImage="Creates MBR image."
MSG_HELP_ogCreatePartitions="Creates disk partition table."
MSG_HELP_ogCreatePartitionTable="Creates partition table, if necessary."
MSG_HELP_ogCreateTorrent=""
MSG_HELP_ogCopyEfiBootLoader="Copy the boot loader from the EFI partition to system partition."
MSG_HELP_ogDeleteCache="Deletes local cache partition."
MSG_HELP_ogDeleteFile="Deletes file from storage."
MSG_HELP_ogDeletePartitionTable="Deletes disk table partition"
MSG_HELP_ogDeleteRegistryKey="Deletes empty Windows registry key."
MSG_HELP_ogDeleteRegistryValue="Deletes Windows registry value."
MSG_HELP_ogDeleteTree="Deletes directory tree."
MSG_HELP_ogDevToDisk="Returns disk or partition ordinal number for device file path."
MSG_HELP_ogDiskToDev="Returns device file path for disk or partition ordinal number."
MSG_HELP_ogDomainScript=""
MSG_HELP_ogEcho="Displays and log messages."
MSG_HELP_ogExecAndLog="Runs and logs command"
MSG_HELP_ogExtendFs="Expands file system size to partition maximum."
MSG_HELP_ogFindCache="Shows local cache reserved partition."
MSG_HELP_ogFixBootSector=""
MSG_HELP_ogFormatCache="Formats (clears) local cache."
MSG_HELP_ogFormat="Formats file system."
MSG_HELP_ogFormatFs=MSG_HELP_ogFormat
MSG_HELP_ogGetArch="Returns client architecture."
MSG_HELP_ogGetCacheSize="Returns local cache partition size."
MSG_HELP_ogGetCacheSpace="Returns maximum available space that can be reserved for local cache partition."
MSG_HELP_ogGetCaller="Returns program or function which is calling to current one"
MSG_HELP_ogGetDiskSize="Returns disk size."
MSG_HELP_ogGetDiskType="Returns disk type."
MSG_HELP_ogGetFreeSize=""
MSG_HELP_ogGetFsSize="Returns file system size."
MSG_HELP_ogGetFsType="Returns file system type."
MSG_HELP_ogGetGroupDir="Returns default directory path for client group."
MSG_HELP_ogGetGroupName="Returns client group name."
MSG_HELP_ogGetHivePath="Returns full path of file from Windows registry section."
MSG_HELP_ogGetHostname="Returns local hostname."
MSG_HELP_ogGetImageCompressor="Returns image compression tool."
MSG_HELP_ogGetImageInfo="Displays monolithic image information: cloning; compressor; file system; size(KB)."
MSG_HELP_ogGetImageProgram="Returns used program to create image."
MSG_HELP_ogGetImageSize="Returns system image size."
MSG_HELP_ogGetImageType="Returns image file system."
MSG_HELP_ogGetIpAddress="Returns client IP."
MSG_HELP_ogGetLastSector="Returns last available sector from disk or partition."
MSG_HELP_ogGetMacAddress="Returns client Ethernet address."
MSG_HELP_ogGetMountImageDir="Returns mounting directory of image."
MSG_HELP_ogGetMountPoint="Returns directory of local file system mount point."
MSG_HELP_ogGetNetInterface=""
MSG_HELP_ogGetOsType="Returns installed OS type."
MSG_HELP_ogGetOsUuid="Returns OS UUID"
MSG_HELP_ogGetOsVersion="Returns OS version."
MSG_HELP_ogGetParentPath="Returns full path of OpenGnsys system file parent directory."
MSG_HELP_ogGetPartitionActive="Returns disk active partition."
MSG_HELP_ogGetPartitionId="Returns partition type ID."
MSG_HELP_ogGetPartitionSize="Returns partition size."
MSG_HELP_ogGetPartitionsNumber="Returns disk partitions number."
MSG_HELP_ogGetPartitionTableType="Returns disk partition table type."
MSG_HELP_ogGetPartitionType="Returns partition type."
MSG_HELP_ogGetPath="Returns full path of OpenGnsys system file."
MSG_HELP_ogGetRegistryValue="Returns data from Windows registry value."
MSG_HELP_ogGetRepoIp="Returns OpenGnsys Repository IP address ."
MSG_HELP_ogGetSerialNumber="Returns host serial number."
MSG_HELP_ogGetServerIp="Returns main OpenGnsys Server IP address."
MSG_HELP_ogGetSizeParameters="Returns file system data size, required space for image and if it fits in the chosen repository."
MSG_HELP_ogGetWindowsName="Returns saved client name on Windows registry."
MSG_HELP_ogGrubAddOgLive="Adds MBR grub an entry calling Opengnsys client."
MSG_HELP_ogGrubDefaultEntry="Sets GRUB default entry."
MSG_HELP_ogGrubDeleteEntry="Deletes partition start entries on MBR grub."
MSG_HELP_ogGrubHidePartitions="Sets MBR grub to hide non starting Windows partitions. Allows you to select a partition that will not be hidden (e.g. for data)."
MSG_HELP_ogGrubInstallMbr="Installs GRUB boot loader on 1st HD MBR"
MSG_HELP_ogGrubInstallPartition="Installs GRUB boot loader on BootSector"
MSG_HELP_ogGrubOgliveDefaultEntry="Sets ogLive entry as default GRUB entry."
MSG_HELP_ogGrubSecurity="Configures user and password for change the menu entries of grub."
MSG_HELP_ogGrubUefiConf="Generates the grub.cfg file of the EFI partition."
MSG_HELP_ogHelp="Shows functions help messages."
MSG_HELP_ogHidePartition="Hides Windows partition."
MSG_HELP_ogIdToType="Returns partition type identifier."
MSG_HELP_ogInstallFirstBoot="Creates file to run on first Windows boot."
MSG_HELP_ogInstallLaunchDaemon="Installs file to run on MACos boot."
MSG_HELP_ogInstallLinuxClient=MSG_OBSOLETE
MSG_HELP_ogInstallMiniSetup="Installs file to run on Windows boot."
MSG_HELP_ogInstallRunonce="Creates file to run on admin-user Windows boot."
MSG_HELP_ogInstallWindowsClient=MSG_OBSOLETE
MSG_HELP_ogIsFormated="Checks file system if formatted."
MSG_HELP_ogIsImageLocked="Checks image if blocked by exclusive use operation."
MSG_HELP_ogIsLocked="Checks partition or disk if blocked by exclusive use operation."
MSG_HELP_ogIsDiskLocked="Checks disk if blocked by exclusive use operation."
MSG_HELP_ogIsMounted="Checks file system if mounted."
MSG_HELP_ogIsNewerFile="Checks if one file is newer (or has been modified later) than another one."
MSG_HELP_ogIsPartitionLocked=MSG_HELP_ogIsLocked
MSG_HELP_ogIsRepoLocked=""
MSG_HELP_ogIsSyncImage="Checks image if synchronizable."
MSG_HELP_ogIsVirtualMachine="Checks if client is a virtual machine"
MSG_HELP_ogIsWritable="Checks if mounted file system has write permissions."
MSG_HELP_ogLinuxBootParameters="Returns installed Linux boot parameters."
MSG_HELP_ogListHardwareInfo="Lists the client hardware inventory."
MSG_HELP_ogListLogicalPartitions="Lists disk logic partitions."
MSG_HELP_ogListPartitions="Lists disk partitions table."
MSG_HELP_ogListPrimaryPartitions="Lists disk primary partitions"
MSG_HELP_ogListRegistryKeys="Lists sub-keys names included on a Windows registry key."
MSG_HELP_ogListRegistryValues="Lists value names included on a Windows registry key."
MSG_HELP_ogListSoftware="Lists OS installed programs inventory."
MSG_HELP_ogLock="Blocks partition for exclusive use operation."
MSG_HELP_ogLockDisk="Blocks disk for exclusive use operation."
MSG_HELP_ogLockImage="Blocks image for exclusive use operation."
MSG_HELP_ogLockPartition=MSG_HELP_ogLock
MSG_HELP_ogMakeChecksumFile="Stores file checksum."
MSG_HELP_ogMakeDir="Makes OpenGnsys directory."
MSG_HELP_ogMakeGroupDir="Makes group (lab) directory on repository."
MSG_HELP_ogMcastReceiverFile=""
MSG_HELP_ogMcastReceiverPartition=""
MSG_HELP_ogMcastRequest=""
MSG_HELP_ogMcastSendFile=""
MSG_HELP_ogMcastSendPartition=""
MSG_HELP_ogMcastSyntax=""
MSG_HELP_ogMountCache="Mounts cache file system."
MSG_HELP_ogMountCdrom="Mounts default optical drive."
MSG_HELP_ogMountImage="Mounts synchronizable image"
MSG_HELP_ogMount="Mounts file system and returns mount point."
MSG_HELP_ogMountFs=MSG_HELP_ogMount
MSG_HELP_ogNvramActiveEntry="Sets active a bootloader (NVRAM) entry."
MSG_HELP_ogNvramAddEntry="Creates new entry in bootloader (NVRAM)."
MSG_HELP_ogNvramDeleteEntry="Deletes a bootloader (NVRAM) entry."
MSG_HELP_ogNvramGetCurrent="Displays the bootloader (NVRAM) entry that was started by the computer."
MSG_HELP_ogNvramGetNext="Displays the bootloader (NVRAM) entry for the boot next."
MSG_HELP_ogNvramGetOrder="Displays the bootloader (NVRAM) entries order."
MSG_HELP_ogNvramGetTimeout="Displays the bootloader (NVRAM) timeout."
MSG_HELP_ogNvramInactiveEntry="Sets inactive bootloader (NVRAM) entry."
MSG_HELP_ogNvramList="Lists bootloader (NVRAM) entries, by staring actives ones."
MSG_HELP_ogNvramPxeFirstEntry="Set the network as the NVRAM first boot."
MSG_HELP_ogNvramSetNext="Set the bootloader (NVRAM) entry for the boot next."
MSG_HELP_ogNvramSetOrder="Sets the bootloader (NVRAM) entries order."
MSG_HELP_ogNvramSetTimeout="Sets the bootloader (NVRAM) timeout."
MSG_HELP_ogRaiseError="Displays and registers error messages and returns code."
MSG_HELP_ogReduceFs="Reduces file system size to minimum."
MSG_HELP_ogReduceImage="Reduces image size."
MSG_HELP_ogRefindDeleteEntry="Deletes the menu entry of a partition in rEFInd."
MSG_HELP_ogRefindDefaultEntry="Configures default menu entry in rEFInd."
MSG_HELP_ogRefindOgliveDefaultEntry="Configures ogLive menu entry as default menu entry in rEFInd."
MSG_HELP_ogRefindSetTheme="Configures rEFInd's theme."
MSG_HELP_ogRefindSetTimeOut="Defines the time that rEFInd shows the menu."
MSG_HELP_ogRefindSetResolution="Defines the resolucion of rEFInd's theme."
MSG_HELP_ogRefindInstall="Installs and configures rEFInd boot loader in ESP."
MSG_HELP_ogRestoreAclImage="Restores Windows ACL (Inf. must be on /tmp)."
MSG_HELP_ogRestoreBootLoaderImage=""
MSG_HELP_ogRestoreDiskImage="Restores disk image."
MSG_HELP_ogRestoreEfiBootLoader="Copy the boot loader from the system partition to the EFI partition."
MSG_HELP_ogRestoreImage="Restore OS image."
MSG_HELP_ogRestoreInfoImage="Restores system information: ACL and symbolic links"
MSG_HELP_ogRestoreMbrImage="Restores boot sector image (MBR)."
MSG_HELP_ogRestoreUuidPartitions="Restores UUID of partitions and partition table."
MSG_HELP_ogSaveImageInfo="Creates the image information file."
MSG_HELP_ogSetLinuxName=""
MSG_HELP_ogSetPartitionActive="Sets active partition number of disk."
MSG_HELP_ogSetPartitionId="Changes partition ID using mnemonic."
MSG_HELP_ogSetPartitionSize="Sets partition size."
MSG_HELP_ogSetPartitionType="Changes partition type ID."
MSG_HELP_ogSetRegistryValue="Assigns data to a Windows registry values."
MSG_HELP_ogSetWindowsName="Assigns client name to Windows registry."
MSG_HELP_ogSetWinlogonUser="Assigns Windows default user name to Windows input manager."
MSG_HELP_ogSyncCreate="Synchronizes partition data to image"
MSG_HELP_ogSyncRestore="Synchronize image data to partition"
MSG_HELP_ogTorrentStart=""
MSG_HELP_ogTypeToId="Returns the ID of partition type mnemonic."
MSG_HELP_ogUcastReceiverPartition=""
MSG_HELP_ogUcastSendFile=""
MSG_HELP_ogUcastSendPartition=""
MSG_HELP_ogUcastSyntax=""
MSG_HELP_ogUnhidePartition="Unhides Windows partition."
MSG_HELP_ogUninstallLinuxClient="Uninstalls old OpenGnSys agent from Linux OS."
MSG_HELP_ogUninstallWindowsClient="Uninstalls oldOpenGnSys agent from Windows OS."
MSG_HELP_ogUnlock="Unlocks partition after exclusive use operation."
MSG_HELP_ogUnlockDisk="Unlocks disk after exclusive use operation."
MSG_HELP_ogUnlockImage="Unlocks image after exclusive use operation."
MSG_HELP_ogUnlockPartition=MSG_HELP_ogUnlock
MSG_HELP_ogUnmountAll="Unmounts all file systems."
MSG_HELP_ogUnmountCache="Unmounts cache file system."
MSG_HELP_ogUnmountImage="Unmounts image"
MSG_HELP_ogUnmount="Unmounts file system."
MSG_HELP_ogUnmountFs=MSG_HELP_ogUnmount
MSG_HELP_ogUnsetDirtyBit=""
MSG_HELP_ogUpdateCacheIsNecesary="Checks if necessary file update in local cache."
MSG_HELP_ogUpdatePartitionTable="Updates disk partition table info "
MSG_HELP_ogUuidChange="Replaces the filesystem UUID"
MSG_HELP_ogWaitSyncImage=""
MSG_HELP_ogWindowsBootParameters=""
MSG_HELP_ogWindowsRegisterPartition=""
# Scripts
MSG_HELP_configureOs="Post-configure system boot"
MSG_HELP_createBaseImage="Create partition basic image"
MSG_HELP_createDiffImage="Create partition differential image from basic image"
MSG_HELP_installOfflineMode="Prepare client for off-line mode."
MSG_HELP_partclone2sync="Turn part-clone image into synchronizable image."
MSG_HELP_restoreBaseImage="Restore basic image into partition"
MSG_HELP_restoreDiffImage="Restore differential image into partition"
MSG_HELP_updateCache="Update cache"
# INTERFACE functions messages.
MSG_INTERFACE_START="[START Interface] Run command: "
MSG_INTERFACE_END="[END Interface] Command finished with this code: "
# SCRIPTS messages.
MSG_SCRIPTS_START=" START scripts: "
MSG_SCRIPTS_END=" END scripts: "
MSG_SCRIPTS_TASK_END="End of task"
MSG_SCRIPTS_TASK_SLEEP="Waiting to start"
MSG_SCRIPTS_TASK_START="Starting"
MSG_SCRIPTS_TASK_ERR="Error"
# createImage script
MSG_SCRIPTS_FILE_RENAME="Rename previous image-file: "
MSG_SCRIPTS_CREATE_SIZE="Check required and available storing space(KB): "
# updateCache script
MSG_SCRIPTS_UPDATECACHE_DOUPDATE="Check if it is necessary to update image file"
MSG_SCRIPTS_UPDATECACHE_CHECKSIZECACHE="Check if Cache size is bigger than image file size."
# Script updateCache: for dir synchronized images .
MSG_SCRIPTS_UPDATECACHE_CHECKSIZEDIR="Calculate image size."
MSG_SCRIPTS_UPDATECACHE_CHECKSIZEIMG="Check if repository image file size is bigger than Cache size."
MSG_SCRIPTS_UPDATECACHE_IFNOTCACHEDO="Check free Cache and apply engine.cfg"
MSG_SCRIPTS_UPDATECACHE_CHECKMCASTSESSION="Checking Multicast Session McastServer:DataPort"
# interface temporarily replaces restore script
MSG_SCRIPTS_CHECK_ENGINE="Analyze process to carry out according to engine.cfg"
MSG_SCRIPTS_MULTICAST_PRECHECK_PORT="Check main and auxiliary Multicast port."
MSG_SCRIPTS_MULTICAST_CHECK_PORT="Check session and data ports"
MSG_SCRIPTS_MULTICAST_REQUEST_PORT="Request Multicast port opening: "
MSG_SCRIPTS_OS_CONFIGURE="Start restored system setting"
# TIME MESSAGES
MSG_SCRIPTS_TIME_TOTAL="Total process time"
MSG_SCRIPTS_TIME_PARTIAL="Partial sub-process time"
# HTTPLOG
MSG_HTTPLOG_NOUSE="PLEASE DO NOT TURN OFF THIS COMPUTER"
# Messages for synchronized images (complementary to errors)
MSG_SYNC_RESIZE="Resize image to necessary size"
MSG_SYNC_RESTORE="Get files list and download image"
MSG_SYNC_DELETE="Differential: Delete old files"
MSG_SYNC_SLEEP="Wait for mounting/reducing image"
# Messages for synchronized images (complementary to errors)
MSG_SYNC_DIFFERENTFS="Destination file system does not match image"
MSG_SYNC_EXTENSION="Image extension must be img or diff"
MSG_SYNC_NOCHECK="Image mounted by another process. Cannot verify it"
MSG_RESTORE="Restore image on "

View File

@ -0,0 +1,387 @@
#!/usr/bin/python3
# Fichero de idioma: español.
#@version 1.1.1
#@author
# Mensajes de error.
MSG_ERR_GENERIC="Error imprevisto no definido"
MSG_ERR_FORMAT="Formato de ejecución incorrecto"
MSG_ERR_OUTOFLIMIT="Valor fuera de rango o no válido"
MSG_ERR_NOTFOUND="Fichero o dispositivo no encontrado"
MSG_ERR_PARTITION="Partición errónea o desconocida"
MSG_ERR_LOCKED="Recurso bloqueado por operación de uso exclusivo"
MSG_ERR_CACHE="Error en partición de caché local"
MSG_ERR_NOGPT="El disco indicado no contiene una partición GPT"
MSG_ERR_REPO="Error al montar el repositorio de imágenes"
MSG_ERR_NOMSDOS="El disco indicado no contiene una partición MSDOS"
MSG_ERR_FILESYS="Sistema de archivos desconocido o no se puede montar"
MSG_ERR_NOTOS="Sistema operativo no detectado o no se puede iniciar"
MSG_ERR_IMAGE="No se puede crear o restaurar una image de sistema"
MSG_ERR_IMAGEFILE="Archivo de imagen corrupto o de otra versión de partclone"
MSG_ERR_NOTEXEC="Programa o función no ejecutable"
MSG_ERR_NOTWRITE="No hay acceso de escritura"
MSG_ERR_NOTCACHE="No existe partición caché en el cliente"
MSG_ERR_NOTUEFI="La interfaz UEFI no está activa"
MSG_ERR_NOTBIOS="La interfaz BIOS Legacy no está activa"
MSG_ERR_CACHESIZE="El espacio de la caché local o remota no es suficiente"
MSG_ERR_REDUCEFS="Error al reducir el sistema de archivos"
MSG_ERR_EXTENDFS="Error al expandir el sistema de archivos"
MSG_ERR_IMGSIZEPARTITION="Error al restaurar: Partición mas pequeña que la imagen"
MSG_ERR_UPDATECACHE="Error al realizar el comando updateCache"
MSG_ERR_UCASTSYNTAXT="Error en la generación de sintaxis de transferenica Unicast"
MSG_ERR_UCASTSENDPARTITION="Error en envío Unicast de una partición"
MSG_ERR_UCASTSENDFILE="Error en envío Unicast de un fichero"
MSG_ERR_UCASTRECEIVERPARTITION="Error en la recepción Unicast de una partición"
MSG_ERR_UCASTRECEIVERFILE="Error en la recepción Unicast de un fichero"
MSG_ERR_MCASTSYNTAXT="Error en la generación de sintaxis de transferenica Multicast"
MSG_ERR_MCASTSENDFILE="Error en envío Multicast de un fichero"
MSG_ERR_MCASTRECEIVERFILE="Error en la recepción Multicast de un fichero"
MSG_ERR_MCASTSENDPARTITION="Error en envío Multicast de una partición"
MSG_ERR_MCASTRECEIVERPARTITION="Error en la recepción Multicast de un fichero"
MSG_ERR_PROTOCOLJOINMASTER="Error en la conexión de una sesión Unicast|Multicast con el Master"
MSG_ERR_DONTFORMAT="Error al formatear"
MSG_ERR_DONTMOUNT_IMAGE="Error al montar/reducir la imagen"
MSG_ERR_DONTUNMOUNT_IMAGE="Error al desmontar la imagen"
MSG_ERR_DONTSYNC_IMAGE="Imagen no sincronizable"
MSG_ERR_NOTDIFFERENT="No se detectan diferencias entre la imagen básica y la partición"
MSG_ERR_SYNCHRONIZING="Error al sincronizar, puede afectar la creacion|restauracion de la imagen"
# Mensajes de avisos.
MSG_DONTMOUNT="Sistema de archivos no montado"
MSG_DONTUSE="NO USAR"
MSG_DONTUNMOUNT="El sistema de archivos no se puede desmontar o no está montado"
MSG_MOUNT="Sistema de archivos montado"
MSG_MOUNTREADONLY="Sistema de archivos montado solo de lectura"
MSG_OBSOLETE="EN DESUSO"
# Mensajes complementarios para las ayudas.
MSG_64BIT="64 bits"
MSG_DISK="disco"
MSG_ERROR="Error"
MSG_EXAMPLE="Ejemplo"
MSG_FORMAT="Formato"
MSG_FUNCTION="Función"
MSG_HARDWAREINVENTORY="Inventario de hardware de la máquina"
MSG_IMAGE="imagen"
MSG_INSTALLED="instalado"
MSG_NOCACHE="sin caché local"
MSG_NOEXTENDED="sin partición extendida"
MSG_PARTITION="partición"
MSG_PROTOCOL="protocolo"
MSG_RESERVEDVALUE="Valor reservado"
MSG_SEE="Ver"
MSG_UNKNOWN="Desconocido"
MSG_WARNING="Aviso"
# Mensajes del proceso de arranque.
MSG_DETECTLVMRAID="Detectar metadispositivos LVM y RAID."
MSG_ERRBOOTMODE=f"{MSG_ERROR}: Modo de arranque desconocido."
MSG_LAUNCHCLIENT="Ejecutar cliente."
MSG_LOADAPI="Cargar funciones del motor de clonación."
MSG_LOADMODULES="Cargar módulos del kernel."
MSG_MAKELINKS="Crear enlaces simbólicos."
MSG_MOUNTREPO="Montar repositorio por %s en modo %s."
MSG_OFFLINEMODE="Modo de arranque sin conexión."
MSG_OTHERSERVICES="Iniciar servicios complementarios del cliente."
MSG_POWEROFFCONF="Definir parámetros de ahorro de energía."
# Mensajes del menú por defecto.
MSG_BOOT="Iniciar"
MSG_DUPLEX="D&uacute;plex"
MSG_HOSTNAME="Equipo"
MSG_IPADDR="Direcci&oacute;n IP"
MSG_MACADDR="Direcci&oacute;n MAC"
MSG_MENUTITLE="Men&uacute; de opciones"
MSG_POWEROFF="Apagar el equipo"
MSG_SPEED="Velocidad"
# Mensajes de descripción breve de las funciones de la API.
MSG_HELP_ogAclFilter="Extrae las acl de los ficheros de la diferencial"
MSG_HELP_ogAddCmd="Añade comandos al fichero creado por la función ogInstalMiniSetup."
MSG_HELP_ogAddRegistryKey="Añade una nueva clave al registro de Windows."
MSG_HELP_ogAddRegistryValue="Añade un nuevo valor al registro de Windows."
MSG_HELP_ogAddToLaunchDaemon=""
MSG_HELP_ogBoot="Arranca un sistema operativo instalado."
MSG_HELP_ogBootLoaderDeleteEntry=MSG_DONTUSE
MSG_HELP_ogBootLoaderHidePartitions=MSG_DONTUSE
MSG_HELP_ogBootMbrGeneric=""
MSG_HELP_ogBootMbrXP=""
MSG_HELP_ogBurgDefaultEntry="Configura la entrada por defecto de Burg."
MSG_HELP_ogBurgDeleteEntry="Borra en el Burg del MBR las entradas para el inicio en una particion."
MSG_HELP_ogBurgHidePartitions="Configura el Burg del MBR para que oculte las particiones de windows que no se esten iniciando. Permite definir una partición que no se ocultará (ej: para datos)."
MSG_HELP_ogBurgInstallMbr="Instala el gestor de arranque BURG en el MBR del primer disco duro"
MSG_HELP_ogBurgOgliveDefaultEntry="Configura la entrada de ogLive como la entrada por defecto de Burg."
MSG_HELP_ogCalculateChecksum="Calcula la suma de comprobación (checksum) de un fichero."
MSG_HELP_ogCalculateFullChecksum="Calcula la suma de comprobación completa de un fichero."
MSG_HELP_ogChangeRepo="Cambia el repositorio para el recurso remoto images."
MSG_HELP_ogCheckFs="Comprueba la consistencia de un sistema de archivos."
MSG_HELP_ogCheckIpAddress=""
MSG_HELP_ogCheckProgram=""
MSG_HELP_ogCheckStringInGroup=""
MSG_HELP_ogCheckStringInReg=""
MSG_HELP_ogCheckSyncImage="Muestra el contenido de la imagen para comprobarla."
MSG_HELP_ogCleanLinuxDevices=""
MSG_HELP_ogCleanOs="Elimina los archivos que no son necesarios en el sistema operativo."
MSG_HELP_ogCompareChecksumFiles="Compara si coinciden las sumas de comprobación almacenadas de 2 ficheros."
MSG_HELP_ogConfigureFstab=""
MSG_HELP_ogConfigureOgagent="Configura el nuevo agente OGAgent para sistemas operativos."
MSG_HELP_ogCopyFile="Copia un fichero a otro almacenamiento."
MSG_HELP_ogCreateBootLoaderImage=""
MSG_HELP_ogCreateCache="Reserva espacio para la partición de caché al final del disco."
MSG_HELP_ogCreateDiskImage="Genera una imagen exacta de un disco completo."
MSG_HELP_ogCreateFileImage="Crea/redimensiona el archivo de la imagen sincronizada"
MSG_HELP_ogCreateGptPartitions=""
MSG_HELP_ogCreateImage="Genera una imagen exacta de un sistema operativo instalado localmente."
MSG_HELP_ogCreateImageSyntax=""
MSG_HELP_ogCreateInfoImage="Crea información del contenido de la imagen"
MSG_HELP_ogCreateMbrImage="Genera una imagen del sector de arranque (MBR)."
MSG_HELP_ogCreatePartitions="Define la estructura de particiones de un disco."
MSG_HELP_ogCreatePartitionTable="Genera una tabla de particiones en caso de que no sea valida."
MSG_HELP_ogCreateTorrent=""
MSG_HELP_ogCopyEfiBootLoader="Copia el cargador de arranque desde la partición EFI a la de sistema."
MSG_HELP_ogDeleteCache="Elimina la partición de caché local."
MSG_HELP_ogDeleteFile="Borra un fichero de un espacio de almacenamiento."
MSG_HELP_ogDeletePartitionTable="Elimina la tabla de particiones del disco"
MSG_HELP_ogDeleteRegistryKey="Borra una clave vacía del registro de Windows."
MSG_HELP_ogDeleteRegistryValue="Borra un valor del registro de Windows."
MSG_HELP_ogDeleteTree="Borra un árbol de directorios de un espacio de almacenamiento."
MSG_HELP_ogDevToDisk="Devuelve el nº de orden de disco o de partición correspondiente al camino del fichero de dispositivo."
MSG_HELP_ogDiskToDev="Devuelve el camino del fichero de dispositivo correspondiente al nº de orden de disco o de partición."
MSG_HELP_ogDomainScript=""
MSG_HELP_ogEcho="Muestra un mensaje en pantalla y permite registrarlo en fichero de log"
MSG_HELP_ogExecAndLog="Ejecuta un comando y registra su salida en fichero de log"
MSG_HELP_ogExtendFs="Extiende el tamaño de un sistema de archivo al máximo de su partición."
MSG_HELP_ogFindCache="Indica la partición reservada para caché local."
MSG_HELP_ogFixBootSector=""
MSG_HELP_ogFormatCache="Formatea (inicia) el sistema de caché local."
MSG_HELP_ogFormat="Formatea o reformatea un sistema de archivos."
MSG_HELP_ogFormatFs=MSG_HELP_ogFormat
MSG_HELP_ogGetArch="Devuelve el tipo de arquitectura del cliente."
MSG_HELP_ogGetCacheSize="Devuelve el tamaño de la partición de caché local."
MSG_HELP_ogGetCacheSpace="Devuelve el espacio máximo disponible que puede ser reservado para la partición de caché local."
MSG_HELP_ogGetCaller="Devuelve el programa o función que llama al actual"
MSG_HELP_ogGetDiskSize="Devuelve el tamaño del disco."
MSG_HELP_ogGetDiskType="Devuelve el mnemónico de tipo de disco."
MSG_HELP_ogGetFreeSize=""
MSG_HELP_ogGetFsSize="Devuelve el tamaño de un sistema de archivos."
MSG_HELP_ogGetFsType="Devuelve el mnemónico de tipo de sistema de archivos."
MSG_HELP_ogGetGroupDir="Devuelve el camino del directorio por defecto para el grupo del cliente."
MSG_HELP_ogGetGroupName="Devuelve el nombre del grupo al que pertenece el cliente."
MSG_HELP_ogGetHivePath="Devuelve el camino completo del fichero de una sección del registro de Windows."
MSG_HELP_ogGetHostname="Devuelve el nombre de la máquina local."
MSG_HELP_ogGetImageCompressor="Devuelve la herramienta de compresión de la imagen."
MSG_HELP_ogGetImageInfo="Muestra información sobre la imagen monolitica: clonacion:compresor:sistemaarchivos:tamañoKB."
MSG_HELP_ogGetImageProgram="Devuelve el programa usado para crear la imagen."
MSG_HELP_ogGetImageSize="Devuelve el tamaño de una imagen de sistema."
MSG_HELP_ogGetImageType="Devuelve el sistema de ficheros de la imagen."
MSG_HELP_ogGetIpAddress="Devuelve la dirección IP del cliente."
MSG_HELP_ogGetLastSector="Devuelve el último sector usable del disco o de una partición."
MSG_HELP_ogGetMacAddress="Devuelve la dirección Ethernet del cliente."
MSG_HELP_ogGetMountImageDir="Devuelve el directorio de montaje de una imagen."
MSG_HELP_ogGetMountPoint="Devuelve el directorio donde está montado un sistema de archivos local."
MSG_HELP_ogGetNetInterface=""
MSG_HELP_ogGetOsType="Devuelve el tipo de un sistema operativo instalado."
MSG_HELP_ogGetOsUuid="Devuelve el UUID de un sistema operativo"
MSG_HELP_ogGetOsVersion="Devuelve el tipo y la versión de un sistema operativo instalado."
MSG_HELP_ogGetParentPath="Devuelve el camino completo del directorio padre de un fichero de sistema OpenGnsys."
MSG_HELP_ogGetPartitionActive="Indica cual es la partición marcada como activa en un disco."
MSG_HELP_ogGetPartitionId="Devuelve el identificador de tipo de una partición."
MSG_HELP_ogGetPartitionSize="Devuelve el tamaño de una partición."
MSG_HELP_ogGetPartitionsNumber="Devuelve el número de particiones de un disco"
MSG_HELP_ogGetPartitionTableType="Devuelve el tipo de tabla de particiones del disco"
MSG_HELP_ogGetPartitionType="Devuelve el mnemónico de tipo de una partición."
MSG_HELP_ogGetPath="Devuelve el camino completo de un fichero de sistema OpenGnsys."
MSG_HELP_ogGetRegistryValue="Devuelve el dato de un valor del registro de Windows."
MSG_HELP_ogGetRepoIp="Devuelve la dirección IP del repositorio de datos."
MSG_HELP_ogGetSerialNumber="Devuelve el número de serie del equipo"
MSG_HELP_ogGetServerIp="Devuelve la dirección IP del servidor principal."
MSG_HELP_ogGetSizeParameters="Devuelve el tamaño de los datos de un sistema de ficheros, el espacio necesario para la imagen y si cabe en el repositorio elegido."
MSG_HELP_ogGetWindowsName="Devuelve el nombre del cliente guardado en el registro de Windows."
MSG_HELP_ogGrubAddOgLive="Incluye en el grub del MBR una entrada llamando al cliente de opengnsys."
MSG_HELP_ogGrubDefaultEntry="Configura la entrada por defecto de GRUB."
MSG_HELP_ogGrubDeleteEntry="Borra en el grub del MBR las entradas para el inicio en una particion."
MSG_HELP_ogGrubHidePartitions="Configura el grub del MBR para que oculte las particiones de windows que no se esten iniciando. Permite definir una partición que no se ocultará (ej: para datos)."
MSG_HELP_ogGrubInstallMbr="Instala el gestor de arranque GRUB en el MBR del primer disco duro"
MSG_HELP_ogGrubInstallPartition="Instala el gestor de arranque GRUB en el BootSector"
MSG_HELP_ogGrubOgliveDefaultEntry="Configura la entrada de ogLive como la entrada por defecto de GRUB."
MSG_HELP_ogGrubSecurity="Configura usuario y clave para modificar las entradas del menu del Grub."
MSG_HELP_ogGrubUefiConf="Genera el fichero grub.cfg de la partición EFI."
MSG_HELP_ogHelp="Muestra mensajes de ayudas para las funciones."
MSG_HELP_ogHidePartition="Oculta una partición de Windows."
MSG_HELP_ogIdToType="Devuelve el mnemónico asociado al identificador de tipo de partición."
MSG_HELP_ogInstallFirstBoot="Crea un archivo que se ejecutará en el primer arranque de Windows."
MSG_HELP_ogInstallLaunchDaemon="Instala un archivo que se ejecutará en el arranque de macOS."
MSG_HELP_ogInstallLinuxClient=MSG_OBSOLETE
MSG_HELP_ogInstallMiniSetup="Instala un archivo que se ejecutará en el arranque de Windows."
MSG_HELP_ogInstallRunonce="Crea archivo que se ejecutará en el inicio de un usuario administrador de Windows."
MSG_HELP_ogInstallWindowsClient=MSG_OBSOLETE
MSG_HELP_ogIsFormated="Comprueba si un sistema de archivos está formateado."
MSG_HELP_ogIsImageLocked="Comprueba si una imagen está bloqueada por una operación de uso exclusivo."
MSG_HELP_ogIsLocked="Comprueba si una partición o su disco están bloqueados por una operación de uso exclusivo."
MSG_HELP_ogIsDiskLocked="Comprueba si un disco está bloqueado por una operación de uso exclusivo."
MSG_HELP_ogIsMounted="Comprueba si un sistema de archivos está montado."
MSG_HELP_ogIsNewerFile="Comprueba si un fichero es más nuevo (se ha modificado después) que otro."
MSG_HELP_ogIsPartitionLocked=MSG_HELP_ogIsLocked
MSG_HELP_ogIsRepoLocked=""
MSG_HELP_ogIsSyncImage="Comprueba si la imagen es sincronizable."
MSG_HELP_ogIsVirtualMachine="Comprueba si el cliente es una máquina virtual"
MSG_HELP_ogIsWritable="Comprueba si un sistema de archivos está montado con permiso de escritura."
MSG_HELP_ogLinuxBootParameters="Devuelve los parámetros de arranque de un sistema operativo Linux instalado."
MSG_HELP_ogListHardwareInfo="Lista el inventario de dispositivos del cliente."
MSG_HELP_ogListLogicalPartitions="Lista las particiones lógicas de un disco"
MSG_HELP_ogListPartitions="Lista la estructura de particiones de un disco."
MSG_HELP_ogListPrimaryPartitions="Lista las particiones primarias de un disco"
MSG_HELP_ogListRegistryKeys="Lista los nombres de las subclaves incluidas en una clave del registro de Windows."
MSG_HELP_ogListRegistryValues="Lista los nombres de los valores incluidos en una clave del registro de Windows."
MSG_HELP_ogListSoftware="Lista el inventario de programas instalados en un sistema operativo."
MSG_HELP_ogLock="Bloquea una partición para operación de uso exclusivo."
MSG_HELP_ogLockDisk="Bloquea un disco para operación de uso exclusivo."
MSG_HELP_ogLockImage="Bloquea una imagen para operación de uso exclusivo."
MSG_HELP_ogLockPartition=MSG_HELP_ogLock
MSG_HELP_ogMakeChecksumFile="Almacena la suma de comprobación de un fichero."
MSG_HELP_ogMakeDir="Crea un directorio para OpenGnsys."
MSG_HELP_ogMakeGroupDir="Crea el directorio de grupo (aula) en un repositorio."
MSG_HELP_ogMcastReceiverFile=""
MSG_HELP_ogMcastReceiverPartition=""
MSG_HELP_ogMcastRequest=""
MSG_HELP_ogMcastSendFile=""
MSG_HELP_ogMcastSendPartition=""
MSG_HELP_ogMcastSyntax=""
MSG_HELP_ogMountCache="Monta el sistema de archivos dedicado a caché local."
MSG_HELP_ogMountCdrom="Monta dispositivo óptico por defecto."
MSG_HELP_ogMountImage="Monta una imagen sincronizable"
MSG_HELP_ogMount="Monta un sistema de archivos y devuelve el punto de montaje."
MSG_HELP_ogMountFs=MSG_HELP_ogMount
MSG_HELP_ogNvramActiveEntry="Configura a activa entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramAddEntry="Crea nueva entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramDeleteEntry="Borra entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramGetCurrent="Muestra la entrada del gestor de arranque (NVRAM) que ha iniciado el equipo."
MSG_HELP_ogNvramGetNext="Muestra la entrada del gestor de arranque (NVRAM) que se utilizará en el próximo arranque."
MSG_HELP_ogNvramGetOrder="Muestra el orden de las entradas del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramGetTimeout="Muestra el tiempo de espera del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramInactiveEntry="Configura a inactiva entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramList="Lista las entradas del gestor de arranque (NVRAN) marcando con un asterisco las activas"
MSG_HELP_ogNvramPxeFirstEntry="Configura la tarjeta de red como primer arranque en la NVRAM."
MSG_HELP_ogNvramSetNext="Configura el próximo arranque con la entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramSetOrder="Configura el orden de las entradas del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramSetTimeout="Configura el tiempo de espera del gestor de arranque (NVRAM)."
MSG_HELP_ogRaiseError="Muestra y registra mensajes de error y devuelve el código correspondiente."
MSG_HELP_ogReduceFs="Reduce el tamaño del sistema de archivos al mínimo ocupado por sus datos."
MSG_HELP_ogReduceImage="Reduce el tamaño de la imagen"
MSG_HELP_ogRefindDeleteEntry="Borra en rEFInd las entradas para el inicio en una particion."
MSG_HELP_ogRefindDefaultEntry="Configura la entrada por defecto de rEFInd."
MSG_HELP_ogRefindOgliveDefaultEntry="Configura la entrada de ogLive como la entrada por defecto de rEFInd."
MSG_HELP_ogRefindSetTheme="Asigna un tema al rEFInd."
MSG_HELP_ogRefindSetTimeOut="Define el tiempo (segundos) que se muestran las opciones de inicio de rEFInd."
MSG_HELP_ogRefindSetResolution="Define la resolución que usuará el thema del gestor de arranque rEFInd."
MSG_HELP_ogRefindInstall="Instala y configura el gestor rEFInd en la particion EFI"
MSG_HELP_ogRestoreAclImage="Restaura las ACL de Windows (La informacion debe estar copiada en /tmp)."
MSG_HELP_ogRestoreBootLoaderImage=""
MSG_HELP_ogRestoreDiskImage="Restaura una imagen de un disco completo."
MSG_HELP_ogRestoreEfiBootLoader="Copia el cargador de arranque de la partición de sistema a la partición EFI."
MSG_HELP_ogRestoreImage="Restaura una imagen de sistema operativo."
MSG_HELP_ogRestoreInfoImage="Restablece información del sistema: ACL y enlaces simbolicos"
MSG_HELP_ogRestoreMbrImage="Restaura una imagen del sector de arranque (MBR)."
MSG_HELP_ogRestoreUuidPartitions="Restaura los uuid de las particiones y la tabla de particiones."
MSG_HELP_ogSaveImageInfo="Crea un fichero con la información de la imagen."
MSG_HELP_ogSetLinuxName=""
MSG_HELP_ogSetPartitionActive="Establece el número de partición activa de un disco."
MSG_HELP_ogSetPartitionId="Modifica el tipo de una partición física usando el mnemónico del tipo."
MSG_HELP_ogSetPartitionSize="Establece el tamaño de una partición."
MSG_HELP_ogSetPartitionType="Modifica el identificador de tipo de una partición física."
MSG_HELP_ogSetRegistryValue="Asigna un dato a un valor del registro de Windows."
MSG_HELP_ogSetWindowsName="Asigna el nombre del cliente en el registro de Windows."
MSG_HELP_ogSetWinlogonUser="Asigna el nombre de usuario por defecto para el gestor de entrada de Windows."
MSG_HELP_ogSyncCreate="Sincroniza los datos de la partición a la imagen"
MSG_HELP_ogSyncRestore="Sincroniza los datos de la imagen a la partición"
MSG_HELP_ogTorrentStart=""
MSG_HELP_ogTypeToId="Devuelve el identificador asociado al mnemónico de tipo de partición."
MSG_HELP_ogUcastReceiverPartition=""
MSG_HELP_ogUcastSendFile=""
MSG_HELP_ogUcastSendPartition=""
MSG_HELP_ogUcastSyntax=""
MSG_HELP_ogUnhidePartition="Hace visible una partición de Windows."
MSG_HELP_ogUninstallLinuxClient="Desinstala el antiguo cliente OpenGnSys en un sistema operativo Linux."
MSG_HELP_ogUninstallWindowsClient="Desinstala el antiguo cliente OpenGnSys en un sistema operativo Windows."
MSG_HELP_ogUnlock="Desbloquea una partición tras finalizar una operación de uso exclusivo."
MSG_HELP_ogUnlockDisk="Desbloquea un disco tras finalizar una operación de uso exclusivo."
MSG_HELP_ogUnlockImage="Desbloquea una imagen tras finalizar una operación de uso exclusivo."
MSG_HELP_ogUnlockPartition=MSG_HELP_ogUnlock
MSG_HELP_ogUnmountAll="Desmonta todos los sistemas de archivos."
MSG_HELP_ogUnmountCache="Desmonta el sistema de archivos de caché local."
MSG_HELP_ogUnmount="Desmonta un sistema de archivos."
MSG_HELP_ogUnmountImage="Desmonta la imagen."
MSG_HELP_ogUnmountFs=MSG_HELP_ogUnmount
MSG_HELP_ogUnsetDirtyBit=""
MSG_HELP_ogUpdateCacheIsNecesary="Comprueba si es necesario actualizar una archivo en la cache local."
MSG_HELP_ogUpdatePartitionTable="Actualiza información de la tabla de particiones del disco."
MSG_HELP_ogUuidChange="Reemplaza el UUID de un sistema de ficheros."
MSG_HELP_ogWaitSyncImage=""
MSG_HELP_ogWindowsBootParameters=""
MSG_HELP_ogWindowsRegisterPartition=""
# Scripts
MSG_HELP_configureOs="Post-configura de arranque del sistema"
MSG_HELP_createBaseImage="Genera imagen básica de la partición"
MSG_HELP_createDiffImage="Genera imagen diferencial de la partición respecto a la imagen básica"
MSG_HELP_installOfflineMode="Prepara el equipo cliente para el modo offline."
MSG_HELP_partclone2sync="Convierte imagen de partclone en imagen sincronizable."
MSG_HELP_restoreBaseImage="Restaura una imagen básica en una partición"
MSG_HELP_restoreDiffImage="Restaura una imagen diferencial en una partición"
MSG_HELP_updateCache="Realiza la actualización de la caché"
# Mensajes de descripción breve de la interfaz.
MSG_INTERFACE_START="[START Interface] Ejecutar comando: "
MSG_INTERFACE_END="[END Interface] Comando terminado con este código: "
# Mensajes de scripts.
MSG_SCRIPTS_START=" INICIO scripts: "
MSG_SCRIPTS_END=" FIN scripts: "
MSG_SCRIPTS_TASK_END="Fin de la tarea"
MSG_SCRIPTS_TASK_SLEEP="Esperando para iniciar"
MSG_SCRIPTS_TASK_START="Iniciando"
MSG_SCRIPTS_TASK_ERR="Error"
# Script createImage.
MSG_SCRIPTS_FILE_RENAME=" Renombrar fichero-imagen previo: "
MSG_SCRIPTS_CREATE_SIZE=" Calcular espacio (KB) requerido para almacenarlo y el disponible: "
# Script updateCache.
MSG_SCRIPTS_UPDATECACHE_DOUPDATE="Comprobar si es necesario actualizar el fichero imagen "
MSG_SCRIPTS_UPDATECACHE_CHECKSIZECACHE="Comprobar que el tamaño de la caché es mayor que el fichero a descargar."
# Script updateCache: para las imágenes sincronizadas tipo dir.
MSG_SCRIPTS_UPDATECACHE_CHECKSIZEDIR="Calcular el tamaño de la imagen."
MSG_SCRIPTS_UPDATECACHE_CHECKSIZEIMG="Comprobar si la imagen del repositorio es mayor que la de la caché."
MSG_SCRIPTS_UPDATECACHE_IFNOTCACHEDO="Comprobar el espacio libre de la caché y actuar según engine.cfg"
MSG_SCRIPTS_UPDATECACHE_CHECKMCASTSESSION="Comprobando sesión Multicast: ServidorMcast:PuertoDatos"
# interface sustituye temporalmente al scritp restore
MSG_SCRIPTS_CHECK_ENGINE="Analizar proceso a realizar según engine.cfg"
MSG_SCRIPTS_MULTICAST_PRECHECK_PORT="Determinar puerto principal y auxiliar Multicast."
MSG_SCRIPTS_MULTICAST_CHECK_PORT="Comprobar puertos de sesión y datos"
MSG_SCRIPTS_MULTICAST_REQUEST_PORT="Solicitar la apertura: "
MSG_SCRIPTS_OS_CONFIGURE="Iniciar la configuración del sistema restaurado"
# TIME MESSAGES
MSG_SCRIPTS_TIME_TOTAL="tiempo total del proceso"
MSG_SCRIPTS_TIME_PARTIAL="tiempo parcial del subproceso"
# HTTPLOG
MSG_HTTPLOG_NOUSE="No apague este ordenador por favor"
# Mensajes sincronizadas
MSG_SYNC_RESIZE="Redimensiona la imagen al tamaño necesario"
MSG_SYNC_RESTORE="Trae el listado ficheros y baja la imagen"
MSG_SYNC_DELETE="Diferencial: Borra archivos antiguos"
MSG_SYNC_SLEEP="Espera que se monte/reduzca la imagen"
# Mensajes sincronizadas complementarios a errores
MSG_SYNC_DIFFERENTFS="El sistema de ficheros de destino no coincide con el de la imagen"
MSG_SYNC_EXTENSION="Las extensiones de la imagenes deben ser img o diff"
MSG_SYNC_NOCHECK="La imagen esta montada por otro proceso, no podemos comprobarla"
MSG_RESTORE="Restaura la imagen en"

View File

@ -0,0 +1,112 @@
#!/usr/bin/python3
import sys
import os.path
import locale
import importlib.util
def load_lang (name):
global lang
if name in sys.modules:
return True
elif (spec := importlib.util.find_spec (name)) is not None:
lang = importlib.util.module_from_spec (spec)
sys.modules[name] = lang
spec.loader.exec_module (lang)
return True
else:
#print(f"can't find the {name!r} module")
return False
l = locale.getlocale()[0]
if not l: print (f"couldn't set locale")
if not l or not load_lang (f'lang_{l}'):
if not load_lang ('lang_en_GB'):
raise ModuleNotFoundError (f"can't find the default language module", name=name)
TZ='Europe/Madrid'
## engine.cfg
OGLOGSESSION='/tmp/session.log'
OGLOGCOMMAND='/tmp/command.log'
#OGWINCHKDISK=True #Hacer chkdisk tras la clonacion
ACTIONCACHEFULL='NONE' #Que hacer cuando la cache no tenga espacio libre. [ NONE | FORMAT ] ]
RESTOREPROTOCOLNOTCACHE=None #Que protocolo de restauracion usar en el caso de que no exista cache o no exista espacio sufiente. [NONE | UNICAST | MULTICAST].NONE retorna error
IMGPROG='partclone'
IMGCOMP='lzop'
IMGEXT='img'
IMGREDUCE=True
#OGWINREDUCE=True #Al enviar particion reducir el sistema de archivos previamente.
MCASTERRORSESSION=120 #timeout (segundos) para abortar la sesion de multicast si no contacta con el servidor de multicast. Valor asignado a 0, utiliza los valores por defecto de udp-cast
MCASTWAIT=30 # timeout (segundos) para abortar la la transferencia si se interrumpe. Valor asignado a 0, utiliza los valores por defecto de udp-cast
#CREATESPEED=100000*4 # Factor para calcular el time-out al crear la imagen. 100000k -> 4s
#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
NODEBUGFUNCTIONS=['ogCreateImageSyntax', 'ogGetHivePath', 'ogGetOsType', 'ogRestoreImageSyntax', 'ogUnmountAll', 'ogUnmountCache'] # Funciones que no deben mostrar salida de avisos si son llamadas por otras funciones.
#DEFAULTSPEED=''
## /engine.cfg
## loadenviron.sh
OPENGNSYS = '/opt/opengnsys'
OGBIN = os.path.join (OPENGNSYS, 'bin')
OGETC = os.path.join (OPENGNSYS, 'etc')
OGLIB = os.path.join (OPENGNSYS, 'lib')
OGAPI = os.path.join (OGLIB, 'engine', 'bin')
OGSCRIPTS = os.path.join (OPENGNSYS, 'scripts')
OGIMG = os.path.join (OPENGNSYS, 'images')
OGCAC = os.path.join (OPENGNSYS, 'cache')
OGLOG = os.path.join (OPENGNSYS, 'log')
OGLOGFILE = f'{OGLOG}/192.168.42.42' ## TODO import NetLib; OGLOGFILE = f'$OGLOG/{NetLib.ogGetIpAddress()}.log'
DEBUG = 'yes'
## /loadenviron.sh
# Declaración de códigos de error.
OG_ERR_FORMAT=1 # Formato de ejecución incorrecto.
OG_ERR_NOTFOUND=2 # Fichero o dispositivo no encontrado.
OG_ERR_PARTITION=3 # Error en partición de disco.
OG_ERR_LOCKED=4 # Partición o fichero bloqueado.
OG_ERR_IMAGE=5 # Error al crear o restaurar una imagen.
OG_ERR_NOTOS=6 # Sin sistema operativo.
OG_ERR_NOTEXEC=7 # Programa o función no ejecutable.
# Códigos 8-13 reservados por ogAdmClient.h
OG_ERR_NOTWRITE=14 # No hay acceso de escritura
OG_ERR_NOTCACHE=15 # No hay particion cache en cliente
OG_ERR_CACHESIZE=16 # No hay espacio en la cache para almacenar fichero-imagen
OG_ERR_REDUCEFS=17 # Error al reducir sistema archivos
OG_ERR_EXTENDFS=18 # Error al expandir el sistema de archivos
OG_ERR_OUTOFLIMIT=19 # Valor fuera de rango o no válido.
OG_ERR_FILESYS=20 # Sistema de archivos desconocido o no se puede montar
OG_ERR_CACHE=21 # Error en partición de caché local
OG_ERR_NOGPT=22 # El disco indicado no contiene una particion GPT
OG_ERR_REPO=23 # Error al montar el repositorio de imagenes
OG_ERR_NOMSDOS=24 # El disco indicado no contienen una particion MSDOS
OG_ERR_IMGSIZEPARTITION=30 # Error al restaurar partición más pequeña que la imagen
OG_ERR_UPDATECACHE=31 # Error al realizar el comando updateCache
OG_ERR_DONTFORMAT=32 # Error al formatear
OG_ERR_IMAGEFILE=33 # Archivo de imagen corrupto o de otra versión de $IMGPROG
OG_ERR_GENERIC=40 # Error imprevisto no definido
OG_ERR_UCASTSYNTAXT=50 # Error en la generación de sintaxis de transferenica UNICAST
OG_ERR_UCASTSENDPARTITION=51 # Error en envío UNICAST de partición
OG_ERR_UCASTSENDFILE=52 # Error en envío UNICAST de un fichero
OG_ERR_UCASTRECEIVERPARTITION=53 # Error en la recepcion UNICAST de una particion
OG_ERR_UCASTRECEIVERFILE=54 # Error en la recepcion UNICAST de un fichero
OG_ERR_MCASTSYNTAXT=55 # Error en la generacion de sintaxis de transferenica Multicast.
OG_ERR_MCASTSENDFILE=56 # Error en envio MULTICAST de un fichero
OG_ERR_MCASTRECEIVERFILE=57 # Error en la recepcion MULTICAST de un fichero
OG_ERR_MCASTSENDPARTITION=58 # Error en envio MULTICAST de una particion
OG_ERR_MCASTRECEIVERPARTITION=59 # Error en la recepcion MULTICAST de una particion
OG_ERR_PROTOCOLJOINMASTER=60 # Error en la conexion de una sesion UNICAST|MULTICAST con el MASTER
OG_ERR_DONTMOUNT_IMAGE=70 # Error al montar una imagen sincronizada.
OG_ERR_DONTSYNC_IMAGE=71 # Imagen no sincronizable (es monolitica)
OG_ERR_DONTUNMOUNT_IMAGE=72 # Error al desmontar la imagen
OG_ERR_NOTDIFFERENT=73 # No se detectan diferencias entre la imagen basica y la particion.
OG_ERR_SYNCHRONIZING=74 # Error al sincronizar, puede afectar la creacion/restauracion de la imagen
OG_ERR_NOTUEFI=80 # La interfaz UEFI no está activa
OG_ERR_NOTBIOS=81 # La interfaz BIOS legacy no está activa

View File

@ -0,0 +1,25 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from PostConfLib import ogAddCmd
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('par')
parser.add_argument ('cmdfile')
parser.add_argument ('cmd')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogAddCmd', 'ogAddCmd int_ndisk int_npartition str_filename str_commands', ['ogAddCmd 1 1 filename.cmd command'])
sys.exit (0)
args = parser.parse_args()
ret = ogAddCmd (args.disk, args.par, args.cmdfile, args.cmd)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,24 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from RegistryLib import ogAddRegistryKey
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('mntpt')
parser.add_argument ('hive')
parser.add_argument ('k')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogAddRegistryKey', 'ogAddRegistryKey path_mountpoint str_hive str_key', [r'ogAddRegistryKey /mnt/sda1 SOFTWARE "\Microsoft\NewKey"'])
sys.exit (0)
args = parser.parse_args()
ret = ogAddRegistryKey (args.mntpt, args.hive, args.k)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,25 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from RegistryLib import ogAddRegistryValue
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('mntpt')
parser.add_argument ('hive')
parser.add_argument ('k')
parser.add_argument ('vtype', nargs='?', default='STRING')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogAddRegistryValue', 'ogAddRegistryValue path_mountpoint str_hive str_valuename [str_valuetype]', [r'ogAddRegistryValue /mnt/sda1 SOFTWARE "\Microsoft\NewKey\Value1"', r'ogAddRegistryValue /mnt/sda1 SOFTWARE "\Microsoft\NewKey\Value1" DWORD'])
sys.exit (0)
args = parser.parse_args()
ret = ogAddRegistryValue (args.mntpt, args.hive, args.k, args.vtype)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,32 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from FileLib import ogCalculateChecksum
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogCalculateChecksum', 'ogCalculateChecksum [ str_repo | int_ndisk int_npartition ] path_filepath', ['ogCalculateChecksum REPO ubuntu.img'])
sys.exit (0)
parser = argparse.ArgumentParser (add_help=False)
if 3 == len (sys.argv):
parser.add_argument ('container', nargs='?', default=None)
parser.add_argument ('file', nargs='?', default=None)
elif 4 == len (sys.argv):
parser.add_argument ('disk', nargs='?', default=None)
parser.add_argument ('par', nargs='?', default=None)
parser.add_argument ('file', nargs='?', default=None)
args = parser.parse_args()
if 3 == len (sys.argv):
ret = ogCalculateChecksum (container=args.container, file=args.file)
elif 4 == len (sys.argv):
ret = ogCalculateChecksum (container=f'{args.disk} {args.par}', file=args.file)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,32 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from FileLib import ogCalculateFullChecksum
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogCalculateFullChecksum', 'ogCalculateFullChecksum [ str_repo | int_ndisk int_npartition ] path_filepath', ['ogCalculateFullChecksum REPO ubuntu.img'])
sys.exit (0)
parser = argparse.ArgumentParser (add_help=False)
if 3 == len (sys.argv):
parser.add_argument ('container', nargs='?', default=None)
parser.add_argument ('file', nargs='?', default=None)
elif 4 == len (sys.argv):
parser.add_argument ('disk', nargs='?', default=None)
parser.add_argument ('par', nargs='?', default=None)
parser.add_argument ('file', nargs='?', default=None)
args = parser.parse_args()
if 3 == len (sys.argv):
ret = ogCalculateFullChecksum (container=args.container, file=args.file)
elif 4 == len (sys.argv):
ret = ogCalculateFullChecksum (container=f'{args.disk} {args.par}', file=args.file)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
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
ogHelp ('ogChangeRepo', 'ogChangeRepo IPREPO', ['ogChangeRepo 10.1.120.3'])
sys.exit (0)
args = parser.parse_args()
ret = ogChangeRepo (args.ip_repo, args.og_unit)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from FileSystemLib import ogCheckFs
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('par')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogCheckFs', 'ogCheckFs int_ndisk int_nfilesys', ['ogCheckFs 1 1'])
sys.exit (0)
args = parser.parse_args()
ret = ogCheckFs (args.disk, args.par)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,22 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from StringLib import ogCheckIpAddress
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('ip')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogCheckIpAddress')
sys.exit (0)
args = parser.parse_args()
ret = ogCheckIpAddress (args.ip)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from BootLib import ogCleanLinuxDevices
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('par')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogCleanLinuxDevices', 'ogCleanLinuxDevices int_ndisk int_nfilesys', ['ogCleanLinuxDevices 1 1'])
sys.exit (0)
args = parser.parse_args()
ret = ogCleanLinuxDevices (args.disk, args.par)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from PostConfLib import ogCleanOs
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('par')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogCleanOs', 'ogCleanOs int_ndisk int_nfilesys', ['ogCleanOs 1 1'])
sys.exit (0)
args = parser.parse_args()
ret = ogCleanOs (args.disk, args.par)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from BootLib import ogConfigureFstab
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('par')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogConfigureFstab', 'ogConfigureFstab int_ndisk int_nfilesys', ['ogConfigureFstab 1 1'])
sys.exit (0)
args = parser.parse_args()
ret = ogConfigureFstab (args.disk, args.par)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from PostConfLib import ogConfigureOgagent
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('par')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogConfigureOgagent', 'ogConfigureOgagent int_ndisk int_filesys', ['ogConfigureOgagent 1 1'])
sys.exit (0)
args = parser.parse_args()
ret = ogConfigureOgagent (args.disk, args.par)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from UEFILib import ogCopyEfiBootLoader
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('par')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogCopyEfiBootLoader', 'ogCopyEfiBootLoader int_ndisk int_part', ['ogCopyEfiBootLoader 1 2'])
sys.exit (0)
args = parser.parse_args()
ret = ogCopyEfiBootLoader (args.disk, args.par)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,63 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from FileLib import ogCopyFile
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogCopyFile', 'ogCopyFile [ str_repo | int_ndisk int_npartition ] path_source [ str_repo | int_ndisk int_npartition ] path_target', ['ogCopyFile REPO newfile.txt 1 2 /tmp/newfile.txt'])
sys.exit (0)
parser = argparse.ArgumentParser (add_help=False)
if 5 == len (sys.argv):
parser.add_argument ('src_container')
parser.add_argument ('src_file')
parser.add_argument ('dst_container')
parser.add_argument ('dst_file')
args = parser.parse_args()
src = { 'container': args.src_container, 'file': args.src_file }
dst = { 'container': args.dst_container, 'file': args.dst_file }
elif 7 == len (sys.argv):
parser.add_argument ('src_disk')
parser.add_argument ('src_par')
parser.add_argument ('src_file')
parser.add_argument ('dst_disk')
parser.add_argument ('dst_par')
parser.add_argument ('dst_file')
args = parser.parse_args()
src = { 'disk': args.src_disk, 'par': args.src_par, 'file': args.src_file }
dst = { 'disk': args.dst_disk, 'par': args.dst_par, 'file': args.dst_file }
elif 6 == len (sys.argv):
## can be either:
## - src_disk src_par src_file dst_container dst_file
## - src_container src_file dst_disk dst_par dst_file
try:
num = int (sys.argv[1]) ## raises ValueError if sys.argv[1] doesn't look like a number
## "src_disk src_par src_file dst_container dst_file"
parser.add_argument ('src_disk')
parser.add_argument ('src_par')
parser.add_argument ('src_file')
parser.add_argument ('dst_container')
parser.add_argument ('dst_file')
args = parser.parse_args()
src = { 'disk': args.src_disk, 'par': args.src_par, 'file': args.src_file }
dst = { 'container': args.dst_container, 'file': args.dst_file }
except:
## "src_container src_file dst_disk dst_par dst_file"
parser.add_argument ('src_container')
parser.add_argument ('src_file')
parser.add_argument ('dst_disk')
parser.add_argument ('dst_par')
parser.add_argument ('dst_file')
args = parser.parse_args()
src = { 'container': args.src_container, 'file': args.src_file }
dst = { 'disk': args.dst_disk, 'par': args.dst_par, 'file': args.dst_file }
ret = ogCopyFile (src, dst)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,36 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from CacheLib import ogCreateCache
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogCreateCache', 'ogCreateCache [int_ndisk [int_npart]] int_partsize', ['ogCreateCache 10000000', 'ogCreateCache 1 10000000', 'ogCreateCache 1 4 10000000'])
sys.exit (0)
parser = argparse.ArgumentParser (add_help=False)
if 2 == len (sys.argv):
parser.add_argument ('sizecache')
elif 3 == len (sys.argv):
parser.add_argument ('disk')
parser.add_argument ('sizecache')
elif 4 == len (sys.argv):
parser.add_argument ('disk')
parser.add_argument ('part')
parser.add_argument ('sizecache')
args = parser.parse_args()
if 2 == len (sys.argv):
ret = ogCreateCache (sizecache=args.sizecache)
elif 3 == len (sys.argv):
ret = ogCreateCache (ndsk=args.disk, sizecache=args.sizecache)
elif 4 == len (sys.argv):
ret = ogCreateCache (ndsk=int(args.disk), part=int(args.part), sizecache=int(args.sizecache))
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from DiskLib import ogCreateGptPartitions
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogCreateGptPartitions', 'ogCreateGptPartitions int_ndisk str_parttype:int_partsize ...', ['ogCreateGptPartitions 1 NTFS:10000000 EXT3:5000000 LINUX-SWAP:1000000'])
sys.exit (0)
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('parts', nargs='+')
args = parser.parse_args()
ret = ogCreateGptPartitions (args.disk, args.parts)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,37 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from ImageLib import ogCreateImage
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogCreateImage', 'ogCreateImage int_ndisk int_npart str_repo path_image', ['ogCreateImage 1 1 REPO /aula1/win7'])
sys.exit (0)
parser = argparse.ArgumentParser (add_help=False)
if 5 == len (sys.argv):
parser.add_argument ('disk')
parser.add_argument ('par')
parser.add_argument ('container')
parser.add_argument ('imgfile')
elif 7 == len (sys.argv):
parser.add_argument ('disk')
parser.add_argument ('par')
parser.add_argument ('container')
parser.add_argument ('imgfile')
parser.add_argument ('tool')
parser.add_argument ('level')
args = parser.parse_args()
if 5 == len (sys.argv):
ret = ogCreateImage (args.disk, args.par, args.container, args.imgfile)
elif 7 == len (sys.argv):
ret = ogCreateImage (args.disk, args.par, args.container, args.imgfile, args.tool, args.level)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,25 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from ImageLib import ogCreateImageSyntax
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('dev')
parser.add_argument ('imgfile')
parser.add_argument ('tool', nargs='?', default='partclone')
parser.add_argument ('level', nargs='?', default='gzip')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogCreateImageSyntax', 'ogCreateImageSyntax path_device path_imagefile [str_tool] [str_compressionlevel]', ['ogCreateImageSyntax /dev/sda1 /opt/opengnsys/images/prueba.img partclone lzop', 'ogCreateImageSyntax /dev/sda1 /opt/opengnsys/images/prueba.img'])
sys.exit (0)
args = parser.parse_args()
ret = ogCreateImageSyntax (args.dev, args.imgfile, args.tool, args.level)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,30 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from DiskLib import ogCreatePartitionTable
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogCreatePartitionTable', 'ogCreatePartitionTable int_ndisk [str_partype]', ['ogCreatePartitionTable 1 GPT', 'ogCreatePartitionTable 1'])
sys.exit (0)
parser = argparse.ArgumentParser (add_help=False)
if 2 == len (sys.argv):
parser.add_argument ('disk')
elif 3 == len (sys.argv):
parser.add_argument ('disk')
parser.add_argument ('createptt')
args = parser.parse_args()
if 2 == len (sys.argv):
ret = ogCreatePartitionTable (args.disk)
elif 3 == len (sys.argv):
ret = ogCreatePartitionTable (args.disk, args.createptt)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from DiskLib import ogCreatePartitions
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogCreatePartitions', 'ogCreatePartitions int_ndisk str_parttype:int_partsize ...', ['ogCreatePartitions 1 NTFS:10000000 EXT3:5000000 LINUX-SWAP:1000000'])
sys.exit (0)
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('parts', nargs='+')
args = parser.parse_args()
ret = ogCreatePartitions (args.disk, args.parts)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,31 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from ProtocolLib import ogCreateTorrent
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogCreateTorrent', 'ogCreateTorrent [str_REPOSITORY] [int_ndisk int_npart] Relative_path_file IpBttrack', ['ogCreateTorrent 1 1 /aula1/winxp 10.1.15.23', 'ogCreateTorrent REPO /aula1/winxp 10.1.15.45'])
sys.exit (0)
parser = argparse.ArgumentParser (add_help=False)
if 4 == len (sys.argv):
parser.add_argument ('container')
elif 5 == len (sys.argv):
parser.add_argument ('disk')
parser.add_argument ('par')
parser.add_argument ('file')
parser.add_argument ('ip_bttrack')
args = parser.parse_args()
if 4 == len (sys.argv):
ret = ogCreateTorrent (container=args.container, file=args.file, ip_bttrack=args.ip_bttrack)
elif 5 == len (sys.argv):
ret = ogCreateTorrent (disk=args.disk, par=args.par, file=args.file, ip_bttrack=args.ip_bttrack)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,13 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from CacheLib import ogDeleteCache
ret = ogDeleteCache()
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,32 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from FileLib import ogDeleteFile
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogDeleteFile', 'ogDeleteFile [ str_repo | int_ndisk int_npartition ] path_file', ['ogDeleteFile 1 2 /tmp/newfile.txt'])
sys.exit (0)
parser = argparse.ArgumentParser (add_help=False)
if 3 == len (sys.argv):
parser.add_argument ('container', nargs='?', default=None)
parser.add_argument ('file', nargs='?', default=None)
elif 4 == len (sys.argv):
parser.add_argument ('disk', nargs='?', default=None)
parser.add_argument ('par', nargs='?', default=None)
parser.add_argument ('file', nargs='?', default=None)
args = parser.parse_args()
if 3 == len (sys.argv):
ret = ogDeleteFile (container=args.container, file=args.file)
elif 4 == len (sys.argv):
ret = ogDeleteFile (container=f'{args.disk} {args.par}', file=args.file)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,22 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from DiskLib import ogDeletePartitionTable
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogDeletePartitionTable', 'ogDeletePartitionTable int_ndisk', ['ogDeletePartitionTable 1'])
sys.exit (0)
args = parser.parse_args()
ret = ogDeletePartitionTable (args.disk)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,24 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from RegistryLib import ogDeleteRegistryKey
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('mntpt')
parser.add_argument ('hive')
parser.add_argument ('k')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogDeleteRegistryKey', 'ogDeleteRegistryKey path_mountpoint str_hive str_key', [r'ogDeleteRegistryKey /mnt/sda1 SOFTWARE "\Microsoft\NewKey"'])
sys.exit (0)
args = parser.parse_args()
ret = ogDeleteRegistryKey (args.mntpt, args.hive, args.k)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,24 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from RegistryLib import ogDeleteRegistryValue
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('mntpt')
parser.add_argument ('hive')
parser.add_argument ('k')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogDeleteRegistryValue', 'ogDeleteRegistryValue path_mountpoint str_hive str_valuename', [r'ogDeleteRegistryValue /mnt/sda1 SOFTWARE "\Microsoft\NewKey\Value1"'])
sys.exit (0)
args = parser.parse_args()
ret = ogDeleteRegistryValue (args.mntpt, args.hive, args.k)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,32 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from FileLib import ogDeleteTree
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogDeleteTree', 'ogDeleteTree [ str_repo | int_ndisk int_npartition ] path_dir', ['ogDeleteTree 1 2 /tmp/newdir'])
sys.exit (0)
parser = argparse.ArgumentParser (add_help=False)
if 3 == len (sys.argv):
parser.add_argument ('container', nargs='?', default=None)
parser.add_argument ('file', nargs='?', default=None)
elif 4 == len (sys.argv):
parser.add_argument ('disk', nargs='?', default=None)
parser.add_argument ('par', nargs='?', default=None)
parser.add_argument ('file', nargs='?', default=None)
args = parser.parse_args()
if 3 == len (sys.argv):
ret = ogDeleteTree (container=args.container, file=args.file)
elif 4 == len (sys.argv):
ret = ogDeleteTree (container=f'{args.disk} {args.par}', file=args.file)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,22 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from DiskLib import ogDevToDisk
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('arg_dev')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogDevToDisk', 'ogDevToDisk path_device | LABEL=str_label | UUID=str_uuid', ['ogDevToDisk /dev/sda', 'ogDevToDisk /dev/sda1', 'ogDevToDisk LABEL=CACHE'])
sys.exit (0)
args = parser.parse_args()
ret = ogDevToDisk (args.arg_dev)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from DiskLib import ogDiskToDev
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('arg_disk', nargs='?', default=None)
parser.add_argument ('arg_part', 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
ogHelp ('ogDiskToDev', 'ogDiskToDev int_ndisk [int_npartition]', ['ogDiskToDev', 'ogDiskToDev 1', 'ogDiskToDev 1 1'])
sys.exit (0)
args = parser.parse_args()
ret = ogDiskToDev (args.arg_disk, args.arg_part)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,24 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from SystemLib import ogEcho
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('logtypes')
parser.add_argument ('loglevel')
parser.add_argument ('msg')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogEcho')
sys.exit (0)
args = parser.parse_args()
ret = ogEcho (args.logtypes, args.loglevel, args.msg)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,53 @@
#!/usr/bin/python3
import sys
## lo siento, pero tiene que ser así
from BootLib import *
from CacheLib import *
from DiskLib import *
from FileLib import *
from FileSystemLib import *
from ImageLib import *
from InventoryLib import *
from NetLib import *
from PostConfLib import *
from ProtocolLib import *
from RegistryLib import *
from StringLib import *
from SystemLib import *
from UEFILib import *
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogExecAndLog', 'ogExecAndLog str_logfile ... str_command ...', ['ogExecAndLog COMMAND ls -al /'])
sys.exit (0)
logtypes = []
while True:
if sys.argv[1] in ['command', 'log', 'session']:
logtypes.append (sys.argv.pop (1))
else: break
fun_name = sys.argv.pop (1)
try:
fun = locals()[fun_name]
except KeyError:
print (f'not implemented: {fun_name}')
sys.exit (1)
args = []
kwargs = {}
for arg in sys.argv[1:]:
if '=' in arg:
k, v = arg.split ('=')
kwargs[k] = v
else:
args.append (arg)
## args has to be a tuple
args = tuple (args)
ret = ogExecAndLog (logtypes, fun, *args, **kwargs)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from FileSystemLib import ogExtendFs
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('par')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogExtendFs', 'ogExtendFs int_ndisk int_nfilesys', ['ogExtendFs 1 1'])
sys.exit (0)
args = parser.parse_args()
ret = ogExtendFs (args.disk, args.par)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,22 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from CacheLib import ogFindCache
parser = argparse.ArgumentParser (add_help=False)
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogFindCache', 'ogFindCache')
sys.exit (0)
args = parser.parse_args()
ret = ogFindCache ()
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from BootLib import ogFixBootSector
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('par')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogFixBootSector', 'ogFixBootSector int_ndisk int_partition', ['ogFixBootSector 1 1'])
sys.exit (0)
args = parser.parse_args()
ret = ogFixBootSector (args.disk, args.par)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,28 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from FileSystemLib import ogFormat
from CacheLib import ogFormatCache
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogFormat', 'ogFormat int_ndisk int_nfilesys [str_label]', ['ogFormat 1 1', 'ogFormat 1 1 EXT4', 'ogFormat 1 1 DATA', 'ogFormat 1 1 EXT4 DATA'])
sys.exit (0)
if 2 == len (sys.argv) and 'cache' == sys.argv[1]:
ret = ogFormatCache()
else:
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('par')
parser.add_argument ('fs', nargs='?', default=None)
parser.add_argument ('label', nargs='?', default=None)
args = parser.parse_args()
ret = ogFormat (args.disk, args.par, args.fs, args.label)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,22 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from CacheLib import ogFormatCache
parser = argparse.ArgumentParser (add_help=False)
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogFormatCache', 'ogFormatCache')
sys.exit (0)
args = parser.parse_args()
ret = ogFormatCache ()
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,25 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from FileSystemLib import ogFormatFs
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('par')
parser.add_argument ('type', nargs='?', default=None)
parser.add_argument ('label', 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
ogHelp ('ogFormatFs', 'ogFormatFs int_ndisk int_nfilesys [str_label]', ['ogFormatFs 1 1', 'ogFormatFs 1 1 EXT4', 'ogFormatFs 1 1 DATA', 'ogFormatFs 1 1 EXT4 DATA'])
sys.exit (0)
args = parser.parse_args()
ret = ogFormatFs (args.disk, args.par, args.type, args.label)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,22 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from InventoryLib import ogGetArch
parser = argparse.ArgumentParser (add_help=False)
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetArch')
sys.exit (0)
args = parser.parse_args()
ret = ogGetArch ()
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,22 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from CacheLib import ogGetCacheSize
parser = argparse.ArgumentParser (add_help=False)
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetCacheSize', 'ogGetCacheSize')
sys.exit (0)
args = parser.parse_args()
ret = ogGetCacheSize ()
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,13 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from CacheLib import ogGetCacheSpace
ret = ogGetCacheSpace()
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,22 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from SystemLib import ogGetCaller
parser = argparse.ArgumentParser (add_help=False)
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetCaller')
sys.exit (0)
args = parser.parse_args()
ret = ogGetCaller ()
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,22 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from DiskLib import ogGetDiskSize
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetDiskSize', 'ogGetDiskSize int_ndisk', ['ogGetDiskSize 1'])
sys.exit (0)
args = parser.parse_args()
ret = ogGetDiskSize (args.disk)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,22 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from DiskLib import ogGetDiskType
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('dev')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetDiskType', 'ogGetDiskType path_device', ['ogGetDiskType /dev/sdb'])
sys.exit (0)
args = parser.parse_args()
ret = ogGetDiskType (args.dev)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,22 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from DiskLib import ogGetEsp
parser = argparse.ArgumentParser (add_help=False)
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetEsp')
sys.exit (0)
args = parser.parse_args()
ret = ogGetEsp ()
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,24 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from FileSystemLib import ogGetFreeSize
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('part')
parser.add_argument ('unit', nargs='?', default='KB')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetFreeSize', 'ogGetFreeSize int_disco int_partition str_SizeOutput [ kB MB GB ]', ['ogGetFreeSize 1 1 MB'])
sys.exit (0)
args = parser.parse_args()
ret = ogGetFreeSize (args.disk, args.part, args.unit)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,24 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from FileSystemLib import ogGetFsSize
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('par')
parser.add_argument ('unit', nargs='?', default='KB')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetFsSize', 'ogGetFsSize int_ndisk int_npartition [str_unit]', ['ogGetFsSize 1 1', 'ogGetFsSize 1 1 KB'])
sys.exit (0)
args = parser.parse_args()
ret = ogGetFsSize (args.disk, args.par, args.unit)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from FileSystemLib import ogGetFsType
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('part')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetFsType', 'ogGetFsType int_ndisk int_nfilesys', ['ogGetFsType 1 1'])
sys.exit (0)
args = parser.parse_args()
ret = ogGetFsType (args.disk, args.part)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from RegistryLib import ogGetHivePath
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('mntpt')
parser.add_argument ('hive')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetHivePath', 'ogGetHivePath path_mountpoint [str_hive|str_user]', ['ogGetHivePath /mnt/sda1 SOFTWARE', 'ogGetHivePath /mnt/sda1 user1'])
sys.exit (0)
args = parser.parse_args()
ret = ogGetHivePath (args.mntpt, args.hive)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,22 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from NetLib import ogGetHostname
parser = argparse.ArgumentParser (add_help=False)
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetHostname')
sys.exit (0)
args = parser.parse_args()
ret = ogGetHostname ()
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from ImageLib import ogGetImageCompressor
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('container')
parser.add_argument ('filename')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetImageCompressor', 'ogGetImageCompressor str_repo path_image', ['ogGetImageCompressor REPO prueba'])
sys.exit (0)
args = parser.parse_args()
ret = ogGetImageCompressor (args.container, args.filename)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,22 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from ImageLib import ogGetImageInfo
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('imgfile')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetImageInfo', 'ogGetImageInfo path_filename', ['ogGetImageInfo /opt/opengnsys/images/prueba.img'])
sys.exit (0)
args = parser.parse_args()
ret = ogGetImageInfo (args.imgfile)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from ImageLib import ogGetImageProgram
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('container')
parser.add_argument ('filename')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetImageProgram', 'ogGetImageProgram str_repo path_image', ['ogGetImageProgram REPO prueba'])
sys.exit (0)
args = parser.parse_args()
ret = ogGetImageProgram (args.container, args.filename)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from ImageLib import ogGetImageSize
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('repo')
parser.add_argument ('imgname')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetImageSize', 'ogGetImageSize str_repo path_image', ['ogGetImageSize REPO prueba'])
sys.exit (0)
args = parser.parse_args()
ret = ogGetImageSize (args.repo, args.imgname)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from ImageLib import ogGetImageType
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('repo')
parser.add_argument ('imgname')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetImageType', 'ogGetImageType str_repo path_image', ['ogGetImageType REPO prueba'])
sys.exit (0)
args = parser.parse_args()
ret = ogGetImageType (args.repo, args.imgname)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,22 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from NetLib import ogGetIpAddress
parser = argparse.ArgumentParser (add_help=False)
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetIpAddress')
sys.exit (0)
args = parser.parse_args()
ret = ogGetIpAddress ()
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,30 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from DiskLib import ogGetLastSector
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetLastSector', 'ogGetLastSector int_ndisk [int_npart]', ['ogGetLastSector 1'], ['ogGetLastSector 1 1'])
sys.exit (0)
parser = argparse.ArgumentParser (add_help=False)
if 2 == len (sys.argv):
parser.add_argument ('disk')
elif 3 == len (sys.argv):
parser.add_argument ('disk')
parser.add_argument ('par')
args = parser.parse_args()
if 2 == len (sys.argv):
ret = ogGetLastSector (args.disk)
elif 3 == len (sys.argv):
ret = ogGetLastSector (args.disk, args.par)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,22 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from NetLib import ogGetMacAddress
parser = argparse.ArgumentParser (add_help=False)
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetMacAddress')
sys.exit (0)
args = parser.parse_args()
ret = ogGetMacAddress ()
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from FileSystemLib import ogGetMountPoint
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('par')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetMountPoint', 'ogGetMountPoint int_ndisk int_nfilesys', ['ogGetMountPoint 1 1'])
sys.exit (0)
args = parser.parse_args()
ret = ogGetMountPoint (args.disk, args.par)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from InventoryLib import ogGetOsType
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('partition')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetOsType', 'ogGetOsType int_ndisk int_npartition', ['ogGetOsType 1 2'])
sys.exit (0)
args = parser.parse_args()
ret = ogGetOsType (args.disk, args.partition)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from InventoryLib import ogGetOsUuid
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('par')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetOsUuid', 'ogGetOsUuid int_ndisk int_nfilesys', ['ogGetOsUuid 1 2'])
sys.exit (0)
args = parser.parse_args()
ret = ogGetOsUuid (args.disk, args.par)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from InventoryLib import ogGetOsVersion
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('part')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetOsVersion', 'ogGetOsVersion int_ndisk int_nfilesys', ['ogGetOsVersion 1 2'])
sys.exit (0)
args = parser.parse_args()
ret = ogGetOsVersion (args.disk, args.part)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,32 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from FileLib import ogGetParentPath
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetParentPath', 'ogGetParentPath [ str_repo | int_ndisk int_npartition ] path_filepath', ['ogGetParentPath /mnt/sda1/windows/system32', 'ogGetPath REPO /etc/fstab', 'ogGetPath 1 1 /windows/system32'])
sys.exit (0)
parser = argparse.ArgumentParser (add_help=False)
if 3 == len (sys.argv):
parser.add_argument ('src', nargs='?', default=None)
parser.add_argument ('file', nargs='?', default=None)
elif 4 == len (sys.argv):
parser.add_argument ('disk', nargs='?', default=None)
parser.add_argument ('par', nargs='?', default=None)
parser.add_argument ('file', nargs='?', default=None)
args = parser.parse_args()
if 3 == len (sys.argv):
ret = ogGetParentPath (src=args.src, file=args.file)
elif 4 == len (sys.argv):
ret = ogGetParentPath (src=f'{args.disk} {args.par}', file=args.file)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,22 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from DiskLib import ogGetPartitionActive
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetPartitionActive', 'ogGetPartitionActive int_ndisk', ['ogGetPartitionActive 1'])
sys.exit (0)
args = parser.parse_args()
ret = ogGetPartitionActive (args.disk)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from DiskLib import ogGetPartitionId
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('par')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetPartitionId', 'ogGetPartitionId int_ndisk int_npartition', ['ogGetPartitionId 1 1'])
sys.exit (0)
args = parser.parse_args()
ret = ogGetPartitionId (args.disk, args.par)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
import sys
import argparse
from SystemLib import ogHelp
from DiskLib import ogGetPartitionSize
parser = argparse.ArgumentParser (add_help=False)
parser.add_argument ('disk')
parser.add_argument ('par')
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
#parser.print_help() sale en inglés aunque la locale indique otra cosa
ogHelp ('ogGetPartitionSize', 'ogGetPartitionSize int_ndisk int_npartition', ['ogGetPartitionSize 1 1'])
sys.exit (0)
args = parser.parse_args()
ret = ogGetPartitionSize (args.disk, args.par)
if ret is not None:
if ret == True: sys.exit (0)
elif ret == False: sys.exit (1)
else: print (ret)

Some files were not shown because too many files have changed in this diff Show More