{% extends "ui/_layout.html" %} {% block title %}Settings - bty-web{% endblock %} {% block content %}
bty-web is gated by the OS password of the
{{ service_user }} account. To rotate the credential,
run sudo passwd {{ service_user }} on the server.
Sessions are server-signed cookies (Starlette's
SessionMiddleware) with a sliding 7-day TTL. To
invalidate every existing session in one shot, rotate the
session secret:
sudo rm /var/lib/bty/session-secret && sudo systemctl
restart bty-web. The restart regenerates the secret on
startup; no reboot needed.
When active, bty-pxe-proxy answers PXE / HTTP-Boot DHCP queries on the chosen interface and bty-tftp serves the iPXE binaries. Pick the interface facing the target machines, supply the subnet they're on, and click Activate. Deactivate stops and disables both daemons. The diagnostic panel below shows each daemon's current state.
{% if missing_netboot_artifacts %} {# Netboot env incomplete: activating PXE now would let clients chain into iPXE but they'd 404 fetching the kernel. Surface the precondition prominently so the operator sees it before they activate (or right after, when the activate handler's warning flash arrives). #}{{ boot_root }}:
{% for name in missing_netboot_artifacts %}
{{ name }}{% if not loop.last %}, {% endif %}
{% endfor %}.
PXE proxy-DHCP can still be activated, but clients chaining
into bty's iPXE script will 404 on the kernel fetch until
these files are present.
{{ pxe.interface }}, subnet
{{ pxe.subnet }}.
{{ pxe.interface }} but that interface is
not currently present. dnsmasq
is failing to bind. Deactivate and re-activate on a present
interface below.
boot_policy=flash won't actually be served until you
activate it here.
Proxy-DHCP only: bty assumes there is already a DHCP server on this segment. Full DHCP is intentionally not offered here - misconfigured rogue-DHCP would conflict with the LAN's real DHCP server. Run a dedicated DHCP daemon next to bty if you need one.
Live state and triage knobs for the two PXE-stack daemons. Both are required for end-to-end PXE; running one without the other leaves clients with a working DHCP offer pointing at a file no one serves (or vice versa). Use these for triage; use the Activate / Deactivate flow above for normal operation.
| Daemon | State | Actions |
|---|---|---|
{{ d.unit }}.service |
{# Map the raw systemctl state to a Bootstrap badge class. ``active`` is green; ``failed`` is red; ``activating`` / ``deactivating`` are amber; everything else (``inactive``, ``unknown``, ...) is neutral grey. #} {% if d.state == 'active' %} {{ d.state }} {% elif d.state == 'failed' %} {{ d.state }} {% elif d.state in ('activating', 'deactivating', 'reloading') %} {{ d.state }} {% else %} {{ d.state }} {% endif %} |
``Start`` of a daemon that doesn't see
/etc/default/bty-pxe-proxy is a no-op: the unit's
ConditionPathExists= guard keeps it cleanly inactive
until you activate the PXE workflow above.
| Time | Daemon | Event | Detail |
|---|---|---|---|
| {{ e.hms_utc }} | {{ e.unit }} |
{# Map event prefix to a Bootstrap badge: offer / complete = green (good), error / giveup = red, ignore = amber, everything else (discover, rrq, ...) neutral. #} {% if e.event in ('dhcp.offer', 'tftp.complete') %} {{ e.event }} {% elif e.event in ('dhcp.error', 'tftp.error', 'tftp.giveup') %} {{ e.event }} {% elif e.event == 'dhcp.ignore' %} {{ e.event }} {% else %} {{ e.event }} {% endif %} | {# Flat key=value list keeps the wire shape obvious. Operators reading this are diagnosing PXE so they want the raw fields, not a stylised view. #} {% for k, v in e.fields.items() %} {{ k }}={{ v }} {% endfor %} |
No daemon events recorded yet. Activate PXE and trigger a target to PXE-boot; this feed populates from journald (which captures the daemons' structured JSON output).
{% endif %}