refs #1037 full functionality of InventarioHardware.py script is added; InventoryLib.lib library is renamed to InventoryLib.py and hardware inventory functions are updated.

pull/1/head
Antonio Guerrero 2024-11-04 04:37:04 +00:00
parent 41012ac0bf
commit 1c53ce8173
4 changed files with 404 additions and 33 deletions

View File

@ -3,13 +3,27 @@ import sys
def main(output_file):
# Ejecutar el comando `listHardwareInfo.py` y capturar el resultado
result = subprocess.run(["python3", "/opt/opengnsys/scripts/listHardwareInfo.py"], capture_output=True, text=True, check=True)
file_path = result.stdout.strip() # Obtener la ruta del archivo de salida de `listHardwareInfo.py`
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)
# 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:

View File

@ -1,23 +0,0 @@
#!/usr/bin/python3
import os
import stat
#def ogGetArch():
#def ogGetOsType():
#def ogGetOsUuid():
#def ogGetSerialNumber():
#/**
# ogIsEfiActive
#@brief Comprueba si el sistema tiene activo el arranque EFI.
#*/ ##
def ogIsEfiActive():
try:
return stat.S_ISDIR (os.stat ('/sys/firmware/efi').st_mode)
except:
return False
#def ogListHardwareInfo():
#def ogListSoftware():
#def ogGetOsVersion():

View File

@ -0,0 +1,379 @@
import glob
import platform
import sys
import os
import subprocess
import tempfile
import re
import json
import shutil
import sqlite3
from SystemLib import ogMount, ogGetOsType, ogRaiseError, ogHelp, ogGetOsVersion, ogGetHivePath, ogListRegistryKeys, ogGetRegistryValue, ogGetIpAddress
sys.path.append('/opt/opengnsys/lib/engine/bin')
from SystemLib import ogEcho
#from Disklib import ogDiskToDev
#from engine.FileLib import *
#from engine.RegistryLib import *
#from engine.FileSystemLib import *
MSG_HARDWAREINVENTORY = "Inventario de hardware de la máquina"
def ogGetArch():
if len(sys.argv) > 1 and sys.argv[1] == "help":
ogHelp(sys.argv[0], sys.argv[0], sys.argv[0] + " => x86_64")
return
if platform.machine().endswith("64"):
print("x86_64")
else:
print("i386")
def ogGetOsType():
# Si se solicita, mostrar ayuda.
if len(sys.argv) > 1 and sys.argv[1] == "help":
ogHelp(sys.argv[0], sys.argv[0] + " int_ndisk int_npartition", sys.argv[0] + " 1 2 => Linux")
return
ogGetOsVersion(sys.argv[1:]).split(':')[0]
def ogGetOsUuid():
# Si se solicita, mostrar ayuda.
if len(sys.argv) > 1 and sys.argv[1] == "help":
ogHelp(sys.argv[0], sys.argv[0] + " int_ndisk int_nfilesys", sys.argv[0] + " 1 2 => 540e47c6-8e78-4178-aa46-042e4803fb16")
return
# Error si no se reciben 2 parametros.
if len(sys.argv) != 3:
ogRaiseError(OG_ERR_FORMAT)
return
# Montar la particion, si no lo estaba previamente.
MNTDIR = ogMount(sys.argv[1], sys.argv[2])
if not MNTDIR:
return
# Obtener UUID según el tipo de sistema operativo.
os_type = ogGetOsType(sys.argv[1], sys.argv[2])
if os_type == "Linux":
# Leer el UUID del sistema de ficheros raíz o el fichero de identificador.
uuid = subprocess.check_output(["findmnt", "-no", "UUID", MNTDIR], stderr=subprocess.DEVNULL).decode().strip() or open(os.path.join(MNTDIR, "etc", "machine-id")).read().strip()
print(uuid)
elif os_type == "Windows":
# Leer identificador en clave de registro.
uuid = ogGetRegistryValue(MNTDIR, "SOFTWARE", "\\Microsoft\\Cryptography\\MachineGuid")
print(uuid)
def ogGetSerialNumber():
# Si se solicita, mostrar ayuda.
if len(sys.argv) > 1 and sys.argv[1] == "help":
ogHelp(sys.argv[0], sys.argv[0], sys.argv[0] + " => 123456")
return
# Obtener nº de serie (ignorar los no especificados).
SERIALNO = subprocess.check_output(["dmidecode", "-s", "system-serial-number"]).decode().strip()
SERIALNO = re.sub(r"(not specified|to be filled|invalid entry|default string)", "", SERIALNO, flags=re.IGNORECASE)
SERIALNO = SERIALNO.replace(" ", "")
SERIALNO = SERIALNO[:25] if len(SERIALNO) > 25 else SERIALNO
if SERIALNO:
print(SERIALNO)
return 0
def ogIsEfiActive():
return os.path.isdir("/sys/firmware/efi")
import subprocess
import os
import sys
def parse_lshw_output():
try:
# Ejecutar lshw en formato JSON para un fácil procesamiento
lshw_output = subprocess.check_output(["lshw", "-json"], text=True)
lshw_data = json.loads(lshw_output) # Convertir la salida JSON a un diccionario
# Extraer información relevante en el formato clave=valor
parsed_output = []
# Ejemplo de datos clave que podríamos extraer
if "product" in lshw_data:
parsed_output.append(f"product={lshw_data['product']}")
if "vendor" in lshw_data:
parsed_output.append(f"vendor={lshw_data['vendor']}")
if "configuration" in lshw_data and "memory" in lshw_data["configuration"]:
parsed_output.append(f"memory={lshw_data['configuration']['memory']}")
# Recorrer los dispositivos para obtener información de CPU, almacenamiento, etc.
for item in lshw_data.get("children", []):
if item["class"] == "processor":
parsed_output.append(f"cpu={item.get('product', 'Unknown')}")
elif item["class"] == "memory" and "size" in item:
parsed_output.append(f"total_memory={item['size']}")
elif item["class"] == "disk":
parsed_output.append(f"disk={item.get('product', 'Unknown')}")
# Devolver los datos combinados
return "\n".join(parsed_output)
except subprocess.CalledProcessError as e:
print(f"Error al ejecutar lshw: {e}")
return "Error al obtener información de hardware"
def ogListHardwareInfo():
# Ejecutar dmidecode y obtener tipo de chasis
try:
output = subprocess.check_output('echo "cha=$(dmidecode -s chassis-type)" | grep -v "Other"', shell=True).decode().strip()
except subprocess.CalledProcessError:
output = "cha=Unknown"
# Detectar BIOS o UEFI
firmware = "boo=UEFI" if os.path.isdir("/sys/firmware/efi") else "boo=BIOS"
print(firmware)
# Ejecutar y analizar lshw
lshw_output = parse_lshw_output()
# Combina y devuelve los resultados
return f"{output}\n{firmware}\n{lshw_output}"
def ogListSoftware(disk, partition):
# Error si no se reciben 2 parametros
if disk is None or partition is None:
og_raise_error("OG_ERR_FORMAT")
return
# Obtener tipo de sistema de archivos y montarlo
mnt_dir = og_mount(disk, partition)
os_type = og_get_os_type(disk, partition)
# Ficheros temporales
apps_file = tempfile.NamedTemporaryFile(delete=False)
tmp_file = tempfile.NamedTemporaryFile(delete=False)
try:
if os_type == "Linux":
# Procesar paquetes dpkg
pkg_dir = os.path.join(mnt_dir, "var/lib/dpkg")
if os.path.exists(pkg_dir):
with open(os.path.join(pkg_dir, "status"), "r") as status_file:
for line in status_file:
# Process lines to extract software info
pass
# Procesar paquetes RPM
pkg_dir = os.path.join(mnt_dir, "var/lib/rpm")
if os.path.exists(pkg_dir):
# Execute rpm command if available
if shutil.which("rpm"):
subprocess.run(["rpm", "--dbpath", pkg_dir, "-qa", "--qf", "%{NAME} %{VERSION}\n"], stdout=apps_file)
else:
# Compatibility mode for older systems
pass
# Procesar otros tipos de paquetes (pacman, snap, flatpak, etc.)
pass
elif os_type == "Windows":
# Procesar aplicaciones instaladas en Windows
hive_path = og_get_hive_path(mnt_dir, "software")
if hive_path:
subprocess.run(["hivexregedit", "--unsafe-printable-strings", "--export", hive_path, '\Microsoft\Windows\CurrentVersion\Uninstall'], stdout=tmp_file)
elif os_type == "MacOS":
# Procesar aplicaciones instaladas en MacOS
pass
elif os_type == "BSD":
# Procesar aplicaciones instaladas en FreeBSD
pass
else:
og_raise_error("OG_ERR_NOTOS", disk, partition)
finally:
# Eliminar archivos temporales
apps_file.close()
tmp_file.close()
os.remove(apps_file.name)
os.remove(tmp_file.name)
# Mostrar sistema operativo y aplicaciones
og_get_os_version(disk, partition)
with open(apps_file.name, "r") as apps:
for line in sorted(set(apps.readlines())):
print(line.strip())
def ogGetOsVersion(ndisk, nfilesys):
# Variables locales.
MNTDIR = ogMount(ndisk, nfilesys)
TYPE = ""
VERSION = ""
IS64BIT = ""
# Si se solicita, mostrar ayuda.
if len(sys.argv) > 1 and sys.argv[1] == "help":
ogHelp(sys.argv[0], sys.argv[0] + " int_ndisk int_nfilesys", sys.argv[0] + " 1 2 => Linux:Ubuntu precise (12.04 LTS) 64 bits")
return
# Error si no se reciben 2 parametros.
if len(sys.argv) != 3:
ogRaiseError(OG_ERR_FORMAT)
return
# Montar la particion, si no lo estaba previamente.
MNTDIR = ogMount(sys.argv[1], sys.argv[2])
if not MNTDIR:
return
# Buscar tipo de sistema operativo.
# Para GNU/Linux: leer descripción.
TYPE = "Linux"
FILE = os.path.join(MNTDIR, "etc", "os-release")
if os.path.exists(FILE):
with open(FILE, "r") as f:
for line in f:
if line.startswith("PRETTY_NAME"):
VERSION = line.split("=")[1].strip().strip('"')
break
# Si no se puede obtener, buscar en ficheros del sistema.
if not VERSION:
FILE = os.path.join(MNTDIR, "etc", "lsb-release")
if os.path.exists(FILE):
with open(FILE, "r") as f:
for line in f:
if line.startswith("DESCRIPTION"):
VERSION = line.split("=")[1].strip().strip('"')
break
for DISTRIB in ["redhat", "SuSE", "mandrake", "gentoo"]:
FILE = os.path.join(MNTDIR, "etc", f"{DISTRIB}-release")
if os.path.exists(FILE):
with open(FILE, "r") as f:
VERSION = f.readline().strip()
break
FILE = os.path.join(MNTDIR, "etc", "arch-release")
if os.path.exists(FILE):
VERSION = "Arch Linux"
FILE = os.path.join(MNTDIR, "etc", "slackware-version")
if os.path.exists(FILE):
with open(FILE, "r") as f:
VERSION = f.read().strip()
# Si no se encuentra, intentar ejecutar "lsb_release".
if not VERSION:
try:
output = subprocess.check_output(["chroot", MNTDIR, "lsb_release", "-d"], stderr=subprocess.DEVNULL).decode().strip()
VERSION = output.split(":")[1].strip()
except subprocess.CalledProcessError:
pass
# Comprobar Linux de 64 bits.
if VERSION and os.path.exists(os.path.join(MNTDIR, "lib64")):
IS64BIT = "64 bits"
# Para Android, leer fichero de propiedades.
if not VERSION:
TYPE = "Android"
FILE = os.path.join(MNTDIR, "android*", "system", "build.prop")
if glob.glob(FILE):
with open(glob.glob(FILE)[0], "r") as f:
lines = f.readlines()
brand = ""
release = ""
for line in lines:
if line.startswith("product.brand"):
brand = line.split("=")[1].strip()
elif line.startswith("build.version.release"):
release = line.split("=")[1].strip()
VERSION = f"Android {brand} {release}"
if os.path.exists(os.path.join(MNTDIR, "lib64")):
IS64BIT = "64 bits"
# Para GNU/Hurd, comprobar fichero de inicio (basado en os-prober).
if not VERSION:
TYPE = "Hurd"
FILE = os.path.join(MNTDIR, "hurd", "init")
if os.path.exists(FILE):
VERSION = "GNU/Hurd"
# Para Windows: leer la version del registro.
if not VERSION:
TYPE = "Windows"
FILE = ogGetHivePath(MNTDIR, "SOFTWARE")
if FILE:
try:
output = subprocess.check_output(["hivexsh", "load", FILE, "cd", "\\Microsoft\\Windows NT\\CurrentVersion", "lsval", "ProductName", "lsval", "DisplayVersion"], stderr=subprocess.DEVNULL).decode().strip()
lines = output.split("\n")
if len(lines) == 2:
VERSION = lines[1].strip()
if ogGetRegistryValue(MNTDIR, "SOFTWARE", "\\Microsoft\\Windows\\CurrentVersion\\ProgramW6432Dir"):
IS64BIT = "64 bits"
except subprocess.CalledProcessError:
pass
# Para cargador Windows: buscar versión en fichero BCD (basado en os-prober).
if not VERSION:
TYPE = "WinLoader"
FILE = ogGetPath(MNTDIR, "boot", "bcd")
if not FILE:
FILE = ogGetPath(MNTDIR, "EFI", "Microsoft", "boot", "bcd")
if FILE:
for DISTRIB in ["Windows Recovery", "Windows Boot"]:
with open(FILE, "rb") as f:
if re.search(DISTRIB.encode(), f.read()):
VERSION = f"{DISTRIB} loader"
break
# Para macOS: detectar kernel y completar con fichero plist de información del sistema.
if not VERSION:
TYPE = "MacOS"
FILE = os.path.join(MNTDIR, "mach_kernel")
if os.path.exists(FILE) and not subprocess.check_output(["file", "-b", FILE]).decode().strip().startswith("text"):
if subprocess.check_output(["file", "-b", FILE]).decode().strip().startswith("Mach-O"):
VERSION = "macOS"
if subprocess.check_output(["file", "-b", FILE]).decode().strip().startswith("Mach-O 64-bit"):
IS64BIT = "64 bits"
FILE = os.path.join(MNTDIR, "System", "Library", "CoreServices", "SystemVersion.plist")
if os.path.exists(FILE):
with open(FILE, "r") as f:
plist_data = f.read()
product_name = re.search(r"<key>ProductName</key>\s*<string>(.*?)</string>", plist_data)
product_version = re.search(r"<key>ProductVersion</key>\s*<string>(.*?)</string>", plist_data)
if product_name and product_version:
VERSION = f"{product_name.group(1)} {product_version.group(1)}"
FILE = os.path.join(MNTDIR, "com.apple.recovery.boot")
if os.path.exists(FILE) and VERSION:
VERSION = f"{VERSION} recovery"
# Para FreeBSD: obtener datos del Kernel.
if not VERSION:
TYPE = "BSD"
FILE = os.path.join(MNTDIR, "boot", "kernel", "kernel")
if os.path.exists(FILE):
output = subprocess.check_output(["strings", FILE]).decode().strip()
match = re.search(r"@.*RELEASE", output)
if match:
VERSION = match.group().split("@")[0].strip()
if subprocess.check_output(["file", "-b", FILE]).decode().strip().endswith("x86-64"):
IS64BIT = "64 bits"
# Para Solaris: leer el fichero de versión.
if not VERSION:
TYPE = "Solaris"
FILE = os.path.join(MNTDIR, "etc", "release")
if os.path.exists(FILE):
with open(FILE, "r") as f:
VERSION = f.readline().strip()
# Para cargador GRUB, comprobar fichero de configuración.
if not VERSION:
TYPE = "GrubLoader"
for FILE in [os.path.join(MNTDIR, "grub", "menu.lst"), os.path.join(MNTDIR, "boot", "grub", "menu.lst")]:
if os.path.exists(FILE):
VERSION = "GRUB Loader"
break
for FILE in glob.glob(os.path.join(MNTDIR, "{,boot/}{grub{,2},EFI/*}/grub.cfg")):
if os.path.exists(FILE):
VERSION = "GRUB2 Loader"
break
# Mostrar resultado y salir sin errores.
if VERSION:
print(f"{TYPE}:{VERSION} {IS64BIT}")
return 0

View File

@ -1,9 +1,10 @@
import subprocess
import os
import sys
sys.path.append('/opt/opengnsys/lib/engine/bin') # Agregar ruta de NetLib.py
from InventoryLib import ogListHardwareInfo
sys.path.append('/opt/opengnsys/lib/engine/bin')
from NetLib import ogGetIpAddress
sys.path.append('/opt/opengnsys/lib/engine/bin')
from InventoryLib import ogListHardwareInfo
def get_server_log_dir():
# Obtener el directorio de logs del servidor
@ -19,10 +20,10 @@ def get_server_log_dir():
def list_hardware_info():
oglog = os.getenv("OGLOG", "/tmp") # Usar /tmp como valor por defecto para OGLOG
ip_address = ogGetIpAddress()
# Fichero de listado de hardware basado en la IP obtenida
hardfile = f"hard-{ogGetIpAddress()}"
print(f"hardfile:{hardfile}")
# Ejecutar ogListHardwareInfo y redirigir al archivo de listado
hardware_info_path = os.path.join(oglog, hardfile)
with open(hardware_info_path, 'w') as output_file: