Skip to content

Commit 09b8a68

Browse files
authored
Merge pull request #28 from miciav/feature/runner-controller-ui
Feature/runner controller UI
2 parents 8fd19bb + f84386c commit 09b8a68

File tree

283 files changed

+14614
-6853
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

283 files changed

+14614
-6853
lines changed

.flake8

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
[flake8]
2+
max-line-length = 88
3+
extend-ignore = E203, W503
4+
5+
banned-modules =
6+
lb_controller.ansible = Use lb_controller.api instead.
7+
lb_controller.ansible.* = Use lb_controller.api instead.
8+
lb_controller.ansible_executor = Use lb_controller.api instead.
9+
lb_controller.controller = Use lb_controller.api instead.
10+
lb_controller.controller_playbooks = Use lb_controller.api instead.
11+
lb_controller.controller_runner = Use lb_controller.api instead.
12+
lb_controller.controller_state = Use lb_controller.api instead.
13+
lb_controller.controller_stop = Use lb_controller.api instead.
14+
lb_controller.contracts = Use lb_controller.api instead.
15+
lb_controller.interrupts = Use lb_controller.api instead.
16+
lb_controller.journal = Use lb_controller.api instead.
17+
lb_controller.journal_sync = Use lb_controller.api instead.
18+
lb_controller.lifecycle = Use lb_controller.api instead.
19+
lb_controller.paths = Use lb_controller.api instead.
20+
lb_controller.pending = Use lb_controller.api instead.
21+
lb_controller.stop_coordinator = Use lb_controller.api instead.
22+
lb_controller.types = Use lb_controller.api instead.
23+
lb_controller.services = Use lb_controller.api instead.
24+
lb_controller.services.* = Use lb_controller.api instead.
25+
26+
per-file-ignores =
27+
lb_controller/*:I251
28+
tests/unit/lb_controller/*:I251
29+
tests/unit/common/test_lb_events_callback.py:I251
30+
tests/unit/common/test_plugin_installer.py:I251
31+
tests/e2e/test_plugin_git_install_e2e.py:I251

.github/social-preview.png

118 KB
Loading

.github/workflows/diagrams.yml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
diagrams:
99
runs-on: ubuntu-latest
1010
permissions:
11-
contents: read
11+
contents: write
1212
actions: write
1313
steps:
1414
- name: Checkout
@@ -31,7 +31,7 @@ jobs:
3131
- name: Generate diagrams
3232
run: |
3333
mkdir -p docs/diagrams
34-
pyreverse -o png -p linux-benchmark lb_runner lb_controller lb_ui -S
34+
pyreverse -o png -p linux-benchmark lb_runner lb_controller lb_app lb_ui lb_analytics lb_provisioner -S
3535
# pyreverse naming differs across pylint versions; glob and normalize.
3636
shopt -s nullglob
3737
classes_png=(classes*.png)
@@ -43,7 +43,7 @@ jobs:
4343
fi
4444
mv "${classes_png[0]}" docs/diagrams/classes.png
4545
mv "${packages_png[0]}" docs/diagrams/packages.png
46-
pyreverse -o puml -p linux-benchmark lb_runner lb_controller lb_ui -S
46+
pyreverse -o puml -p linux-benchmark lb_runner lb_controller lb_app lb_ui lb_analytics lb_provisioner -S
4747
classes_puml=(classes*.puml)
4848
packages_puml=(packages*.puml)
4949
if [ ${#classes_puml[@]} -eq 0 ] || [ ${#packages_puml[@]} -eq 0 ]; then
@@ -60,3 +60,10 @@ jobs:
6060
name: diagrams-${{ github.ref_name }}
6161
path: docs/diagrams
6262
if-no-files-found: error
63+
64+
- name: Attach diagrams to release
65+
uses: softprops/action-gh-release@v2
66+
with:
67+
files: |
68+
docs/diagrams/*.png
69+
docs/diagrams/*.puml

.github/workflows/pages.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
with:
2323
python-version: "3.13"
2424
- name: Install deps
25-
run: pip install -e ".[docs]"
25+
run: pip install -e ".[docs,controller]"
2626
- name: Build site
2727
run: mkdocs build --strict
2828
- uses: actions/upload-pages-artifact@v3
@@ -36,4 +36,4 @@ jobs:
3636
url: ${{ steps.deployment.outputs.page_url }}
3737
steps:
3838
- id: deployment
39-
uses: actions/deploy-pages@v4
39+
uses: actions/deploy-pages@v4

AGENTS.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# Repository Guidelines
22

33
## Project Structure & Module Organization
4-
- Core configuration now lives under `lb_runner/` (`benchmark_config.py`).
5-
- Runner code is under `lb_runner/`; controller under `lb_controller/`; UI under `lb_ui/`.
4+
- Core configuration lives under `lb_runner/` (`benchmark_config.py`).
5+
- Runner code is under `lb_runner/`; controller under `lb_controller/`; app-layer API under `lb_app/`; UI under `lb_ui/`.
6+
- Reporting and post-processing live under `lb_analytics/`; shared utilities in `lb_common/`; provisioning helpers in `lb_provisioner/`.
7+
- Use the stable APIs from `lb_runner.api`, `lb_controller.api`, and `lb_app.api` instead of importing deep modules.
68
- Collectors sit in `lb_runner/metric_collectors/` (PSUtil, CLI, perf, eBPF) and workload plugins in `lb_runner/plugins/` (stress-ng, dd, fio, hpl), each with base abstractions plus concrete implementations.
79
- Tests are under `tests/`; sample usage is in `example.py`. Output artifacts are written to `benchmark_results/`, `reports/`, and `data_exports/` (these may be absent until generated).
810

@@ -14,6 +16,7 @@
1416
## Coding Style & Naming Conventions
1517
- Python 3.13, formatted with Black (line length 88) and linted with Flake8; type checking is strict via MyPy (no untyped defs, no implicit Optional). Pydocstyle runs with D100/D104/D203/D213 ignored; keep concise docstrings for public APIs.
1618
- Use `snake_case` for functions/variables/modules, `PascalCase` for classes, and `UPPER_SNAKE_CASE` for constants. Prefer well-named dataclasses for configs and keep CLI/tool shelling confined to collectors/generators.
19+
- Logging policy: configure logging via `lb_common.configure_logging()` in entrypoints. `lb_runner` does not auto-configure logging; callers should opt in to keep `LB_EVENT` output on stdout clean.
1720

1821
## Testing Guidelines
1922
- Framework: pytest; tests live in `tests/` with files `test_*.py`, classes `Test*`, functions `test_*`. Favor unit tests for collectors/generators with fake command outputs and small integration tests that exercise the controller.

CLI.md

Lines changed: 62 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,80 @@
1-
CLI Reference
2-
=============
1+
# CLI Reference
32

4-
> Note: the user-facing CLI lives in `lb_ui` (invoke via `lb` or `python -m lb_ui.cli`). Runner/controller packages no longer import the UI or expose separate entrypoints.
3+
> Note: the user-facing CLI lives in `lb_ui` (invoke via `lb` or `python -m lb_ui.cli`). Runner/controller packages do not expose separate entrypoints.
4+
5+
## Setup
56

6-
Setup
7-
-----
87
- Install in a venv: `uv venv && uv pip install -e .`
98
- Make `lb` globally available (optional): `uv tool install -e .`
10-
- Enable shell completion: `lb --install-completion` (bash/zsh/fish) and restart your shell.
9+
- Enable shell completion: `lb --install-completion` (bash/zsh/fish)
10+
11+
## Global flags
12+
13+
- `--headless` forces headless output (useful in CI or pipes).
14+
15+
## Config resolution
1116

12-
Config resolution
13-
-----------------
1417
Order used by commands that need a config:
18+
1519
1. `-c/--config` flag
1620
2. Saved default at `~/.config/lb/config_path` (set via `lb config set-default` or `lb config init`)
1721
3. `./benchmark_config.json` if present
1822
4. Built-in defaults
1923

20-
Top-level commands
21-
------------------
22-
- `lb plugin list|ls [--select] [--enable NAME | --disable NAME] [-c FILE] [--set-default]`
23-
Show plugins with enabled state; optionally enable/disable a workload in the config or open an interactive selector (arrows + space). (`lb plugins` remains as a compatibility alias.)
24-
- `lb plugin select [-c FILE] [--set-default]`
25-
Directly open the interactive selector to toggle plugins with arrows + space.
26-
- `lb plugin install PATH|URL [--manifest FILE] [--force] [--regen-assets/--no-regen-assets]`
27-
Install a plugin from a .py file, directory, archive (.zip/.tar.gz), or git repository URL.
28-
- `lb plugin uninstall NAME [--purge-config/--keep-config] [--regen-assets/--no-regen-assets]`
29-
Remove a user plugin and optionally delete its config entries.
30-
- `lb hosts [-c FILE]`
31-
Show remote hosts from the resolved config.
32-
- `lb run [TEST ...] [-c FILE] [--run-id ID] [--remote/--no-remote] [--repetitions N]`
33-
Run workloads locally or remotely (auto-follows config unless overridden). Use `--repetitions` to temporarily change how many times each workload runs.
34-
- `lb run ... --docker [--docker-image TAG] [--docker-engine docker|podman] [--docker-no-build] [--docker-no-cache]`
35-
Build/use the container image and run the CLI inside it. Mounts the repo read-only and writes artifacts to the container’s `benchmark_results`.
36-
- `lb runs list [--root PATH] [-c FILE]` / `lb runs show RUN_ID [--root PATH] [-c FILE]`
37-
List past runs stored under `benchmark_results/` and inspect a single run (hosts, workloads, paths).
38-
- `lb analyze [RUN_ID] [--root PATH] [--kind aggregate] [--workload NAME] [--host NAME]`
39-
Run post-processing analytics on an existing run. If `RUN_ID` or selectors are omitted and you are in an interactive TTY, prompts will guide selection.
40-
41-
Config management (`lb config ...`)
42-
-----------------------------------
24+
## Top-level commands
25+
26+
- `lb run [WORKLOAD ...] [-c FILE] [--run-id ID] [--resume [latest|ID]] [--remote/--no-remote] [--repetitions N] [--intensity LEVEL] [--setup/--no-setup] [--stop-file PATH] [--debug]`
27+
Run workloads remotely via Ansible. Local execution is not supported by the CLI.
28+
- `lb run ... --docker [--docker-engine docker|podman] [--nodes N]`
29+
Dev-only: provision containers and run via Ansible (requires `.lb_dev_cli` or `LB_ENABLE_TEST_CLI=1`).
30+
- `lb run ... --multipass [--nodes N]`
31+
Dev-only: provision Multipass VMs and run via Ansible (requires `.lb_dev_cli` or `LB_ENABLE_TEST_CLI=1`).
32+
- `lb runs list [--root PATH] [-c FILE]` / `lb runs show RUN_ID [--root PATH] [-c FILE]`
33+
Inspect stored runs under `benchmark_results/`.
34+
- `lb analyze [RUN_ID] [--root PATH] [--workload NAME] [--host NAME]`
35+
Run analytics on an existing run (currently `aggregate`).
36+
- `lb plugin ...` / `lb plugins ...`
37+
Inspect and manage workload plugins.
38+
- `lb config ...`
39+
Create and manage benchmark configuration files.
40+
- `lb doctor ...`
41+
Run prerequisite checks.
42+
- `lb test multipass ...` (dev-only)
43+
Helper to run integration tests.
44+
45+
## Plugin management (`lb plugin ...`)
46+
47+
- `lb plugin list|ls [--select] [--enable NAME | --disable NAME] [-c FILE] [--set-default]`
48+
- `lb plugin select [-c FILE] [--set-default]`
49+
- `lb plugin install PATH|URL [--manifest FILE] [--force]`
50+
- `lb plugin uninstall NAME [--purge-config/--keep-config] [-c FILE]`
51+
52+
## Config management (`lb config ...`)
53+
4354
- `lb config init [-i] [--path FILE] [--set-default/--no-set-default]`
44-
Create a config (prompt for a remote host with `-i`).
4555
- `lb config set-repetitions N [-c FILE] [--set-default/--no-set-default]`
46-
Persist the desired number of repetitions to a config file (defaults to `~/.config/lb/config.json`).
4756
- `lb config set-default FILE` / `lb config unset-default` / `lb config show-default`
48-
- `lb config edit [-p FILE]`
49-
Open the config in `$EDITOR`.
50-
- `lb config workloads [-c FILE]`
51-
List workloads and enabled status.
52-
- `lb config enable-workload NAME [-c FILE] [--set-default]`
53-
(creates if missing)
57+
- `lb config edit [-p FILE]`
58+
- `lb config workloads [-c FILE]`
59+
- `lb config enable-workload NAME [-c FILE] [--set-default]`
5460
- `lb config disable-workload NAME [-c FILE] [--set-default]`
61+
- `lb config select-workloads [-c FILE] [--set-default]`
62+
63+
## Doctor checks (`lb doctor ...`)
5564

56-
Doctor checks (`lb doctor ...`)
57-
-------------------------------
58-
- `lb doctor controller` — Python deps + ansible/ansible-runner + config resolution.
59-
- `lb doctor local-tools` — stress-ng, fio, sysstat tools, perf (needed only for local runs).
60-
- `lb doctor multipass` — check presence of multipass (optional).
61-
- `lb doctor all` — run all checks.
65+
- `lb doctor controller` - Python deps + Ansible requirements
66+
- `lb doctor local` - local workload tools (stress-ng, fio, sysstat)
67+
- `lb doctor multipass` - Multipass availability
68+
- `lb doctor all` - run all checks
69+
70+
## Test helpers (`lb test ...`, dev installs only)
6271

63-
Integration helper (`lb test ...`, dev installs only)
64-
-----------------------------------------------------
6572
- Available when `.lb_dev_cli` exists in the project root or `LB_ENABLE_TEST_CLI=1` is set.
66-
- `lb test multipass [-o DIR] [--vm-count {1,2}] [--multi-workloads] [-- EXTRA_PYTEST_ARGS...]`
67-
Runs the Multipass integration test. Artifacts go to `tests/results` by default (override with `-o` or `LB_TEST_RESULTS_DIR`). `--vm-count` (or `LB_MULTIPASS_VM_COUNT`) launches 1–2 VMs. Use `--multi-workloads` to run the stress_ng + dd + fio variant. Requires multipass + ansible/ansible-runner locally.
73+
- `lb test multipass [-o DIR] [--vm-count {1,2}] [--multi-workloads] [-- EXTRA_PYTEST_ARGS...]`
74+
75+
## Environment variables
76+
77+
- `LB_ENABLE_TEST_CLI=1` enables `lb test` and provisioning flags in the CLI.
78+
- `LB_USER_PLUGIN_DIR` overrides the user plugin install directory.
79+
- `LB_STOP_FILE` sets a stop sentinel path if `--stop-file` is omitted.
80+
- `LB_TEST_RESULTS_DIR`, `LB_MULTIPASS_VM_COUNT` customize test helpers.

GEMINI.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Linux Benchmark Library (linux-benchmark-lib)
2+
3+
## Project Overview
4+
`linux-benchmark-lib` is a robust, configurable Python library designed for benchmarking Linux compute nodes. It supports running repeatable workloads and collecting detailed system metrics under synthetic load.
5+
6+
### Key Features
7+
* **Operation Modes:**
8+
* **Agent (Local):** Lightweight installation for target nodes.
9+
* **Controller (Remote):** Full orchestration layer using Ansible for managing remote benchmarks.
10+
* **UI/CLI:** TUI-based interaction (via `rich` and `typer`).
11+
* **Metric Collection:** PSUtil, Linux CLI tools, perf events, eBPF.
12+
* **Workloads:** Plugin-based system (stress-ng, dd, fio, hpl, stream). Extensible via Python entry points.
13+
* **Data Handling:** Aggregation using Pandas, reporting with Matplotlib/Seaborn.
14+
15+
## Architecture
16+
* `lb_runner/`: Core execution logic, workload plugins, and metric collectors.
17+
* `local_runner.py`: Orchestrates the benchmark workflow on a single node.
18+
* `lb_controller/`: Remote orchestration, Ansible integration, and result handling.
19+
* `lb_ui/`: CLI and TUI layer. **Note:** Runner/Controller modules do not import UI components.
20+
* `lb_analytics/`: Data aggregation and reporting logic.
21+
* `benchmark_results/`: Stores raw metric data.
22+
* `reports/`: Generated text reports and plots.
23+
24+
## Development & Usage
25+
26+
### Setup
27+
The project uses `uv` for dependency management.
28+
29+
```bash
30+
# Install core dependencies
31+
uv sync
32+
33+
# Install controller extras (Ansible, plotting)
34+
uv sync --extra controller
35+
36+
# Install dev dependencies
37+
uv sync --all-extras --dev
38+
```
39+
40+
### Key Commands (`lb`)
41+
The CLI entry point is `lb` (or `python -m lb_ui.cli`).
42+
43+
* **Run Benchmarks:**
44+
* `lb run [workload_name]` (e.g., `lb run stress_ng`)
45+
* `lb run --remote` (uses configured remote hosts)
46+
* **Plugin Management:**
47+
* `lb plugin list` (show status)
48+
* `lb plugin install <url/path>`
49+
* **Configuration:**
50+
* `lb config init` (initialize config)
51+
* `lb config edit` (open in editor)
52+
* **Diagnostics:**
53+
* `lb doctor all` (run health checks)
54+
55+
### Testing
56+
Tests are managed with `pytest` and marked for different scopes.
57+
58+
```bash
59+
# Run all tests
60+
uv run pytest tests/
61+
62+
# Run specific types
63+
uv run pytest -m unit
64+
uv run pytest -m integration
65+
uv run pytest -m tui
66+
```
67+
68+
### Coding Standards
69+
* **Style:** `black` (line length 88), `flake8`.
70+
* **Typing:** Strict `mypy` (Python 3.12+).
71+
* **Docstrings:** `pydocstyle` (subset of rules).
72+
* **Conventions:** `snake_case` for functions/vars, `PascalCase` for classes. Dataclasses for configuration.
73+
74+
## File Structure Highlights
75+
* `pyproject.toml`: Dependency and build configuration.
76+
* `lb_runner/benchmark_config.py`: Configuration dataclasses.
77+
* `lb_runner/plugins/`: Workload plugin implementations.
78+
* `lb_controller/ansible/`: Ansible playbooks and roles.

0 commit comments

Comments
 (0)