refs #1401 add ogListSoftware, fix a bug

pull/1/head
Natalia Serrano 2025-01-29 18:13:20 +01:00
parent 30c90442b7
commit fab9fe7ddb
3 changed files with 143 additions and 50 deletions

View File

@ -605,6 +605,8 @@ def ogConfigureFstab (disk, par):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{disk},{par},/etc/fstab') SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{disk},{par},/etc/fstab')
return return
efiopt = ''
shutil.copy2 (fstab, fstab+'.backup') shutil.copy2 (fstab, fstab+'.backup')
with open ('/etc/fstab', 'r') as fd: with open ('/etc/fstab', 'r') as fd:

View File

@ -10,12 +10,12 @@ import platform
import sys import sys
import os import os
import subprocess import subprocess
import tempfile
import re import re
import json import json
import shutil import shutil
import glob import glob
import plistlib import plistlib
#import bsddb
import ogGlobals import ogGlobals
import SystemLib import SystemLib
@ -197,65 +197,132 @@ def ogListHardwareInfo():
#@note Requisitos: ... #@note Requisitos: ...
#@todo Detectar software en Linux #@todo Detectar software en Linux
#*/ ## #*/ ##
def ogListSoftware(disk, partition): def ogListSoftware (disk, par):
if disk is None or partition is None: mntdir = FileSystemLib.ogMount (disk, par)
SystemLib.ogRaiseError(ogGlobals.OG_ERR_FORMAT) if not mntdir: return None
return [] ostype = ogGetOsType (disk, par)
if not ostype: return None
mnt_dir = FileSystemLib.ogMount(disk, partition)
os_type = ogGetOsType(disk, partition)
apps_file = tempfile.NamedTemporaryFile(delete=False, mode="w+")
tmp_file = tempfile.NamedTemporaryFile(delete=False, mode="w+")
apps = [] apps = []
try: if 'Linux' == ostype:
if os_type == "Linux": # Procesar paquetes dpkg.
pkg_dir = os.path.join(mnt_dir, "var/lib/dpkg") pkgdir = f'{mntdir}/var/lib/dpkg'
status_file = os.path.join(pkg_dir, "status") if os.path.exists (pkgdir):
if os.path.exists(status_file): status_file = os.path.join(pkgdir, "status")
with open(status_file, "r") as f: awk_script = '''
pkg, ver = None, None /Package:/ {if (pack!="") print pack,vers;
for line in f: sub(/-dev$/,"",$2);
if line.startswith("Package:"): pack=$2}
pkg = line.split(":", 1)[1].strip() /Version:/ {sub(/^.*:/,"",$2); sub(/-.*$/,"",$2);
elif line.startswith("Version:"): vers=$2}
ver = line.split(":", 1)[1].strip() /Status:/ {if ($2!="install") pack=vers=""}
elif line.startswith("Status:") and "install" not in line: END {if (pack!="") print pack,vers}
pkg, ver = None, None '''
if pkg and ver: awk_out = subprocess.run (['awk', awk_script, status_file], capture_output=True, text=True).stdout
apps.append(f"{pkg} {ver}") apps = awk_out.splitlines()
pkg, ver = None, None
pkg_dir = os.path.join(mnt_dir, "var/lib/rpm") # Procesar paquetes RPM.
if os.path.exists(pkg_dir): pkgdir = f'{mntdir}/var/lib/rpm'
if shutil.which("rpm"): if os.path.exists (pkgdir):
result = subprocess.run( if shutil.which ('rpm'):
["rpm", "--dbpath", pkg_dir, "-qa", "--qf", "%{NAME} %{VERSION}\n"], for f in glob.glob (f'{pkgdir}/__db.*'):
capture_output=True, os.unlink (f)
text=True rpm_out = subprocess.run (['rpm', '--dbpath', pkgdir, '-qa', '--qf', '%{NAME} %{VERSION}\n'], capture_output=True, text=True).stdout
) for l in rpm_out.splitlines():
if result.returncode == 0: words = l.split()
apps.extend(result.stdout.strip().splitlines()) if (not re.search ('-devel$', words[0])):
words[1] = re.sub ('-.*', '', words[1])
apps.append (' '.join (words))
for f in glob.glob (f'{pkgdir}/__db.*'):
os.unlink (f)
else: else:
SystemLib.ogEcho("session", "error", "The rpm command is not available.") pass
#db = bsddb.hashopen (f'{pkgdir}/Name', 'r');
#for k in db.keys():
# apps.append (re.sub ('-devel$', '', k))
# Procesar paquetes pacman.
pkgdir = f'{mntdir}/var/lib/pacman/local'
if os.path.exists (pkgdir):
for f in glob.glob (f'{pkgdir}/*'):
if '-' not in f: continue
idx = f[0:f.rfind ('-')].rfind ('-') ## index of 2nd-to-last dash
apps.append (f[0:idx] + ' ' + f[idx+1:])
# Procesar aplicaciones Snappy.
pkgdir = f'{mntdir}/snap'
out = ''
awk_script = '''
/name:/ {pack=$2}
/version:/ {vers=$2}
END {if (pack!="") print pack,"(snap)",vers}
'''
files = subprocess.run (['find', f'{pkgdir}/*/current/meta', '-name', 'snap.yaml'], capture_output=True, text=True).stdout.splitlines()
for f in files:
awk_out = subprocess.run (['awk', awk_script, f], capture_output=True, text=True).stdout
out += awk_out
apps += out.splitlines()
# Procesar aplicaciones Flatpak.
pkgdir = f'{mntdir}/var/lib/flatpak'
files = glob.glob (f'{pkgdir}/app/*/current/active/deploy/*')
for f in files:
p = open (f.strip()).read().split ('\0')
try:
if (p[0] != 'flathub'): raise ValueError
apps.append ('{} (flatpak) {}'.format (p[p.index('appdata-name') + 4], p[p.index('appdata-version') + 1]))
except ValueError:
pass pass
elif 'Windows' == ostype:
if shutil.which ('hivexregedit'):
hive = RegistryLib.ogGetHivePath (mntdir, 'software')
if hive:
cmd1_out = subprocess.run (['hivexregedit', '--unsafe-printable-strings', '--export', hive, r'\Microsoft\Windows\CurrentVersion\Uninstall'], capture_output=True, text=True).stdout
cmd1_out += subprocess.run (['hivexregedit', '--unsafe-printable-strings', '--export', hive, r'\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'], capture_output=True, text=True).stdout
out = name = ''
for l in cmd1_out.splitlines():
words = l.split ('"')
if len(words) < 4: continue
if (re.match (r'\[', words[0])): name=''
if (re.search ('DisplayName', words[1])): name=words[3]
if (re.search ('DisplayVersion', words[1])): apps.append (f'{name} {words[3]}')
else: else:
SystemLib.ogRaiseError(ogGlobals.OG_ERR_NOTOS, disk, partition) keys = RegistryLib.ogListRegistryKeys (mntdir, 'software', r'\Microsoft\Windows\CurrentVersion\Uninstall')
return [] keys32 = RegistryLib.ogListRegistryKeys (mntdir, 'software', r'\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall')
for k in keys:
prog = RegistryLib.ogGetRegistryValue (mntdir, 'software', rf'\Microsoft\Windows\CurrentVersion\Uninstall\{k}\DisplayName')
if prog:
vers = RegistryLib.ogGetRegistryValue (mntdir, 'software', rf'\Microsoft\Windows\CurrentVersion\Uninstall\{k}\DisplayVersion')
apps.append (f'{prog} {vers}')
for k in keys32:
prog = RegistryLib.gGetRegistryValue (mntdir, 'software', rf'\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{k}\DisplayName')
if prog:
vers = RegistryLib.ogGetRegistryValue (mntdir, 'software', rf'\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{k}\DisplayVersion')
apps.append (f'{prog} {vers}')
finally: elif 'MacOS' == ostype:
apps_file.close() files = subprocess.run (['find', f'{mntdir}/Applications', '-type', 'd', '-name', '*.app', '-prune', '-print'], capture_output=True, text=True).stdout.splitlines()
tmp_file.close() for k in files:
os.remove(apps_file.name) FILE = f'{k}/Contents/version.plist'
os.remove(tmp_file.name) if not os.stat (FILE).st_size:
FILE = f'{k}/Contents/version.plist.uncompress'
if os.stat (FILE).st_size:
VERSION = subprocess.run (['awk', '-F[<>]', '/ShortVersionString/ {getline;v=$3} END {print v}', FILE], capture_output=True, text=True).stdout.strip()
bn = os.path.basename (k)
bn = re.sub ('.app$', '', bn)
apps.append (f'{bn} {VERSION}')
os_version = ogGetOsVersion(disk, partition) elif 'BSD' == ostype:
print(f"Operative System: {os_version}") sqlite_out = subprocess.run (['sqlite3', f'{mntdir}/var/db/pkg/local.sqlite'], input='SELECT name FROM pkg_search;\n', capture_output=True, text=True).stdout
for l in sqlite_out.splitlines():
apps.append (' '.join (re.search ('(.*)-(.*)', l).groups()))
return sorted(set(apps)) else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, f'{disk}, {par} ({ostype})')
return None
os_version = ogGetOsVersion (disk, par).split (':')[1]
return [os_version] + sorted (set (apps))
## https://stackoverflow.com/questions/2522651/find-a-key-inside-a-deeply-nested-dictionary/2522706#2522706 ## https://stackoverflow.com/questions/2522651/find-a-key-inside-a-deeply-nested-dictionary/2522706#2522706
def _find_key_recursive(plist_dict, key_substr): def _find_key_recursive(plist_dict, key_substr):

View File

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