137 lines
4.4 KiB
Python
Executable File
137 lines
4.4 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
##
|
|
## This script will scan all of the packages in PSTAGE_DIR (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 = []
|
|
|
|
try:
|
|
path = sysv.arg[1]
|
|
except:
|
|
# Assume pstage is a child of tmp, Poky's default
|
|
tmpdir = None
|
|
sub.Popen(["bitbake", "-e"], stdout=sub.PIPE,stderr=sub.PIPE)
|
|
err, out = p.communicate()
|
|
if (!out):
|
|
print("bitbake not in your environment, try pstage-scanner /some/path/to/pstage")
|
|
exit
|
|
for line in out:
|
|
if line.find("PSTAGE_DIR=") != -1:
|
|
tmpdir = line.partition("=")[2].strip("\"")
|
|
break
|
|
|
|
if len(path) < 1 or not os.path.exists(path):
|
|
print ("No path defined and bitbake not in your environment, try pstage-scanner /some/path/to/pstage")
|
|
exit
|
|
|
|
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()
|