diff --git a/ober/README.md b/ober/README.md index 96b4aba..7b64311 100644 --- a/ober/README.md +++ b/ober/README.md @@ -7,7 +7,7 @@ en [klant-ip] door het ip-adres van het rekentuig dat de klant draait. - Als je het programmaatje niet als root wilt uitvoeren, verander dan ook de gebruiker in dit script. -3. Plaats aiuo-shutdown.service in `/etc/systemd/system`. -4. Start de de systemd-service. Als je zeker weet dat het werkt, schakel het dan in. +3. Plaats aiuo-shutdown.service, aiuo-shutdown-suspend.service en aiuo-wakeup.service in `/etc/systemd/system`. +4. Start deze services met systemd. Als je zeker weet dat het werkt, schakel het dan in. - Ik heb mijn rekentuig een keer onopstartbaar gemaakt, omdat het zichzelf meteen afsloot. Houd hier rekening mee! diff --git a/ober/aiuo-shutdown-suspend.service b/ober/aiuo-shutdown-suspend.service new file mode 100644 index 0000000..a233a20 --- /dev/null +++ b/ober/aiuo-shutdown-suspend.service @@ -0,0 +1,11 @@ +[Unit] +Description=Notify aiuo-shutdown when system goes sleeping +StopWhenUnneeded=yes + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStop=aiuo-shutdown --notify sleep + +[Install] +WantedBy=sleep.target diff --git a/ober/aiuo-shutdown-wakeup.service b/ober/aiuo-shutdown-wakeup.service new file mode 100644 index 0000000..eb054c1 --- /dev/null +++ b/ober/aiuo-shutdown-wakeup.service @@ -0,0 +1,12 @@ +[Unit] +Description=Notify aiuo-shutdown when system wakes up +After=sleep.target +StopWhenUnneeded=yes + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStop=aiuo-shutdown --notify wakeup + +[Install] +WantedBy=suspend.target diff --git a/ober/ober/autoshutdown.py b/ober/ober/autoshutdown.py index b526fde..aa9ebad 100755 --- a/ober/ober/autoshutdown.py +++ b/ober/ober/autoshutdown.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -import aio_msgpack_rpc +import msgpackrpc import argparse import asyncio import logging @@ -16,7 +16,6 @@ last_checked_value: bool = False cur_timeout: float = TIMEOUT client = None - def count_users() -> int: """Checks if any users are logged in""" cmd = "who | wc -l" @@ -53,41 +52,45 @@ def trusty_sleep(amount: float): LOGGER.debug("Woke up early") time.sleep(amount - (time.time() - last_checked)) -async def sigint_handler(*_, **__): +def sigterm_handler(signum, frame): LOGGER.debug("Notifying of shutdown") - await client.notify("NotifyShutdown") + client.notify("NotifyShutdown") -async def main() -> None: +def sigusr1_handler(signum, frame): + LOGGER.debug("Going to sleep") + client.notify("NotifySleep") + +def sigusr2_handler(signum, frame): + LOGGER.debug("Waking up") + client.notify("NotifyWakeup") + + +def main() -> None: global TIMEOUT global CLIENT_IP global last_checked global last_checked_value global client - logging.basicConfig(format='[%(asctime)s %(levelname)s] %(name)s: %(message)s', level=logging.DEBUG) - argparser = argparse.ArgumentParser(description="AIUO - Automatisch In- en Uitschakelen Ober (Oberkant)") - argparser.add_argument("wachttijd", type=float, help="Wachttijd voor het uitschakelen van ober, in secondes") - argparser.add_argument("ip_klant", type=str, help="IP-adres van klant") - args = argparser.parse_args() - CLIENT_IP = args.ip_klant - TIMEOUT = args.wachttijd - + LOGGER.debug("Trying to connect via RPC") success = False while not success: try: - client = aio_msgpack_rpc.Client(*await asyncio.open_connection(CLIENT_IP, 18002)) + client = msgpackrpc.Client(msgpackrpc.Address(CLIENT_IP, 18002)) success = True except Exception as e: LOGGER.debug(f"Connection failed: {e}. Retrying in 10s") - await asyncio.sleep(10) + time.sleep(10) - LOGGER.debug(await client.call("GetBootReason")) + LOGGER.debug(client.call("GetBootReason")) # Alleen de klant op de hoogte stellen nadat we hebben laten weten dat we er zijn. - LOGGER.debug("SIGINT verwerken") - loop = asyncio.get_running_loop() + LOGGER.debug("signalen registreren") #loop.add_signal_handler(signal.SIGINT, lambda: asyncio.ensure_future(sigint_handler())) + signal.signal(signal.SIGTERM, sigterm_handler) + signal.signal(signal.SIGUSR1, sigusr1_handler) + signal.signal(signal.SIGUSR2, sigusr2_handler) final_verdict = False @@ -103,22 +106,39 @@ async def main() -> None: last_checked_value = True else: last_checked_value = False - await sigint_handler() + sigterm_handler() os.system("shutdown +1 The system is going to shut down because no active sessions were found and no one is on the server") -def start_main(): - #asyncio.run(main()) - loop = asyncio.get_event_loop() - try: - loop.run_until_complete(main()) - except KeyboardInterrupt as e: - LOGGER.debug("Keyboard interrupt") - finally: - LOGGER.debug("Notify shutdown") - loop.run_forever(sigint_handler()) - loop.run_until_complete(loop.shutdown_asyncgens()) - loop.close() +def notify(what) -> None: + if what == "sleep": + sig_to_send = "USR1" + elif what == "wakeup": + sig_to_send = "USR2" + else: + return -1 + os.system(f"systemctl kill -s {sig_to_send} aiuo-shutdown.service") + + return 0 + + +def start_main(): + global CLIENT_IP + global TIMEOUT + + logging.basicConfig(format='[%(asctime)s %(levelname)s] %(name)s: %(message)s', level=logging.DEBUG) + argparser = argparse.ArgumentParser(description="AIUO - Automatisch In- en Uitschakelen Ober (Oberkant)") + argparser.add_argument("wachttijd", type=float, nargs="?", help="Wachttijd voor het uitschakelen van ober, in secondes") + argparser.add_argument("ip_klant", type=str, nargs="?", help="IP-adres van klant") + argparser.add_argument("--notify", type=str, help="Notify before sleep (sleep) or after wakeup (wakeup)") + args = argparser.parse_args() + if args.notify: + return notify(args.notify) + else: + CLIENT_IP = args.ip_klant + TIMEOUT = args.wachttijd + + return main() if __name__ == "__main__": start_main() diff --git a/ober/setup.py b/ober/setup.py index 0c9e85b..a77680b 100644 --- a/ober/setup.py +++ b/ober/setup.py @@ -2,12 +2,12 @@ from setuptools import setup setup(name="AIUO-ober", - version="0.2", + version="0.3", description="Automatisch In- en Uitschakelen Ober Ober", author="Chris Josten", author_email="chris@netsoj.nl", packages=["ober"], - install_requires=["aio_msgpack_rpc"], + install_requires=["msgpack-rpc-python"], entry_points={ "console_scripts": { "aiuo-shutdown = ober.autoshutdown:start_main"