2018-06-14 09:42:56 +02:00
|
|
|
from __future__ import print_function
|
|
|
|
|
2018-11-05 15:46:50 +01:00
|
|
|
from osc import OscConfigParser
|
2018-01-08 21:08:00 -06:00
|
|
|
from collections import OrderedDict
|
2017-04-28 22:12:32 -05:00
|
|
|
import io
|
2015-02-17 17:50:20 +01:00
|
|
|
import os
|
|
|
|
import operator
|
|
|
|
import re
|
|
|
|
|
|
|
|
from osc import conf
|
2018-08-16 23:32:36 -05:00
|
|
|
from osclib.memoize import memoize
|
2015-02-17 17:50:20 +01:00
|
|
|
|
|
|
|
|
2018-11-20 10:49:03 +01:00
|
|
|
# Sane defaults for openSUSE and SUSE. The string interpolation rule
|
2015-02-19 10:57:55 +01:00
|
|
|
# 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.
|
|
|
|
|
2015-02-17 17:50:20 +01:00
|
|
|
DEFAULT = {
|
2018-10-18 15:55:41 -05:00
|
|
|
r'openSUSE:(?P<project>Factory)(?::NonFree)?$': {
|
2015-02-17 17:50:20 +01:00
|
|
|
'staging': 'openSUSE:%(project)s:Staging',
|
2016-05-02 10:50:02 +02:00
|
|
|
'staging-group': 'factory-staging',
|
2017-09-15 09:55:23 +02:00
|
|
|
'staging-archs': 'i586 x86_64',
|
2018-06-29 18:17:20 +08:00
|
|
|
'staging-dvd-archs': '',
|
2016-06-02 14:55:02 +02:00
|
|
|
'nocleanup-packages': 'Test-DVD-x86_64 Test-DVD-ppc64le bootstrap-copy',
|
2015-02-19 10:57:55 +01:00
|
|
|
'rings': 'openSUSE:%(project)s:Rings',
|
2016-12-06 12:54:36 +01:00
|
|
|
'nonfree': 'openSUSE:%(project)s:NonFree',
|
|
|
|
'rebuild': 'openSUSE:%(project)s:Rebuild',
|
|
|
|
'product': 'openSUSE.product',
|
|
|
|
'openqa': 'https://openqa.opensuse.org',
|
|
|
|
'lock': 'openSUSE:%(project)s:Staging',
|
|
|
|
'lock-ns': 'openSUSE',
|
2017-09-26 18:53:05 +08:00
|
|
|
'delreq-review': 'factory-maintainers',
|
|
|
|
'main-repo': 'standard',
|
2018-08-17 22:09:23 -05:00
|
|
|
'pseudometa_package': 'openSUSE:%(project)s:Staging/dashboard',
|
2018-02-05 19:42:55 -06:00
|
|
|
'download-baseurl': 'http://download.opensuse.org/tumbleweed/',
|
2017-10-11 22:19:24 -05:00
|
|
|
# check_source.py
|
2018-06-28 12:13:26 -05:00
|
|
|
'check-source-single-action-require': 'True',
|
2017-10-11 22:19:24 -05:00
|
|
|
'devel-project-enforce': 'True',
|
|
|
|
'review-team': 'opensuse-review-team',
|
2018-03-07 14:47:03 -06:00
|
|
|
'legal-review-group': 'legal-auto',
|
2017-10-11 22:19:24 -05:00
|
|
|
'repo-checker': 'repo-checker',
|
2018-08-21 02:16:20 -05:00
|
|
|
'repo_checker-no-filter': 'True',
|
2018-08-22 21:43:47 -05:00
|
|
|
'repo_checker-package-comment-devel': 'True',
|
2018-02-05 19:56:00 -06:00
|
|
|
'pkglistgen-product-family-include': 'openSUSE:Leap:N',
|
2018-04-10 22:30:57 -05:00
|
|
|
'mail-list': 'opensuse-factory@opensuse.org',
|
|
|
|
'mail-maintainer': 'Dominique Leuenberger <dimstar@suse.de>',
|
|
|
|
'mail-noreply': 'noreply@opensuse.org',
|
|
|
|
'mail-release-list': 'opensuse-releaseteam@opensuse.org',
|
2016-12-06 12:54:36 +01:00
|
|
|
},
|
2018-11-20 10:49:03 +01:00
|
|
|
r'openSUSE:(?P<project>Factory):ARM$': {
|
|
|
|
'product': 'openSUSE.product',
|
|
|
|
'openqa': 'https://openqa.opensuse.org',
|
|
|
|
'main-repo': 'standard',
|
|
|
|
'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',
|
|
|
|
},
|
2018-10-18 15:55:41 -05:00
|
|
|
r'openSUSE:(?P<project>Leap:(?P<version>[\d.]+))(?::NonFree)?$': {
|
2016-12-06 12:54:36 +01:00
|
|
|
'staging': 'openSUSE:%(project)s:Staging',
|
|
|
|
'staging-group': 'factory-staging',
|
|
|
|
'staging-archs': 'i586 x86_64',
|
2018-06-29 18:17:20 +08:00
|
|
|
'staging-dvd-archs': '',
|
2018-05-09 23:31:59 -05:00
|
|
|
'nocleanup-packages': 'bootstrap-copy 000product 000release-packages',
|
2016-12-06 12:54:36 +01:00
|
|
|
'rings': 'openSUSE:%(project)s:Rings',
|
2015-02-19 10:57:55 +01:00
|
|
|
'nonfree': 'openSUSE:%(project)s:NonFree',
|
|
|
|
'rebuild': 'openSUSE:%(project)s:Rebuild',
|
|
|
|
'product': 'openSUSE.product',
|
|
|
|
'openqa': 'https://openqa.opensuse.org',
|
2015-02-17 17:50:20 +01:00
|
|
|
'lock': 'openSUSE:%(project)s:Staging',
|
2015-02-19 10:57:55 +01:00
|
|
|
'lock-ns': 'openSUSE',
|
2018-03-05 17:21:15 -06:00
|
|
|
'leaper-override-group': 'leap-reviewers',
|
2017-10-02 20:14:31 +08:00
|
|
|
'delreq-review': None,
|
2017-10-02 20:49:41 +08:00
|
|
|
'main-repo': 'standard',
|
2018-08-17 22:09:23 -05:00
|
|
|
'pseudometa_package': 'openSUSE:%(project)s:Staging/dashboard',
|
2018-02-05 19:42:55 -06:00
|
|
|
'download-baseurl': 'http://download.opensuse.org/distribution/leap/%(version)s/',
|
2018-02-15 09:01:33 -06:00
|
|
|
'download-baseurl-update': 'http://download.opensuse.org/update/leap/%(version)s/',
|
2018-03-09 13:45:14 +01:00
|
|
|
'check-source-add-review-team': 'False',
|
2018-03-07 14:47:03 -06:00
|
|
|
'review-team': 'opensuse-review-team',
|
|
|
|
'legal-review-group': 'legal-auto',
|
2017-10-11 22:19:24 -05:00
|
|
|
# check_source.py
|
2018-06-28 12:13:26 -05:00
|
|
|
'check-source-single-action-require': 'True',
|
2017-10-11 22:19:24 -05:00
|
|
|
# review-team optionally added by leaper.py.
|
|
|
|
'repo-checker': 'repo-checker',
|
2018-02-14 15:05:41 -06:00
|
|
|
'repo_checker-arch-whitelist': 'x86_64',
|
2018-08-21 02:16:20 -05:00
|
|
|
'repo_checker-no-filter': 'True',
|
2018-08-22 21:43:47 -05:00
|
|
|
'repo_checker-package-comment-devel': 'True',
|
2018-02-06 02:09:59 -06:00
|
|
|
# 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': '',
|
2018-02-06 02:10:24 -06:00
|
|
|
# Allow `unselect --cleanup` to operate immediately on:
|
|
|
|
# - Update crawler requests (leaper)
|
|
|
|
# - F-C-C submitter requests (maxlin_factory)
|
|
|
|
'unselect-cleanup-whitelist': 'leaper maxlin_factory',
|
2017-12-21 00:32:20 -06:00
|
|
|
'pkglistgen-archs': 'x86_64',
|
2018-12-04 04:40:28 +01:00
|
|
|
'pkglistgen-scopes': 'target rings staging',
|
2018-01-10 14:10:17 +01:00
|
|
|
'pkglistgen-locales-from': 'openSUSE.product',
|
2018-05-09 23:31:37 -05:00
|
|
|
'pkglistgen-include-suggested': 'False',
|
2018-01-17 14:33:36 +01:00
|
|
|
'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',
|
2018-04-10 22:30:57 -05:00
|
|
|
'mail-list': 'opensuse-factory@opensuse.org',
|
|
|
|
'mail-maintainer': 'Ludwig Nussel <ludwig.nussel@suse.de>',
|
|
|
|
'mail-noreply': 'noreply@opensuse.org',
|
|
|
|
'mail-release-list': 'opensuse-releaseteam@opensuse.org',
|
2015-02-17 17:50:20 +01:00
|
|
|
},
|
2018-11-20 10:49:03 +01:00
|
|
|
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',
|
|
|
|
'mail-list': 'opensuse-arm@opensuse.org',
|
|
|
|
'mail-maintainer': 'Dirk Mueller <dmueller@suse.com>',
|
|
|
|
'mail-noreply': 'noreply@opensuse.org',
|
|
|
|
},
|
2018-10-18 15:55:41 -05:00
|
|
|
r'openSUSE:(?P<project>Leap:(?P<version>[\d.]+)(?::NonFree)?:Update)$': {
|
2018-08-16 23:54:59 -05:00
|
|
|
'main-repo': 'standard',
|
|
|
|
'leaper-override-group': 'leap-reviewers',
|
|
|
|
'repo_checker-arch-whitelist': 'x86_64',
|
2018-08-21 02:16:20 -05:00
|
|
|
'repo_checker-no-filter': 'True',
|
2018-08-22 21:43:47 -05:00
|
|
|
'repo_checker-package-comment-devel': 'True',
|
2018-08-16 23:54:59 -05:00
|
|
|
},
|
2018-08-16 23:50:23 -05:00
|
|
|
r'openSUSE:(?P<project>Backports:(?P<version>[^:]+))$': {
|
2018-06-29 11:29:21 +02:00
|
|
|
'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': 'leap-reviewers',
|
|
|
|
'review-team': 'opensuse-review-team',
|
|
|
|
'legal-review-group': 'legal-auto',
|
|
|
|
# review-team optionally added by leaper.py.
|
|
|
|
'repo-checker': 'repo-checker',
|
2018-08-22 23:54:30 -05:00
|
|
|
'repo_checker-project-skip': 'True',
|
2018-06-29 11:29:21 +02:00
|
|
|
# 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': '',
|
|
|
|
# Allow `unselect --cleanup` to operate immediately on:
|
|
|
|
# - Update crawler requests (leaper)
|
|
|
|
'unselect-cleanup-whitelist': 'leaper',
|
|
|
|
},
|
2018-08-22 23:54:30 -05:00
|
|
|
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',
|
|
|
|
},
|
2018-01-08 21:22:04 -06:00
|
|
|
# Allows devel projects to utilize tools that require config, but not
|
|
|
|
# complete StagingAPI support.
|
|
|
|
r'(?P<project>.*$)': {
|
2018-08-17 00:03:59 -05:00
|
|
|
'staging': None,
|
2018-01-08 21:22:04 -06:00
|
|
|
'staging-group': None,
|
|
|
|
'staging-archs': '',
|
|
|
|
'staging-dvd-archs': '',
|
2018-06-29 11:29:21 +02:00
|
|
|
'onlyadi': False,
|
2018-01-08 21:22:04 -06:00
|
|
|
'rings': None,
|
|
|
|
'nonfree': None,
|
|
|
|
'rebuild': None,
|
|
|
|
'product': None,
|
|
|
|
'openqa': None,
|
|
|
|
'lock': None,
|
|
|
|
'lock-ns': None,
|
|
|
|
'delreq-review': None,
|
2018-06-29 11:25:20 +02:00
|
|
|
'_priority': '0', # Apply defaults first
|
2018-01-08 21:22:04 -06:00
|
|
|
},
|
2015-02-17 17:50:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#
|
|
|
|
# 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
|
2015-02-19 10:57:55 +01:00
|
|
|
# rings = openSUSE:Factory:Rings
|
2015-02-17 17:50:20 +01:00
|
|
|
# lock = openSUSE:Factory:Staging
|
|
|
|
#
|
|
|
|
|
|
|
|
|
2018-03-09 13:14:01 +01:00
|
|
|
def str2bool(v):
|
2018-03-29 16:37:19 +08:00
|
|
|
return (v is not None and v.lower() in ("yes", "true", "t", "1"))
|
2018-03-09 13:14:01 +01:00
|
|
|
|
|
|
|
|
2015-02-17 17:50:20 +01:00
|
|
|
class Config(object):
|
|
|
|
"""Helper class to configuration file."""
|
|
|
|
|
2018-08-16 21:46:05 -05:00
|
|
|
def __init__(self, apiurl, project):
|
2015-02-17 17:50:20 +01:00
|
|
|
self.project = project
|
2018-08-16 21:46:05 -05:00
|
|
|
self.remote_values = self.fetch_remote(apiurl)
|
2015-02-17 17:50:20 +01:00
|
|
|
|
2017-10-23 23:02:21 -05:00
|
|
|
conf_file = conf.config.get('conffile', os.environ.get('OSC_CONFIG', '~/.oscrc'))
|
2015-02-17 17:50:20 +01:00
|
|
|
self.conf_file = os.path.expanduser(conf_file)
|
|
|
|
|
|
|
|
# Populate the configuration dictionary
|
|
|
|
self.populate_conf()
|
|
|
|
|
2018-08-16 23:32:36 -05:00
|
|
|
@staticmethod
|
|
|
|
@memoize(session=True) # Allow reset by memoize_session_reset() for ReviewBot.
|
|
|
|
def get(apiurl, project):
|
|
|
|
"""Cached version for directly accessing project config."""
|
|
|
|
Config(apiurl, project)
|
|
|
|
return conf.config.get(project, [])
|
|
|
|
|
2015-02-17 17:50:20 +01:00
|
|
|
@property
|
|
|
|
def conf(self):
|
|
|
|
return conf
|
|
|
|
|
|
|
|
def populate_conf(self):
|
2018-08-16 21:46:05 -05:00
|
|
|
"""Add sane default into the configuration and layer (defaults, remote, ~/.oscrc)."""
|
2015-02-17 17:50:20 +01:00
|
|
|
defaults = {}
|
2018-06-29 11:25:20 +02:00
|
|
|
default_ordered = OrderedDict(sorted(DEFAULT.items(), key=lambda i: int(i[1].get('_priority', 99))))
|
2018-01-08 21:08:00 -06:00
|
|
|
for prj_pattern in default_ordered:
|
2015-02-17 17:50:20 +01:00
|
|
|
match = re.match(prj_pattern, self.project)
|
|
|
|
if match:
|
|
|
|
project = match.group('project')
|
2015-02-19 10:57:55 +01:00
|
|
|
for k, v in DEFAULT[prj_pattern].items():
|
2018-06-29 11:25:20 +02:00
|
|
|
if k.startswith('_'):
|
|
|
|
continue
|
2018-11-15 14:03:36 +01:00
|
|
|
if isinstance(v, str) and '%(project)s' in v:
|
2015-02-19 10:57:55 +01:00
|
|
|
defaults[k] = v % {'project': project}
|
2018-11-15 14:03:36 +01:00
|
|
|
elif isinstance(v, str) and '%(project.lower)s' in v:
|
2015-02-19 10:57:55 +01:00
|
|
|
defaults[k] = v % {'project.lower': project.lower()}
|
2018-11-15 14:03:36 +01:00
|
|
|
elif isinstance(v, str) and '%(version)s' in v:
|
2018-02-05 19:42:18 -06:00
|
|
|
defaults[k] = v % {'version': match.group('version')}
|
2015-02-19 10:57:55 +01:00
|
|
|
else:
|
|
|
|
defaults[k] = v
|
2018-06-29 11:25:20 +02:00
|
|
|
if int(DEFAULT[prj_pattern].get('_priority', 99)) != 0:
|
|
|
|
break
|
2015-02-17 17:50:20 +01:00
|
|
|
|
2017-04-28 22:12:32 -05:00
|
|
|
if self.remote_values:
|
|
|
|
defaults.update(self.remote_values)
|
|
|
|
|
2015-02-17 17:50:20 +01:00
|
|
|
# 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.
|
|
|
|
|
|
|
|
"""
|
2018-11-05 15:46:50 +01:00
|
|
|
cp = OscConfigParser.OscConfigParser(defaults=defaults)
|
2015-02-17 17:50:20 +01:00
|
|
|
cp.read(self.conf_file)
|
|
|
|
if cp.has_section(section):
|
|
|
|
return dict(cp.items(section))
|
|
|
|
else:
|
|
|
|
return defaults
|
2017-04-28 22:12:32 -05:00
|
|
|
|
2018-08-16 21:46:05 -05:00
|
|
|
def fetch_remote(self, apiurl):
|
2018-08-17 22:09:23 -05:00
|
|
|
from osclib.core import attribute_value_load
|
2018-08-16 21:46:05 -05:00
|
|
|
config = attribute_value_load(apiurl, self.project, 'Config')
|
2017-04-28 22:12:32 -05:00
|
|
|
if config:
|
2018-11-05 15:46:50 +01:00
|
|
|
cp = OscConfigParser.OscConfigParser()
|
2018-11-16 15:03:40 +01:00
|
|
|
config = u'[remote]\n' + config
|
|
|
|
cp.readfp(io.StringIO(config))
|
2018-08-16 21:46:05 -05:00
|
|
|
return dict(cp.items('remote'))
|
|
|
|
|
|
|
|
return None
|