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')
return
efiopt = ''
shutil.copy2 (fstab, fstab+'.backup')
with open ('/etc/fstab', 'r') as fd:

View File

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