diff options
-rwxr-xr-x | scripts/pstage-scanner | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/scripts/pstage-scanner b/scripts/pstage-scanner new file mode 100755 index 000000000..923491258 --- /dev/null +++ b/scripts/pstage-scanner @@ -0,0 +1,127 @@ +#!/usr/bin/env python + +## +## This script will scan all of the packages in ${OEROOT}/pstage (or argv[1]) +## in search of packages which install files outside of their native sysroot +## + +import os, sys, tarfile, shutil +import subprocess as sub + +logf = "" +pcount = 0 +ecount = 0 + +def main(): + """Generate a list of pstage packages and scan them for badness""" + package_list = [] + + ## First we walk the pstage directory, let's assume we're running from + ## a sibling of pstage (i.e. scripts) if no path defined + try: + path = sysv.arg[1] + except: + path = os.path.join(os.environ.get("OEROOT"), "pstage") + + if len(path) < 1 or not os.path.exists(path): + path = os.path.join(os.environ.get("OEROOT"), "pstage") + + global logf + try: + logf = sys.argv[2] + except: + logf = os.path.join(path, "pstage-scanner.log") + + ## Create a working directory + tempdir = os.path.join(path, "tmp") + os.mkdir(tempdir) + + ## Iterate each child of the target directory looking for .ipk files and + ## building a list of files to process + for root, dirs, files in os.walk(path): + for d in dirs: + for f in os.listdir(os.path.join(root,d)): + if os.path.splitext(f)[1] == ".ipk" and f.find("native") == -1 and f.find("cross") == -1: + package_list.append(os.path.join(root,d,f)) + + ## Next we iterate our built list of files and process each package + for pkg in package_list: + tmp = os.path.join(tempdir, os.path.splitext(os.path.split(pkg)[1])[0]) + os.mkdir(tmp) + scan_package(pkg, tmp) + + ## Tidy up working directory + shutil.rmtree(tempdir) + + ## Report a summary + log("Finished scanning packaged staging. Scanned %i packages with %i errors" % (pcount, ecount)) + +def scan_package(filepath, parentdir): + """Helper method to do bookkeeping, passes all installable directories to + scan_dir which does the actual scanning.""" + os.chdir(parentdir) + + ## increment the package count, for the summary + global pcount + pcount += 1 + + ## An ipk file is an ar archive containing two gzipped tarball directories + ## data.tar.gz is inflated to / and contains the actual files + ## control.tar.gz is metadata and scripts for the package + ## The archive also contains a file, debian binary, which is unused + ## Python can't handle ar archives ootb. So we cheat and inflate with + ## the ar program on the host + sub.call(["ar", "x", filepath]) + + ## The things we care about are in data.tar.gz + tgz = tarfile.open(os.path.join(parentdir, "data.tar.gz")) + dest = os.path.join(parentdir, "inflate") + os.mkdir(dest) + tgz.extractall(dest) + + ## We want to know the target arch so that we can ensure the package is + ## only installing into its target sysroot + arch = os.path.splitext(os.path.basename(filepath))[0].split("_")[-1] + if arch == "64": + arch = "x86_64" + + ## The ignored list contains directories we don't care to scan + ignored = ["pkgdata", "stamps", "deploy"] + + ## Scan the package for badness + pname = os.path.split(filepath)[1] + for di in os.listdir(dest): + if di not in ignored: + scan_dir(os.path.join(dest, di), arch, pname) + +def scan_dir (directory, arch, package_name): + """Scan the contents of directory for things installing outside of native + sysroot""" + + global ecount + msg = "" + + head, tail = os.path.split(directory) + if not tail == "sysroots": + msg += "Tsk tsk, installing to " + tail + "\n" + for d in os.listdir(directory): + msg += "Installing %s in %s" % (d, tail) + "\n" + ecount += 1 + else: + for d in os.listdir(directory): + if not d.startswith(arch) and d.find("fixmepath") == -1: + msg += "Tsk tsk, installing into non-native sysroot " + os.path.join(directory, d) + ecount += 1 + + if len(msg) > 0: + log("Scanning package " + package_name + "\n" + msg) + +def log (message): + global logf + logfile = open (logf, 'a+') + logfile.write(message + "\n") + print "LOG: " + message + logfile.close() + +if __name__ == "__main__": + main() |