Drop dependency on sdnotify (#5871)

... to save OSes which don't use it from having to maintain a port.

Fixes #5865.
release-v1.3.1
Richard van der Hoff 2019-08-17 09:09:52 +01:00 committed by GitHub
parent c188bd2c12
commit 412c6e21a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 11 deletions

1
changelog.d/5871.feature Normal file
View File

@ -0,0 +1 @@
Drop hard dependency on `sdnotify` python package.

View File

@ -17,10 +17,10 @@ import gc
import logging import logging
import os import os
import signal import signal
import socket
import sys import sys
import traceback import traceback
import sdnotify
from daemonize import Daemonize from daemonize import Daemonize
from twisted.internet import defer, error, reactor from twisted.internet import defer, error, reactor
@ -246,13 +246,12 @@ def start(hs, listeners=None):
def handle_sighup(*args, **kwargs): def handle_sighup(*args, **kwargs):
# Tell systemd our state, if we're using it. This will silently fail if # Tell systemd our state, if we're using it. This will silently fail if
# we're not using systemd. # we're not using systemd.
sd_channel = sdnotify.SystemdNotifier() sdnotify(b"RELOADING=1")
sd_channel.notify("RELOADING=1")
for i in _sighup_callbacks: for i in _sighup_callbacks:
i(hs) i(hs)
sd_channel.notify("READY=1") sdnotify(b"READY=1")
signal.signal(signal.SIGHUP, handle_sighup) signal.signal(signal.SIGHUP, handle_sighup)
@ -308,16 +307,12 @@ def setup_sdnotify(hs):
# Tell systemd our state, if we're using it. This will silently fail if # Tell systemd our state, if we're using it. This will silently fail if
# we're not using systemd. # we're not using systemd.
sd_channel = sdnotify.SystemdNotifier()
hs.get_reactor().addSystemEventTrigger( hs.get_reactor().addSystemEventTrigger(
"after", "after", "startup", sdnotify, b"READY=1\nMAINPID=%i" % (os.getpid(),)
"startup",
lambda: sd_channel.notify("READY=1\nMAINPID=%s" % (os.getpid())),
) )
hs.get_reactor().addSystemEventTrigger( hs.get_reactor().addSystemEventTrigger(
"before", "shutdown", lambda: sd_channel.notify("STOPPING=1") "before", "shutdown", sdnotify, b"STOPPING=1"
) )
@ -414,3 +409,35 @@ class _DeferredResolutionReceiver(object):
def resolutionComplete(self): def resolutionComplete(self):
self._deferred.callback(()) self._deferred.callback(())
self._receiver.resolutionComplete() self._receiver.resolutionComplete()
sdnotify_sockaddr = os.getenv("NOTIFY_SOCKET")
def sdnotify(state):
"""
Send a notification to systemd, if the NOTIFY_SOCKET env var is set.
This function is based on the sdnotify python package, but since it's only a few
lines of code, it's easier to duplicate it here than to add a dependency on a
package which many OSes don't include as a matter of principle.
Args:
state (bytes): notification to send
"""
if not isinstance(state, bytes):
raise TypeError("sdnotify should be called with a bytes")
if not sdnotify_sockaddr:
return
addr = sdnotify_sockaddr
if addr[0] == "@":
addr = "\0" + addr[1:]
try:
with socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) as sock:
sock.connect(addr)
sock.sendall(state)
except Exception as e:
# this is a bit surprising, since we don't expect to have a NOTIFY_SOCKET
# unless systemd is expecting us to notify it.
logger.warning("Unable to send notification to systemd: %s", e)

View File

@ -72,7 +72,6 @@ REQUIREMENTS = [
"netaddr>=0.7.18", "netaddr>=0.7.18",
"Jinja2>=2.9", "Jinja2>=2.9",
"bleach>=1.4.3", "bleach>=1.4.3",
"sdnotify>=0.3",
] ]
CONDITIONAL_REQUIREMENTS = { CONDITIONAL_REQUIREMENTS = {