1
0
Fork 0

Compare commits

..

No commits in common. "main" and "code-review" have entirely different histories.

554 changed files with 1682 additions and 87795 deletions

View File

@ -1,158 +0,0 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.8.0] - 2025-04-23
### Added
- Have the oglive agent send /stopped on poweroff or restart
## [0.7.2] - 2025-04-21
### Fixed
- Have the partitioning functions return a meaningful rc
## [0.7.1] - 2025-04-15
### Fixed
- getConfiguration.py: don't fail if NTFS filesystems are mounted ro
## [0.7.0] - 2025-04-15
### Removed
- Removed references to ogGlobals.OGLOG in python code
## [0.6.1] - 2025-04-15
### Fixed
- Fixed capturing of partclone output and management of return value
## [0.6.0] - 2025-04-15
### Changed
- ogGetIpAddress() is no longer required in ogGlobals--move it back into NetLib
## [0.5.0] - 2025-04-15
### Changed
- Log to /var/log/clone-engine.log and clone-engine.json.log
## [0.4.1] - 2025-04-10
### Fixed
- restoreImage.py: return negated rc to the shell
## [0.4.0] - 2025-04-10
### Changed
- Make /opt/opengnsys writable in clients, just like it used to be
## [0.3.6] - 2025-04-09
### Fixed
- Fixed ogReduceFs
## [0.3.5] - 2025-04-09
### Fixed
- Fixed syntax
## [0.3.4] - 2025-04-09
### Fixed
- Fixed usage of ogEcho in FileSystemLib
## [0.3.3] - 2025-04-09
### Fixed
- Kill coproc'ed browser in all execution branches in Configurar.py
## [0.3.2] - 2025-04-07
### Fixed
- Handle invalid number of arguments pass to functions/ogCopyFile
## [0.3.1] - 2025-04-03
### Fixed
- Fixed invocation to ogCheckIpAddress in interfaceAdm/CrearImagen.py
## [0.3.0] - 2025-04-03
### Removed
- Removed burg and rsync 3.1
## [0.2.6] - 2025-03-31
### Fixed
- Restore qt4 browser
## [0.2.5] - 2025-03-31
### Fixed
- Don't require protoopts in interfaceAdm/RestaurarImagen.py
## [0.2.4] - 2025-03-28
### Removed
- Removed burg, QT4 stuff, rsync 3.1 and the old browser
## [0.2.3] - 2025-03-28
### Fixed
- Fixed some errors in Configurar.py, ogCreateCache, ogCreatePartitions and initCache.py
## [0.2.2] - 2025-03-26
### Fixed
- Prevent EjecutarScript.py from capturing the output of the script
## [0.2.1] - 2025-03-26
### Fixed
- Run scripts with bash to avoid errno 8 "Exec format error"
## [0.2.0] - 2025-03-25
### Added
- getConfiguration.py now collects the firmware type
- Configurar.py now creates partition tables of the right type (MSDOS/GPT) for each machine
## [0.1.1] - 2025-03-19
### Added
- Missing functions in BootLib
- Some interfaceAdm python scripts
## [0.1.0] - 2025-02-28
### Added
- Merge pull request 'Include all client files, build debian package' (#2) from deb-package into main

View File

@ -1,105 +0,0 @@
@Library('jenkins-shared-library') _
pipeline {
agent {
label 'jenkins-slave'
}
environment {
DEBIAN_FRONTEND = 'noninteractive'
DEFAULT_DEV_NAME = 'Opengnsys Team'
DEFAULT_DEV_EMAIL = 'opengnsys@qindel.com'
}
options {
skipDefaultCheckout()
}
parameters {
string(name: 'DEV_NAME', defaultValue: '', description: 'Nombre del desarrollador')
string(name: 'DEV_EMAIL', defaultValue: '', description: 'Email del desarrollador')
}
stages {
stage('Prepare Workspace') {
steps {
script {
env.BUILD_DIR = "${WORKSPACE}/ogclient"
sh "mkdir -p ${env.BUILD_DIR}"
}
}
}
stage('Checkout') {
steps {
dir("${env.BUILD_DIR}") {
checkout scm
}
}
}
stage('Generate Changelog') {
when {
expression {
return env.TAG_NAME != null
}
}
steps {
script {
def devName = params.DEV_NAME ? params.DEV_NAME : env.DEFAULT_DEV_NAME
def devEmail = params.DEV_EMAIL ? params.DEV_EMAIL : env.DEFAULT_DEV_EMAIL
generateDebianChangelog(env.BUILD_DIR, devName, devEmail)
}
}
}
stage('Generate Changelog (Nightly)'){
when {
branch 'main'
}
steps {
script {
def devName = params.DEV_NAME ? params.DEV_NAME : env.DEFAULT_DEV_NAME
def devEmail = params.DEV_EMAIL ? params.DEV_EMAIL : env.DEFAULT_DEV_EMAIL
generateDebianChangelog(env.BUILD_DIR, devName, devEmail,"nightly")
}
}
}
stage('Build') {
steps {
script {
construirPaquete(env.BUILD_DIR, "../artifacts", "172.17.8.68", "/var/tmp/opengnsys/debian-repo/ogclient")
}
}
}
stage ('Publish to Debian Repository') {
when {
expression {
return env.TAG_NAME != null
}
}
agent { label 'debian-repo' }
steps {
script {
// Construir el patrón de versión esperado en el nombre del paquete
def versionPattern = "${env.TAG_NAME}-${env.BUILD_NUMBER}"
publicarEnAptly('/var/tmp/opengnsys/debian-repo/ogclient', 'opengnsys-devel', versionPattern)
}
}
}
stage ('Publish to Debian Repository (Nightly)') {
when {
branch 'main'
}
agent { label 'debian-repo' }
steps {
script {
// Construir el patrón de versión esperado en el nombre del paquete
def versionPattern = "-${env.BUILD_NUMBER}~nightly"
publicarEnAptly('/var/tmp/opengnsys/debian-repo/ogclient', 'nightly', versionPattern)
}
}
}
}
post {
always {
notifyBuildStatus('narenas@qindel.com')
}
}
}

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,10 @@
#!/usr/bin/env python3
import os
import sys
def main():
os.system('poweroff')
sys.exit(0)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,54 @@
#!/usr/bin/env python3
import os
import sys
import subprocess
import NetLib
import SystemLib
def main():
if len(sys.argv) != 2:
print("Usage: CambiarAcceso.py <mode>")
sys.exit(1)
mode = sys.argv[1]
repo_ip = NetLib.ogGetRepoIp()
if not repo_ip:
SystemLib.ogRaiseError("OG_ERR_NOTFOUND", "repo no montado")
if SystemLib.ogIsRepoLocked():
SystemLib.ogRaiseError("OG_ERR_LOCKED", f"repo {repo_ip}")
proto = os.getenv("ogprotocol", "smb")
if proto not in ["nfs", "smb"]:
SystemLib.ogRaiseError("OG_ERR_FORMAT", f"protocolo desconocido {proto}")
if mode == "admin":
mount_mode = "rw"
elif mode == "user":
mount_mode = "ro"
else:
SystemLib.ogRaiseError("OG_ERR_FORMAT", f"modo desconocido {mode}")
OGIMG = os.getenv("OGIMG", "/mnt/OGIMG")
OGUNIT = os.getenv("OGUNIT", "")
if OGUNIT:
OGUNIT = f"/{OGUNIT}"
subprocess.run(["umount", OGIMG], check=True)
SystemLib.ogEcho("info", f"Montar repositorio {repo_ip} por {proto} en modo {mode}")
if proto == "nfs":
subprocess.run(["mount", "-t", "nfs", f"{repo_ip}:{OGIMG}{OGUNIT}", OGIMG, "-o", mount_mode], check=True)
elif proto == "smb":
with open("/scripts/ogfunctions", "r") as f:
for line in f:
if "OPTIONS=" in line:
pass_option = line.split("pass=")[1].split()[0]
break
else:
pass_option = "og"
subprocess.run(["mount.cifs", f"//{repo_ip}/ogimages{OGUNIT}", OGIMG, "-o", f"{mount_mode},serverino,acl,username=opengnsys,password={pass_option}"], check=True)
if __name__ == "__main__":
main()

View File

@ -9,7 +9,6 @@ import SystemLib
import CacheLib
import FileSystemLib
import DiskLib
import InventoryLib
#Load engine configurator from engine.cfg file.
#Carga el configurador del engine desde el fichero engine.cfg
@ -62,24 +61,23 @@ sparam = tbprm[1] # Partitioning and formatting parameters
# 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 = tch = None
dis = ptt = tch = None
for item in tbprm:
if '=' not in item: continue
k, v = item.split ('=', 1)
if k not in ['dis', 'tch']:
if k not in ['dis', 'tch', 'ptt']: ## 'ptt' added, unused 'che' removed
print (f'ignoring unknown disk parameter ({k})')
continue
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:
coproc.kill()
sys.exit (ogGlobals.OG_ERR_FORMAT)
if tch is None:
tch = '0'
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)
@ -114,7 +112,6 @@ for item in tbprm:
if tam is None: missing_params.append ('tam')
if missing_params:
print (f'partition data ({item}) missing required parameters ({' '.join (missing_params)})')
coproc.kill()
sys.exit (1)
# Componer datos de particionado.
@ -141,21 +138,18 @@ CacheLib.ogUnmountCache()
# Elimina la tabla de particiones
cur_ptt = DiskLib.ogGetPartitionTableType (dis)
ptt = 'GPT' if InventoryLib.ogIsEfiActive() else 'MSDOS'
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}')
rc = SystemLib.ogExecAndLog ('command', CacheLib.initCache, tch)
if rc:
SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_CACHE, f'initCache failed')
coproc.kill()
sys.exit (1)
SystemLib.ogExecAndLog ('command', CacheLib.initCache, tch)
# Definir particionado.
SystemLib.ogEcho (['session', 'log'], None, f'[50] {ogGlobals.lang.MSG_HELP_ogCreatePartitions}')

View File

@ -0,0 +1,74 @@
#!/usr/bin/env python3
import os
import subprocess
import sys
import time
import NetLib
import ogGlobals
def load_engine_config():
engine_config_path = "/opt/opengnsys/etc/engine.cfg"
if os.path.exists(engine_config_path):
with open(engine_config_path) as f:
exec(f.read(), globals())
def clear_temp_logs():
open(os.getenv('OGLOGSESSION'), 'w').close()
open(os.getenv('OGLOGCOMMAND'), 'w').close()
open(f"{os.getenv('OGLOGCOMMAND')}.tmp", 'w').close()
def log_session_start(script_name, args):
SystemLib.ogEcho("log session", f"{os.getenv('MSG_INTERFACE_START')} {script_name} {' '.join(args)}")
def log_session_end(retval):
SystemLib.ogEcho("log session", f"{os.getenv('MSG_INTERFACE_END')} {retval}")
def ogCheckIpAddress(ip):
try:
subprocess.check_call(["ping", "-c", "1", ip])
return 0
except subprocess.CalledProcessError:
return 1
def create_image(disk_num, partition_num, repo, image_name):
if subprocess.call(["which", "createImageCustom"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0:
return subprocess.call(["createImageCustom", disk_num, partition_num, repo, f"/{image_name}"])
else:
return subprocess.call(["createImage", disk_num, partition_num, repo, f"/{image_name}"])
def main():
if len(sys.argv) != 5:
sys.exit(SystemLib.ogRaiseError(OG_ERR_FORMAT, "Incorrect number of arguments"))
disk_num, partition_num, image_name, repo = sys.argv[1:5]
start_time = time.time()
load_engine_config()
clear_temp_logs()
log_session_start(sys.argv[0], sys.argv[1:])
repo = repo if repo else "REPO"
if repo == NetLib.ogGetIpAddress():
repo = "CACHE"
if ogCheckIpAddress(repo) == 0 or repo == "REPO":
OGUNIT = os.getenv('OGUNIT', "")
if not NetLib.ogChangeRepo(repo, OGUNIT):
sys.exit(SystemLib.ogRaiseError(OG_ERR_NOTFOUND, f"{repo}"))
if repo == "REPO" and os.getenv('boot') != "admin":
retval = CambiarAcceso("admin")
if retval > 0:
sys.exit(retval)
retval = create_image(disk_num, partition_num, repo, image_name)
if repo == "REPO" and os.getenv('boot') != "admin":
CambiarAcceso("user")
log_session_end(retval)
sys.exit(retval)
if __name__ == "__main__":
main()

View File

@ -0,0 +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.
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
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
SystemLib.ogEcho('log session', f"{os.environ['MSG_INTERFACE_START']} {sys.argv[0]} {' '.join(sys.argv[1:])}")
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()) )
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 ret_val == 0:
SystemLib.ogEcho('log session', f"[100] Duracion de la operacion {int(elapsed_time // 60)}m {int(elapsed_time % 60)}s")
else:
SystemLib.ogRaiseError('log session', ret_val)
SystemLib.ogEcho('log session', 'error "Operacion no realizada"')
# Registro de fin de ejecución
SystemLib.ogEcho('log session', f"{os.environ['MSG_INTERFACE_END']} {ret_val}")
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])

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

@ -0,0 +1,18 @@
#!/usr/bin/env python3
import sys
import subprocess
def main():
args = sys.argv[1:]
if len(args) == 1:
disk = 1
part = args[0]
else:
disk = args[0]
part = args[1]
boot_os(disk, part)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,33 @@
#!/usr/bin/env python3
import subprocess
import sys
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)
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("Uso: python3 InventarioHardware.py <archivo_salida>")
sys.exit(1)
main(sys.argv[1])

View File

@ -0,0 +1,53 @@
#!/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()
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(" ")
with open(og_log_command, 'w') as f:
f.write(" ")
with open(f"{og_log_command}.tmp", 'w') as f:
f.write(" ")
msg_interface_start = os.getenv(ogGlobals.lang.MSG_INTERFACE_START)
if msg_interface_start:
SystemLib.ogEcho("log", "session", f"{msg_interface_start} {__file__} {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)
elapsed_time = time.time() - start_time
msg_scripts_time_partial = os.getenv(ogGlobals.lang.MSG_SCRIPTS_TIME_PARTIAL)
if msg_scripts_time_partial:
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])

View File

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

View File

@ -0,0 +1,19 @@
#!/usr/bin/env python3
import sys
import subprocess
if __name__ == "__main__":
if len(sys.argv) < 7:
print("Usage: python RestaurarImagen.py <disk> <partition> <image_name> <ip> <protocol> <protocol_options> [additional_args...]")
sys.exit(1)
disk = sys.argv[1]
partition = sys.argv[2]
image_name = sys.argv[3]
ip = sys.argv[4]
protocol = sys.argv[5]
protocol_options = sys.argv[6]
additional_args = sys.argv[7:]
exit_code = deploy_image(ip, image_name, disk, partition, protocol, protocol_options, *additional_args)
sys.exit(exit_code)

View File

@ -0,0 +1,80 @@
#!/usr/bin/env python3
import os
import subprocess
def run_command(command):
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return result.stdout.decode().strip()
def main():
# No registrar los errores.
os.environ["DEBUG"] = "no"
ser = run_command("ogGetSerialNumber")
cfg = ""
disks = int(run_command("ogDiskToDev | wc -w"))
for dsk in range(1, disks + 1):
particiones = run_command(f"ogGetPartitionsNumber {dsk}")
particiones = int(particiones) if particiones else 0
ptt = run_command(f"ogGetPartitionTableType {dsk}")
ptt_map = {
"MSDOS": 1,
"GPT": 2,
"LVM": 3,
"ZPOOL": 4
}
ptt = ptt_map.get(ptt, 0)
cfg += f"{dsk}:0:{ptt}:::{run_command(f'ogGetDiskSize {dsk}')}:0;"
for par in range(1, particiones + 1):
cod = run_command(f"ogGetPartitionId {dsk} {par} 2>/dev/null")
fsi = run_command(f"getFsType {dsk} {par} 2>/dev/null") or "EMPTY"
tam = run_command(f"ogGetPartitionSize {dsk} {par} 2>/dev/null") or "0"
soi = ""
uso = 0
if fsi not in ["", "EMPTY", "LINUX-SWAP", "LINUX-LVM", "ZVOL"]:
if run_command(f"ogMount {dsk} {par} 2>/dev/null"):
soi = run_command(f"getOsVersion {dsk} {par} 2>/dev/null").split(":")[1]
if not soi:
soi = run_command(f"getOsVersion {dsk} {par} 2>/dev/null").split(":")[1]
if not soi and fsi not in ["EMPTY", "CACHE"]:
soi = "DATA"
uso = int(run_command(f"df $(ogGetMountPoint {dsk} {par}) | awk '{{getline; printf \"%d\",$5}}'") or 0)
else:
soi = ""
uso = 0
cfg += f"{dsk}:{par}:{cod}:{fsi}:{soi}:{tam}:{uso};"
if not cfg:
cfg = "1:0:0:::0;"
cfgfile = "/tmp/getconfig"
with open(cfgfile, "w") as f:
f.write(f"{ser + ';' if ser else ''}{cfg}")
run_command("generateMenuDefault &>/dev/null")
with open(cfgfile, "r") as f:
data = f.read()
lines = data.split(";")
for line in lines:
if line:
parts = line.split(":")
if len(parts) == 1:
print(f"ser={parts[0]}")
else:
print(f"disk={parts[0]}\tpar={parts[1]}\tcpt={parts[2]}\tfsi={parts[3]}\tsoi={parts[4]}\ttam={parts[5]}\tuso={parts[6]}")
run_command("rm -f /mnt/*/ogboot.* /mnt/*/*/ogboot.*")
# Volver a registrar los errores.
os.environ.pop("DEBUG", None)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,10 @@
#!/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(get_ip_address())

View File

@ -12,7 +12,6 @@ import tempfile
import subprocess
import shutil
import glob
import inspect
import ogGlobals
import SystemLib
@ -22,7 +21,6 @@ import DiskLib
import InventoryLib
import FileLib
import UEFILib
import CacheLib
#/**
# ogBoot int_ndisk int_nfilesys [ NVRAMPERM ] [str_kernel str_initrd str_krnlparams]
@ -39,168 +37,6 @@ import CacheLib
#@note En Linux, si no se indican los parámetros de arranque se detectan de la opción por defecto del cargador GRUB.
#@note En Linux, debe arrancarse la partición del directorio \c /boot
#*/ ##
def ogBoot (disk, par, nvramperm=False, params=''):
# Detectar tipo de sistema de archivos y montarlo.
part = DiskLib.ogDiskToDev (disk, par)
if not part: return None
type = InventoryLib.ogGetOsType (disk, par)
if not type: return None
# Error si no puede montar sistema de archivos.
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir: return None
#params = None
#if 'NVRAMPERM' == nvramperm.upper():
# nvramperm = True
#else:
# params = nvramperm
# nvramperm = False
if 'Linux' == type or 'Android' == type:
# Si no se indican, obtiene los parámetros de arranque para Linux.
if not params:
params = ogLinuxBootParameters (disk, par)
# Si no existe y el UEFI buscar en particion ESP
if not params and InventoryLib.ogIsEfiActive():
esp = DiskLib.ogGetEsp()
efidisk, efipart = esp.split()
params = ogLinuxBootParameters (efidisk, efipart)
params += ' ' + esp
# Si no existe, buscar sistema de archivo /boot en /etc/fstab.
if not params and os.path.exists (f'{mntdir}/etc/fstab'):
# Localizar S.F. /boot en /etc/fstab del S.F. actual.
dev = None
with open (f'{mntdir}/etc/fstab', 'r') as fd:
while True:
l = fd.readline()
if not l: break
parts = l.split()
if '#' != parts[0] and '/boot' == parts[1]:
dev = parts[0]
break
if dev:
fstab_part = DiskLib.ogDevToDisk (dev)
else:
return None
# Montar S.F. de /boot.
fstab_disk, fstab_par = fstab_part.split()
mntdir = FileSystemLib.ogMount (fstab_disk, fstab_par)
if not mntdir: return None
# Buscar los datos de arranque.
params = ogLinuxBootParameters (fstab_disk, fstab_par)
kernel = initrd = append = None
if params:
kernel, initrd, append = params.split (maxsplit=2)
# Si no hay kernel, no hay sistema operativo.
if not kernel or not os.path.exists (f'{mntdir}/{kernel}'):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, f'{disk} {par} ({type})')
return None
# Arrancar de partición distinta a la original.
if os.path.exists (f'{mntdir}/etc'):
append = re.sub ('root=[-+=_/a-zA-Z0-9]* ', f'root={part} ', append)
# Comprobar tipo de sistema.
if InventoryLib.ogIsEfiActive():
# Comprobar si el Kernel está firmado.
file_out = subprocess.run (['file', '-k', f'{mntdir}/{kernel}'], capture_output=True, text=True).stdout
if not file_out or not 'EFI app' in file_out:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, f'{disk} {par} ({type}, EFI)')
return None
bootlabel = f'Part-{int(disk):02d}-{int(par):02d}'
bootloader = 'shimx64.efi'
# Obtener parcición EFI.
esp = DiskLib.ogGetEsp()
#efidisk, efipart = esp.split()
# TODO: Comprobamos que existe la BOOTLABEL, si no buscamos por sistema operativo
if '' == FileLib.ogGetPath (src=esp, file=f'EFI/{bootlabel}'):
osversion = InventoryLib.ogGetOsVersion (disk, par)
if 'SUSE' in osversion:
bootlabel = 'opensuse'
elif 'Fedora' in osversion:
bootlabel = 'fedora'
elif 'Ubuntu' in osversion:
bootlabel = 'ubuntu'
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{esp} Boot loader')
return None
# Crear orden de arranque (con unos valores por defecto).
UEFILib.ogNvramAddEntry (bootlabel, f'/EFI/{bootlabel}/Boot/{bootloader}', nvramperm)
# Marcar próximo arranque y reiniciar.
UEFILib.ogNvramSetNext (bootlabel)
subprocess.run (['reboot'])
else:
# Arranque BIOS: configurar kernel Linux con los parámetros leídos de su GRUB.
subprocess.run (['kexec', '-l', f'{mntdir}{kernel}', f'--append={append}', f'--initrd={mntdir}{initrd}'])
subprocess.Popen (['kexec', '-e'])
elif 'Windows' == type:
# Comprobar tipo de sistema.
if InventoryLib.ogIsEfiActive():
bootlabel = f'Part-{int(disk):02d}-{int(par):02d}'
# Obtener parcición EFI.
esp = DiskLib.ogGetEsp()
efidisk, efipart = esp.split()
if not efipart:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'ESP')
return None
efidir = FileSystemLib.ogMount (efidisk, efipart)
if not efidir: return None
# Comprobar cargador (si no existe buscar por defecto en ESP).
loader = FileLib.ogGetPath (file=f'{efidir}/EFI/{bootlabel}/Boot/bootmgfw.efi')
if not loader:
bootlabel = 'Microsoft'
loader = FileLib.ogGetPath (file=f'{efidir}/EFI/Microsoft/Boot/bootmgfw.efi')
if not loader:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, f'{disk} {par} ({type}, EFI)')
return None
# Crear orden de arranque (con unos valores por defecto).
l = re.sub ('^.*EFI(.*)$', r'\1', loader)
UEFILib.ogNvramAddEntry (bootlabel, l, nvramperm)
# Marcar próximo arranque y reiniciar.
UEFILib.ogNvramSetNext (bootlabel)
subprocess.run (['reboot'])
else:
# Arranque BIOS: comprueba si hay un cargador de Windows.
for f in ['io.sys', 'ntldr', 'bootmgr']:
file = FileLib.ogGetPath (src=f'{disk} {par}', file=f)
if file: loader=f
if not loader:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, f'{disk} {par} ({type})')
return None
winboot = os.environ.get ('winboot', '')
if 'kexec' == winboot:
# Modo de arranque en caliente (con kexec).
for f in glob.glob (f'{ogGlobals.OGLIB}/grub4dos/*'):
shutil.copy2 (f, mntdir)
disk0 = int(disk)-1
par0 = int(par)-1
subprocess.run (['kexec', '-l', f'{mntdir}/grub.exe', '--append=--config-file=root (hd{disk0},{par0}); chainloader (hd{disk0},{par0})/{loader}; tpm --init'])
subprocess.Popen (['kexec', '-e'])
else:
# Modo de arranque por reinicio (con reboot).
subprocess.run (['dd', 'if=/dev/zero', f'of={mntdir}/ogboot.me', 'bs=1024', 'count=3'])
subprocess.run (['dd', 'if=/dev/zero', f'of={mntdir}/ogboot.firstboot', 'bs=1024', 'count=3'])
subprocess.run (['dd', 'if=/dev/zero', f'of={mntdir}/ogboot.secondboot', 'bs=1024', 'count=3'])
v = RegistryLib.ogGetRegistryValue (mntdir, 'SOFTWARE', r'\Microsoft\Windows\CurrentVersion\Run\ogcleannboot')
if not v:
RegistryLib.ogAddRegistryValue (mntdir, 'SOFTWARE', r'\Microsoft\Windows\CurrentVersion\Run\ogcleanboot')
RegistryLib.ogSetRegistryValue (mntdir, 'SOFTWARE', r'\Microsoft\Windows\CurrentVersion\Run\ogcleanboot', r'cmd /c del c:\ogboot.*')
# Activar la partición.
DiskLib.ogSetPartitionActive (disk, par)
subprocess.run (['reboot'])
elif 'MacOS' == type:
# Modo de arranque por reinicio.
# Nota: el cliente tiene que tener configurado correctamente Grub.
if not os.path.exists (f'{mntdir}/boot.mac'):
open (f'{mntdir}/boot.mac', 'w').close()
subprocess.run (['reboot'])
elif 'GrubLoader' == type:
# Reiniciar.
#subprocess.run (['reboot'])
pass
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, f'{disk} {par} ({type})')
return None
#/**
@ -213,12 +49,6 @@ def ogBoot (disk, par, nvramperm=False, params=''):
#@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.
#*/ ##
def ogGetWindowsName (disk, par):
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir: return None
# Obtener dato del valor de registro.
return RegistryLib.ogGetRegistryValue (mntdir, 'system', r'\ControlSet001\Control\ComputerName\ComputerName\ComputerName')
#/**
@ -232,52 +62,6 @@ def ogGetWindowsName (disk, par):
#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar.
#@warning Función básica usada por \c ogBoot
#*/ ##
def ogLinuxBootParameters (disk, par):
# Detectar id. de tipo de partición y codificar al mnemonico.
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir: return None
# Fichero de configuración de GRUB.
confdir = mntdir # Sistema de archivos de arranque (/boot).
if os.path.isdir (f'{mntdir}/boot'):
confdir = f'{mntdir}/boot' # Sist. archivos raíz con directorio boot.
## original bash code:
## $MNTDIR/{,boot/}{{grubMBR,grubPARTITION}/boot/,}{grub{2,},{,efi/}EFI/*}/{menu.lst,grub.cfg}; do
conffile = None
for _uno in ['', 'boot']:
for _dos in ['grubMBR/boot', 'grubPARTITION/boot', '']:
for _tres in ['grub', 'grub2', 'EFI/*', 'efi/EFI/*']:
for _cuatro in ['menu.lst', 'grub.cfg']:
path = '/'.join ([mntdir, _uno, _dos, _tres, _cuatro])
if os.path.exists (path):
conffile = path
if not conffile:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, 'grub.cfg')
return None
# Toma del fichero de configuracion los valores del kernel, initrd
# y parámetros de arranque usando las cláusulas por defecto
# ("default" en GRUB1, "set default" en GRUB2)
# y los formatea para que sean compatibles con \c kexec . */
awk_script = '''BEGIN {cont=-1;}
$1~/^default$/ {sub(/=/," "); def=$2;}
$1~/^set$/ && $2~/^default/ { gsub(/[="]/," "); def=$3;
if (def ~ /saved_entry/) def=0;
}
$1~/^(title|menuentry)$/ {cont++}
$1~/^set$/ && $2~/^root=.\\(hd__DISK__,(msdos|gpt)__PAR__\\).$/ { if (def==0) def=cont; }
$1~/^(kernel|linux(16|efi)?)$/ { if (def==cont) {
kern=$2;
sub($1,""); sub($1,""); sub(/^[ \\t]*/,""); app=$0
}
}
$1~/^initrd(16|efi)?$/ {if (def==cont) init=$2}
END {if (kern!="") printf("%s %s %s", kern,init,app)}
'''
awk_script = awk_script.replace ('__DISK__', str (int (disk) - 1))
awk_script = awk_script.replace ('__PAR__', par)
awk_out = subprocess.run (['awk', awk_script, conffile], capture_output=True, text=True).stdout
return awk_out
#/**
@ -321,10 +105,6 @@ def ogSetWindowsName (disk, par, name):
#@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.
#*/ ##
def ogSetWinlogonUser (disk, par, username):
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir: return None
RegistryLib.ogSetRegistryValue (mntdir, 'SOFTWARE', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultUserName', username)
#/**
@ -336,11 +116,6 @@ def ogSetWinlogonUser (disk, par, username):
#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar.
#*/ ##
def ogBootMbrXP (disk):
DISK = DiskLib.ogDiskToDev (disk)
if not DISK: return None
subprocess.run (['ms-sys', '-z', '-f', DISK])
subprocess.run (['ms-sys', '-m', '-f', DISK])
#/**
# ogBootMbrGeneric int_ndisk
@ -351,17 +126,6 @@ def ogBootMbrXP (disk):
#@exception OG_ERR_NOTFOUND Tipo de partición desconocido o no se puede montar.
#*/ ##
def ogBootMbrGeneric (disk):
DISK = DiskLib.ogDiskToDev (disk)
if not DISK: return None
subprocess.run (['ms-sys', '-z', '-f', DISK])
subprocess.run (['ms-sys', '-s', '-f', DISK])
# Firma necesaria para Windows equipos UEFI
with open ('/proc/sys/kernel/random/uuid', 'r') as fd:
kernel_random_uuid = fd.read().split ('-')[0]
signature = f'0x{kernel_random_uuid}'
subprocess.run (['ms-sys', '-S', signature, DISK])
@ -405,10 +169,6 @@ fix_first_sector=yes
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Dispositivo de disco no encontrado.
#*/ ##
def ogGetBootMbr (disk):
DISK = DiskLib.ogDiskToDev (disk)
if not DISK: return None
subprocess.run (['ms-sys', '-f', DISK])
#/**
# ogWindowsBootParameters int_ndisk int_parition
@ -654,9 +414,6 @@ def ogGrubInstallMbr (disk, par, checkos='FALSE', kernelparam=''):
if InventoryLib.ogIsEfiActive():
esp = DiskLib.ogGetEsp()
if not esp:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'ESP')
return None
efidisk, efipart = esp.split()
# Comprobamos que exista ESP y el directorio para ubuntu
efisecondstage = FileSystemLib.ogMount (efidisk, efipart)
@ -682,7 +439,7 @@ def ogGrubInstallMbr (disk, par, checkos='FALSE', kernelparam=''):
prefixsecondstage = '' # Reactivamos el grub con el grub.cfg original.
else: # SI Reconfigurar segunda etapa (grub.cfg) == TRUE
#llamada a updateBootCache para que aloje la primera fase del ogLive
subprocess.run ([f'{ogGlobals.OGSCRIPTS}/updateBootCache.py'], check=True)
subprocess.run ([f'{ogGlobals.OGSCRIPTS}/updateBootCache.py'], check=True) ## TODO: check that this works
if InventoryLib.ogIsEfiActive():
# UEFI: grubSintax necesita grub.cfg para detectar los kernels: si no existe recupero backup.
@ -696,7 +453,7 @@ def ogGrubInstallMbr (disk, par, checkos='FALSE', kernelparam=''):
fd.write ('GRUB_DISABLE_RECOVERY="true"\n')
fd.write ('GRUB_DISABLE_LINUX_UUID="true"\n')
os.makedirs (f'{secondstage}{prefixsecondstage}/boot/grub/', exist_ok=True) #Preparar configuración segunda etapa: crear ubicacion
os.makedirs (f'{secondstage}{prefixsecondstage}/boot/grub/') #Preparar configuración segunda etapa: crear ubicacion
subprocess.run (['sed', '-i', 's/^set -e/#set -e/', '/etc/grub.d/00_header']) #Preparar configuración segunda etapa: crear cabecera del fichero (ingnorar errores)
# (ogLive 5.0) Si 'pkgdatadir' está vacía ponemos valor de otros ogLive
subprocess.run (['sed', '-i', r'/grub-mkconfig_lib/i\pkgdatadir=${pkgdatadir:-"${datarootdir}/grub"}', '/etc/grub.d/00_header'])
@ -818,14 +575,11 @@ def ogGrubInstallPartition (disk, par, checkos='FALSE', kernelparam=''):
with open (f'{secondstage}{prefixsecondstage}/boot/grub/grub.cfg', 'a') as fd:
fd.write (out + '\n')
#Instalar el grub
eval = subprocess.run (['grub-install', '--force'] + efioptgrub + [f'--root-directory={secondstage}{prefixsecondstage}', firststage]).returncode
# Movemos el grubx64.efi
if InventoryLib.ogIsEfiActive():
if InventoryLib.ogIsEfiActive(): # Movemos el grubx64.efi
for b in (glob.glob (f'{efisecondstage}/EFI/{efisubdir}/EFI/BOOT/*')):
bn = os.path.basename (b)
os.rename (f'{efisecondstage}/EFI/{efisubdir}/EFI/BOOT/{bn}', f'{efisecondstage}/EFI/{efisubdir}/Boot/{bn}')
os.rename (f'{efisecondstage}/EFI/{efisubdir}/EFI/BOOT/{b}', f'{efisecondstage}/EFI/{efisubdir}/Boot/{b}')
shutil.rmtree (f'{efisecondstage}/EFI/{efisubdir}/EFI')
shutil.copy2 ('/usr/lib/shim/shimx64.efi.signed', f'{efisecondstage}/EFI/{efisubdir}/Boot/shimx64.efi')
# Nombre OpenGnsys para cargador
@ -914,30 +668,6 @@ def ogConfigureFstab (disk, par):
#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar.
#@note Si no se indica nombre, se asigna un valor por defecto.
#*/ ##
def ogSetLinuxName (disk, par, hostname='pc'):
# Montar el sistema de archivos.
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir: return None
etc = FileLib.ogGetPath (src=f'{disk} {par}', file='/etc')
if os.path.isdir (etc):
#cambio de nombre en hostname
with open (f'{etc}/hostname', 'w') as fd:
fd.write (f'{hostname}\n')
#Opcion A para cambio de nombre en hosts
#sed "/127.0.1.1/ c\127.0.1.1 \t $HOSTNAME" $ETC/hosts > /tmp/hosts && cp /tmp/hosts $ETC/ && rm /tmp/hosts
#Opcion B componer fichero de hosts
with open (f'{etc}/hosts', 'w') as fd:
fd.write ('127.0.0.1 localhost\n')
fd.write (f'127.0.1.1 {hostname}\n')
fd.write ('\n')
fd.write ('# The following lines are desirable for IPv6 capable hosts\n')
fd.write ('::1 ip6-localhost ip6-loopback\n')
fd.write ('fe00::0 ip6-localnet\n')
fd.write ('ff00::0 ip6-mcastprefix\n')
fd.write ('ff02::1 ip6-allnodes\n')
fd.write ('ff02::2 ip6-allrouters\n')
@ -977,89 +707,17 @@ def ogCleanLinuxDevices (disk, par):
# /// FIXME: Solo para el grub instalado en MBR por Opengnsys, ampliar para más casos.
#*/ ##
def ogGrubAddOgLive (disk, par, timeout=None, offline=''):
oglivedir = os.environ.get ('oglivedir', 'ogLive')
# Error si no existe el kernel y el initrd en la cache.
# Falta crear nuevo codigo de error.
if not os.path.exists (f'{ogGlobals.OGCAC}/boot/{oglivedir}/ogvmlinuz') or not os.path.exists (f'{ogGlobals.OGCAC}/boot/{oglivedir}/oginitrd.img'):
SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_NOTFOUND, 'CACHE: ogvmlinuz, oginitrd.img')
return None
# Archivo de configuracion del grub
dirmount = FileSystemLib.ogMount (disk, par)
grubcfg = f'{dirmount}/boot/grubMBR/boot/grub/grub.cfg'
# Error si no existe archivo del grub
if not os.path.exists (grubcfg):
SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_NOTFOUND, grubcfg)
return None
# Si existe la entrada de opengnsys, se borra
grubcfg_contents = ''
with open (grubcfg, 'r') as fd:
grubcfg_contents = fd.read()
if 'menuentry Opengnsys' in grubcfg_contents:
subprocess.run (['sed', '-ie', '/menuentry Opengnsys/,+6d', grubcfg])
# Tipo de tabla de particiones
parttabletype = DiskLib.ogGetPartitionTableType (disk)
parttabletype = parttabletype.lower()
# Localizacion de la cache
cachepart = CacheLib.ogFindCache()
if not cachepart:
SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_NOTCACHE, '')
return None
numdisk, numpart = cachepart.split()
numdisk = int (numdisk) - 1
# kernel y sus opciones. Pasamos a modo usuario
proc_cmdline = ''
with open ('/proc/cmdline', 'r') as fd:
proc_cmdline = fd.read().strip()
proc_cmdline = re.sub ('^.*linuz', '', proc_cmdline)
proc_cmdline = re.sub ('ogactiveadmin=[a-z]*', '', proc_cmdline)
kernel = f'/boot/{oglivedir}/ogvmlinuz {proc_cmdline}'
# Configuracion offline si existe parametro
STATUS = ''
if not offline: offline = ''
if 'offline' in offline: STATUS = 'offline'
if 'online' in offline: STATUS = 'online'
if STATUS:
kernel = re.sub ('ogprotocol=[a-z]* ', 'ogprotocol=local ', kernel)
kernel += f' ogstatus={STATUS}'
# Numero de línea de la primera entrada del grub.
grep_out = subprocess.run (['grep', '--line-number', '--max-count', '1', '^menuentry', grubcfg], capture_output=True, text=True).stdout
numline, _ = grep_out.split (':', maxsplit=1)
# Texto de la entrada de opengnsys
menuentry = f'''menuentry "OpenGnsys" --class opengnsys --class gnu --class os {{ \\
\tinsmod part_{parttabletype} \\
\tinsmod ext2 \\
\tset root='(hd{numdisk},{parttabletype}{numpart})' \\
\tlinux {kernel} \\
\tinitrd /boot/{oglivedir}/oginitrd.img \\
}}'''
# Insertamos la entrada de opengnsys antes de la primera entrada existente.
subprocess.run (['sed', '-i', f'{numline}i\\ {menuentry}', grubcfg])
# Ponemos que la entrada por defecto sea la primera.
subprocess.run (['sed', '-i', f's/set.*default.*$/set default="0"/g', grubcfg])
# Si me dan valor para timeout lo cambio en el grub.
if timeout:
subprocess.run (['sed', '-i', f's/timeout=.*$/timeout={timeout}/g', grubcfg])
#/**
# ogGrubHidePartitions num_disk num_part
#@brief ver ogBootLoaderHidePartitions
#@see ogBootLoaderHidePartitions
#*/ ##
def ogGrubHidePartitions (disk, par, datadisk=None, datapar=None):
return ogBootLoaderHidePartitions (disk, par, datadisk, datapar)
#/**
# ogBurgHidePartitions num_disk num_part
#@brief ver ogBootLoaderHidePartitions
#@see ogBootLoaderHidePartitions
#*/ ##
#/**
# ogBootLoaderHidePartitions num_disk num_part
@ -1073,89 +731,23 @@ def ogGrubHidePartitions (disk, par, datadisk=None, datapar=None):
#@exception No existe archivo de configuracion del grub/burg.
#*/
def ogBootLoaderHidePartitions (disk, par, datadisk=None, datapar=None):
# Nombre de la función que llama a esta.
func = inspect.stack()[1][3]
# Si no existe $4 pongo un valor imposible para la partición de datos
if datapar:
partdata = DiskLib.ogDiskToDev (datadisk, datapar)
else:
partdata = '0'
# Archivo de configuracion del grub
DIRMOUNT = FileSystemLib.ogMount (disk, par)
# La función debe ser llamanda desde ogGrubHidePartitions or ogBurgHidePartitions.
if 'ogGrubHidePartitions' == func:
cfgfile = f'{DIRMOUNT}/boot/grubMBR/boot/grub/grub.cfg'
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Use ogGrubHidePartitions')
return None
# Error si no existe archivo del grub
if not os.path.exists (cfgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, cfgfile)
return None
# Si solo hay una particion de Windows me salgo
num_ntfs = 0
disks = DiskLib.ogDiskToDev()
fdisk_out = subprocess.run (['fdisk', '-l']+disks, capture_output=True, text=True).stdout
for l in fdisk_out.splitlines():
if 'NTFS' in l: num_ntfs += 1
if 1 == num_ntfs: return True
# Elimino llamadas a parttool, se han incluido en otras ejecuciones de esta funcion.
subprocess.run (['sed', '-i', '/parttool/d', cfgfile])
parttabletype = DiskLib.ogGetPartitionTableType (disk)
parttabletype = parttabletype.lower()
# Entradas de Windows: numero de linea y particion. De mayor a menor.
#1:/dev/sda2
#2:/dev/sda3
awk_out = subprocess.run (f'''
awk '/menuentry.*Windows/ {{gsub(/\\)"/, ""); gsub(/^.*dev/,""); print NR":/dev"$1}} ' {cfgfile}
''', shell=True, text=True, capture_output=True).stdout
if awk_out:
winentry = awk_out.splitlines()
winentry.reverse()
else:
winentry = []
# Particiones de Windows, pueden no estar en el grub.
winpart = []
for l in fdisk_out.splitlines(): ## aprovechamos la variable fdisk_out de antes
if 'NTFS' not in l: continue
items = l.split (' ')
winpart.append (items[0])
winpart.reverse()
# Modifico todas las entradas de Windows.
for entry in winentry:
line, part = entry.split (':')
# En cada entrada, oculto o muestro cada particion.
text = ''
for parthidden in winpart:
# Muestro la particion de la entrada actual y la de datos.
if parthidden == part or parthidden == partdata:
hidden = '-'
else:
hidden = '+'
numdisk, numpart = DiskLib.ogDevToDisk (parthidden).split()
numdisk = int (numdisk)
numpart = int (numpart)
text = f'\tparttool (hd{numdisk-1},{parttabletype}{numpart}) hidden{hidden} \n{text}'
subprocess.run (['sed', '-i', f'{line}a\\ {text}', cfgfile])
# Activamos la particion que se inicia en todas las entradas de windows.
subprocess.run (['sed', '-i', '/chainloader/i\\\tparttool ${root} boot+', cfgfile])
#/**
# ogGrubDeleteEntry num_disk num_part num_disk_delete num_part_delete
#@brief ver ogBootLoaderDeleteEntry
#@see ogBootLoaderDeleteEntry
#*/
def ogGrubDeleteEntry (disk, par, diskdel, pardel):
return ogBootLoaderDeleteEntry (disk, par, diskdel, pardel)
#/**
# ogBurgDeleteEntry num_disk num_part num_disk_delete num_part_delete
#@brief ver ogBootLoaderDeleteEntry
#@see ogBootLoaderDeleteEntry
#*/
#/**
# ogRefindDeleteEntry num_disk_delete num_part_delete
#@brief ver ogBootLoaderDeleteEntry
#@see ogBootLoaderDeleteEntry
#*/
#/**
# ogBootLoaderDeleteEntry num_disk num_part num_part_delete
@ -1164,73 +756,43 @@ def ogGrubDeleteEntry (disk, par, diskdel, pardel):
#@param 2 Numero de particion donde esta el grub
#@param 3 Numero del disco del que borramos las entradas
#@param 4 Numero de la particion de la que borramos las entradas
#@note Tiene que ser llamada desde ogGrubDeleteEntry
#@note Tiene que ser llamada desde ogGrubDeleteEntry, ogBurgDeleteEntry o ogRefindDeleteEntry
#@return (nada)
#@exception OG_ERR_FORMAT Use ogGrubDeleteEntry
#@exception OG_ERR_FORMAT Use ogGrubDeleteEntry or ogBurgDeleteEntry.
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND No existe archivo de configuracion del grub.
#*/ ##
def ogBootLoaderDeleteEntry (disk, par, diskdel, pardel):
# Nombre de la función que llama a esta.
func = inspect.stack()[1][3]
#/**
# ogBurgInstallMbr int_disk_GRUBCFG int_partition_GRUBCFG
#@param bolean_Check_Os_installed_and_Configure_2ndStage true | false[default]
#@brief Instala y actualiza el gestor grub en el MBR del disco duro donde se encuentra el fichero grub.cfg. Admite sistemas Windows.
#@param int_disk_SecondStage
#@param int_part_SecondStage
#@param bolean_Check_Os_installed_and_Configure_2ndStage true | false[default]
#@return
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_PARTITION Partición no soportada
#*/ ##
# Archivo de configuracion del grub
dirmount = FileSystemLib.ogMount (disk, par)
# La función debe ser llamanda desde ogGrubDeleteEntry, ogBurgDeleteEntry or ogRefindDeleteEntry.
if 'ogGrubDeleteEntry' == func:
cfgfile = f'{dirmount}/boot/grubMBR/boot/grub/grub.cfg'
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Use ogGrubDeleteEntry')
return None
# Dispositivo
label = DiskLib.ogDiskToDev (diskdel, pardel)
# Error si no existe archivo de configuración
if not os.path.exists (cfgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, cfgfile)
return None
# Numero de linea de cada entrada.
menuentry = []
grep_out = subprocess.run (['grep', '-n', '-e', 'menuentry', cfgfile], capture_output=True, text=True).stdout
if grep_out:
for l in grep_out.splitlines():
lineno, _ = l.split (':', maxsplit=1)
menuentry.append (lineno)
menuentry.reverse()
# Entradas que hay que borrar.
deleteentry = []
grep_out = subprocess.run (['grep', '-n', f'menuentry.*{label}', cfgfile], capture_output=True, text=True).stdout
if grep_out:
for l in grep_out.splitlines():
lineno, _ = l.split (':', maxsplit=1)
deleteentry.append (lineno)
# Si no hay entradas para borrar me salgo con aviso
if not deleteentry:
SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_NOTFOUND, f'Menuentry {label}')
return None
# Recorremos el fichero del final hacia el principio.
with open (cfgfile, 'r') as fd:
endentry = len (fd.read().splitlines())
for entry in menuentry:
# Comprobamos si hay que borrar la entrada.
if entry in deleteentry:
endentry -= 1
subprocess.run (['sed', '-i', '-e', f'{entry},{endentry}d', cfgfile])
# Guardamos el número de línea de la entrada, que sera el final de la siguiente.
endentry = entry
#/**
# ogGrubDefaultEntry int_disk_GRUGCFG int_partition_GRUBCFG int_disk_default_entry int_npartition_default_entry
#@brief ver ogBootLoaderDefaultEntry
#@see ogBootLoaderDefaultEntry
#*/ ##
def ogGrubDefaultEntry (disk, par, diskdefault, pardefault):
return ogBootLoaderDefaultEntry (disk, par, diskdefault, pardefault)
#/**
# ogBurgDefaultEntry int_disk_BURGCFG int_partition_BURGCFG int_disk_default_entry int_npartition_default_entry
#@brief ver ogBootLoaderDefaultEntry
#@see ogBootLoaderDefaultEntry
#*/ ##
#/**
# ogRefindDefaultEntry int_disk_default_entry int_npartition_default_entry
#@brief ver ogBootLoaderDefaultEntry
#@see ogBootLoaderDefaultEntry
#*/ ##
#/**
# ogBootLoaderDefaultEntry int_disk_CFG int_partition_CFG int_disk_default_entry int_npartition_default_entry
@ -1245,64 +807,25 @@ def ogGrubDefaultEntry (disk, par, diskdefault, pardefault):
#@exception OG_ERR_OUTOFLIMIT Param $3 no es entero.
#@exception OG_ERR_NOTFOUND Fichero de configuración no encontrado: burg.cfg.
#*/ ##
def ogBootLoaderDefaultEntry (disk, par, diskdefault, pardefault):
# Nombre de la función que llama a esta.
func = inspect.stack()[1][3]
# Error si no puede montar sistema de archivos.
dirmount = FileSystemLib.ogMount (disk, par)
if not dirmount: return None
# Comprobamos que exista fichero de configuración
# La función debe ser llamanda desde ogGrubDefaultEntry, ogBurgDefaultEntry or ogRefindDefaultEntry.
if 'ogGrubDefaultEntry' == func:
cfgfile = f'{dirmount}/boot/grubMBR/boot/grub/grub.cfg'
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Use ogGrubDefaultEntry')
return None
# Error si no existe archivo de configuración
if not os.path.exists (cfgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, cfgfile)
return None
# Dispositivo
label = DiskLib.ogDiskToDev (diskdefault, pardefault)
# Número de línea de la entrada por defecto en CFGFILE (primera de la partición).
grep_out = subprocess.run (['grep', '--line-number', '--max-count', '1', f'menuentry.*{label}', cfgfile], capture_output=True, text=True).stdout
if not grep_out:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'menuentry {label}')
return None
defaultentry, _ = grep_out.split (':', maxsplit=1)
# Si no hay entradas para borrar me salgo con aviso
if not defaultentry:
SystemLib.ogRaiseError (['session', 'log'], ogGlobals.OG_ERR_NOTFOUND, f'No menuentry {label}')
return None
# Número de la de linea por defecto en el menú de usuario
menuentry = subprocess.run (f'grep -n -e menuentry {cfgfile}| cut -d: -f1 | grep -n {defaultentry} |cut -d: -f1', shell=True, text=True, capture_output=True).stdout
if not menuentry: return None
menuentry = int (menuentry)
# En grub y burg las líneas empiezan a contar desde cero
menuentry -= 1
subprocess.run (['sed', '--regexp-extended', '-i', f's/set default="?[0-9]*"?$/set default="{menuentry}"/g', cfgfile])
MSG = f'ogGlobals.lang.MSG_HELP_{func}'
try: MSG = eval (MSG)
except: MSG = ''
if '.' == MSG[-1]: MSG=MSG[0:-1]
print (f'{MSG}: {disk} {par} {diskdefault} {pardefault}')
return True
#/**
# ogGrubOgliveDefaultEntry num_disk num_part
#@brief ver ogBootLoaderOgliveDefaultEntry
#@see ogBootLoaderOgliveDefaultEntry
#*/ ##
def ogGrubOgliveDefaultEntry (disk, par):
return ogBootLoaderOgliveDefaultEntry (disk, par)
#/**
# ogBurgOgliveDefaultEntry num_disk num_part
#@brief ver ogBootLoaderOgliveDefaultEntry
#@see ogBootLoaderOgliveDefaultEntry
#*/ ##
#/**
# ogRefindOgliveDefaultEntry
#@brief ver ogBootLoaderOgliveDefaultEntry
#@see ogBootLoaderOgliveDefaultEntry
#*/ ##
#/**
@ -1316,49 +839,6 @@ def ogGrubOgliveDefaultEntry (disk, par):
#@exception OG_ERR_NOTFOUND Fichero de configuración no encontrado: burg.cfg.
#@exception OG_ERR_NOTFOUND Entrada de OgLive no encontrada en burg.cfg.
#*/ ##
def ogBootLoaderOgliveDefaultEntry (disk, par):
# Nombre de la función que llama a esta.
func = inspect.stack()[1][3]
# Error si no puede montar sistema de archivos.
PART = FileSystemLib.ogMount (disk, par)
if not PART: return None
# La función debe ser llamanda desde ogGrubOgliveDefaultEntry, ogBurgOgliveDefaultEntry or ogRefindOgliveDefaultEntry.
if 'ogGrubOgliveDefaultEntry' == func:
cfgfile = f'{PART}/boot/grubMBR/boot/grub/grub.cfg'
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Use ogGrubOgliveDefaultEntry')
return None
# Comprobamos que exista fichero de configuración
if not os.path.exists (cfgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, cfgfile)
return None
# Detectamos cual es la entrada de ogLive
numentry = 0
with open (cfgfile, 'r') as fd:
while True:
l = fd.readline()
if not l: break
if l.startswith ('menuentry'):
numentry += 1
if 'OpenGnsys Live' in l: break
# Si no existe entrada de ogLive nos salimos
if not numentry:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'menuentry OpenGnsys Live in {cfgfile}')
return None
numentry -= 1
subprocess.run (['sed', '--regexp-extended', '-i', f's/set default="?[0-9]+"?/set default="{numentry}"/g', cfgfile])
MSG = f'ogGlobals.lang.MSG_HELP_{func}'
try: MSG = eval (MSG)
except: MSG = ''
if '.' == MSG[-1]: MSG=MSG[0:-1]
print (f'{MSG}: {disk} {par}')
return True
#/**
@ -1373,44 +853,6 @@ def ogBootLoaderOgliveDefaultEntry (disk, par):
#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar (ogMount).
#@exception OG_ERR_NOTFOUND No encuentra archivo de configuración del grub.
#*/ ##
def ogGrubSecurity (disk, par, user='root', passwd=''):
#localizar disco segunda etapa del grub
secondstage = FileSystemLib.ogMount (disk, par)
if not secondstage: return None
## original bash code:
## $SECONDSTAGE/{,boot/}{{grubMBR,grubPARTITION}/boot/,}{grub{,2},{,efi/}EFI/*}/{menu.lst,grub.cfg,grub.cfg.backup.og}
grubcfg = []
for _uno in ['', 'boot']:
for _dos in ['grubMBR/boot', 'grubPARTITION/boot', '']:
for _tres in ['grub', 'grub2', 'EFI/*', 'efi/EFI/*']:
for _cuatro in ['menu.lst', 'grub.cfg', 'grub.cfg.backup.og']:
path = '/'.join ([secondstage, _uno, _dos, _tres, _cuatro])
grubcfg += glob.glob (path)
# comprobamos que exista el archivo de configuración.
if not grubcfg:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, 'grub.cfg')
return None
if passwd:
encryptpasswd = subprocess.run (['grub-mkpasswd-pbkdf2'], input=f'{passwd}\n{passwd}', text=True, capture_output=True).stdout
if encryptpasswd:
lines = encryptpasswd.strip().splitlines()
encryptpasswd = lines[-1]
encryptpasswd = re.sub ('^.*grub', 'grub', encryptpasswd)
for file in grubcfg:
# Eliminamos configuración anterior
subprocess.run (['sed', '-i', '-e', '/superusers/d', '-e', '/password_pbkdf2/d', file])
# Configuramos grub.cfg para que sólo permita editar o entrar en línea de comandos al usuario especificado
if passwd:
subprocess.run (['sed', '-i', f'1i\\password_pbkdf2 {user} {encryptpasswd}', file])
subprocess.run (['sed', '-i', f'1i\\set superusers="{user}"', file])
# Permitimos que se seleccionen las entradas
subprocess.run (['sed', '-i', '/menuentry /s/{/--unrestricted {/', file])
#/**
@ -1419,6 +861,19 @@ def ogGrubSecurity (disk, par, user='root', passwd=''):
#@see ogBootLoaderSetTheme
#*/ ##
#/**
# ogBurgSetTheme num_disk num_part str_theme
#@brief ver ogBootLoaderSetTheme
#@see ogBootLoaderSetTheme
#*/ ##
#/**
# ogRefindSetTheme str_theme
#@brief ver ogBootLoaderSetTheme
#@see ogBootLoaderSetTheme
#*/ ##
#/**
# ogBootLoaderSetTheme
@ -1441,6 +896,12 @@ def ogGrubSecurity (disk, par, user='root', passwd=''):
#@see ogBootLoaderSetTheme
#*/ ##
#/**
# ogBurgSetAdminKeys num_disk num_part str_bolean
#@brief ver ogBootLoaderSetAdminKeys
#@see ogBootLoaderSetAdminKeys
#*/ ##
#/**
@ -1463,8 +924,19 @@ def ogGrubSecurity (disk, par, user='root', passwd=''):
#@brief ver ogBootLoaderSetTimeOut
#@see ogBootLoaderSetTimeOut
#*/ ##
def ogGrubSetTimeOut (disk, par, timeout):
return ogBootLoaderSetTimeOut (disk, par, timeout)
#/**
# ogBurgSetTimeOut num_disk num_part str_bolean
#@brief ver ogBootLoaderSetTimeOut
#@see ogBootLoaderSetTimeOut
#*/ ##
#/**
# ogRefindSetTimeOut int_timeout_second
#@brief ver ogBootLoaderSetTimeOut
#@see ogBootLoaderSetTimeOut
#*/ ##
#/**
# ogBootLoaderSetTimeOut
@ -1478,29 +950,6 @@ def ogGrubSetTimeOut (disk, par, timeout):
#@exception OG_ERR_NOTFOUND Fichero de configuración no encontrado: grub.cfg burg.cfg.
#@exception OG_ERR_NOTFOUND Entrada deltema no encontrada en burg.cfg.
#*/ ##
def ogBootLoaderSetTimeOut (disk, par, timeout):
# Nombre de la función que llama a esta.
func = inspect.stack()[1][3]
# Error si no puede montar sistema de archivos.
PART = FileSystemLib.ogMount (disk, par)
if not PART: return None
# La función debe ser llamanda desde ogGrubSetTimeOut, ogBurgSetTimeOut or ogRefindSetTimeOut.
if 'ogGrubSetTimeOut' == func:
bootloader = 'grub'
bootloaderdir = 'boot/grubMBR'
cfgfile = f'{PART}/boot/grubMBR/boot/grub/grub.cfg'
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Use ogGrubSetTimeOut')
return None
# Comprobamos que exista fichero de configuración
if not os.path.exists (cfgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, cfgfile)
return None
# Asignamos el timeOut.
subprocess.run (['sed', '-i', f's/timeout=.*$/timeout={timeout}/g', cfgfile])
#/**
@ -1509,6 +958,12 @@ def ogBootLoaderSetTimeOut (disk, par, timeout):
#@see ogBootLoaderSetResolution
#*/ ##
#/**
# ogBurgSetResolution num_disk num_part str_bolean
#@brief ver ogBootLoaderSetResolution
#@see ogBootLoaderSetResolution
#*/ ##
#/**
@ -1537,6 +992,18 @@ def ogBootLoaderSetTimeOut (disk, par, timeout):
#@exception OG_ERR_NOTFOUND Fichero de configuración no encontrado: grub.cfg burg.cfg.
#*/ ##
# ogRefindInstall bool_autoconfig
#@brief Instala y actualiza el gestor rEFInd en la particion EFI
#@param bolean_Check__auto_config true | false[default]
#@return
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND No se encuentra la partición ESP.
#@exception OG_ERR_NOTFOUND No se encuentra shimx64.efi.signed.
#@exception OG_ERR_NOTFOUND No se encuentra refind-install o refind en OGLIB
#@exception OG_ERR_PARTITION No se puede montar la partición ESP.
#@note Refind debe estar instalado en el ogLive o compartido en OGLIB
#*/ ##
#/**
# ogGrub4dosInstallMbr int_ndisk
#@brief Genera un nuevo Codigo de arranque en el MBR del disco indicado, compatible con los SO tipo Windows, Linux.
@ -1549,54 +1016,3 @@ def ogBootLoaderSetTimeOut (disk, par, timeout):
#@exception OG_ERR_NOMSDOS Disco duro no particioniado en modo msdos
#@exception OG_ERR_NOTWRITE Particion no modificable.
#*/ ##
def ogGrub4dosInstallMbr (disk, par):
#Controlar existencia de disco y particion
device = DiskLib.ogDiskToDev (disk)
if not device:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, '')
return None
mountdisk = FileSystemLib.ogMount (disk, par)
if not mountdisk:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_ERROR)
return None
#Controlar acceso de escritura a la particion
if FileSystemLib.ogIsReadonly (disk, par):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTWRITE, f': {disk} {par}')
return None
#Controlar disco no uefi
if InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTBIOS, ' : grub4dos solo soporta PC con bios legacy')
return None
#Controlar particionado tipo msdos
ptt = DiskLib.ogGetPartitionTableType (disk)
if 'MSDOS' != ptt:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOMSDOS, ': grub2dos requiere particionado tipo MSDOS')
return None
#Controlar la existencia del grub4dos con acceso a ntfs
bindir = f'{ogGlobals.OGLIB}/grub4dos/grub4dos-0.4.6a'
if not os.path.exists (f'{bindir}/bootlace.com'):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f': {bindir}/bootlace.com')
return None
#instalar el bootloader de grlrd en el MBR
subprocess.run ([f'{bindir}/bootlace64.com', device], capture_output=True)
#copiar grld a la particion
shutil.copy2 (f'{bindir}/grldr', mountdisk)
#Instalar y configurar grub4dos
if os.path.exists (f'{mountdisk}/boot/grub/menu.lst'):
os.unlink (f'{mountdisk}/boot/grub/menu.lst')
os.rmdir (f'/{mountdisk}/boot/grub')
if not os.path.exists (f'{mountdisk}/boot/grub/menu.lst'):
os.makedirs (f'/{mountdisk}/boot/grub', exist_ok=True)
open (f'/{mountdisk}/boot/grub/menu.lst', 'w').close()
grubdisk = int (disk) - 1
with open (f'/{mountdisk}/boot/grub/menu.lst', 'w') as fd:
fd.write ('##NO-TOCAR-ESTA-LINEA MBR\n')
fd.write ('timeout 0\n')
fd.write ('title MBR\n')
fd.write (f'root (hd{grubdisk},0)\n')
fd.write (f'chainloader (hd{grubdisk},0)+1\n')
fd.write ('boot\n')
fd.write ('EOT\n')
fd.write ('\n')

View File

@ -9,6 +9,7 @@ import ogGlobals
import SystemLib
import DiskLib
import FileSystemLib
import CacheLib
#/**
# ogCreateCache [int_ndisk] int_partsize
@ -86,8 +87,8 @@ def ogCreateCache (ndsk=1, part=4, sizecache=0):
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], capture_output=True, text=True).returncode:
subprocess.run (['gdisk', DISK], input='2\nw\nY\n', capture_output=True, text=True)
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
@ -113,7 +114,6 @@ def ogCreateCache (ndsk=1, part=4, sizecache=0):
subprocess.run (['sfdisk', '--no-reread', DISK], input=i, text=True)
# Actualiza la tabla de particiones en el kernel.
DiskLib.ogUpdatePartitionTable()
return True
@ -232,7 +232,8 @@ def ogFormatCache():
os.makedirs (j, exist_ok=True)
# Incluir kernel e Initrd del ogLive
subprocess.run ([f'{ogGlobals.OGSCRIPTS}/updateBootCache.py'])
## como lo llamo sin especificar el path entero?
#subprocess.run (['scripts/updateBootCache.py']) ## TODO
#/**
@ -356,5 +357,5 @@ def ogUnmountCache():
#@return lo mismo que devuelve initCache
#*/ ##
def initCache (*args):
p = subprocess.run ([f'{ogGlobals.OGSCRIPTS}/initCache.py'] + list(args))
p = subprocess.run (['/opt/opengnsys/images/nati/client/shared/scripts/initCache.py'] + list(args))
return p.returncode

View File

@ -76,7 +76,7 @@ def ogCreatePartitions (disk, parts):
CACHEPART = CacheLib.ogFindCache()
if CACHEPART:
cache_disk, cache_part = CACHEPART.split()
if ND == int (cache_disk):
if ND == cache_disk:
CACHESIZE = int (CacheLib.ogGetCacheSize()) * 2
# Sector de inicio (la partición 1 empieza en el sector 63).
IODISCO = ogDiskToDev (disk)
@ -108,7 +108,6 @@ def ogCreatePartitions (disk, parts):
if f'{ND} {PART}' == CACHEPART and CACHESIZE:
sfdisk_input += f'{DISK}{NVME_PREFIX}{PART} : start={SECTORS+1}, size={CACHESIZE}, Id=ca\n'
PART += 1
continue
# Leer formato de cada parámetro - Tipo:Tamaño
TYPE, SIZE = p.split (':')
@ -176,10 +175,10 @@ def ogCreatePartitions (disk, parts):
ogCreatePartitionTable (ND)
# Definir particiones y notificar al kernel.
p = subprocess.run (['sfdisk', DISK], input=sfdisk_input, capture_output=True, text=True)
subprocess.run (['sfdisk', DISK], input=sfdisk_input, capture_output=True, text=True)
subprocess.run (['partprobe', DISK])
if CACHESIZE: CacheLib.ogMountCache()
return not p.returncode
return True
#/**
@ -220,7 +219,6 @@ def ogCreateGptPartitions (disk, parts):
ALIGN = int (subprocess.run (['sgdisk', '-D', DISK], capture_output=True, text=True).stdout)
START = ALIGN
PART = 1
print (f'START ({START}) SECTORS ({SECTORS}) PART ({PART})')
# Leer parámetros con definición de particionado.
DELOPTIONS = []
@ -282,10 +280,10 @@ def ogCreateGptPartitions (disk, parts):
ogCreatePartitionTable (ND, 'GPT')
# Definir particiones y notificar al kernel.
p = subprocess.run (['sgdisk'] + DELOPTIONS + OPTIONS + [DISK], capture_output=True, text=True)
subprocess.run (['sgdisk'] + DELOPTIONS + OPTIONS + [DISK])
subprocess.run (['partprobe', DISK])
if CACHESIZE: CacheLib.ogMountCache()
return not p.returncode
return True
#/**
@ -814,7 +812,7 @@ def ogGetPartitionId (disk, par):
if fsid == '8300' and f'{disk} {par}' == CacheLib.ogFindCache():
fsid = 'CA00'
elif 'MSDOS' == pttype:
fsid = subprocess.run (['sfdisk', '--part-type', DISK, str(par)], capture_output=True, text=True).stdout.strip()
fsid = subprocess.run (['sfdisk', '--part-type', DISK, par], capture_output=True, text=True).stdout.strip()
elif 'LVM' == pttype:
fsid = '10000'
elif 'ZPOOL' == pttype:
@ -1171,7 +1169,6 @@ def ogSetPartitionActive (disk, par):
#@exception OG_ERR_PARTITION Error al cambiar el id. de partición.
#@attention Requisitos: fdisk, sgdisk
#*/ ##
## for GPT partitions, id must be one of the valid types as reported by 'sgdisk --list-types', eg. 0700 or 8200
def ogSetPartitionId (disk, par, id):
DISK = ogDiskToDev (disk)
if not DISK: return None

View File

@ -213,8 +213,10 @@ def ogCopyFile (src, dst):
if not TARGET:
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).
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
@ -504,10 +506,12 @@ def ogMakeDir (container=None, disk=None, par=None, file=None):
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

View File

@ -14,6 +14,7 @@ import ogGlobals
import SystemLib
import DiskLib
import CacheLib
import FileSystemLib
#/**
@ -286,11 +287,15 @@ def ogGetFsSize (disk, par, unit='KB'):
elif unit.upper() == "TB":
factor = 1024 * 1024 * 1024
elif unit.upper() != "KB":
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f"{unit} != {{ KB, MB, GB, TB }}")
SystemLib.ogRaiseError (
[],
ogGlobals.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).
mnt = ogMount (disk, par)
mnt = FileSystemLib.ogMount (disk, par)
if mnt:
result = subprocess.run(["df", "-BK", mnt], capture_output=True, text=True)
val = result.stdout.split("\n")[1].split()[1]
@ -327,7 +332,11 @@ def ogGetFsType(disk, part):
try:
subprocess.run(["zfs", "mount", PART])
except FileNotFoundError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTEXEC, 'zfs')
SystemLib.ogRaiseError (
[],
ogGlobals.OG_ERR_NOTEXEC,
'zfs'
)
return
out = subprocess.run(["mount"], capture_output=True, text=True).stdout.splitlines()
for line in out:
@ -336,7 +345,11 @@ def ogGetFsType(disk, part):
break
if not TYPE:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{disk} {part}')
SystemLib.ogRaiseError (
[],
ogGlobals.OG_ERR_NOTFOUND,
f'{disk} {part}'
)
return
# Componer valores correctos.
@ -580,7 +593,11 @@ def ogMountFs (disk, par):
try:
rc = subprocess.run(['mount', dev, mntdir, '-o', 'force,remove_hiberfile'], check=True).returncode
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk}, {par}")
SystemLib.ogRaiseError (
[],
ogGlobals.OG_ERR_PARTITION,
f"{disk}, {par}"
)
return
if 0 == rc:
@ -589,18 +606,26 @@ def ogMountFs (disk, par):
try:
subprocess.run (['ntfsfix', '-d', par], check=True)
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk, par}")
SystemLib.ogRaiseError (
[],
ogGlobals.OG_ERR_PARTITION,
f"{disk, par}"
)
#return
else:
try:
subprocess.run (['mount', par, mntdir, '-o', 'ro'], check=True)
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk, par}")
SystemLib.ogRaiseError (
[],
ogGlobals.OG_ERR_PARTITION,
f"{disk, par}"
)
#return
# Aviso de montaje de solo lectura.
if ogIsReadonly(disk, par):
SystemLib.ogEcho ([], "warning", f'ogMountFs: {ogGlobals.lang.MSG_MOUNTREADONLY}: "{disk}, {par}"')
SystemLib.ogEcho("warning", f'ogMountFs: {ogGlobals.lang.MSG_MOUNTREADONLY}: "{disk}, {par}"')
else:
# Montar sistema de archivos ZFS (un ZPOOL no comienza por "/").
subprocess.run(['zfs', 'mount', dev])
@ -692,8 +717,7 @@ def ogReduceFs (disk, par):
break
elif type == 'NTFS':
ogUnmount (disk, par)
ntfsresize_out = subprocess.run (['ntfsresize', '-fi', PART], capture_output=True, text=True).stdout
nr_lines = ntfsresize_out.splitlines()
nr_lines = subprocess.run (['ntfsresize', '-fi', PART], capture_output=True, text=True).stdout.splitlines()
maxsize = None
size = None
for l in nr_lines:
@ -703,10 +727,12 @@ def ogReduceFs (disk, par):
size = l.split()[4]
size = int ((int (size) * 1.1 / 1024 + 1) * 1024)
if not maxsize or not size:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk},{par} ({ntfsresize_out})')
if not maxsize and not size:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk},{par}')
return None
import time
extrasize = 0
retval = 1
while retval != 0 and size+extrasize < maxsize:
@ -784,14 +810,18 @@ def ogUnmountFs(disk, par):
if MNTDIR:
# Error si la particion está bloqueada.
if ogIsLocked (disk, par):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f"{ogGlobals.lang.MSG_PARTITION}, {disk} {par}")
SystemLib.ogRaiseError (
[],
ogGlobals.OG_ERR_LOCKED,
f"{ogGlobals.lang.MSG_PARTITION}, {disk} {par}"
)
return
# Desmontar y borrar punto de montaje.
try:
subprocess.run(["umount", PART], check=True)
except subprocess.CalledProcessError:
SystemLib.ogEcho ([], "warning", f'ogUnmountFs: {ogGlobals.lang.MSG_DONTUNMOUNT}: "{disk}, {par}"')
SystemLib.ogEcho("warning", f'ogUnmountFs: {ogGlobals.lang.MSG_DONTUNMOUNT}: "{disk}, {par}"')
try:
os.rmdir(MNTDIR)
except:
@ -865,7 +895,7 @@ def ogGetFreeSize(disk, part, unit='KB'):
kk
factor = unit2factor[unit.lower()]
particion = ogMount (disk, part)
particion = FileSystemLib.ogMount (disk, part)
if not particion:
kk
df = subprocess.run (['df'], capture_output=True, text=True).stdout

View File

@ -233,7 +233,7 @@ def ogCreateImage (disk, par, container, imgfile, tool='partclone', level='gzip'
bn = os.path.basename (imgfile)
IMGFILE = f'{imgdir}/{bn}.{imgtype}'
if ogIsImageLocked (container=None, imgfile=IMGFILE):
if ogIsImageLocked (IMGFILE):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{ogGlobals.lang.MSG_IMAGE} {container}, {imgfile}')
return None
@ -512,8 +512,6 @@ def ogRestoreImage (repo, imgpath, disk, par):
rc = None
try:
p = subprocess.run (program, shell=True, capture_output=True, text=True)
print (p.stdout)
print (p.stderr)
rc = p.returncode
if not rc:
SystemLib.ogRaiseError ([], ogGlobalsOG_ERR_IMAGE, f'{imgfile}, {disk}, {par}')

View File

@ -115,6 +115,7 @@ def ogIsEfiActive():
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 ])

View File

@ -39,32 +39,48 @@ def _ogConnect (server, protocol, src, dst, options, readonly):
#@param 2 Abreviatura Unidad Organizativa
#@return Cambio recurso remoto en OGIMG.
#*/
def ogChangeRepo (ip_repo):
ogprotocol = os.environ.get ('ogprotocol', 'smb')
def ogChangeRepo(ip_repo, og_unit=None):
ogprotocol = os.environ['ogprotocol'] or 'smb'
if og_unit:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, 'the og_unit parameter became unsupported')
return None
try:
mount = subprocess.run (['mount'], capture_output=True, text=True).stdout
ro = bool (list (filter (lambda line: re.search (r'ogimages.*\bro,', line), mount.splitlines())))
current_repo = ogGetRepoIp()
new_repo = current_repo if ip_repo.upper() == 'REPO' else ip_repo
new_repo = current_repo if ip_repo.upper() == "REPO" else ip_repo
if new_repo == current_repo: return True
subprocess.run (['umount', ogGlobals.OGIMG], check=True)
subprocess.run(["umount", ogGlobals.OGIMG], check=True)
SystemLib.ogEcho (['session', 'log'], None, f'{ogGlobals.lang.MSG_HELP_ogChangeRepo} {new_repo}')
options = _ogConnect_options()
if not _ogConnect (new_repo, ogprotocol, 'ogimages', ogGlobals.OGIMG, options, ro):
_ogConnect (current_repo, ogprotocol, 'ogimages', ogGlobals.OGIMG, options, ro)
SystemLib.ogRaiseError ('session', ogGlobals.OG_ERR_REPO, f'Error connecting to the new repository: {new_repo}')
SystemLib.ogRaiseError(
"session",
ogGlobals.OG_ERR_REPO,
f"Error connecting to the new repository: {new_repo}",
)
return False
SystemLib.ogEcho (['session', 'log'], None, f'Repository successfully changed to {new_repo}'.strip())
SystemLib.ogEcho(
["session", "log"],
None,
f"Repository successfully changed to {new_repo}".strip(),
)
return True
except Exception as e:
SystemLib.ogRaiseError ('session', ogGlobals.OG_ERR_GENERIC, f'Error executing ogChangeRepo: {e}')
SystemLib.ogRaiseError(
"session",
ogGlobals.OG_ERR_GENERIC,
f"Error executing ogChangeRepo: {e}",
)
return None
#/**
@ -199,6 +215,7 @@ def ogGetMacAddress():
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")

View File

@ -120,7 +120,7 @@ def ogUcastSyntax (op, sess, file=None, device=None, tool=None, level=None):
#@note
#@todo: ogIsLocked siempre devuelve 1
#*/ ##
#ogUcastSendPartition 1 2 8001:192.168.1.113 partclone lzop
def ogUcastSendPartition (disk, par, sess, tool, level):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return None
@ -151,7 +151,6 @@ def ogUcastSendPartition (disk, par, sess, tool, level):
#@note
#@todo:
#*/ ##
#ogUcastReceiverPartition 1 1 8001:192.168.1.111 partclone lzop
def ogUcastReceiverPartition (disk, par, sess, tool, level):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return None
@ -189,10 +188,6 @@ def ogUcastReceiverPartition (disk, par, sess, tool, level):
#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')
#ogUcastSendFile 1 2 /boot/vmlinuz-6.8.0-51-generic 8000:192.168.1.113
#ogUcastSendFile 1 4 /swapfile.sys 8000:192.168.1.111
#ogUcastSendFile REPO /ubu24.img 8000:192.168.1.111
def ogUcastSendFile (disk=None, par=None, container=None, file=None, sess=None):
if file is None:
raise TypeError ('missing required argument: "file"')
@ -447,10 +442,6 @@ def ogMcastSyntax (op, sess, file=None, device=None, tool=None, level=None):
#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')
#ogMcastSendFile 1 2 /boot/vmlinuz-6.8.0-51-generic 9000:full-duplex:239.194.37.31:50M:20:10
#ogMcastSendFile REPO /ubu24.img 9000:full-duplex:239.194.37.31:50M:20:10
#ogMcastSendFile /usr/lib64/ld-linux-x86-64.so.2 9000:full-duplex:239.194.37.31:50M:20:10
def ogMcastSendFile (disk=None, par=None, container=None, file=None, sess=None):
if file is None:
raise TypeError ('missing required argument: "file"')
@ -513,8 +504,6 @@ def ogMcastSendFile (disk=None, par=None, container=None, file=None, sess=None):
#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')
#ogMcastReceiverFile 9000:full-duplex:239.194.37.31 1 4 /hola
def ogMcastReceiverFile (disk=None, par=None, container=None, file=None, sess=None):
if file is None:
raise TypeError ('missing required argument: "file"')
@ -573,7 +562,6 @@ def ogMcastReceiverFile (disk=None, par=None, container=None, file=None, sess=No
#ogMcastSendPartition (disk, par, SessionMulticastSERVER, tools, compresor)
#ogMcastSendPartition (1, 1, '9000:full-duplex:239.194.37.31:50M:20:2', 'partclone', 'lzop')
#ogMcastSendPartition 1 2 9000:full-duplex:239.194.37.31:50M:20:10 partclone lzop
def ogMcastSendPartition (disk, par, sess, tool, compressor):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return
@ -598,7 +586,6 @@ def ogMcastSendPartition (disk, par, sess, tool, compressor):
#@return
#@exception $OG_ERR_FORMAT
#*/ ##
#ogMcastReceiverPartition 1 1 9000:full-duplex:239.194.37.31 partclone lzop
def ogMcastReceiverPartition (disk, par, sess, tool, compressor):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return
@ -642,9 +629,6 @@ def ogMcastRequest (img, proto):
#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')
#ogTorrentStart /opt/opengnsys/cache/opt/opengnsys/images/ubu24.EXTFS.torrent seeder:10000
#ogTorrentStart 1 4 /opt/opengnsys/images/ubu24.EXTFS.torrent seeder:10000
#ogTorrentStart CACHE /ubu24.EXTFS.torrent seeder:10000
def ogTorrentStart (disk=None, par=None, container=None, torrentfile=None, torrentsess=None):
if torrentfile is None:
raise TypeError ('missing required argument: "torrentfile"')

View File

@ -3,7 +3,6 @@ import datetime
from zoneinfo import ZoneInfo
import sys
import os
import json
import shutil
import inspect
import glob
@ -14,6 +13,7 @@ from contextlib import redirect_stdout, redirect_stderr
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
@ -21,7 +21,6 @@ import StringLib
def _logtype2logfile (t):
if 'log' == t.lower(): return ogGlobals.OGLOGFILE
if 'jsonlog' == t.lower(): return ogGlobals.OGJSONLOGFILE
elif 'command' == t.lower(): return ogGlobals.OGLOGCOMMAND
elif 'session' == t.lower(): return ogGlobals.OGLOGSESSION
else: raise Exception (f'unknown log type ({t})')
@ -37,40 +36,24 @@ def ogEcho (logtypes, loglevel, msg):
logfiles = ['/dev/stdout']
if type (logtypes) is list:
for l in logtypes:
if 'log' == l:
logfiles.append (_logtype2logfile ('log'))
logfiles.append (_logtype2logfile ('jsonlog'))
else:
logfiles.append (_logtype2logfile (l))
logfiles.append (_logtype2logfile (l))
else: ## string
if 'log' == logtypes:
logfiles.append (_logtype2logfile ('log'))
logfiles.append (_logtype2logfile ('jsonlog'))
else:
logfiles.append (_logtype2logfile (logtypes))
logfiles.append (_logtype2logfile (logtypes))
if loglevel is None or 'help' == loglevel:
if ogGlobals.DEBUG.lower() != "no":
logfiles.append (ogGlobals.OGLOGFILE)
logfiles.append (ogGlobals.OGJSONLOGFILE)
for f in logfiles:
with open (f, 'a') as fd:
if ogGlobals.OGJSONLOGFILE == f:
fd.write (json.dumps ({'message':msg}) + '\n')
else:
fd.write (msg + '\n')
fd.write (msg + '\n')
return
if 'info' == loglevel or 'warning' == loglevel or 'error' == loglevel:
DATETIME = datetime.datetime.now (ZoneInfo (ogGlobals.TZ)).strftime ('%F %T %Z')
DATETIME_json = datetime.datetime.now (ZoneInfo (ogGlobals.TZ)).strftime ('%Y-%m-%d %H:%M:%S')
DATETIME = datetime.datetime.now(ZoneInfo(ogGlobals.TZ)).strftime("%F %T %Z")
for f in logfiles:
with open (f, 'a') as fd:
if ogGlobals.OGJSONLOGFILE == f:
fd.write (json.dumps ({'timestamp':DATETIME_json, 'severity':loglevel, 'message':msg}) + '\n')
else:
fd.write (f"OpenGnsys {loglevel} {DATETIME} {msg}\n")
fd.write (f"OpenGnsys {loglevel} {DATETIME} {msg}\n")
else:
raise Exception (f'unknown loglevel ({loglevel})')
@ -83,28 +66,20 @@ def ogEcho (logtypes, loglevel, msg):
#@return Salida de ejecución del comando.
#@note str_logfile = { LOG, SESSION, COMMAND }
#*/
#ogExecAndLog (str_logfile ... str_command ...",
#ogExecAndLog ([], ogMyLib.ogSomeMethod, *args, **kwargs)
#ogExecAndLog ('command', ogMyLib.ogSomeMethod, *args, **kwargs)
#ogExecAndLog (['command'], ogMyLib.ogSomeMethod, *args, **kwargs)
#ogExecAndLog (['log', 'command'], ogMyLib.ogSomeMethod, *args, **kwargs)
#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))
if 'log' == l:
logfiles.append (_logtype2logfile ('log'))
logfiles.append (_logtype2logfile ('jsonlog'))
else:
logfiles.append (_logtype2logfile (l))
logfiles.append (_logtype2logfile (l))
else: ## string
logtypes = logtypes.lower()
if 'log' == logtypes:
logfiles.append (_logtype2logfile ('log'))
logfiles.append (_logtype2logfile ('jsonlog'))
else:
logfiles.append (_logtype2logfile (logtypes))
logfiles.append (_logtype2logfile (logtypes))
if not fun:
ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'no function provided')
@ -146,19 +121,9 @@ def ogExecAndLog (logtypes, fun, *args, **kwargs):
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 ogGlobals.OGJSONLOGFILE == f:
if sout: fd.write (json.dumps ({'message':sout}) + '\n')
if serr: fd.write (json.dumps ({'message':serr}) + '\n')
if rc_str: fd.write (json.dumps ({'message':rc_str}) + '\n')
else:
if sout: fd.write (f'{sout}\n')
if serr: fd.write (f'{serr}\n')
if rc_str: fd.write (f'{rc_str}\n')
#fd.write (f"ogExecAndLog: {fun.__name__} rc:\n{rc_str}\n")
#if sout: fd.write (f"ogExecAndLog: {fun.__name__} stdout:\n{sout}\n")
#else: fd.write (f"ogExecAndLog: {fun.__name__} stdout: (none)\n")
#if serr: fd.write (f"ogExecAndLog: {fun.__name__} stderr:\n{serr}\n")
#else: fd.write (f"ogExecAndLog: {fun.__name__} stderr: (none)\n")
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
@ -312,11 +277,11 @@ def ogIsRepoLocked():
# FUNCNAME = ogCheckProgram.__name__
#
# if not program or not isinstance(program, str):
# ogRaiseError ("session", ogGlobals.OG_ERR_FORMAT, f"Error: {ogGlobals.lang.MSG_ERR_FORMAT} {FUNCNAME} \"program\"")
# SystemLib.ogRaiseError ("session", ogGlobals.OG_ERR_FORMAT, f"Error: {ogGlobals.lang.MSG_ERR_FORMAT} {FUNCNAME} \"program\"")
# return
#
# if not shutil.which(program):
# ogRaiseError ( "session", ogGlobals.OG_ERR_NOTEXEC, f"Error: The program '{program}' is not available on the system.")
# SystemLib.ogRaiseError ( "session", ogGlobals.OG_ERR_NOTEXEC, f"Error: The program '{program}' is not available on the system.")
# return
#
# return 0

View File

@ -42,8 +42,8 @@ def ogNvramActiveEntry (entry):
numentries.append (words[0][4:8])
except ValueError:
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=2)
if len(words) < 3: continue
words = l.split (maxsplit=1)
if len(words) < 2: continue
if words[1] == entry:
numentries.append (words[0][4:8])
@ -135,6 +135,8 @@ def ogCopyEfiBootLoader (disk, par):
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':
@ -178,8 +180,8 @@ def ogNvramDeleteEntry (entry):
numentries.append (words[0][4:8])
except ValueError:
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=2)
if len(words) < 3: continue
words = l.split (maxsplit=1)
if len(words) < 2: continue
if words[1] == entry:
numentries.append (words[0][4:8])
@ -323,8 +325,8 @@ def ogNvramInactiveEntry (entry):
numentries.append (words[0][4:8])
except ValueError:
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=2)
if len(words) < 3: continue
words = l.split (maxsplit=1)
if len(words) < 2: continue
if words[1] == entry:
numentries.append (words[0][4:8])
@ -426,7 +428,7 @@ def ogRestoreEfiBootLoader (disk, par):
return
osversion = InventoryLib.ogGetOsVersion (disk, par)
if osversion and 'Windows 1' in osversion:
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:
@ -485,8 +487,8 @@ def ogNvramSetNext (entry):
numentries.append (words[0][4:8])
except ValueError:
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=2)
if len(words) < 3: continue
words = l.split (maxsplit=1)
if len(words) < 2: continue
if words[1] == entry:
numentries.append (words[0][4:8])
@ -494,7 +496,7 @@ def ogNvramSetNext (entry):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'NVRAM entry "{entry}"')
return
if 1 != len (numentries):
if 1 != len(numentries):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, f'more than one entry found')
return

View File

View File

@ -1,7 +1,6 @@
#!/usr/bin/python3
import sys
import os
import os.path
import locale
import importlib.util
@ -57,45 +56,12 @@ 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')
OGPYFUNCS = os.path.join (OPENGNSYS, 'functions')
OGSCRIPTS = os.path.join (OPENGNSYS, 'scripts')
OGIMG = os.path.join (OPENGNSYS, 'images')
OGCAC = os.path.join (OPENGNSYS, 'cache')
OGLOGFILE = '/var/log/clone-engine.log'
OGJSONLOGFILE = '/var/log/clone-engine.json.log'
OGLOG = os.path.join (OPENGNSYS, 'log')
OGLOGFILE = f'{OGLOG}/192.168.42.42' ## TODO import NetLib; OGLOGFILE = f'$OGLOG/{NetLib.ogGetIpAddress()}.log'
DEBUG = 'yes'
_path = os.environ['PATH'] + ':/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin:/opt/oglive/rootfs/opt/drbl/sbin'
os.environ['PATH'] = ':'.join ([OGSCRIPTS, _path, OGAPI, OGBIN])
if os.path.exists ('/tmp/initrd.cfg'):
with open ('/tmp/initrd.cfg', 'r') as fd:
initrd_cfg = fd.read()
for l in initrd_cfg.splitlines():
if not l.startswith ('DEVICECFG='): continue ## eg. "DEVICECFG=/run/net-enp0s3.conf"
device_cfg = l.split ('=')[1]
if os.path.exists (device_cfg):
with open (device_cfg, 'r') as fd:
contents = fd.read()
exec (contents) ## !!!
## example contents:
#DEVICE='enp0s3'
#PROTO='none'
#IPV4ADDR='192.168.2.11'
#IPV4BROADCAST='192.168.2.255'
#IPV4NETMASK='255.255.255.0'
#IPV4GATEWAY='192.168.2.1'
#IPV4DNS0='0.0.0.0'
#IPV4DNS1='0.0.0.0'
#HOSTNAME='pc1'
#DNSDOMAIN=''
#NISDOMAIN=''
#ROOTSERVER='10.0.2.15'
#ROOTPATH=''
#filename=''
#UPTIME='161'
#DHCPLEASETIME='0'
#DOMAINSEARCH=''
break
## /loadenviron.sh
# Declaración de códigos de error.

View File

@ -7,6 +7,7 @@ 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
@ -15,7 +16,7 @@ if 2 == len (sys.argv) and 'help' == sys.argv[1]:
args = parser.parse_args()
ret = ogChangeRepo (args.ip_repo)
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)

View File

@ -55,9 +55,6 @@ elif 6 == len (sys.argv):
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 }
else:
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 (1)
ret = ogCopyFile (src, dst)
if ret is not None:

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