refs #840 Review and correction of bugs in migrated code

pull/2/head
Antonio Guerrero 2024-10-16 05:10:24 +00:00
commit c113468f71
18 changed files with 4125 additions and 0 deletions

View File

@ -0,0 +1,254 @@
import subprocess
import sys
import os
from engine.FileLib import *
from engine.SystemLib import *
def ogChangeRepo():
SRCIMG = ""
NEWREPO = ""
REPO = ""
OGUNIT = ""
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
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]
# 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"
# 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()
# Parametros de entrada. Si $1 = "REPO" dejo el repositorio actual
if sys.argv[1].upper() == "REPO":
NEWREPO = REPO
# 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(["source", "/scripts/functions"], shell=True)
subprocess.run(["source", "/scripts/ogfunctions"], shell=True)
subprocess.run(["umount", OGIMG])
if sys.argv[2] == "":
SRCIMG = "ogimages"
else:
SRCIMG = "ogimages/" + sys.argv[2]
subprocess.run(["eval", "$(grep \"OPTIONS=\" /scripts/ogfunctions)"])
ogEcho("session", "log", MSG_HELP_ogChangeRepo + " " + NEWREPO + " " + sys.argv[2].rstrip())
ogConnect(NEWREPO, ogprotocol, SRCIMG, OGIMG, RW)
# 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 = ""
if len(sys.argv) < 2:
ogHelp("ogGetGroupDir", "ogGetGroupDir str_repo", "ogGetGroupDir REPO ==> /opt/opengnsys/images/groups/Grupo1")
return
if len(sys.argv) == 1:
REPO = "REPO"
else:
REPO = sys.argv[1]
GROUP = ogGetGroupName()
if GROUP:
DIR = ogGetPath(REPO, "/groups/" + GROUP, stderr=subprocess.DEVNULL)
if os.path.isdir(DIR):
print(DIR)
return 0
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
def ogGetHostname():
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:
for line in f:
if "option host-name" in line:
HOST = line.split('"')[1]
break
# 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)
if HOSTNAME != HOST:
os.environ["HOSTNAME"] = HOST
if HOST:
print(HOST)
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 = [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.
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]
# Mostrar solo la primera.
if MAC:
print(MAC[0])
return 0
def ogGetNetInterface():
if len(sys.argv) >= 2 and sys.argv[1] == "help":
ogHelp("ogGetNetInterface", "ogGetNetInterface", "ogGetNetInterface => eth0")
return
if "DEVICE" in os.environ:
print(os.environ["DEVICE"])
return 0
def ogGetRepoIp():
# Variables locales.
SOURCE = ""
FSTYPE = ""
# Mostrar ayuda.
if len(sys.argv) >= 2 and sys.argv[1] == "help":
ogHelp("ogGetRepoIp", "ogGetRepoIp", "ogGetRepoIp => 192.168.0.2")
return
# 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
def ogGetServerIp():
# Variables locales.
SOURCE = ""
FSTYPE = ""
# Mostrar ayuda.
if len(sys.argv) >= 2 and sys.argv[1] == "help":
ogHelp("ogGetServerIp", "ogGetServerIp", "ogGetServerIp => 192.168.0.2")
return
# 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
def ogMakeGroupDir():
REPO = ""
DIR = ""
GROUP = ""
if len(sys.argv) < 2:
ogHelp("ogMakeGroupDir", "ogMakeGroupDir str_repo", "ogMakeGroupDir", "ogMakeGroupDir REPO")
return
if len(sys.argv) == 1:
REPO = "REPO"
else:
REPO = sys.argv[1]
DIR = ogGetPath(REPO, "/groups/" + ogGetGroupName(), stderr=subprocess.DEVNULL)
if DIR:
subprocess.run(["mkdir", "-p", DIR], stderr=subprocess.DEVNULL)
return 0

View File

View File

@ -0,0 +1,59 @@
import os
import subprocess
print (">>>>>>>>>>>>>>>>>>>> Load ", __name__, " <<<<<<<<<<<<<<<<<<<<<<")
print("==============================================")
print("OpenGnsys Clonning Engine Start...")
# Cargar entorno de OpenGnsys
#os.environ['OGETC'] = '/opt/opengnsys/etc' #Entorno opengnsys
os.environ['OGETC'] = 'etc' #Pruebas locales
print (f"OGETC: {os.environ['OGETC']}")
os.environ['PYTHONUNBUFFERED'] = '1'
print (f"PYTHONUNBUFFERED: {os.environ['PYTHONUNBUFFERED']}")
#loadenviron_path = os.path.join(os.environ['OGETC'], 'preinit', 'loadenviron.sh')
loadenviron_path = os.path.join(os.environ['OGETC'], 'preinit', 'loadenviron.py')
print (f"loadenviron_path: {loadenviron_path}")
print ("s//////////////////////////////////////////////////")
# Ejecutar el script y cargar las variables de entorno en Python
exec(open(loadenviron_path).read())
# Configurar las variables de entorno globales
for key, value in globals().items():
if isinstance(value, str):
os.environ[key] = value
print ("Variables de entorno cargadas desde loadenviron.py")
# Ejecutar un subproceso que utilizará las nuevas variables de entorno
################################################################################subprocess.run(['bash', '-c', 'env'], shell=True)
# Scripts de inicio
print ("step 2.1 >>>>>>>>>>>>>>>>>>>>>>>>>>")
scripts = ['fileslinks', 'loadmodules', 'metadevs', 'mountrepo', 'poweroff', 'otherservices']
for script in scripts:
script_path = os.path.join(os.environ['OGETC'], 'preinit', f'{script}.py')
print (f"<<<<<< script_path: {script_path}")
#subprocess.run(['bash', script_path])
subprocess.run(['python3', script_path])
print ("step 2.2 >>>>>>>>>>>>>>>>>>>>>>>>>>")
# Check and run the appropriate init script
init_scripts = [
os.path.join(os.environ['OGETC'], 'init', f'{os.environ.get("IPV4ADDR", "")}.sh'),
os.path.join(os.environ['OGETC'], 'init', f'{os.environ.get("OGGROUP", "")}.sh'),
os.path.join(os.environ['OGETC'], 'init', 'default.sh')
]
print ("step 2.3 >>>>>>>>>>>>>>>>>>>>>>>>>>")
for script in init_scripts:
if os.path.isfile(script):
subprocess.run(['bash', script])
break
else:
print("No se ha encontrado script de inicio (RUN halt)")
#subprocess.run(['halt'])
print("OpenGnsys Clonning Engine End.")
print("==============================================")

View File

@ -0,0 +1,74 @@
import os
import shutil
import stat
# Si está configurado OpenGnsys ...
if os.getenv("OPENGNSYS"):
print(os.getenv("MSG_MAKELINKS", "."))
# Shell BASH por defecto (para usar "runtest")
try:
os.symlink('/bin/bash', '/bin/sh')
except FileExistsError:
pass
# Crear directorio de bloqueos
os.makedirs('/var/lock', exist_ok=True)
if not os.path.exists('/var/lock'):
os.makedirs('/run/lock', exist_ok=True)
# Crear ficheros temporales.
oglogcommand = os.getenv("OGLOGCOMMAND")
oglogsession = os.getenv("OGLOGSESSION")
temp_files = [oglogcommand, f"{oglogcommand}.tmp", oglogsession, "/tmp/menu.tmp"]
for temp_file in temp_files:
with open(temp_file, 'a'):
os.utime(temp_file, None)
os.chmod(temp_file, 0o777)
#####################################################################################
##### Pendiente instalar Qt5 en el sistema y crear enlaces simbólicos a las librerías
# Enlaces para Qt Embeded. ######################################################
qtdir = "/usr/local"
os.makedirs(os.path.join(qtdir, 'etc'), exist_ok=True)
os.makedirs(os.path.join(qtdir, 'lib'), exist_ok=True)
os.makedirs(os.path.join(qtdir, 'plugins'), exist_ok=True)
oglib = os.getenv("OGLIB")
for i in os.listdir(os.path.join(oglib, 'qtlib')) + [os.path.join(oglib, 'fonts')]:
src = os.path.join(oglib, 'qtlib', i)
dst = os.path.join(qtdir, 'lib', i)
if not os.path.exists(dst):
try:
os.symlink(src, dst)
except FileExistsError:
pass
for i in os.listdir(os.path.join(oglib, 'qtplugins')):
src = os.path.join(oglib, 'qtplugins', i)
dst = os.path.join(qtdir, 'plugins', i)
if not os.path.exists(dst):
try:
os.symlink(src, dst)
except FileExistsError:
pass
ogetc = os.getenv("OGETC")
for i in os.listdir(ogetc):
if i.endswith('.qmap'):
src = os.path.join(ogetc, i)
dst = os.path.join(qtdir, 'etc', i)
if not os.path.exists(dst):
try:
os.symlink(src, dst)
except FileExistsError:
pass
# Autenticación con clave pública para SSH
if os.path.isfile('/scripts/ssl/authorized_keys'):
for file in os.listdir('/scripts/ssl'):
shutil.copy(os.path.join('/scripts/ssl', file), '/root/.ssh')
else:
# FIXME Error: entorno de OpenGnsys no configurado.
print("Error: OpenGnsys environment is not configured.") # FIXME: definir mensaje.
exit(1)

View File

@ -0,0 +1,215 @@
import os
import subprocess
import sys
sys.path.append('/opt/opengnsys/client/lib/engine/bin')
from NetLib import *
print(f"##################+++++++++++++++ {sys.path} ++++++++++++++################3")
print(" ")
print("=============== path =================")
print("-- step 0")
print(sys.path)
#!/usr/bin/env python3
# Cargar API de funciones.
def execute_lib_file(filepath):
with open(filepath) as f:
code = compile(f.read(), filepath, 'exec')
exec(code, globals())
print("=============== START LOAD ENVIRONMENT =================")
# Idioma por defecto.
os.environ["LANG"] = os.getenv("LANG", "es_ES")
print("-- step 2")
os.environ["LC_ALL"] = os.getenv("LC_ALL", os.environ["LANG"])
print("-- step 3")
result = subprocess.run(["locale-gen", os.environ["LANG"]], capture_output=True, text=True)
if result.returncode != 0:
print(f"Error generating locale: {result.stderr}")
print("-- step 4")
print("-- step 5")
# Directorios del proyecto OpenGnsys.
os.environ["OPENGNSYS"] = os.getenv("OPENGNSYS", "/opt/opengnsys")
opengnsys_path = os.environ['OPENGNSYS']
print(f"OPENGNSYS Directory: {opengnsys_path}")
print("-- step 6")
print (f"OPENGNSYS: {os.environ['OPENGNSYS']}")
if os.path.isdir(os.environ["OPENGNSYS"]):
print("OPENGNSYS directory found")
os.environ["OGBIN"] = os.path.join(os.environ["OPENGNSYS"], "bin")
os.environ["OGETC"] = os.path.join(os.environ["OPENGNSYS"], "etc")
os.environ["OGLIB"] = os.path.join(os.environ["OPENGNSYS"], "lib")
os.environ["OGAPI"] = os.path.join(os.environ["OGLIB"], "engine", "bin")
os.environ["OGSCRIPTS"] = os.path.join(os.environ["OPENGNSYS"], "scripts")
os.environ["OGIMG"] = os.path.join(os.environ["OPENGNSYS"], "images")
os.environ["OGCAC"] = os.path.join(os.environ["OPENGNSYS"], "cache")
os.environ["OGLOG"] = os.path.join(os.environ["OPENGNSYS"], "log")
os.environ["PATH"] = os.pathsep.join([
os.environ["PATH"],
"/sbin",
"/usr/sbin",
"/usr/local/sbin",
"/bin",
"/usr/bin",
"/usr/local/bin",
"/opt/oglive/rootfs/opt/drbl/sbin",
os.environ["OGSCRIPTS"],
os.environ["OGAPI"],
os.environ["OGBIN"]
])
print("-- step 7")
# Exportar parámetros del kernel.
with open("/proc/cmdline") as f:
for i in f.read().split():
if "=" in i:
key, value = i.split("=", 1)
os.environ[key] = value
print("-- step 8")
# Cargar fichero de idioma.
lang_file = os.path.join(os.environ["OGETC"], f"lang.{os.environ['LANG'].split('@')[0]}.conf")
if os.path.isfile(lang_file):
with open(lang_file) as f:
for line in f:
if "=" in line:
key, value = line.strip().split("=", 1)
os.environ[key] = value
print("-- step 9")
# Mensaje de carga del entorno.
print(os.getenv("MSG_LOADAPI", "."))
print("-- step 10")
# Cargar mapa de teclado.
subprocess.run(["loadkeys", os.environ["LANG"].split("_")[0]], stdout=subprocess.DEVNULL)
print("-- step 10.1")
# Imprimir todas las variables de entorno declaradas hasta el momento.
for key, value in os.environ.items():
print(f"{key}: {value}")
print("-- step 11")
for lib_file in os.listdir(os.environ["OGAPI"]):
if lib_file.endswith(".lib"):
execute_lib_file(os.path.join(os.environ["OGAPI"], lib_file))
# for lib_file in os.listdir(os.environ["OGAPI"]):
# if lib_file.endswith(".lib"):
# exec(open(os.path.join(os.environ["OGAPI"], lib_file)).read())
print("-- step 12")
# Cargar configuración del engine.
engine_cfg = os.path.join(os.environ["OGETC"], "engine.cfg")
if os.path.isfile(engine_cfg):
exec(open(engine_cfg).read())
os.environ["OGLOGCOMMAND"] = os.getenv("OGLOGCOMMAND", "/tmp/command.log")
os.environ["OGLOGSESSION"] = os.getenv("OGLOGSESSION", "/tmp/session.log")
print("-- step 13")
# Cargar las APIs según engine.
ogengine = os.getenv("ogengine")
if ogengine:
for api_file in os.listdir(os.environ["OGAPI"]):
if api_file.endswith(f".{ogengine}"):
exec(open(os.path.join(os.environ["OGAPI"], api_file)).read())
print("-- step 14")
# Configuración de la red (modo offline).
initrd_cfg = "/tmp/initrd.cfg"
if os.path.isfile(initrd_cfg):
with open(initrd_cfg) as f:
for line in f:
if line.startswith("DEVICECFG="):
device_cfg = line.strip().split("=", 1)[1]
os.environ["DEVICECFG"] = device_cfg
if os.path.isfile(device_cfg):
exec(open(device_cfg).read())
print("-- step 15")
# FIXME Pruebas para grupos de ordenadores
os.environ["OGGROUP"] = os.getenv("group", "")
print("-- step 16")
root_repo = os.getenv("ROOTREPO", os.getenv("OGSERVERIMAGES"))
print(f"-- step 17",ogGetIpAddress())
# Fichero de registros.
og_log_file = os.path.join(os.environ["OGLOG"], f"{ogGetIpAddress()}.log")
os.environ["OGLOGFILE"] = og_log_file
else:
print("ERROR: OPENGNSYS directory not found")
print("-- step 18")
# Compatibilidad para usar proxy en clientes ogLive.
if not os.getenv("http_proxy") and os.getenv("ogproxy"):
os.environ["http_proxy"] = os.getenv("ogproxy")
print("-- step 19")
# Compatibilidad para usar servidor DNS en clientes ogLive.
if not os.path.isfile("/run/resolvconf/resolv.conf") and os.getenv("ogdns"):
os.makedirs("/run/resolvconf", exist_ok=True)
with open("/run/resolvconf/resolv.conf", "w") as f:
f.write(f"nameserver {os.getenv('ogdns')}\n")
print("-- step 20")
# Declaración de códigos de error.
error_codes = {
"OG_ERR_FORMAT": 1,
"OG_ERR_NOTFOUND": 2,
"OG_ERR_PARTITION": 3,
"OG_ERR_LOCKED": 4,
"OG_ERR_IMAGE": 5,
"OG_ERR_NOTOS": 6,
"OG_ERR_NOTEXEC": 7,
"OG_ERR_NOTWRITE": 14,
"OG_ERR_NOTCACHE": 15,
"OG_ERR_CACHESIZE": 16,
"OG_ERR_REDUCEFS": 17,
"OG_ERR_EXTENDFS": 18,
"OG_ERR_OUTOFLIMIT": 19,
"OG_ERR_FILESYS": 20,
"OG_ERR_CACHE": 21,
"OG_ERR_NOGPT": 22,
"OG_ERR_REPO": 23,
"OG_ERR_NOMSDOS": 24,
"OG_ERR_IMGSIZEPARTITION": 30,
"OG_ERR_UPDATECACHE": 31,
"OG_ERR_DONTFORMAT": 32,
"OG_ERR_IMAGEFILE": 33,
"OG_ERR_GENERIC": 40,
"OG_ERR_UCASTSYNTAXT": 50,
"OG_ERR_UCASTSENDPARTITION": 51,
"OG_ERR_UCASTSENDFILE": 52,
"OG_ERR_UCASTRECEIVERPARTITION": 53,
"OG_ERR_UCASTRECEIVERFILE": 54,
"OG_ERR_MCASTSYNTAXT": 55,
"OG_ERR_MCASTSENDFILE": 56,
"OG_ERR_MCASTRECEIVERFILE": 57,
"OG_ERR_MCASTSENDPARTITION": 58,
"OG_ERR_MCASTRECEIVERPARTITION": 59,
"OG_ERR_PROTOCOLJOINMASTER": 60,
"OG_ERR_DONTMOUNT_IMAGE": 70,
"OG_ERR_DONTSYNC_IMAGE": 71,
"OG_ERR_DONTUNMOUNT_IMAGE": 72,
"OG_ERR_NOTDIFFERENT": 73,
"OG_ERR_SYNCHRONIZING": 74,
"OG_ERR_NOTUEFI": 80,
"OG_ERR_NOTBIOS": 81
}
print("-- step 20")
for key, value in error_codes.items():
os.environ[key] = str(value)

View File

@ -0,0 +1,29 @@
#!/usr/bin/env python3
import os
import subprocess
import glob
"""
@file loadmodules.py
@brief Script de inicio para cargar módulos complementarios del kernel.
@version 1.0.5 - Cargar módulos específicos para el cliente.
"""
def main():
msg_loadmodules = os.getenv('MSG_LOADMODULES', '.')
print(msg_loadmodules)
# Módulo del ratón.
subprocess.run(['modprobe', 'psmouse'], stderr=subprocess.DEVNULL)
# Cargar módulos específicos del kernel del cliente.
kernel_version = os.uname().release
module_path = os.path.join(os.getenv('OGLIB', ''), 'modules', kernel_version, '*.ko')
for module in glob.glob(module_path):
if os.access(module, os.R_OK):
subprocess.run(['insmod', module], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,32 @@
import os
import subprocess
import sys
#!/usr/bin/env python3
"""
@file metadevs.py
@brief Script de inicio para detectar metadispositivos LVM y RAID.
@note Desglose del script "loadenviron.sh".
@warning License: GNU GPLv3+
"""
def main():
opengnsys = os.getenv('OPENGNSYS')
print(f"____________________________________ OpenGnsys environment: {opengnsys}")
msg_detectlvmraid = os.getenv('MSG_DETECTLVMRAID', '')
print(f"____________________________________ Message: {msg_detectlvmraid}")
if opengnsys:
print(msg_detectlvmraid)
# Detectar metadispositivos LVM.
subprocess.run(['vgchange', '-ay'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
# Detectar metadispositivos RAID.
subprocess.run(['dmraid', '-ay'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
else:
# FIXME Error: entorno de OpenGnsys no configurado.
print("Error: OpenGnsys environment is not configured.") # FIXME: definir mensaje.
sys.exit(1)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,62 @@
#!/usr/bin/env python3
import os
import subprocess
#/**
# @file mountrepo.py
# @brief Script para montar el repositorio de datos remoto.
#*/
OGIMG = os.getenv('OGIMG', '/opt/opengnsys/images')
ROOTREPO = os.getenv('ROOTREPO', os.getenv('ROOTSERVER'))
ogactiveadmin = os.getenv('ogactiveadmin')
ogprotocol = os.getenv('ogprotocol', 'smb')
ogunit = os.getenv('ogunit', '')
ogstatus = os.getenv('ogstatus')
SERVER = os.getenv('SERVER')
OGCAC = os.getenv('OGCAC')
MSG_MOUNTREPO = "Mounting repository using protocol: {} in mode: {}"
def mount_repo():
if ogactiveadmin == "true":
os.environ['boot'] = 'admin' # ATENCIÓN: siempre en modo "admin".
subprocess.run(['umount', OGIMG], stderr=subprocess.DEVNULL)
protocol = ogprotocol
OGUNIT = f"/{ogunit}" if ogunit else ""
print(MSG_MOUNTREPO.format(protocol, 'admin'))
if protocol == 'nfs':
subprocess.run(['mount.nfs', f'{ROOTREPO}:{OGIMG}{OGUNIT}', OGIMG, '-o', 'rw,nolock'])
elif protocol == 'smb':
PASS = get_password()
subprocess.run(['mount.cifs', f'//{ROOTREPO}/ogimages{OGUNIT}', OGIMG, '-o', f'rw,serverino,acl,username=opengnsys,password={PASS}'])
elif protocol == 'local':
handle_local_mount()
def get_password():
try:
with open('/scripts/ogfunctions') as f:
for line in f:
if 'OPTIONS=' in line:
return line.split('pass=')[1].split()[0]
except Exception:
pass
return 'og'
def handle_local_mount():
if ogstatus == "offline" or not SERVER:
TYPE = subprocess.getoutput("blkid | grep REPO | awk -F'TYPE=' '{print $2}' | tr -d '\"'")
if not TYPE:
if os.path.isdir(f'{OGCAC}/{OGIMG}'):
subprocess.run(['mount', '--bind', f'{OGCAC}/{OGIMG}', OGIMG])
else:
subprocess.run(['mount', '-t', TYPE, 'LABEL=REPO', OGIMG], stderr=subprocess.DEVNULL)
else:
if subprocess.run(['smbclient', '-L', SERVER, '-N'], stderr=subprocess.DEVNULL).returncode == 0:
PASS = get_password()
subprocess.run(['mount.cifs', f'//{ROOTREPO}/ogimages', OGIMG, '-o', f'rw,serverino,acl,username=opengnsys,password={PASS}'])
if __name__ == "__main__":
mount_repo()

View File

@ -0,0 +1,44 @@
#!/usr/bin/env python3
import os
import subprocess
"""
@file otherservices.py
@brief Script de inicio para cargar otros servicios complementarios.
"""
# Lanzar servicios complementarios del cliente.
print(os.getenv('MSG_OTHERSERVICES', '.'))
# Iniciar rsyslog, si es necesario.
if not os.path.exists('/dev/log'):
subprocess.run(['service', 'rsyslog', 'start'])
# Adpatar la clave de "root" para acceso SSH.
with open('/scripts/ogfunctions', 'r') as file:
for line in file:
if 'OPTIONS=' in line:
pass_option = line.split('pass=')[1].split()[0]
break
else:
pass_option = 'og'
passwd = pass_option or 'og'
subprocess.run(['passwd', 'root'], input=f'{passwd}\n{passwd}\n', text=True)
# Cargar el entorno OpenGnsys en conexión SSH.
subprocess.run(['cp', '-a', f'{os.getenv("OPENGNSYS")}/etc/preinit/loadenviron.py', '/etc/profile.d/'])
# Arrancar SSH.
subprocess.run(['/etc/init.d/ssh', 'start'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
# Desactivado apagado de monitor.
# subprocess.run(['setterm', '-blank', '0', '-powersave', 'off', '-powerdown', '0'], stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
# Activado WOL en la interfaz usada en arranque PXE.
subprocess.run(['ethtool', '-s', os.getenv('DEVICE'), 'wol', 'g'], stderr=subprocess.DEVNULL)
# TODO Localizar correctamente el script de arranque.
if os.path.isfile('/opt/opengnsys/scripts/runhttplog.sh'):
subprocess.run(['/opt/opengnsys/scripts/runhttplog.sh'], stderr=subprocess.DEVNULL)

View File

@ -0,0 +1,52 @@
#!/usr/bin/env python3
import os
import subprocess
import sys
"""
@file poweroff.py
@brief Script de inicio para cargar el proceso comprobación de clientes inactivos.
@note Arranca y configura el proceso "cron".
"""
def main():
opengnsys = os.getenv('OPENGNSYS')
if opengnsys:
msg_poweroffconf = os.getenv('MSG_POWEROFFCONF', '.')
print(msg_poweroffconf)
ogntp = os.getenv('ogntp')
status = os.getenv('status')
# Sincronización horaria con servidor NTP.
if ogntp and status != "offline":
subprocess.run(['ntpdate', ogntp])
# Crear fichero de configuración por defecto (30 min. de espera).
poweroff_conf = '/etc/poweroff.conf'
with open(poweroff_conf, 'w') as f:
f.write("POWEROFFSLEEP=30\nPOWEROFFTIME=\n")
# Incluir zona horaria en el fichero de configuración.
with open('/proc/cmdline') as f:
cmdline = f.read()
tz = ' '.join([x for x in cmdline.split() if x.startswith('TZ=')])
with open(poweroff_conf, 'a') as f:
f.write(tz + '\n')
# Lanzar el proceso "cron".
subprocess.run(['cron', '-l'])
# Definir la "crontab" lanzando el proceso de comprobación cada minuto.
ogbin = os.getenv('OGBIN')
crontab_line = f"* * * * * [ -x {ogbin}/poweroffconf ] && {ogbin}/poweroffconf\n"
subprocess.run(['crontab', '-'], input=crontab_line, text=True)
else:
# FIXME Error: entorno de OpenGnsys no configurado.
print("Error: OpenGnsys environment is not configured.") # FIXME: definir mensaje.
sys.exit(1)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,212 @@
import os
import re
import subprocess
import shutil
import sys
import platform
from FileSystemLib import *
from SystemLib import *
from DiskLib import *
print (">>>>>>>>>>>>>>>>>>>> Load ", __name__, " <<<<<<<<<<<<<<<<<<<<<<")
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é.
"""
if partsize is None:
raise ValueError("El tamaño de la partición debe especificarse.")
# 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.")
# 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:
return None
return None
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)
return
disk = ogDiskToDev(cachepart)
# 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}")
# Crear estructura básica.
mntdir = ogMountCache()
os.makedirs(os.path.join(mntdir, OGIMG), exist_ok=True)
# Incluir kernel e Initrd del ogLive
updateBootCache()
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)
# Devuelve tamaño de la partición de caché.
return ogGetPartitionSize(cachepart)
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)
# 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}")
# 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}")
# Calcular el espacio libre en kilobytes.
if end_sector_part3 > total_sectors // 2:
free_space_kb = (total_sectors - end_sector_part3) // 2
else:
free_space_kb = total_sectors // 4
return free_space_kb
def ogMountCache():
"""
Monta la partición de caché en el directorio /mnt/sda4.
: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")
# 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}")
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é.")
# 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}")
# Eliminar el enlace simbólico de /mnt/ParticiónCache.
os.remove(f"/mnt/{cachepart}")

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,293 @@
import subprocess
import os
import shutil
print (">>>>>>>>>>>>>>>>>>>> Load ", __name__, " <<<<<<<<<<<<<<<<<<<<<<")
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")
return
# Get the file path
file_path = ogGetPath(*args)
if not file_path:
ogRaiseError(OG_ERR_NOTFOUND, *args)
return
# Calculate the checksum
result = subprocess.run(["tail", "-c1M", file_path], capture_output=True)
checksum = result.stdout.decode().split()[0]
return checksum
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")
return
ARGS = args
if args[0].startswith("/"):
# Camino completo. */ (Comentario 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:]
TARGET = ogGetPath(*args)
try:
with open(f"{SOURCE}.sum", "r") as source_file:
source_checksum = source_file.read().strip()
with open(f"{TARGET}.sum", "r") as target_file:
target_checksum = target_file.read().strip()
return source_checksum == target_checksum
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
# Calculate the checksum
result = subprocess.run(["md5sum", FILE, "-b"], capture_output=True)
checksum = result.stdout.decode().split()[0]
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:]
TARGET = ogGetPath(*args)
# Comprobar fichero origen y directorio destino.
if not SOURCE:
ogRaiseError(OG_ERR_NOTFOUND, *args[:-1])
return
if not TARGET:
ogRaiseError(OG_ERR_NOTFOUND, *args)
return
# 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])
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
# 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])
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])
else:
ogRaiseError(OG_ERR_FORMAT)
return
# Eliminar caracteres \c / duplicados y finales.
FILE = os.path.normpath(FILE)
# Comprobar si existe el fichero para reducir tiempos.
if os.path.exists(FILE):
FILEPATH = FILE
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:])
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")
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]}')}"
else:
ogRaiseError(OG_ERR_FORMAT)
return
return ogGetPath(PARENT)
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")
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:]
TARGET = ogGetPath(*args)
# Comprobar que existen los ficheros origen y destino.
if not SOURCE:
ogRaiseError(OG_ERR_NOTFOUND, *args[:-1])
return
if not TARGET:
ogRaiseError(OG_ERR_NOTFOUND, *args)
return
# Devolver si el primer fichero se ha modificado después que el segundo.
return os.path.getmtime(SOURCE) > os.path.getmtime(TARGET)
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")
return
# Comprobar que existe el fichero y guardar su checksum.
FILE = ogGetPath(*args)
if not FILE:
ogRaiseError(OG_ERR_NOTFOUND, *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
DIR = os.path.basename(args[-1])
os.makedirs(os.path.join(PARENT, DIR), exist_ok=True)

View File

@ -0,0 +1,831 @@
import subprocess
import sys
from SystemLib import *
from DiskLib import *
from CacheLib import *
print (">>>>>>>>>>>>>>>>>>>> Load ", __name__, " <<<<<<<<<<<<<<<<<<<<<<")
def ogCheckFs(int_ndisk, int_nfilesys):
# Si se solicita, mostrar ayuda.
if int_ndisk == "help":
ogHelp("ogCheckFs", "ogCheckFs int_ndisk int_nfilesys", "ogCheckFs 1 1")
return
# Error si no se reciben 2 parámetros.
if len(sys.argv) != 3:
ogRaiseError(OG_ERR_FORMAT)
return
# Obtener partición.
PART = ogDiskToDev(int_ndisk, int_nfilesys)
if not PART:
return
TYPE = ogGetFsType(int_ndisk, int_nfilesys)
if TYPE == "EXT[234]" or TYPE == "CACHE":
PROG = "e2fsck"
PARAMS = "-y"
CODES = [1, 2]
elif TYPE == "BTRFS":
PROG = "btrfsck"
CODES = [1]
elif TYPE == "REISERFS":
PROG = "fsck.reiserfs"
PARAMS = "<<<\"Yes\""
CODES = [1, 2]
elif TYPE == "REISER4":
PROG = "fsck.reiser4"
PARAMS = "-ay"
elif TYPE == "JFS":
PROG = "fsck.jfs"
CODES = [1, 2]
elif TYPE == "XFS":
PROG = "xfs_repair"
elif TYPE == "F2FS":
PROG = "fsck.f2fs"
elif TYPE == "NTFS":
PROG = "ntfsfix"
elif TYPE == "EXFAT":
PROG = "fsck.exfat"
elif TYPE == "FAT32":
PROG = "dosfsck"
PARAMS = "-a"
CODES = [1]
elif TYPE == "FAT16":
PROG = "dosfsck"
PARAMS = "-a"
CODES = [1]
elif TYPE == "FAT12":
PROG = "dosfsck"
PARAMS = "-a"
CODES = [1]
elif TYPE == "HFS":
PROG = "fsck.hfs"
PARAMS = "-f"
elif TYPE == "HFSPLUS":
PROG = "fsck.hfs"
PARAMS = "-f"
elif TYPE == "UFS":
PROG = "fsck.ufs"
elif TYPE == "ZFS":
PROG = "fsck.zfs"
else:
ogRaiseError(OG_ERR_PARTITION, f"{int_ndisk}, {int_nfilesys}")
return
# Error si el sistema de archivos esta montado o bloqueado.
ogUnmount(int_ndisk, int_nfilesys)
if ogIsMounted(int_ndisk, int_nfilesys):
ogRaiseError(OG_ERR_PARTITION, f"{int_ndisk} {int_nfilesys}")
return
if ogIsLocked(int_ndisk, int_nfilesys):
ogRaiseError(OG_ERR_LOCKED, f"{int_ndisk} {int_nfilesys}")
return
# Comprobar en modo uso exclusivo.
ogLock(int_ndisk, int_nfilesys)
try:
result = subprocess.run([PROG, PARAMS, PART], capture_output=True)
ERRCODE = result.returncode
except FileNotFoundError:
ogRaiseError(OG_ERR_NOTEXEC, PROG)
ERRCODE = OG_ERR_NOTEXEC
except:
ogRaiseError(OG_ERR_PARTITION, f"{int_ndisk} {int_nfilesys}")
ERRCODE = OG_ERR_PARTITION
ogUnlock(int_ndisk, int_nfilesys)
return ERRCODE
def ogExtendFs():
# Si se solicita, mostrar ayuda.
if len(sys.argv) == 2 and sys.argv[1] == "help":
ogHelp("ogExtendFs", "ogExtendFs int_ndisk int_nfilesys", "ogExtendFs 1 1")
return
# Error si no se reciben 2 parámetros.
if len(sys.argv) != 3:
ogRaiseError(OG_ERR_FORMAT)
return
# Obtener partición.
PART = ogDiskToDev(int(sys.argv[1]), int(sys.argv[2]))
if not PART:
return
# Redimensionar al tamaño máximo según el tipo de partición.
TYPE = ogGetFsType(int(sys.argv[1]), int(sys.argv[2]))
if TYPE == "EXT[234]":
PROG = "resize2fs"
PARAMS = "-f"
elif TYPE == "BTRFS":
PROG = "btrfs"
PARAMS = "filesystem resize max"
DOMOUNT = True # Debe estar montado.
elif TYPE == "REISERFS" or TYPE == "REISER4":
PROG = "resize_reiserfs"
PARAMS = "-f"
elif TYPE == "F2FS" or TYPE == "JFS" or TYPE == "NILFS2" or TYPE == "XFS" or TYPE == "EXFAT" or TYPE == "FAT32" or TYPE == "FAT16" or TYPE == "HFS" or TYPE == "HFSPLUS" or TYPE == "UFS":
return # No se reduce (por el momento).
elif TYPE == "NTFS":
PROG = "ntfsresize"
PARAMS = "<<<\"y\" -f"
else:
ogRaiseError(OG_ERR_PARTITION, f"{int(sys.argv[1])} {int(sys.argv[2])} {TYPE}")
return
# Salida normal si no se va a aplicar la operación.
if not PROG:
return
# Error si el sistema de archivos no se queda en el estado de montaje adecuado.
if DOMOUNT:
PART = ogMount(int(sys.argv[1]), int(sys.argv[2]))
if not PART:
return
else:
ogUnmount(int(sys.argv[1]), int(sys.argv[2]))
if ogIsMounted(int(sys.argv[1]), int(sys.argv[2])):
ogRaiseError(OG_ERR_PARTITION, f"{int(sys.argv[1])} {int(sys.argv[2])}")
return
# Error si el sistema de archivos está bloqueado.
if ogIsLocked(int(sys.argv[1]), int(sys.argv[2])):
ogRaiseError(OG_ERR_LOCKED, f"{int(sys.argv[1])} {int(sys.argv[2])}")
return
# Redimensionar en modo uso exclusivo.
ogLock(int(sys.argv[1]), int(sys.argv[2]))
try:
subprocess.run([PROG, PARAMS, PART], capture_output=True)
ERRCODE = 0
except FileNotFoundError:
ogRaiseError(OG_ERR_NOTEXEC, PROG)
ERRCODE = OG_ERR_NOTEXEC
except:
ogRaiseError(OG_ERR_PARTITION, f"{int(sys.argv[1])} {int(sys.argv[2])}")
ERRCODE = OG_ERR_PARTITION
ogUnlock(int(sys.argv[1]), int(sys.argv[2]))
return ERRCODE
def ogFormat(int_ndisk, int_nfilesys):
if int_nfilesys.lower() == "cache":
ogFormatCache()
else:
ogFormatFs(int_ndisk, int_nfilesys)
def ogFormatFs(int_ndisk, int_nfilesys, str_label=None):
# Si se solicita, mostrar ayuda.
if str_label == "help":
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\"")
return
# Error si no se reciben entre 2 y 4 parámetros.
if not (2 <= len(sys.argv) <= 4):
ogRaiseError(OG_ERR_FORMAT)
return
# Obtener fichero de dispositivo.
PART = ogDiskToDev(int_ndisk, int_nfilesys)
if not PART:
return
# Error si la partición está montada o bloqueada.
if ogIsMounted(int_ndisk, int_nfilesys):
ogRaiseError(OG_ERR_DONTFORMAT, f"{MSG_MOUNT}: {int_ndisk} {int_nfilesys}")
return
if ogIsLocked(int_ndisk, int_nfilesys):
ogRaiseError(OG_ERR_LOCKED, f"{int_ndisk} {int_nfilesys}")
return
# Si no se indica el tipo de sistema de archivos, intentar obtenerlo.
TYPE = ogGetFsType(int_ndisk, int_nfilesys)
if not TYPE:
TYPE = sys.argv[3]
# Error, si no especifica el tipo de sistema de archivos a formatear.
if not TYPE:
ogRaiseError(OG_ERR_FORMAT, f"{int_ndisk} {int_nfilesys} ...")
return
# Elegir tipo de formato.
if TYPE == "EXT2":
PROG = "mkfs.ext2"
PARAMS = "-F"
elif TYPE == "EXT3":
PROG = "mkfs.ext3"
PARAMS = "-F"
elif TYPE == "EXT4":
PROG = "mkfs.ext4"
PARAMS = "-F"
elif TYPE == "BTRFS":
PROG = "mkfs.btrfs"
PARAMS = "-f"
elif TYPE == "REISERFS":
PROG = "mkfs.reiserfs"
PARAMS = "-f"
LABELPARAM = "-l"
elif TYPE == "REISER4":
PROG = "mkfs.reiser4"
PARAMS = "-f <<<\"y\""
elif TYPE == "XFS":
PROG = "mkfs.xfs"
PARAMS = "-f"
elif TYPE == "JFS":
PROG = "mkfs.jfs"
PARAMS = "<<<\"y\""
elif TYPE == "F2FS":
PROG = "mkfs.f2fs"
LABELPARAM = "-l"
elif TYPE == "NILFS2":
PROG = "mkfs.nilfs2"
PARAMS = "-f"
elif TYPE == "LINUX-SWAP":
PROG = "mkswap"
elif TYPE == "NTFS":
PROG = "mkntfs"
PARAMS = "-f"
elif TYPE == "EXFAT":
PROG = "mkfs.exfat"
LABELPARAM = "-n"
elif TYPE == "FAT32":
PROG = "mkdosfs"
PARAMS = "-F 32"
LABELPARAM = "-n"
elif TYPE == "FAT16":
PROG = "mkdosfs"
PARAMS = "-F 16"
LABELPARAM = "-n"
elif TYPE == "FAT12":
PROG = "mkdosfs"
PARAMS = "-F 12"
LABELPARAM = "-n"
elif TYPE == "HFS":
PROG = "mkfs.hfs"
elif TYPE == "HFSPLUS":
PROG = "mkfs.hfsplus"
LABELPARAM = "-v"
elif TYPE == "UFS":
PROG = "mkfs.ufs"
PARAMS = "-O 2"
else:
ogRaiseError(OG_ERR_PARTITION, f"{int_ndisk} {int_nfilesys} {TYPE}")
return
# Etiquetas de particion.
if not str_label:
if sys.argv[4] == "CACHE":
ogRaiseError(OG_ERR_FORMAT, f"{MSG_RESERVEDVALUE}: CACHE")
return
if len(sys.argv) >= 4:
PARAMS = f"{PARAMS} {LABELPARAM or '-L'} {sys.argv[4]}"
else:
PARAMS = f"{PARAMS} {LABELPARAM or '-L'} {str_label}"
# Formatear en modo uso exclusivo (desmontar siempre).
ogLock(int_ndisk, int_nfilesys)
try:
subprocess.run([PROG, PARAMS, PART], capture_output=True)
ERRCODE = 0
except FileNotFoundError:
ogRaiseError(OG_ERR_NOTEXEC, PROG)
ERRCODE = OG_ERR_NOTEXEC
except:
ogRaiseError(OG_ERR_PARTITION, f"{int_ndisk} {int_nfilesys}")
ERRCODE = OG_ERR_PARTITION
ogUnlock(int_ndisk, int_nfilesys)
return ERRCODE
def ogGetFsSize(int_ndisk, int_npartition, str_unit=None):
# Si se solicita, mostrar ayuda.
if str_unit == "help":
ogHelp("ogGetFsSize", "ogGetFsSize int_ndisk int_npartition [str_unit]", "ogGetFsSize 1 1", "ogGetFsSize 1 1 KB")
return
# Error si no se reciben 2 o 3 parámetros.
if not (2 <= len(sys.argv) <= 3):
ogRaiseError(OG_ERR_FORMAT)
return
# Obtener unidad y factor de medida.
UNIT = str_unit or "KB"
FACTOR = 1
if UNIT.upper() == "MB":
FACTOR = 1024
elif UNIT.upper() == "GB":
FACTOR = 1024 * 1024
elif UNIT.upper() == "TB":
FACTOR = 1024 * 1024 * 1024
elif UNIT.upper() != "KB":
ogRaiseError(OG_ERR_FORMAT, f"{UNIT} != {{ KB, MB, GB, TB }}")
return
# Obtener el tamaño del sistema de archivo (si no está formateado; tamaño = 0).
MNTDIR = ogMount(int_ndisk, int_npartition)
if MNTDIR:
result = subprocess.run(["df", "-BK", MNTDIR], capture_output=True, text=True)
VALUE = result.stdout.split("\n")[1].split()[1]
SIZE = float(VALUE) / FACTOR
else:
SIZE = 0
# Devolver el tamaño (quitar decimales si son 0).
return int(SIZE) if SIZE.is_integer() else SIZE
def ogGetFsType(int_ndisk, int_nfilesys):
# Si se solicita, mostrar ayuda.
if len(sys.argv) == 3 and sys.argv[2] == "help":
ogHelp("ogGetFsType", "ogGetFsType int_ndisk int_nfilesys", "ogGetFsType 1 1")
return
# Error si no se reciben 2 parámetros.
if len(sys.argv) != 3:
ogRaiseError(OG_ERR_FORMAT)
return
# Obtener partición.
PART = ogDiskToDev(int_ndisk, int_nfilesys)
if not PART:
return
# Detectar tipo de sistema de archivo (independientemente del tipo de partición).
if PART.startswith("/"):
result = subprocess.run(["blkid", "-o", "export", PART], capture_output=True, text=True)
TYPE = ""
for line in result.stdout.split("\n"):
if line.startswith("TYPE="):
TYPE = line.split("=")[1].upper()
break
else:
subprocess.run(["zfs", "mount", PART], stderr=subprocess.DEVNULL)
result = subprocess.run(["mount"], capture_output=True, text=True)
TYPE = ""
for line in result.stdout.split("\n"):
if line.startswith(PART):
TYPE = line.split()[4].upper()
break
# Componer valores correctos.
if TYPE == "EXT4":
if f"{int_ndisk} {int_nfilesys}" == ogFindCache():
if ogIsFormated(int_ndisk, int_nfilesys):
TYPE = "CACHE"
elif TYPE == "VFAT":
result = subprocess.run(["blkid", "-po", "export", PART], capture_output=True, text=True)
for line in result.stdout.split("\n"):
if line.startswith("VERSION="):
TYPE = line.split("=")[1].upper()
break
elif TYPE == "SWAP":
TYPE = "LINUX-SWAP"
elif TYPE.startswith("LVM"):
TYPE = "LINUX-LVM"
elif "RAID" in TYPE:
TYPE = "LINUX-RAID"
elif TYPE == "ZFS_MEMBER":
TYPE = "ZVOL"
elif "_MEMBER" in TYPE:
TYPE = TYPE.replace("_MEMBER", "")
if TYPE:
return TYPE
def ogGetMountPoint(int_ndisk, int_nfilesys):
# Si se solicita, mostrar ayuda.
if len(sys.argv) == 3 and sys.argv[2] == "help":
ogHelp("ogGetMountPoint", "ogGetMountPoint int_ndisk int_nfilesys", "ogGetMountPoint 1 1")
return
# Error si no se reciben 2 parámetros.
if len(sys.argv) != 3:
ogRaiseError(OG_ERR_FORMAT)
return
# Obtener partición.
PART = ogDiskToDev(int_ndisk, int_nfilesys)
if not PART:
return
# Devolver punto de montaje.
result = subprocess.run(["findmnt", "-n", "-o", "TARGET", PART], capture_output=True, text=True)
return result.stdout.strip()
def ogIsFormated(int_ndisk, int_nfilesys):
# Si se solicita, mostrar ayuda.
if len(sys.argv) == 3 and sys.argv[2] == "help":
ogHelp("ogIsFormated", "ogIsFormated int_ndisk int_nfilesys", "ogIsFormated 1 1")
return
# Error si no se reciben 2 parámetros.
if len(sys.argv) != 3:
ogRaiseError(OG_ERR_FORMAT)
return
# Obtener partición.
PART = ogDiskToDev(int_ndisk, int_nfilesys)
if not PART:
return
# Revisar tipo de sistema de archivos.
if PART.startswith("/"):
result = subprocess.run(["blkid", "-s", "TYPE", PART], capture_output=True, text=True)
return bool(result.stdout.strip())
else:
result = subprocess.run(["zfs", "list", "-Hp", "-o", "canmount", PART], capture_output=True, text=True)
return result.stdout.strip() == "on"
def ogIsLocked(int_ndisk, int_nfilesys):
return ogIsPartitionLocked(int_ndisk, int_nfilesys)
def ogIsPartitionLocked(int_ndisk, int_npartition):
# Si se solicita, mostrar ayuda.
if len(sys.argv) == 3 and sys.argv[2] == "help":
ogHelp("ogIsPartitionLocked", "ogIsPartitionLocked int_ndisk int_npartition", "ogIsPartitionLocked 1 1")
return
# Error si no se reciben 2 parámetros.
if len(sys.argv) != 3:
ogRaiseError(OG_ERR_FORMAT)
return
# Obtener partición.
PART = ogDiskToDev(int_ndisk, int_npartition)
if not PART:
return
# Comprobar existencia de fichero de bloqueo de la partición o de su disco.
LOCKDISK = f"/var/lock/lock{ogDiskToDev(int_ndisk).replace('/', '-')}"
LOCKPART = f"/var/lock/lock{PART.replace('/', '-')}"
return os.path.isfile(LOCKDISK) or os.path.isfile(LOCKPART)
def ogIsMounted(int_ndisk, int_nfilesys):
# Si se solicita, mostrar ayuda.
if len(sys.argv) == 3 and sys.argv[2] == "help":
ogHelp("ogIsMounted", "ogIsMounted int_ndisk int_nfilesys", "ogIsMounted 1 1")
return
# Error si no se reciben 2 parámetros.
if len(sys.argv) != 3:
ogRaiseError(OG_ERR_FORMAT)
return
# Obtener punto de montaje.
MNTDIR = ogGetMountPoint(int_ndisk, int_nfilesys)
return bool(MNTDIR)
def ogIsReadonly(int_ndisk, int_nfilesys):
# Si se solicita, mostrar ayuda.
if len(sys.argv) == 3 and sys.argv[2] == "help":
ogHelp("ogIsReadonly", "ogIsReadonly int_ndisk int_nfilesys", "ogIsReadonly 1 1")
return
# Error si no se reciben 2 parámetros.
if len(sys.argv) != 3:
ogRaiseError(OG_ERR_FORMAT)
return
# Obtener partición.
PART = ogDiskToDev(int_ndisk, int_nfilesys)
if not PART:
return
# Comprobar si la partición está montada en modo de solo lectura.
result = subprocess.run(["findmnt", "-n", "-o", "OPTIONS", PART], capture_output=True, text=True)
options = result.stdout.strip().split(",")
return "ro" in options
def ogIsWritable(int_ndisk, int_nfilesys):
# Si se solicita, mostrar ayuda.
if len(sys.argv) == 3 and sys.argv[2] == "help":
ogHelp("ogIsWritable", "ogIsWritable int_ndisk int_nfilesys", "ogIsWritable 1 1")
return
# Error si no se reciben 2 parámetros.
if len(sys.argv) != 3:
ogRaiseError(OG_ERR_FORMAT)
return
# Obtener partición.
PART = ogDiskToDev(int_ndisk, int_nfilesys)
if not PART:
return
# Comprobar si la partición está montada en modo de escritura.
result = subprocess.run(["findmnt", "-n", "-o", "OPTIONS", PART], capture_output=True, text=True)
options = result.stdout.strip().split(",")
return "rw" in options
def ogLock(int_ndisk, int_nfilesys):
ogLockPartition(int_ndisk, int_nfilesys)
def ogLockPartition(int_ndisk, int_npartition):
# Si se solicita, mostrar ayuda.
if len(sys.argv) == 3 and sys.argv[2] == "help":
ogHelp("ogLockPartition", "ogLockPartition int_ndisk int_npartition", "ogLockPartition 1 1")
return
# Error si no se reciben 2 parámetros.
if len(sys.argv) != 3:
ogRaiseError(OG_ERR_FORMAT)
return
# Obtener partición.
PART = ogDiskToDev(int_ndisk, int_npartition)
if not PART:
return
# Crear archivo de bloqueo exclusivo.
LOCKFILE = f"/var/lock/lock{PART.replace('/', '-')}"
open(LOCKFILE, 'a').close()
def ogMount():
args = sys.argv[2:]
if args == ["CACHE"] or args == ["cache"]:
ogMountCache()
elif args == ["CDROM"] or args == ["cdrom"]:
ogMountCdrom()
else:
ogMountFs(*args)
def ogMountFirstFs(int_ndisk):
# Obtener número de particiones del disco.
NPARTS = ogGetPartitionsNumber(int_ndisk)
for PART in range(1, NPARTS + 1):
MNTDIR = ogMount(int_ndisk, PART)
if MNTDIR:
return MNTDIR
ogRaiseError(OG_ERR_NOTFOUND, int_ndisk)
return OG_ERR_NOTFOUND
def ogMountFs(int_ndisk, int_nfilesys):
FUNCNAME = ogExecAndLog.__name__
# Si se solicita, mostrar ayuda.
if len(sys.argv) == 3 and sys.argv[2] == "help":
ogHelp(f"{FUNCNAME}", "{FUNCNAME} int_ndisk int_nfilesys", "{FUNCNAME} 1 1 => /mnt/sda1")
return
# Error si no se reciben 2 parámetros.
if len(sys.argv) != 3:
ogRaiseError(OG_ERR_FORMAT)
return
# Obtener partición.
PART = ogDiskToDev(int_ndisk, int_nfilesys)
if not PART:
return
# Comprobar si el sistema de archivos ya está montada.
MNTDIR = ogGetMountPoint(int_ndisk, int_nfilesys)
# Si no, montarlo en un directorio de sistema.
if not MNTDIR:
# Error si la particion esta bloqueada.
if ogIsLocked(int_ndisk, int_nfilesys):
ogRaiseError(OG_ERR_LOCKED, f"{MSG_PARTITION}, {int_ndisk} {int_nfilesys}")
return
# El camino de un dispositivo normal comienza por el carácter "/".
if PART.startswith("/"):
# Crear punto de montaje o enlace simbólico para caché local.
MNTDIR = PART.replace("/dev", "/mnt")
DEBUG = "no"
if f"{int_ndisk} {int_nfilesys}" == ogFindCache() and OGCAC:
os.makedirs(OGCAC, exist_ok=True)
os.symlink(OGCAC, MNTDIR)
else:
os.makedirs(MNTDIR, exist_ok=True)
del DEBUG
# Montar sistema de archivos.
try:
subprocess.run(["mount", PART, MNTDIR], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError:
try:
subprocess.run(["mount", PART, MNTDIR, "-o", "force,remove_hiberfile"], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError:
ogRaiseError(OG_ERR_PARTITION, f"{int_ndisk}, {int_nfilesys}")
return
# Aviso de montaje de solo lectura.
if ogIsReadonly(int_ndisk, int_nfilesys):
ogEcho("warning", f"{FUNCNAME}: {MSG_MOUNTREADONLY}: \"{int_ndisk}, {int_nfilesys}\"")
else:
# Montar sistema de archivos ZFS (un ZPOOL no comienza por "/").
try:
subprocess.run(["zfs", "mount", PART], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError:
pass
return MNTDIR
def ogMountCdrom():
DEV = "/dev/cdrom" # Por defecto
MNTDIR = subprocess.run(["mount", "-l", "-t", "iso9660", DEV], capture_output=True, text=True)
MNTDIR = MNTDIR.stdout.strip().split(" ")[2]
if not MNTDIR:
MNTDIR = DEV.replace("/dev", "/mnt")
os.makedirs(MNTDIR, exist_ok=True)
try:
subprocess.run(["mount", "-t", "iso9660", DEV, MNTDIR], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError:
ogRaiseError(OG_ERR_PARTITION, "cdrom")
return
return MNTDIR
def ogReduceFs(int_ndisk, int_nfilesys):
# Si se solicita, mostrar ayuda.
if len(sys.argv) == 3 and sys.argv[2] == "help":
ogHelp("ogReduceFs", "ogReduceFs int_ndisk int_nfilesys", "ogReduceFs 1 1")
return
# Error si no se reciben 2 parámetros.
if len(sys.argv) != 3:
ogRaiseError(OG_ERR_FORMAT)
return
# Obtener partición.
PART = ogDiskToDev(int_ndisk, int_nfilesys)
if not PART:
return
# Redimensionar según el tipo de partición.
TYPE = ogGetFsType(int_ndisk, int_nfilesys)
if TYPE == "EXT4":
ogUnmount(int_ndisk, int_nfilesys)
subprocess.run(["resize2fs", "-fpM", PART], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
elif TYPE == "BTRFS":
MNTDIR = ogMount(int_ndisk, int_nfilesys)
SIZE = subprocess.run(["btrfs", "filesystem", "show", MNTDIR], capture_output=True, text=True)
SIZE = SIZE.stdout.strip().split(" ")[6]
SIZE = int(float(SIZE) * 1.1 + 1)
subprocess.run(["btrfs", "filesystem", "resize", str(SIZE), MNTDIR], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
elif TYPE in ["REISERFS", "REISER4"]:
MNTDIR = ogMount(int_ndisk, int_nfilesys)
SIZE = int(subprocess.run(["df", "-k", MNTDIR], capture_output=True, text=True).stdout.strip().split("\n")[1].split()[2])
SIZE = SIZE * 110 // 100
ogUnmount(int_ndisk, int_nfilesys)
subprocess.run(["resize_reiserfs", "-s" + str(SIZE) + "K", PART], input="y\n", stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
elif TYPE == "NTFS":
ogUnmount(int_ndisk, int_nfilesys)
MAXSIZE, SIZE = subprocess.run(["ntfsresize", "-fi", PART], capture_output=True, text=True)
MAXSIZE = MAXSIZE.strip().split(" ")[3]
SIZE = SIZE.strip().split(" ")[4]
SIZE = int(float(SIZE) * 1.1 / 1024 + 1) * 1024
RETVAL = 1
while RETVAL != 0 and SIZE + EXTRASIZE < MAXSIZE:
EXTRASIZE = subprocess.run(["ntfsresize", "-fns", str(SIZE), PART], capture_output=True, text=True)
EXTRASIZE = int(EXTRASIZE.stdout.strip()) if EXTRASIZE.stdout.strip() else 0
RETVAL = EXTRASIZE != 0
SIZE += EXTRASIZE
if SIZE < MAXSIZE:
subprocess.run(["ntfsresize", "-fs", str(SIZE), PART], input="y\n", stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
elif TYPE in ["FAT32", "FAT16"]:
# No se reduce (por el momento).
pass
elif TYPE == "HFS" or TYPE == "HFSPLUS":
# No se reduce (por el momento).
pass
elif TYPE == "UFS":
# No se reduce (por el momento).
pass
else:
ogRaiseError(OG_ERR_PARTITION, f"{int_ndisk}, {int_nfilesys}")
# Devuelve tamaño del sistema de ficheros.
return ogGetFsSize(int_ndisk, int_nfilesys)
def ogUnlock(int_ndisk, int_npartition):
ogUnlockPartition(int_ndisk, int_npartition)
def ogUnlockPartition(int_ndisk, int_npartition):
# Si se solicita, mostrar ayuda.
if len(sys.argv) == 3 and sys.argv[2] == "help":
ogHelp("ogUnlockPartition", "ogUnlockPartition int_ndisk int_npartition", "ogUnlockPartition 1 1")
return
# Error si no se reciben 2 parámetros.
if len(sys.argv) != 3:
ogRaiseError(OG_ERR_FORMAT)
return
# Obtener partición.
PART = ogDiskToDev(int_ndisk, int_npartition)
if not PART:
return
# Borrar archivo de bloqueo exclusivo.
LOCKFILE = f"/var/lock/lock{PART.replace('/', '-')}"
os.remove(LOCKFILE)
def ogUnmount():
ogUnmountFs(*sys.argv[2:])
def ogUnmountFs(int_ndisk, int_npartition):
FUNCNAME = ogUnmountFs.__name__
# Si se solicita, mostrar ayuda.
if len(sys.argv) == 3 and sys.argv[2] == "help":
ogHelp("ogUnmountFs", "ogUnmountFs int_ndisk int_npartition", "ogUnmountFs 1 1")
return
# Error si no se reciben 2 parámetros.
if len(sys.argv) != 3:
ogRaiseError(OG_ERR_FORMAT)
return
# Obtener partición y punto de montaje.
PART = ogDiskToDev(int_ndisk, int_npartition)
MNTDIR = ogGetMountPoint(int_ndisk, int_npartition)
# Si está montada, desmontarla.
if MNTDIR:
# Error si la particion está bloqueada.
if ogIsPartitionLocked(int_ndisk, int_npartition):
ogRaiseError(OG_ERR_LOCKED, f"{MSG_PARTITION}, {int_ndisk} {int_npartition}")
return
# Desmontar y borrar punto de montaje.
try:
subprocess.run(["umount", PART], check=True, stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError:
ogEcho("warning", f"{FUNCNAME}: {MSG_DONTUNMOUNT}: \"{int_ndisk}, {int_npartition}\"")
try:
os.rmdir(MNTDIR)
except OSError:
os.remove(MNTDIR)
else:
ogEcho("warning", f"{MSG_DONTMOUNT}: \"{int_ndisk},{int_npartition}\"")
ogUnmountFs(int_ndisk, int_npartition)
def ogUnmountAll(int_ndisk):
# Si se solicita, mostrar ayuda.
if len(sys.argv) == 3 and sys.argv[2] == "help":
ogHelp("ogUnmountAll", "ogUnmountAll int_ndisk", "ogUnmountAll 1")
return
# Error si no se recibe 1 parámetro.
if len(sys.argv) != 3:
ogRaiseError(OG_ERR_FORMAT)
return
# Obtener partición y punto de montaje.
DISK = ogDiskToDev(int_ndisk)
for PART in range(1, ogGetPartitionsNumber(int_ndisk) + 1):
if ogGetFsType(int_ndisk, PART) != "CACHE":
ogUnmount(int_ndisk, PART)
def ogUnsetDirtyBit(int_ndisk, int_nfilesys):
# Si se solicita, mostrar ayuda.
if len(sys.argv) == 3 and sys.argv[2] == "help":
ogHelp("ogUnsetDirtyBit", "ogUnsetDirtyBit int_ndisk int_nfilesys", "ogUnsetDirtyBit 1 1")
return
# Error si no se reciben 2 parámetros.
if len(sys.argv) != 3:
ogRaiseError(OG_ERR_FORMAT)
return
# Obtener partición y punto de montaje.
PART = ogDiskToDev(int_ndisk, int_nfilesys)
if not PART:
return
# Realizar acciones específicas según el tipo de sistema de archivos.
TYPE = ogGetFsType(int_ndisk, int_nfilesys)
if TYPE == "NTFS":
ogUnmount(int_ndisk, int_nfilesys)
subprocess.run(["ntfsfix", "-d", PART], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
else:
pass # Add more specific actions for other file systems if needed.
def ogGetFreeSize(int_ndisk, int_npartition, str_SizeOutput):
if len(sys.argv) == 3 and sys.argv[2] == "help":
ogHelp("ogGetFreeSize", "ogGetFreeSize int_ndisk int_npartition str_SizeOutput", "ogGetFreeSize 1 1 GB")
return
if len(sys.argv) < 3:
ogRaiseError(OG_ERR_FORMAT)
return
PART = ogDiskToDev(int_ndisk, int_npartition)
if not PART:
return
unit = str_SizeOutput
if not unit:
unit = "GB"
factor = 1.024 / 1000000
if unit == "kB":
factor = 1.024
elif unit == "MB":
factor = 1.024 / 1000
result = subprocess.run(["df", PART], capture_output=True, text=True)
output = result.stdout.strip().split("\n")[1].split()
size = float(output[1]) * factor
used = float(output[2]) * factor
free = float(output[3]) * factor
return free

View File

@ -0,0 +1,254 @@
import subprocess
import sys
import os
from FileLib import *
from SystemLib import *
def ogChangeRepo():
SRCIMG = ""
NEWREPO = ""
REPO = ""
OGUNIT = ""
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
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]
# 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"
# 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()
# Parametros de entrada. Si $1 = "REPO" dejo el repositorio actual
if sys.argv[1].upper() == "REPO":
NEWREPO = REPO
# 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(["source", "/scripts/functions"], shell=True)
subprocess.run(["source", "/scripts/ogfunctions"], shell=True)
subprocess.run(["umount", OGIMG])
if sys.argv[2] == "":
SRCIMG = "ogimages"
else:
SRCIMG = "ogimages/" + sys.argv[2]
subprocess.run(["eval", "$(grep \"OPTIONS=\" /scripts/ogfunctions)"])
ogEcho("session", "log", MSG_HELP_ogChangeRepo + " " + NEWREPO + " " + sys.argv[2].rstrip())
ogConnect(NEWREPO, ogprotocol, SRCIMG, OGIMG, RW)
# 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 = ""
if len(sys.argv) < 2:
ogHelp("ogGetGroupDir", "ogGetGroupDir str_repo", "ogGetGroupDir REPO ==> /opt/opengnsys/images/groups/Grupo1")
return
if len(sys.argv) == 1:
REPO = "REPO"
else:
REPO = sys.argv[1]
GROUP = ogGetGroupName()
if GROUP:
DIR = ogGetPath(REPO, "/groups/" + GROUP, stderr=subprocess.DEVNULL)
if os.path.isdir(DIR):
print(DIR)
return 0
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
def ogGetHostname():
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:
for line in f:
if "option host-name" in line:
HOST = line.split('"')[1]
break
# 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)
if HOSTNAME != HOST:
os.environ["HOSTNAME"] = HOST
if HOST:
print(HOST)
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 = [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.
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]
# Mostrar solo la primera.
if MAC:
print(MAC[0])
return 0
def ogGetNetInterface():
if len(sys.argv) >= 2 and sys.argv[1] == "help":
ogHelp("ogGetNetInterface", "ogGetNetInterface", "ogGetNetInterface => eth0")
return
if "DEVICE" in os.environ:
print(os.environ["DEVICE"])
return 0
def ogGetRepoIp():
# Variables locales.
SOURCE = ""
FSTYPE = ""
# Mostrar ayuda.
if len(sys.argv) >= 2 and sys.argv[1] == "help":
ogHelp("ogGetRepoIp", "ogGetRepoIp", "ogGetRepoIp => 192.168.0.2")
return
# 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
def ogGetServerIp():
# Variables locales.
SOURCE = ""
FSTYPE = ""
# Mostrar ayuda.
if len(sys.argv) >= 2 and sys.argv[1] == "help":
ogHelp("ogGetServerIp", "ogGetServerIp", "ogGetServerIp => 192.168.0.2")
return
# 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
def ogMakeGroupDir():
REPO = ""
DIR = ""
GROUP = ""
if len(sys.argv) < 2:
ogHelp("ogMakeGroupDir", "ogMakeGroupDir str_repo", "ogMakeGroupDir", "ogMakeGroupDir REPO")
return
if len(sys.argv) == 1:
REPO = "REPO"
else:
REPO = sys.argv[1]
DIR = ogGetPath(REPO, "/groups/" + ogGetGroupName(), stderr=subprocess.DEVNULL)
if DIR:
subprocess.run(["mkdir", "-p", DIR], stderr=subprocess.DEVNULL)
return 0

View File

@ -0,0 +1,45 @@
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
def ogCheckIpAddress(ip):
"""
Función para determinar si una cadena es una dirección ipv4 válida.
:param ip: string de la ip a comprobar
:return: True si es una dirección válida, False si NO es una dirección válida
"""
if not isinstance(ip, str):
raise ValueError("Formato incorrecto, el parámetro debe ser una cadena.")
regex = r"^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$"
if re.match(regex, ip):
parts = ip.split('.')
if all(0 <= int(part) <= 255 for part in parts):
return True
return False

View File

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

View File