Merge pull request 'Convert into daemon' (#17) from daemon into master

Reviewed-on: https://git.disroot.org/pranav/naxalnet/pulls/17
This commit is contained in:
Pranav Jerry 2021-09-10 14:59:01 +00:00
commit 74a061507f
16 changed files with 321 additions and 163 deletions

View File

@ -1,9 +1,14 @@
# Changelog # Changelog
## [Unreleased][] - 2021-09-05 ## [Unreleased][] - 2021-09-09
- Now logs to systemd journal. New dependency - `python3-systemd` - naxalnet is now a daemon! naxalnet will reconfigure the WiFi network
every time a WiFi adapter is plugged in or removed
- **Logging**: logs to systemd journal when run from systemd, stderr
otherwise
- New dependency `python-systemd`
- Fixed dependency order in systemd service - Fixed dependency order in systemd service
- Added `--verbose` argument
## [v0.3.0][] - 2021-08-19 ## [v0.3.0][] - 2021-08-19
@ -22,9 +27,9 @@
## [v0.1.0][] - 2021-06-19 ## [v0.1.0][] - 2021-06-19
Initial version. At first, this was a shell script. Than it was converted Initial python version. At first, this was a shell script. Than it was
into a single python file that did just what the shell script used to do. converted into a single python file that did just what the shell script
The shell script was not given a version. used to do. The shell script was not given a version.
[unreleased]: https://git.disroot.org/pranav/naxalnet/compare/v0.3.0...HEAD [unreleased]: https://git.disroot.org/pranav/naxalnet/compare/v0.3.0...HEAD
[v0.3.0]: https://git.disroot.org/pranav/naxalnet/compare/v0.2.0...v0.3.0 [v0.3.0]: https://git.disroot.org/pranav/naxalnet/compare/v0.2.0...v0.3.0

View File

@ -16,7 +16,7 @@ install: build
uninstall: uninstall:
$(PIP) uninstall -y naxalnet $(PIP) uninstall -y naxalnet
rm -rf /usr/share/naxalnet /usr/lib/systemd/system/naxalnet.service rm -rf /usr/share/naxalnet /usr/lib/systemd/system/naxalnet.service
@-test -d /etc/naxalnet && echo "The directory /etc/naxalnet was not removed." && \ @echo "The directory /etc/naxalnet was not removed." && \
echo "Do 'sudo make purge' to remove it." echo "Do 'sudo make purge' to remove it."
# remove config files, like apt purge # remove config files, like apt purge

View File

@ -18,13 +18,12 @@ network.
<!-- NOTE TO ACTIVISTS <!-- NOTE TO ACTIVISTS
Running this program in the world's largest (partly-free) democracy Running this program in the world's largest (partly-free) democracy
may result in you getting arrested under the UAPA, and not may result in you getting arrested under the Act Which Must Not Be Named,
getting bail because of false evidence planted in your phone by and not getting bail because of false evidence planted in your phone by
Pegasus, or by a forensic lab in Gujarat. Pegasus, or by a forensic lab in Gujarat.
The author, much like the Government of India, does not wish The author, much like the GoI, does not wish to take responsibility in your
to take responsibility in your well-being if you get arrested under well-being if you get arrested under a draconian national security law.
a draconian national security law.
--> -->
<!-- UNCOMMENT WHEN NECESSARY <!-- UNCOMMENT WHEN NECESSARY
@ -32,7 +31,7 @@ a draconian national security law.
**Disclaimer**: **Disclaimer**:
In case you are either 1) a complete idiot; or 2) a member of the saffron In case you are either 1) a complete idiot; or 2) a member of the saffron
brigade; or 3) both, please be aware that this project is not affiliated brigade; or 3) both, please be aware that this project is not affiliated
with any groups designated as "terrorist" groups in India. with any human rights groups designated as "terrorist" groups in India.
Using the name naxal does not imply any form of connection Using the name naxal does not imply any form of connection
with anyone currently at risk of death in overcrowded prisons. with anyone currently at risk of death in overcrowded prisons.
@ -46,12 +45,12 @@ with anyone currently at risk of death in overcrowded prisons.
- [iwd][] for controlling the WiFi adapter - [iwd][] for controlling the WiFi adapter
- python3 - python3
- python3-setuptools, for building and installing naxalnet - python3-setuptools, for building and installing naxalnet
- python3-systemd, for logging to systemd journal - [python-systemd][], for logging to systemd journal
- [dasbus][], for communicating with iwd - [dasbus][], for communicating with iwd
- two or more machines with a WiFi adapter having ad-hoc support, called - two or more machines with a WiFi adapter having ibss support, called
nodes or peers nodes or peers
- batctl (optional, for debugging) - batctl (optional, for debugging)
- python3-pip (optional, for `make uninstall` to work) - python3-pip (for installing dasbus on Debian-based distributions)
## Installing ## Installing
@ -117,15 +116,10 @@ git clone https://git.disroot.org/pranav/naxalnet.git
cd naxalnet cd naxalnet
``` ```
Or, if you have an [IPFS client][ipfs] running, try this instead: Now, build and install naxalnet:
```sh
git clone http://k51qzi5uqu5dlye74be0n9iihwk6sm54vexo7bf7pdr4w811y6mmrcp25djozv.ipns.localhost:8080/naxalnet.git
```
Now, install naxalnet:
```sh ```sh
make
sudo make install sudo make install
``` ```
@ -136,13 +130,24 @@ service files:
sudo systemctl daemon-reload sudo systemctl daemon-reload
``` ```
To upgrade, clean the build files, update the repo and reinstall:
```sh
make clean
git pull
make
sudo make uninstall install
```
This will keep the configuration files.
## How to use ## How to use
You need more than one machine running naxalnet for the connection to work. You need more than one machine running naxalnet for the connection to work.
### Start naxalnet ### Start naxalnet
Though naxalnet can run from the commandline, it was designed to be Though naxalnet can run from the command line, it was designed to be
run as a systemd service. run as a systemd service.
To start naxalnet, do the command on all the nodes: To start naxalnet, do the command on all the nodes:
@ -152,25 +157,25 @@ sudo systemctl start naxalnet.service
This will start a mesh network and connect to all nodes. This will start a mesh network and connect to all nodes.
To test if it works, run `sudo batctl n -w` and check for To test if it works, run `sudo batctl n -w` and check for
nodes. If there are any nodes, your network is up. nodes. If there are any nodes, your network is up. Press
Ctrl+C to stop `batctl`.
### Getting internet access ### Getting internet access
Connect an ethernet cable from a router to any of the peers and Connect an ethernet cable from a router to any of the nodes and
[start naxalnet][startnx]. If it was already started, you should
renew the DHCP connection of all peers. To do this, type renew the DHCP connection of all peers. To do this, type
`sudo networkctl renew bridge0` on all peers. `sudo networkctl renew bridge0` on all nodes.
### Tethering via WiFi AP ### Tethering via WiFi AP
If there are two adapters in a peer, naxalnet will start a If there are two adapters in a peer, naxalnet will start a
WiFi ap (also called WiFi hotspot) on one of them. WiFi ap (also called WiFi hotspot) on one of them.
Connect two WiFi adapters on a device and [start naxalnet][startnx]. Connect two WiFi adapters on a node.
Now an ap will be started on one of the adapters. Now an AP will be started on one of the adapters.
Type `naxalnet --print-wifi` to get the WiFi SSID and password. Type `naxalnet --print-wifi` to get the WiFi SSID and password.
If you had set up internet access on one of the peers, internet If you had set up internet access on one of the nodes, internet
can be accessed from the AP. can be accessed from the AP.
### Running at boot ### Running at boot
@ -223,7 +228,7 @@ naxalnet --help
## How it works ## How it works
There are three modes commonly supported by WiFi adapters - `ap` (WiFi There are three modes commonly supported by WiFi adapters - `ap` (WiFi
hotspot), `station` (for joining WiFi networks) and `ad-hoc` (for hotspot), `station` (for joining WiFi networks) and `ad-hoc` (or ibss, for
decentralised networks). There are other modes supported by some WiFi decentralised networks). There are other modes supported by some WiFi
adapters too, like `p2p` (WiFi direct), but this program doesn't use them. adapters too, like `p2p` (WiFi direct), but this program doesn't use them.
@ -235,7 +240,7 @@ naxalnet starts an ad-hoc on one of them and an ap on the other.
You can use the ap for connecting mobile phones and other devices You can use the ap for connecting mobile phones and other devices
to the mesh network. to the mesh network.
Read the code and the documentation to learn the details. Read the code and the documentation in the code to learn the details.
See the directory [systemd-networkd](systemd-networkd) to see how See the directory [systemd-networkd](systemd-networkd) to see how
systemd-networkd configures the network. systemd-networkd configures the network.
@ -284,13 +289,13 @@ See [HACKING.md](HACKING.md)
Many projects make setting up B.A.T.M.A.N. Advanced mesh networks with Many projects make setting up B.A.T.M.A.N. Advanced mesh networks with
WiFi routers easier. They are easier to setup and are more WiFi routers easier. They are easier to setup and are more
configurable. But naxalnet is different from them. It simplifies configurable. But naxalnet is different from them. It simplifies
setting up mesh networks with _laptops or computers_, and is not setting up mesh networks with _laptops or computers_, and was not
designed to work with routers. made to work with routers.
The following projects does something similar to naxalnet, but The following projects does something similar to naxalnet, but
requires special devices or routers to work. If you live in an area requires special devices or routers to work. If you live in an area
where the materials required for any of them are easily available, where the materials are easily available, consider using them instead
consider using them instead of naxalnet. of naxalnet.
- [LibreMesh][]: framework for OpenWrt-based firmwares - [LibreMesh][]: framework for OpenWrt-based firmwares
- [disaster.radio][]: solar-powered communications network - [disaster.radio][]: solar-powered communications network
@ -322,3 +327,4 @@ See [LICENSE](LICENSE) for the complete version of the license.
[enablenx]: #running-at-boot [enablenx]: #running-at-boot
[requirements]: #requirements [requirements]: #requirements
[install-manual]: #manually [install-manual]: #manually
[python-systemd]: https://github.com/systemd/python-systemd

View File

@ -18,5 +18,6 @@ name = NxMesh
[ap] [ap]
# An AP is started if your machine has more than one WiFi adapter. # An AP is started if your machine has more than one WiFi adapter.
ssid = MeshWiFi ssid = MeshWiFi
# Note the spelling. It's passwd, not password.
passwd = naxalnet256 passwd = naxalnet256

View File

@ -17,28 +17,24 @@ 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. ExecStart=/usr/bin/naxalnet --systemd
# If naxalnet is run before iwd finds devices, # Reload systemd-networkd after naxalnet signals it is ready
# 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
# 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 # When naxalnet exits, delete all files starting
ExecStop=/usr/bin/find /run/systemd/network -type f -delete -name "mesh.*" # with mesh.* in /run/systemd/network
# Delete the interfaces created... ExecStopPost=/usr/bin/find /run/systemd/network -type f -delete -name "mesh.*"
# Then delete the two 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

@ -1,5 +1,4 @@
#!/usr/bin/env python3 # This file is part of naxalnet.
# Copyright (C) 2021 The naxalnet Authors # Copyright (C) 2021 The naxalnet Authors
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
@ -36,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" __version__ = "0.3.0a3"

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python3 # This file is part of naxalnet.
# Copyright (C) 2021 The naxalnet Authors # Copyright (C) 2021 The naxalnet Authors
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
@ -15,13 +14,14 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
If called as python -m naxalnet, this file makes naxalnet run like If called as python -m naxalnet, this file makes naxalnet run like
it was called from the commandline. Try: it was called from the commandline. Try:
python -m naxalnet --help python -m naxalnet --help
""" """
from naxalnet.scripts import here_be_dragons from naxalnet.scripts import main
if __name__ == "__main__": if __name__ == "__main__":
here_be_dragons() main()

View File

@ -1,4 +1,18 @@
#!/usr/bin/env python3 # This file is part of naxalnet.
# Copyright (C) 2021 The naxalnet Authors
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
config.py config.py
@ -46,7 +60,6 @@ from pathlib import Path
from configparser import ConfigParser 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():
@ -70,14 +83,14 @@ def parse_config():
Parse all configuration files, with the values in Parse all configuration files, with the values in
default.py as fallback default.py as fallback
""" """
logger.debug("Parsing config files") # logger.debug("Parsing config files")
parser = ConfigParser() parser = ConfigParser()
# encoded defaults # encoded defaults
parser.read_dict(CONFIG) parser.read_dict(CONFIG)
# read config files # read config files
files = get_config_files() files = get_config_files()
for i in files: for i in files:
logger.debug("Reading config file %s", str(i)) # logger.debug("Reading config file %s", str(i))
parser.read_file(i.open()) parser.read_file(i.open())
return parser return parser
@ -138,6 +151,13 @@ def parse_args() -> Namespace:
help="volatile directory where configuration files of systemd-networkd should be copied", help="volatile directory where configuration files of systemd-networkd should be copied",
) )
parser.add_argument(
"--systemd",
action="store_true",
default=False,
help="send log messages to systemd journal",
)
parser.add_argument( parser.add_argument(
"--version", "--version",
default=False, default=False,
@ -145,5 +165,12 @@ def parse_args() -> Namespace:
help="prints the version and exit", help="prints the version and exit",
) )
logger.debug("Parsing arguments") parser.add_argument(
"-v", "--verbose", action="count", default=0, help="increase output verbosity"
)
# logger.debug("Parsing arguments")
return parser.parse_args() return parser.parse_args()
args = parse_args()

69
naxalnet/daemon.py Normal file
View File

@ -0,0 +1,69 @@
# This file is part of naxalnet.
# Copyright (C) 2021 The naxalnet Authors
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
daemon.py
---------
The daemon part. This is currently under construction.
"""
from dasbus.loop import EventLoop
from naxalnet.iwd import IWD, IWD_DEVICE_INTERFACE
from naxalnet.log import logger
class Daemon:
"""implements the daemon part"""
def __init__(self):
self.loop = EventLoop()
self.iwd = IWD()
def on_device_add(self, path, data):
"""
this function will be run every time a device is added
"""
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, path, data):
"""
this function will be run every time a device is removed
"""
if IWD_DEVICE_INTERFACE in data:
logger.debug("A device was removed")
logger.info("Reloading")
self.callback()
def add_callback(self, callback):
"""
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

@ -1,4 +1,18 @@
#!/usr/bin/env python3 # This file is part of naxalnet.
# Copyright (C) 2021 The naxalnet Authors
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
default.py default.py

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python3 # This file is part of naxalnet.
# Copyright (C) 2021 The naxalnet Authors # Copyright (C) 2021 The naxalnet Authors
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
@ -15,7 +14,6 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
iwd.py iwd.py
------ ------
@ -58,6 +56,7 @@ and what they mean:
- node: a machine that runs naxalnet and is therefore - node: a machine that runs naxalnet and is therefore
connected to the mesh. connected to the mesh.
""" """
from dasbus.connection import SystemMessageBus from dasbus.connection import SystemMessageBus
from naxalnet.log import logger from naxalnet.log import logger
@ -236,6 +235,7 @@ class Device:
if it isn't already on ad-hoc and power onn the device if it isn't already on ad-hoc and power onn the device
if it is off if it is off
""" """
print("Starting adhoc", name)
if self.get_mode() != "ad-hoc": if self.get_mode() != "ad-hoc":
self.set_mode("ad-hoc") self.set_mode("ad-hoc")
@ -270,9 +270,7 @@ class Device:
# Stop ap if already started # Stop ap if already started
self.stop_ap() self.stop_ap()
logger.debug( logger.debug("Starting ap on %s with ssid %s", self.name, ssid)
"Starting ap on %s with ssid %s and password %s", self.name, ssid, passwd
)
self._proxy.Start(ssid, passwd) self._proxy.Start(ssid, passwd)
def stop_ap(self): def stop_ap(self):
@ -310,11 +308,13 @@ class Adapter:
"""power on the adapter""" """power on the adapter"""
self._proxy.Powered = True self._proxy.Powered = True
logger.debug("Powered on adapter %s", self.name) logger.debug("Powered on adapter %s", self.name)
self.reload()
def power_off(self): def power_off(self):
"""power off the adapter""" """power off the adapter"""
self._proxy.Powered = False self._proxy.Powered = False
logger.debug("Powered off adapter %s", self.name) logger.debug("Powered off adapter %s", self.name)
self.reload()
def supports_mode(self, mode: str) -> bool: def supports_mode(self, mode: str) -> bool:
""" """

View File

@ -1,16 +1,38 @@
#!/usr/bin/env python3
""" """
log.py log.py
------ ------
This file contains the logger object, which is required for logging Initialise the logger for other submodules to import. Do not
to the systemd journal import any submodules here except for naxallnet.config
""" """
import logging import logging
from systemd import journal from systemd.journal import JournalHandler
from naxalnet.config import args
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG) def get_logger():
logger.addHandler(journal.JournalHandler()) """
Initialise the logger and return it.
This function is meant to be used only by naxalnet.log.
If you want to import the logger, use:
from naxalnet.log import logger
"""
log = logging.getLogger("naxalnet")
# --verbose
if args.verbose >= 2:
loglevel = logging.DEBUG
elif args.verbose == 1:
loglevel = logging.INFO
else:
loglevel = logging.WARNING
# if --systemd is given, log to systemd journal
if args.systemd:
logging.basicConfig(level=logging.DEBUG)
log.addHandler(JournalHandler())
else:
logging.basicConfig(level=loglevel)
return log
logger = get_logger()

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python3 # This file is part of naxalnet.
# Copyright (C) 2021 The naxalnet Authors # Copyright (C) 2021 The naxalnet Authors
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
@ -24,103 +23,116 @@ and doing the things this program is supposed to do.
This file is named scripts.py because the original developer This file is named scripts.py because the original developer
of this program could not think of a better name that suits this file. of this program could not think of a better name that suits this file.
If you want to hack naxalnet, this is the right place to start. If you want to hack naxalnet, this is the right place to start.
When run from the commandline, the function here_be_dragons() is called. When run from the commandline, the function main() is called.
""" """
import sys import sys
from pathlib import Path from pathlib import Path
from shutil import copy from shutil import copy
from dasbus.error import DBusError from dasbus.error import DBusError
from systemd.daemon import notify
from naxalnet import __version__ from naxalnet import __version__
from naxalnet.iwd import Adapter, Device, IWD
from naxalnet.config import parse_args
from naxalnet.log import logger from naxalnet.log import logger
from naxalnet.iwd import Adapter, Device, IWD
from naxalnet.config import args
from naxalnet.daemon import Daemon
def copy_files(args): def copy_files():
""" """
Copy networkd configs to volatile dir. Copy networkd configs to volatile dir.
The D-Bus API does not support creating new interfaces The D-Bus API does not support creating new interfaces
or linking to bridges. So we use config files. or linking to bridges. So we use config files.
See man:systemd.network(5) 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)
logger.info("Copying network config files") # Create the volatile directory if it doesn't exist
dest = Path(args.networkd_runtime_dir) dest.mkdir(parents=True, exist_ok=True)
src = Path(args.networkd_config_dir)
# Create the volatile directory if it doesn't exist # Copy all files in src to dest
dest.mkdir(parents=True, exist_ok=True) for i in src.iterdir():
copy(i, dest)
# Copy all files in src to dest except PermissionError as error:
for i in src.iterdir(): logger.error("Cannot copy file: %s", error)
copy(i, dest) sys.exit(3)
def setup_devices(args): def setup_devices():
""" """
Setup wifi interfaces using iwd Setup wifi interfaces using iwd
This function should be called every time an interface This function should be called every time an interface
is connected or removed. is connected or removed.
args should be what parse_args() returns
""" """
iwd = IWD() try:
devices = iwd.get_devices() notify("STATUS=Setting up mesh...")
adhoc_devices = [] iwd = IWD()
ap_devices = [] devices = iwd.get_devices()
adhoc_devices = []
ap_devices = []
# Find devices supporting ad-hoc and ap # Find devices supporting ad-hoc and ap
for i in devices: for i in devices:
# For each device, check if its adapter supports # For each device, check if its adapter supports
# ad-hoc or ap. Many adapters will support both, # ad-hoc or ap. Many adapters will support both,
# so we will prioritise ad-hoc over ap. # so we will prioritise ad-hoc over ap.
device = Device(i) device = Device(i)
logger.debug("Found device %s", device.name) logger.debug("Found device %s", device.name)
adapter = Adapter(device.adapter) adapter = Adapter(device.adapter)
if adapter.supports_mode("ad-hoc"): if adapter.supports_mode("ad-hoc"):
logger.debug("The device %s can be used for ad-hoc", device.name) logger.debug("The device %s can be used for ad-hoc", device.name)
adhoc_devices.append(i) adhoc_devices.append(i)
if adapter.supports_mode("ap"): if adapter.supports_mode("ap"):
logger.debug("The device %s can be used for ap", device.name) logger.debug("The device %s can be used for ap", device.name)
ap_devices.append(i) ap_devices.append(i)
if len(adhoc_devices) != 0:
# Start ad-hoc on first device supporting ad-hoc
adhoc_device = Device(adhoc_devices.pop())
# The same device is likely to have ap support too.
# But we can't start ad-hoc and ap on the same interface.
# So we will remove adhoc_device from ap_devices if it exists there
if adhoc_device.name in ap_devices:
ap_devices.remove(adhoc_device.name)
if len(adhoc_devices) != 0:
# Start ad-hoc on first device supporting ad-hoc
adhoc_device = Device(adhoc_devices.pop())
# The same device is likely to have ap support too.
# But we can't start ad-hoc and ap on the same interface.
# So we will remove adhoc_device from ap_devices if it exists there
if adhoc_device.name in ap_devices:
ap_devices.remove(adhoc_device.name)
logger.info("Starting mesh on %s", adhoc_device.name)
# Turn on adapter if it is off
# See issue #9
adhoc_adapter = Adapter(adhoc_device.adapter)
if not adhoc_adapter.is_powered_on():
logger.debug("Adapter %s is off. Turning on", adhoc_adapter.name)
adhoc_adapter.power_on()
adhoc_device.reload()
adhoc_device.start_adhoc_open(args.adhoc_name)
# Start Access point if ap_device is not empty,
# ie, we have more devices
if len(ap_devices) != 0:
ap_device = Device(ap_devices.pop())
logger.info("Starting WiFi Access Point on %s", ap_device.name)
logger.info("Use naxalnet --print-wifi to get password")
# Turn on adapter if it is off # Turn on adapter if it is off
# See issue #9 # See issue #9
ap_adapter = Adapter(ap_device.adapter) adhoc_adapter = Adapter(adhoc_device.adapter)
if not ap_adapter.is_powered_on(): if not adhoc_adapter.is_powered_on():
logger.debug("Adapter %s is off. Turning on", ap_adapter.name) logger.debug("Adapter %s is off. Turning on", adhoc_adapter.name)
ap_adapter.power_on() adhoc_adapter.power_on()
ap_adapter.reload() logger.info("Starting mesh on %s", adhoc_device.name)
ap_device.start_ap(args.ap_ssid, args.ap_passwd) adhoc_device.start_adhoc_open(args.adhoc_name)
# Start Access point if ap_device is not empty,
# ie, we have more devices
if len(ap_devices) != 0:
ap_device = Device(ap_devices.pop())
logger.info("Starting WiFi Access Point on %s", ap_device.name)
logger.info("Use naxalnet --print-wifi to get password")
# Turn on adapter if it is off
# See issue #9
ap_adapter = Adapter(ap_device.adapter)
if not ap_adapter.is_powered_on():
logger.debug("Adapter %s is off. Turning on", ap_adapter.name)
ap_adapter.power_on()
ap_device.start_ap(args.ap_ssid, args.ap_passwd)
else:
logger.warning("Not setting up WiFi AP.")
else:
logger.warning(
"No device found to setup mesh. Make sure a WiFi adapter is connected"
)
# naxalnet prints Bye if no errors occured except DBusError:
logger.info("Bye") logger.exception("Error while communicating with iwd")
sys.exit(4)
def print_wifi(args): def print_wifi():
""" """
Prints the name and password of the adhoc, and ap Prints the name and password of the adhoc, and ap
from the arguments from the arguments
@ -135,31 +147,33 @@ def print_version():
print(__version__) print(__version__)
def here_be_dragons(): def main():
""" """
This is where the magic happens! This is where the magic happens!
This function is run every time you This function is run every time you
execute naxalnet from the commandline execute naxalnet from the commandline
""" """
args = parse_args()
if args.print_wifi: if args.print_wifi:
print_wifi(args) print_wifi()
sys.exit(0) sys.exit(0)
elif args.version: elif args.version:
print_version() print_version()
sys.exit(0) sys.exit(0)
copy_files()
try: setup_devices()
copy_files(args) # Notify systemd that naxalnet is ready.
except PermissionError as error: # see man:sd_notify(3)
logger.error("Cannot copy file: %s", error) notify("READY=1")
sys.exit(3)
try: # Start the daemon so that setup_devices() is called every
setup_devices(args) # time a device is connected or removed.
except DBusError: daemon = Daemon()
logger.exception("Error while communicating with iwd") daemon.add_callback(setup_devices)
sys.exit(4)
logger.debug("Finished.") notify("STATUS=Waiting for changes")
daemon.start()
# naxalnet prints Bye while exiting.
logger.info("Bye")

3
pyproject.toml Normal file
View File

@ -0,0 +1,3 @@
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

View File

@ -27,7 +27,7 @@ install_requires =
[options.entry_points] [options.entry_points]
console_scripts = console_scripts =
naxalnet = naxalnet.scripts:here_be_dragons naxalnet = naxalnet.scripts:main
[options.data_files] [options.data_files]
lib/systemd/system = lib/systemd/system =

View File

@ -1,5 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""
See setup.py --help for usage
"""
from setuptools import setup from setuptools import setup
setup() setup()