From: Fabian Groffen Date: Sun, 28 Feb 2010 14:18:21 +0000 (-0000) Subject: Merged from trunk -r15489:15493 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=2efa6394e59af20b3122a639fc3fe4423fcba692;p=portage.git Merged from trunk -r15489:15493 | 15490 | Move the MtimeDB class to portage.util.mtimedb and deprecate | | zmedico | the commit_mtimedb function. | | 15491 | Move deprecated_profile_check to portage.package.ebuild | | zmedico | submodule. | | 15492 | Move legacy globals code into a _legacy_globals module | | zmedico | that's imported on demand. | | 15493 | Fix broken fakedbapi.cpv_inject/cpv_remove calls. | | zmedico | | svn path=/main/branches/prefix/; revision=15499 --- diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 670ef204d..e7c9a04d4 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -107,6 +107,8 @@ try: 'doebuild_environment,spawn,spawnebuild', 'portage.package.ebuild.config:autouse,best_from_dict,' + \ 'check_config_instance,config', + 'portage.package.ebuild.deprecated_profile_check:' + \ + 'deprecated_profile_check', 'portage.package.ebuild.digestcheck:digestcheck', 'portage.package.ebuild.digestgen:digestgen', 'portage.package.ebuild.fetch:fetch', @@ -131,12 +133,14 @@ try: 'portage.util.ExtractKernelVersion:ExtractKernelVersion', 'portage.util.listdir:cacheddir,listdir', 'portage.util.movefile:movefile', + 'portage.util.mtimedb:MtimeDB', 'portage.versions', 'portage.versions:best,catpkgsplit,catsplit,cpv_getkey,' + \ 'cpv_getkey@getCPFromCPV,endversion_keys,' + \ 'suffix_value@endversion,pkgcmp,pkgsplit,vercmp,ververify', 'portage.xpak', - 'portage._deprecated:dep_virtual,digestParseFile,getvirtuals,pkgmerge', + 'portage._deprecated:commit_mtimedb,dep_virtual,' + \ + 'digestParseFile,getvirtuals,pkgmerge', ) import portage.const @@ -504,122 +508,18 @@ auxdbkeys = ( ) auxdbkeylen=len(auxdbkeys) -def deprecated_profile_check(settings=None): - config_root = "/" - if settings is not None: - config_root = settings["PORTAGE_CONFIGROOT"] - deprecated_profile_file = os.path.join(config_root, - DEPRECATED_PROFILE_FILE) - if not os.access(deprecated_profile_file, os.R_OK): - return False - dcontent = codecs.open(_unicode_encode(deprecated_profile_file, - encoding=_encodings['fs'], errors='strict'), - mode='r', encoding=_encodings['content'], errors='replace').readlines() - writemsg(colorize("BAD", _("\n!!! Your current profile is " - "deprecated and not supported anymore.")) + "\n", noiselevel=-1) - writemsg(colorize("BAD", _("!!! Use eselect profile to update your " - "profile.")) + "\n", noiselevel=-1) - if not dcontent: - writemsg(colorize("BAD", _("!!! Please refer to the " - "Gentoo Upgrading Guide.")) + "\n", noiselevel=-1) - return True - newprofile = dcontent[0] - writemsg(colorize("BAD", _("!!! Please upgrade to the " - "following profile if possible:")) + "\n", noiselevel=-1) - writemsg(8*" " + colorize("GOOD", newprofile) + "\n", noiselevel=-1) - if len(dcontent) > 1: - writemsg(_("To upgrade do the following steps:\n"), noiselevel=-1) - for myline in dcontent[1:]: - writemsg(myline, noiselevel=-1) - writemsg("\n\n", noiselevel=-1) - return True - -def commit_mtimedb(mydict=None, filename=None): - if mydict is None: - global mtimedb - if "mtimedb" not in globals() or mtimedb is None: - return - mtimedb.commit() - return - if filename is None: - global mtimedbfile - filename = mtimedbfile - mydict["version"] = VERSION - d = {} # for full backward compat, pickle it as a plain dict object. - d.update(mydict) - try: - f = atomic_ofstream(filename, mode='wb') - pickle.dump(d, f, protocol=2) - f.close() - portage.util.apply_secpass_permissions(filename, - uid=uid, gid=portage_gid, mode=0o644) - except (IOError, OSError) as e: - pass - def portageexit(): - global uid,portage_gid,portdb,db - if secpass and os.environ.get("SANDBOX_ON") != "1": + if secpass > 1 and os.environ.get("SANDBOX_ON") != "1": close_portdbapi_caches() - commit_mtimedb() + try: + mtimedb + except NameError: + pass + else: + mtimedb.commit() atexit_register(portageexit) -class MtimeDB(dict): - def __init__(self, filename): - dict.__init__(self) - self.filename = filename - self._load(filename) - - def _load(self, filename): - try: - f = open(_unicode_encode(filename), 'rb') - mypickle = pickle.Unpickler(f) - try: - mypickle.find_global = None - except AttributeError: - # TODO: If py3k, override Unpickler.find_class(). - pass - d = mypickle.load() - f.close() - del f - except (IOError, OSError, EOFError, ValueError, pickle.UnpicklingError) as e: - if isinstance(e, pickle.UnpicklingError): - writemsg(_("!!! Error loading '%s': %s\n") % \ - (filename, str(e)), noiselevel=-1) - del e - d = {} - - if "old" in d: - d["updates"] = d["old"] - del d["old"] - if "cur" in d: - del d["cur"] - - d.setdefault("starttime", 0) - d.setdefault("version", "") - for k in ("info", "ldpath", "updates"): - d.setdefault(k, {}) - - mtimedbkeys = set(("info", "ldpath", "resume", "resume_backup", - "starttime", "updates", "version")) - - for k in list(d): - if k not in mtimedbkeys: - writemsg(_("Deleting invalid mtimedb key: %s\n") % str(k)) - del d[k] - self.update(d) - self._clean_data = copy.deepcopy(d) - - def commit(self): - if not self.filename: - return - d = {} - d.update(self) - # Only commit if the internal state has changed. - if d != self._clean_data: - commit_mtimedb(mydict=d, filename=self.filename) - self._clean_data = copy.deepcopy(d) - def create_trees(config_root=None, target_root=None, trees=None): if trees is None: trees = {} @@ -663,10 +563,6 @@ def create_trees(config_root=None, target_root=None, trees=None): return trees class _LegacyGlobalProxy(proxy.objectproxy.ObjectProxy): - """ - Instances of these serve as proxies to global variables - that are initialized on demand. - """ __slots__ = ('_name',) @@ -675,53 +571,19 @@ class _LegacyGlobalProxy(proxy.objectproxy.ObjectProxy): object.__setattr__(self, '_name', name) def _get_target(self): - init_legacy_globals() name = object.__getattribute__(self, '_name') - return globals()[name] - -class _PortdbProxy(proxy.objectproxy.ObjectProxy): - """ - The portdb is initialized separately from the rest - of the variables, since sometimes the other variables - are needed while the portdb is not. - """ - - __slots__ = () - - def _get_target(self): - init_legacy_globals() - global db, portdb, root, _portdb_initialized - if not _portdb_initialized: - portdb = db[root]["porttree"].dbapi - _portdb_initialized = True - return portdb - -class _MtimedbProxy(proxy.objectproxy.ObjectProxy): - """ - The mtimedb is independent from the portdb and other globals. - """ - - __slots__ = ('_name',) - - def __init__(self, name): - proxy.objectproxy.ObjectProxy.__init__(self) - object.__setattr__(self, '_name', name) - - def _get_target(self): - global mtimedb, mtimedbfile, _mtimedb_initialized - if not _mtimedb_initialized: - mtimedbfile = os.path.join(os.path.sep, - CACHE_PATH, "mtimedb") - mtimedb = MtimeDB(mtimedbfile) - _mtimedb_initialized = True - name = object.__getattribute__(self, '_name') - return globals()[name] + from portage._legacy_globals import _get_legacy_global + return _get_legacy_global(name) _legacy_global_var_names = ("archlist", "db", "features", "groups", "mtimedb", "mtimedbfile", "pkglines", "portdb", "profiledir", "root", "selinux_enabled", "settings", "thirdpartymirrors", "usedefaults") +for k in _legacy_global_var_names: + globals()[k] = _LegacyGlobalProxy(k) +del k + def _disable_legacy_globals(): """ This deletes the ObjectProxy instances that are used @@ -732,80 +594,3 @@ def _disable_legacy_globals(): global _legacy_global_var_names for k in _legacy_global_var_names: globals().pop(k, None) - -# Initialization of legacy globals. No functions/classes below this point -# please! When the above functions and classes become independent of the -# below global variables, it will be possible to make the below code -# conditional on a backward compatibility flag (backward compatibility could -# be disabled via an environment variable, for example). This will enable new -# code that is aware of this flag to import portage without the unnecessary -# overhead (and other issues!) of initializing the legacy globals. - -def init_legacy_globals(): - global _globals_initialized - if _globals_initialized: - return - _globals_initialized = True - - global db, settings, root, portdb, selinux_enabled, mtimedbfile, mtimedb, \ - archlist, features, groups, pkglines, thirdpartymirrors, usedefaults, \ - profiledir - - # Portage needs to ensure a sane umask for the files it creates. - os.umask(0o22) - - kwargs = {} - kwargs["config_root"] = os.environ.get("PORTAGE_CONFIGROOT", EPREFIX + "/") - kwargs["target_root"] = os.environ.get("ROOT", "/") - - global _initializing_globals - _initializing_globals = True - db = create_trees(**kwargs) - del _initializing_globals - - settings = db["/"]["vartree"].settings - - for myroot in db: - if myroot != "/": - settings = db[myroot]["vartree"].settings - break - - root = settings["ROOT"] - output._init(config_root=settings['PORTAGE_CONFIGROOT']) - - # ======================================================================== - # COMPATIBILITY - # These attributes should not be used - # within Portage under any circumstances. - # ======================================================================== - archlist = settings.archlist() - features = settings.features - groups = settings["ACCEPT_KEYWORDS"].split() - pkglines = settings.packages - selinux_enabled = settings.selinux_enabled() - thirdpartymirrors = settings.thirdpartymirrors() - usedefaults = settings.use_defs - profiledir = os.path.join(settings["PORTAGE_CONFIGROOT"], PROFILE_PATH) - if not os.path.isdir(profiledir): - profiledir = None - # ======================================================================== - # COMPATIBILITY - # These attributes should not be used - # within Portage under any circumstances. - # ======================================================================== - -if True: - - _mtimedb_initialized = False - mtimedb = _MtimedbProxy("mtimedb") - mtimedbfile = _MtimedbProxy("mtimedbfile") - - _portdb_initialized = False - portdb = _PortdbProxy() - - _globals_initialized = False - - for k in ("db", "settings", "root", "selinux_enabled", - "archlist", "features", "groups", - "pkglines", "thirdpartymirrors", "usedefaults", "profiledir"): - globals()[k] = _LegacyGlobalProxy(k) diff --git a/pym/portage/_deprecated.py b/pym/portage/_deprecated.py index a2b5331d5..0a94ddc8a 100644 --- a/pym/portage/_deprecated.py +++ b/pym/portage/_deprecated.py @@ -16,6 +16,11 @@ from portage.localization import _ from portage.manifest import Manifest from portage.util import writemsg, writemsg_stdout +def commit_mtimedb(mydict=None, filename=None): + warnings.warn("portage.commit_mtimedb() is deprecated, " + \ + "use portage.mtimedb.commit() instead", + DeprecationWarning, stacklevel=2) + def digestParseFile(myfilename, mysettings=None): """(filename) -- Parses a given file for entries matching: diff --git a/pym/portage/_legacy_globals.py b/pym/portage/_legacy_globals.py new file mode 100644 index 000000000..f524cbe38 --- /dev/null +++ b/pym/portage/_legacy_globals.py @@ -0,0 +1,87 @@ +# Copyright 2010 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +import portage +from portage import os +from portage.const import CACHE_PATH, PROFILE_PATH + +_legacy_globals = {} + +def _get_legacy_global(name): + global _legacy_globals + target = _legacy_globals.get(name, _legacy_globals) + if target is not _legacy_globals: + return target + + if name == 'portdb': + portage.portdb = portage.db[portage.root]["porttree"].dbapi + _legacy_globals[name] = portage.portdb + return _legacy_globals[name] + elif name in ('mtimedb', 'mtimedbfile'): + portage.mtimedbfile = os.path.join(portage.root, + CACHE_PATH, "mtimedb") + _legacy_globals['mtimedbfile'] = portage.mtimedbfile + portage.mtimedb = portage.MtimeDB(portage.mtimedbfile) + _legacy_globals['mtimedb'] = portage.mtimedb + return _legacy_globals[name] + + # Portage needs to ensure a sane umask for the files it creates. + os.umask(0o22) + + kwargs = {} + kwargs["config_root"] = os.environ.get("PORTAGE_CONFIGROOT", EPREFIX + "/") + kwargs["target_root"] = os.environ.get("ROOT", "/") + + portage._initializing_globals = True + portage.db = portage.create_trees(**kwargs) + _legacy_globals['db'] = portage.db + del portage._initializing_globals + + settings = portage.db["/"]["vartree"].settings + + for root in portage.db: + if root != "/": + settings = portage.db[root]["vartree"].settings + break + + portage.output._init(config_root=settings['PORTAGE_CONFIGROOT']) + + portage.settings = settings + _legacy_globals['settings'] = settings + + portage.root = root + _legacy_globals['root'] = root + + # COMPATIBILITY + # These attributes should not be used within + # Portage under any circumstances. + + portage.archlist = settings.archlist() + _legacy_globals['archlist'] = portage.archlist + + portage.features = settings.features + _legacy_globals['features'] = portage.features + + portage.groups = settings["ACCEPT_KEYWORDS"].split() + _legacy_globals['groups'] = portage.groups + + portage.pkglines = settings.packages + _legacy_globals['pkglines'] = portage.pkglines + + portage.selinux_enabled = settings.selinux_enabled() + _legacy_globals['selinux_enabled'] = portage.selinux_enabled + + portage.thirdpartymirrors = settings.thirdpartymirrors() + _legacy_globals['thirdpartymirrors'] = portage.thirdpartymirrors + + portage.usedefaults = settings.use_defs + _legacy_globals['usedefaults'] = portage.usedefaults + + profiledir = os.path.join(settings["PORTAGE_CONFIGROOT"], PROFILE_PATH) + if not os.path.isdir(profiledir): + profiledir = None + portage.profiledir = profiledir + _legacy_globals['profiledir'] = portage.profiledir + + return _legacy_globals[name] diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py index 6a5a4f862..6e5519eef 100644 --- a/pym/portage/dbapi/bintree.py +++ b/pym/portage/dbapi/bintree.py @@ -69,11 +69,11 @@ class bindbapi(fakedbapi): def cpv_inject(self, cpv, **kwargs): self._aux_cache.pop(cpv, None) - fakedbapi.cpv_inject(cpv, **kwargs) + fakedbapi.cpv_inject(self, cpv, **kwargs) def cpv_remove(self, cpv): self._aux_cache.pop(cpv, None) - fakedbapi.cpv_remove(cpv) + fakedbapi.cpv_remove(self, cpv) def aux_get(self, mycpv, wants): if self.bintree and not self.bintree.populated: diff --git a/pym/portage/package/ebuild/deprecated_profile_check.py b/pym/portage/package/ebuild/deprecated_profile_check.py new file mode 100644 index 000000000..b3f99f5fe --- /dev/null +++ b/pym/portage/package/ebuild/deprecated_profile_check.py @@ -0,0 +1,43 @@ +# Copyright 2010 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +__all__ = ['deprecated_profile_check'] + +import codecs + +from portage import os, _encodings, _unicode_encode +from portage.const import DEPRECATED_PROFILE_FILE +from portage.localization import _ +from portage.output import colorize +from portage.util import writemsg + +def deprecated_profile_check(settings=None): + config_root = "/" + if settings is not None: + config_root = settings["PORTAGE_CONFIGROOT"] + deprecated_profile_file = os.path.join(config_root, + DEPRECATED_PROFILE_FILE) + if not os.access(deprecated_profile_file, os.R_OK): + return False + dcontent = codecs.open(_unicode_encode(deprecated_profile_file, + encoding=_encodings['fs'], errors='strict'), + mode='r', encoding=_encodings['content'], errors='replace').readlines() + writemsg(colorize("BAD", _("\n!!! Your current profile is " + "deprecated and not supported anymore.")) + "\n", noiselevel=-1) + writemsg(colorize("BAD", _("!!! Use eselect profile to update your " + "profile.")) + "\n", noiselevel=-1) + if not dcontent: + writemsg(colorize("BAD", _("!!! Please refer to the " + "Gentoo Upgrading Guide.")) + "\n", noiselevel=-1) + return True + newprofile = dcontent[0] + writemsg(colorize("BAD", _("!!! Please upgrade to the " + "following profile if possible:")) + "\n", noiselevel=-1) + writemsg(8*" " + colorize("GOOD", newprofile) + "\n", noiselevel=-1) + if len(dcontent) > 1: + writemsg(_("To upgrade do the following steps:\n"), noiselevel=-1) + for myline in dcontent[1:]: + writemsg(myline, noiselevel=-1) + writemsg("\n\n", noiselevel=-1) + return True diff --git a/pym/portage/util/mtimedb.py b/pym/portage/util/mtimedb.py new file mode 100644 index 000000000..cbeb1bb8c --- /dev/null +++ b/pym/portage/util/mtimedb.py @@ -0,0 +1,77 @@ +# Copyright 2010 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +__all__ = ['MtimeDB'] + +import copy + +from portage import pickle, VERSION, _unicode_encode +from portage.data import portage_gid, uid +from portage.localization import _ +from portage.util import apply_secpass_permissions, atomic_ofstream, writemsg + +class MtimeDB(dict): + def __init__(self, filename): + dict.__init__(self) + self.filename = filename + self._load(filename) + + def _load(self, filename): + try: + f = open(_unicode_encode(filename), 'rb') + mypickle = pickle.Unpickler(f) + try: + mypickle.find_global = None + except AttributeError: + # TODO: If py3k, override Unpickler.find_class(). + pass + d = mypickle.load() + f.close() + del f + except (IOError, OSError, EOFError, ValueError, pickle.UnpicklingError) as e: + if isinstance(e, pickle.UnpicklingError): + writemsg(_("!!! Error loading '%s': %s\n") % \ + (filename, str(e)), noiselevel=-1) + del e + d = {} + + if "old" in d: + d["updates"] = d["old"] + del d["old"] + if "cur" in d: + del d["cur"] + + d.setdefault("starttime", 0) + d.setdefault("version", "") + for k in ("info", "ldpath", "updates"): + d.setdefault(k, {}) + + mtimedbkeys = set(("info", "ldpath", "resume", "resume_backup", + "starttime", "updates", "version")) + + for k in list(d): + if k not in mtimedbkeys: + writemsg(_("Deleting invalid mtimedb key: %s\n") % str(k)) + del d[k] + self.update(d) + self._clean_data = copy.deepcopy(d) + + def commit(self): + if not self.filename: + return + d = {} + d.update(self) + # Only commit if the internal state has changed. + if d != self._clean_data: + d["version"] = VERSION + try: + f = atomic_ofstream(self.filename, mode='wb') + except EnvironmentError: + pass + else: + pickle.dump(d, f, protocol=2) + f.close() + apply_secpass_permissions(self.filename, + uid=uid, gid=portage_gid, mode=0o644) + self._clean_data = copy.deepcopy(d)