OLD | NEW |
1 #!/usr/bin/python2.6 | 1 #!/usr/bin/python2.6 |
2 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 2 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Program to run emerge in parallel, for significant speedup. | 6 """Program to run emerge in parallel, for significant speedup. |
7 | 7 |
8 Usage: | 8 Usage: |
9 ./parallel_emerge [--board=BOARD] [--workon=PKGS] [--no-workon-deps] | 9 ./parallel_emerge [--board=BOARD] [--workon=PKGS] [--no-workon-deps] |
10 [emerge args] package" | 10 [emerge args] package" |
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 | 559 |
560 def _Status(self): | 560 def _Status(self): |
561 """Print status.""" | 561 """Print status.""" |
562 seconds = time.time() - GLOBAL_START | 562 seconds = time.time() - GLOBAL_START |
563 line = ("Pending %s, Ready %s, Running %s, Retrying %s, Total %s " | 563 line = ("Pending %s, Ready %s, Running %s, Retrying %s, Total %s " |
564 "[Time %dm%ds Load %s]") | 564 "[Time %dm%ds Load %s]") |
565 print line % (len(self._deps_map), len(self._emerge_queue), | 565 print line % (len(self._deps_map), len(self._emerge_queue), |
566 len(self._jobs), len(self._retry_queue), self._total_jobs, | 566 len(self._jobs), len(self._retry_queue), self._total_jobs, |
567 seconds / 60, seconds % 60, self._LoadAvg()) | 567 seconds / 60, seconds % 60, self._LoadAvg()) |
568 | 568 |
569 def _LaunchOneEmerge(self, target): | 569 def _LaunchOneEmerge(self, target, action): |
570 """Run emerge --nodeps to do a single package install. | 570 """Run emerge --nodeps to do a single package install. |
571 | 571 |
572 If this is a pseudopackage, that means we're done, and can select in in the | 572 If this is a pseudopackage, that means we're done, and can select in in the |
573 world file. | 573 world file. |
574 Args: | 574 Args: |
575 target: The full package name of the package to install. | 575 target: The full package name of the package to install. |
576 eg. "sys-apps/portage-2.17" | 576 eg. "sys-apps/portage-2.17" |
577 Returns: | 577 Returns: |
578 Triplet containing (target name, subprocess object, output buffer object). | 578 Triplet containing (target name, subprocess object, output buffer object). |
579 """ | 579 """ |
580 if target.startswith("original-"): | 580 if target.startswith("original-"): |
581 # "original-" signifies one of the packages we originally requested. | 581 # "original-" signifies one of the packages we originally requested. |
582 # Since we have explicitly installed the versioned package as a dep of | 582 # Since we have explicitly installed the versioned package as a dep of |
583 # this, we only need to tag in "world" that we are done with this | 583 # this, we only need to tag in "world" that we are done with this |
584 # install request. | 584 # install request. |
585 # --nodeps: Ignore dependencies -- we handle them internally. | 585 # --nodeps: Ignore dependencies -- we handle them internally. |
586 # --noreplace: Don't replace or upgrade any packages. (In this case, the | 586 # --noreplace: Don't replace or upgrade any packages. (In this case, the |
587 # package is already installed, so we are just updating the | 587 # package is already installed, so we are just updating the |
588 # world file.) | 588 # world file.) |
589 # --selective: Make sure that --noreplace sticks even if --selective=n is | 589 # --selective: Make sure that --noreplace sticks even if --selective=n is |
590 # specified by the user on the command-line. | 590 # specified by the user on the command-line. |
591 # NOTE: If the user specifies --oneshot on the command-line, this command | 591 # NOTE: If the user specifies --oneshot on the command-line, this command |
592 # will do nothing. That is desired, since the user requested not to | 592 # will do nothing. That is desired, since the user requested not to |
593 # update the world file. | 593 # update the world file. |
594 newtarget = target.replace("original-", "") | 594 newtarget = target.replace("original-", "") |
595 cmdline = (EmergeCommand() + " --nodeps --selective --noreplace " + | 595 cmdline = (EmergeCommand() + " --nodeps --selective --noreplace " + |
596 newtarget) | 596 newtarget) |
| 597 elif action == "uninstall": |
| 598 cmdline = EmergeCommand() + " --nodeps --unmerge =" + target |
597 else: | 599 else: |
598 # This package is a dependency of something we specifically | 600 # This package is a dependency of something we specifically |
599 # requested. Therefore we should install it but not allow it | 601 # requested. Therefore we should install it but not allow it |
600 # in the "world" file, which represents explicit installs. | 602 # in the "world" file, which represents explicit installs. |
601 # --oneshot" here will prevent it from being tagged in world. | 603 # --oneshot" here will prevent it from being tagged in world. |
602 cmdline = EmergeCommand() + " --nodeps --oneshot " | 604 cmdline = EmergeCommand() + " --nodeps --oneshot " |
603 this_pkg = self._deps_map[target] | 605 this_pkg = self._deps_map[target] |
604 if this_pkg["workon"]: | 606 if this_pkg["workon"]: |
605 # --usepkg=n --getbinpkg=n: Build from source | 607 # --usepkg=n --getbinpkg=n: Build from source |
606 # --selective=n: Re-emerge even if package is already installed. | 608 # --selective=n: Re-emerge even if package is already installed. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
664 # We maintain a tree of all deps, if this doesn't need | 666 # We maintain a tree of all deps, if this doesn't need |
665 # to be installed just free up it's children and continue. | 667 # to be installed just free up it's children and continue. |
666 # It is possible to reinstall deps of deps, without reinstalling | 668 # It is possible to reinstall deps of deps, without reinstalling |
667 # first level deps, like so: | 669 # first level deps, like so: |
668 # chromeos (merge) -> eselect (nomerge) -> python (merge) | 670 # chromeos (merge) -> eselect (nomerge) -> python (merge) |
669 if action == "nomerge": | 671 if action == "nomerge": |
670 self._Finish(target) | 672 self._Finish(target) |
671 else: | 673 else: |
672 # Kick off the build if it's marked to be built. | 674 # Kick off the build if it's marked to be built. |
673 print "Emerging %s (%s)" % (target, action) | 675 print "Emerging %s (%s)" % (target, action) |
674 job = self._LaunchOneEmerge(target) | 676 job = self._LaunchOneEmerge(target, action) |
675 # Append it to the active jobs list. | 677 # Append it to the active jobs list. |
676 self._jobs.append(job) | 678 self._jobs.append(job) |
677 continue | 679 continue |
678 # Wait a bit to see if maybe some jobs finish. You can't | 680 # Wait a bit to see if maybe some jobs finish. You can't |
679 # wait on a set of jobs in python, so we'll just poll. | 681 # wait on a set of jobs in python, so we'll just poll. |
680 time.sleep(1) | 682 time.sleep(1) |
681 secs += 1 | 683 secs += 1 |
682 if secs % 30 == 0: | 684 if secs % 30 == 0: |
683 # Print an update. | 685 # Print an update. |
684 self._Status() | 686 self._Status() |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
786 | 788 |
787 if VERBOSE: | 789 if VERBOSE: |
788 PrintDepsMap(dependency_graph) | 790 PrintDepsMap(dependency_graph) |
789 | 791 |
790 # Run the queued emerges. | 792 # Run the queued emerges. |
791 scheduler = EmergeQueue(dependency_graph) | 793 scheduler = EmergeQueue(dependency_graph) |
792 scheduler.Run() | 794 scheduler.Run() |
793 | 795 |
794 print "Done" | 796 print "Done" |
795 | 797 |
OLD | NEW |