pybatmesh/naxalnet/network.py
Pranav Jerry 61a96ea3b3
updated documentation and some other changes
Made messages printed in Makefile more understandable. Removed full path
of naxalnet from the systemd service. Now you can start naxalnet even if
it is installed in /usr/local/bin, if systemd allows (I have not tested
it). Many comments were made to respect the 80 chars per line rule.
And, of course, added some political commentary to insult the global
superpower (superpower in terms of money, military and something else I
forgot). And removed MANIFEST.in, which probably haven't changed anything.
2021-10-02 14:13:53 +05:30

121 lines
4.2 KiB
Python

# 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/>.
"""
network.py
----------
This submodule manages the systemd-networkd configuration. This is used to
add configuration files to the systemd-networkd runtime directory.
Some configuration files have variables which should be substituted by
str.format() in python. The values for these variables can be set using
NetworkD.set_vars(). See files in the systemd-networkd directory for
examples.
"""
import subprocess
from pathlib import Path
from dasbus.connection import SystemMessageBus
NETWORKD_BUS = "org.freedesktop.network1"
NETWORKD_PATH = "/org/freedesktop/network1"
class NetworkD:
"""
Control systemd-networkd using configuration files. Since these
were made for use by naxalnet only, the class is not suitable for
importing outside naxalnet.
"""
def __init__(self, runtime_dir="/run/systemd/network", bus=SystemMessageBus()):
self._bus = bus
self.proxy_reload()
self.variables = {}
self.runtime_path = Path(runtime_dir)
# Create the runtime directory if it doesn't exist
self.runtime_path.mkdir(parents=True, exist_ok=True)
def set_vars(self, **variables):
"""set the variables to replace with str.format"""
self.variables = variables
def proxy_reload(self) -> None:
"""reload the proxy"""
self.proxy = self._bus.get_proxy(NETWORKD_BUS, NETWORKD_PATH)
def reload(self) -> None:
"""
Reload the systemd-networkd configuration. This is used by many
class methods after doing their job.
"""
self.proxy.Reload()
def add_config(self, name: str) -> None:
"""add config file to runtime directory and reload networkd"""
source = Path(name)
destination = self.runtime_path / source.name
# Substitute variables in the config
text = source.read_text(encoding="utf-8").format(**self.variables)
# now write it to a runtime config of the same name
destination.write_text(text, encoding="utf-8")
self.reload()
def is_routable(self) -> bool:
"""returns true if any interface is routable"""
return self.proxy.AddressState == "routable"
def delete_interface(self, name: str) -> None:
"""delete the given interface"""
# If anyone knows a better way of doing this, create
# an issue and get things done
subprocess.run(["networkctl", "delete", name], check=True)
# This is probably not required. This is mainly to shut up
# pylint's messages
self.reload()
def disable_config(self, name: str) -> None:
"""
Disable or mask the config of the same name. This can only be
used for configs in /usr/lib/systemd/network and
/usr/local/lib/systemd/network. It works on the same principle
used by systemctl mask, that is, it created a symlink of the same
name in the runtime directory and links it to /dev/null.
"""
path = self.runtime_path / name
path.symlink_to("/dev/null")
self.reload()
def remove_config(self, name: str) -> None:
"""
remove the file called 'name' from the runtime dir and reload
"""
path = self.runtime_path / name
path.unlink()
self.reload()
def remove_all_configs(self) -> None:
"""
Remove all configs in runtime_path. This will remove all files
in runtime_path without checking who put them there.
"""
for i in self.runtime_path.iterdir():
self.remove_config(i.name)