mirror of
https://git.disroot.org/pranav/pybatmesh.git
synced 2025-04-24 03:49:05 +05:30
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:
commit
74a061507f
15
CHANGELOG.md
15
CHANGELOG.md
@ -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
|
||||||
|
2
Makefile
2
Makefile
@ -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
|
||||||
|
66
README.md
66
README.md
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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()
|
||||||
|
@ -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
69
naxalnet/daemon.py
Normal 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()
|
@ -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
|
||||||
|
@ -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:
|
||||||
"""
|
"""
|
||||||
|
@ -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()
|
||||||
|
@ -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
3
pyproject.toml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[build-system]
|
||||||
|
requires = ["setuptools", "wheel"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
@ -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 =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user