Gentoo Archives: gentoo-commits

From: "Zac Medico (zmedico)" <zmedico@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r10885 - main/trunk/pym/_emerge
Date: Wed, 02 Jul 2008 01:13:22
Message-Id: E1KDquK-00062I-Bt@stork.gentoo.org
1 Author: zmedico
2 Date: 2008-07-02 01:13:15 +0000 (Wed, 02 Jul 2008)
3 New Revision: 10885
4
5 Modified:
6 main/trunk/pym/_emerge/__init__.py
7 Log:
8 * Rename existing EbuildBuild class to EbuildExecuter.
9 * Split more code out of Scheduler._execute_task() and use it to make
10 a more comprehensive EbuildBuild class.
11
12
13 Modified: main/trunk/pym/_emerge/__init__.py
14 ===================================================================
15 --- main/trunk/pym/_emerge/__init__.py 2008-07-01 18:47:14 UTC (rev 10884)
16 +++ main/trunk/pym/_emerge/__init__.py 2008-07-02 01:13:15 UTC (rev 10885)
17 @@ -52,6 +52,7 @@
18 # white looks bad on terminals with white background
19 from portage.output import bold as white
20
21 +import portage.elog
22 import portage.dep
23 portage.dep._dep_check_strict = True
24 import portage.util
25 @@ -1439,7 +1440,7 @@
26
27 class EbuildFetcher(SlotObject):
28
29 - __slots__ = ("fetch_all", "pkg", "pretend", "settings")
30 + __slots__ = ("cancelled", "fetch_all", "pkg", "pretend", "settings")
31
32 def execute(self):
33 portdb = self.pkg.root_config.trees["porttree"].dbapi
34 @@ -1454,7 +1455,7 @@
35
36 class EbuildFetcherAsync(SlotObject):
37
38 - __slots__ = ("log_file", "fd_pipes", "pkg",
39 + __slots__ = ("cancelled", "log_file", "fd_pipes", "pkg",
40 "register", "unregister",
41 "pid", "returncode", "files")
42
43 @@ -1463,6 +1464,10 @@
44 _bufsize = 4096
45
46 def start(self):
47 +
48 + if self.cancelled:
49 + return
50 +
51 # flush any pending output
52 fd_pipes = self.fd_pipes
53 if fd_pipes is None:
54 @@ -1554,6 +1559,18 @@
55 self._set_returncode(retval)
56 return self.returncode
57
58 + def cancel(self):
59 + if self.isAlive():
60 + os.kill(self.pid, signal.SIGTERM)
61 + self.cancelled = True
62 + if self.pid is not None:
63 + self.wait()
64 + return self.returncode
65 +
66 + def isAlive(self):
67 + return self.pid is not None and \
68 + self.returncode is None
69 +
70 def wait(self):
71 if self.returncode is not None:
72 return self.returncode
73 @@ -1644,20 +1661,137 @@
74 class AlreadyLocked(portage.exception.PortageException):
75 pass
76
77 -class EbuildBuild(Task):
78 - """
79 - TODO: Support asynchronous execution, to implement parallel builds.
80 - """
81 +class EbuildBuild(SlotObject):
82 +
83 + __slots__ = ("args_set", "find_blockers",
84 + "ldpath_mtimes", "logger", "opts",
85 + "pkg", "pkg_count", "scheduler",
86 + "settings")
87 +
88 + def execute(self):
89 +
90 + args_set = self.args_set
91 + find_blockers = self.find_blockers
92 + ldpath_mtimes = self.ldpath_mtimes
93 + logger = self.logger
94 + opts = self.opts
95 + pkg = self.pkg
96 + pkg_count = self.pkg_count
97 + scheduler = self.scheduler
98 + settings = self.settings
99 + root_config = pkg.root_config
100 + root = root_config.root
101 + system_set = root_config.sets["system"]
102 + world_set = root_config.sets["world"]
103 + vartree = root_config.trees["vartree"]
104 + portdb = root_config.trees["porttree"].dbapi
105 + debug = settings.get("PORTAGE_DEBUG") == "1"
106 + features = self.settings.features
107 + settings["EMERGE_FROM"] = pkg.type_name
108 + settings.backup_changes("EMERGE_FROM")
109 + settings.reset()
110 + ebuild_path = portdb.findname(self.pkg.cpv)
111 +
112 + #buildsyspkg: Check if we need to _force_ binary package creation
113 + issyspkg = "buildsyspkg" in features and \
114 + system_set.findAtomForPackage(pkg) and \
115 + not opts.buildpkg
116 +
117 + if opts.fetchonly:
118 + fetcher = EbuildFetcher(fetch_all=opts.fetch_all_uri,
119 + pkg=pkg, pretend=opts.pretend, settings=settings)
120 + retval = fetcher.execute()
121 + if retval != os.EX_OK:
122 + from portage.elog.messages import eerror
123 + eerror("!!! Fetch for %s failed, continuing..." % pkg.cpv,
124 + phase="unpack", key=pkg.cpv)
125 + return retval
126 +
127 + build_dir = EbuildBuildDir(pkg=pkg, settings=settings)
128 + try:
129 + build_dir.lock()
130 + # Cleaning is triggered before the setup
131 + # phase, in portage.doebuild().
132 + msg = " === (%s of %s) Cleaning (%s::%s)" % \
133 + (pkg_count.curval, pkg_count.maxval, pkg.cpv, ebuild_path)
134 + short_msg = "emerge: (%s of %s) %s Clean" % \
135 + (pkg_count.curval, pkg_count.maxval, pkg.cpv)
136 + logger.log(msg, short_msg=short_msg)
137 +
138 + if opts.buildpkg or issyspkg:
139 + if issyspkg:
140 + portage.writemsg(">>> This is a system package, " + \
141 + "let's pack a rescue tarball.\n", noiselevel=-1)
142 + msg = " === (%s of %s) Compiling/Packaging (%s::%s)" % \
143 + (pkg_count.curval, pkg_count.maxval, pkg.cpv, ebuild_path)
144 + short_msg = "emerge: (%s of %s) %s Compile" % \
145 + (pkg_count.curval, pkg_count.maxval, pkg.cpv)
146 + logger.log(msg, short_msg=short_msg)
147 +
148 + build = EbuildExecuter(pkg=pkg, register=scheduler.register,
149 + schedule=scheduler.schedule, settings=settings,
150 + unregister=scheduler.unregister)
151 + retval = build.execute()
152 + if retval != os.EX_OK:
153 + return retval
154 +
155 + build = EbuildBinpkg(pkg=pkg, settings=settings)
156 + retval = build.execute()
157 + if retval != os.EX_OK:
158 + return retval
159 +
160 + if opts.buildpkgonly:
161 + msg = " === (%s of %s) Merging (%s::%s)" % \
162 + (pkg_count.curval, pkg_count.maxval,
163 + pkg.cpv, ebuild_path)
164 + short_msg = "emerge: (%s of %s) %s Merge" % \
165 + (pkg_count.curval, pkg_count.maxval, pkg.cpv)
166 + logger.log(msg, short_msg=short_msg)
167 +
168 + merge = EbuildMerge(
169 + find_blockers=find_blockers,
170 + ldpath_mtimes=ldpath_mtimes,
171 + pkg=pkg, settings=settings)
172 + retval = merge.execute()
173 + if retval != os.EX_OK:
174 + return retval
175 + elif "noclean" not in settings.features:
176 + portage.doebuild(ebuild_path, "clean", root,
177 + settings, debug=debug, mydbapi=portdb,
178 + tree="porttree")
179 + else:
180 + msg = " === (%s of %s) Compiling/Merging (%s::%s)" % \
181 + (pkg_count.curval, pkg_count.maxval, pkg.cpv, ebuild_path)
182 + short_msg = "emerge: (%s of %s) %s Compile" % \
183 + (pkg_count.curval, pkg_count.curval, pkg.cpv)
184 + logger.log(msg, short_msg=short_msg)
185 +
186 + build = EbuildExecuter(pkg=pkg, register=scheduler.register,
187 + schedule=scheduler.schedule, settings=settings,
188 + unregister=scheduler.unregister)
189 + retval = build.execute()
190 + if retval != os.EX_OK:
191 + return retval
192 +
193 + merge = EbuildMerge(
194 + find_blockers=self.find_blockers,
195 + ldpath_mtimes=ldpath_mtimes,
196 + pkg=pkg, settings=settings)
197 + retval = merge.execute()
198 +
199 + if retval != os.EX_OK:
200 + return retval
201 + finally:
202 + if build_dir.locked:
203 + portage.elog.elog_process(pkg.cpv, settings)
204 + build_dir.unlock()
205 +
206 +class EbuildExecuter(SlotObject):
207 +
208 __slots__ = ("pkg", "register", "schedule", "settings", "unregister")
209
210 _phases = ("setup", "unpack", "compile", "test", "install")
211
212 - def _get_hash_key(self):
213 - hash_key = getattr(self, "_hash_key", None)
214 - if hash_key is None:
215 - self._hash_key = ("EbuildBuild", self.pkg._get_hash_key())
216 - return self._hash_key
217 -
218 def execute(self):
219 root_config = self.pkg.root_config
220 portdb = root_config.trees["porttree"].dbapi
221 @@ -2013,8 +2147,8 @@
222 def start(self):
223
224 if self.cancelled:
225 - self.pid = -1
226 return
227 + writemsg(">>> starting parallel binpkg fetcher\n")
228
229 fd_pipes = self.fd_pipes
230 if fd_pipes is None:
231 @@ -2196,6 +2330,12 @@
232 return self._hash_key
233
234 def execute(self):
235 +
236 + settings = self.settings
237 + settings["EMERGE_FROM"] = self.pkg.type_name
238 + settings.backup_changes("EMERGE_FROM")
239 + settings.reset()
240 +
241 root_config = self.pkg.root_config
242 retval = portage.pkgmerge(self.pkg_path, root_config.root,
243 self.settings,
244 @@ -6654,6 +6794,22 @@
245
246 _fetch_log = "/var/log/emerge-fetch.log"
247
248 + class _iface_class(SlotObject):
249 + __slots__ = ("register", "schedule", "unregister")
250 +
251 + class _build_opts_class(SlotObject):
252 + __slots__ = ("buildpkg", "buildpkgonly",
253 + "fetch_all_uri", "fetchonly", "pretend")
254 +
255 + class _pkg_count_class(SlotObject):
256 + __slots__ = ("curval", "maxval")
257 +
258 + class _emerge_log_class(SlotObject):
259 + __slots__ = ("xterm_titles",)
260 +
261 + def log(self, *pargs, **kwargs):
262 + emergelog(self.xterm_titles, *pargs, **kwargs)
263 +
264 def __init__(self, settings, trees, mtimedb, myopts,
265 spinner, mergelist, favorites, digraph):
266 self.settings = settings
267 @@ -6664,6 +6820,10 @@
268 self._mtimedb = mtimedb
269 self._mergelist = mergelist
270 self._favorites = favorites
271 + self._args_set = InternalPackageSet(favorites)
272 + self._build_opts = self._build_opts_class()
273 + for k in self._build_opts.__slots__:
274 + setattr(self._build_opts, k, "--" + k.replace("_", "-") in myopts)
275 self.edebug = 0
276 if settings.get("PORTAGE_DEBUG", "") == "1":
277 self.edebug = 1
278 @@ -6672,6 +6832,11 @@
279 self.pkgsettings[root] = portage.config(
280 clone=trees[root]["vartree"].settings)
281 self.curval = 0
282 + self._logger = self._emerge_log_class(
283 + xterm_titles=("notitles" not in settings.features))
284 + self._sched_iface = self._iface_class(
285 + register=self._register, schedule=self._schedule,
286 + unregister=self._unregister)
287 self._poll_event_handlers = {}
288 self._poll = select.poll()
289 from collections import deque
290 @@ -6905,12 +7070,12 @@
291 "--onlydeps" in self.myopts
292 pretend = "--pretend" in self.myopts
293 ldpath_mtimes = mtimedb["ldpath"]
294 - xterm_titles = "notitles" not in self.settings.features
295 + logger = self._logger
296
297 if "--resume" in self.myopts:
298 # We're resuming.
299 print colorize("GOOD", "*** Resuming merge...")
300 - emergelog(xterm_titles, " *** Resuming merge...")
301 + self._logger.log(" *** Resuming merge...")
302
303 # Do this before verifying the ebuild Manifests since it might
304 # be possible for the user to use --resume --skipfirst get past
305 @@ -6923,6 +7088,7 @@
306 getbinpkg = "--getbinpkg" in self.myopts
307
308 if self._parallel_fetch:
309 + portage.writemsg(">>> starting parallel fetch\n")
310 for pkg in mylist:
311 if not isinstance(pkg, Package):
312 continue
313 @@ -6981,7 +7147,8 @@
314 # Filter mymergelist so that all the len(mymergelist) calls
315 # below (for display) do not count Uninstall instances.
316 mymergelist = [x for x in mymergelist if x[-1] == "merge"]
317 - mergecount=0
318 + pkg_count = self._pkg_count_class(
319 + curval=0, maxval=len(mymergelist))
320 for x in task_list:
321 if x[0] == "blocks":
322 continue
323 @@ -7005,24 +7172,24 @@
324 else:
325 raise AssertionError("Package type: '%s'" % pkg_type)
326 if not x.installed:
327 - mergecount += 1
328 + pkg_count.curval += 1
329 try:
330 self._execute_task(bad_resume_opts,
331 failed_fetches,
332 - mydbapi, mergecount,
333 + mydbapi, pkg_count,
334 myfeat, mymergelist, x,
335 - prefetchers, xterm_titles)
336 + prefetchers)
337 except self._pkg_failure, e:
338 return e.status
339 - return self._post_merge(mtimedb, xterm_titles, failed_fetches)
340 + return self._post_merge(mtimedb,
341 + self._logger.xterm_titles, failed_fetches)
342
343 def _execute_task(self, bad_resume_opts,
344 - failed_fetches, mydbapi, mergecount, myfeat,
345 - mymergelist, pkg, prefetchers, xterm_titles):
346 + failed_fetches, mydbapi, pkg_count, myfeat,
347 + mymergelist, pkg, prefetchers):
348 favorites = self._favorites
349 mtimedb = self._mtimedb
350 - from portage.elog import elog_process
351 - from portage.elog.filtering import filter_mergephases
352 + mergecount = pkg_count.curval
353 pkgsettings = self.pkgsettings[pkg.root]
354 buildpkgonly = "--buildpkgonly" in self.myopts
355 fetch_all = "--fetch-all-uri" in self.myopts
356 @@ -7035,6 +7202,7 @@
357 xterm_titles = "notitles" not in self.settings.features
358
359 x = pkg
360 + y = None
361 root_config = pkg.root_config
362 system_set = root_config.sets["system"]
363 args_set = InternalPackageSet(favorites)
364 @@ -7056,7 +7224,7 @@
365
366 if x[0]=="blocks":
367 pkgindex=3
368 - y = portdb.findname(pkg_key)
369 +
370 if "--pretend" not in self.myopts:
371 print "\n>>> Emerging (" + \
372 colorize("MERGE_LIST_PROGRESS", str(mergecount)) + " of " + \
373 @@ -7066,109 +7234,19 @@
374 str(mergecount)+" of "+str(len(mymergelist))+\
375 ") "+x[pkgindex]+" to "+x[1])
376
377 - pkgsettings["EMERGE_FROM"] = x[0]
378 - pkgsettings.backup_changes("EMERGE_FROM")
379 - pkgsettings.reset()
380 + self._schedule()
381
382 - #buildsyspkg: Check if we need to _force_ binary package creation
383 - issyspkg = ("buildsyspkg" in myfeat) \
384 - and x[0] != "blocks" \
385 - and system_set.findAtomForPackage(pkg) \
386 - and "--buildpkg" not in self.myopts
387 - if x[0] in ["ebuild","blocks"]:
388 - if x[0] == "blocks" and "--fetchonly" not in self.myopts:
389 - raise Exception, "Merging a blocker"
390 - elif fetchonly:
391 - fetcher = EbuildFetcher(fetch_all=fetch_all,
392 - pkg=pkg, pretend=pretend, settings=pkgsettings)
393 - retval = fetcher.execute()
394 - if (retval is None) or retval:
395 - print
396 - print "!!! Fetch for",y,"failed, continuing..."
397 - print
398 - failed_fetches.append(pkg_key)
399 - self.curval += 1
400 - return
401 + if x.type_name == "ebuild":
402 + y = portdb.findname(pkg.cpv)
403 + build = EbuildBuild(args_set=self._args_set,
404 + find_blockers=self._find_blockers(pkg),
405 + ldpath_mtimes=ldpath_mtimes, logger=self._logger,
406 + opts=self._build_opts, pkg=pkg, pkg_count=pkg_count,
407 + settings=pkgsettings, scheduler=self._sched_iface)
408 + retval = build.execute()
409 + if retval != os.EX_OK:
410 + raise self._pkg_failure(retval)
411
412 - build_dir = EbuildBuildDir(pkg=pkg, settings=pkgsettings)
413 - try:
414 - build_dir.lock()
415 - # Cleaning is triggered before the setup
416 - # phase, in portage.doebuild().
417 - msg = " === (%s of %s) Cleaning (%s::%s)" % \
418 - (mergecount, len(mymergelist), pkg_key, y)
419 - short_msg = "emerge: (%s of %s) %s Clean" % \
420 - (mergecount, len(mymergelist), pkg_key)
421 - emergelog(xterm_titles, msg, short_msg=short_msg)
422 -
423 - if "--buildpkg" in self.myopts or issyspkg:
424 - if issyspkg:
425 - print ">>> This is a system package, " + \
426 - "let's pack a rescue tarball."
427 - msg = " === (%s of %s) Compiling/Packaging (%s::%s)" % \
428 - (mergecount, len(mymergelist), pkg_key, y)
429 - short_msg = "emerge: (%s of %s) %s Compile" % \
430 - (mergecount, len(mymergelist), pkg_key)
431 - emergelog(xterm_titles, msg, short_msg=short_msg)
432 -
433 - build = EbuildBuild(pkg=pkg, register=self._register,
434 - schedule=self._schedule, settings=pkgsettings,
435 - unregister=self._unregister)
436 - retval = build.execute()
437 - if retval != os.EX_OK:
438 - raise self._pkg_failure(retval)
439 -
440 - build = EbuildBinpkg(pkg=pkg, settings=pkgsettings)
441 - retval = build.execute()
442 - if retval != os.EX_OK:
443 - raise self._pkg_failure(retval)
444 -
445 - if "--buildpkgonly" not in self.myopts:
446 - msg = " === (%s of %s) Merging (%s::%s)" % \
447 - (mergecount, len(mymergelist), pkg_key, y)
448 - short_msg = "emerge: (%s of %s) %s Merge" % \
449 - (mergecount, len(mymergelist), pkg_key)
450 - emergelog(xterm_titles, msg, short_msg=short_msg)
451 -
452 - merge = EbuildMerge(
453 - find_blockers=self._find_blockers(pkg),
454 - ldpath_mtimes=ldpath_mtimes,
455 - pkg=pkg, pretend=pretend, settings=pkgsettings)
456 - retval = merge.execute()
457 - if retval != os.EX_OK:
458 - raise self._pkg_failure(retval)
459 - elif "noclean" not in pkgsettings.features:
460 - portage.doebuild(y, "clean", myroot,
461 - pkgsettings, self.edebug, mydbapi=portdb,
462 - tree="porttree")
463 - else:
464 - msg = " === (%s of %s) Compiling/Merging (%s::%s)" % \
465 - (mergecount, len(mymergelist), pkg_key, y)
466 - short_msg = "emerge: (%s of %s) %s Compile" % \
467 - (mergecount, len(mymergelist), pkg_key)
468 - emergelog(xterm_titles, msg, short_msg=short_msg)
469 -
470 - build = EbuildBuild(pkg=pkg, register=self._register,
471 - schedule=self._schedule, settings=pkgsettings,
472 - unregister=self._unregister)
473 - retval = build.execute()
474 - if retval != os.EX_OK:
475 - raise self._pkg_failure(retval)
476 -
477 - merge = EbuildMerge(
478 - find_blockers=self._find_blockers(pkg),
479 - ldpath_mtimes=ldpath_mtimes,
480 - pkg=pkg, pretend=pretend, settings=pkgsettings)
481 - retval = merge.execute()
482 -
483 - if retval != os.EX_OK:
484 - raise self._pkg_failure(retval)
485 - finally:
486 - if build_dir.locked:
487 - elog_process(pkg.cpv, pkgsettings,
488 - phasefilter=filter_mergephases)
489 - build_dir.unlock()
490 -
491 elif x.type_name == "binary":
492 # The prefetcher have already completed or it
493 # could be running now. If it's running now,
494 @@ -7182,17 +7260,22 @@
495 prefetcher = prefetchers.get(pkg)
496 if prefetcher is not None:
497 if not prefetcher.isAlive():
498 + writemsg(">>> prefetcher not alive, cancelling\n")
499 prefetcher.cancel()
500 else:
501 + writemsg(">>> prefetcher alive, waiting\n")
502 retval = None
503 while retval is None:
504 self._schedule()
505 retval = prefetcher.poll()
506 del prefetcher
507 + else:
508 + writemsg(">>> prefetcher does not exist\n")
509
510 fetcher = BinpkgFetcher(pkg=pkg, pretend=pretend,
511 use_locks=("distlocks" in pkgsettings.features))
512 mytbz2 = fetcher.pkg_path
513 + y = mytbz2
514 if "--getbinpkg" in self.myopts:
515 retval = fetcher.execute()
516 if fetcher.remote:
517 @@ -7280,7 +7363,7 @@
518 (mergecount, len(mymergelist), x[pkgindex])
519 emergelog(xterm_titles, (" === (%s of %s) " + \
520 "Post-Build Cleaning (%s::%s)") % \
521 - (mergecount, len(mymergelist), x[pkgindex], y),
522 + (mergecount, len(mymergelist), pkg.cpv, y),
523 short_msg=short_msg)
524 emergelog(xterm_titles, " ::: completed emerge ("+\
525 str(mergecount)+" of "+str(len(mymergelist))+") "+\
526
527 --
528 gentoo-commits@l.g.o mailing list