Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: bin/parallel_emerge

Issue 6728018: Update parallel_emerge to use Portage APIs to grab package information. (Closed) Base URL: http://git.chromium.org/git/chromite.git@master
Patch Set: Use BUILD_TIME instead of _mtime_ Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 [--force-remote-binary=PKGS] [emerge args] package 10 [--force-remote-binary=PKGS] [emerge args] package
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 708
709 Args: 709 Args:
710 deps: Dependency tree structure. 710 deps: Dependency tree structure.
711 depth: Allows printing the tree recursively, with indentation. 711 depth: Allows printing the tree recursively, with indentation.
712 """ 712 """
713 for entry in sorted(deps): 713 for entry in sorted(deps):
714 action = deps[entry]["action"] 714 action = deps[entry]["action"]
715 print "%s %s (%s)" % (depth, entry, action) 715 print "%s %s (%s)" % (depth, entry, action)
716 self.PrintTree(deps[entry]["deps"], depth=depth + " ") 716 self.PrintTree(deps[entry]["deps"], depth=depth + " ")
717 717
718 def RemotePackageDatabase(self, binhost_url, settings): 718 def RemotePackageDatabase(self):
719 """Grab the latest binary package database from the prebuilt server. 719 """Grab the latest binary package database from the prebuilt server.
720 720
721 We need to know the modification times of the prebuilt packages so that we 721 We need to know the modification times of the prebuilt packages so that we
722 know when it is OK to use these packages and when we should rebuild them 722 know when it is OK to use these packages and when we should rebuild them
723 instead. 723 instead.
724 724
725 Args:
726 binhost_url: Base URL of remote packages (PORTAGE_BINHOST).
727
728 Returns: 725 Returns:
729 A dict mapping package identifiers to modification times. 726 A dict mapping package identifiers to modification times.
730 """ 727 """
731 728 root = self.emerge.settings["ROOT"]
732 if not binhost_url: 729 bindb = self.emerge.trees[root]["bintree"].dbapi
733 return {}
734
735 def retry_urlopen(url, tries=3):
736 """Open the specified url, retrying if we run into temporary errors.
737
738 We retry for both network errors and 5xx Server Errors. We do not retry
739 for HTTP errors with a non-5xx code.
740
741 Args:
742 url: The specified url.
743 tries: The number of times to try.
744
745 Returns:
746 The result of urllib2.urlopen(url).
747 """
748 for i in range(tries):
749 try:
750 return urllib2.urlopen(url)
751 except urllib2.HTTPError as e:
752 print "Cannot GET %s: %s" % (url, str(e))
753 if i + 1 >= tries or e.code < 500:
754 raise
755 except urllib2.URLError as e:
756 print "Cannot GET %s: %s" % (url, str(e))
757 if i + 1 >= tries:
758 raise
759 print "Sleeping for 10 seconds before retrying..."
760 time.sleep(10)
761
762 url = os.path.join(binhost_url, "Packages")
763 tmp_filename = None
764 if url.startswith("http://"):
765 try:
766 f = retry_urlopen(url)
767 except urllib2.HTTPError as e:
768 if e.code == 404:
769 return {}
770 else:
771 raise
772 else:
773 parsed_url = urlparse.urlparse(url)
774 setting = 'FETCHCOMMAND_' + parsed_url.scheme.upper()
775 fcmd = settings.get(setting)
776 if not fcmd:
777 print >>sys.stderr, "Unrecognized URL:", url
778 sys.exit(1)
779 fd, tmp_filename = tempfile.mkstemp()
780 tmp_dirname, tmp_basename = os.path.split(tmp_filename)
781 os.close(fd)
782 success = portage.getbinpkg.file_get(url, tmp_dirname, fcmd=fcmd,
783 filename=tmp_basename)
784 if not success:
785 os.unlink(tmp_filename)
786 return {}
787 f = open(tmp_filename)
788
789 prebuilt_pkgs = {} 730 prebuilt_pkgs = {}
790 for line in f: 731 for pkg in bindb.cpv_all():
791 if line.startswith("CPV: "): 732 prebuilt_pkgs[pkg] = bindb.aux_get(pkg, ["BUILD_TIME"])[0]
792 pkg = line.replace("CPV: ", "").rstrip()
793 elif line.startswith("MTIME: "):
794 prebuilt_pkgs[pkg] = int(line[:-1].replace("MTIME: ", ""))
795 f.close()
796
797 if tmp_filename:
798 os.unlink(tmp_filename)
799
800 return prebuilt_pkgs 733 return prebuilt_pkgs
801 734
802 def GenDependencyGraph(self, deps_tree, deps_info, remote_pkgs): 735 def GenDependencyGraph(self, deps_tree, deps_info, remote_pkgs):
803 """Generate a doubly linked dependency graph. 736 """Generate a doubly linked dependency graph.
804 737
805 Args: 738 Args:
806 deps_tree: Dependency tree structure. 739 deps_tree: Dependency tree structure.
807 deps_info: More details on the dependencies. 740 deps_info: More details on the dependencies.
808 Returns: 741 Returns:
809 Deps graph in the form of a dict of packages, with each package 742 Deps graph in the form of a dict of packages, with each package
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
1104 1037
1105 def LocalPackageDatabase(): 1038 def LocalPackageDatabase():
1106 """Get the modification times of the packages in the local database. 1039 """Get the modification times of the packages in the local database.
1107 1040
1108 We need to know the modification times of the local packages so that we 1041 We need to know the modification times of the local packages so that we
1109 know when they need to be rebuilt. 1042 know when they need to be rebuilt.
1110 1043
1111 Returns: 1044 Returns:
1112 A dict mapping package identifiers to modification times. 1045 A dict mapping package identifiers to modification times.
1113 """ 1046 """
1114 if self.board: 1047 vardb = emerge.trees[root]["vartree"].dbapi
1115 path = "/build/%s/packages/Packages" % self.board
1116 else:
1117 path = "/var/lib/portage/pkgs/Packages"
1118 local_pkgs = {} 1048 local_pkgs = {}
1119 for line in file(path): 1049 for pkg in vardb.cpv_all():
1120 if line.startswith("CPV: "): 1050 local_pkgs[pkg] = vardb.aux_get(pkg, ["BUILD_TIME"])[0]
1121 pkg = line.replace("CPV: ", "").rstrip()
1122 elif line.startswith("MTIME: "):
1123 local_pkgs[pkg] = int(line[:-1].replace("MTIME: ", ""))
1124
1125 return local_pkgs 1051 return local_pkgs
1126 1052
1127 def AutoRebuildDeps(local_pkgs, remote_pkgs, cycles): 1053 def AutoRebuildDeps(local_pkgs, remote_pkgs, cycles):
1128 """Recursively rebuild packages when necessary using modification times. 1054 """Recursively rebuild packages when necessary using modification times.
1129 1055
1130 If you've modified a package, it's a good idea to rebuild all the packages 1056 If you've modified a package, it's a good idea to rebuild all the packages
1131 that depend on it from source. This function looks for any packages which 1057 that depend on it from source. This function looks for any packages which
1132 depend on packages that have been modified and ensures that they get 1058 depend on packages that have been modified and ensures that they get
1133 rebuilt. 1059 rebuilt.
1134 1060
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after
1848 nomerge_packages = " ".join(deps.nomerge) 1774 nomerge_packages = " ".join(deps.nomerge)
1849 print "Starting fast-emerge." 1775 print "Starting fast-emerge."
1850 print " Building package %s on %s" % (cmdline_packages, 1776 print " Building package %s on %s" % (cmdline_packages,
1851 deps.board or "root") 1777 deps.board or "root")
1852 if nomerge_packages: 1778 if nomerge_packages:
1853 print " Skipping package %s on %s" % (nomerge_packages, 1779 print " Skipping package %s on %s" % (nomerge_packages,
1854 deps.board or "root") 1780 deps.board or "root")
1855 1781
1856 remote_pkgs = {} 1782 remote_pkgs = {}
1857 if "--getbinpkg" in emerge.opts: 1783 if "--getbinpkg" in emerge.opts:
1858 binhosts = emerge.settings["PORTAGE_BINHOST"] 1784 remote_pkgs = deps.RemotePackageDatabase()
1859 for binhost in binhosts.split():
1860 try:
1861 remote_pkgs.update(deps.RemotePackageDatabase(binhost, emerge.settings))
1862 except (urllib2.HTTPError, urllib2.URLError):
1863 pass
1864 if not remote_pkgs:
1865 print "Can't find any binary packages. Building from source..."
1866 del emerge.opts["--getbinpkg"]
1867 1785
1868 deps_tree, deps_info = deps.GenDependencyTree(remote_pkgs) 1786 deps_tree, deps_info = deps.GenDependencyTree(remote_pkgs)
1869 1787
1870 # You want me to be verbose? I'll give you two trees! Twice as much value. 1788 # You want me to be verbose? I'll give you two trees! Twice as much value.
1871 if "--tree" in emerge.opts and "--verbose" in emerge.opts: 1789 if "--tree" in emerge.opts and "--verbose" in emerge.opts:
1872 deps.PrintTree(deps_tree) 1790 deps.PrintTree(deps_tree)
1873 1791
1874 deps_graph = deps.GenDependencyGraph(deps_tree, deps_info, remote_pkgs) 1792 deps_graph = deps.GenDependencyGraph(deps_tree, deps_info, remote_pkgs)
1875 1793
1876 # OK, time to print out our progress so far. 1794 # OK, time to print out our progress so far.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1920 # need to upgrade the rest of the packages. So we'll go ahead and do that. 1838 # need to upgrade the rest of the packages. So we'll go ahead and do that.
1921 if portage_upgrade: 1839 if portage_upgrade:
1922 args = sys.argv[1:] + ["--nomerge=sys-apps/portage"] 1840 args = sys.argv[1:] + ["--nomerge=sys-apps/portage"]
1923 os.execvp(os.path.realpath(sys.argv[0]), args) 1841 os.execvp(os.path.realpath(sys.argv[0]), args)
1924 1842
1925 print "Done" 1843 print "Done"
1926 sys.exit(0) 1844 sys.exit(0)
1927 1845
1928 if __name__ == "__main__": 1846 if __name__ == "__main__":
1929 main() 1847 main()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698