1 |
Author: grobian |
2 |
Date: 2008-07-03 17:05:34 +0000 (Thu, 03 Jul 2008) |
3 |
New Revision: 10914 |
4 |
|
5 |
Modified: |
6 |
main/branches/prefix/bin/repoman |
7 |
main/branches/prefix/pym/_emerge/__init__.py |
8 |
main/branches/prefix/pym/portage/__init__.py |
9 |
Log: |
10 |
Merged from trunk 10904:10913 |
11 |
|
12 |
| 10905 | Split out a new _add_prefetchers() method from | |
13 |
| zmedico | Scheduler._merge(). | |
14 |
|
15 |
| 10906 | Remove the Scheduler._post_merge() method, and create a new | |
16 |
| zmedico | _show_failed_fetches() method. | |
17 |
|
18 |
| 10907 | Remove unused BinpkgMerge class. | |
19 |
| zmedico | | |
20 |
|
21 |
| 10908 | Split out a _restart_if_necessary() method from | |
22 |
| zmedico | Scheduler._merge(). | |
23 |
|
24 |
| 10909 | Add a portage._disable_legacy_globals() function. This | |
25 |
| zmedico | deletes the ObjectProxy instances that are used for lazy | |
26 |
| | initialization of legacy global variables. The purpose of | |
27 |
| | deleting them is to prevent new code from referencing these | |
28 |
| | deprecated variables. This allows the removal of the | |
29 |
| | PORTAGE_LEGACY_GLOBALS variable which used to serve the same | |
30 |
| | purpose. | |
31 |
|
32 |
| 10910 | Clean up Scheduler.merge() and split out a | |
33 |
| zmedico | _save_resume_list() method. | |
34 |
|
35 |
| 10911 | Split logging and world atom code out of | |
36 |
| zmedico | Scheduler._execute() task, and trigger it inside | |
37 |
| | EbuildPhase.execute(). | |
38 |
|
39 |
| 10912 | Remove old unused vars inside _execute_task() and fix code | |
40 |
| zmedico | not to use the old vars. | |
41 |
|
42 |
| 10913 | Split out a _create_prefetcher() method from | |
43 |
| zmedico | _add_prefetchers(). | |
44 |
|
45 |
|
46 |
Modified: main/branches/prefix/bin/repoman |
47 |
=================================================================== |
48 |
--- main/branches/prefix/bin/repoman 2008-07-03 12:04:45 UTC (rev 10913) |
49 |
+++ main/branches/prefix/bin/repoman 2008-07-03 17:05:34 UTC (rev 10914) |
50 |
@@ -38,7 +38,6 @@ |
51 |
if not hasattr(__builtins__, "set"): |
52 |
from sets import Set as set |
53 |
|
54 |
-os.environ["PORTAGE_LEGACY_GLOBALS"] = "false" |
55 |
|
56 |
# for an explanation on this logic, see pym/_emerge/__init__.py |
57 |
import os |
58 |
@@ -49,7 +48,7 @@ |
59 |
sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "pym")) |
60 |
import portage |
61 |
|
62 |
-del os.environ["PORTAGE_LEGACY_GLOBALS"] |
63 |
+portage._disable_legacy_globals() |
64 |
|
65 |
from repoman.checks import run_checks |
66 |
from repoman import utilities |
67 |
|
68 |
Modified: main/branches/prefix/pym/_emerge/__init__.py |
69 |
=================================================================== |
70 |
--- main/branches/prefix/pym/_emerge/__init__.py 2008-07-03 12:04:45 UTC (rev 10913) |
71 |
+++ main/branches/prefix/pym/_emerge/__init__.py 2008-07-03 17:05:34 UTC (rev 10914) |
72 |
@@ -31,7 +31,6 @@ |
73 |
import os, stat |
74 |
import platform |
75 |
|
76 |
-os.environ["PORTAGE_LEGACY_GLOBALS"] = "false" |
77 |
|
78 |
# Portage module path logic (Prefix way) |
79 |
# In principle we don't want to be dependant on the environment |
80 |
@@ -52,7 +51,7 @@ |
81 |
sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "pym")) |
82 |
import portage |
83 |
|
84 |
-del os.environ["PORTAGE_LEGACY_GLOBALS"] |
85 |
+portage._disable_legacy_globals() |
86 |
from portage import digraph, portdbapi |
87 |
from portage.const import NEWS_LIB_PATH, CACHE_PATH, PRIVATE_PATH, USER_CONFIG_PATH, GLOBAL_CONFIG_PATH |
88 |
|
89 |
@@ -1730,7 +1729,7 @@ |
90 |
__slots__ = ("args_set", "find_blockers", |
91 |
"ldpath_mtimes", "logger", "opts", |
92 |
"pkg", "pkg_count", "scheduler", |
93 |
- "settings") |
94 |
+ "settings", "world_atom") |
95 |
|
96 |
def execute(self): |
97 |
|
98 |
@@ -1743,12 +1742,14 @@ |
99 |
pkg_count = self.pkg_count |
100 |
scheduler = self.scheduler |
101 |
settings = self.settings |
102 |
+ world_atom = self.world_atom |
103 |
root_config = pkg.root_config |
104 |
root = root_config.root |
105 |
system_set = root_config.sets["system"] |
106 |
world_set = root_config.sets["world"] |
107 |
vartree = root_config.trees["vartree"] |
108 |
- portdb = root_config.trees["porttree"].dbapi |
109 |
+ tree = "porttree" |
110 |
+ portdb = root_config.trees[tree].dbapi |
111 |
debug = settings.get("PORTAGE_DEBUG") == "1" |
112 |
features = self.settings.features |
113 |
settings["EMERGE_FROM"] = pkg.type_name |
114 |
@@ -1812,17 +1813,17 @@ |
115 |
(pkg_count.curval, pkg_count.maxval, pkg.cpv) |
116 |
logger.log(msg, short_msg=short_msg) |
117 |
|
118 |
- merge = EbuildMerge( |
119 |
- find_blockers=find_blockers, |
120 |
- ldpath_mtimes=ldpath_mtimes, |
121 |
- pkg=pkg, settings=settings) |
122 |
+ merge = EbuildMerge(find_blockers=find_blockers, |
123 |
+ ldpath_mtimes=ldpath_mtimes, logger=logger, pkg=pkg, |
124 |
+ pkg_count=pkg_count, pkg_path=ebuild_path, |
125 |
+ settings=settings, tree=tree, world_atom=world_atom) |
126 |
retval = merge.execute() |
127 |
if retval != os.EX_OK: |
128 |
return retval |
129 |
elif "noclean" not in settings.features: |
130 |
portage.doebuild(ebuild_path, "clean", root, |
131 |
settings, debug=debug, mydbapi=portdb, |
132 |
- tree="porttree") |
133 |
+ tree=tree) |
134 |
else: |
135 |
msg = " === (%s of %s) Compiling/Merging (%s::%s)" % \ |
136 |
(pkg_count.curval, pkg_count.maxval, pkg.cpv, ebuild_path) |
137 |
@@ -1837,10 +1838,10 @@ |
138 |
if retval != os.EX_OK: |
139 |
return retval |
140 |
|
141 |
- merge = EbuildMerge( |
142 |
- find_blockers=self.find_blockers, |
143 |
- ldpath_mtimes=ldpath_mtimes, |
144 |
- pkg=pkg, settings=settings) |
145 |
+ merge = EbuildMerge(find_blockers=self.find_blockers, |
146 |
+ ldpath_mtimes=ldpath_mtimes, logger=logger, pkg=pkg, |
147 |
+ pkg_count=pkg_count, pkg_path=ebuild_path, |
148 |
+ settings=settings, tree=tree, world_atom=world_atom) |
149 |
retval = merge.execute() |
150 |
|
151 |
if retval != os.EX_OK: |
152 |
@@ -1859,7 +1860,8 @@ |
153 |
|
154 |
def execute(self): |
155 |
root_config = self.pkg.root_config |
156 |
- portdb = root_config.trees["porttree"].dbapi |
157 |
+ tree = "porttree" |
158 |
+ portdb = root_config.trees[tree].dbapi |
159 |
ebuild_path = portdb.findname(self.pkg.cpv) |
160 |
settings = self.settings |
161 |
debug = settings.get("PORTAGE_DEBUG") == "1" |
162 |
@@ -1883,7 +1885,7 @@ |
163 |
for mydo in self._phases: |
164 |
ebuild_phase = EbuildPhase(fd_pipes=fd_pipes, |
165 |
pkg=self.pkg, phase=mydo, register=self.register, |
166 |
- settings=settings, unregister=self.unregister) |
167 |
+ settings=settings, tree=tree, unregister=self.unregister) |
168 |
|
169 |
ebuild_phase.start() |
170 |
retval = None |
171 |
@@ -1899,7 +1901,7 @@ |
172 |
class EbuildPhase(SubProcess): |
173 |
|
174 |
__slots__ = ("fd_pipes", "phase", "pkg", |
175 |
- "register", "settings", "unregister", |
176 |
+ "register", "settings", "tree", "unregister", |
177 |
"files", "registered") |
178 |
|
179 |
_file_names = ("log", "stdout", "ebuild") |
180 |
@@ -1908,9 +1910,10 @@ |
181 |
|
182 |
def start(self): |
183 |
root_config = self.pkg.root_config |
184 |
- portdb = root_config.trees["porttree"].dbapi |
185 |
- ebuild_path = portdb.findname(self.pkg.cpv) |
186 |
+ tree = self.tree |
187 |
+ mydbapi = root_config.trees[tree].dbapi |
188 |
settings = self.settings |
189 |
+ ebuild_path = settings["EBUILD"] |
190 |
debug = settings.get("PORTAGE_DEBUG") == "1" |
191 |
logfile = settings.get("PORTAGE_LOG_FILE") |
192 |
master_fd = None |
193 |
@@ -1971,7 +1974,7 @@ |
194 |
|
195 |
retval = portage.doebuild(ebuild_path, self.phase, |
196 |
root_config.root, settings, debug, |
197 |
- mydbapi=portdb, tree="porttree", |
198 |
+ mydbapi=mydbapi, tree=tree, |
199 |
fd_pipes=fd_pipes, returnpid=True) |
200 |
|
201 |
self.pid = retval[0] |
202 |
@@ -2071,17 +2074,12 @@ |
203 |
|
204 |
return retval |
205 |
|
206 |
-class EbuildMerge(Task): |
207 |
+class EbuildMerge(SlotObject): |
208 |
|
209 |
- __slots__ = ("find_blockers", "ldpath_mtimes", |
210 |
- "pkg", "pretend", "settings") |
211 |
+ __slots__ = ("find_blockers", "logger", "ldpath_mtimes", |
212 |
+ "pkg", "pkg_count", "pkg_path", "pretend", |
213 |
+ "settings", "tree", "world_atom") |
214 |
|
215 |
- def _get_hash_key(self): |
216 |
- hash_key = getattr(self, "_hash_key", None) |
217 |
- if hash_key is None: |
218 |
- self._hash_key = ("EbuildMerge", self.pkg._get_hash_key()) |
219 |
- return self._hash_key |
220 |
- |
221 |
def execute(self): |
222 |
root_config = self.pkg.root_config |
223 |
settings = self.settings |
224 |
@@ -2090,12 +2088,32 @@ |
225 |
os.path.join(settings["PORTAGE_BUILDDIR"], |
226 |
"build-info"), root_config.root, settings, |
227 |
myebuild=settings["EBUILD"], |
228 |
- mytree="porttree", mydbapi=root_config.trees["porttree"].dbapi, |
229 |
+ mytree=self.tree, mydbapi=root_config.trees[self.tree].dbapi, |
230 |
vartree=root_config.trees["vartree"], |
231 |
prev_mtimes=self.ldpath_mtimes, |
232 |
blockers=self.find_blockers) |
233 |
+ |
234 |
+ if retval == os.EX_OK: |
235 |
+ self.world_atom(self.pkg) |
236 |
+ self._log_success() |
237 |
+ |
238 |
return retval |
239 |
|
240 |
+ def _log_success(self): |
241 |
+ pkg = self.pkg |
242 |
+ pkg_count = self.pkg_count |
243 |
+ pkg_path = self.pkg_path |
244 |
+ logger = self.logger |
245 |
+ if "noclean" not in self.settings.features: |
246 |
+ short_msg = "emerge: (%s of %s) %s Clean Post" % \ |
247 |
+ (pkg_count.curval, pkg_count.maxval, pkg.cpv) |
248 |
+ logger.log((" === (%s of %s) " + \ |
249 |
+ "Post-Build Cleaning (%s::%s)") % \ |
250 |
+ (pkg_count.curval, pkg_count.maxval, pkg.cpv, pkg_path), |
251 |
+ short_msg=short_msg) |
252 |
+ logger.log(" ::: completed emerge (%s of %s) %s to %s" % \ |
253 |
+ (pkg_count.curval, pkg_count.maxval, pkg.cpv, pkg.root)) |
254 |
+ |
255 |
class PackageUninstall(Task): |
256 |
|
257 |
__slots__ = ("ldpath_mtimes", "opts", "pkg", "settings") |
258 |
@@ -2120,7 +2138,7 @@ |
259 |
__slots__ = ("find_blockers", |
260 |
"ldpath_mtimes", "logger", "opts", |
261 |
"pkg", "pkg_count", "prefetcher", "scheduler", |
262 |
- "settings") |
263 |
+ "settings", "world_atom") |
264 |
|
265 |
def execute(self): |
266 |
|
267 |
@@ -2132,6 +2150,8 @@ |
268 |
pkg_count = self.pkg_count |
269 |
scheduler = self.scheduler |
270 |
settings = self.settings |
271 |
+ world_atom = self.world_atom |
272 |
+ tree = "bintree" |
273 |
settings.setcpv(pkg) |
274 |
debug = settings.get("PORTAGE_DEBUG") == "1" |
275 |
|
276 |
@@ -2212,7 +2232,6 @@ |
277 |
root_config = self.pkg.root_config |
278 |
ebuild_path = os.path.join(infloc, pkg.pf + ".ebuild") |
279 |
cleanup = 1 |
280 |
- tree = "bintree" |
281 |
mydbapi = root_config.trees[tree].dbapi |
282 |
|
283 |
retval = portage.doebuild(ebuild_path, "clean", |
284 |
@@ -2276,7 +2295,7 @@ |
285 |
phase = "setup" |
286 |
ebuild_phase = EbuildPhase(fd_pipes=fd_pipes, |
287 |
pkg=pkg, phase=phase, register=scheduler.register, |
288 |
- settings=settings, unregister=scheduler.unregister) |
289 |
+ settings=settings, tree=tree, unregister=scheduler.unregister) |
290 |
|
291 |
ebuild_phase.start() |
292 |
retval = None |
293 |
@@ -2302,10 +2321,10 @@ |
294 |
noiselevel=-1) |
295 |
return retval |
296 |
|
297 |
- merge = EbuildMerge( |
298 |
- find_blockers=find_blockers, |
299 |
- ldpath_mtimes=ldpath_mtimes, |
300 |
- pkg=pkg, settings=settings) |
301 |
+ merge = EbuildMerge(find_blockers=find_blockers, |
302 |
+ ldpath_mtimes=ldpath_mtimes, logger=logger, pkg=pkg, |
303 |
+ pkg_count=pkg_count, pkg_path=pkg_path, |
304 |
+ settings=settings, tree=tree, world_atom=world_atom) |
305 |
|
306 |
retval = merge.execute() |
307 |
if retval != os.EX_OK: |
308 |
@@ -2479,33 +2498,6 @@ |
309 |
self.env = self.pkg.root_config.settings.environ() |
310 |
SpawnProcess.start(self) |
311 |
|
312 |
-class BinpkgMerge(Task): |
313 |
- |
314 |
- __slots__ = ("find_blockers", "ldpath_mtimes", |
315 |
- "pkg", "pretend", "pkg_path", "settings") |
316 |
- |
317 |
- def _get_hash_key(self): |
318 |
- hash_key = getattr(self, "_hash_key", None) |
319 |
- if hash_key is None: |
320 |
- self._hash_key = ("BinpkgMerge", self.pkg._get_hash_key()) |
321 |
- return self._hash_key |
322 |
- |
323 |
- def execute(self): |
324 |
- |
325 |
- settings = self.settings |
326 |
- settings["EMERGE_FROM"] = self.pkg.type_name |
327 |
- settings.backup_changes("EMERGE_FROM") |
328 |
- settings.reset() |
329 |
- |
330 |
- root_config = self.pkg.root_config |
331 |
- retval = portage.pkgmerge(self.pkg_path, root_config.root, |
332 |
- self.settings, |
333 |
- mydbapi=root_config.trees["bintree"].dbapi, |
334 |
- vartree=root_config.trees["vartree"], |
335 |
- prev_mtimes=self.ldpath_mtimes, |
336 |
- blockers=self.find_blockers) |
337 |
- return retval |
338 |
- |
339 |
class DependencyArg(object): |
340 |
def __init__(self, arg=None, root_config=None): |
341 |
self.arg = arg |
342 |
@@ -7022,6 +7014,9 @@ |
343 |
"--fetchonly", "--fetch-all-uri", |
344 |
"--nodeps", "--pretend"]) |
345 |
|
346 |
+ _bad_resume_opts = set(["--ask", "--changelog", |
347 |
+ "--resume", "--skipfirst"]) |
348 |
+ |
349 |
_fetch_log = EPREFIX + "/var/log/emerge-fetch.log" |
350 |
|
351 |
class _iface_class(SlotObject): |
352 |
@@ -7061,6 +7056,9 @@ |
353 |
for k in self._binpkg_opts.__slots__: |
354 |
setattr(self._binpkg_opts, k, "--" + k.replace("_", "-") in myopts) |
355 |
|
356 |
+ # The root where the currently running |
357 |
+ # portage instance is installed. |
358 |
+ self._running_root = trees["/"]["root_config"] |
359 |
self.edebug = 0 |
360 |
if settings.get("PORTAGE_DEBUG", "") == "1": |
361 |
self.edebug = 1 |
362 |
@@ -7085,7 +7083,12 @@ |
363 |
self._task_queue = deque() |
364 |
self._running_tasks = set() |
365 |
self._max_jobs = 1 |
366 |
+ self._prefetchers = weakref.WeakValueDictionary() |
367 |
+ self._failed_fetches = [] |
368 |
self._parallel_fetch = False |
369 |
+ self._pkg_count = self._pkg_count_class( |
370 |
+ curval=0, maxval=len(mergelist)) |
371 |
+ |
372 |
features = self.settings.features |
373 |
if "parallel-fetch" in features and \ |
374 |
not ("--pretend" in self.myopts or \ |
375 |
@@ -7194,6 +7197,116 @@ |
376 |
|
377 |
return os.EX_OK |
378 |
|
379 |
+ def _add_prefetchers(self): |
380 |
+ |
381 |
+ if not self._parallel_fetch: |
382 |
+ return |
383 |
+ |
384 |
+ if self._parallel_fetch: |
385 |
+ portage.writemsg(">>> starting parallel fetch\n") |
386 |
+ |
387 |
+ prefetchers = self._prefetchers |
388 |
+ getbinpkg = "--getbinpkg" in self.myopts |
389 |
+ |
390 |
+ for pkg in self._mergelist: |
391 |
+ prefetcher = self._create_prefetcher(pkg) |
392 |
+ if prefetcher is not None: |
393 |
+ self._add_task(prefetcher) |
394 |
+ prefetchers[pkg] = prefetcher |
395 |
+ |
396 |
+ def _create_prefetcher(self, pkg): |
397 |
+ """ |
398 |
+ @return: a prefetcher, or None if not applicable |
399 |
+ """ |
400 |
+ prefetcher = None |
401 |
+ |
402 |
+ if not isinstance(pkg, Package): |
403 |
+ pass |
404 |
+ |
405 |
+ elif pkg.type_name == "ebuild": |
406 |
+ |
407 |
+ prefetcher = EbuildFetcherAsync(logfile=self._fetch_log, pkg=pkg, |
408 |
+ register=self._register, unregister=self._unregister) |
409 |
+ |
410 |
+ elif pkg.type_name == "binary" and \ |
411 |
+ "--getbinpkg" in self.myopts and \ |
412 |
+ pkg.root_config.trees["bintree"].isremote(pkg.cpv): |
413 |
+ |
414 |
+ prefetcher = BinpkgFetcherAsync(logfile=self._fetch_log, |
415 |
+ pkg=pkg, register=self._register, unregister=self._unregister) |
416 |
+ |
417 |
+ return prefetcher |
418 |
+ |
419 |
+ def _show_failed_fetches(self): |
420 |
+ failed_fetches = self._failed_fetches |
421 |
+ if not failed_fetches or not \ |
422 |
+ ("--fetchonly" in self.myopts or \ |
423 |
+ "--fetch-all-uri" in self.myopts): |
424 |
+ return |
425 |
+ |
426 |
+ sys.stderr.write("\n\n!!! Some fetch errors were " + \ |
427 |
+ "encountered. Please see above for details.\n\n") |
428 |
+ |
429 |
+ for cpv in failed_fetches: |
430 |
+ sys.stderr.write(" ") |
431 |
+ sys.stderr.write(cpv) |
432 |
+ sys.stderr.write("\n") |
433 |
+ |
434 |
+ sys.stderr.write("\n") |
435 |
+ |
436 |
+ def _restart_if_necessary(self, pkg): |
437 |
+ """ |
438 |
+ Use execv() to restart emerge. This happens |
439 |
+ if portage upgrades itself and there are |
440 |
+ remaining packages in the list. |
441 |
+ """ |
442 |
+ |
443 |
+ if "--pretend" in self.myopts or \ |
444 |
+ "--fetchonly" in self.myopts or \ |
445 |
+ "--fetch-all-uri" in self.myopts: |
446 |
+ return |
447 |
+ |
448 |
+ # Figure out if we need a restart. |
449 |
+ if pkg.root != self._running_root.root or \ |
450 |
+ EPREFIX != BPREFIX or \ |
451 |
+ not portage.match_from_list( |
452 |
+ portage.const.PORTAGE_PACKAGE_ATOM, [pkg]): |
453 |
+ return |
454 |
+ |
455 |
+ if self._pkg_count.curval >= self._pkg_count.maxval: |
456 |
+ return |
457 |
+ |
458 |
+ logger = self._logger |
459 |
+ pkg_count = self._pkg_count |
460 |
+ mtimedb = self._mtimedb |
461 |
+ bad_resume_opts = self._bad_resume_opts |
462 |
+ |
463 |
+ logger.log(" ::: completed emerge (%s of %s) %s to %s" % \ |
464 |
+ (pkg_count.curval, pkg_count.maxval, pkg.cpv, pkg.root)) |
465 |
+ |
466 |
+ logger.log(" *** RESTARTING " + \ |
467 |
+ "emerge via exec() after change of " + \ |
468 |
+ "portage version.") |
469 |
+ |
470 |
+ del mtimedb["resume"]["mergelist"][0] |
471 |
+ mtimedb.commit() |
472 |
+ portage.run_exitfuncs() |
473 |
+ mynewargv = [sys.argv[0], "--resume"] |
474 |
+ resume_opts = self.myopts.copy() |
475 |
+ # For automatic resume, we need to prevent |
476 |
+ # any of bad_resume_opts from leaking in |
477 |
+ # via EMERGE_DEFAULT_OPTS. |
478 |
+ resume_opts["--ignore-default-opts"] = True |
479 |
+ for myopt, myarg in resume_opts.iteritems(): |
480 |
+ if myopt not in bad_resume_opts: |
481 |
+ if myarg is True: |
482 |
+ mynewargv.append(myopt) |
483 |
+ else: |
484 |
+ mynewargv.append(myopt +"="+ myarg) |
485 |
+ # priority only needs to be adjusted on the first run |
486 |
+ os.environ["PORTAGE_NICENESS"] = "0" |
487 |
+ os.execv(mynewargv[0], mynewargv) |
488 |
+ |
489 |
def merge(self): |
490 |
|
491 |
if "--resume" in self.myopts: |
492 |
@@ -7202,34 +7315,19 @@ |
493 |
colorize("GOOD", "*** Resuming merge...\n"), noiselevel=-1) |
494 |
self._logger.log(" *** Resuming merge...") |
495 |
|
496 |
+ self._save_resume_list() |
497 |
rval = self._check_manifests() |
498 |
if rval != os.EX_OK: |
499 |
return rval |
500 |
|
501 |
keep_going = "--keep-going" in self.myopts |
502 |
- running_tasks = self._running_tasks |
503 |
mtimedb = self._mtimedb |
504 |
|
505 |
while True: |
506 |
+ self._merge() |
507 |
+ self._show_failed_fetches() |
508 |
+ del self._failed_fetches[:] |
509 |
|
510 |
- # Do this before verifying the ebuild Manifests since it might |
511 |
- # be possible for the user to use --resume --skipfirst get past |
512 |
- # a non-essential package with a broken digest. |
513 |
- mtimedb["resume"]["mergelist"] = [list(x) \ |
514 |
- for x in self._mergelist \ |
515 |
- if isinstance(x, Package) and x.operation == "merge"] |
516 |
- |
517 |
- mtimedb.commit() |
518 |
- |
519 |
- try: |
520 |
- rval = self._merge() |
521 |
- finally: |
522 |
- # clean up child process if necessary |
523 |
- self._task_queue.clear() |
524 |
- while running_tasks: |
525 |
- task = running_tasks.pop() |
526 |
- task.cancel() |
527 |
- |
528 |
if rval == os.EX_OK or not keep_going: |
529 |
break |
530 |
if "resume" not in mtimedb: |
531 |
@@ -7274,9 +7372,46 @@ |
532 |
del _eerror, msg |
533 |
del dropped_tasks |
534 |
self._mergelist = mylist |
535 |
+ self._save_resume_list() |
536 |
+ self._pkg_count.curval = 0 |
537 |
+ self._pkg_count.maxval = len(mylist) |
538 |
|
539 |
+ self._logger.log(" *** Finished. Cleaning up...") |
540 |
+ |
541 |
return rval |
542 |
|
543 |
+ def _merge(self): |
544 |
+ |
545 |
+ self._add_prefetchers() |
546 |
+ |
547 |
+ try: |
548 |
+ for task in self._mergelist: |
549 |
+ try: |
550 |
+ self._execute_task(task) |
551 |
+ except self._pkg_failure, e: |
552 |
+ return e.status |
553 |
+ finally: |
554 |
+ # clean up child process if necessary |
555 |
+ self._task_queue.clear() |
556 |
+ running_tasks = self._running_tasks |
557 |
+ while running_tasks: |
558 |
+ task = running_tasks.pop() |
559 |
+ task.cancel() |
560 |
+ return os.EX_OK |
561 |
+ |
562 |
+ def _save_resume_list(self): |
563 |
+ """ |
564 |
+ Do this before verifying the ebuild Manifests since it might |
565 |
+ be possible for the user to use --resume --skipfirst get past |
566 |
+ a non-essential package with a broken digest. |
567 |
+ """ |
568 |
+ mtimedb = self._mtimedb |
569 |
+ mtimedb["resume"]["mergelist"] = [list(x) \ |
570 |
+ for x in self._mergelist \ |
571 |
+ if isinstance(x, Package) and x.operation == "merge"] |
572 |
+ |
573 |
+ mtimedb.commit() |
574 |
+ |
575 |
def _calc_resume_list(self): |
576 |
""" |
577 |
Use the current resume list to calculate a new one, |
578 |
@@ -7354,122 +7489,53 @@ |
579 |
|
580 |
return state_changed |
581 |
|
582 |
- def _merge(self): |
583 |
- mylist = self._mergelist |
584 |
- favorites = self._favorites |
585 |
- mtimedb = self._mtimedb |
586 |
- buildpkgonly = "--buildpkgonly" in self.myopts |
587 |
- failed_fetches = [] |
588 |
- fetchonly = "--fetchonly" in self.myopts or \ |
589 |
- "--fetch-all-uri" in self.myopts |
590 |
- oneshot = "--oneshot" in self.myopts or \ |
591 |
- "--onlydeps" in self.myopts |
592 |
- pretend = "--pretend" in self.myopts |
593 |
- ldpath_mtimes = mtimedb["ldpath"] |
594 |
- logger = self._logger |
595 |
+ def _world_atom(self, pkg): |
596 |
+ """ |
597 |
+ Add the package to the world file, but only if |
598 |
+ it's supposed to be added. Otherwise, do nothing. |
599 |
+ """ |
600 |
+ if pkg.root != self.target_root: |
601 |
+ return |
602 |
|
603 |
- prefetchers = weakref.WeakValueDictionary() |
604 |
- getbinpkg = "--getbinpkg" in self.myopts |
605 |
+ args_set = self._args_set |
606 |
+ if not args_set.findAtomForPackage(pkg): |
607 |
+ return |
608 |
|
609 |
- if self._parallel_fetch: |
610 |
- portage.writemsg(">>> starting parallel fetch\n") |
611 |
- for pkg in mylist: |
612 |
- if not isinstance(pkg, Package): |
613 |
- continue |
614 |
- if pkg.type_name == "ebuild": |
615 |
- self._add_task(EbuildFetcherAsync( |
616 |
- logfile=self._fetch_log, |
617 |
- pkg=pkg, register=self._register, |
618 |
- unregister=self._unregister)) |
619 |
- elif pkg.type_name == "binary" and getbinpkg and \ |
620 |
- pkg.root_config.trees["bintree"].isremote(pkg.cpv): |
621 |
- prefetcher = BinpkgFetcherAsync( |
622 |
- logfile=self._fetch_log, |
623 |
- pkg=pkg, register=self._register, |
624 |
- unregister=self._unregister) |
625 |
- prefetchers[pkg] = prefetcher |
626 |
- self._add_task(prefetcher) |
627 |
- del prefetcher |
628 |
+ logger = self._logger |
629 |
+ pkg_count = self._pkg_count |
630 |
+ root_config = pkg.root_config |
631 |
+ world_set = root_config.sets["world"] |
632 |
+ world_set.lock() |
633 |
+ try: |
634 |
+ world_set.load() # maybe it's changed on disk |
635 |
+ atom = create_world_atom(pkg, args_set, root_config) |
636 |
+ if atom: |
637 |
+ portage.writemsg_stdout(('>>> Recording %s in "world" ' + \ |
638 |
+ 'favorites file...\n') % atom) |
639 |
+ logger.log(" === (%s of %s) Updating world file (%s)" % \ |
640 |
+ (pkg_count.curval, pkg_count.maxval, pkg.cpv)) |
641 |
+ world_set.add(atom) |
642 |
+ finally: |
643 |
+ world_set.unlock() |
644 |
|
645 |
- root_config = self.trees[self.target_root]["root_config"] |
646 |
- mymergelist = mylist |
647 |
- myfeat = self.settings.features[:] |
648 |
- bad_resume_opts = set(["--ask", "--changelog", "--skipfirst", |
649 |
- "--resume"]) |
650 |
- metadata_keys = [k for k in portage.auxdbkeys \ |
651 |
- if not k.startswith("UNUSED_")] + ["USE"] |
652 |
+ def _execute_task(self, pkg): |
653 |
|
654 |
- task_list = mymergelist |
655 |
- # Filter mymergelist so that all the len(mymergelist) calls |
656 |
- # below (for display) do not count Uninstall instances. |
657 |
- mymergelist = [x for x in mymergelist if x[-1] == "merge"] |
658 |
- pkg_count = self._pkg_count_class( |
659 |
- curval=0, maxval=len(mymergelist)) |
660 |
- for x in task_list: |
661 |
- if x[0] == "blocks": |
662 |
- continue |
663 |
- pkg_type, myroot, pkg_key, operation = x |
664 |
- built = pkg_type != "ebuild" |
665 |
- installed = pkg_type == "installed" |
666 |
- portdb = self.trees[myroot]["porttree"].dbapi |
667 |
- bindb = self.trees[myroot]["bintree"].dbapi |
668 |
- vartree = self.trees[myroot]["vartree"] |
669 |
- vardb = vartree.dbapi |
670 |
- root_config = self.trees[myroot]["root_config"] |
671 |
- if pkg_type == "blocks": |
672 |
- pass |
673 |
- elif pkg_type == "ebuild": |
674 |
- mydbapi = portdb |
675 |
- else: |
676 |
- if pkg_type == "binary": |
677 |
- mydbapi = bindb |
678 |
- elif pkg_type == "installed": |
679 |
- mydbapi = vardb |
680 |
- else: |
681 |
- raise AssertionError("Package type: '%s'" % pkg_type) |
682 |
- if not x.installed: |
683 |
- pkg_count.curval += 1 |
684 |
- try: |
685 |
- self._execute_task(bad_resume_opts, |
686 |
- failed_fetches, |
687 |
- mydbapi, pkg_count, |
688 |
- myfeat, mymergelist, x, |
689 |
- prefetchers) |
690 |
- except self._pkg_failure, e: |
691 |
- return e.status |
692 |
- return self._post_merge(mtimedb, |
693 |
- self._logger.xterm_titles, failed_fetches) |
694 |
- |
695 |
- def _execute_task(self, bad_resume_opts, |
696 |
- failed_fetches, mydbapi, pkg_count, myfeat, |
697 |
- mymergelist, pkg, prefetchers): |
698 |
- favorites = self._favorites |
699 |
- mtimedb = self._mtimedb |
700 |
- mergecount = pkg_count.curval |
701 |
- pkgsettings = self.pkgsettings[pkg.root] |
702 |
buildpkgonly = "--buildpkgonly" in self.myopts |
703 |
fetch_all = "--fetch-all-uri" in self.myopts |
704 |
fetchonly = fetch_all or "--fetchonly" in self.myopts |
705 |
- |
706 |
- oneshot = "--oneshot" in self.myopts or \ |
707 |
- "--onlydeps" in self.myopts |
708 |
pretend = "--pretend" in self.myopts |
709 |
+ |
710 |
+ pkgsettings = self.pkgsettings[pkg.root] |
711 |
+ mtimedb = self._mtimedb |
712 |
ldpath_mtimes = mtimedb["ldpath"] |
713 |
- xterm_titles = "notitles" not in self.settings.features |
714 |
+ failed_fetches = self._failed_fetches |
715 |
+ pkg_count = self._pkg_count |
716 |
+ prefetchers = self._prefetchers |
717 |
|
718 |
- x = pkg |
719 |
- y = None |
720 |
- root_config = pkg.root_config |
721 |
- system_set = root_config.sets["system"] |
722 |
- args_set = InternalPackageSet(favorites) |
723 |
- world_set = root_config.sets["world"] |
724 |
- vartree = self.trees[pkg.root]["vartree"] |
725 |
- portdb = root_config.trees["porttree"].dbapi |
726 |
- bindb = root_config.trees["bintree"].dbapi |
727 |
- pkg_type, myroot, pkg_key, operation = x |
728 |
- pkgindex = 2 |
729 |
- metadata = pkg.metadata |
730 |
- if pkg.installed: |
731 |
+ if not pkg.installed: |
732 |
+ pkg_count.curval += 1 |
733 |
+ mergecount = pkg_count.curval |
734 |
+ else: |
735 |
if not (buildpkgonly or fetchonly or pretend): |
736 |
uninstall = PackageUninstall(ldpath_mtimes=ldpath_mtimes, |
737 |
opts=self.myopts, pkg=pkg, settings=pkgsettings) |
738 |
@@ -7478,27 +7544,24 @@ |
739 |
raise self._pkg_failure(retval) |
740 |
return |
741 |
|
742 |
- if x[0]=="blocks": |
743 |
- pkgindex=3 |
744 |
+ if not pretend: |
745 |
+ portage.writemsg_stdout( |
746 |
+ "\n>>> Emerging (%s of %s) %s to %s\n" % \ |
747 |
+ (colorize("MERGE_LIST_PROGRESS", str(pkg_count.curval)), |
748 |
+ colorize("MERGE_LIST_PROGRESS", str(pkg_count.maxval)), |
749 |
+ colorize("GOOD", pkg.cpv), pkg.root), noiselevel=-1) |
750 |
+ self._logger.log(" >>> emerge (%s of %s) %s to %s" % \ |
751 |
+ (pkg_count.curval, pkg_count.maxval, pkg.cpv, pkg.root)) |
752 |
|
753 |
- if "--pretend" not in self.myopts: |
754 |
- print "\n>>> Emerging (" + \ |
755 |
- colorize("MERGE_LIST_PROGRESS", str(mergecount)) + " of " + \ |
756 |
- colorize("MERGE_LIST_PROGRESS", str(len(mymergelist))) + ") " + \ |
757 |
- colorize("GOOD", x[pkgindex]) + " to " + x[1] |
758 |
- emergelog(xterm_titles, " >>> emerge ("+\ |
759 |
- str(mergecount)+" of "+str(len(mymergelist))+\ |
760 |
- ") "+x[pkgindex]+" to "+x[1]) |
761 |
- |
762 |
self._schedule() |
763 |
|
764 |
- if x.type_name == "ebuild": |
765 |
- y = portdb.findname(pkg.cpv) |
766 |
+ if pkg.type_name == "ebuild": |
767 |
build = EbuildBuild(args_set=self._args_set, |
768 |
find_blockers=self._find_blockers(pkg), |
769 |
ldpath_mtimes=ldpath_mtimes, logger=self._logger, |
770 |
opts=self._build_opts, pkg=pkg, pkg_count=pkg_count, |
771 |
- settings=pkgsettings, scheduler=self._sched_iface) |
772 |
+ settings=pkgsettings, scheduler=self._sched_iface, |
773 |
+ world_atom=self._world_atom) |
774 |
retval = build.execute() |
775 |
if retval != os.EX_OK: |
776 |
if fetchonly: |
777 |
@@ -7506,12 +7569,12 @@ |
778 |
else: |
779 |
raise self._pkg_failure(retval) |
780 |
|
781 |
- elif x.type_name == "binary": |
782 |
+ elif pkg.type_name == "binary": |
783 |
binpkg = Binpkg(find_blockers=self._find_blockers(pkg), |
784 |
ldpath_mtimes=ldpath_mtimes, logger=self._logger, |
785 |
opts=self._binpkg_opts, pkg=pkg, pkg_count=pkg_count, |
786 |
prefetcher=prefetchers.get(pkg), settings=pkgsettings, |
787 |
- scheduler=self._sched_iface) |
788 |
+ scheduler=self._sched_iface, world_atom=self._world_atom) |
789 |
retval = binpkg.execute() |
790 |
if retval != os.EX_OK: |
791 |
if fetchonly: |
792 |
@@ -7519,102 +7582,16 @@ |
793 |
else: |
794 |
raise self._pkg_failure(retval) |
795 |
|
796 |
- if not buildpkgonly: |
797 |
- if not (fetchonly or oneshot or pretend) and \ |
798 |
- args_set.findAtomForPackage(pkg): |
799 |
- world_set.lock() |
800 |
- world_set.load() # maybe it's changed on disk |
801 |
- myfavkey = create_world_atom(pkg, args_set, root_config) |
802 |
- if myfavkey: |
803 |
- print ">>> Recording",myfavkey,"in \"world\" favorites file..." |
804 |
- emergelog(xterm_titles, " === ("+\ |
805 |
- str(mergecount)+" of "+\ |
806 |
- str(len(mymergelist))+\ |
807 |
- ") Updating world file ("+x[pkgindex]+")") |
808 |
- world_set.add(myfavkey) |
809 |
- world_set.unlock() |
810 |
- |
811 |
- if "--pretend" not in self.myopts and \ |
812 |
- "--fetchonly" not in self.myopts and \ |
813 |
- "--fetch-all-uri" not in self.myopts: |
814 |
- |
815 |
- # Figure out if we need a restart. |
816 |
- if myroot == "/" and pkg.cp == "sys-apps/portage": |
817 |
- if len(mymergelist) > mergecount and EPREFIX == BPREFIX: |
818 |
- emergelog(xterm_titles, |
819 |
- " ::: completed emerge ("+ \ |
820 |
- str(mergecount)+" of "+ \ |
821 |
- str(len(mymergelist))+") "+ \ |
822 |
- x[2]+" to "+x[1]) |
823 |
- emergelog(xterm_titles, " *** RESTARTING " + \ |
824 |
- "emerge via exec() after change of " + \ |
825 |
- "portage version.") |
826 |
- del mtimedb["resume"]["mergelist"][0] |
827 |
- mtimedb.commit() |
828 |
- portage.run_exitfuncs() |
829 |
- mynewargv=[sys.argv[0],"--resume"] |
830 |
- resume_opts = self.myopts.copy() |
831 |
- # For automatic resume, we need to prevent |
832 |
- # any of bad_resume_opts from leaking in |
833 |
- # via EMERGE_DEFAULT_OPTS. |
834 |
- resume_opts["--ignore-default-opts"] = True |
835 |
- for myopt, myarg in resume_opts.iteritems(): |
836 |
- if myopt not in bad_resume_opts: |
837 |
- if myarg is True: |
838 |
- mynewargv.append(myopt) |
839 |
- else: |
840 |
- mynewargv.append(myopt +"="+ myarg) |
841 |
- # priority only needs to be adjusted on the first run |
842 |
- os.environ["PORTAGE_NICENESS"] = "0" |
843 |
- os.execv(mynewargv[0], mynewargv) |
844 |
- |
845 |
- if "--pretend" not in self.myopts and \ |
846 |
- "--fetchonly" not in self.myopts and \ |
847 |
- "--fetch-all-uri" not in self.myopts: |
848 |
- if "noclean" not in self.settings.features: |
849 |
- short_msg = "emerge: (%s of %s) %s Clean Post" % \ |
850 |
- (mergecount, len(mymergelist), x[pkgindex]) |
851 |
- emergelog(xterm_titles, (" === (%s of %s) " + \ |
852 |
- "Post-Build Cleaning (%s::%s)") % \ |
853 |
- (mergecount, len(mymergelist), pkg.cpv, y), |
854 |
- short_msg=short_msg) |
855 |
- emergelog(xterm_titles, " ::: completed emerge ("+\ |
856 |
- str(mergecount)+" of "+str(len(mymergelist))+") "+\ |
857 |
- x[2]+" to "+x[1]) |
858 |
- |
859 |
- # Unsafe for parallel merges |
860 |
+ self._restart_if_necessary(pkg) |
861 |
del mtimedb["resume"]["mergelist"][0] |
862 |
+ if not mtimedb["resume"]["mergelist"]: |
863 |
+ del mtimedb["resume"] |
864 |
# Commit after each merge so that --resume may still work in |
865 |
# in the event that portage is not allowed to exit normally |
866 |
# due to power failure, SIGKILL, etc... |
867 |
mtimedb.commit() |
868 |
self.curval += 1 |
869 |
|
870 |
- def _post_merge(self, mtimedb, xterm_titles, failed_fetches): |
871 |
- if "--pretend" not in self.myopts: |
872 |
- emergelog(xterm_titles, " *** Finished. Cleaning up...") |
873 |
- |
874 |
- # We're out of the loop... We're done. Delete the resume data. |
875 |
- if "resume" in mtimedb: |
876 |
- del mtimedb["resume"] |
877 |
- mtimedb.commit() |
878 |
- |
879 |
- #by doing an exit this way, --fetchonly can continue to try to |
880 |
- #fetch everything even if a particular download fails. |
881 |
- if "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts: |
882 |
- if failed_fetches: |
883 |
- sys.stderr.write("\n\n!!! Some fetch errors were " + \ |
884 |
- "encountered. Please see above for details.\n\n") |
885 |
- for cpv in failed_fetches: |
886 |
- sys.stderr.write(" ") |
887 |
- sys.stderr.write(cpv) |
888 |
- sys.stderr.write("\n") |
889 |
- sys.stderr.write("\n") |
890 |
- sys.exit(1) |
891 |
- else: |
892 |
- sys.exit(0) |
893 |
- return os.EX_OK |
894 |
- |
895 |
class UninstallFailure(portage.exception.PortageException): |
896 |
""" |
897 |
An instance of this class is raised by unmerge() when |
898 |
|
899 |
Modified: main/branches/prefix/pym/portage/__init__.py |
900 |
=================================================================== |
901 |
--- main/branches/prefix/pym/portage/__init__.py 2008-07-03 12:04:45 UTC (rev 10913) |
902 |
+++ main/branches/prefix/pym/portage/__init__.py 2008-07-03 17:05:34 UTC (rev 10914) |
903 |
@@ -7095,6 +7095,22 @@ |
904 |
name = object.__getattribute__(self, '_name') |
905 |
return globals()[name] |
906 |
|
907 |
+_legacy_global_var_names = ("archlist", "db", "features", |
908 |
+ "groups", "mtimedb", "mtimedbfile", "pkglines", |
909 |
+ "portdb", "profiledir", "root", "selinux_enabled", |
910 |
+ "settings", "thirdpartymirrors", "usedefaults") |
911 |
+ |
912 |
+def _disable_legacy_globals(): |
913 |
+ """ |
914 |
+ This deletes the ObjectProxy instances that are used |
915 |
+ for lazy initialization of legacy global variables. |
916 |
+ The purpose of deleting them is to prevent new code |
917 |
+ from referencing these deprecated variables. |
918 |
+ """ |
919 |
+ global _legacy_global_var_names |
920 |
+ for k in _legacy_global_var_names: |
921 |
+ globals().pop(k, None) |
922 |
+ |
923 |
# Initialization of legacy globals. No functions/classes below this point |
924 |
# please! When the above functions and classes become independent of the |
925 |
# below global variables, it will be possible to make the below code |
926 |
@@ -7158,11 +7174,7 @@ |
927 |
# within Portage under any circumstances. |
928 |
# ======================================================================== |
929 |
|
930 |
-# WARNING! |
931 |
-# The PORTAGE_LEGACY_GLOBALS environment variable is reserved for internal |
932 |
-# use within Portage. External use of this variable is unsupported because |
933 |
-# it is experimental and it's behavior is likely to change. |
934 |
-if "PORTAGE_LEGACY_GLOBALS" not in os.environ: |
935 |
+if True: |
936 |
|
937 |
_mtimedb_initialized = False |
938 |
mtimedb = _MtimedbProxy("mtimedb") |
939 |
|
940 |
-- |
941 |
gentoo-commits@l.g.o mailing list |