many changes, see full commit message

- Renamed here_be_dragons() to main().
- Added daemon.py (doesn't do anything yet).
- Added GPL disclaimer to all python files and removed the shebang #!
  from all files.
- args is now defined outside any function in scripts.py
- Changed arguments of some functions in scripts.py
This commit is contained in:
Pranav Jerry 2021-09-06 21:54:24 +05:30
parent 0bcd31b6e3
commit 6fff558405
No known key found for this signature in database
GPG Key ID: F1DCDC4FED0A0C5B
9 changed files with 188 additions and 104 deletions

View File

@ -1,9 +1,12 @@
# Changelog # Changelog
## [Unreleased][] - 2021-09-05 ## [Unreleased][] - 2021-09-06
- Now logs to systemd journal. New dependency - `python3-systemd` - **Logging**: logs to systemd journal when run from systemd, stderr
otherwise.
- New dependency `python3-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 +25,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

@ -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.dev2" __version__ = "0.3.0a2.dev3"

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

59
naxalnet/daemon.py Normal file
View File

@ -0,0 +1,59 @@
# 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.
"""
import logging
from naxalnet.iwd import IWD
class Daemon:
"""implements the daemon part"""
logger = logging.getLogger(__name__)
def __init__(self):
iwd = IWD()
self.device_add_call = self.device_remove_call = None
def on_device_add(self, callback):
"""
run the given callback with no arguments
every time a device is added
"""
self.device_add_call = callback
def on_device_remove(self, callback):
"""
run the given callback with no arguments
every time a device is removed
"""
self.device_remove_call = callback
def register_callbacks(self):
"""
register the callbacks with D-Bus
"""
def start(self):
"""
start the daemon
"""

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
------ ------

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,7 +23,7 @@ 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
@ -40,93 +39,100 @@ from naxalnet.config import parse_args
# from naxalnet.log import logger # from naxalnet.log import logger
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
args = parse_args()
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:
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() iwd = IWD()
adhoc_devices = [] devices = iwd.get_devices()
ap_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: if len(adhoc_devices) != 0:
# Start ad-hoc on first device supporting ad-hoc # Start ad-hoc on first device supporting ad-hoc
adhoc_device = Device(adhoc_devices.pop()) adhoc_device = Device(adhoc_devices.pop())
# The same device is likely to have ap support too. # The same device is likely to have ap support too.
# But we can't start ad-hoc and ap on the same interface. # 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 # So we will remove adhoc_device from ap_devices if it exists there
if adhoc_device.name in ap_devices: if adhoc_device.name in ap_devices:
ap_devices.remove(adhoc_device.name) ap_devices.remove(adhoc_device.name)
logger.info("Starting mesh on %s", adhoc_device.name) logger.info("Starting mesh on %s", adhoc_device.name)
# Turn on adapter if it is off # Turn on adapter if it is off
# See issue #9 # See issue #9
adhoc_adapter = Adapter(adhoc_device.adapter) adhoc_adapter = Adapter(adhoc_device.adapter)
if not adhoc_adapter.is_powered_on(): if not adhoc_adapter.is_powered_on():
logger.debug("Adapter %s is off. Turning on", adhoc_adapter.name) logger.debug("Adapter %s is off. Turning on", adhoc_adapter.name)
adhoc_adapter.power_on() adhoc_adapter.power_on()
adhoc_device.start_adhoc_open(args.adhoc_name) adhoc_device.start_adhoc_open(args.adhoc_name)
# Start Access point if ap_device is not empty, # Start Access point if ap_device is not empty,
# ie, we have more devices # ie, we have more devices
if len(ap_devices) != 0: if len(ap_devices) != 0:
ap_device = Device(ap_devices.pop()) ap_device = Device(ap_devices.pop())
logger.info("Starting WiFi Access Point on %s", ap_device.name) logger.info("Starting WiFi Access Point on %s", ap_device.name)
logger.info("Use naxalnet --print-wifi to get password") 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) ap_adapter = Adapter(ap_device.adapter)
if not ap_adapter.is_powered_on(): if not ap_adapter.is_powered_on():
logger.debug("Adapter %s is off. Turning on", ap_adapter.name) logger.debug("Adapter %s is off. Turning on", ap_adapter.name)
ap_adapter.power_on() ap_adapter.power_on()
ap_device.start_ap(args.ap_ssid, args.ap_passwd) ap_device.start_ap(args.ap_ssid, args.ap_passwd)
else:
logger.info("Not setting up WiFi AP.")
else: else:
logger.info("Not setting up WiFi AP.") logger.warning(
else: "No device found to setup mesh. Make sure a WiFi adapter is connected"
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)
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
@ -141,14 +147,19 @@ 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:
print_wifi()
sys.exit(0)
elif args.version:
print_version()
sys.exit(0)
# --verbose # --verbose
if args.verbose >= 2: if args.verbose >= 2:
loglevel = logging.DEBUG loglevel = logging.DEBUG
@ -164,23 +175,9 @@ def here_be_dragons():
else: else:
logging.basicConfig(level=loglevel) logging.basicConfig(level=loglevel)
if args.print_wifi: copy_files()
print_wifi(args)
sys.exit(0)
elif args.version:
print_version()
sys.exit(0)
try: setup_devices()
copy_files(args)
except PermissionError as error:
logger.error("Cannot copy file: %s", error)
sys.exit(3)
try:
setup_devices(args)
except DBusError:
logger.exception("Error while communicating with iwd")
sys.exit(4)
# naxalnet prints Bye if no errors occured # naxalnet prints Bye if no errors occured
logger.info("Bye") logger.info("Bye")

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 =