Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to set static IPs, gateway, DNS to wired/wireless networks #5

Open
wants to merge 38 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
0ca6a42
Removed logic to disable ethernet
nikeflight Jan 16, 2025
79a1f9a
Add support for wireless:
nikeflight Jan 16, 2025
f437299
Added support for wired networks: setting static ip, gateway, netmask…
nikeflight Jan 17, 2025
afeb7b9
remove dhcpd in piaware_config.py
nikeflight Jan 20, 2025
531a9d0
Add start-network.service, start_network.py to up the connections aft…
nikeflight Jan 20, 2025
a07dffa
Merge pull request #6 from flightaware/wifi-reboot-fix
nikeflight Jan 20, 2025
9ca90ee
Revert network-manager to dhcp in wireless/wired-type
nikeflight Jan 21, 2025
e821e38
Add test commands to README
nikeflight Jan 21, 2025
c0140e6
Add in logic to `ip addr show` then | to `grep`. Makes parsing for br…
nikeflight Jan 22, 2025
885d14a
manually upping wireless connections is not needed. Because we create…
nikeflight Jan 22, 2025
3d3f25a
Change network manager back to dhcp in debian-bookworm/piaware-config…
nikeflight Jan 22, 2025
4d7474c
Merge branch 'wired-network-change' of https://github.com/flightaware…
nikeflight Jan 22, 2025
9bff625
Add an ignore_list field to MetadataSetting. Adding a file to this li…
nikeflight Jan 22, 2025
4b14afe
updated .gitignore
nikeflight Jan 22, 2025
5ca30df
Addressing PR comments
nikeflight Jan 23, 2025
ccda2fa
PR comments
nikeflight Jan 23, 2025
5389a40
Merge branch 'wired-network-change' of https://github.com/flightaware…
nikeflight Jan 23, 2025
b7e6b0a
PR comments
nikeflight Jan 23, 2025
69ecfef
Add shebang to generate_network_config_bookworm.py
nikeflight Jan 23, 2025
a930fbd
Merge pull request #7 from flightaware/verify-brd-address
nikeflight Jan 24, 2025
9d5f156
PR comments
nikeflight Jan 24, 2025
41cebad
drop .py extension from generate_network_config_bookworm
nikeflight Jan 27, 2025
eb6fdf5
Change ignore_list to deprecated field
nikeflight Jan 27, 2025
2a566ab
Clean up dict init
nikeflight Jan 27, 2025
12512bb
Chnage netmask to be dotted decimal format
nikeflight Jan 27, 2025
1c13391
Add in default netmask for class A,B,C static IPs
nikeflight Jan 28, 2025
a27c1a0
Clean up unused settings
nikeflight Jan 29, 2025
07635dd
Revert "Clean up unused settings"
nikeflight Jan 29, 2025
f223731
We actually need the settings that I removed.
nikeflight Jan 29, 2025
c08b88f
Add in WHITEOUT logic
nikeflight Jan 29, 2025
b5325f1
Add netmask validation
nikeflight Jan 29, 2025
d088f43
PR comments
nikeflight Jan 30, 2025
2c8bdf2
Update piaware-restart-network-bookworm script and generalize name wh…
eric1tran Jan 31, 2025
8f79c06
Fix typo
eric1tran Jan 31, 2025
5d1ffbf
Moved validation and parsing to class types
nikeflight Jan 31, 2025
10e875f
Add method to read config
nikeflight Jan 31, 2025
f54fffb
Move piaware_config.py to own directory
nikeflight Jan 31, 2025
7cf8b87
Merge pull request #8 from flightaware/update_piaware_network_restart…
eric1tran Feb 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions debian-bookworm/piaware-config.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#
# This file configures the Piaware sdcard image
# configuration. Whenever the system boots, this
# file is read and its contents are used to
# configure the system.
#
# Lines beginning with a '#' are comment lines
# and are ignored. Blank lines are also ignored.
# All other lines specify configuration settings.
#

# For simplicity, this file only shows the most common options.
# For a complete list of options, see
# https://flightaware.com/adsb/piaware/advanced_configuration

#
# NETWORK CONFIGURATION
#

# By default, PiAware will use NetworkManager when connecting to your network.
nikeflight marked this conversation as resolved.
Show resolved Hide resolved
# For other configurations, see the Advanced Configuration page
# linked at the top of this file.

# For the latest Bookworm image, if an ethernet cable is inserted, wired-network will be enabled.
# If not, the wired-network will be disabled.

# Should piaware use a wifi adaptor for network access?
# If you are using a Pi 3, this will use the built-in wifi.
# Otherwise, you will need to attach a supported USB wifi adaptor.

wireless-network yes

# Wifi SSID and password.
# This should be changed to match your wireless
# network SSID and, for networks that require
# a passphrase, the passphrase.
#
# If your SSID or password contains characters other than
# numbers and letters, such as the # character or whitespace,
# you should enclose the value in quotation marks. For example,
# "pass word" or "pass#word".
#
# To include quotation marks (") in a quoted value, use \"
# To include a backslash (\) in a quoted value, use \\

wireless-ssid MyWifiNetwork
wireless-password s3cr3t99

#
# 1090MHZ RECEIVER CONFIGURATION
#

# For a complete list of receiver types and their associated settings,
# see the Advanced Configuration page linked at the top of this file.

# For a receiver type of 'rtlsdr', this setting controls the dongle gain.
# Use "max" for maximum gain. Other values are interpreted as a gain in dB.
rtlsdr-gain max

#
# OTHER CONFIGURATION
#

# Should automatic system updates (initiated by FlightAware) be allowed?
allow-auto-updates yes

# Should manual system updates (initiated by you from the website control
# panel) be allowed?
allow-manual-updates yes

# Should PiAware enable multilateration where possible?
# You may need to disable this if multilateration overloads your receiver.
allow-mlat yes

# Should PiAware enable reception of Mode A/C messages when requested?
# You may need to disable this if processing Mode A/C overloads your receiver.
allow-modeac yes


# Additional settings can be added below.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ DefaultDependencies=no

[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /usr/lib/piaware-support/generate-network-config-bookworm.py
ExecStart=/usr/bin/python3 /usr/lib/piaware-support/generate_network_config_bookworm.py
eric1tran marked this conversation as resolved.
Show resolved Hide resolved

[Install]
WantedBy=network.target
4 changes: 2 additions & 2 deletions debian-bookworm/piaware-support.install
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package/*.tcl usr/lib/piaware-support/
scripts/generate-network-config-bookworm.py usr/lib/piaware-support/
scripts/generate_network_config_bookworm.py usr/lib/piaware-support/
scripts/generate-receiver-config usr/lib/piaware-support/
scripts/piaware_config.py usr/lib/piaware-support/
scripts/set-rfkill usr/lib/piaware-support/
scripts/piaware-console-status usr/lib/piaware-support/
scripts/rpi-bootconfig usr/lib/piaware-support/
etc/modprobe.d/
piaware-config.txt boot/firmware
debian-bookworm/piaware-config.txt boot/firmware
debian/piaware-image-config.txt usr/share/piaware-support/
systemd/NetworkManager.service.d/restart.conf lib/systemd/system/NetworkManager.service.d/
systemd/config-ready.target lib/systemd/system/
Expand Down
67 changes: 0 additions & 67 deletions scripts/generate-network-config-bookworm.py

This file was deleted.

144 changes: 144 additions & 0 deletions scripts/generate_network_config_bookworm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
from piaware_config import get_standard_config_group, ConfigGroup
from uuid import uuid4
import subprocess
import os

SYS_CON_DIR = "/etc/NetworkManager/system-connections"

def format_dns(dns_string: str) -> str:
names = dns_string.strip(" \n\t")
eric1tran marked this conversation as resolved.
Show resolved Hide resolved
names = names.split(" ")
formatted = ";".join(names) + ";"
return formatted

def check_address_and_netmask_set(network_type: str, config: ConfigGroup):
if config.get(f"{network_type}-address") is None:
raise ValueError(f"{network_type}-type was set to static but address was not set")
if config.get(f"{network_type}-netmask") is None:
raise ValueError(f"{network_type}-type was set to static but netmask was not set")

def configure_static_network(network_type: str, config: ConfigGroup):
check_address_and_netmask_set(network_type, config)

ip = ""
static_ip = config.get(f"{network_type}-address") + "/" + config.get(f"{network_type}-netmask")
gateway = config.get(f"{network_type}-gateway")
if gateway is not None:
static_ip += f",{gateway}"
ip += f"address1={static_ip}\n"

name_servers = config.get(f"{network_type}-nameservers")
if name_servers is not None:
ip += f"dns={format_dns(name_servers)}\n"
return ip
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since what you're doing here is building a list of lines, it might be more obvious to literally build a list of lines, then str.join() the list at the end.


def wired_conn_file_template(config: ConfigGroup):
eric1tran marked this conversation as resolved.
Show resolved Hide resolved
new_uuid = uuid4()
file = f"""
[connection]
id=wired
uuid={new_uuid}
type=ethernet
autoconnect-priority=999
interface-name=eth0

[ethernet]
"""
ipv4 = """
[ipv4]
"""
if config.get("wired-type") == "static":
try:
ipv4 += configure_static_network("wired", config)
ipv4 += "method=manual\n"
except ValueError:
ipv4 += "method=auto\n"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hides a multitude of errors in a non-obvious way. Bad config should really result in user-visible errors.

else:
ipv4 += "method=auto\n"
file += ipv4
file += """
[ipv6]
addr-gen-mode=default
method=auto

[proxy]
"""

return file

def wireless_conn_file_template(config: ConfigGroup):
nikeflight marked this conversation as resolved.
Show resolved Hide resolved
new_uuid = uuid4()
ssid = config.get("wireless-ssid")
psk = config.get("wireless-password")

file = f"""
[connection]
id=wireless
uuid={new_uuid}
type=wifi

[wifi]
mode=infrastructure
ssid={ssid}

[wifi-security]
key-mgmt=wpa-psk
psk={psk}
"""

ipv4 = """
[ipv4]
"""
if config.get("wireless-type") == "static":
try:
ipv4 += configure_static_network("wireless", config)
ipv4 += f"method=manual\n"
except ValueError:
ipv4 += "method=auto\n"
else:
ipv4 += "method=auto\n"

ipv4 += """
[ipv6]
addr-gen-mode=default
method=auto

[proxy]
"""
file += ipv4
return file

def generate_wired_network_config(config: ConfigGroup):
with open(f"{SYS_CON_DIR}/wired.nmconnection", "w") as conn_file:
eric1tran marked this conversation as resolved.
Show resolved Hide resolved
conn_file.write(wired_conn_file_template(config))

subprocess.run(["chmod", "600", f"{SYS_CON_DIR}/wired.nmconnection"])
eric1tran marked this conversation as resolved.
Show resolved Hide resolved
subprocess.run(["sync"])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're going to sync, let's do it once at the very end.

Also, use os.sync


print("Created wired connection")
subprocess.run(["nmcli", "con", "up", "wired"])


def generate_wireless_network_config(config: ConfigGroup):
if not config.get("wireless-network"):
print("wireless-network set to no")
subprocess.run(["nmcli", "radio", "wifi", "off"])
return

eric1tran marked this conversation as resolved.
Show resolved Hide resolved
with open(f"{SYS_CON_DIR}/wireless.nmconnection", "w") as conn_file:
conn_file.write(wireless_conn_file_template(config))

subprocess.run(["chmod", "600", f"{SYS_CON_DIR}/wireless.nmconnection"])
subprocess.run(["sync"])
eric1tran marked this conversation as resolved.
Show resolved Hide resolved

print("Upping wireless")
subprocess.run(["nmcli", "radio", "wifi", "on"])
subprocess.run(["nmcli", "con", "up", "wireless"])

def main(dryrun=False, extra_file_path: str = None):
config_group = get_standard_config_group(extra_file_path)
generate_wired_network_config(config_group)
generate_wireless_network_config(config_group)

if __name__ == "__main__":
main()
26 changes: 13 additions & 13 deletions scripts/piaware_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

PIAWARE_CONFIG_ENUMS["receiver"] = ["rtlsdr", "sdr", "bladerf", "beast", "relay", "radarcape", "radarcape-local", "other", "none"]
PIAWARE_CONFIG_ENUMS["uat_receiver"] = ["sdr", "stratuxv3", "other", "none"]
PIAWARE_CONFIG_ENUMS["network_type"] = ["static", "dhcp"]
PIAWARE_CONFIG_ENUMS["network_type"] = ["static", "dhcp", "network-manager"]
nikeflight marked this conversation as resolved.
Show resolved Hide resolved
PIAWARE_CONFIG_ENUMS["slow_cpu"] = ["yes", "no", "auto"]
PIAWARE_CONFIG_ENUMS["network_config_style"] = ["default", "buster", "jessie"]

Expand Down Expand Up @@ -57,20 +57,20 @@ def __init__(self, **kwargs):
self.settings["network-config-style"] = MetadataSettings(setting_type="network_config_style", default="default", sdonly=True, network=True)
self.settings["wired-network"] = MetadataSettings(setting_type="bool", default=True, sdonly=True, network=True)
self.settings["wired-type"] = MetadataSettings(setting_type="network_type", default="dhcp", sdonly=True, network=True)
self.settings["wired-address"] = MetadataSettings(sdonly=True, network=True)
self.settings["wired-netmask"] = MetadataSettings(sdonly=True, network=True)
self.settings["wired-broadcast"] = MetadataSettings(sdonly=True, network=True)
self.settings["wired-gateway"] = MetadataSettings(sdonly=True, network=True)
self.settings["wired-nameservers"] = MetadataSettings(default= ["8.8.8.8", "8.8.4.4"], sdonly=True, network=True)
self.settings["wired-address"] = MetadataSettings(sdonly=True, network=True, setting_type="str")
nikeflight marked this conversation as resolved.
Show resolved Hide resolved
self.settings["wired-netmask"] = MetadataSettings(sdonly=True, network=True, setting_type="str")
self.settings["wired-broadcast"] = MetadataSettings(sdonly=True, network=True, setting_type="str")
self.settings["wired-gateway"] = MetadataSettings(sdonly=True, network=True, setting_type="str")
self.settings["wired-nameservers"] = MetadataSettings(default= "8.8.8.8 8.8.4.4", sdonly=True, network=True, setting_type="str")
self.settings["wireless-network"] = MetadataSettings(setting_type="bool", default=False, sdonly=True, network=True)
self.settings["wireless-ssid"] = MetadataSettings(sdonly=True, network=True, setting_type="str")
self.settings["wireless-password"] = MetadataSettings(protect=True, sdonly=True, network=True, setting_type="str")
self.settings["wireless-type"] = MetadataSettings(setting_type="network_type", default="dhcp", sdonly=True, network=True)
self.settings["wireless-address"] = MetadataSettings(sdonly=True, network=True)
self.settings["wireless-broadcast"] = MetadataSettings(sdonly=True, network=True)
self.settings["wireless-netmask"] = MetadataSettings(sdonly=True, network=True)
self.settings["wireless-gateway"] = MetadataSettings(sdonly=True, network=True)
self.settings["wireless-nameservers"] = MetadataSettings(default = ["8.8.8.8", "8.8.4.4"], sdonly=True, network=True)
self.settings["wireless-address"] = MetadataSettings(sdonly=True, network=True, setting_type="str")
self.settings["wireless-broadcast"] = MetadataSettings(sdonly=True, network=True, setting_type="str")
self.settings["wireless-netmask"] = MetadataSettings(sdonly=True, network=True, setting_type="str")
self.settings["wireless-gateway"] = MetadataSettings(sdonly=True, network=True, setting_type="str")
self.settings["wireless-nameservers"] = MetadataSettings(default = "8.8.8.8 8.8.4.4", sdonly=True, network=True, setting_type="str")
self.settings["wireless-country"] = MetadataSettings(default = "00", setting_type="country", sdonly=True, network=True)
self.settings["allow-dhcp-duic"] = MetadataSettings(default=True, setting_type="bool", sdonly=True, network=True)
self.settings["http-proxy-host"] = MetadataSettings(network=True)
Expand Down Expand Up @@ -163,7 +163,7 @@ def convert_value(self, key, val) -> any:
return self.convert_str_to_gain(val)

case _:
raise TypeError(f"Unrecognized type {t}")
raise TypeError(f"Cannot convert unrecognized type {t} for {key}, {val}")

def validate_bool(self, val: str) -> bool:
val = val.lower()
Expand Down Expand Up @@ -240,7 +240,7 @@ def validate_value(self, key, val) -> bool:
return self.validate_gain(val)

case _:
raise TypeError(f"Unrecognized type {t}")
raise TypeError(f"Cannot validate Unrecognized type {t} from {key}, {val}")


class ConfigFile():
Expand Down
Loading