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 [emerge args] package | 9 ./parallel_emerge --board=BOARD [emerge args] package |
10 | 10 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 # emerge args we are passing through. | 60 # emerge args we are passing through. |
61 PACKAGE = None | 61 PACKAGE = None |
62 EMERGE_ARGS = "" | 62 EMERGE_ARGS = "" |
63 BOARD = None | 63 BOARD = None |
64 | 64 |
65 # Runtime flags. TODO(): Maybe make these command-line options or | 65 # Runtime flags. TODO(): Maybe make these command-line options or |
66 # environment variables. | 66 # environment variables. |
67 VERBOSE = False | 67 VERBOSE = False |
68 AUTOCLEAN = False | 68 AUTOCLEAN = False |
69 | 69 |
| 70 # Global start time |
| 71 GLOBAL_START = time.time() |
| 72 |
70 | 73 |
71 def ParseArgs(argv): | 74 def ParseArgs(argv): |
72 """Set global vars based on command line. | 75 """Set global vars based on command line. |
73 | 76 |
74 We need to be compatible with emerge arg format. | 77 We need to be compatible with emerge arg format. |
75 We scrape --board=XXX and --jobs=XXX, and distinguish between args | 78 We scrape --board=XXX and --jobs=XXX, and distinguish between args |
76 and package names. | 79 and package names. |
77 TODO(): Robustify argument processing, as it's possible to | 80 TODO(): Robustify argument processing, as it's possible to |
78 pass in many two argument parameters that are difficult | 81 pass in many two argument parameters that are difficult |
79 to programmatically identify, although we don't currently | 82 to programmatically identify, although we don't currently |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 # List of total package installs represented in deps_map. | 469 # List of total package installs represented in deps_map. |
467 install_jobs = [x for x in deps_map if deps_map[x]["action"] == "merge"] | 470 install_jobs = [x for x in deps_map if deps_map[x]["action"] == "merge"] |
468 self._total_jobs = len(install_jobs) | 471 self._total_jobs = len(install_jobs) |
469 | 472 |
470 # Initialize the ready queue, these are jobs with no unmet dependencies. | 473 # Initialize the ready queue, these are jobs with no unmet dependencies. |
471 self._emerge_queue = [x for x in deps_map if not deps_map[x]["needs"]] | 474 self._emerge_queue = [x for x in deps_map if not deps_map[x]["needs"]] |
472 # Initialize the failed queue to empty. | 475 # Initialize the failed queue to empty. |
473 self._retry_queue = [] | 476 self._retry_queue = [] |
474 self._failed = {} | 477 self._failed = {} |
475 | 478 |
| 479 def _LoadAvg(self): |
| 480 loads = open('/proc/loadavg', 'r').readline().split()[:3] |
| 481 return ' '.join(loads) |
| 482 |
476 def _Status(self): | 483 def _Status(self): |
477 """Print status.""" | 484 """Print status.""" |
478 print "Pending %s, Ready %s, Running %s, Retrying %s, Total %s" % ( | 485 seconds = time.time() - GLOBAL_START |
| 486 print "Pending %s, Ready %s, Running %s, Retrying %s, Total %s " \ |
| 487 "[Time %dm%ds Load %s]" % ( |
479 len(self._deps_map), len(self._emerge_queue), | 488 len(self._deps_map), len(self._emerge_queue), |
480 len(self._jobs), len(self._retry_queue), self._total_jobs) | 489 len(self._jobs), len(self._retry_queue), self._total_jobs, |
| 490 seconds / 60, seconds % 60, self._LoadAvg()) |
481 | 491 |
482 def _LaunchOneEmerge(self, target): | 492 def _LaunchOneEmerge(self, target): |
483 """Run emerge --nodeps to do a single package install. | 493 """Run emerge --nodeps to do a single package install. |
484 | 494 |
485 If this is a pseudopackage, that means we're done, and can select in in the | 495 If this is a pseudopackage, that means we're done, and can select in in the |
486 world file. | 496 world file. |
487 Args: | 497 Args: |
488 target: The full package name of the package to install. | 498 target: The full package name of the package to install. |
489 eg. "sys-apps/portage-2.17" | 499 eg. "sys-apps/portage-2.17" |
490 Returns: | 500 Returns: |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 | 670 |
661 if VERBOSE: | 671 if VERBOSE: |
662 PrintDepsMap(dependency_graph) | 672 PrintDepsMap(dependency_graph) |
663 | 673 |
664 # Run the queued emerges. | 674 # Run the queued emerges. |
665 scheduler = EmergeQueue(dependency_graph) | 675 scheduler = EmergeQueue(dependency_graph) |
666 scheduler.Run() | 676 scheduler.Run() |
667 | 677 |
668 print "Done" | 678 print "Done" |
669 | 679 |
OLD | NEW |