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