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

Side by Side Diff: parallel_emerge

Issue 4552007: Update parallel_emerge to correct use flags, fixing a regression. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/crosutils.git
Patch Set: Created 10 years, 1 month 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 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 457
458 # Grab the set of flags that are requested for the given package. 458 # Grab the set of flags that are requested for the given package.
459 # This includes flags that don't affect the package, and includes 459 # This includes flags that don't affect the package, and includes
460 # all sources of flags (e.g. USE environment variable, make.conf, 460 # all sources of flags (e.g. USE environment variable, make.conf,
461 # make.defaults, package.use.{mask,force}, etc.). 461 # make.defaults, package.use.{mask,force}, etc.).
462 # 462 #
463 # This is used by portage in the _reinstall_for_flags function below. 463 # This is used by portage in the _reinstall_for_flags function below.
464 forced_flags = set(pkgsettings.useforce).union(pkgsettings.usemask) 464 forced_flags = set(pkgsettings.useforce).union(pkgsettings.usemask)
465 465
466 depgraph = self.emerge.depgraph 466 depgraph = self.emerge.depgraph
467
468 flags = depgraph._reinstall_for_flags(forced_flags, cur_use, 467 flags = depgraph._reinstall_for_flags(forced_flags, cur_use,
469 cur_iuse, now_use, now_iuse) 468 cur_iuse, now_use, now_iuse)
470 return not flags 469 return not flags
471 470
472 def GenDependencyTree(self, remote_pkgs): 471 def GenDependencyTree(self, remote_pkgs):
473 """Get dependency tree info from emerge. 472 """Get dependency tree info from emerge.
474 473
475 TODO(): Update cros_extract_deps to also use this code. 474 TODO(): Update cros_extract_deps to also use this code.
476 Returns: 475 Returns:
477 Dependency tree 476 Dependency tree
478 """ 477 """
479 start = time.time() 478 start = time.time()
480 479
481 # Setup emerge options. 480 # Setup emerge options.
482 # 481 #
483 # We treat dependency info a bit differently than emerge itself. Unless 482 # We treat dependency info a bit differently than emerge itself. Unless
484 # you're using --usepkgonly, we disable --getbinpkg and --usepkg here so 483 # you're using --usepkgonly, we disable --getbinpkg and --usepkg here so
485 # that emerge will look at the dependencies of the source ebuilds rather 484 # that emerge will look at the dependencies of the source ebuilds rather
486 # than the binary dependencies. This helps ensure that we have the option 485 # than the binary dependencies. This helps ensure that we have the option
487 # of merging a package from source, if we want to switch to it with 486 # of merging a package from source, if we want to switch to it with
488 # --workon and the dependencies have changed. 487 # --workon and the dependencies have changed.
489 emerge = self.emerge 488 emerge = self.emerge
490 emerge_opts = emerge.opts.copy() 489 emerge_opts = emerge.opts.copy()
491 if self.mandatory_source or self.rebuild or self.force_remote_binary:
492 # Enable --emptytree so that we get the full tree, which we need for
493 # dependency analysis. By default, with this option, emerge optimizes
494 # the graph by removing uninstall instructions from the graph. By
495 # specifying --tree as well, we tell emerge that it's not safe to remove
496 # uninstall instructions because we're planning on analyzing the output.
497 emerge_opts["--tree"] = True
498 emerge_opts["--emptytree"] = True
499 490
500 # Tell emerge not to worry about use flags yet. We handle those inside 491 # Enable --emptytree so that we get the full tree, which we need for
501 # parallel_emerge itself. Further, when we use the --force-remote-binary 492 # dependency analysis. By default, with this option, emerge optimizes
502 # flag, we don't emerge to reject a package just because it has different 493 # the graph by removing uninstall instructions from the graph. By
503 # use flags. 494 # specifying --tree as well, we tell emerge that it's not safe to remove
504 emerge_opts.pop("--newuse", None) 495 # uninstall instructions because we're planning on analyzing the output.
505 emerge_opts.pop("--reinstall", None) 496 emerge_opts["--tree"] = True
497 emerge_opts["--emptytree"] = True
498
499 # Tell emerge not to worry about use flags yet. We handle those inside
500 # parallel_emerge itself. Further, when we use the --force-remote-binary
501 # flag, we don't emerge to reject a package just because it has different
502 # use flags.
503 emerge_opts.pop("--newuse", None)
504 emerge_opts.pop("--reinstall", None)
506 505
507 # Create a list of packages to merge 506 # Create a list of packages to merge
508 packages = set(emerge.cmdline_packages[:]) 507 packages = set(emerge.cmdline_packages[:])
509 if self.mandatory_source: 508 if self.mandatory_source:
510 packages.update(self.mandatory_source) 509 packages.update(self.mandatory_source)
511 if self.force_remote_binary: 510 if self.force_remote_binary:
512 forced_pkgs = {} 511 forced_pkgs = {}
513 for pkg in remote_pkgs: 512 for pkg in remote_pkgs:
514 category, pkgname, _, _ = portage.catpkgsplit(pkg) 513 category, pkgname, _, _ = portage.catpkgsplit(pkg)
515 full_pkgname = "%s/%s" % (category, pkgname) 514 full_pkgname = "%s/%s" % (category, pkgname)
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 585
587 # Ask portage for its install plan, so that we can only throw out 586 # Ask portage for its install plan, so that we can only throw out
588 # dependencies that portage throws out. Also, keep track of the old 587 # dependencies that portage throws out. Also, keep track of the old
589 # versions of packages that we're either upgrading or replacing. 588 # versions of packages that we're either upgrading or replacing.
590 # 589 #
591 # The "vardb" is the database of installed packages. 590 # The "vardb" is the database of installed packages.
592 root = emerge.settings["ROOT"] 591 root = emerge.settings["ROOT"]
593 frozen_config = depgraph._frozen_config 592 frozen_config = depgraph._frozen_config
594 vardb = frozen_config.trees[root]["vartree"].dbapi 593 vardb = frozen_config.trees[root]["vartree"].dbapi
595 pkgsettings = frozen_config.pkgsettings[root] 594 pkgsettings = frozen_config.pkgsettings[root]
595
596 # It's time to start worrying about use flags, if necessary.
597 for flag in ("--newuse", "--reinstall"):
598 if flag in emerge.opts:
599 emerge_opts[flag] = emerge.opts[flag]
600
596 deps_info = {} 601 deps_info = {}
597 for pkg in depgraph.altlist(): 602 for pkg in depgraph.altlist():
598 if isinstance(pkg, Package): 603 if isinstance(pkg, Package):
604 # If we're not using --force-remote-binary, check what flags are being
605 # used by the real package.
606 if "--usepkgonly" not in emerge.opts:
607 try:
608 pkg = emerge.depgraph._pkg(pkg.cpv, "ebuild", emerge.root_config)
609 except portage.exception.PackageNotFound:
610 # This is a --force-remote-binary package.
611 pass
612 self.package_db[pkg.cpv] = pkg
613
599 # If we're not in emptytree mode, and we're going to replace a package 614 # If we're not in emptytree mode, and we're going to replace a package
600 # that is already installed, then this operation is possibly optional. 615 # that is already installed, then this operation is possibly optional.
601 # ("--selective" mode is handled later, in RemoveInstalledPackages()) 616 # ("--selective" mode is handled later, in RemoveInstalledPackages())
602 optional = False 617 optional = False
603 if not emptytree: 618 if not emptytree:
604 for vardb_pkg in vardb.match_pkgs(pkg.cpv): 619 for vardb_pkg in vardb.match_pkgs(pkg.cpv):
605 if self.CheckUseFlags(pkgsettings, vardb_pkg, pkg): 620 if self.CheckUseFlags(pkgsettings, vardb_pkg, pkg):
606 optional = True 621 optional = True
607 break 622 break
608 623
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
1142 mtime = int(db_vals.pop() or 0) 1157 mtime = int(db_vals.pop() or 0)
1143 metadata = zip(db_keys, db_vals) 1158 metadata = zip(db_keys, db_vals)
1144 db_pkg = Package(built=True, cpv=pkg, installed=False, 1159 db_pkg = Package(built=True, cpv=pkg, installed=False,
1145 metadata=metadata, onlydeps=False, mtime=mtime, 1160 metadata=metadata, onlydeps=False, mtime=mtime,
1146 operation="merge", root_config=root_config, 1161 operation="merge", root_config=root_config,
1147 type_name="binary") 1162 type_name="binary")
1148 prebuilt_pkgs[pkg] = db_pkg 1163 prebuilt_pkgs[pkg] = db_pkg
1149 1164
1150 # Calculate what packages need to be rebuilt due to changes in use flags. 1165 # Calculate what packages need to be rebuilt due to changes in use flags.
1151 for pkg, db_pkg in prebuilt_pkgs.iteritems(): 1166 for pkg, db_pkg in prebuilt_pkgs.iteritems():
1152 db_pkg_src = self.package_db.get(pkg) 1167 if not self.CheckUseFlags(pkgsettings, db_pkg, self.package_db[pkg]):
1153 if db_pkg_src and not self.CheckUseFlags(pkgsettings, db_pkg,
1154 db_pkg_src):
1155 MergeChildren(pkg, "mandatory_source") 1168 MergeChildren(pkg, "mandatory_source")
1156 1169
1157 # Convert eligible packages to binaries. 1170 # Convert eligible packages to binaries.
1158 for pkg, info in deps_map.iteritems(): 1171 for pkg, info in deps_map.iteritems():
1159 if info and info["action"] == "merge" and pkg in prebuilt_pkgs: 1172 if info and info["action"] == "merge" and pkg in prebuilt_pkgs:
1160 if not info["mandatory_source"] or info["force_remote_binary"]: 1173 if not info["mandatory_source"] or info["force_remote_binary"]:
1161 self.package_db[pkg] = prebuilt_pkgs[pkg] 1174 self.package_db[pkg] = prebuilt_pkgs[pkg]
1162 1175
1163 seconds = time.time() - start 1176 seconds = time.time() - start
1164 if "--quiet" not in emerge.opts: 1177 if "--quiet" not in emerge.opts:
1165 print "Prebuilt DB populated in %dm%.1fs" % (seconds / 60, seconds % 60) 1178 print "Prebuilt DB populated in %dm%.1fs" % (seconds / 60, seconds % 60)
1166 1179
1167 return prebuilt_pkgs 1180 return prebuilt_pkgs
1168 1181
1169 def AddRemainingPackages():
1170 """Fill in packages that don't have entries in the package db.
1171
1172 Every package we are installing needs an entry in the package db.
1173 This function should only be called after we have removed the
1174 packages that are not being merged from our deps_map.
1175 """
1176 for pkg in deps_map:
1177 if pkg not in self.package_db:
1178 if deps_map[pkg]["action"] != "merge":
1179 # We should only fill in packages that are being merged. If
1180 # there's any other packages here, something funny is going on.
1181 print "Missing entry for %s in package db" % pkg
1182 sys.exit(1)
1183
1184 db_pkg = emerge.depgraph._pkg(pkg, "ebuild", emerge.root_config)
1185 self.package_db[pkg] = db_pkg
1186
1187 ReverseTree(deps_tree) 1182 ReverseTree(deps_tree)
1188 BuildFinalPackageSet() 1183 BuildFinalPackageSet()
1189 AddSecretDeps() 1184 AddSecretDeps()
1190 1185
1191 # Mark that we want to use remote binaries only for a particular package. 1186 # Mark that we want to use remote binaries only for a particular package.
1192 vardb = emerge.depgraph._frozen_config.trees[root]["vartree"].dbapi 1187 vardb = emerge.depgraph._frozen_config.trees[root]["vartree"].dbapi
1193 for pkg in self.force_remote_binary: 1188 for pkg in self.force_remote_binary:
1194 for db_pkg in final_db.match_pkgs(pkg): 1189 for db_pkg in final_db.match_pkgs(pkg):
1195 match = deps_map.get(str(db_pkg.cpv)) 1190 match = deps_map.get(str(db_pkg.cpv))
1196 if match: 1191 if match:
(...skipping 19 matching lines...) Expand all
1216 1211
1217 # We need to remove installed packages so that we can use the dependency 1212 # We need to remove installed packages so that we can use the dependency
1218 # ordering of the install process to show us what cycles to crack. Once 1213 # ordering of the install process to show us what cycles to crack. Once
1219 # we've done that, we also need to recalculate our list of cycles so that 1214 # we've done that, we also need to recalculate our list of cycles so that
1220 # we don't include the installed packages in our cycles. 1215 # we don't include the installed packages in our cycles.
1221 RemoveInstalledPackages() 1216 RemoveInstalledPackages()
1222 SanitizeTree() 1217 SanitizeTree()
1223 if deps_map: 1218 if deps_map:
1224 if "--usepkg" in emerge.opts: 1219 if "--usepkg" in emerge.opts:
1225 UsePrebuiltPackages(remote_pkgs) 1220 UsePrebuiltPackages(remote_pkgs)
1226 AddRemainingPackages()
1227 return deps_map 1221 return deps_map
1228 1222
1229 def PrintInstallPlan(self, deps_map): 1223 def PrintInstallPlan(self, deps_map):
1230 """Print an emerge-style install plan. 1224 """Print an emerge-style install plan.
1231 1225
1232 The install plan lists what packages we're installing, in order. 1226 The install plan lists what packages we're installing, in order.
1233 It's useful for understanding what parallel_emerge is doing. 1227 It's useful for understanding what parallel_emerge is doing.
1234 1228
1235 Args: 1229 Args:
1236 deps_map: The dependency graph. 1230 deps_map: The dependency graph.
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after
1836 # need to upgrade the rest of the packages. So we'll go ahead and do that. 1830 # need to upgrade the rest of the packages. So we'll go ahead and do that.
1837 if portage_upgrade: 1831 if portage_upgrade:
1838 args = sys.argv[1:] + ["--nomerge=sys-apps/portage"] 1832 args = sys.argv[1:] + ["--nomerge=sys-apps/portage"]
1839 os.execvp(os.path.realpath(sys.argv[0]), args) 1833 os.execvp(os.path.realpath(sys.argv[0]), args)
1840 1834
1841 print "Done" 1835 print "Done"
1842 sys.exit(0) 1836 sys.exit(0)
1843 1837
1844 if __name__ == "__main__": 1838 if __name__ == "__main__":
1845 main() 1839 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