Permalink
Browse files

Support systemd socket activation

  • Loading branch information...
timbertson committed May 15, 2012
1 parent 32c2877 commit 41a54723977d2042c5040ee15c0754e8a7cb5525
View
@@ -21,6 +21,7 @@ import subprocess
import tempfile, time
import os, sys, re
import stat
+import socket
from optparse import OptionParser
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from SocketServer import ThreadingMixIn
@@ -35,6 +36,7 @@ os.environ['FROM_EDIT_SERVER'] = 'true'
processes = {}
INCREMENTAL = True
delay_in_minutes = 5
+SYSTEMD_FIRST_SOCKET_FD = 3
class HttpError(RuntimeError):
pass
@@ -172,6 +174,15 @@ class Handler(BaseHTTPRequestHandler):
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
pass
+class SocketInheritingHTTPServer(ThreadedHTTPServer):
+ """A HttpServer subclass that takes over an inherited socket from systemd"""
+ def __init__(self, address_info, handler, fd, bind_and_activate=True):
+ ThreadedHTTPServer.__init__(self, address_info, handler, bind_and_activate=False)
+ self.socket = socket.fromfd(fd, self.address_family, self.socket_type)
+ if bind_and_activate:
+ # NOTE: systemd provides ready-bound sockets, so we only need to activate:
+ self.server_activate()
+
def main():
global delay_in_minutes, INCREMENTAL, open_cmd
try:
@@ -186,9 +197,15 @@ def main():
if args:
open_cmd = args
- httpserv = ThreadedHTTPServer(('localhost', int(port)), Handler)
+ logging.info('edit-server PID is %s' % (os.getpid(),))
+ server_args = [('localhost', int(port)), Handler]
+ if os.environ.get('LISTEN_PID', None) == str(os.getpid()):
+ httpserv = SocketInheritingHTTPServer(*server_args, fd=SYSTEMD_FIRST_SOCKET_FD)
+ logging.info('edit-server started on socket fd %s' % (SYSTEMD_FIRST_SOCKET_FD,))
+ else:
+ httpserv = ThreadedHTTPServer(*server_args)
+ logging.info('edit-server started on port %s' % (port,))
httpserv.table = {}
- logging.info('edit-server started on port %s' % (port,))
httpserv.serve_forever()
except KeyboardInterrupt:
httpserv.socket.close()
View
@@ -0,0 +1,23 @@
+#!/usr/bin/python
+
+# this script simulates what I believe systemd does when passing a socket over
+# to a socket-activated service, which is useful in debugging issues.
+
+import socket, os
+HOST = 'localhost'
+PORT = 9292
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+s.bind((HOST, PORT))
+# Note that we don't call s.listen() as normal
+fd = s.fileno()
+os.dup2(fd, 3) # systemd starts passing fds at 3
+pid = os.fork()
+if pid == 0: # child
+ pid = os.getpid()
+ print "child pid = %s" % pid
+ os.environ['LISTEN_PID'] = str(pid)
+ os.execv(os.path.join(os.path.dirname(__file__), 'edit-server'), ['edit-server'])
+
+ret = os.waitpid(pid, 0)
+print "child returned %s" % (ret,)
+
@@ -4,7 +4,5 @@ Description=Edit Server
[Service]
ExecStart=/usr/bin/env 0launch -c http://gfxmonk.net/dist/0install/edit-server.xml
Restart=always
-
-[Install]
-WantedBy=default.target
-
+StandardOutput=syslog
+StandardError=syslog
@@ -0,0 +1,9 @@
+[Unit]
+Description=Edit Server
+
+[Socket]
+ListenStream=9292
+
+[Install]
+WantedBy=default.target
+

0 comments on commit 41a5472

Please sign in to comment.