commit: 10cccf7e0a1423f77a0962bcd7bf9658d2a15343 Author: Arfrever Frehtes Taifersar Arahesis <Arfrever <AT> Apache <DOT> Org> AuthorDate: Tue Dec 1 06:49:05 2015 +0000 Commit: Arfrever Frehtes Taifersar Arahesis <arfrever <AT> apache <DOT> org> CommitDate: Tue Dec 1 06:49:05 2015 +0000 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=10cccf7e
Support environmental variables overriding parts of configuration of repositories. PORTAGE_REPOSITORY:${repository_name}:${attribute} overrides value of given attribute. PORTAGE_ADDED_REPOSITORIES specifies names of repositories added to configuration. PORTAGE_DELETED_REPOSITORIES specifies names of repositories deleted from configuration. man/portage.5 | 19 ++++++++++++---- .../package/ebuild/_config/special_env_vars.py | 13 ++++++++--- pym/portage/package/ebuild/config.py | 5 +++-- pym/portage/repository/config.py | 25 ++++++++++++++++++++-- 4 files changed, 51 insertions(+), 11 deletions(-) diff --git a/man/portage.5 b/man/portage.5 index c9e70a0..6c41332 100644 --- a/man/portage.5 +++ b/man/portage.5 @@ -1,4 +1,4 @@ -.TH "PORTAGE" "5" "Nov 2015" "Portage VERSION" "Portage" +.TH "PORTAGE" "5" "Dec 2015" "Portage VERSION" "Portage" .SH NAME portage \- the heart of Gentoo .SH "DESCRIPTION" @@ -862,9 +862,6 @@ only. .TP .BR repos.conf Specifies \fIsite\-specific\fR repository configuration information. -.br -Configuration specified in \fBrepos.conf\fR can be overriden by \fBPORTAGE_REPOSITORIES\fR -environmental variable, which has the same format as \fBrepos.conf\fR. .I Format: .nf @@ -874,6 +871,20 @@ environmental variable, which has the same format as \fBrepos.conf\fR. \- attributes are specified in "${attribute} = ${value}" format .fi +.I Environmental variables overriding configuration: +.nf +\- \fBPORTAGE_REPOSITORIES\fR overrides full configuration. + Format: Format of repos.conf + Environmental variables described below are ignored when PORTAGE_REPOSITORIES is set. +\- \fBPORTAGE_REPOSITORY:${repository_name}:${attribute}\fR overrides value of given attribute. + Usage of \fBenv\fR(1) tool is needed if ":" character is not supported in names of shell variables. + Example: env PORTAGE_REPOSITORY:gentoo:location=/var/repositories/gentoo emerge ... +\- \fBPORTAGE_ADDED_REPOSITORIES\fR specifies names of repositories added to configuration. + Format: Whitespace\-separated list of names of repositories +\- \fBPORTAGE_DELETED_REPOSITORIES\fR specifies names of repositories deleted from configuration. + Format: Whitespace\-separated list of names of repositories +.fi + .I Attributes supported in DEFAULT section: .RS .RS diff --git a/pym/portage/package/ebuild/_config/special_env_vars.py b/pym/portage/package/ebuild/_config/special_env_vars.py index 905d5e7..8479cf5 100644 --- a/pym/portage/package/ebuild/_config/special_env_vars.py +++ b/pym/portage/package/ebuild/_config/special_env_vars.py @@ -1,15 +1,18 @@ -# Copyright 2010-2014 Gentoo Foundation +# Copyright 2010-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 from __future__ import unicode_literals __all__ = ( - 'case_insensitive_vars', 'default_globals', 'env_blacklist', \ - 'environ_filter', 'environ_whitelist', 'environ_whitelist_re', + 'case_insensitive_vars', 'default_globals', 'env_blacklist', + 'environ_filter', 'environ_filter_re', 'environ_whitelist', + 'environ_whitelist_re', 'global_only_vars', 'validate_commands' ) import re +from portage.repository.config import _repo_attr_override_var_re + # Blacklisted variables are internal variables that are never allowed # to enter the config instance from the external environment or # configuration files. @@ -157,10 +160,12 @@ environ_filter += [ "FETCHCOMMAND_HTTP", "FETCHCOMMAND_HTTPS", "FETCHCOMMAND_RSYNC", "FETCHCOMMAND_SFTP", "GENTOO_MIRRORS", "NOCONFMEM", "O", + "PORTAGE_ADDED_REPOSITORIES", "PORTAGE_BACKGROUND", "PORTAGE_BACKGROUND_UNMERGE", "PORTAGE_BINHOST", "PORTAGE_BINPKG_FORMAT", "PORTAGE_BUILDDIR_LOCKED", "PORTAGE_CHECKSUM_FILTER", + "PORTAGE_DELETED_REPOSITORIES", "PORTAGE_ELOG_CLASSES", "PORTAGE_ELOG_MAILFROM", "PORTAGE_ELOG_MAILSUBJECT", "PORTAGE_ELOG_MAILURI", "PORTAGE_ELOG_SYSTEM", @@ -190,6 +195,8 @@ environ_filter += [ environ_filter = frozenset(environ_filter) +environ_filter_re = re.compile(r"(" + _repo_attr_override_var_re.pattern + r")") + # Variables that are not allowed to have per-repo or per-package # settings. global_only_vars = frozenset([ diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py index da9a936..7cf5a4c 100644 --- a/pym/portage/package/ebuild/config.py +++ b/pym/portage/package/ebuild/config.py @@ -168,6 +168,7 @@ class config(object): _default_globals = special_env_vars.default_globals _env_blacklist = special_env_vars.env_blacklist _environ_filter = special_env_vars.environ_filter + _environ_filter_re = special_env_vars.environ_filter_re _environ_whitelist = special_env_vars.environ_whitelist _environ_whitelist_re = special_env_vars.environ_whitelist_re _global_only_vars = special_env_vars.global_only_vars @@ -2712,7 +2713,7 @@ class config(object): environ_whitelist = self._environ_whitelist for x in self: - if x in environ_filter: + if x in environ_filter or self._environ_filter_re.match(x) is not None: continue myvalue = self.get(x) if myvalue is None: @@ -2723,7 +2724,7 @@ class config(object): continue if filter_calling_env and \ x not in environ_whitelist and \ - not self._environ_whitelist_re.match(x): + self._environ_whitelist_re.match(x) is None: # Do not allow anything to leak into the ebuild # environment unless it is explicitly whitelisted. # This ensures that variables unset by the ebuild diff --git a/pym/portage/repository/config.py b/pym/portage/repository/config.py index a21c891..b987b56 100644 --- a/pym/portage/repository/config.py +++ b/pym/portage/repository/config.py @@ -50,6 +50,8 @@ _portage1_profiles_allow_directories = frozenset( _repo_name_sub_re = re.compile(r'[^\w-]') +_repo_attr_override_var_re = re.compile(r'^PORTAGE_REPOSITORY:([^:]+):([^:]+)$') + def _gen_valid_repo(name): """ Substitute hyphen in place of characters that don't conform to PMS 3.1.5, @@ -546,7 +548,7 @@ class RepoConfigLoader(object): return portdir @staticmethod - def _parse(paths, prepos, local_config, default_opts): + def _parse(paths, prepos, local_config, default_opts, added_repos, deleted_repos, attrs_overrides): """Parse files in paths to load config""" parser = SafeConfigParser(defaults=default_opts) @@ -595,11 +597,24 @@ class RepoConfigLoader(object): prepos['DEFAULT'] = RepoConfig("DEFAULT", parser.defaults(), local_config=local_config) + # Apply overrides from PORTAGE_ADDED_REPOSITORIES and PORTAGE_DELETED_REPOSITORIES environmental variables. + for added_repo in added_repos: + if not parser.has_section(added_repo): + parser.add_section(added_repo) + for deleted_repo in deleted_repos: + parser.remove_section(deleted_repo) + for sname in parser.sections(): optdict = {} for oname in parser.options(sname): optdict[oname] = parser.get(sname, oname) + # Apply overrides from PORTAGE_REPOSITORY:${repository_name}:${attribute} environmental variables. + for k, v in attrs_overrides.items(): + m = _repo_attr_override_var_re.match(k) + if m is not None and m.group(1) == sname: + optdict[m.group(2)] = v + repo = RepoConfig(sname, optdict, local_config=local_config) for o in portage.sync.module_specific_options(repo): if parser.has_option(sname, o): @@ -628,11 +643,17 @@ class RepoConfigLoader(object): } if "PORTAGE_REPOSITORIES" in settings: + added_repos = [] + deleted_repos = [] + attrs_overrides = {} portdir = "" portdir_overlay = "" # deprecated portdir_sync portdir_sync = "" else: + added_repos = settings.get("PORTAGE_ADDED_REPOSITORIES", "").split() + deleted_repos = settings.get("PORTAGE_DELETED_REPOSITORIES", "").split() + attrs_overrides = {x: settings[x] for x in settings if _repo_attr_override_var_re.match(x) is not None} portdir = settings.get("PORTDIR", "") portdir_overlay = settings.get("PORTDIR_OVERLAY", "") # deprecated portdir_sync @@ -642,7 +663,7 @@ class RepoConfigLoader(object): settings.get("PORTAGE_RSYNC_EXTRA_OPTS", None) try: - self._parse(paths, prepos, settings.local_config, default_opts) + self._parse(paths, prepos, settings.local_config, default_opts, added_repos, deleted_repos, attrs_overrides) except ConfigParserError as e: writemsg( _("!!! Error while reading repo config file: %s\n") % e,