# 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//`. 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 ` / `` / ``? - 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.