127 lines
5.4 KiB
Markdown
127 lines
5.4 KiB
Markdown
|
|
# 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 Q1–Q7 are answered — adding them to an existing model is straightforward; guessing them now is expensive.
|