added local RPM support for listing files in RPM
This commit is contained in:
parent
cfc48cac26
commit
ca4a9e4b08
@ -4,6 +4,8 @@
|
|||||||
# Definitely probably won't work on 5.x since they use MD5(?), and 6.5? and up
|
# Definitely probably won't work on 5.x since they use MD5(?), and 6.5? and up
|
||||||
# use SHA256.
|
# use SHA256.
|
||||||
|
|
||||||
|
# TODO: add support for .rpm files (like list_files_package.py)
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import copy
|
import copy
|
||||||
import datetime
|
import datetime
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
# For when CentOS/RHEL switch to python 3 by default (if EVER).
|
# For when CentOS/RHEL switch to python 3 by default (if EVER).
|
||||||
import sys
|
import sys
|
||||||
@ -13,7 +14,7 @@ pyver = sys.version_info
|
|||||||
try:
|
try:
|
||||||
import rpm
|
import rpm
|
||||||
except ImportError:
|
except ImportError:
|
||||||
exit('This script only runs on RHEL/CentOS/other RPM-based distros.')
|
exit('This script only runs on the system-provided Python on RHEL/CentOS/other RPM-based distros.')
|
||||||
|
|
||||||
def all_pkgs():
|
def all_pkgs():
|
||||||
# Gets a list of all packages.
|
# Gets a list of all packages.
|
||||||
@ -29,70 +30,106 @@ class FileGetter(object):
|
|||||||
self.symlinks = symlinks
|
self.symlinks = symlinks
|
||||||
self.verbose = verbose
|
self.verbose = verbose
|
||||||
self.trns = rpm.TransactionSet()
|
self.trns = rpm.TransactionSet()
|
||||||
|
self.files = {}
|
||||||
|
for p in kwargs['pkgs']:
|
||||||
|
if p not in self.files.keys():
|
||||||
|
self.getFiles(p)
|
||||||
|
if kwargs['rpm_files']:
|
||||||
|
self.getLocalFiles(kwargs['rpm_files'])
|
||||||
|
|
||||||
def getfiles(self, pkgnm):
|
def getLocalFiles(self, rpm_files):
|
||||||
files = {}
|
# Needed because the rpm module can't handle arbitrary rpm files??? If it can, someone let me know.
|
||||||
for pkg in self.trns.dbMatch('name', pkgnm):
|
import yum
|
||||||
# The canonical package name
|
for r in rpm_files:
|
||||||
_pkgnm = pkg.sprintf('%{NAME}')
|
pkg = yum.YumLocalPackage(ts = self.trns,
|
||||||
# Return just a list of files, or a dict of filepath:hash
|
filename = r)
|
||||||
# if verbose is enabled.
|
_pkgnm = pkg.hdr.sprintf('%{NAME}')
|
||||||
|
if _pkgnm in self.files:
|
||||||
|
continue
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
files[_pkgnm] = {}
|
self.files[_pkgnm] = {}
|
||||||
else:
|
else:
|
||||||
files[_pkgnm] = []
|
self.files[_pkgnm] = []
|
||||||
for f in pkg.fiFromHeader():
|
for f in pkg.hdr.fiFromHeader():
|
||||||
_symlink = (True if re.search('^0+$', f[12]) else False)
|
_symlink = (True if re.search('^0+$', f[12]) else False)
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
if _symlink:
|
if _symlink:
|
||||||
if self.symlinks:
|
if self.symlinks:
|
||||||
files[_pkgnm][f[0]] = '(symbolic link)'
|
self.files[_pkgnm][f[0]] = '(symbolic link or directory)'
|
||||||
continue
|
continue
|
||||||
files[_pkgnm][f[0]] = f[12]
|
self.files[_pkgnm][f[0]] = f[12]
|
||||||
else:
|
else:
|
||||||
# Skip if it is a symlink but they aren't enabled
|
# Skip if it is a symlink but they aren't enabled
|
||||||
if _symlink and not self.symlinks:
|
if _symlink and not self.symlinks:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
files[_pkgnm].append(f[0])
|
self.files[_pkgnm].append(f[0])
|
||||||
files[_pkgnm].sort()
|
self.files[_pkgnm].sort()
|
||||||
return(files)
|
return()
|
||||||
|
|
||||||
|
def getFiles(self, pkgnm):
|
||||||
|
for pkg in self.trns.dbMatch('name', pkgnm):
|
||||||
|
# The canonical package name
|
||||||
|
_pkgnm = pkg.sprintf('%{NAME}')
|
||||||
|
# Return just a list of files, or a dict of filepath:hash if verbose is enabled.
|
||||||
|
if self.verbose:
|
||||||
|
self.files[_pkgnm] = {}
|
||||||
|
else:
|
||||||
|
self.files[_pkgnm] = []
|
||||||
|
for f in pkg.fiFromHeader():
|
||||||
|
_symlink = (True if re.search('^0+$', f[12]) else False)
|
||||||
|
if self.verbose:
|
||||||
|
if _symlink:
|
||||||
|
if self.symlinks:
|
||||||
|
self.files[_pkgnm][f[0]] = '(symbolic link)'
|
||||||
|
continue
|
||||||
|
self.files[_pkgnm][f[0]] = f[12]
|
||||||
|
else:
|
||||||
|
# Skip if it is a symlink but they aren't enabled
|
||||||
|
if _symlink and not self.symlinks:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
self.files[_pkgnm].append(f[0])
|
||||||
|
self.files[_pkgnm].sort()
|
||||||
|
return()
|
||||||
|
|
||||||
def parseArgs():
|
def parseArgs():
|
||||||
args = argparse.ArgumentParser(description = (
|
args = argparse.ArgumentParser(description = ('This script allows you get a list of files for a given package '
|
||||||
'This script allows you get a list of files for a given '
|
'name(s) without installing any extra packages (such as yum-utils '
|
||||||
'package name(s) without installing any extra packages '
|
'for repoquery). It is highly recommended to use at least one '
|
||||||
'(such as yum-utils for repoquery).'))
|
'-r/--rpm, -p/--package, or both.'))
|
||||||
args.add_argument('-l', '--ignore-symlinks',
|
args.add_argument('-l', '--ignore-symlinks',
|
||||||
dest = 'symlinks',
|
dest = 'symlinks',
|
||||||
action = 'store_false',
|
action = 'store_false',
|
||||||
help = ('If specified, don\'t report files that are ' +
|
help = ('If specified, don\'t report files that are symlinks in the RPM'))
|
||||||
'symlinks in the RPM'))
|
|
||||||
args.add_argument('-v', '--verbose',
|
args.add_argument('-v', '--verbose',
|
||||||
dest = 'verbose',
|
dest = 'verbose',
|
||||||
action = 'store_true',
|
action = 'store_true',
|
||||||
help = ('If specified, include the hashes of the files'))
|
help = ('If specified, include the hashes of the files'))
|
||||||
|
args.add_argument('-r', '--rpm',
|
||||||
|
dest = 'rpm_files',
|
||||||
|
metavar = 'PATH/TO/RPM',
|
||||||
|
action = 'append',
|
||||||
|
default = [],
|
||||||
|
help = ('If specified, use this RPM file instead of the system\'s RPM database. Can be '
|
||||||
|
'specified multiple times'))
|
||||||
args.add_argument('-p', '--package',
|
args.add_argument('-p', '--package',
|
||||||
dest = 'pkgs',
|
dest = 'pkgs',
|
||||||
#nargs = 1,
|
#nargs = 1,
|
||||||
metavar = 'PKGNAME',
|
metavar = 'PKGNAME',
|
||||||
action = 'append',
|
action = 'append',
|
||||||
default = [],
|
default = [],
|
||||||
help = ('If specified, restrict the list of ' +
|
help = ('If specified, restrict the list of packages to check against to only this package. Can '
|
||||||
'packages to check against to only this ' +
|
'be specified multiple times. HIGHLY RECOMMENDED'))
|
||||||
'package. Can be specified multiple times. ' +
|
|
||||||
'HIGHLY RECOMMENDED'))
|
|
||||||
return(args)
|
return(args)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
args = vars(parseArgs().parse_args())
|
args = vars(parseArgs().parse_args())
|
||||||
if not args['pkgs']:
|
args['rpm_files'] = [os.path.abspath(os.path.expanduser(i)) for i in args['rpm_files']]
|
||||||
prompt_str = (
|
if not any((args['rpm_files'], args['pkgs'])):
|
||||||
'You have not specified any package names.\nThis means we will '
|
prompt_str = ('You have not specified any package names.\nThis means we will get file lists for EVERY SINGLE '
|
||||||
'get file lists for EVERY SINGLE installed package.\nThis is a '
|
'installed package.\nThis is a LOT of output and can take a few moments.\nIf this was a mistake, '
|
||||||
'LOT of output and can take a few moments.\nIf this was a '
|
'you can hit ctrl-c now.\nOtherwise, hit the enter key to continue.\n')
|
||||||
'mistake, you can hit ctrl-c now.\nOtherwise, hit the enter key '
|
|
||||||
'to continue.\n')
|
|
||||||
sys.stderr.write(prompt_str)
|
sys.stderr.write(prompt_str)
|
||||||
if pyver.major >= 3:
|
if pyver.major >= 3:
|
||||||
input()
|
input()
|
||||||
@ -100,11 +137,7 @@ def main():
|
|||||||
raw_input()
|
raw_input()
|
||||||
args['pkgs'] = all_pkgs()
|
args['pkgs'] = all_pkgs()
|
||||||
gf = FileGetter(**args)
|
gf = FileGetter(**args)
|
||||||
file_rslts = {}
|
print(json.dumps(gf.files, indent = 4))
|
||||||
for p in args['pkgs']:
|
|
||||||
if p not in file_rslts.keys():
|
|
||||||
file_rslts[p] = gf.getfiles(p)
|
|
||||||
print(json.dumps(file_rslts, indent = 4))
|
|
||||||
return()
|
return()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
Loading…
Reference in New Issue
Block a user