scripts/pstage-scanner: new script to sanity test the contents of pstage

Currently the script will scan all packages in the pstage directory and log
packages which contain destinations outside of the native sysroot.
The script currently ignores pkgdata, stamps and deploy but does trigger the
work dir for packages with a package-split file, this may well be a false
positive.

Signed-off-by: Joshua Lock <josh@linux.intel.com>
This commit is contained in:
Joshua Lock 2010-04-22 17:51:07 +01:00
parent 23ff2e0819
commit d2c6f3ef36
1 changed files with 127 additions and 0 deletions

127
scripts/pstage-scanner Executable file
View File

@ -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()