furtka/docs/resource-manager.md

127 lines
5.4 KiB
Markdown
Raw Normal View History

# Resource Manager — Design Notes
Scaffold for the conversation between Daniel and Robert. Captures what Robert already sketched in chat on 2026-04-15 and lists the open questions that need an answer before we write code.
**Status:** Draft 2026-04-15. Nothing implemented. First app to consume this will be a LAN fileshare (SMB/NFS) — that's the forcing function.
---
## What's the Resource Manager?
The layer between Furtka apps and the underlying system (disk, Docker, network, users). Apps don't touch Docker or the filesystem directly — they declare what they need, the Resource Manager provisions and tracks it.
Robert's framing (2026-04-15): *"żeby później można było manipulować wszystkimi peryferiami"* — so we can manipulate all peripherals from one place later.
---
## Decided (Robert, 2026-04-15)
1. **An app is a folder.** A Furtka app is defined as a directory containing:
- a manifest
- a `docker-compose.yaml`
- a `.env` file
2. **A registration script** reads that folder and wires the app into the backend.
3. **Each app gets its own named Docker volume.** Sharing between apps is possible but opt-in, not default.
4. **Filesystem is the source of truth (for now).** No SQL database yet — the Resource Manager reads current state from Docker and the OS ad-hoc. DB gets added when we actually need to store intent the OS doesn't know (e.g. "this share belongs to App X, readable by User Y").
These are locked; don't re-litigate without Robert.
---
## Open questions
These need an answer before the first line of code.
### Q1 — What's in the manifest?
This is the contract between app authors and Furtka. Changing it later is expensive. Known candidates:
- `name` (machine id, must match folder name?)
- `display_name` (shown in UI)
- `version` (semver? calver?)
- `description`
- `volumes` (list of named volumes the app needs)
- `ports` (which ports the app wants exposed; needed for reverse proxy later)
- `icon` (path or URL)
- ... anything else?
**Format:** YAML / TOML / JSON — not decided.
### Q2 — Where do apps live on disk?
Suggested-but-not-decided: `/var/lib/furtka/apps/<app-name>/`. Robert: confirm path?
### Q3 — What does the registration script actually do?
Robert said "Skript do rejestrowania w backendzie". Concretely that means some subset of:
- Validate manifest (schema check, required fields, volume names unique)
- Create any declared named volumes that don't exist yet
- Run `docker compose up -d` inside the app folder
- Record the app in whatever passes for the backend index (right now: nothing — we'd just re-scan the folder each time)
**Sub-question:** is registration a one-shot on install, or does something (systemd unit?) re-scan `/var/lib/furtka/apps/` on every boot so the filesystem really is authoritative?
### Q4 — How does the user actually install an app?
Out of scope for the first cut, but needed to know the shape of the CLI:
- Admin UI with a button "Install Fileshare"?
- CLI: `furtka app install <tarball>` / `<git repo>` / `<name-from-catalog>`?
- Catalog = a separate repo with app folders?
### Q5 — Upgrades and removal
- Upgrade strategy: replace folder + re-run compose? Preserve volumes across upgrades (yes obviously, but needs stating)?
- Removal: does it delete the volume or keep it? Robert's "apki się dzielą" implies a volume can outlive its original app.
### Q6 — Volume sharing semantics
Robert: "jak będzie trzeba to będą mogły się dzielić". Open:
- Who requests the share — the sharing app's manifest, or an admin action?
- What's the permission model (read-only, read-write, per-user)?
- This is probably the *first* piece of "intent not reflected in OS state" — might be what finally motivates the DB.
### Q7 — Backend API surface
Once the filesystem model is clear, the Resource Manager's backend still needs *some* Python/whatever surface that the web UI and the register script both call. Rough shape:
- `list_apps()` — scan `/var/lib/furtka/apps/`, return manifests + running status
- `install_app(folder)` — validate + compose up
- `remove_app(name)` — compose down, optionally rm volume
- `list_volumes()` — from Docker
- `list_shares()` — ???
Not decided whether this lives in the existing `webinstaller` Flask app, a new backend service, or a thin CLI that the Flask app shells out to.
---
## First consumer — Fileshare
The point of doing this now is to unblock the fileshare app (see `../memory/project_first_app_fileshare.md` for the conversation context). Walking it through the model above:
```
/var/lib/furtka/apps/fileshare/
manifest.??? # see Q1 — what exactly goes here?
docker-compose.yaml
.env
```
- App declares a volume (e.g. `files`).
- Compose runs a Samba/NFS container mounting that volume.
- On Mac/Windows/Android you mount `smb://furtka.local/files`.
If we can get *this* end-to-end through the Resource Manager, we've validated the whole model with the simplest possible app. Nextcloud, Jellyfin, etc. are the same shape with more knobs.
---
## What we do NOT do yet
- No database. (Decided.)
- No user/permissions model beyond what Samba/OS already give us.
- No reverse proxy / TLS integration in the manifest. (Tracked separately — see `../memory/project_ssl_local_deferred.md`.)
- No app catalog / store UI. Manual install first.
- No auto-updates.
These all become easier once Q1Q7 are answered — adding them to an existing model is straightforward; guessing them now is expensive.