aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2010-02-27 04:07:39 +0000
committerZac Medico <zmedico@gentoo.org>2010-02-27 04:07:39 +0000
commit92a9759a0ce171e7980b1f155f18121d14b00bd8 (patch)
treeb39d5dddc4923ff0428370c697f15ebd6cdbbb27 /pym/portage/_global_updates.py
parentRemove unused 'dircache' variable that's moved to portage.util.listdir. (diff)
downloadportage-92a9759a0ce171e7980b1f155f18121d14b00bd8.tar.gz
portage-92a9759a0ce171e7980b1f155f18121d14b00bd8.tar.bz2
portage-92a9759a0ce171e7980b1f155f18121d14b00bd8.zip
Move portage._global_updates to a submodule.
svn path=/main/trunk/; revision=15475
Diffstat (limited to 'pym/portage/_global_updates.py')
-rw-r--r--pym/portage/_global_updates.py152
1 files changed, 152 insertions, 0 deletions
diff --git a/pym/portage/_global_updates.py b/pym/portage/_global_updates.py
new file mode 100644
index 000000000..baf2e9b72
--- /dev/null
+++ b/pym/portage/_global_updates.py
@@ -0,0 +1,152 @@
+# Copyright 2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+from __future__ import print_function
+
+import stat
+
+from portage import os
+from portage.const import WORLD_FILE
+from portage.data import secpass
+from portage.exception import DirectoryNotFound
+from portage.localization import _
+from portage.output import bold, colorize
+from portage.update import grab_updates, parse_updates, update_config_files, update_dbentry
+from portage.util import grabfile, writemsg, writemsg_stdout, write_atomic
+
+def _global_updates(trees, prev_mtimes):
+ """
+ Perform new global updates if they exist in $PORTDIR/profiles/updates/.
+
+ @param trees: A dictionary containing portage trees.
+ @type trees: dict
+ @param prev_mtimes: A dictionary containing mtimes of files located in
+ $PORTDIR/profiles/updates/.
+ @type prev_mtimes: dict
+ @rtype: None or List
+ @return: None if no were no updates, otherwise a list of update commands
+ that have been performed.
+ """
+ # only do this if we're root and not running repoman/ebuild digest
+
+ if secpass < 2 or "SANDBOX_ACTIVE" in os.environ:
+ return
+ root = "/"
+ mysettings = trees["/"]["vartree"].settings
+ updpath = os.path.join(mysettings["PORTDIR"], "profiles", "updates")
+
+ try:
+ if mysettings["PORTAGE_CALLER"] == "fixpackages":
+ update_data = grab_updates(updpath)
+ else:
+ update_data = grab_updates(updpath, prev_mtimes)
+ except DirectoryNotFound:
+ writemsg(_("--- 'profiles/updates' is empty or "
+ "not available. Empty portage tree?\n"), noiselevel=1)
+ return
+ myupd = None
+ if len(update_data) > 0:
+ do_upgrade_packagesmessage = 0
+ myupd = []
+ timestamps = {}
+ for mykey, mystat, mycontent in update_data:
+ writemsg_stdout("\n\n")
+ writemsg_stdout(colorize("GOOD",
+ _("Performing Global Updates: "))+bold(mykey)+"\n")
+ writemsg_stdout(_("(Could take a couple of minutes if you have a lot of binary packages.)\n"))
+ writemsg_stdout(_(" %s='update pass' %s='binary update' "
+ "%s='/var/db update' %s='/var/db move'\n"
+ " %s='/var/db SLOT move' %s='binary move' "
+ "%s='binary SLOT move'\n %s='update /etc/portage/package.*'\n") % \
+ (bold("."), bold("*"), bold("#"), bold("@"), bold("s"), bold("%"), bold("S"), bold("p")))
+ valid_updates, errors = parse_updates(mycontent)
+ myupd.extend(valid_updates)
+ writemsg_stdout(len(valid_updates) * "." + "\n")
+ if len(errors) == 0:
+ # Update our internal mtime since we
+ # processed all of our directives.
+ timestamps[mykey] = mystat[stat.ST_MTIME]
+ else:
+ for msg in errors:
+ writemsg("%s\n" % msg, noiselevel=-1)
+
+ world_file = os.path.join(root, WORLD_FILE)
+ world_list = grabfile(world_file)
+ world_modified = False
+ for update_cmd in myupd:
+ for pos, atom in enumerate(world_list):
+ new_atom = update_dbentry(update_cmd, atom)
+ if atom != new_atom:
+ world_list[pos] = new_atom
+ world_modified = True
+ if world_modified:
+ world_list.sort()
+ write_atomic(world_file,
+ "".join("%s\n" % (x,) for x in world_list))
+
+ update_config_files("/",
+ mysettings.get("CONFIG_PROTECT","").split(),
+ mysettings.get("CONFIG_PROTECT_MASK","").split(),
+ myupd)
+
+ vardb = trees["/"]["vartree"].dbapi
+ bindb = trees["/"]["bintree"].dbapi
+ if not os.access(bindb.bintree.pkgdir, os.W_OK):
+ bindb = None
+ for update_cmd in myupd:
+ if update_cmd[0] == "move":
+ moves = vardb.move_ent(update_cmd)
+ if moves:
+ writemsg_stdout(moves * "@")
+ if bindb:
+ moves = bindb.move_ent(update_cmd)
+ if moves:
+ writemsg_stdout(moves * "%")
+ elif update_cmd[0] == "slotmove":
+ moves = vardb.move_slot_ent(update_cmd)
+ if moves:
+ writemsg_stdout(moves * "s")
+ if bindb:
+ moves = bindb.move_slot_ent(update_cmd)
+ if moves:
+ writemsg_stdout(moves * "S")
+
+ # The above global updates proceed quickly, so they
+ # are considered a single mtimedb transaction.
+ if len(timestamps) > 0:
+ # We do not update the mtime in the mtimedb
+ # until after _all_ of the above updates have
+ # been processed because the mtimedb will
+ # automatically commit when killed by ctrl C.
+ for mykey, mtime in timestamps.items():
+ prev_mtimes[mykey] = mtime
+
+ # We gotta do the brute force updates for these now.
+ if mysettings["PORTAGE_CALLER"] == "fixpackages" or \
+ "fixpackages" in mysettings.features:
+ def onUpdate(maxval, curval):
+ if curval > 0:
+ writemsg_stdout("#")
+ vardb.update_ents(myupd, onUpdate=onUpdate)
+ if bindb:
+ def onUpdate(maxval, curval):
+ if curval > 0:
+ writemsg_stdout("*")
+ bindb.update_ents(myupd, onUpdate=onUpdate)
+ else:
+ do_upgrade_packagesmessage = 1
+
+ # Update progress above is indicated by characters written to stdout so
+ # we print a couple new lines here to separate the progress output from
+ # what follows.
+ print()
+ print()
+
+ if do_upgrade_packagesmessage and bindb and \
+ bindb.cpv_all():
+ writemsg_stdout(_(" ** Skipping packages. Run 'fixpackages' or set it in FEATURES to fix the tbz2's in the packages directory.\n"))
+ writemsg_stdout(bold(_("Note: This can take a very long time.")))
+ writemsg_stdout("\n")
+ if myupd:
+ return myupd