1 |
commit: eee0d5751702515c4f9ce665644000c8d5aeaa25 |
2 |
Author: Alexander Bersenev <bay <AT> hackerdom <DOT> ru> |
3 |
AuthorDate: Tue Aug 2 00:39:30 2011 +0000 |
4 |
Commit: Александр Берсенев <bay <AT> hackerdom <DOT> ru> |
5 |
CommitDate: Tue Aug 2 00:39:30 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/autodep.git;a=commit;h=eee0d575 |
7 |
|
8 |
auto access blocking |
9 |
|
10 |
--- |
11 |
docs/source/intro.rst | 3 +- |
12 |
src/autodep/{showfsevents.py => autodep} | 0 |
13 |
src/autodep/helpers/events_analysis.py | 30 ++++++- |
14 |
.../package_utils/portage_misc_functions.py | 94 ++++++++++++++++++-- |
15 |
src/autodep/package_utils/portage_utils.py | 21 +++++ |
16 |
5 files changed, 139 insertions(+), 9 deletions(-) |
17 |
|
18 |
diff --git a/docs/source/intro.rst b/docs/source/intro.rst |
19 |
index 5ee0dd5..3914bbc 100644 |
20 |
--- a/docs/source/intro.rst |
21 |
+++ b/docs/source/intro.rst |
22 |
@@ -5,7 +5,8 @@ Introduction |
23 |
Overview |
24 |
=================================== |
25 |
Auto dependency builder is a tool for analysis files accessed during |
26 |
-building a package. It also can be used for runtime dependencies analysis. |
27 |
+building a package. It also can be used for buildtime and runtime dependency |
28 |
+analysis. |
29 |
|
30 |
The tool can block an access to files of defined packages. |
31 |
|
32 |
|
33 |
diff --git a/src/autodep/showfsevents.py b/src/autodep/autodep |
34 |
old mode 100755 |
35 |
new mode 100644 |
36 |
similarity index 100% |
37 |
rename from src/autodep/showfsevents.py |
38 |
rename to src/autodep/autodep |
39 |
|
40 |
diff --git a/src/autodep/helpers/events_analysis.py b/src/autodep/helpers/events_analysis.py |
41 |
index 2928aad..ed5792b 100644 |
42 |
--- a/src/autodep/helpers/events_analysis.py |
43 |
+++ b/src/autodep/helpers/events_analysis.py |
44 |
@@ -1,15 +1,41 @@ |
45 |
#!/usr/bin/env python |
46 |
|
47 |
+excluded_paths=set( |
48 |
+['/etc/sandbox.d/'] |
49 |
+) |
50 |
+ |
51 |
+excluded_packages=set( |
52 |
+# autodep shows these two packages every time |
53 |
+['net-zope/zope-fixers', 'net-zope/zope-interface'] |
54 |
+) |
55 |
+ |
56 |
+def is_file_excluded(f): |
57 |
+ for path in excluded_paths: |
58 |
+ if f.startswith(path): # if path is excluded |
59 |
+ return True |
60 |
+ return False |
61 |
+ |
62 |
+def is_pkg_excluded(p): |
63 |
+ for pkg in excluded_packages: |
64 |
+ if p.startswith(pkg): # if package is excluded |
65 |
+ return True |
66 |
+ return False |
67 |
|
68 |
|
69 |
## some heuristics here to cut few packets |
70 |
def is_package_useful(pkg,stages,files): |
71 |
- # test 1: package is not useful if all files are *.desktop or *.xml or *.m4 |
72 |
+ if is_pkg_excluded(pkg): |
73 |
+ return False |
74 |
+ |
75 |
for f in files: |
76 |
+ if is_file_excluded(f): |
77 |
+ continue |
78 |
+ |
79 |
+ # test 1: package is not useful if all files are *.desktop or *.xml or *.m4 |
80 |
if not (f.endswith(".desktop") or f.endswith(".xml") or f.endswith(".m4")): |
81 |
break |
82 |
else: |
83 |
- return False |
84 |
+ return False # we get here if cycle ends not with break |
85 |
|
86 |
return True |
87 |
|
88 |
|
89 |
diff --git a/src/autodep/package_utils/portage_misc_functions.py b/src/autodep/package_utils/portage_misc_functions.py |
90 |
index c090d89..ca6d890 100644 |
91 |
--- a/src/autodep/package_utils/portage_misc_functions.py |
92 |
+++ b/src/autodep/package_utils/portage_misc_functions.py |
93 |
@@ -8,6 +8,13 @@ from portage.dbapi._expand_new_virt import expand_new_virt |
94 |
# parse_opts function will always be there |
95 |
from _emerge.main import parse_opts |
96 |
|
97 |
+# TODO: check if actions always here |
98 |
+try: |
99 |
+ from _emerge import actions |
100 |
+ from _emerge.create_depgraph_params import create_depgraph_params |
101 |
+ from _emerge.depgraph import backtrack_depgraph, depgraph |
102 |
+except ImportError, Err: # non-critical, just print warning(TODO: strerr) |
103 |
+ print "Error while loading modules: %s" % Err.message |
104 |
|
105 |
class portage_api: |
106 |
""" class for accessing the portage api """ |
107 |
@@ -20,10 +27,87 @@ class portage_api: |
108 |
self.metadata_keys = [k for k in portage.auxdbkeys if not k.startswith("UNUSED_")] |
109 |
self.use=self.settings["USE"] |
110 |
|
111 |
+ def get_best_visible_pkg(self,pkg): |
112 |
+ """ |
113 |
+ Gets best candidate on installing. Returns empty string if no found |
114 |
+ |
115 |
+ """ |
116 |
+ try: |
117 |
+ return self.portdb.xmatch("bestmatch-visible", pkg) |
118 |
+ except: |
119 |
+ return '' |
120 |
+ |
121 |
+ def get_merge_list(self,emergeargs): |
122 |
+ """ |
123 |
+ Gets list of packages that emerge with emergeargs-arguments will merge |
124 |
+ This function uses very internal functions of portage so |
125 |
+ it may be unreliable in various portage versions |
126 |
+ |
127 |
+ """ |
128 |
+ |
129 |
+ try: |
130 |
+ settings,trees,mtimedb=actions.load_emerge_config() |
131 |
+ action, opts, files = parse_opts(emergeargs, silent=True) |
132 |
+ params=create_depgraph_params(opts,action) |
133 |
+ |
134 |
+ success, mydepgraph, favorites = backtrack_depgraph( |
135 |
+ settings, trees, opts, params, action, files, None) |
136 |
+ if not success: |
137 |
+ return [] |
138 |
+ |
139 |
+ ret=[] |
140 |
+ for pkg in mydepgraph.altlist(): |
141 |
+ ret.append(pkg.cpv) |
142 |
+ return ret |
143 |
+ |
144 |
+ except: |
145 |
+ return [] |
146 |
+ |
147 |
+ # non-recursive dependency getter |
148 |
+ def get_dep(self,pkg,dep_type=["RDEPEND","DEPEND"]): |
149 |
+ """ |
150 |
+ Gets current dependencies of a package. Looks in portage db |
151 |
+ |
152 |
+ :param pkg: name of package |
153 |
+ :param dep_type: type of dependencies to recurse. Can be ["DEPEND"] or |
154 |
+ ["RDEPEND", "DEPEND"] |
155 |
+ :returns: **set** of packages names |
156 |
+ """ |
157 |
+ |
158 |
+ ret=set() |
159 |
+ |
160 |
+ pkg = self.get_best_visible_pkg(pkg) |
161 |
+ if not pkg: |
162 |
+ return ret |
163 |
+ |
164 |
+ # we found the best visible match in common tree |
165 |
+ |
166 |
+ metadata = dict(zip(self.metadata_keys, |
167 |
+ self.portdb.aux_get(pkg, self.metadata_keys))) |
168 |
+ dep_str = " ".join(metadata[k] for k in dep_type) |
169 |
+ |
170 |
+ success, atoms = portage.dep_check(dep_str, None, self.settings, |
171 |
+ myuse=self.use.split(), trees=portage.db, myroot=self.settings["ROOT"]) |
172 |
+ if not success: |
173 |
+ return ret |
174 |
+ |
175 |
+ for atom in atoms: |
176 |
+ atomname = self.vartree.dep_bestmatch(atom) |
177 |
+ |
178 |
+ if not atomname: |
179 |
+ continue |
180 |
+ |
181 |
+ for unvirt_pkg in expand_new_virt(self.vartree.dbapi,'='+atomname): |
182 |
+ for pkg in self.vartree.dep_match(unvirt_pkg): |
183 |
+ ret.add(pkg) |
184 |
+ |
185 |
+ return ret |
186 |
+ |
187 |
# recursive dependency getter |
188 |
def get_deps(self,pkg,dep_type=["RDEPEND","DEPEND"]): |
189 |
""" |
190 |
Gets current dependencies of a package on any depth |
191 |
+ All dependencies **must** be installed |
192 |
|
193 |
:param pkg: name of package |
194 |
:param dep_type: type of dependencies to recurse. Can be ["DEPEND"] or |
195 |
@@ -36,14 +120,15 @@ class portage_api: |
196 |
|
197 |
ret=set() |
198 |
|
199 |
+ # get porttree dependencies on the first package |
200 |
+ |
201 |
pkg = self.portdb.xmatch("bestmatch-visible", pkg) |
202 |
if not pkg: |
203 |
return ret |
204 |
|
205 |
- #print pkg |
206 |
- |
207 |
known_packages=set() |
208 |
- unknown_packages={pkg} |
209 |
+ unknown_packages=self.get_dep(pkg,dep_type) |
210 |
+ ret=ret.union(unknown_packages) |
211 |
|
212 |
while unknown_packages: |
213 |
p=unknown_packages.pop() |
214 |
@@ -52,16 +137,13 @@ class portage_api: |
215 |
continue |
216 |
known_packages.add(p) |
217 |
|
218 |
- #print self.metadata_keys, p,self.portdb.aux_get(p, self.metadata_keys) |
219 |
metadata = dict(zip(self.metadata_keys, self.vardb.aux_get(p, self.metadata_keys))) |
220 |
- #print "proceeding2 "+p |
221 |
|
222 |
dep_str = " ".join(metadata[k] for k in dep_type) |
223 |
|
224 |
success, atoms = portage.dep_check(dep_str, None, self.settings, myuse=self.use.split(), |
225 |
trees=portage.db, myroot=self.settings["ROOT"]) |
226 |
|
227 |
- #print atoms |
228 |
if not success: |
229 |
continue |
230 |
|
231 |
|
232 |
diff --git a/src/autodep/package_utils/portage_utils.py b/src/autodep/package_utils/portage_utils.py |
233 |
index 5401d99..d33ada6 100644 |
234 |
--- a/src/autodep/package_utils/portage_utils.py |
235 |
+++ b/src/autodep/package_utils/portage_utils.py |
236 |
@@ -69,5 +69,26 @@ def getfilesbypackage(packagename): |
237 |
|
238 |
return ret |
239 |
|
240 |
+def get_all_packages_files(): |
241 |
+ """ |
242 |
+ Memory-hungry operation |
243 |
+ |
244 |
+ :returns: **set** of all files that belongs to package |
245 |
+ """ |
246 |
+ ret=[] |
247 |
+ try: |
248 |
+ proc=subprocess.Popen(['qlist']+['--all',"--obj"], |
249 |
+ stdout=subprocess.PIPE,stderr=subprocess.PIPE, |
250 |
+ bufsize=4096) |
251 |
+ |
252 |
+ out,err=proc.communicate() |
253 |
+ if err!=None and len(err)!=0 : |
254 |
+ print "Noncritical error while launch qlist: %s" % err; |
255 |
+ |
256 |
+ ret=out.split("\n") |
257 |
+ except OSError,e: |
258 |
+ print "Error while launching qfile: %s" % e |
259 |
+ |
260 |
+ return set(ret) |
261 |
|
262 |
|
263 |
\ No newline at end of file |