
Refactors configuration loading in order to simplify it and to allow overriding defaults using environment variables. This behavior is similar to other tools like pip or ansible, which can load any configurable option from env. This step ease migration towards containerized use, where we do not want to keep any secrets inside containers and we may want to avoid volume mounting, especially when testing. Change-Id: I0d3a9f19b0ba8d1604d0ca63db01296a3219fb47
144 lines
5.4 KiB
Python
144 lines
5.4 KiB
Python
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import os
|
|
import re
|
|
import configparser
|
|
|
|
# Can be overriden by defining environment variables with same name
|
|
DEFAULTS = {
|
|
'ES_URL': 'http://logstash.openstack.org:80/elasticsearch',
|
|
'LS_URL': 'http://logstash.openstack.org',
|
|
'DB_URI': 'mysql+pymysql://query:query@logstash.openstack.org/subunit2sql',
|
|
'server_password': '',
|
|
'CI_USERNAME': 'jenkins',
|
|
'JOBS_RE': 'dsvm',
|
|
'PID_FN': '/var/run/elastic-recheck/elastic-recheck.pid',
|
|
'INDEX_FORMAT': r'logstash-%Y.%m.%d',
|
|
'GERRIT_QUERY_FILE': 'queries',
|
|
'GERRIT_HOST': 'review.opendev.org',
|
|
'IRC_LOG_CONFIG': None
|
|
}
|
|
|
|
# Not all teams actively used elastic recheck for categorizing their
|
|
# work, so to keep the uncategorized page more meaningful, we exclude
|
|
# jobs from teams that don't use this toolchain.
|
|
EXCLUDED_JOBS = (
|
|
# Docs team
|
|
"api-site",
|
|
"operations-guide",
|
|
"openstack-manuals",
|
|
# Ansible
|
|
"ansible",
|
|
# Puppet
|
|
"puppet",
|
|
)
|
|
|
|
EXCLUDED_JOBS_REGEX = re.compile('(' + '|'.join(EXCLUDED_JOBS) + ')')
|
|
|
|
INCLUDED_PROJECTS_REGEX = "(^openstack/|devstack|grenade)"
|
|
|
|
# TODO(dmsimard): Revisit this query once Zuul v2 is no longer supported
|
|
# Let's value legibility over pep8 line width here...
|
|
ALL_FAILS_QUERY = (
|
|
'('
|
|
'(filename:"job-output.txt" AND message:"POST-RUN END" AND message:"playbooks/base/post.yaml")' # noqa E501
|
|
' OR '
|
|
'(filename:"console.html" AND (message:"[Zuul] Job complete" OR message:"[SCP] Copying console log" OR message:"Grabbing consoleLog"))' # noqa E501
|
|
')'
|
|
' AND build_status:"FAILURE"'
|
|
' AND build_queue:"gate"'
|
|
' AND voting:"1"'
|
|
)
|
|
|
|
UNCAT_MAX_SEARCH_SIZE = 30000
|
|
|
|
|
|
class Config(object):
|
|
|
|
def __init__(self,
|
|
config_file=None,
|
|
config_obj=None,
|
|
es_url=None,
|
|
ls_url=None,
|
|
db_uri=None,
|
|
jobs_re=None,
|
|
ci_username=None,
|
|
pid_fn=None,
|
|
es_index_format=None,
|
|
all_fails_query=None,
|
|
excluded_jobs_regex=None,
|
|
included_projects_regex=None,
|
|
uncat_search_size=None,
|
|
gerrit_query_file=None):
|
|
|
|
# override defaults with environment variables
|
|
for key, val in os.environ.items():
|
|
if key in DEFAULTS:
|
|
DEFAULTS[key] = val
|
|
|
|
self.es_url = es_url or DEFAULTS['ES_URL']
|
|
self.ls_url = ls_url or DEFAULTS['LS_URL']
|
|
self.db_uri = db_uri or DEFAULTS['DB_URI']
|
|
self.jobs_re = jobs_re or DEFAULTS['JOBS_RE']
|
|
self.ci_username = ci_username or DEFAULTS['CI_USERNAME']
|
|
self.es_index_format = es_index_format or DEFAULTS['INDEX_FORMAT']
|
|
self.pid_fn = pid_fn or DEFAULTS['PID_FN']
|
|
self.ircbot_channel_config = None
|
|
self.irc_log_config = DEFAULTS['IRC_LOG_CONFIG']
|
|
self.all_fails_query = all_fails_query or ALL_FAILS_QUERY
|
|
self.excluded_jobs_regex = excluded_jobs_regex or EXCLUDED_JOBS_REGEX
|
|
self.included_projects_regex = \
|
|
included_projects_regex or INCLUDED_PROJECTS_REGEX
|
|
self.uncat_search_size = uncat_search_size or UNCAT_MAX_SEARCH_SIZE
|
|
self.gerrit_query_file = (gerrit_query_file or
|
|
DEFAULTS['GERRIT_QUERY_FILE'])
|
|
self.gerrit_user = None
|
|
self.gerrit_host = None
|
|
self.gerrit_host_key = None
|
|
|
|
if config_file or config_obj:
|
|
if config_obj:
|
|
config = config_obj
|
|
else:
|
|
config = configparser.ConfigParser()
|
|
config.read(config_file)
|
|
cfg_map = {
|
|
'db_uri': ('data_source', 'db_uri'),
|
|
'es_url': ('data_source', 'es_url'),
|
|
'gerrit_host': ('gerrit', 'host'),
|
|
'gerrit_host_key': ('gerrit', 'key'),
|
|
'gerrit_query_file': ('gerrit', 'query_file'),
|
|
'gerrit_user': ('gerrit', 'user'),
|
|
'index_format': ('data_source', 'index_format'),
|
|
'irc_log_config': ('ircbot', 'log_config'),
|
|
'ircbot_channel_config': ('ircbot', 'channel_config'),
|
|
'ircbot_server': ('ircbot', 'server_password'),
|
|
'ircbot_sever_password': ('ircbot', 'port'),
|
|
'jobs_re': ('recheckwatch', 'jobs_re'),
|
|
'ls_url': ('data_source', 'ls_url'),
|
|
'nick': ('ircbot', 'nick'),
|
|
'pass': ('ircbot', 'pass'),
|
|
'pid_fn': ('ircbot', 'pidfile'),
|
|
'recheckwatch': ('recheckwatch', 'ci_username'),
|
|
}
|
|
for k, v in cfg_map.items():
|
|
try:
|
|
if hasattr(self, k) and getattr(self, k) is None:
|
|
setattr(self, k, config.get(v[0], v[1]))
|
|
except (
|
|
configparser.NoOptionError,
|
|
configparser.NoSectionError):
|
|
pass
|