Voeg ober-broncode toe

This commit is contained in:
Chris Josten 2020-03-13 14:15:38 +01:00
parent 4b4bebafdf
commit 43d1a912b0
5 changed files with 144 additions and 0 deletions

13
ober/README.md Normal file
View file

@ -0,0 +1,13 @@
# Hoe te gebruiken
1. Voer `sudo pip3 install .` uit in deze map.
- Je zou een specifieke gebruiker aan kunnen maken voor dit script, maar zorg dan
wel dat deze gebruiker machtigingen heeft om het commando "shutdown" uit te voeren.
2. Pas aiuo-shutdown.service aan
- Vervang [wachttijd] door de tijd die gewacht moet worden (in secondes)
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.
- Ik heb mijn rekentuig een keer onopstartbaar gemaakt, omdat het zichzelf meteen
afsloot. Houd hier rekening mee!

View file

@ -0,0 +1,12 @@
[Unit]
Description=AIUO Shutdown Manager
Wants=network-online.target
After=network-online.target
[Service]
Type=idle
ExecStart=aiuo-shutdown [timeout] [ip user]
User=root
[Install]
WantedBy=multi-user.target

0
ober/ober/__init__.py Normal file
View file

103
ober/ober/autoshutdown.py Executable file
View file

@ -0,0 +1,103 @@
#!/usr/bin/env python3
import aio_msgpack_rpc
import argparse
import asyncio
import logging
import os
import subprocess
import time
CLIENT_IP="example.org"
LOGGER = logging.getLogger(__name__)
TIMEOUT: float = 30 * 60
last_checked: float = time.time()
last_checked_value: bool = False
cur_timeout: float = TIMEOUT
def count_users() -> int:
"""Checks if any users are logged in"""
cmd = "who | wc -l"
ps = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
output = ps.communicate()[0]
try:
user_count = int(output)
except Exception as e:
LOGGER.exception(f"{output} could not be parsed as an int")
return user_count
def count_minecraft_players() -> int:
"""Checks if there any minecraft players"""
cmd = "netstat | grep 25565 | grep -v TIME_WAIT | wc -l"
ps = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
output = ps.communicate()[0]
try:
minecraft_players = int(output)
except Exception as e:
LOGGER.exception(f"{output} could not be parsed as an int")
return minecraft_players
def should_shutdown() -> bool:
user_count = count_users()
player_count = count_minecraft_players()
res = user_count == 0 and player_count == 0
LOGGER.debug(f"Player count: {player_count}")
LOGGER.debug(f"User count: {user_count}")
LOGGER.info("Should shut down" if res else "Should not shut down")
return res
def trusty_sleep(amount: float):
while time.time() - last_checked < amount:
LOGGER.debug("Woke up early")
time.sleep(amount - (time.time() - last_checked))
async def main() -> None:
global TIMEOUT
global CLIENT_IP
global last_checked
global last_checked_value
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))
success = True
except Exception as e:
LOGGER.debug(f"Connection failed: {e}. Retrying in 10s")
await asyncio.sleep(10)
LOGGER.debug(await client.call("GetBootReason"))
final_verdict = False
while not final_verdict:
LOGGER.debug("Stayling alive")
trusty_sleep(TIMEOUT / 2)
last_checked = time.time()
shutdown = should_shutdown()
if last_checked_value and shutdown:
break
elif shutdown:
last_checked_value = True
else:
last_checked_value = False
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())
if __name__ == "__main__":
start_main()

16
ober/setup.py Normal file
View file

@ -0,0 +1,16 @@
#!/usr/bin/env python3
from setuptools import setup
setup(name="AIUO-ober",
version="0.1",
description="Automatisch In- en Uitschakelen Ober Ober",
author="Chris Josten",
author_email="chris@netsoj.nl",
packages=["ober"],
install_requires=["aio_msgpack_rpc"],
entry_points={
"console_scripts": {
"aiuo-shutdown = ober.autoshutdown:start_main"
}
}
)