diff options
author | Joshua Lock <josh@linux.intel.com> | 2010-04-22 17:51:07 +0100 |
---|---|---|
committer | Joshua Lock <josh@linux.intel.com> | 2010-04-27 16:58:43 +0100 |
commit | d2c6f3ef36d08ac7ac8a9deab6662f4c3b1a318c (patch) | |
tree | f9c67437709ba2f314c68d561b7a6a7c1b497c61 | |
parent | 23ff2e08194221abf8f09af25d1be98efe46ffb7 (diff) | |
download | poky-d2c6f3ef36d08ac7ac8a9deab6662f4c3b1a318c.tar.gz |
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>
-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 0000000000..9234912581 --- /dev/null +++ b/scripts/pstage-scanner | |||
@@ -0,0 +1,127 @@ | |||
1 | #!/usr/bin/env python | ||
2 | |||
3 | ## | ||
4 | ## This script will scan all of the packages in ${OEROOT}/pstage (or argv[1]) | ||
5 | ## in search of packages which install files outside of their native sysroot | ||
6 | ## | ||
7 | |||
8 | import os, sys, tarfile, shutil | ||
9 | import subprocess as sub | ||
10 | |||
11 | logf = "" | ||
12 | pcount = 0 | ||
13 | ecount = 0 | ||
14 | |||
15 | def main(): | ||
16 | """Generate a list of pstage packages and scan them for badness""" | ||
17 | package_list = [] | ||
18 | |||
19 | ## First we walk the pstage directory, let's assume we're running from | ||
20 | ## a sibling of pstage (i.e. scripts) if no path defined | ||
21 | try: | ||
22 | path = sysv.arg[1] | ||
23 | except: | ||
24 | path = os.path.join(os.environ.get("OEROOT"), "pstage") | ||
25 | |||
26 | if len(path) < 1 or not os.path.exists(path): | ||
27 | path = os.path.join(os.environ.get("OEROOT"), "pstage") | ||
28 | |||
29 | global logf | ||
30 | try: | ||
31 | logf = sys.argv[2] | ||
32 | except: | ||
33 | logf = os.path.join(path, "pstage-scanner.log") | ||
34 | |||
35 | ## Create a working directory | ||
36 | tempdir = os.path.join(path, "tmp") | ||
37 | os.mkdir(tempdir) | ||
38 | |||
39 | ## Iterate each child of the target directory looking for .ipk files and | ||
40 | ## building a list of files to process | ||
41 | for root, dirs, files in os.walk(path): | ||
42 | for d in dirs: | ||
43 | for f in os.listdir(os.path.join(root,d)): | ||
44 | if os.path.splitext(f)[1] == ".ipk" and f.find("native") == -1 and f.find("cross") == -1: | ||
45 | package_list.append(os.path.join(root,d,f)) | ||
46 | |||
47 | ## Next we iterate our built list of files and process each package | ||
48 | for pkg in package_list: | ||
49 | tmp = os.path.join(tempdir, os.path.splitext(os.path.split(pkg)[1])[0]) | ||
50 | os.mkdir(tmp) | ||
51 | scan_package(pkg, tmp) | ||
52 | |||
53 | ## Tidy up working directory | ||
54 | shutil.rmtree(tempdir) | ||
55 | |||
56 | ## Report a summary | ||
57 | log("Finished scanning packaged staging. Scanned %i packages with %i errors" % (pcount, ecount)) | ||
58 | |||
59 | def scan_package(filepath, parentdir): | ||
60 | """Helper method to do bookkeeping, passes all installable directories to | ||
61 | scan_dir which does the actual scanning.""" | ||
62 | os.chdir(parentdir) | ||
63 | |||
64 | ## increment the package count, for the summary | ||
65 | global pcount | ||
66 | pcount += 1 | ||
67 | |||
68 | ## An ipk file is an ar archive containing two gzipped tarball directories | ||
69 | ## data.tar.gz is inflated to / and contains the actual files | ||
70 | ## control.tar.gz is metadata and scripts for the package | ||
71 | ## The archive also contains a file, debian binary, which is unused | ||
72 | ## Python can't handle ar archives ootb. So we cheat and inflate with | ||
73 | ## the ar program on the host | ||
74 | sub.call(["ar", "x", filepath]) | ||
75 | |||
76 | ## The things we care about are in data.tar.gz | ||
77 | tgz = tarfile.open(os.path.join(parentdir, "data.tar.gz")) | ||
78 | dest = os.path.join(parentdir, "inflate") | ||
79 | os.mkdir(dest) | ||
80 | tgz.extractall(dest) | ||
81 | |||
82 | ## We want to know the target arch so that we can ensure the package is | ||
83 | ## only installing into its target sysroot | ||
84 | arch = os.path.splitext(os.path.basename(filepath))[0].split("_")[-1] | ||
85 | if arch == "64": | ||
86 | arch = "x86_64" | ||
87 | |||
88 | ## The ignored list contains directories we don't care to scan | ||
89 | ignored = ["pkgdata", "stamps", "deploy"] | ||
90 | |||
91 | ## Scan the package for badness | ||
92 | pname = os.path.split(filepath)[1] | ||
93 | for di in os.listdir(dest): | ||
94 | if di not in ignored: | ||
95 | scan_dir(os.path.join(dest, di), arch, pname) | ||
96 | |||
97 | def scan_dir (directory, arch, package_name): | ||
98 | """Scan the contents of directory for things installing outside of native | ||
99 | sysroot""" | ||
100 | |||
101 | global ecount | ||
102 | msg = "" | ||
103 | |||
104 | head, tail = os.path.split(directory) | ||
105 | if not tail == "sysroots": | ||
106 | msg += "Tsk tsk, installing to " + tail + "\n" | ||
107 | for d in os.listdir(directory): | ||
108 | msg += "Installing %s in %s" % (d, tail) + "\n" | ||
109 | ecount += 1 | ||
110 | else: | ||
111 | for d in os.listdir(directory): | ||
112 | if not d.startswith(arch) and d.find("fixmepath") == -1: | ||
113 | msg += "Tsk tsk, installing into non-native sysroot " + os.path.join(directory, d) | ||
114 | ecount += 1 | ||
115 | |||
116 | if len(msg) > 0: | ||
117 | log("Scanning package " + package_name + "\n" + msg) | ||
118 | |||
119 | def log (message): | ||
120 | global logf | ||
121 | logfile = open (logf, 'a+') | ||
122 | logfile.write(message + "\n") | ||
123 | print "LOG: " + message | ||
124 | logfile.close() | ||
125 | |||
126 | if __name__ == "__main__": | ||
127 | main() | ||