STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
generate_dhcp_config Namespace Reference

Functions

"NoReturn" _die (str msg)
None _warn (str msg)
str|None normalize_mac (str raw)
ipaddress.IPv4Network resolve_subnet (dict cfg)
str detect_interface (ipaddress.IPv4Network subnet)
list[str] interfaces_in_subnet (str ip_addr_output, ipaddress.IPv4Network subnet)
None write_atomic (Path path, str text)
str recovery_address (str mac)
list[tuple[str, str, str]] collect_reservations (dict cfg, ipaddress.IPv4Network subnet)
str sanitize_hostname (str name)
str build_hosts (list[tuple[str, str, str]] reservations)
str build_gui_reservations (list[tuple[str, str, str]] reservations, dict boards)
str build_conf (*, str interface, ipaddress.IPv4Network subnet, int pool_start, int pool_end, str lease, Path hostsfile, str leasefile)
int main (list[str]|None argv=None)

Variables

 ENV_INTERFACE = os.environ.get("DHCP_INTERFACE")
int DEFAULT_POOL_START = 200
int DEFAULT_POOL_END = 250
str DEFAULT_LEASE = "2h"
str DEFAULT_LEASEFILE = "/var/lib/misc/star-dhcp.leases"
 _MAC_RE = re.compile(r"^([0-9a-f]{2}:){5}[0-9a-f]{2}$")

Detailed Description

Generate dnsmasq DHCP config from the DAQ board registry.

The board LAN is an isolated segment (unmanaged switch + wifi bridge, no router)
that the DAQ server owns end-to-end, so the server runs dnsmasq as the sole DHCP
authority. Each board's static IP is a *reservation* keyed by its MAC; unknown
boards get a lease from a small dynamic pool so their MAC can be discovered and
promoted to a reservation.

Single source of truth is the `[boards.*]` table in the active DAQ config
(the same TOML the rest of the stack reads): each board already carries `ip`
and `board_id`; this reads the `mac` field added alongside them. IP is handed
out unchanged (== 192.168.2.<board_id>), so DHCP replaces *how* a board gets its
address, not *which* address — nothing downstream renumbers.

Emits two files into --out-dir:
  star-dhcp.conf   stable base config (interface, pool, options); DHCP-only.
  star-dhcp.hosts  MAC->IP reservations, one per board that has a mac.

--gui-reservations additionally writes the Test-GUI's reservations.json from
the same table. The GUI carries its own bench DHCP server for stands with no
DAQ host; pointing both at this registry keeps them from disagreeing about
which board owns which address. dnsmasq here remains the authority -- the two
must never serve the same wire at once.

The systemd unit points dnsmasq at star-dhcp.conf, which references the hosts
file via dhcp-hostsfile. Reservations reload on SIGHUP (systemctl reload) with
no service bounce; base-config changes need a restart.

--hosts-only rewrites just the reservations, atomically. star-dhcp-sync.path
runs that (as root, from a root-owned copy of this script) whenever the
deployed config.toml changes, then reloads dnsmasq -- so saving a board's `mac =`
in the config editor is the whole procedure. A config this refuses leaves the
served reservations exactly as they were.

Function Documentation

◆ _die()

"NoReturn" generate_dhcp_config._die ( str msg)
protected

◆ _warn()

None generate_dhcp_config._warn ( str msg)
protected

Definition at line 71 of file generate_dhcp_config.py.

Referenced by collect_reservations().

◆ build_conf()

str generate_dhcp_config.build_conf ( * ,
str interface,
ipaddress.IPv4Network subnet,
int pool_start,
int pool_end,
str lease,
Path hostsfile,
str leasefile )

Definition at line 244 of file generate_dhcp_config.py.

References _die(), and split().

Referenced by main().

◆ build_gui_reservations()

str generate_dhcp_config.build_gui_reservations ( list[tuple[str, str, str]] reservations,
dict boards )
The Test-GUI's reservations.json, from the same registry.

Schema is boardgui.dhcp.Reservation.to_json(): mac, ip, board_id, label.
Written sorted by IP so regenerating produces no spurious diffs.

Definition at line 218 of file generate_dhcp_config.py.

Referenced by main().

◆ build_hosts()

str generate_dhcp_config.build_hosts ( list[tuple[str, str, str]] reservations)

Definition at line 205 of file generate_dhcp_config.py.

Referenced by main().

◆ collect_reservations()

list[tuple[str, str, str]] generate_dhcp_config.collect_reservations ( dict cfg,
ipaddress.IPv4Network subnet )
(name, mac, ip) per board that has a usable mac. Boards without a mac are
skipped with a warning — that's the normal pre-discovery state.

Definition at line 150 of file generate_dhcp_config.py.

References _die(), _warn(), normalize_mac(), and recovery_address().

Referenced by main().

◆ detect_interface()

str generate_dhcp_config.detect_interface ( ipaddress.IPv4Network subnet)
The interface holding an address in `subnet` (`ip -o -4 addr show`).

Definition at line 104 of file generate_dhcp_config.py.

References _die(), and interfaces_in_subnet().

Referenced by main().

◆ interfaces_in_subnet()

list[str] generate_dhcp_config.interfaces_in_subnet ( str ip_addr_output,
ipaddress.IPv4Network subnet )
Parse `ip -o -4 addr show`: names of interfaces with an address in subnet.

Definition at line 118 of file generate_dhcp_config.py.

Referenced by detect_interface().

◆ main()

int generate_dhcp_config.main ( list[str] | None argv = None)

◆ normalize_mac()

str | None generate_dhcp_config.normalize_mac ( str raw)
Return a lowercase colon-form MAC, or None if `raw` isn't a MAC.

Accepts colon- or hyphen-separated, any case. Blank -> None (no reservation
yet, not an error).

Definition at line 75 of file generate_dhcp_config.py.

References _die().

Referenced by collect_reservations().

◆ recovery_address()

str generate_dhcp_config.recovery_address ( str mac)
Where a board sits when no DHCP server answered it:
169.254.<1 + mac[4] % 254>.<mac[5]>. Must match BoardNet::recoveryAddress
(firmware/Hotfire_Code/common/board_net.h) and firmware/tools/ota_upload.py.

Definition at line 142 of file generate_dhcp_config.py.

Referenced by collect_reservations().

◆ resolve_subnet()

ipaddress.IPv4Network generate_dhcp_config.resolve_subnet ( dict cfg)
Board-LAN subnet. Prefer [discovery].subnet, fall back to
[system.network].base_ip, else derive from the board IPs.

Definition at line 88 of file generate_dhcp_config.py.

References _die().

Referenced by main().

◆ sanitize_hostname()

str generate_dhcp_config.sanitize_hostname ( str name)
dnsmasq accepts a hostname label per reservation; keep it DNS-safe.

Definition at line 199 of file generate_dhcp_config.py.

◆ write_atomic()

None generate_dhcp_config.write_atomic ( Path path,
str text )
dnsmasq may re-read at any moment; it must never see half a file.

Definition at line 134 of file generate_dhcp_config.py.

Referenced by main().

Variable Documentation

◆ _MAC_RE

generate_dhcp_config._MAC_RE = re.compile(r"^([0-9a-f]{2}:){5}[0-9a-f]{2}$")
protected

Definition at line 63 of file generate_dhcp_config.py.

◆ DEFAULT_LEASE

str generate_dhcp_config.DEFAULT_LEASE = "2h"

Definition at line 60 of file generate_dhcp_config.py.

◆ DEFAULT_LEASEFILE

str generate_dhcp_config.DEFAULT_LEASEFILE = "/var/lib/misc/star-dhcp.leases"

Definition at line 61 of file generate_dhcp_config.py.

◆ DEFAULT_POOL_END

int generate_dhcp_config.DEFAULT_POOL_END = 250

Definition at line 59 of file generate_dhcp_config.py.

◆ DEFAULT_POOL_START

int generate_dhcp_config.DEFAULT_POOL_START = 200

Definition at line 58 of file generate_dhcp_config.py.

◆ ENV_INTERFACE

generate_dhcp_config.ENV_INTERFACE = os.environ.get("DHCP_INTERFACE")

Definition at line 57 of file generate_dhcp_config.py.