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