20 KiB
Installing FiWiControl
Repository: FiWiControl (checkout directory, mixed case).
Python package / pip name: **fiwicontrol** (lowercase). See the Naming paragraph at the top of **README.md** if that split is confusing.
Design: **docs/architecture.md** (system architecture, package map, alignment with html/Fi-Wi-L4S.html). Faults / FDIR: **docs/fdir.md** (detection, isolation, recovery, exit codes).
Requirements: Python 3.11+. For SSH automation to rigs, passwordless **root@<host>** — see **docs/node-control-asyncio-design.md**.
**fiwicontrol import layout:** besides **commands**, **lab**, and **power** (this guide’s focus), the distribution includes **fronthaul**, **telemetry**, **radio**, **concentrator** (local workstation CPU / PCIe / DMI snapshot; not fabric JSON — see **docs/system-test-scripts.md**), **fabric** (fabric JSON + optional **[fabric]** / **[fabric.rrh.*]** lab INI merge, then **Fabric** for harnesses), **flows**, and **spc** — see the numbered package list and **src/fiwicontrol/** tree in **README.md**. Long-running hardware harness scripts belong under **scripts/system/** (not **pytest**); fabric binding for the bench is **python3 -m fiwicontrol.fabric bind** (needs **pip install -e ".[power]"** on the host that sees Acroname USB). See **docs/fabric-builder.md**, **docs/system-test-scripts.md**, **docs/power-control-and-inventory.md** ([fabric]), and **docs/pcie-hotswap-setup.md** (PCIe hot-swap harness).
Environment variables (quick reference)
| Variable | Purpose |
|---|---|
**FIWI_LAB_INI** |
Default lab INI path when tools are run without **-c**. |
**FIWI_SSH_CONFIG** |
Path passed to **ssh -F** (Fedora **ssh_config.d** quirks; see **tests/conftest.py**). |
**FIWI_RUN_REMOTE_TESTS** |
Set to **1** / **true** / **yes** to run SSH integration tests in **tests/test_node_control.py** and **tests/test_remote_power_dependencies.py** under pytest. |
**FIWI_REMOTE_IP** |
Rig IP for those tests and some scripts (default **192.168.1.39** where a default exists). |
**FIWI_REMOTE_PYTHON** |
Remote interpreter for SSH discovery / tests when **python3** on the rig is not the one with **fiwicontrol**. |
**FIWI_REMOTE_PIP_FLAGS** |
Extra args for remote **pip** (e.g. **--break-system-packages** on Pi OS). |
**FIWI_REMOTE_REPO** |
Remote checkout path for **python3 -m fiwicontrol.commands …** (default **/root/Code/FiWiControl**). |
**FIWI_VERIFY_POWER_INI** |
Set to **1** to run live INI verification in **tests/test_inventory_verify_live.py**. |
**FIWI_TEST_INI** |
Optional path for **tests/test_fabric_instantiation.py** (default **configs/default.ini** in repo). |
Running **python3 tests/test_node_control.py …** or **python3 tests/test_remote_power_dependencies.py** directly (not via pytest) sets **FIWI_RUN_REMOTE_TESTS=1** if it is unset, so a deliberate script run still exercises SSH without extra env.
Security and trust boundaries
FiWiControl is operator-driven lab and deployment tooling, not a hardened multi-tenant service. Keep these boundaries explicit:
| Topic | What to assume |
|---|---|
| Process identity | Commands run as your workstation user. They read and write paths you pass (**-c**, **--fabric-json**, **--patch-panel-json**, INI/JSON under **configs/**). |
| SSH | **ssh_node** runs **ssh** with a fixed argument vector (no shell). Targets come from INI **ipaddr**, **FIWI_REMOTE_IP**, or flags. You are trusting SSH host keys and **~/.ssh** the same way as normal OpenSSH use. |
| Remote code | Integration tests and remote discovery execute fixed remote command lines (e.g. **python3 -m fiwicontrol.power --discovery-json**). Do not point automation at hosts you do not control unless that is intentional. |
| JSON / INI | Lab files are data. Very large patch-panel map files are ignored (size and entry limits in **fiwicontrol.fabric.patch_panel_json**) so a bad file cannot exhaust memory as easily. Do not store secrets in these files. |
| CI / pytest | Remote tests require **FIWI_RUN_REMOTE_TESTS=1** so CI does not open outbound SSH by default. |
| Life support / safety-critical | FiWiControl is not intended, validated, or cleared for life support, patient-connected, or other safety-critical applications. Using it in those contexts would require a separate regulated development lifecycle, hazard analysis, verification, and organizational controls—none of which this open-source project provides. |
Bring up systems (new workstation + lab rig)
Use this order the first time you (or someone else) joins the project or replaces a machine. Replace **192.168.1.39** with your rig’s IP when needed.
| Step | Where | What to do |
|---|---|---|
| 1 | Workstation | Clone this repo and **cd** into it. |
| 2 | Workstation | Python 3.11+ and an editable install: **python3 -m pip install -e ".[dev]", then **python3 -m pip install -e ".[power]"** if you use Acroname/Monsoon or remote power tests. Add **".[flows]"** / **".[spc]"** when you use **fiwicontrol.flows** or **fiwicontrol.spc** (see Workstation below and **docs/flows.md / **docs/spc.md**). |
| 3 | Workstation → rig | Passwordless SSH as root: **ssh -o BatchMode=yes root@192.168.1.39 true** must exit 0 with no password prompt. On the rig, install your workstation’s public key in **/root/.ssh/authorized_keys** and ensure **sshd** allows **root** with pubkey auth. |
| 4 | Rig (e.g. Pi) | **git clone** the same repo where you will run power/discovery (often **/root/Code/FiWiControl**). Your **--remote-repo** path must match. |
| 5 | Workstation | From your clone, run **python3 -m fiwicontrol.commands** with the Pi IP and **--remote-repo** (PEP 668 / Raspberry Pi OS needs **--break-system-packages** or **FIWI_REMOTE_PIP_FLAGS**). See Remote host setup below (numbered subsections 3 and 4: install **fiwicontrol[power]** on the rig, then align **python3** with **pip**). |
| 6 | Workstation | Verify (minimal): **python3 -m pytest -q tests/test_package_layout.py** (imports **fiwicontrol.commands**, **lab**, **power**, **flows**, **spc**, **fronthaul**, **telemetry**, **radio**, **concentrator**, **fabric**). Full tree: **python3 -m pytest tests/ -q** (expect skipped tests: live INI unless **FIWI_VERIFY_POWER_INI=1**, SSH integration unless **FIWI_RUN_REMOTE_TESTS=1**). With a reachable rig: **FIWI_RUN_REMOTE_TESTS=1 FIWI_REMOTE_IP=… python3 -m pytest -q tests/test_node_control.py tests/test_remote_power_dependencies.py** (default **FIWI_REMOTE_IP** is **192.168.1.39** if unset). For INI / **--verify-inventory**, see **docs/power-control-and-inventory.md** → “Verification checklist (after install)”. |
SSH user: **ssh_node** ( **sshtype="ssh"** ) always uses an explicit **root@<ipaddr>** (or whatever **ssh_session** **user** is set to). It does not open **ssh 192.168.1.39** with your local login name, so your manual tests should use **root@…** as well.
After a git pull on the rig: if the Pi uses an editable **pip install -e**, pull there before expecting new Python code on the node.
Workstation (e.g. Fedora): recommended install
From your clone of this repo, use an editable install so **python3 -m fiwicontrol…**, **pytest**, and **import fiwicontrol.*** work from any working directory (use a venv if you prefer not to touch system Python):
cd ~/Code/FiWiControl
python3 -m pip install -U pip setuptools wheel
python3 -m pip install -e ".[dev]"
Add power / USB dependencies when you work with Acroname or Monsoon discovery locally:
python3 -m pip install -e ".[power]"
Or in one line:
python3 -m pip install -e ".[dev,power]"
Flows (async iperf over SSH, SciPy / Matplotlib stack) and SPC (Shewhart / Hotelling T² helpers) are separate optional extras:
python3 -m pip install -e ".[flows]" # NumPy, SciPy, Matplotlib — see docs/flows.md
python3 -m pip install -e ".[spc]" # NumPy, SciPy — see docs/spc.md
Or combined with dev and power:
python3 -m pip install -e ".[dev,power,flows,spc]"
Why this is the default: you avoid remembering **PYTHONPATH=src**, IDEs and **python -m** behave predictably, and it matches how **pyproject.toml** / **pytest** are meant to be used.
Without a local install (one-off)
If you have not run **pip install -e .**, you can still run modules from the repo root:
cd ~/Code/FiWiControl
PYTHONPATH=src python3 -m pytest tests/test_package_layout.py -q
PYTHONPATH=src python3 -m fiwicontrol.power --discovery-json
This is easy to forget after you **cd** elsewhere, so prefer an editable install for day-to-day work.
Summary (workstation): use editable install on your main dev box; use **PYTHONPATH=src** when you deliberately skip a local install.
Remote host setup
End-to-end steps for a lab rig (e.g. Raspberry Pi 5) that **ssh_node** and **fiwicontrol.power** talk to over **ssh root@<ip>**. Same SSH user and rules as in **docs/node-control-asyncio-design.md** (passwordless **BatchMode=yes**).
1. SSH from your workstation
ssh -o BatchMode=yes -i ~/.ssh/id_ed25519 root@192.168.1.39 true
(no output, exit 0). If this fails, fix keys and **/root/.ssh/authorized_keys** on the rig first.
On some Linux workstations, OpenSSH aborts before connecting with **Bad owner or permissions on …/ssh_config.d/…** (for example Fedora’s **20-systemd-ssh-proxy.conf**). FiWiControl’s pytest session sets **FIWI_SSH_CONFIG** to a minimal client file under **tests/fixtures/** so **ssh -F** skips the system **/etc/ssh/ssh_config**. For ad hoc runs (inventory, scripts), export **FIWI_SSH_CONFIG** to that same file, or to your own minimal **ssh_config** that does not **Include** the broken drop-in.
2. Repo on the remote
The Pi needs a git checkout of FiWiControl (same tree you pushed). Example for **root**:
# on the Pi (as root)
mkdir -p /root/Code
cd /root/Code
git clone <YOUR_FIWICONTROL_REPO_URL> FiWiControl
Use your team’s real clone URL. **--remote-repo** below must be that directory (e.g. **/root/Code/FiWiControl**).
3. Install **fiwicontrol[power]** on the remote from Fedora
Your Fedora machine must already run **python3 -m fiwicontrol.power** (usually **pip install -e .** from your local clone — see above).
Then:
cd ~/Code/FiWiControl
python3 -m fiwicontrol.commands 192.168.1.39 --remote-repo /root/Code/FiWiControl --break-system-packages
Raspberry Pi OS / Debian (PEP 668): system Python blocks **pip install** without **--break-system-packages**. Prefer the **--break-system-packages** flag above.
Do not pass a separate token after **--pip-flags** if it starts with **--** (argparse will treat it as another option). Use either:
**--break-system-packages**, or**--pip-flags=--break-system-packages**(equals form), or**export FIWI_REMOTE_PIP_FLAGS='--break-system-packages'**and omit**--pip-flags**.
Wrapper: **scripts/setup_pi_power.sh** sets **PYTHONPATH=src** on Fedora if needed, then runs **python3 -m fiwicontrol.commands** (**--setup-remote**-style args) using **FIWI_REMOTE_IP** and **FIWI_REMOTE_REPO**:
cd ~/Code/FiWiControl
chmod +x scripts/setup_pi_power.sh # once
export FIWI_REMOTE_IP=192.168.1.39
export FIWI_REMOTE_REPO=/root/Code/FiWiControl
export FIWI_REMOTE_PIP_FLAGS='--break-system-packages'
./scripts/setup_pi_power.sh
(You can extend the script or pass **--** args if you add **--break-system-packages** to the script later.)
4. Python on the remote (one interpreter for pip and for SSH)
If **pip show fiwicontrol** reports **Location: …/python3.11/…** but plain **python3** on the rig is a different version, imports over SSH will fail even though the package is installed. Install and run with the same binary, or on Fedora set:
export FIWI_REMOTE_PYTHON=python3.11 # or full path, e.g. /usr/bin/python3.11
That variable is read by **discover_devices_remote_async**, **tests/test_remote_power_dependencies.py**, and **python3 -m fiwicontrol.commands … --remote-python …** (remote setup).
5. Verify after install
Quick remote sanity (imports + **python3 -m fiwicontrol.power --discovery-json** over SSH; needs **FIWI_REMOTE_IP** if not **192.168.1.39**; opt-in **FIWI_RUN_REMOTE_TESTS=1**):
FIWI_RUN_REMOTE_TESTS=1 python3 -m pytest -q tests/test_remote_power_dependencies.py
Full checklist for a new machine (local discovery, **ssh root@…**, remote **fiwicontrol**, INI editing, **--list-power-devices**, **--verify-inventory**, optional pytest): **docs/power-control-and-inventory.md** → “Verification checklist (after install)”.
INI layout (**[site]**, **[machine.*]**, **[fabric]** / **[fabric.rrh.*]**, **acroname** / **monsoon**): **docs/power-control-and-inventory.md**.
Quick import check
python3 -c "import fiwicontrol.commands, fiwicontrol.power; print('ok')"
With only **[dev]** installed, **fiwicontrol.power** still imports; hardware discovery needs **[power]** ( **brainstem**, **pyserial** ).