implemented daemon

naxalnet is now a daemon! When run from systemd, it checks for new
devices or removal of devices and reloads the wifi configuration.
Updated the systemd service and changed Type to notify. Unfortunately,
there is some problem with logging. The messages from naxalnet.iwd could
not be found in the systemd journal or while running without --systemd.
This commit is contained in:
Pranav Jerry 2021-09-07 11:19:14 +05:30
parent 6fff558405
commit 68b53ccad1
No known key found for this signature in database
GPG Key ID: F1DCDC4FED0A0C5B
6 changed files with 58 additions and 37 deletions

View File

@ -17,28 +17,23 @@ After=NetworkManager.service
After=wpa_supplicant.service After=wpa_supplicant.service
[Service] [Service]
# TODO: change to notify when naxalnet becomes a daemon Type=notify
Type=oneshot NotifyAccess=all
RemainAfterExit=yes
Restart=on-failure Restart=on-failure
RestartSec=2sec RestartSec=2sec
# IWD takes some time to find devices.
# If naxalnet is run before iwd finds devices,
# naxalnet cannot start a mesh network but exits without errors.
# So, we give a 2s delay.
ExecStartPre=/usr/bin/sleep 2
ExecStart=/usr/bin/naxalnet --systemd ExecStart=/usr/bin/naxalnet --systemd
# Reload systemd-networkd after naxalnet exits # Reload systemd-networkd after naxalnet exits
ExecStartPost=/usr/bin/networkctl reload ExecStartPost=/usr/bin/networkctl reload
# Delete all files starting with mesh.* in /run/systemd/network # Delete all files starting with mesh.* in /run/systemd/network
ExecStop=/usr/bin/find /run/systemd/network -type f -delete -name "mesh.*" ExecStopPost=/usr/bin/find /run/systemd/network -type f -delete -name "mesh.*"
# Delete the interfaces created... # Delete the interfaces created...
ExecStopPost=/usr/bin/networkctl delete bridge0 bat0 ExecStopPost=/usr/bin/networkctl delete bridge0 bat0
# ... and reload the configuration files. # ... and reload the configuration files.
ExecStopPost=/usr/bin/networkctl reload ExecStopPost=/usr/bin/networkctl reload
# naxalnet already logs to systemd journal so we don't need
# Disable python buffering # stdout and stderr.
Environment=PYTHONUNBUFFERED=1 StandardOutput=null
StandardError=null
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View File

@ -35,4 +35,4 @@ See README.md for documentation.
# #
# In case you forgot to change the version, skip the number # In case you forgot to change the version, skip the number
# and put the next number in the next commit. # and put the next number in the next commit.
__version__ = "0.3.0a2.dev3" __version__ = "0.3.0a2.dev4"

View File

@ -61,8 +61,6 @@ from configparser import ConfigParser
from argparse import ArgumentParser, Namespace from argparse import ArgumentParser, Namespace
from naxalnet.default import CONFIG, CONFIG_FILES, CONFIG_DIRS from naxalnet.default import CONFIG, CONFIG_FILES, CONFIG_DIRS
# from naxalnet.log import logger
def get_config_files(): def get_config_files():
""" """

View File

@ -22,38 +22,50 @@ The daemon part. This is currently under construction.
""" """
import logging import logging
from naxalnet.iwd import IWD from dasbus.loop import EventLoop
from naxalnet.iwd import IWD, IWD_DEVICE_INTERFACE
logger = logging.getLogger(__name__)
class Daemon: class Daemon:
"""implements the daemon part""" """implements the daemon part"""
logger = logging.getLogger(__name__)
def __init__(self): def __init__(self):
iwd = IWD() self.loop = EventLoop()
self.device_add_call = self.device_remove_call = None self.iwd = IWD()
def on_device_add(self, callback): def on_device_add(self, path, data):
""" """
run the given callback with no arguments this function will be run every time a device is added
every time a device is added
""" """
self.device_add_call = callback if IWD_DEVICE_INTERFACE in data:
logger.debug("New device %s found", str(data[IWD_DEVICE_INTERFACE]["Name"]))
logger.info("Reloading")
self.callback()
def on_device_remove(self, callback): def on_device_remove(self, path, data):
""" """
run the given callback with no arguments this function will be run every time a device is removed
every time a device is removed
""" """
self.device_remove_call = callback if IWD_DEVICE_INTERFACE in data:
logger.debug("A device was removed")
logger.info("Reloading")
self.callback()
def register_callbacks(self): def add_callback(self, callback):
""" """
register the callbacks with D-Bus register the callback with D-Bus so that callback is
run every time a device is added or removed
""" """
self.callback = callback
proxy = self.iwd._proxy
proxy.InterfacesAdded.connect(self.on_device_add)
proxy.InterfacesRemoved.connect(self.on_device_remove)
def start(self): def start(self):
""" """
start the daemon start the daemon
""" """
logger.debug("Starting daemon")
self.loop.run()

View File

@ -59,7 +59,6 @@ and what they mean:
import logging import logging
from dasbus.connection import SystemMessageBus from dasbus.connection import SystemMessageBus
# from naxalnet.log import logger
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
IWD_BUS = "net.connman.iwd" IWD_BUS = "net.connman.iwd"

View File

@ -32,13 +32,16 @@ from pathlib import Path
from shutil import copy from shutil import copy
from dasbus.error import DBusError from dasbus.error import DBusError
from systemd import journal from systemd import journal
from systemd.daemon import notify
from naxalnet import __version__ from naxalnet import __version__
from naxalnet.iwd import Adapter, Device, IWD from naxalnet.iwd import Adapter, Device, IWD
from naxalnet.config import parse_args from naxalnet.config import parse_args
from naxalnet.daemon import Daemon
# from naxalnet.log import logger # Do not use getLogger(__name__) here.
# getLogger() without any args will give us
logger = logging.getLogger(__name__) # the root logger, which is waht we need.
logger = logging.getLogger()
args = parse_args() args = parse_args()
@ -50,6 +53,7 @@ def copy_files():
See man:systemd.network(5) See man:systemd.network(5)
""" """
try: try:
notify("STATUS=Configuring the network...")
logger.info("Copying network config files") logger.info("Copying network config files")
dest = Path(args.networkd_runtime_dir) dest = Path(args.networkd_runtime_dir)
src = Path(args.networkd_config_dir) src = Path(args.networkd_config_dir)
@ -72,6 +76,7 @@ def setup_devices():
is connected or removed. is connected or removed.
""" """
try: try:
notify("STATUS=Setting up mesh...")
iwd = IWD() iwd = IWD()
devices = iwd.get_devices() devices = iwd.get_devices()
adhoc_devices = [] adhoc_devices = []
@ -122,11 +127,12 @@ def setup_devices():
ap_adapter.power_on() ap_adapter.power_on()
ap_device.start_ap(args.ap_ssid, args.ap_passwd) ap_device.start_ap(args.ap_ssid, args.ap_passwd)
else: else:
logger.info("Not setting up WiFi AP.") logger.warning("Not setting up WiFi AP.")
else: else:
logger.warning( logger.warning(
"No device found to setup mesh. Make sure a WiFi adapter is connected" "No device found to setup mesh. Make sure a WiFi adapter is connected"
) )
except DBusError: except DBusError:
logger.exception("Error while communicating with iwd") logger.exception("Error while communicating with iwd")
sys.exit(4) sys.exit(4)
@ -170,7 +176,7 @@ def main():
# if --systemd is given, log to systemd journal # if --systemd is given, log to systemd journal
if args.systemd: if args.systemd:
logger.setLevel(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
logger.addHandler(journal.JournalHandler()) logger.addHandler(journal.JournalHandler())
else: else:
logging.basicConfig(level=loglevel) logging.basicConfig(level=loglevel)
@ -178,6 +184,17 @@ def main():
copy_files() copy_files()
setup_devices() setup_devices()
# Notify systemd that naxalnet is ready.
# see man:sd_notify(3)
notify("READY=1")
# naxalnet prints Bye if no errors occured # Start the daemon so that setup_devices() is called every
# time a device is connected or removed.
daemon = Daemon()
daemon.add_callback(setup_devices)
notify("STATUS=Waiting for changes")
daemon.start()
# naxalnet prints Bye while exiting.
logger.info("Bye") logger.info("Bye")