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
Signed by: pranav
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
[Service]
# TODO: change to notify when naxalnet becomes a daemon
Type=oneshot
RemainAfterExit=yes
Type=notify
NotifyAccess=all
Restart=on-failure
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
# Reload systemd-networkd after naxalnet exits
ExecStartPost=/usr/bin/networkctl reload
# 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...
ExecStopPost=/usr/bin/networkctl delete bridge0 bat0
# ... and reload the configuration files.
ExecStopPost=/usr/bin/networkctl reload
# Disable python buffering
Environment=PYTHONUNBUFFERED=1
# naxalnet already logs to systemd journal so we don't need
# stdout and stderr.
StandardOutput=null
StandardError=null
[Install]
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
# 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 naxalnet.default import CONFIG, CONFIG_FILES, CONFIG_DIRS
# from naxalnet.log import logger
def get_config_files():
"""

View File

@ -22,38 +22,50 @@ The daemon part. This is currently under construction.
"""
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:
"""implements the daemon part"""
logger = logging.getLogger(__name__)
def __init__(self):
iwd = IWD()
self.device_add_call = self.device_remove_call = None
self.loop = EventLoop()
self.iwd = IWD()
def on_device_add(self, callback):
def on_device_add(self, path, data):
"""
run the given callback with no arguments
every time a device is added
this function will be run 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
every time a device is removed
this function will be run 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):
"""
start the daemon
"""
logger.debug("Starting daemon")
self.loop.run()

View File

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

View File

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