--- title: Editing the hardware docs --- # Editing the hardware docs The hardware inventory is **one Markdown file per device** under `docs/hardware/`. The YAML frontmatter at the top of each file is the single source of truth. Everything you see rendered — the [Hardware Overview](../hardware/index.md) table, the per-device **Specs** box, the [rack elevation](../infrastructure/racks/rack01.md) SVG, and the network graph — is **generated** from that frontmatter. !!! warning "The golden rule" After editing any file in `docs/hardware/`, run **`make docs-index`** and commit the regenerated files. CI rebuilds the indices and fails the build if they differ from what you committed. This is the single most common reason a push goes red. ## Quick start: add a device 1. Pick a hostname following the [naming scheme](hardware-naming-scheme.md): `` — a 2-digit number, unique per kind (`srv`, `sw`, `pp`, `pdu`, `ups`, `shf`, …). Example: `srv06`. 2. Create `docs/hardware/.md`. **The filename stem must equal the `hostname` field** — `srv06.md` must contain `hostname: srv06`. 3. Fill in the frontmatter (see the reference below). Write any free-text under `## Notes`. 4. Run `make docs-index` and commit **both** your new file and the regenerated index / rack files. ```markdown --- hostname: srv06 kind: server status: staging location: The pile cpu: Intel Core i5-3570K @ 3.40GHz cpu_cores: 4 cpu_threads: 4 ram_gb: 8 storage_gb: 500 storage_type: hdd nic_gbps: 1 rack: rack01 rack_u: 7 u_height: 2 rack_face: front power: - { pdu: pdu01, outlet: 5 } links: - { local: eth0, peer: sw01, peer_port: 6, speed_gbps: 1 } --- ## Notes Donated tower; PSU replaced 2026-06. ``` ## Frontmatter reference ### Required on every device | Field | Notes | |---|---| | `hostname` | Must equal the filename stem. | | `kind` | One of the enum below. | | `status` | One of the enum below. | **`kind`** — `server`, `laptop`, `sbc`, `switch`, `ap`, `desktop`, `pdu`, `patch-panel`, `shelf`, `blank`, `ups`, `kvm`. **`status`** — `in-use`, `staging`, `spare`, `broken`, `donated`. ### Specs (optional, shown in the table and Specs box) | Field | Example | Notes | |---|---|---| | `location` | `The pile` | Free text. | | `cpu` | `Intel Core i5-3570K @ 3.40GHz` | Model string. | | `cpu_cores` / `cpu_threads` | `4` / `8` | Integers; threads shown only if they differ from cores. | | `ram_gb` | `8` | Integer (rendered as `8 GB`). | | `storage_gb` + `storage_type` | `500` + `hdd` | `storage_type` ∈ `nvme`, `ssd`, `hdd`, `mixed`. | | `storage` | `[{gb: 500, type: ssd}, {gb: 2000, type: hdd}]` | List form for multiple drives (alternative to the two fields above). | | `nic_gbps` | `1` or `[1, 10]` | Number or list (rendered as `GbE`). | ### Placement in a rack Only files that declare a `rack:` appear in a rack elevation. The rack is 48U. === "Front / rear (U-mounted)" ```yaml rack: rack01 rack_face: front # front | rear | both rack_u: 7 # starting U (1–48) u_height: 2 # height in U (≥1) ``` `both` occupies the same U range on **front and rear**. Two U-mounted devices may not overlap on the same face. === "0U side rail (e.g. vertical PDU)" ```yaml rack: rack01 rack_face: left # left | right # no rack_u / u_height ``` Side-rail (`left`/`right`) items are 0U and **must omit** `rack_u` and `u_height`. === "Shelf-mounted" ```yaml rack: rack01 mounted_on: shf01 # an existing kind:shelf in the same rack shelf_face: front # front | rear shelf_slot: 2 # integer ≥1 # no rack_u / u_height / rack_face ``` The shelf itself must be placed (have `rack_u` + `u_height`). Two devices can't share the same `(shelf, face, slot)`. ### Power feeds A device draws power by listing feeds. Each feed must point at a real `kind:pdu` file, and the outlet must be within that PDU's `outlets` count. ```yaml power: - { pdu: pdu01, outlet: 5 } ``` A `pdu` device must declare a positive integer `outlets:` (e.g. `outlets: 8`). ### Network links Links feed the network graph. `peer` is the hostname of a switch / patch-panel / peer device. ```yaml links: - { local: eth0, peer: sw01, peer_port: 6, speed_gbps: 1 } ``` ## The make process | Command | What it does | |---|---| | `make docs-index` | Regenerate the hardware/services indices and rack elevations from frontmatter. **Run this after every edit.** | | `make docs-check` | Regenerate, then fail if the result differs from the committed copies — exactly what CI runs. | | `make docs-build` | Build the static site with `mkdocs build --strict`. | | `make docs-serve` | Live-reload local preview at `http://127.0.0.1:8000`. | | `make test` | Run the Python unit tests (`pytest`). | A typical edit loop: ```bash $EDITOR docs/hardware/srv06.md make docs-index # regenerate make docs-check # confirm no drift (optional sanity check) git add docs/hardware/srv06.md docs/hardware/index.md docs/infrastructure/racks/ git commit -m "hardware: add srv06" git push # CI builds and publishes to docs.makerfloss.eu ``` On push to `main`, CI regenerates the indices, runs the drift check, builds the site strictly, and publishes it. If you forgot `make docs-index`, the drift check fails and nothing is published. ## Dos and don'ts !!! success "Do" - **Do** run `make docs-index` and commit the regenerated files with your change. - **Do** keep the filename equal to the `hostname`. - **Do** use the [`` naming scheme](hardware-naming-scheme.md), 2 digits, unique per kind. - **Do** mark unknown values as provisional placeholders and ask before inventing rack/power/network numbers. - **Do** preview locally with `make docs-serve` before pushing. !!! danger "Don't" - **Don't** hand-edit generated files — `docs/hardware/index.md`, `docs/services/index.md`, `docs/infrastructure/racks/*.md`, and the `*-elevation.svg` files all carry a *"do not edit by hand"* banner and will be overwritten. - **Don't** put non-device Markdown into `docs/hardware/` — the generators scan that folder and expect host frontmatter. Guides like this one live in `docs/guides/`. - **Don't** give a 0U side-rail item (`left`/`right`) a `rack_u`/`u_height`, and don't give a U-mounted item a side-rail face — the generator rejects both. - **Don't** point `power` at a non-PDU, or use an outlet number beyond the PDU's `outlets` count. - **Don't** rename a file without renaming the `hostname` to match.