From 5c66b8101162f1d588086c20ced5e2db9de5dcb2 Mon Sep 17 00:00:00 2001 From: Fabio Erculiani Date: Fri, 21 Oct 2011 23:01:37 +0200 Subject: [PATCH] [entropy.client] make possible to enable splitdebug per-package, close bug 2712 --- conf/packages/package.splitdebug.example | 24 +++++++++ lib/entropy/client/interfaces/package.py | 63 +++++++++++++++++++++++- lib/entropy/core/settings/base.py | 44 ++++++++++++++++- 3 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 conf/packages/package.splitdebug.example diff --git a/conf/packages/package.splitdebug.example b/conf/packages/package.splitdebug.example new file mode 100644 index 000000000..98a19a939 --- /dev/null +++ b/conf/packages/package.splitdebug.example @@ -0,0 +1,24 @@ +# package.splitdebug example file +# +# In this file you can specify dependencies, one per line, for which you +# would like to have the splitdebug feature turned on. This means that +# if at least one valid entry is listed here, the installation of +# /usr/lib/debug files will be enabled only for it. +# Otherwise, if splitdebug is enabled in client.conf and no entries +# are listed here, splitdebug will be considered enabled for any package. + +# LINE CONSTRUCTION: +# +# See examples below +# NOTE: for inline comments, please use "##" instead of "#" + +# EXAMPLES: +# >=media-libs/foo-1.2.3 +# media-libs/foo +# =media-libs/foo-1.2.3#2.6.23-sabayon-r1 +# media-libs/foo::sabayon-repo +# +# :1 means package with SLOT="1" +# #2.6.23-sabayon-r1 means package with kernel tag = 2.6.23-sabayon-r1 diff --git a/lib/entropy/client/interfaces/package.py b/lib/entropy/client/interfaces/package.py index 1829319f2..723287963 100644 --- a/lib/entropy/client/interfaces/package.py +++ b/lib/entropy/client/interfaces/package.py @@ -3684,6 +3684,38 @@ class Package: # generate metadata dictionary self._generate_metadata() + def _package_splitdebug_enabled(self, pkg_match): + """ + Determine if splitdebug is enabled for the package being installed + or just fetched. This method should be called only if system-wide + splitdebug setting in client.conf is enabled already. + """ + # this is a SystemSettings.CachingList object + split_data = self._settings['splitdebug'] + if not split_data: + # no entries, consider splitdebug always enabled + return True + + pkg_id, pkg_repo = pkg_match + pkg_matches = split_data.get() + if pkg_matches is None: + # compute the package matching then + pkg_matches = set() + for dep in self._settings['splitdebug']: + dep, repo_ids = entropy.dep.dep_get_match_in_repos(dep) + if repo_ids is not None: + if pkg_repo not in repo_ids: + # skip entry, not me + continue + dep_matches, rc = self._entropy.atom_match( + dep, multi_match=True, multi_repo=True) + pkg_matches |= dep_matches + # set cache back + split_data.set(pkg_matches) + # determine if it's enabled then + enabled = pkg_match in pkg_matches + return enabled + def __get_base_metadata(self, action): def get_splitdebug_data(): sys_set_plg_id = \ @@ -3853,6 +3885,18 @@ class Package: self.pkgmeta['edelta_support'] = edelta_support is_package_repo = repository.endswith(etpConst['packagesext']) + # if splitdebug is enabled, check if it's also enabled + # via package.splitdebug + if self.pkgmeta['splitdebug']: + # yeah, this has to affect exported splitdebug setting + # because it is read during package files installation + # Older splitdebug data was in the same package file of + # the actual content. Later on, splitdebug data was moved + # to its own package file that gets downloaded and unpacked + # only if required (if splitdebug is enabled) + self.pkgmeta['splitdebug'] = self._package_splitdebug_enabled( + self._package_match) + # fetch abort function self.pkgmeta['fetch_abort_function'] = \ self.metaopts.get('fetch_abort_function') @@ -4066,6 +4110,13 @@ class Package: if entropy.tools.is_valid_path(fetch_path): self.pkgmeta['fetch_path'] = fetch_path + # if splitdebug is enabled, check if it's also enabled + # via package.splitdebug + splitdebug = self.pkgmeta['splitdebug'] + if splitdebug: + splitdebug = self._package_splitdebug_enabled( + self._package_match) + self.pkgmeta['repository'] = repository self.pkgmeta['idpackage'] = idpackage dbconn = self._entropy.open_repository(repository) @@ -4095,7 +4146,7 @@ class Package: } self.pkgmeta['signatures'] = signatures extra_download = dbconn.retrieveExtraDownload(idpackage) - if not self.pkgmeta['splitdebug']: + if not splitdebug: extra_download = [x for x in extra_download if \ x['type'] != "debug"] self.pkgmeta['extra_download'] = extra_download @@ -4261,7 +4312,15 @@ class Package: idpackage, repository, digest, signatures) extra_downloads = dbconn.retrieveExtraDownload(idpackage) - if not self.pkgmeta['splitdebug']: + + splitdebug = self.pkgmeta['splitdebug'] + # if splitdebug is enabled, check if it's also enabled + # via package.splitdebug + if splitdebug: + splitdebug = self._package_splitdebug_enabled( + (idpackage, repository)) + + if not splitdebug: extra_downloads = [x for x in extra_downloads if \ x['type'] != "debug"] for extra_download in extra_downloads: diff --git a/lib/entropy/core/settings/base.py b/lib/entropy/core/settings/base.py index a6c92a282..2d8df4f55 100644 --- a/lib/entropy/core/settings/base.py +++ b/lib/entropy/core/settings/base.py @@ -50,6 +50,29 @@ class SystemSettings(Singleton, EntropyPluginStore): """ + class CachingList(list): + """ + This object overrides a list, making possible to store + cache information in the same place of the data to be + cached. + """ + def __init__(self, *args, **kwargs): + list.__init__(self, *args, **kwargs) + self.__cache = None + + def get(self): + """ + Get cache object + """ + return self.__cache + + def set(self, cache_obj): + """ + Set cache object + """ + self.__cache = cache_obj + + def init_singleton(self): """ @@ -175,6 +198,7 @@ class SystemSettings(Singleton, EntropyPluginStore): self.__setting_files['unmask'], self.__setting_files['satisfied'], self.__setting_files['system_mask'], + self.__setting_files['splitdebug'], ]) for setting_id, dir_sett, auto_update in self.__setting_dirs.items(): if not auto_update: @@ -220,6 +244,8 @@ class SystemSettings(Singleton, EntropyPluginStore): 'mask': etpConst['confpackagesdir']+"/package.mask", # satisfied packages configuration file 'satisfied': etpConst['confpackagesdir']+"/package.satisfied", + # selectively enable splitdebug for packages + 'splitdebug': etpConst['confpackagesdir']+"/package.splitdebug", # masking configuration files 'license_mask': etpConst['confpackagesdir']+"/license.mask", 'license_accept': etpConst['confpackagesdir']+"/license.accept", @@ -240,7 +266,7 @@ class SystemSettings(Singleton, EntropyPluginStore): 'keywords', 'unmask', 'mask', 'satisfied', 'license_mask', 'license_accept', 'system_mask', 'system_package_sets', 'system_dirs', 'system_dirs_mask', 'extra_ldpaths', - 'system', 'system_rev_symlinks', 'hw_hash', + 'splitdebug', 'system', 'system_rev_symlinks', 'hw_hash', 'broken_syms', 'broken_libs_mask', 'broken_links_mask' ]) self.__setting_files_pre_run.extend(['repositories']) @@ -797,6 +823,20 @@ class SystemSettings(Singleton, EntropyPluginStore): return self.__generic_parser(self.__setting_files['system_mask'], comment_tag = self.__pkg_comment_tag) + def _splitdebug_parser(self): + """ + Parser returning packages for which the splitdebug feature + should be enabled. Splitdebug is about installing /usr/lib/debug + files into system. If no entries are listed in here and + splitdebug is enabled in client.conf, the feature will be considered + enabled for any package. + + @return: parsed metadata + @rtype: dict + """ + return self.__generic_parser(self.__setting_files['splitdebug'], + comment_tag = self.__pkg_comment_tag) + def _license_mask_parser(self): """ Parser returning packages masked by license metadata read from @@ -1555,7 +1595,7 @@ class SystemSettings(Singleton, EntropyPluginStore): comment_tag = comment_tag) # filter out non-ASCII lines lines = [x for x in lines if entropy.tools.is_valid_ascii(x)] - return lines + return SystemSettings.CachingList(lines) def __remove_repo_cache(self, repoid = None): """