Skip to content

Commit b989014

Browse files
committed
add AGENTS.md
1 parent ef73d80 commit b989014

1 file changed

Lines changed: 132 additions & 0 deletions

File tree

AGENTS.md

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# Contributing as an AI Agent to Nagstamon
2+
3+
Nagstamon is a cross-platform PyQt6/Qt5 desktop monitoring application that aggregates status from 20+ monitoring systems (Nagios, Icinga, Zabbix, Prometheus, etc.). This guide helps AI agents understand the codebase structure and development workflows.
4+
5+
## Architecture Overview
6+
7+
**Three-tier structure:**
8+
1. **Configuration Layer** (`Nagstamon/config.py`): Central settings hub, loaded once at startup. Manages cross-platform specifics (Linux/macOS/Windows, desktop environments, Wayland).
9+
2. **Server Plugin System** (`Nagstamon/servers/`): Each monitoring system (Nagios, Icinga, Zabbix, etc.) extends `GenericServer`. Uses dynamic registration pattern via `SERVER_TYPES` dict and `register_server()`.
10+
3. **PyQt6 GUI Layer** (`Nagstamon/qui/`): Qt widgets, dialogs, system tray integration. Imports gui modules cause Qt initialization—avoid in non-gui code.
11+
12+
**Data Flow:**
13+
- `nagstamon.py` (entry point) → `Nagstamon.qui` (GUI app) → `Nagstamon.servers` (status fetching)
14+
- Configuration flows from `config.py` to all server instances
15+
- Status objects (`GenericHost`, `GenericService` in `objects.py`) unify data from all server types
16+
17+
## Server Integration Pattern
18+
19+
**Adding a new monitoring system requires:**
20+
21+
1. Create `Nagstamon/servers/YourServer.py` extending `GenericServer`
22+
2. Register in `Nagstamon/servers/__init__.py` by adding to `servers_list` and importing
23+
3. Implement core methods:
24+
- `init_http()`: Initialize session headers/auth
25+
- `get_status()`: Fetch and parse status, populate `self.hosts` and `self.services`
26+
- `_set_recheck()`, `_acknowledge()`: Actions (optional)
27+
28+
**Key patterns:**
29+
- Server configuration accessed via `conf.servers[self.get_name()]`
30+
- Use `self.session` (from `GenericServer`) for HTTP; add headers in `init_http()`
31+
- Status parsing stores result in `self.hosts` and `self.services` dicts (keyed by host/service name)
32+
- Parse into `GenericHost`/`GenericService` objects with standard fields: `name`, `status` ('UP'/'DOWN'/'OK'/'CRITICAL'/etc.), `status_information`, `acknowledged`, `scheduled_downtime`, `flapping`
33+
34+
**Examples:**
35+
- `Nagios.py`: Classic CGI API parsing
36+
- `Centreon/__init__.py`: Proxy pattern (detects version, switches to `CentreonLegacy` or `CentreonModern`)
37+
- `Alertmanager/alertmanagerserver.py`: JSON REST API with custom mapping fields (`map_to_hostname`, `map_to_status`)
38+
39+
## Testing Pattern
40+
41+
**Three test strategies** (see `tests/test_smoke.py`):
42+
43+
1. **Non-GUI modules** (config, servers, helpers): Full import via `importlib` - catches all runtime errors
44+
2. **GUI modules** (Nagstamon/qui/**): Syntax-only via `py_compile` - requires display/Qt, skipped in headless CI
45+
3. **Vendored Xlib**: Syntax-only (avoid version mismatch errors with system python-xlib)
46+
47+
**Run tests:**
48+
```bash
49+
python -m pytest tests/
50+
```
51+
52+
## Configuration & Cross-Platform Handling
53+
54+
**Key config patterns:**
55+
- Multiple config folder support (`conf.configdir`, `nagstamon.conf`, `nagstamon2.conf/`)
56+
- OS detection: `from Nagstamon.config import OS, OS_WINDOWS, OS_MACOS`
57+
- Desktop environment handling: `DESKTOP_WAYLAND`, `DESKTOP_NEEDS_FIX` for quirky desktops
58+
- Keyring support (optional, disabled on some KDE+Ubuntu combos to avoid segfaults)
59+
60+
**Configuration object** (`conf` singleton from `config.py`):
61+
- `conf.servers` (OrderedDict of server configs)
62+
- `conf.debug_mode` (debug logging)
63+
- `conf.update_interval_seconds` (polling frequency)
64+
- Authentication state and SSL/TLS per server
65+
66+
## Build System
67+
68+
**Multi-platform builds** (see `build/build.py`):
69+
- **Windows**: PyInstaller → exe (optional code signing)
70+
- **macOS**: PyInstaller → app bundle or DMG
71+
- **Linux**:
72+
- Debian/Ubuntu via `setup.py` + debuild
73+
- RPM via `setup.py bdist_rpm`
74+
- DockerFiles for multiple distros (Fedora 41-45, RHEL 9, Debian)
75+
76+
**Dependencies** managed platform-specifically:
77+
- Qt6 preferred on newer systems; Qt5 fallback on older Fedora/RHEL
78+
- Check `build/requirements/{linux,macos,windows}.txt`
79+
80+
## Common Development Tasks
81+
82+
**Running locally:**
83+
```bash
84+
python nagstamon.py
85+
```
86+
87+
**Debugging GUI issues:**
88+
- GUI requires display; use `--help` to check environment
89+
- Set `conf.debug_mode = True` in config for server debug output
90+
91+
**Modifying server status parsing:**
92+
- Edit `get_status()` method
93+
- Test via smoke tests: `python -m pytest tests/test_smoke.py`
94+
- Populate `self.hosts` and `self.services` with correct status strings from `helpers.STATES`
95+
96+
**Adding server config options:**
97+
- Add to server class via `__init__()` defaults
98+
- Add UI widget in `Nagstamon/qui/dialogs/server.py` `VOLATILE_WIDGETS` dict (shown/hidden per server type)
99+
- Persist via `create_server()` in `servers/__init__.py`
100+
101+
## State Values & Severity
102+
103+
**Standard status strings** (`helpers.STATES`):
104+
- Severity order (worst to least): `DISASTER > CRITICAL > DOWN > HIGH > AVERAGE > WARNING > UNKNOWN > INFORMATION > UP`
105+
- Different servers use different names; always normalize to above set
106+
- Example: Zabbix "Disaster" → `DISASTER`, Prometheus AlertManager severity mapping in `map_to_*` fields
107+
108+
## Important Conventions
109+
110+
1. **No circular imports**: GUI modules import server/config; config/servers must NOT import gui. Break cycles via local imports if needed.
111+
2. **Lock mechanism**: Single-instance check at startup via `lock_config_folder()` prevents concurrent runs on same config
112+
3. **Thread lifecycle**: Servers run in update threads; status fetching must be thread-safe, avoid gui imports
113+
4. **Debug infrastructure**: Use `self.debug(server=name, debug=msg)` for logging, routed to `debug_queue` if enabled
114+
5. **Error handling**: Catch exceptions in `get_status()`, return `Result(result=result_code, error=error_msg)` for graceful degradation
115+
116+
## Key Files Reference
117+
118+
- `Nagstamon/config.py` (1248 lines): AppInfo, OS detection, conf singleton, RESOURCES paths
119+
- `Nagstamon/servers/Generic.py` (1800 lines): Base class with HTTP handling, status aggregation, action methods
120+
- `Nagstamon/servers/__init__.py`: Plugin registration, server instantiation, aggregation functions
121+
- `Nagstamon/objects.py`: `GenericHost`/`GenericService` domain models
122+
- `Nagstamon/qui/__init__.py`: Qt app initialization, system tray setup
123+
- `Nagstamon/helpers.py`: Filtering (regex), STATES constant, utilities
124+
125+
## Debugging Tips
126+
127+
1. Enable debug mode in config to see server refresh logs
128+
2. Check `nagstamon.conf` for server credentials and URLs
129+
3. Use `python -c "import Nagstamon.servers.YourServer; print('OK')"` to test server module imports
130+
4. GUI breakpoints require Qt event loop; print debugging more reliable
131+
5. Check for `ClassServerReal` pattern—some servers proxy to real implementation after detection
132+

0 commit comments

Comments
 (0)