Skip to content

Provisioning API

The gb10-provision-api is a FastAPI application that serves as the control-plane for provisioning a fresh GB10 device. It operates entirely offline within a 10.88.0.0/24 LAN boundary, binding exclusively to a specific LAN IP to prevent exposure on WAN interfaces. The server provides cloud-init data (user-data and meta-data) keyed by MAC address, serves static provisioning files like the onboard systemd unit and manifest, and records per-device onboarding progress via heartbeats. State is persisted in a clients.json file protected by file locks to ensure concurrency safety during concurrent onboarding attempts.

The API serves cloud-init data to PXE-booting targets via two endpoints: /cloud-init/user-data and /cloud-init/meta-data. Both endpoints resolve the requesting host’s MAC address, preferring an explicit ?mac= query parameter over kernel ARP table lookups.

The _resolve_mac function determines the MAC address for a request. It first checks for an explicit mac query parameter, which is set by GRUB or cloud-init when known. If absent, it attempts to resolve the client’s IP address (request.client.host) to a MAC address. This resolution prioritizes reading /proc/net/arp and falls back to executing ip neigh show if the proc file is unavailable or incomplete. If no MAC can be resolved, the function returns "unknown" to prevent autoinstall fetches from failing due to missing ARP entries .

The /cloud-init/user-data endpoint renders an autoinstall configuration using a Jinja2 template located at {DATA_PATH}/cloud-init-templates/user-data.yaml.j2. The rendering context includes the MAC address, a filesystem-safe MAC slug, the LAN IP, a generated hostname (gb10-pxe-{mac_slug}), and the provisioning server URL derived from the request’s Host header. If the staged template is missing or fails to render, the API serves a minimal fallback template that sets a default password and enables SSH server installation, while logging a warning .

diagram

The API maintains per-MAC onboarding state in a clients.json file located at {DATA_PATH}/state/clients.json. This state is updated via heartbeats and can be queried via the /clients endpoint.

Each MAC address maps to a record containing:

  • mac: The normalized MAC address.
  • ip: The client’s IP address, updated on each heartbeat.
  • hostname: The generated hostname.
  • current_stage: The latest OnboardStage value.
  • last_heartbeat: ISO 8601 timestamp of the last update.
  • stages: A list of all recorded stage events, including phase, timestamp, and optional detail .

State updates are protected by an exclusive file lock (fcntl.flock) on a sibling .lock file. The _record_heartbeat function performs a read-modify-write cycle under this lock: it reads the current state, merges the new heartbeat into the specific MAC record, writes the updated state to a temporary file, and atomically renames it to clients.json. This prevents lost updates when multiple onboarding processes or retries occur concurrently .

The /heartbeat endpoint accepts POST requests from the onboarding GB10 to report progress. The request body is validated against strict enums for stage and phase.

Upon receiving a valid heartbeat, the API normalizes the MAC address, resolves the client IP, and merges the event into the state store. The response includes the updated per-MAC record. The /clients endpoint allows administrators to query the aggregated state of all onboarding devices .

diagram