refs #1401 add ogListSoftware, fix a bug
parent
30c90442b7
commit
fab9fe7ddb
|
@ -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:
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
Loading…
Reference in New Issue