Add optional internal gearman server.
Change-Id: Id4e6b77f5abba23f46236def28f54509c61fd247
Reviewed-on: https://review.openstack.org/30170
Reviewed-by: Monty Taylor <mordred@inaugust.com>
Reviewed-by: Clark Boylan <clark.boylan@gmail.com>
Reviewed-by: Jeremy Stanley <fungi@yuggoth.org>
Approved: Clark Boylan <clark.boylan@gmail.com>
Tested-by: Jenkins
diff --git a/zuul/cmd/server.py b/zuul/cmd/server.py
index 26e496c..e12e3f3 100755
--- a/zuul/cmd/server.py
+++ b/zuul/cmd/server.py
@@ -28,6 +28,8 @@
import sys
import signal
+import gear
+
# No zuul imports here because they pull in paramiko which must not be
# imported until after the daemonization.
# https://github.com/paramiko/paramiko/issues/59
@@ -37,6 +39,7 @@
def __init__(self):
self.args = None
self.config = None
+ self.gear_server_pid = None
def parse_arguments(self):
parser = argparse.ArgumentParser(description='Project gating system.')
@@ -65,9 +68,9 @@
return
raise Exception("Unable to locate config file in %s" % locations)
- def setup_logging(self):
- if self.config.has_option('zuul', 'log_config'):
- fp = os.path.expanduser(self.config.get('zuul', 'log_config'))
+ def setup_logging(self, section, parameter):
+ if self.config.has_option(section, parameter):
+ fp = os.path.expanduser(self.config.get(section, parameter))
if not os.path.exists(fp):
raise Exception("Unable to read logging config file at %s" %
fp)
@@ -84,8 +87,13 @@
def exit_handler(self, signum, frame):
signal.signal(signal.SIGUSR1, signal.SIG_IGN)
+ self.stop_gear_server()
self.sched.exit()
+ def term_handler(self, signum, frame):
+ self.stop_gear_server()
+ os._exit(0)
+
def test_config(self):
# See comment at top of file about zuul imports
import zuul.scheduler
@@ -96,6 +104,26 @@
self.sched = zuul.scheduler.Scheduler()
self.sched.testConfig(self.config.get('zuul', 'layout_config'))
+ def start_gear_server(self):
+ pipe_read, pipe_write = os.pipe()
+ child_pid = os.fork()
+ if child_pid == 0:
+ os.close(pipe_write)
+ self.setup_logging('gearman_server', 'log_config')
+ gear.Server(4730)
+ # Keep running until the parent dies:
+ pipe_read = os.fdopen(pipe_read)
+ pipe_read.read()
+ os._exit(0)
+ else:
+ os.close(pipe_read)
+ self.gear_server_pid = child_pid
+ self.gear_pipe_write = pipe_write
+
+ def stop_gear_server(self):
+ if self.gear_server_pid:
+ os.kill(self.gear_server_pid, signal.SIGKILL)
+
def main(self):
# See comment at top of file about zuul imports
import zuul.scheduler
@@ -103,6 +131,12 @@
import zuul.trigger.gerrit
import zuul.webapp
+ if (self.config.has_option('gearman_server', 'start') and
+ self.config.getboolean('gearman_server', 'start')):
+ self.start_gear_server()
+
+ self.setup_logging('zuul', 'log_config')
+
self.sched = zuul.scheduler.Scheduler()
gearman = zuul.launcher.gearman.Gearman(self.config, self.sched)
@@ -119,6 +153,7 @@
signal.signal(signal.SIGHUP, self.reconfigure_handler)
signal.signal(signal.SIGUSR1, self.exit_handler)
+ signal.signal(signal.SIGTERM, self.term_handler)
while True:
try:
signal.pause()
@@ -167,11 +202,9 @@
pid = pid_file_module.TimeoutPIDLockFile(pid_fn, 10)
if server.args.nodaemon:
- server.setup_logging()
server.main()
else:
with daemon.DaemonContext(pidfile=pid):
- server.setup_logging()
server.main()