A recent change to scope sql connections to tenants was incorrect because it assumed zuul-web would have access to a tenant's layout, but that is only in the zuul-scheduler's memory. Instead, this change causes zuul-web to perform an RPC call to the scheduler to ask which connection to use before performing sql queries. This slipped through testing because the zuul web test fixture used the same connection registry object as the scheduler, and therefore *was* able to access data which normally would not be available to it. This updates the zuul web test fixture to use a separate connection registry. Also, because zuul-web doesn't need any other kinds of connections at the moment, add a facility to allow it to only load sql connections, so that it doesn't do anything with the gerrit or github drivers. Change-Id: Iac6d8c6960f4a31eb2f78511664b704758e41687
108 lines
3.6 KiB
Python
Executable File
108 lines
3.6 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# Copyright 2017 Red Hat, Inc.
|
|
#
|
|
# 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 logging
|
|
import signal
|
|
import sys
|
|
|
|
import zuul.cmd
|
|
import zuul.model
|
|
import zuul.web
|
|
import zuul.driver.sql
|
|
import zuul.driver.github
|
|
|
|
from zuul.lib.config import get_default
|
|
|
|
|
|
class WebServer(zuul.cmd.ZuulDaemonApp):
|
|
app_name = 'web'
|
|
app_description = 'A standalone Zuul web server.'
|
|
|
|
def exit_handler(self, signum, frame):
|
|
self.web.stop()
|
|
|
|
def _run(self):
|
|
info = zuul.model.WebInfo.fromConfig(self.config)
|
|
|
|
params = dict()
|
|
|
|
params['info'] = info
|
|
params['listen_address'] = get_default(self.config,
|
|
'web', 'listen_address',
|
|
'127.0.0.1')
|
|
params['listen_port'] = get_default(self.config, 'web', 'port', 9000)
|
|
params['static_cache_expiry'] = get_default(self.config, 'web',
|
|
'static_cache_expiry',
|
|
3600)
|
|
params['static_path'] = get_default(self.config,
|
|
'web', 'static_path',
|
|
None)
|
|
params['gear_server'] = get_default(self.config, 'gearman', 'server')
|
|
params['gear_port'] = get_default(self.config, 'gearman', 'port', 4730)
|
|
params['ssl_key'] = get_default(self.config, 'gearman', 'ssl_key')
|
|
params['ssl_cert'] = get_default(self.config, 'gearman', 'ssl_cert')
|
|
params['ssl_ca'] = get_default(self.config, 'gearman', 'ssl_ca')
|
|
|
|
params['connections'] = self.connections
|
|
# Validate config here before we spin up the ZuulWeb object
|
|
for conn_name, connection in self.connections.connections.items():
|
|
try:
|
|
connection.validateWebConfig(self.config, self.connections)
|
|
except Exception:
|
|
self.log.exception("Error validating config")
|
|
sys.exit(1)
|
|
|
|
try:
|
|
self.web = zuul.web.ZuulWeb(**params)
|
|
except Exception as e:
|
|
self.log.exception("Error creating ZuulWeb:")
|
|
sys.exit(1)
|
|
|
|
signal.signal(signal.SIGUSR1, self.exit_handler)
|
|
signal.signal(signal.SIGTERM, self.exit_handler)
|
|
|
|
self.log.info('Zuul Web Server starting')
|
|
self.web.start()
|
|
|
|
try:
|
|
signal.pause()
|
|
except KeyboardInterrupt:
|
|
print("Ctrl + C: asking web server to exit nicely...\n")
|
|
self.exit_handler(signal.SIGINT, None)
|
|
|
|
self.web.stop()
|
|
self.log.info("Zuul Web Server stopped")
|
|
|
|
def run(self):
|
|
self.setup_logging('web', 'log_config')
|
|
self.log = logging.getLogger("zuul.WebServer")
|
|
|
|
self.configure_connections(
|
|
include_drivers=[zuul.driver.sql.SQLDriver,
|
|
zuul.driver.github.GithubDriver])
|
|
|
|
try:
|
|
self._run()
|
|
except Exception:
|
|
self.log.exception("Exception from WebServer:")
|
|
|
|
|
|
def main():
|
|
WebServer().main()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|