mirror of
https://git.disroot.org/pranav/pybatmesh.git
synced 2024-11-27 01:02:15 +05:30
many changes -- read full commit
* Improved docstrings, README * Added argument --version and its implementation * Added "uninstall" rule to Makefile and added it in the README * Updated CHANGELOG * Cleaned up code I've probably forgot something so we can't merge to master yet. And we still have to add installation instructions for ubuntu and fedora
This commit is contained in:
parent
fe146b7a0d
commit
d7a9edc1e8
@ -1,16 +1,18 @@
|
||||
# Changelog
|
||||
|
||||
## [Unreleased][] - 2021-08-13
|
||||
## [Unreleased][] - 2021-08-14
|
||||
|
||||
### Added
|
||||
|
||||
- Support for arguments
|
||||
- Configuration file support
|
||||
- New versioning scheme that conforms to PEP 440
|
||||
- Made messages more readable
|
||||
- Improved documentation in docstrings
|
||||
|
||||
### Changed
|
||||
|
||||
- Changed default name of adhoc network. This will make naxalnet
|
||||
- Changed default name of mesh network. This will make naxalnet
|
||||
incompatible with previous versions.
|
||||
|
||||
## [v0.2.0][] - 2021-07-26
|
||||
|
10
Makefile
10
Makefile
@ -1,5 +1,8 @@
|
||||
# This makefile uses setup.py under the hood
|
||||
# This makefile uses setup.py under the hood.
|
||||
# In ubuntu, python and pip are symlinks to python2 and pip2.
|
||||
# So we have to specify python as python3 by default.
|
||||
PYTHON := python3
|
||||
PIP := pip3
|
||||
DESTDIR:= /
|
||||
|
||||
all: build
|
||||
@ -10,5 +13,10 @@ build:
|
||||
install: build
|
||||
$(PYTHON) setup.py install --root="$(DESTDIR)" --optimize=1 --skip-build
|
||||
|
||||
uninstall:
|
||||
$(PIP) uninstall naxalnet
|
||||
rm -rf /usr/share/naxalnet /usr/lib/systemd/system/naxalnet.service
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf build naxalnet.egg-info
|
||||
|
@ -200,14 +200,15 @@ When a shutdown occurs, [enable naxalnet][enablenx]
|
||||
|
||||
## Uninstalling
|
||||
|
||||
If you installed naxalnet manually, there is no way to uninstall
|
||||
than manually removing the files:
|
||||
If you installed naxalnet manually, use make uninstall to remove
|
||||
naxalnet and its data files:
|
||||
|
||||
```sh
|
||||
sudo pip uninstall naxalnet
|
||||
sudo rm -rf /usr/share/naxalnet* /usr/lib/systemd/system/naxalnet.service
|
||||
sudo make uninstall
|
||||
```
|
||||
|
||||
This requires python pip to be installed.
|
||||
|
||||
## Contributing or reporting bugs
|
||||
|
||||
See [HACKING.md](HACKING.md)
|
||||
|
@ -36,4 +36,4 @@ See README.md for documentation.
|
||||
#
|
||||
# In case you forgot to add a version, put the next number
|
||||
# in the next commit
|
||||
__version__ = "0.2.0a3.dev2"
|
||||
__version__ = "0.2.0a3.dev3"
|
||||
|
@ -8,16 +8,48 @@ This file contains functions to parse configuration files
|
||||
and arguments. Most of these functions are meant to be used
|
||||
by parse_args() internally, so only parse_args() should
|
||||
be imported outside this file.
|
||||
|
||||
Some parts of naxalnet can be configured by configuration
|
||||
files and arguments. First, the default values from
|
||||
default.py is taken. Then, key-value pairs from the
|
||||
configuration files are read, if they exist, in the
|
||||
following order:
|
||||
|
||||
- First it reads /usr/share/naxalnet/naxalnet.conf
|
||||
and then from /usr/share/naxalnet/naxalnet.conf.d/*.conf
|
||||
where *.conf means any file with the name ending with
|
||||
.conf
|
||||
- Then, it looks for the files naxalnet.conf and
|
||||
naxalnet.conf.d/*.conf from the directory
|
||||
/etc/naxalnet, like it did up above.
|
||||
- Then it parses the arguments from the commandline,
|
||||
storing the values in the files parsed until now
|
||||
as fallback. Finally you get an argpase.Namespace object
|
||||
from parse_args().
|
||||
Because of the way this is implemented, all key-value
|
||||
pairs in the configuration should have an argument
|
||||
too, or they won't be parsed.
|
||||
|
||||
All the key-value pairs are replaced if they exist
|
||||
by each new configuration file parsed, similar
|
||||
to how systemd parses configuration and service files.
|
||||
If any of the files checked does not exist, then they are
|
||||
ignored and the next combination is checked. If none of
|
||||
the config files exist and no arguments are given, the
|
||||
fallback data from default.py is used.
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from configparser import ConfigParser
|
||||
from argparse import ArgumentParser
|
||||
from argparse import ArgumentParser, Namespace
|
||||
from naxalnet.default import CONFIG, CONFIG_FILES, CONFIG_DIRS
|
||||
|
||||
|
||||
def get_config_files():
|
||||
"""returns list of configuration files as Path objects to parse"""
|
||||
"""
|
||||
Read list of configuration files and return a list
|
||||
of files that exists as pathlib.Path objects
|
||||
"""
|
||||
config_files = []
|
||||
for directory in CONFIG_DIRS:
|
||||
path = Path(directory)
|
||||
@ -43,7 +75,7 @@ def parse_config():
|
||||
return parser
|
||||
|
||||
|
||||
def parse_args():
|
||||
def parse_args() -> Namespace:
|
||||
"""
|
||||
Parse all arguments and return ArgumentParser.parse_args(),
|
||||
with values in config files as fallback. Ideally, only this
|
||||
@ -69,6 +101,7 @@ def parse_args():
|
||||
help="password of the WiFi AP",
|
||||
default=config["ap"]["passwd"],
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--adhoc-name",
|
||||
"-a",
|
||||
@ -76,32 +109,33 @@ def parse_args():
|
||||
default=config["adhoc"]["name"],
|
||||
help="name of adhoc network",
|
||||
)
|
||||
# TODO: print info about wifi network from config and args and exit
|
||||
|
||||
parser.add_argument(
|
||||
"--print-wifi",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="prints the ssid and password of the WiFi network and exit",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--networkd-config-dir",
|
||||
type=str,
|
||||
default=config["networkd"]["confdir"],
|
||||
help="the directory where systemd-networkd configuration files are stored",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--networkd-runtime-dir",
|
||||
type=str,
|
||||
default=config["networkd"]["runtimedir"],
|
||||
help="the 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(
|
||||
"--version",
|
||||
default=False,
|
||||
action="store_true",
|
||||
help="prints the version and exit",
|
||||
)
|
||||
# TODO: implement --verbose
|
||||
# parser.add_argument(
|
||||
# "-v",
|
||||
# "--verbose",
|
||||
# help="increase output verbosity; can be used multiple times",
|
||||
# action="count",
|
||||
# default=0,
|
||||
# )
|
||||
|
||||
return parser.parse_args()
|
||||
|
@ -1,8 +1,15 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
default.py
|
||||
----------
|
||||
|
||||
This file contains default values for configuration.
|
||||
The values are likely to be replaced by other configuration files.
|
||||
This is taken as fallback data by config.py if no
|
||||
configuration files were found, or if a key-value pair
|
||||
was not present in the config file. The data will be
|
||||
further changed by arguments if naxalnet is called
|
||||
from the commandline. See config.py for more info.
|
||||
"""
|
||||
|
||||
CONFIG = {
|
||||
@ -15,5 +22,5 @@ CONFIG = {
|
||||
}
|
||||
|
||||
# glob
|
||||
CONFIG_FILES = ["naxalnet.conf", "naxalnet.d/*.conf"]
|
||||
CONFIG_DIRS = ["/etc"]
|
||||
CONFIG_FILES = ["naxalnet.conf", "naxalnet.conf.d/*.conf"]
|
||||
CONFIG_DIRS = ["/usr/share/naxalnet", "/etc/naxalnet"]
|
||||
|
@ -16,7 +16,48 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
"""Manage wifi adapter via iwd D-Bus api"""
|
||||
"""
|
||||
iwd.py
|
||||
------
|
||||
|
||||
This file contains methods to communicate with iwd via
|
||||
its D-Bus API and control WiFi adapters.
|
||||
|
||||
Some terms used here, such as device and adapter might
|
||||
confuse you if you haven't used iwctl before.
|
||||
Just as a quick reference, here is a list of terms
|
||||
and what they mean:
|
||||
|
||||
- ad-hoc: a mode supported by some WiFi adapters to
|
||||
start a decentralised network, where there
|
||||
is no central point of failure.
|
||||
|
||||
- ap: a mode used to start a central access point
|
||||
so that other machines without naxalnet can
|
||||
connect to the mesh. AP is also known as
|
||||
WiFi hotspot.
|
||||
|
||||
- station: this is the mode most WiFi adapters use
|
||||
by default. This mode is used to connect to
|
||||
an ap. naxalnet DOES NOT use this mode.
|
||||
|
||||
- adapter: a physical WiFi chip or something similar
|
||||
that is present inside most laptops and phones
|
||||
or can be connected via USB to a machine.
|
||||
|
||||
- device: an interface provided by the kernel to control
|
||||
an adapter. Some adapters can have multiple
|
||||
devices so that you can start an ap on one device
|
||||
and an ad-hoc on the other. By default, iwd starts
|
||||
only one device each for one adapter.
|
||||
|
||||
- machine: Since iwd uses the term device for a
|
||||
WiFi interface, we use the word machine to
|
||||
refer to a computer, or a laptop, or a phone.
|
||||
|
||||
- node: a machine that runs naxalnet and is therefore
|
||||
connected to the mesh.
|
||||
"""
|
||||
|
||||
from dasbus.connection import SystemMessageBus
|
||||
|
||||
@ -27,7 +68,7 @@ IWD_ADAPTER_INTERFACE = "net.connman.iwd.Adapter"
|
||||
|
||||
# If you are new to D-Bus, you might want to use a program
|
||||
# such as D-Feet (https://wiki.gnome.org/Apps/DFeet) for reference.
|
||||
# And try out iwctl to understand iwd's bus objects
|
||||
# And try out iwctl to understand iwd's bus objects.
|
||||
|
||||
|
||||
class IWD:
|
||||
@ -155,23 +196,24 @@ class Device:
|
||||
# name of adapter ('phy0' for example)
|
||||
self.adapter = self._iwd.get_name_from_path(adapter_path)
|
||||
|
||||
def is_adhoc_started(self):
|
||||
def is_adhoc_started(self) -> bool:
|
||||
"""
|
||||
Returns True if an adhoc network is started on this device.
|
||||
Returns None if device is not powered on or not in ad-hoc mode.
|
||||
Returns False if the network is in staring stage, device
|
||||
is not powered on or not in ad-hoc mode.
|
||||
"""
|
||||
if self.is_powered_on() and self.get_mode() == "ad-hoc":
|
||||
return self._proxy.Started
|
||||
# If above condition is not true, return None
|
||||
return None
|
||||
# If above condition is not true, return False
|
||||
return False
|
||||
|
||||
def is_ap_started(self):
|
||||
def is_ap_started(self) -> bool:
|
||||
"""
|
||||
Same as is_adhoc_started(), but for ap
|
||||
"""
|
||||
if self.is_powered_on() and self.get_mode() == "ap":
|
||||
return self._proxy.Started
|
||||
return None
|
||||
return False
|
||||
|
||||
def get_mode(self) -> str:
|
||||
"""
|
||||
@ -250,8 +292,6 @@ class Adapter:
|
||||
self._proxy = self._bus.get_proxy(IWD_BUS, self._path)
|
||||
self.name = self._proxy.Name
|
||||
self.supported_modes = self._proxy.SupportedModes
|
||||
self.model = self._proxy.Model
|
||||
self.vendor = self._proxy.Vendor
|
||||
|
||||
def is_powered_on(self) -> bool:
|
||||
"""returns True if adapter is powered on, False otherwise"""
|
||||
|
@ -16,24 +16,25 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
Setup a working BATMAN Advanced network
|
||||
with systemd-networkd and iwd
|
||||
scripts.py
|
||||
----------
|
||||
|
||||
The functions in this file is used for reading configs, args
|
||||
and doing the things this program is supposed to do.
|
||||
This file is named scripts.py because the original developer
|
||||
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.
|
||||
When run from the commandline, the function here_be_dragons() is called.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from shutil import copy
|
||||
from dasbus.error import DBusError
|
||||
from naxalnet.iwd import IWD, Device, Adapter
|
||||
from naxalnet import __version__
|
||||
from naxalnet.iwd import Adapter, Device, IWD
|
||||
from naxalnet.config import parse_args
|
||||
|
||||
NETWORKD_CONFIGS = "/usr/share/naxalnet/networkd"
|
||||
NETWORKD_VOLATILE_DIR = "/run/systemd/network"
|
||||
# default values
|
||||
ADHOC_NAME = "HelloWorld"
|
||||
AP_SSID = "NaxalNet"
|
||||
AP_PASSWD = "naxalnet256"
|
||||
|
||||
|
||||
def copy_files(args):
|
||||
"""
|
||||
@ -59,7 +60,8 @@ def setup_devices(args):
|
||||
"""
|
||||
Setup wifi interfaces using iwd
|
||||
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()
|
||||
devices = iwd.get_devices()
|
||||
@ -68,6 +70,9 @@ def setup_devices(args):
|
||||
|
||||
# Find devices supporting ad-hoc and ap
|
||||
for i in devices:
|
||||
# For each device, check if its adapter supports
|
||||
# ad-hoc or ap. Many adapters will support both,
|
||||
# so we will prioritise ad-hoc over ap.
|
||||
device = Device(i)
|
||||
adapter = Adapter(device.adapter)
|
||||
if adapter.supports_mode("ad-hoc"):
|
||||
@ -80,10 +85,10 @@ def setup_devices(args):
|
||||
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.
|
||||
# Remove adhoc_device from ap_devices if it exists there
|
||||
# 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)
|
||||
print("Working on ad-hoc")
|
||||
print("Starting mesh on", adhoc_device.name)
|
||||
# Turn on adapter if it is off
|
||||
# See issue #9
|
||||
adhoc_adapter = Adapter(adhoc_device.adapter)
|
||||
@ -94,8 +99,9 @@ def setup_devices(args):
|
||||
# Start Access point if ap_device is not empty,
|
||||
# ie, we have more devices
|
||||
if len(ap_devices) != 0:
|
||||
print("Working on AP")
|
||||
ap_device = Device(ap_devices.pop())
|
||||
print("Starting WiFi Access point on", ap_device.name)
|
||||
print('Use "naxalnet --print-wifi" to get password')
|
||||
# Turn on adapter if it is off
|
||||
# See issue #9
|
||||
ap_adapter = Adapter(ap_device.adapter)
|
||||
@ -106,21 +112,34 @@ def setup_devices(args):
|
||||
|
||||
|
||||
def print_wifi(args):
|
||||
"""
|
||||
Prints the name and password of the adhoc, and ap
|
||||
from the arguments
|
||||
"""
|
||||
print("Mesh name:", args.adhoc_name)
|
||||
print("SSID:", args.ap_ssid)
|
||||
print("Password:", args.ap_passwd)
|
||||
|
||||
|
||||
def print_version():
|
||||
"""Just does what the name suggests"""
|
||||
print(__version__)
|
||||
|
||||
|
||||
def here_be_dragons():
|
||||
"""
|
||||
This is where the magic happens!
|
||||
This function is run every time you
|
||||
execute naxalnet from commandline
|
||||
execute naxalnet from the commandline
|
||||
"""
|
||||
args = parse_args()
|
||||
|
||||
if args.print_wifi:
|
||||
print_wifi(args)
|
||||
sys.exit(0)
|
||||
elif args.version:
|
||||
print_version()
|
||||
sys.exit(0)
|
||||
|
||||
try:
|
||||
copy_files(args)
|
||||
|
Loading…
Reference in New Issue
Block a user