Skip to content

Commit be9d567

Browse files
author
Martin Belanger
committed
code quality: enable copilot
Signed-off-by: Martin Belanger <[email protected]>
1 parent a2f0c69 commit be9d567

1 file changed

Lines changed: 50 additions & 0 deletions

File tree

.github/copilot-instructions.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Copilot Instructions for nvme-stas
2+
3+
## Project Overview
4+
5+
nvme-stas (NVMe STorage Appliance Services) provides two cooperating systemd daemons:
6+
7+
- **`stafd`** — discovers NVMe controllers via Avahi mDNS and/or manual config, connects to them, retrieves discovery log pages, and exposes results on D-Bus (`org.nvmexpress.staf`).
8+
- **`stacd`** — reads discovery results from `stafd` via D-Bus and establishes NVMe-oF I/O controller connections, exposing state on D-Bus (`org.nvmexpress.stac`).
9+
10+
Both daemons are driven by the **GLib main loop**. There is no `asyncio`, no threads, and no thread synchronization primitives. All I/O — timers, name resolution, udev events, D-Bus signals — goes through `GLib.MainLoop`.
11+
12+
## Build System
13+
14+
The project uses **Meson**. Source files are copied (and some templated) into `.build/` at setup time. All tests run against `.build/`, not the source tree. In particular:
15+
16+
- `staslib/defs.py` is a template: `@VERSION@`, `@ETC@`, etc. are substituted by Meson into `.build/staslib/defs.py`.
17+
- Top-level scripts (`stafd.py`, `stacd.py`, etc.) are installed without the `.py` extension; the built copies are `.build/stafd`, `.build/stacd`, etc.
18+
- Meson's incremental build does not reliably re-copy files after edits. A full rebuild (`rm -rf .build/ && meson setup .build && meson compile -C .build`) is often needed.
19+
20+
## Python Compatibility
21+
22+
Code must remain compatible with **Python 3.6+**. This is enforced by `vermin`. Avoid any syntax or stdlib features introduced after 3.6 (e.g., walrus operator `:=`, `math.prod`, `str.removeprefix`).
23+
24+
## Code Style
25+
26+
- **Line length**: 120 characters maximum.
27+
- **Linter/formatter**: `ruff` (configured in `pyproject.toml`). Quote style is `preserve` — do not normalize single vs. double quotes.
28+
- **No docstrings or comments** should be added to code that wasn't changed.
29+
30+
## Key Design Patterns
31+
32+
### Singletons
33+
`SvcConf`, `SysConf`, `NvmeOptions`, and `NbftConf` (all in `staslib/conf.py`) use a `Singleton` metaclass. Always instantiate them by calling the class normally, e.g. `conf.SvcConf()`. Python returns the existing instance after first construction. Pass `default_conf=` only on the very first construction.
34+
35+
### Transport IDs (`TID`)
36+
`staslib/trid.py` defines `TID` — an immutable transport ID (transport, traddr, trsvcid, subsysnqn, host-iface, host-traddr). It is used as a dictionary key throughout the codebase. Do not add mutable state to it.
37+
38+
### GTimer
39+
`GTimer` (in `staslib/gutil.py`) wraps GLib one-shot timers. Calling `start()` on an already-running timer resets the deadline from *now* — it does not stack or queue. Calling it on a stopped timer creates a new GLib source.
40+
41+
### Controller Lifecycle
42+
When a udev "remove" event fires for a controller, `_connect_attempts` resets to 0 and the retry timer restarts at `FAST_CONNECT_RETRY_PERIOD_SEC` — this is intentional, not a bug.
43+
44+
## Tests
45+
46+
- Test files are in `test/` and named `test-*.py`.
47+
- They use **`unittest`**, not pytest (even though pytest is a dev dependency — Meson runs them directly with `python3`).
48+
- Tests needing filesystem mocking use `pyfakefs`.
49+
- Run the full suite with: `meson test -C .build`
50+
- Run a single test: `PYTHONPATH=".build/subprojects/nvme-cli/libnvme:.build" python3 test/test-foo.py -v`

0 commit comments

Comments
 (0)