blob: c55c252a4031842cf733b18499f3946795c7bb57 [file] [log] [blame]
James E. Blair1ce97ad2012-05-29 15:38:19 -07001#!/usr/bin/env python
2# Copyright 2012 Hewlett-Packard Development Company, L.P.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
James E. Blairee743612012-05-29 14:49:32 -070016import argparse
17import ConfigParser
James E. Blaird3bbe002012-05-31 13:06:31 -070018import daemon
19import daemon.pidlockfile
James E. Blaire9d45c32012-05-31 09:56:45 -070020import logging.config
James E. Blairee743612012-05-29 14:49:32 -070021import os
James E. Blaire9d45c32012-05-31 09:56:45 -070022import signal
James E. Blairee743612012-05-29 14:49:32 -070023
James E. Blair32663402012-06-01 10:04:18 -070024# No zuul imports here because they pull in paramiko which must not be
25# imported until after the daemonization.
26# https://github.com/paramiko/paramiko/issues/59
James E. Blairee743612012-05-29 14:49:32 -070027
James E. Blairee743612012-05-29 14:49:32 -070028
James E. Blaire9d45c32012-05-31 09:56:45 -070029class Server(object):
30 def __init__(self):
31 self.args = None
32 self.config = None
James E. Blair1e8dd892012-05-30 09:15:05 -070033
James E. Blaire9d45c32012-05-31 09:56:45 -070034 def parse_arguments(self):
35 parser = argparse.ArgumentParser(description='Project gating system.')
36 parser.add_argument('-c', dest='config',
37 help='specify the config file')
James E. Blaird3bbe002012-05-31 13:06:31 -070038 parser.add_argument('-d', dest='nodaemon', action='store_true',
39 help='do not run as a daemon')
James E. Blaire9d45c32012-05-31 09:56:45 -070040 self.args = parser.parse_args()
James E. Blairee743612012-05-29 14:49:32 -070041
James E. Blaire9d45c32012-05-31 09:56:45 -070042 def read_config(self):
43 self.config = ConfigParser.ConfigParser()
44 if self.args.config:
45 locations = [self.args.config]
46 else:
47 locations = ['/etc/zuul/zuul.conf',
48 '~/zuul.conf']
49 for fp in locations:
50 if os.path.exists(os.path.expanduser(fp)):
51 self.config.read(os.path.expanduser(fp))
52 return
53 raise Exception("Unable to locate config file in %s" % locations)
James E. Blair1e8dd892012-05-30 09:15:05 -070054
James E. Blaire9d45c32012-05-31 09:56:45 -070055 def setup_logging(self):
56 if self.config.has_option('zuul', 'log_config'):
57 fp = os.path.expanduser(self.config.get('zuul', 'log_config'))
58 if not os.path.exists(fp):
59 raise Exception("Unable to read logging config file at %s" %
60 fp)
61 logging.config.fileConfig(fp)
62 else:
63 logging.basicConfig(level=logging.DEBUG)
James E. Blairee743612012-05-29 14:49:32 -070064
James E. Blaire9d45c32012-05-31 09:56:45 -070065 def reconfigure_handler(self, signum, frame):
66 signal.signal(signal.SIGHUP, signal.SIG_IGN)
67 self.read_config()
68 self.setup_logging()
69 self.sched.reconfigure(self.config)
70 signal.signal(signal.SIGHUP, self.reconfigure_handler)
James E. Blair1e8dd892012-05-30 09:15:05 -070071
James E. Blaire9d45c32012-05-31 09:56:45 -070072 def main(self):
James E. Blair32663402012-06-01 10:04:18 -070073 # See comment at top of file about zuul imports
74 import zuul.scheduler
75 import zuul.launcher.jenkins
76 import zuul.trigger.gerrit
77
James E. Blaire9d45c32012-05-31 09:56:45 -070078 self.sched = zuul.scheduler.Scheduler()
James E. Blairee743612012-05-29 14:49:32 -070079
James E. Blaire9d45c32012-05-31 09:56:45 -070080 jenkins = zuul.launcher.jenkins.Jenkins(self.config, self.sched)
81 gerrit = zuul.trigger.gerrit.Gerrit(self.config, self.sched)
James E. Blair1e8dd892012-05-30 09:15:05 -070082
James E. Blaire9d45c32012-05-31 09:56:45 -070083 self.sched.setLauncher(jenkins)
84 self.sched.setTrigger(gerrit)
James E. Blairee743612012-05-29 14:49:32 -070085
James E. Blaire9d45c32012-05-31 09:56:45 -070086 self.sched.start()
87 self.sched.reconfigure(self.config)
88 signal.signal(signal.SIGHUP, self.reconfigure_handler)
89 while True:
90 signal.pause()
James E. Blairee743612012-05-29 14:49:32 -070091
James E. Blairee743612012-05-29 14:49:32 -070092
93if __name__ == '__main__':
James E. Blaire9d45c32012-05-31 09:56:45 -070094 server = Server()
James E. Blaird3bbe002012-05-31 13:06:31 -070095 server.parse_arguments()
96 server.read_config()
James E. Blaird3bbe002012-05-31 13:06:31 -070097
98 if server.config.has_option('zuul', 'pidfile'):
99 pid_fn = os.path.expanduser(server.config.get('zuul', 'pidfile'))
100 else:
101 pid_fn = '/var/run/zuul/zuul.pid'
102 pid = daemon.pidlockfile.TimeoutPIDLockFile(pid_fn, 10)
103
104 if server.args.nodaemon:
James E. Blair4c58c8f2012-05-31 13:38:09 -0700105 server.setup_logging()
James E. Blaird3bbe002012-05-31 13:06:31 -0700106 server.main()
107 else:
108 with daemon.DaemonContext(pidfile=pid):
James E. Blair4c58c8f2012-05-31 13:38:09 -0700109 server.setup_logging()
James E. Blaird3bbe002012-05-31 13:06:31 -0700110 server.main()