* It introduces a new configuration parameter 'required-source-maintainer'. * If defined, it is expected to be a maintainer of the devel project. * If that's not the case, the request is declined and an add_role request is created. Co-authored-by: Ancor Gonzalez Sosa <ancor@suse.de> Co-authored-by: Knut Alejandro Anderssen González <kanderssen@suse.com>
281 lines
11 KiB
Python
281 lines
11 KiB
Python
from __future__ import print_function
|
|
|
|
from osc import OscConfigParser
|
|
from collections import OrderedDict
|
|
import io
|
|
import os
|
|
import operator
|
|
import re
|
|
|
|
from osc import conf
|
|
from osclib.memoize import memoize
|
|
|
|
|
|
# Sane defaults for openSUSE and SUSE. The string interpolation rule
|
|
# is as this:
|
|
#
|
|
# * %(project)s to replace the name of the project.
|
|
# * %(project.lower)s to replace the lower case version of the name of
|
|
# the project.
|
|
|
|
DEFAULT = {
|
|
r'openSUSE:(?P<project>Factory)?$': {
|
|
'staging': 'openSUSE:%(project)s:Staging',
|
|
'staging-group': 'factory-staging',
|
|
'staging-archs': 'i586 x86_64',
|
|
'staging-dvd-archs': '',
|
|
'rings': 'openSUSE:%(project)s:Rings',
|
|
'rebuild': 'openSUSE:%(project)s:Rebuild',
|
|
'product': 'openSUSE.product',
|
|
'openqa': 'https://openqa.opensuse.org',
|
|
'lock': 'openSUSE:%(project)s:Staging',
|
|
'lock-ns': 'openSUSE',
|
|
'main-repo': 'standard',
|
|
'pseudometa_package': 'openSUSE:%(project)s:Staging/dashboard',
|
|
'download-baseurl': 'http://download.opensuse.org/tumbleweed/',
|
|
# check_source.py
|
|
'check-source-single-action-require': 'True',
|
|
'devel-project-enforce': 'True',
|
|
'review-team': 'opensuse-review-team',
|
|
'legal-review-group': 'legal-auto',
|
|
'repo_checker-no-filter': 'True',
|
|
'repo_checker-package-comment-devel': 'True',
|
|
'pkglistgen-product-family-include': 'openSUSE:Leap:N',
|
|
'pkglistgen-locales-from': 'openSUSE.product.in',
|
|
'mail-list': 'factory@lists.opensuse.org',
|
|
'mail-maintainer': 'Dominique Leuenberger <dimstar@suse.de>',
|
|
'mail-noreply': 'noreply@opensuse.org',
|
|
'mail-release-list': 'opensuse-releaseteam@opensuse.org',
|
|
'always_set_productversion_to': '',
|
|
'required-source-maintainer': 'group:factory-maintainers',
|
|
},
|
|
r'openSUSE:(?P<project>Factory):ARM$': {
|
|
'product': 'openSUSE.product',
|
|
'openqa': 'https://openqa.opensuse.org',
|
|
'main-repo': 'standard',
|
|
'rings': 'openSUSE:%(project)s:ARM:Rings',
|
|
'pseudometa_package': 'openSUSE:%(project)s:ARM:Staging/dashboard',
|
|
'download-baseurl': 'http://download.opensuse.org/ports/aarch64/tumbleweed/',
|
|
'mail-list': 'opensuse-arm@opensuse.org',
|
|
'mail-maintainer': 'Dirk Mueller <dmueller@suse.com>',
|
|
'mail-noreply': 'noreply@opensuse.org',
|
|
},
|
|
r'openSUSE:(?P<project>.*:NonFree)$': {
|
|
'staging': 'openSUSE:%(project)s:Staging',
|
|
'staging-group': 'factory-staging',
|
|
'onlyadi': 'True',
|
|
'review-team': 'opensuse-review-team',
|
|
},
|
|
r'openSUSE:(?P<project>Leap:(?P<version>[\d.]+))$': {
|
|
'staging': 'openSUSE:%(project)s:Staging',
|
|
'staging-group': 'factory-staging',
|
|
'staging-archs': 'i586 x86_64',
|
|
'staging-dvd-archs': '',
|
|
'nocleanup-packages': 'bootstrap-copy 000product 000release-packages',
|
|
'rings': 'openSUSE:%(project)s:Rings',
|
|
'rebuild': 'openSUSE:%(project)s:Rebuild',
|
|
'product': 'openSUSE.product',
|
|
'openqa': 'https://openqa.opensuse.org',
|
|
'lock': 'openSUSE:%(project)s:Staging',
|
|
'lock-ns': 'openSUSE',
|
|
'leaper-override-group': 'leap-reviewers',
|
|
'main-repo': 'standard',
|
|
'pseudometa_package': 'openSUSE:%(project)s:Staging/dashboard',
|
|
'download-baseurl': 'http://download.opensuse.org/distribution/leap/%(version)s/',
|
|
'download-baseurl-update': 'http://download.opensuse.org/update/leap/%(version)s/',
|
|
'check-source-add-review-team': 'False',
|
|
'review-team': 'opensuse-review-team',
|
|
'legal-review-group': 'legal-auto',
|
|
# check_source.py
|
|
'check-source-single-action-require': 'True',
|
|
# review-team optionally added by leaper.py.
|
|
'repo_checker-arch-whitelist': 'x86_64',
|
|
'repo_checker-no-filter': 'True',
|
|
'repo_checker-package-comment-devel': 'True',
|
|
# 16 hour staging window for follow-ups since lower throughput.
|
|
'splitter-staging-age-max': '57600',
|
|
# No special packages since they will pass through SLE first.
|
|
'splitter-special-packages': '',
|
|
'pkglistgen-archs': 'x86_64',
|
|
'pkglistgen-scopes': 'target rings staging',
|
|
'pkglistgen-locales-from': 'openSUSE.product',
|
|
'pkglistgen-delete-kiwis-rings': 'openSUSE-ftp-ftp-x86_64.kiwi openSUSE-cd-mini-x86_64.kiwi',
|
|
'pkglistgen-delete-kiwis-staging': 'openSUSE-ftp-ftp-x86_64.kiwi openSUSE-cd-mini-x86_64.kiwi',
|
|
'mail-list': 'factory@lists.opensuse.org',
|
|
'mail-maintainer': 'Ludwig Nussel <ludwig.nussel@suse.de>',
|
|
'mail-noreply': 'noreply@opensuse.org',
|
|
'mail-release-list': 'opensuse-releaseteam@opensuse.org',
|
|
},
|
|
r'openSUSE:(?P<project>Leap:(?P<version>[\d.]+)):ARM$': {
|
|
'product': 'openSUSE.product',
|
|
'openqa': 'https://openqa.opensuse.org',
|
|
'main-repo': 'ports',
|
|
'pseudometa_package': 'openSUSE:%(project)s:ARM:Staging/dashboard',
|
|
'pkglistgen-product-family-include': 'openSUSE:Leap:15.0:ARM',
|
|
'download-baseurl-openSUSE-Leap-15.0-ARM': 'http://download.opensuse.org/ports/aarch64/distribution/leap/15.0/',
|
|
'mail-list': 'opensuse-arm@opensuse.org',
|
|
'mail-maintainer': 'Dirk Mueller <dmueller@suse.com>',
|
|
'mail-noreply': 'noreply@opensuse.org',
|
|
},
|
|
r'openSUSE:(?P<project>Leap:(?P<version>[\d.]+)?:Update)$': {
|
|
'main-repo': 'standard',
|
|
'leaper-override-group': 'leap-reviewers',
|
|
'repo_checker-arch-whitelist': 'x86_64',
|
|
'repo_checker-no-filter': 'True',
|
|
'repo_checker-package-comment-devel': 'True',
|
|
'review-install-check': 'maintenance-installcheck',
|
|
'review-openqa': 'qam-openqa',
|
|
},
|
|
r'openSUSE:(?P<project>Backports:(?P<version>[^:]+))$': {
|
|
'staging': 'openSUSE:%(project)s:Staging',
|
|
'staging-group': 'factory-staging',
|
|
'staging-archs': 'x86_64',
|
|
'lock': 'openSUSE:%(project)s:Staging',
|
|
'lock-ns': 'openSUSE',
|
|
'onlyadi': 'True',
|
|
'leaper-override-group': 'backports-reviewers',
|
|
'review-team': 'opensuse-review-team',
|
|
'legal-review-group': 'legal-auto',
|
|
# review-team optionally added by leaper.py.
|
|
'repo_checker-project-skip': 'True',
|
|
# 16 hour staging window for follow-ups since lower throughput.
|
|
'splitter-staging-age-max': '57600',
|
|
# No special packages since they will pass through Leap first.
|
|
'splitter-special-packages': '',
|
|
},
|
|
r'openSUSE:(?P<project>Backports:SLE-[^:]+(?::Update)?)$': {
|
|
# Skip SLE related projects maintenance projects to avoid processing
|
|
# them during multi-target requests including an openSUSE project. The
|
|
# SLE projects cannot be processed since the repo cannot be mirrored.
|
|
'repo_checker-project-skip': 'True',
|
|
'_priority': '101',
|
|
},
|
|
r'openSUSE:(?P<project>Jump:(?P<version>[\d.]+))$': {
|
|
'product': 'openSUSE.product',
|
|
'openqa': 'https://openqa.opensuse.org',
|
|
'lock-ns': 'openSUSE',
|
|
'main-repo': 'standard',
|
|
'pseudometa_package': 'openSUSE:%(project)s:Staging/dashboard',
|
|
'download-baseurl': 'http://download.opensuse.org/distribution/leap/%(version)s/',
|
|
'download-baseurl-update': 'http://download.opensuse.org/update/leap/%(version)s/',
|
|
'pkglistgen-archs': 'x86_64 aarch64 ppc64le s390x',
|
|
'pkglistgen-scopes': 'target',
|
|
'pkglistgen-locales-from': 'openSUSE.product',
|
|
},
|
|
# Allows devel projects to utilize tools that require config, but not
|
|
# complete StagingAPI support.
|
|
r'(?P<project>.*$)': {
|
|
'staging': '',
|
|
'staging-group': '',
|
|
'staging-archs': '',
|
|
'staging-dvd-archs': '',
|
|
'staging-required-checks-adi': '',
|
|
'installcheck-ignore-duplicated-binaries': '',
|
|
'onlyadi': '',
|
|
'nocleanup-packages': '',
|
|
'rings': '',
|
|
'rebuild': '',
|
|
'product': '',
|
|
'openqa': '',
|
|
'lock': '',
|
|
'lock-ns': '',
|
|
'_priority': '0', # Apply defaults first
|
|
},
|
|
}
|
|
|
|
#
|
|
# You can overwrite the DEFAULT in the configuration file (~/.oscrc).
|
|
# For example, to change the Factory layout you need to add a new
|
|
# section like this:
|
|
#
|
|
# [openSUSE:Factory]
|
|
#
|
|
# staging = openSUSE:Factory:Staging
|
|
# rings = openSUSE:Factory:Rings
|
|
# lock = openSUSE:Factory:Staging
|
|
#
|
|
|
|
|
|
def str2bool(v):
|
|
return (v is not None and v.lower() in ("yes", "true", "t", "1"))
|
|
|
|
|
|
class Config(object):
|
|
"""Helper class to configuration file."""
|
|
|
|
def __init__(self, apiurl, project):
|
|
self.project = project
|
|
self.remote_values = self.fetch_remote(apiurl)
|
|
|
|
conf_file = conf.config.get('conffile', os.environ.get('OSC_CONFIG', '~/.oscrc'))
|
|
self.conf_file = os.path.expanduser(conf_file)
|
|
|
|
# Populate the configuration dictionary
|
|
self.populate_conf()
|
|
|
|
@staticmethod
|
|
@memoize(session=True) # Allow reset by memoize_session_reset() for ReviewBot.
|
|
def get(apiurl, project):
|
|
"""Cached version for directly accessing project config."""
|
|
# Properly handle loading the config for interconnect projects.
|
|
from osclib.core import project_remote_apiurl
|
|
apiurl_remote, project_remote = project_remote_apiurl(apiurl, project)
|
|
|
|
Config(apiurl_remote, project_remote)
|
|
return conf.config.get(project_remote, [])
|
|
|
|
@property
|
|
def conf(self):
|
|
return conf
|
|
|
|
def populate_conf(self):
|
|
"""Add sane default into the configuration and layer (defaults, remote, ~/.oscrc)."""
|
|
defaults = {}
|
|
default_ordered = OrderedDict(sorted(DEFAULT.items(), key=lambda i: int(i[1].get('_priority', 99))))
|
|
for prj_pattern in default_ordered:
|
|
match = re.match(prj_pattern, self.project)
|
|
if match:
|
|
project = match.group('project')
|
|
for k, v in DEFAULT[prj_pattern].items():
|
|
if k.startswith('_'):
|
|
continue
|
|
if isinstance(v, str) and '%(project)s' in v:
|
|
defaults[k] = v % {'project': project}
|
|
elif isinstance(v, str) and '%(project.lower)s' in v:
|
|
defaults[k] = v % {'project.lower': project.lower()}
|
|
elif isinstance(v, str) and '%(version)s' in v:
|
|
defaults[k] = v % {'version': match.group('version')}
|
|
else:
|
|
defaults[k] = v
|
|
if int(DEFAULT[prj_pattern].get('_priority', 99)) != 0:
|
|
break
|
|
|
|
if self.remote_values:
|
|
defaults.update(self.remote_values)
|
|
|
|
# Update the configuration, only when it is necessary
|
|
conf.config[self.project] = self.read_section(self.project, defaults)
|
|
|
|
def read_section(self, section, defaults):
|
|
"""OSC parser is a bit buggy. Re-read the configuration file to find
|
|
extra sections.
|
|
|
|
"""
|
|
cp = OscConfigParser.OscConfigParser(defaults=defaults)
|
|
cp.read(self.conf_file)
|
|
if cp.has_section(section):
|
|
return dict(cp.items(section))
|
|
else:
|
|
return defaults
|
|
|
|
def fetch_remote(self, apiurl):
|
|
from osclib.core import attribute_value_load
|
|
config = attribute_value_load(apiurl, self.project, 'Config')
|
|
if config:
|
|
cp = OscConfigParser.OscConfigParser()
|
|
config = u'[remote]\n' + config
|
|
cp.readfp(io.StringIO(config))
|
|
return dict(cp.items('remote'))
|
|
|
|
return None
|