Merge pull request #588 from Unrud/daemon

Daemon: Exit first process after server is ready
This commit is contained in:
Unrud 2017-05-30 07:50:44 +02:00 committed by GitHub
commit f2bfcfd406

View File

@ -114,45 +114,47 @@ def run():
exit(1) exit(1)
def serve(configuration, logger): def daemonize(configuration, logger):
"""Serve radicale from configuration.""" """Fork and decouple if Radicale is configured as daemon."""
# Fork if Radicale is launched as daemon # Check and create PID file in a race-free manner
if configuration.getboolean("server", "daemon"): if configuration.get("server", "pid"):
# Check and create PID file in a race-free manner try:
if configuration.get("server", "pid"): pid_path = os.path.abspath(os.path.expanduser(
try: configuration.get("server", "pid")))
pid_fd = os.open( pid_fd = os.open(
configuration.get("server", "pid"), pid_path, os.O_CREAT | os.O_EXCL | os.O_WRONLY)
os.O_CREAT | os.O_EXCL | os.O_WRONLY) except OSError as e:
except: raise OSError("PID file exists: %s" %
raise OSError( configuration.get("server", "pid")) from e
"PID file exists: %s" % configuration.get("server", "pid")) pid = os.fork()
pid = os.fork() if pid:
if pid:
sys.exit()
# Write PID # Write PID
if configuration.get("server", "pid"): if configuration.get("server", "pid"):
with os.fdopen(pid_fd, "w") as pid_file: with os.fdopen(pid_fd, "w") as pid_file:
pid_file.write(str(os.getpid())) pid_file.write(str(pid))
# Decouple environment sys.exit()
os.chdir("/") if configuration.get("server", "pid"):
os.setsid() os.close(pid_fd)
with open(os.devnull, "r") as null_in:
os.dup2(null_in.fileno(), sys.stdin.fileno())
with open(os.devnull, "w") as null_out:
os.dup2(null_out.fileno(), sys.stdout.fileno())
os.dup2(null_out.fileno(), sys.stderr.fileno())
# Register exit function # Register exit function
def cleanup(): def cleanup():
"""Remove the PID files.""" """Remove the PID files."""
logger.debug("Cleaning up") logger.debug("Cleaning up")
# Remove PID file # Remove PID file
if (configuration.get("server", "pid") and os.unlink(pid_path)
configuration.getboolean("server", "daemon")): atexit.register(cleanup)
os.unlink(configuration.get("server", "pid")) # Decouple environment
os.chdir("/")
os.setsid()
with open(os.devnull, "r") as null_in:
os.dup2(null_in.fileno(), sys.stdin.fileno())
with open(os.devnull, "w") as null_out:
os.dup2(null_out.fileno(), sys.stdout.fileno())
os.dup2(null_out.fileno(), sys.stderr.fileno())
atexit.register(cleanup)
def serve(configuration, logger):
"""Serve radicale from configuration."""
logger.info("Starting Radicale") logger.info("Starting Radicale")
# Create collection servers # Create collection servers
@ -228,6 +230,8 @@ def serve(configuration, logger):
else: else:
# Fallback to busy waiting # Fallback to busy waiting
select_timeout = 1.0 select_timeout = 1.0
if configuration.getboolean("server", "daemon"):
daemonize(configuration, logger)
logger.debug("Radicale server ready") logger.debug("Radicale server ready")
while not shutdown_program: while not shutdown_program:
try: try: