diff --git a/src/octoprint/daemon.py b/src/octoprint/daemon.py index 4ef56b16..d0146276 100644 --- a/src/octoprint/daemon.py +++ b/src/octoprint/daemon.py @@ -12,35 +12,35 @@ class Daemon: Usage: subclass the daemon class and override the run() method.""" def __init__(self, pidfile): self.pidfile = pidfile - + def daemonize(self): """Deamonize class. UNIX double fork mechanism.""" - try: - pid = os.fork() + try: + pid = os.fork() if pid > 0: # exit first parent - sys.exit(0) - except OSError as err: + sys.exit(0) + except OSError as err: sys.stderr.write('fork #1 failed: {0}\n'.format(err)) sys.exit(1) - + # decouple from parent environment - os.chdir('/') - os.setsid() + os.chdir('/') + os.setsid() os.umask(002) - + # do second fork - try: - pid = os.fork() + try: + pid = os.fork() if pid > 0: # exit from second parent - sys.exit(0) - except OSError as err: + sys.exit(0) + except OSError as err: sys.stderr.write('fork #2 failed: {0}\n'.format(err)) - sys.exit(1) - + sys.exit(1) + # redirect standard file descriptors sys.stdout.flush() sys.stderr.flush() @@ -51,18 +51,14 @@ class Daemon: os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) - + # write pidfile pid = str(os.getpid()) with open(self.pidfile,'w+') as f: f.write(pid + '\n') - # register listener for SIGTERM - signal.signal(signal.SIGTERM, self.term) - - def term(self, _signo, _stack_frame): - os.remove(self.pidfile) - sys.exit(0) + def terminated(self): + self.remove_pidfile() def start(self): """Start the daemon.""" @@ -74,13 +70,13 @@ class Daemon: pid = int(pf.read().strip()) except IOError: pid = None - + if pid: message = "pidfile {0} already exist. " + \ "Daemon already running?\n" sys.stderr.write(message.format(self.pidfile)) sys.exit(1) - + # Start the daemon self.daemonize() self.run() @@ -94,14 +90,14 @@ class Daemon: pid = int(pf.read().strip()) except IOError: pid = None - + if not pid: message = "pidfile {0} does not exist. " + \ "Daemon not running?\n" sys.stderr.write(message.format(self.pidfile)) return # not an error in a restart - # Try killing the daemon process + # Try killing the daemon process try: while 1: os.kill(pid, signal.SIGTERM) @@ -122,7 +118,11 @@ class Daemon: def run(self): """You should override this method when you subclass Daemon. - - It will be called after the process has been daemonized by + + It will be called after the process has been daemonized by start() or restart().""" + def remove_pidfile(self): + """Removes the pidfile.""" + if os.path.isfile(self.pidfile): + os.remove(self.pidfile) diff --git a/src/octoprint/server/__init__.py b/src/octoprint/server/__init__.py index ced52d07..7fd0eb70 100644 --- a/src/octoprint/server/__init__.py +++ b/src/octoprint/server/__init__.py @@ -114,7 +114,7 @@ def load_user(id): class Server(object): - def __init__(self, configfile=None, basedir=None, host="0.0.0.0", port=5000, debug=False, allowRoot=False, logConf=None): + def __init__(self, configfile=None, basedir=None, host="0.0.0.0", port=5000, debug=False, allowRoot=False, logConf=None, octoprint_daemon=None): self._configfile = configfile self._basedir = basedir self._host = host @@ -123,6 +123,7 @@ class Server(object): self._allowRoot = allowRoot self._logConf = logConf self._server = None + self._octoprint_daemon = octoprint_daemon self._logger = None @@ -505,6 +506,11 @@ class Server(object): observer.join() octoprint.plugin.call_plugin(octoprint.plugin.ShutdownPlugin, "on_shutdown") + + if self._octoprint_daemon is not None: + self._logger.info("Cleaning up daemon pidfile") + self._octoprint_daemon.terminated() + self._logger.info("Goodbye!") atexit.register(on_shutdown)