From 8263c6072a89d998dd7f94c571e036795d2b5b0f Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Fri, 6 May 2016 23:18:57 +0200 Subject: [PATCH 1/2] Make Server class octoprint_daemon-aware, make sure terminated() gets invoked on it upon SIGTERM and update respective test (cherry picked from commit 75f8fac) --- src/octoprint/daemon.py | 56 ++++++++++++++++---------------- src/octoprint/server/__init__.py | 8 ++++- 2 files changed, 35 insertions(+), 29 deletions(-) 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) From 2c0fa7c1d1343c6d81c5de2f1e72f96e58608026 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Thu, 12 May 2016 10:17:15 +0200 Subject: [PATCH 2/2] Added @kevans91 to AUTHORS.md (cherry picked from commit 425fa8e) --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index 4a741f2d..dfba891f 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -60,6 +60,7 @@ date of first contribution): * [Siim Raud](https://github.com/2ndalpha) * ["geoporalis"](https://github.com/geoporalis) * [Andrew Malota](https://github.com/2bitoperations) + * [Kyle Evans](https://github.com/kevans91) OctoPrint started off as a fork of [Cura](https://github.com/daid/Cura) by [Daid Braam](https://github.com/daid). Parts of its communication layer and