FiWiControl/docs/install.md

20 KiB
Raw Permalink Blame History

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 guides 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 rigs 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 workstations 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.


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 Fedoras **20-systemd-ssh-proxy.conf**). FiWiControls 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 teams 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** ).