Make Server class octoprint_daemon-aware, make sure terminated() gets invoked on it upon SIGTERM and update respective test
This commit is contained in:
parent
1b1148d0c6
commit
75f8facb05
4 changed files with 13 additions and 21 deletions
|
|
@ -11,7 +11,7 @@ import sys
|
||||||
|
|
||||||
from octoprint.cli import pass_octoprint_ctx, bulk_options, standard_options
|
from octoprint.cli import pass_octoprint_ctx, bulk_options, standard_options
|
||||||
|
|
||||||
def run_server(basedir, configfile, host, port, debug, allow_root, logging_config, verbosity):
|
def run_server(basedir, configfile, host, port, debug, allow_root, logging_config, verbosity, octoprint_daemon = None):
|
||||||
"""Initializes the environment and starts up the server."""
|
"""Initializes the environment and starts up the server."""
|
||||||
|
|
||||||
from octoprint import init_platform, __display_version__
|
from octoprint import init_platform, __display_version__
|
||||||
|
|
@ -38,7 +38,7 @@ def run_server(basedir, configfile, host, port, debug, allow_root, logging_confi
|
||||||
after_logging=log_startup)
|
after_logging=log_startup)
|
||||||
|
|
||||||
from octoprint.server import Server
|
from octoprint.server import Server
|
||||||
octoprint_server = Server(settings=settings, plugin_manager=plugin_manager, host=host, port=port, debug=debug, allow_root=allow_root)
|
octoprint_server = Server(settings=settings, plugin_manager=plugin_manager, host=host, port=port, debug=debug, allow_root=allow_root, octoprint_daemon=octoprint_daemon)
|
||||||
octoprint_server.run()
|
octoprint_server.run()
|
||||||
|
|
||||||
#~~ server options
|
#~~ server options
|
||||||
|
|
@ -114,7 +114,7 @@ def daemon_command(octoprint_ctx, pid, host, port, logging, allow_root, debug, c
|
||||||
self._verbosity = verbosity
|
self._verbosity = verbosity
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
run_server(self._basedir, self._configfile, self._host, self._port, self._debug, self._allow_root, self._logging_config, self._verbosity)
|
run_server(self._basedir, self._configfile, self._host, self._port, self._debug, self._allow_root, self._logging_config, self._verbosity, self)
|
||||||
|
|
||||||
octoprint_daemon = OctoPrintDaemon(pid, octoprint_ctx.basedir, octoprint_ctx.configfile,
|
octoprint_daemon = OctoPrintDaemon(pid, octoprint_ctx.basedir, octoprint_ctx.configfile,
|
||||||
host, port, debug, allow_root, logging, octoprint_ctx.verbosity)
|
host, port, debug, allow_root, logging, octoprint_ctx.verbosity)
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,6 @@ class Daemon:
|
||||||
pid = str(os.getpid())
|
pid = str(os.getpid())
|
||||||
self.set_pid(pid)
|
self.set_pid(pid)
|
||||||
|
|
||||||
# register listener for SIGTERM
|
|
||||||
signal.signal(signal.SIGTERM, self._on_sigterm)
|
|
||||||
|
|
||||||
def _double_fork(self):
|
def _double_fork(self):
|
||||||
try:
|
try:
|
||||||
pid = os.fork()
|
pid = os.fork()
|
||||||
|
|
@ -71,10 +68,8 @@ class Daemon:
|
||||||
os.dup2(so.fileno(), sys.stdout.fileno())
|
os.dup2(so.fileno(), sys.stdout.fileno())
|
||||||
os.dup2(se.fileno(), sys.stderr.fileno())
|
os.dup2(se.fileno(), sys.stderr.fileno())
|
||||||
|
|
||||||
def _on_sigterm(self, _signo, _stack_frame):
|
def terminated(self):
|
||||||
"""Signal handler for SIGTERM, deletes the pidfile."""
|
|
||||||
self.remove_pidfile()
|
self.remove_pidfile()
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
"""Start the daemon."""
|
"""Start the daemon."""
|
||||||
|
|
|
||||||
|
|
@ -113,13 +113,14 @@ def load_user(id):
|
||||||
|
|
||||||
|
|
||||||
class Server(object):
|
class Server(object):
|
||||||
def __init__(self, settings=None, plugin_manager=None, host="0.0.0.0", port=5000, debug=False, allow_root=False):
|
def __init__(self, settings=None, plugin_manager=None, host="0.0.0.0", port=5000, debug=False, allow_root=False, octoprint_daemon=None):
|
||||||
self._settings = settings
|
self._settings = settings
|
||||||
self._plugin_manager = plugin_manager
|
self._plugin_manager = plugin_manager
|
||||||
self._host = host
|
self._host = host
|
||||||
self._port = port
|
self._port = port
|
||||||
self._debug = debug
|
self._debug = debug
|
||||||
self._allow_root = allow_root
|
self._allow_root = allow_root
|
||||||
|
self._octoprint_daemon = octoprint_daemon
|
||||||
self._server = None
|
self._server = None
|
||||||
|
|
||||||
self._logger = None
|
self._logger = None
|
||||||
|
|
@ -515,6 +516,11 @@ class Server(object):
|
||||||
octoprint.plugin.call_plugin(octoprint.plugin.ShutdownPlugin,
|
octoprint.plugin.call_plugin(octoprint.plugin.ShutdownPlugin,
|
||||||
"on_shutdown",
|
"on_shutdown",
|
||||||
sorting_context="ShutdownPlugin.on_shutdown")
|
sorting_context="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!")
|
self._logger.info("Goodbye!")
|
||||||
atexit.register(on_shutdown)
|
atexit.register(on_shutdown)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -155,25 +155,16 @@ class DaemonTest(unittest.TestCase):
|
||||||
self.daemon._double_fork.assert_called_once_with()
|
self.daemon._double_fork.assert_called_once_with()
|
||||||
self.daemon._redirect_io.assert_called_once_with()
|
self.daemon._redirect_io.assert_called_once_with()
|
||||||
self.daemon.set_pid.assert_called_once_with(str(pid))
|
self.daemon.set_pid.assert_called_once_with(str(pid))
|
||||||
mock_signal.assert_called_once_with(signal.SIGTERM, self.daemon._on_sigterm)
|
|
||||||
|
|
||||||
@mock.patch("sys.exit")
|
def test_terminated(self):
|
||||||
def test_on_sigterm(self, mock_exit):
|
|
||||||
# setup
|
# setup
|
||||||
self.daemon.remove_pidfile = mock.MagicMock()
|
self.daemon.remove_pidfile = mock.MagicMock()
|
||||||
|
|
||||||
mock_exit.side_effect = ExpectedExit
|
|
||||||
|
|
||||||
# test
|
# test
|
||||||
try:
|
self.daemon.terminated()
|
||||||
self.daemon._on_sigterm("foo", "bar")
|
|
||||||
self.fail("Expected an exit")
|
|
||||||
except ExpectedExit:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# assert
|
# assert
|
||||||
self.daemon.remove_pidfile.assert_called_once_with()
|
self.daemon.remove_pidfile.assert_called_once_with()
|
||||||
mock_exit.assert_called_once_with(0)
|
|
||||||
|
|
||||||
def test_start(self):
|
def test_start(self):
|
||||||
# setup
|
# setup
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue