diff --git a/docs/autostart_systemd.rst b/docs/autostart_systemd.rst index 90351bbd5..b8d522ccb 100644 --- a/docs/autostart_systemd.rst +++ b/docs/autostart_systemd.rst @@ -28,6 +28,7 @@ Paste the following and replace all instances of :code:`username` with the usern Restart=always RestartSec=15 RestartPreventExitStatus=0 + TimeoutStopSec=10 [Install] WantedBy=multi-user.target @@ -48,6 +49,14 @@ To set the bot to start on boot, you must enable the service, again adding the i :code:`sudo systemctl enable red@instancename` +If you need to shutdown the bot, you can use the ``[p]shutdown`` command or +type the following command in the terminal, still by adding the instance name after the **@**: + +:code:`sudo systemctl stop red@instancename` + +.. warning:: If the service doesn't stop in the next 10 seconds, the process is killed. + Check your logs to know the cause of the error that prevents the shutdown. + To view Red’s log, you can acccess through journalctl: :code:`sudo journalctl -u red@instancename` diff --git a/redbot/__main__.py b/redbot/__main__.py index f990c6553..2f7625fc4 100644 --- a/redbot/__main__.py +++ b/redbot/__main__.py @@ -14,6 +14,7 @@ from redbot.core.cli import interactive_config, confirm, parse_cli_flags, ask_se from redbot.core.core_commands import Core from redbot.core.dev_commands import Dev from redbot.core import __version__ +from signal import SIGTERM import asyncio import logging.handlers import logging @@ -110,6 +111,11 @@ def list_instances(): sys.exit(0) +async def sigterm_handler(red, log): + log.info("SIGTERM received. Quitting...") + await red.shutdown(restart=False) + + def main(): description = "Red - Version {}".format(__version__) cli_flags = parse_cli_flags(sys.argv[1:]) @@ -139,6 +145,8 @@ def main(): if cli_flags.dev: red.add_cog(Dev()) loop = asyncio.get_event_loop() + if os.name == "posix": + loop.add_signal_handler(SIGTERM, lambda: asyncio.ensure_future(sigterm_handler(red, log))) tmp_data = {} loop.run_until_complete(_get_prefix_and_token(red, tmp_data)) token = os.environ.get("RED_TOKEN", tmp_data["token"])