Skip to content

Commit 0513f68

Browse files
authored
Update docs, readme (#140)
Signed-off-by: Daniel Guns <danbguns@gmail.com>
1 parent 47ea7c2 commit 0513f68

8 files changed

Lines changed: 240 additions & 132 deletions

File tree

.github/workflows/check-crd-updates.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ jobs:
3434
- name: Check for changes
3535
id: changes
3636
run: |
37-
if git diff --quiet; then
37+
# Ignore lines that change every run regardless of CRD content:
38+
# - kopium command: comment (contains random /tmp/tmp.XXXXX path)
39+
# - generated_at timestamp in manifest.json
40+
if git diff -I 'kopium command:' -I '"generated_at":' --quiet; then
3841
echo "changed=false" >> "$GITHUB_OUTPUT"
3942
echo "No CRD or model changes detected."
4043
else

docs/README.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ This directory contains the Hugo-based documentation site for flux9s, using the
1111

1212
### Running Locally
1313

14-
1. Install Hugo dependencies:
14+
1. Install local docs dependencies:
1515

1616
```bash
17-
cd docs
18-
hugo mod get
17+
just docs-deps
1918
```
2019

20+
This installs the Node/PostCSS packages from `package-lock.json` and refreshes Hugo modules.
21+
2122
2. Fetch metadata (optional, for local testing):
2223

2324
```bash
@@ -30,6 +31,12 @@ hugo mod get
3031
hugo server
3132
```
3233

34+
Or from the repository root after `just docs-deps`:
35+
36+
```bash
37+
just docs-serve
38+
```
39+
3340
The site will be available at `http://localhost:1313/flux9s/`
3441

3542
### Building
@@ -40,6 +47,12 @@ To build the site:
4047
hugo --minify
4148
```
4249

50+
Or from the repository root after `just docs-deps`:
51+
52+
```bash
53+
just docs-build
54+
```
55+
4356
The built site will be in the `public/` directory.
4457

4558
## Structure

docs/SETUP.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,16 @@ This documentation site is built with [Hugo](https://gohugo.io/) and the [Docsy]
1212
### Local Development
1313

1414
```bash
15-
cd docs
16-
hugo mod get # Install Hugo modules
17-
hugo server # Start local server
15+
just docs-deps # Install Node/PostCSS packages and Hugo modules
16+
just docs-serve # Start local server from the repo root
1817
```
1918

2019
Visit `http://localhost:1313/flux9s/`
2120

2221
### Building
2322

2423
```bash
25-
cd docs
26-
hugo --minify
24+
just docs-build
2725
```
2826

2927
Output will be in `docs/public/`

docs/content/_index.md

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ notoc: true
2020
</div>
2121

2222
<!-- Tagline -->
23-
<p class="lead mb-5">A <a href="https://github.com/derailed/k9s" target="_blank" rel="noopener noreferrer">K9s</a>-inspired terminal UI for monitoring Flux GitOps resources</p>
23+
<p class="lead mb-5">A <a href="https://github.com/derailed/k9s" target="_blank" rel="noopener noreferrer">K9s</a>-inspired terminal UI for Flux resources, controller health, and GitOps state</p>
2424

2525
<!-- Action Buttons -->
2626
<div class="d-flex flex-wrap justify-content-center gap-3 mb-5">
@@ -73,3 +73,34 @@ notoc: true
7373
</div>
7474
</div>
7575
{{< /rawhtml >}}
76+
77+
{{< rawhtml >}}
78+
<div class="container py-5">
79+
<div class="row justify-content-center">
80+
<div class="col-lg-10 col-xl-9">
81+
<h2>What flux9s is</h2>
82+
<p><code>flux9s</code> is a terminal UI for operators who want live visibility into Flux resources and the cluster state around them without leaving the shell. It watches Flux resources in real time, keeps a local in-memory view of their current state, and lets you move quickly between lists, details, YAML, traces, graphs, and reconciliation history.</p>
83+
<p>The project is intentionally keyboard-first and closely follows familiar <a href="https://github.com/derailed/k9s" target="_blank" rel="noopener noreferrer">K9s</a> patterns: <code>j</code>/<code>k</code> navigation, <code>:</code> command mode, context and namespace switching, footer help, and k9s-style skins.</p>
84+
85+
<h2>The problem it solves</h2>
86+
<p>Flux already provides strong controller APIs, and the <a href="https://fluxoperator.dev/web-ui/" target="_blank" rel="noopener noreferrer">Flux Operator Web UI</a> is an excellent browser-based experience for dashboards and cluster-wide visibility. <code>flux9s</code> was built to complement that workflow, not replace it.</p>
87+
<p>Use <code>flux9s</code> when you want to stay in the terminal and:</p>
88+
<ul>
89+
<li>see Flux reconciliation state update live</li>
90+
<li>inspect Kustomizations, HelmReleases, sources, and Flux Operator resources in one place</li>
91+
<li>trace ownership chains and visualize managed workloads</li>
92+
<li>check controller readiness and Flux bundle version from the same interface</li>
93+
<li>run quick actions such as suspend, resume, reconcile, reconcile-with-source, and delete</li>
94+
</ul>
95+
96+
<h2>Why it stays fast</h2>
97+
<p><code>flux9s</code> uses the Kubernetes Watch API for supported Flux resource types instead of repeatedly polling. By default it starts scoped to a namespace, with the default configuration targeting <code>flux-system</code>, and only switches to cluster-wide watches when you explicitly choose <code>all</code>. That keeps API usage and terminal updates lighter on larger clusters.</p>
98+
<p>The same watch-driven model is also used to surface Flux controller pod state and deployment metadata in the header, which is how the UI can show controller readiness and the detected Flux bundle version alongside resource health.</p>
99+
100+
<h2>Built for Flux and Flux Operator</h2>
101+
<p>Beyond core Flux controller resources, <code>flux9s</code> also understands Flux Operator resources such as <code>FluxInstance</code>, <code>ResourceSet</code>, <code>ResourceSetInputProvider</code>, and <code>FluxReport</code>. That support shows up in practical features, not just extra rows in a table: graph and history views extend to operator-managed resources, and the graph builder follows the same relationship-discovery patterns used by the Flux Operator Web UI.</p>
102+
<p>For a deeper code-level walkthrough, see the <a href="{{< relref "developer-guide/" >}}">Developer Guide</a>. If you want to get running quickly, jump to <a href="{{< relref "getting-started/" >}}">Getting Started</a>.</p>
103+
</div>
104+
</div>
105+
</div>
106+
{{< /rawhtml >}}

docs/content/developer-guide/_index.md

Lines changed: 120 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,66 +9,118 @@ type: docs
99

1010
## Architecture
1111

12-
flux9s follows a modified Elm Architecture pattern with async task spawning:
12+
flux9s is a Rust TUI that keeps a live, local model of Flux resources and renders it through a keyboard-first interface. The architecture is intentionally simple: watch Kubernetes objects continuously, normalize them into in-memory state, and keep the UI loop responsive by pushing slower work onto async tasks.
1313

14-
### Model
14+
### Entry Points
15+
16+
The repository currently has two top-level execution modes:
17+
18+
- `src/main.rs` is the CLI and TUI binary entry point.
19+
- `src/lib.rs` exposes the reusable library API, including headless usage through `ClusterSession`.
20+
21+
The crate enables the TUI by default, but the `tui` feature is optional. That means contributor-facing architecture should be understood as "shared Flux watcher/library core plus an optional terminal UI", not only as a standalone binary.
22+
23+
### Data Flow
1524

16-
`App` struct holds all application state in a centralized location. State is organized into logical sub-structures for better maintainability.
25+
At a high level, the runtime looks like this:
1726

18-
### Update
27+
1. `src/watcher/mod.rs` starts a watch stream for each supported Flux resource kind, plus dedicated watchers for Flux controller pods and controller deployments.
28+
2. Watch events are normalized into `WatchEvent` values and applied to `ResourceState` in `src/watcher/state.rs`.
29+
3. `App` in `src/tui/app/` reads that state and renders list, detail, YAML, trace, graph, history, and favorites views.
30+
4. `ResourceService` and `ClusterSession` provide the same watcher/state/operation foundation without requiring the TUI layer.
1931

20-
`handle_key()` processes events and updates state synchronously. Event handling is centralized in `src/tui/app/events.rs`.
32+
### Watch Strategy And Performance
2133

22-
### View
34+
Performance is driven mostly by the watcher design:
35+
36+
- When a namespace is selected, `ResourceWatcher` uses `Api::namespaced(...)`.
37+
- Only when the user switches to `all` does it use `Api::all(...)`.
38+
- Namespace changes restart the watcher set instead of broad-watching everything and filtering afterward.
39+
- The default configuration starts in `flux-system`, which keeps initial watch scope narrow on larger clusters.
40+
41+
This is why flux9s can provide live updates while staying responsive on clusters where a cluster-wide watch would be unnecessarily expensive.
42+
43+
### Model
2344

24-
`render()` displays current state using stateless components. Views are organized in `src/tui/views/` and receive all needed data as parameters.
45+
`App` still follows a modified Elm-style split:
46+
47+
- `App` and the state structs in `src/tui/app/state.rs` hold the centralized TUI state.
48+
- `handle_key()` in `src/tui/app/events.rs` processes input synchronously.
49+
- `render()` in `src/tui/app/rendering.rs` draws the current state using stateless view functions from `src/tui/views/`.
50+
51+
This split keeps event handling predictable while making individual views easy to reason about and test.
2552

2653
### Async Layer
2754

28-
Spawned tasks + oneshot channels handle I/O operations without blocking the UI. Async operations are managed in `src/tui/app/async_ops.rs`.
55+
Network-bound and potentially slower operations are spawned off the main UI loop and returned through `oneshot` channels. This includes YAML fetches, trace resolution, graph building, and write operations such as suspend, resume, reconcile, and delete. The async entry points live in `src/tui/app/async_ops.rs`.
56+
57+
The important behavior is that the UI never blocks on these calls; it schedules the work, keeps rendering, and picks up results later.
58+
59+
### Type System And Generated Models
60+
61+
Flux and Flux Operator CRD types are generated into `src/models/_generated/`. The rest of the codebase relies on `FluxResourceKind` and the Kubernetes API helpers built around it as the single source of truth for resource names, aliases, groups, versions, and plural forms.
62+
63+
That approach is what keeps the watcher registry, fetch paths, command aliases, and type-specific views aligned when CRDs evolve.
64+
65+
### K9s Conventions And Flux-Specific Additions
66+
67+
flux9s deliberately reuses the K9s interaction model where it helps operators move quickly:
68+
69+
- `j`/`k` navigation and keyboard-first workflows
70+
- `:` command mode with aliases and autocomplete
71+
- context and namespace switching
72+
- footer and help overlays driven from centralized keybinding definitions
73+
- k9s-style skin compatibility
74+
75+
On top of that, flux9s adds workflows that are specific to Flux and Flux Operator:
76+
77+
- support for `FluxInstance`, `ResourceSet`, `ResourceSetInputProvider`, and `FluxReport`
78+
- trace and graph views for Flux-managed relationships
79+
- reconciliation history for resource types that expose `status.history`
80+
- reconcile-with-source and other Flux-aware resource actions
81+
82+
The graph code in `src/trace/graph_builder.rs` explicitly follows patterns from the Flux Operator Web UI, which is why Flux Operator resources can participate in the same relationship views as core Flux resources.
2983

3084
## Project Structure
3185

3286
```
3387
flux9s/
3488
├── src/
35-
│ ├── cli/ # CLI command parsing
36-
│ ├── config/ # Configuration management
37-
│ ├── kube/ # Kubernetes client wrapper
38-
│ ├── models/ # Generated and custom models
39-
│ ├── trace/ # Resource tracing
40-
│ ├── tui/ # Terminal UI
41-
│ │ ├── app/ # Application state and logic (refactored)
42-
│ │ │ ├── core.rs # App struct and core logic
43-
│ │ │ ├── state.rs # State structures
44-
│ │ │ ├── events.rs # Event handling
45-
│ │ │ ├── rendering.rs # Render orchestration
46-
│ │ │ └── async_ops.rs # Async operations
47-
│ │ ├── views/ # View components
48-
│ │ ├── submenu.rs # Submenu system
49-
│ │ ├── keybindings.rs # Keybinding management
50-
│ │ └── ... # Other TUI modules
51-
│ └── watcher/ # Resource watching
52-
├── crds/ # Flux CRD files
53-
├── tests/ # Integration tests
54-
└── docs/ # Documentation
89+
│ ├── main.rs # Binary entry point
90+
│ ├── lib.rs # Library entry point and public exports
91+
│ ├── cli/ # CLI commands, config subcommands, logging, version output
92+
│ ├── config/ # Config schema, loading, paths, themes
93+
│ ├── kube/ # Kubernetes API helpers, dynamic fetch, inventory helpers
94+
│ ├── models/ # Generated CRD models plus custom resource field extraction
95+
│ ├── operations.rs # Flux resource operations and operation registry
96+
│ ├── services/ # Headless service layer (`ClusterSession`, `ResourceService`)
97+
│ ├── trace/ # Trace and graph building logic
98+
│ ├── watcher/ # Watch registry, resource bindings, watch state
99+
│ └── tui/ # Optional ratatui/crossterm frontend
100+
│ ├── app/ # App state, events, rendering, async operation polling
101+
│ ├── views/ # Stateless renderers for list/detail/header/footer/etc.
102+
│ ├── commands.rs # Command parsing, aliases, submenus
103+
│ ├── keybindings.rs
104+
│ ├── operations.rs
105+
│ ├── submenu.rs
106+
│ ├── theme.rs
107+
│ └── trace.rs
108+
├── tests/ # Integration-style tests and snapshots
109+
├── docs/ # Hugo docs site
110+
└── justfile # Common contributor workflows
55111
```
56112

57-
### Recent Architecture Changes
113+
### TUI Module Notes
58114

59-
**App Module Refactoring:** The application logic has been refactored from a single `app.rs` file into a modular structure under `src/tui/app/`:
115+
The TUI is not a single monolith anymore. The current split is:
60116

61117
- **`core.rs`** - Main App struct and core logic
62-
- **`state.rs`** - Organized state structures (ViewState, SelectionState, UIState, AsyncOperationState)
118+
- **`state.rs`** - Organized state structures (view, selection, UI, async, controller pod state)
63119
- **`events.rs`** - Event handling and input processing
64120
- **`rendering.rs`** - Rendering orchestration
65121
- **`async_ops.rs`** - Async operation management
66122

67-
This separation improves code organization, maintainability, and makes the codebase easier to navigate.
68-
69-
**Submenu System:** An interactive submenu system has been added for commands like `:ctx` and `:skin`, providing a user-friendly way to select from available options. The system is built using the `CommandSubmenu` trait and can be extended to other commands. See the main `DEVELOPER_GUIDE.md` for implementation details.
70-
71-
**Keybinding Centralization:** All keybindings are now centralized in `src/tui/keybindings.rs`, providing a single source of truth for footer rendering, help text, and layout calculations.
123+
The command palette and submenu behavior live outside that folder in `src/tui/commands.rs` and `src/tui/submenu.rs`, while footer/help consistency is driven by `src/tui/keybindings.rs`.
72124

73125
## Development Setup
74126

@@ -91,11 +143,41 @@ cargo build
91143
just ci
92144
```
93145

94-
This runs:
146+
The current `just ci` workflow runs:
95147

96148
- `cargo fmt` - Format code
97149
- `cargo clippy` - Lint code
98-
- `cargo test` - Run tests
150+
- `cargo audit` - Advisory check
151+
- `cargo test --lib --tests` - Library and unit-style tests
152+
- `cargo test --test ...` - Selected integration-style test binaries
153+
154+
`cargo audit` needs network access to refresh the RustSec advisory database, so it may fail in restricted environments even when the code is fine.
155+
156+
### Docs Workflow
157+
158+
The docs site is maintained in the same repository and has explicit `just` helpers:
159+
160+
```bash
161+
just docs-deps
162+
just docs-serve
163+
just docs-build
164+
```
165+
166+
Use these instead of ad hoc commands when working on the Hugo site from the repo root.
167+
168+
## Testing Layout
169+
170+
The test tree is flatter than some older internal notes imply. Today, most contributor-facing tests live as top-level files under `tests/`:
171+
172+
- `crd_compatibility.rs` - compatibility checks for watched CRDs and status extraction
173+
- `resource_registry.rs` - registry completeness checks
174+
- `field_extraction.rs` - resource field extraction behavior
175+
- `trace_tests.rs` and `graph_tests.rs` - relationship discovery and graph behavior
176+
- `reconciliation_history_tests.rs` - history extraction behavior
177+
- `favorites_tests.rs` - config-backed favorites behavior
178+
- `navigation_tests.rs` and `snapshot_tests.rs` - TUI behavior and rendering snapshots
179+
180+
Snapshot artifacts live in `tests/snapshots/`. TUI-specific tests are feature-gated in `Cargo.toml`, while the headless/library tests run without the `tui` feature.
99181

100182
## Contributing
101183

docs/content/getting-started/_index.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ toc: true
77
type: docs
88
---
99

10+
## What Is flux9s?
11+
12+
`flux9s` is a terminal UI for watching Flux resources and the cluster state around them in real time. It is designed for operators who already live in a shell and want fast visibility into what Flux is doing, how resources relate to each other, and whether quick intervention is needed.
13+
14+
That includes core Flux resources such as `Kustomization`, `HelmRelease`, and source objects, plus Flux Operator resources such as `FluxInstance` and `ResourceSet`. From the same interface you can inspect YAML, trace ownership, open graph and history views, and run common actions like suspend, resume, and reconcile.
15+
16+
## Why Use It If Flux Operator Has a Web UI?
17+
18+
The [Flux Operator Web UI](https://fluxoperator.dev/web-ui/) is excellent for browser-based visibility. `flux9s` complements it with a terminal-first workflow: keyboard navigation, quick context switching, namespace-scoped live watches, and operational actions without leaving your current shell session.
19+
1020
## Quick Start
1121

1222
Follow these steps to get started with flux9s:

justfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,18 @@ build:
3737
build-release:
3838
cargo build --release
3939

40+
# Install local dependencies for the Hugo docs site
41+
docs-deps:
42+
cd docs && npm ci && hugo mod get
43+
44+
# Build the Hugo docs site
45+
docs-build:
46+
cd docs && hugo --minify
47+
48+
# Serve the Hugo docs site locally
49+
docs-serve:
50+
cd docs && hugo server
51+
4052
# Check the project (without building)
4153
check:
4254
cargo check

0 commit comments

Comments
 (0)