updated README and CHANGELOG
This commit is contained in:
+26
-1
@@ -1,6 +1,31 @@
|
|||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
### What was just completed (2026-02-19 session 60)
|
### What was just completed (2026-02-20 session 61)
|
||||||
|
- **v0.19.0 — Deployed App Removal + Missing Field Injection:**
|
||||||
|
|
||||||
|
Two new features: "Eltávolítás" (Remove) action for deployed stacks and automatic missing deploy field injection on template updates.
|
||||||
|
|
||||||
|
**Feature A — Deployed App Removal ("Eltávolítás"):**
|
||||||
|
- `delete.go`: Added `RemoveStack()` — removes deployed (non-orphaned) stack: `docker compose down --volumes`, optional HDD data cleanup, optional backup data cleanup (DB dumps + cross-drive rsync), removes `app.yaml` only (template files preserved for redeploy); stack reverts to "Nincs telepítve" state
|
||||||
|
- `delete.go`: Added `GetStackBackupData()` — returns backup path info (DB dump dir + cross-drive rsync dir) with sizes and existence status
|
||||||
|
- `delete.go`: Added `RemoveResponse`, `BackupDataResponse` structs, `buildPathInfo()` helper
|
||||||
|
- `router.go`: Added `POST /api/stacks/{name}/remove` endpoint — accepts `{remove_hdd_data, remove_backups}`, computes backup paths via `AppDBDumpPath()`/`AppSecondaryRsyncPath()`, cleans cross-drive config on success
|
||||||
|
- `router.go`: Added `GET /api/stacks/{name}/backup-data` endpoint — returns backup data paths with sizes
|
||||||
|
- `crossdrive.go`: Made `getAppDrivePath` → `GetAppDrivePath` (public) for use by router
|
||||||
|
- `stacks.html`: Added "Eltávolítás" button for stopped, deployed, non-orphaned, non-protected stacks
|
||||||
|
- `dashboard.html`: Same button in compact card layout
|
||||||
|
- `layout.html`: Added `removeStack()` modal — fetches HDD + backup data in parallel, 3-section layout (always removed / HDD data with checkbox / backup data with checkbox), reimport warning for preserved HDD data, restic retention note
|
||||||
|
- `layout.html`: Added `confirmRemoveStack()` — POST to `/remove`, shows result summary with removed/preserved paths
|
||||||
|
|
||||||
|
**Feature B — Missing Deploy Field Injection:**
|
||||||
|
- `deploy.go`: Added `InjectMissingFields(stackNames)` — iterates deployed stacks, compares `.felhom.yml` deploy_fields against `app.yaml` env vars, auto-generates values for missing `secret` (using generator spec) and `domain` fields, saves updated `app.yaml`
|
||||||
|
- `deploy.go`: Added `base64key` generator type — produces `base64:<N random bytes base64-encoded>` (for Laravel APP_KEY and similar)
|
||||||
|
- `deploy.go`: Added `containsStr()` helper
|
||||||
|
- `manager.go`: Added `DeployedStackNames()` — returns names of all deployed stacks
|
||||||
|
- `sync.go`: Added `postSyncHook func(updated []string)` field to `Syncer`; `New()` accepts optional hook; hook called in `doSync()` after rescan with names of updated stacks
|
||||||
|
- `main.go`: Wired injection on startup (all deployed stacks) and after sync (updated stacks only)
|
||||||
|
|
||||||
|
### v0.18.0 (2026-02-19 session 60)
|
||||||
- **v0.18.0 — Drive Migration & Tier 2 Restic Deprecation:**
|
- **v0.18.0 — Drive Migration & Tier 2 Restic Deprecation:**
|
||||||
|
|
||||||
Full drive replacement workflow with decommissioned state, enhanced per-app migration with backup awareness, and deprecation of restic as a Tier 2 cross-drive backup method (rsync only).
|
Full drive replacement workflow with decommissioned state, enhanced per-app migration with backup awareness, and deprecation of restic as a Tier 2 cross-drive backup method (rsync only).
|
||||||
|
|||||||
+30
-8
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
A single, lightweight Go container that replaces Portainer + scattered systemd scripts with a unified, Hungarian-language web dashboard for managing Docker Compose stacks, backups, storage, monitoring, and notifications on customer hardware.
|
A single, lightweight Go container that replaces Portainer + scattered systemd scripts with a unified, Hungarian-language web dashboard for managing Docker Compose stacks, backups, storage, monitoring, and notifications on customer hardware.
|
||||||
|
|
||||||
**Current version: v0.16.0**
|
**Current version: v0.19.0**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -111,12 +111,13 @@ The app catalog lives in a separate Git repository. The controller:
|
|||||||
- **Never overwrites** `app.yaml` or `.env` (user secrets are safe)
|
- **Never overwrites** `app.yaml` or `.env` (user secrets are safe)
|
||||||
- Uses SHA-256 content hashing — only writes files that actually changed
|
- Uses SHA-256 content hashing — only writes files that actually changed
|
||||||
- Triggers stack rescan after sync so the dashboard updates immediately
|
- Triggers stack rescan after sync so the dashboard updates immediately
|
||||||
|
- **Post-sync hook**: auto-injects missing deploy fields (new secrets, domains) into existing `app.yaml` for stacks whose templates were updated (see Missing Field Injection below)
|
||||||
- Manual sync via "Sablonok frissitese" button or `POST /api/sync`
|
- Manual sync via "Sablonok frissitese" button or `POST /api/sync`
|
||||||
|
|
||||||
#### First-Time Deploy Flow
|
#### First-Time Deploy Flow
|
||||||
|
|
||||||
1. Customer sees app card with "Telepites" button
|
1. Customer sees app card with "Telepites" button
|
||||||
2. Deploy page shows auto-filled fields (domain), auto-generated secrets (DB passwords, hex keys), and user-configurable inputs (admin password, language, storage path)
|
2. Deploy page shows auto-filled fields (domain), auto-generated secrets (DB passwords, hex keys, base64 keys), and user-configurable inputs (admin password, language, storage path)
|
||||||
3. `checkBeforeDeploy()` JS guard fetches live state first (prevents double-deploy from another tab)
|
3. `checkBeforeDeploy()` JS guard fetches live state first (prevents double-deploy from another tab)
|
||||||
4. **Memory validation** checks `mem_request` against available RAM:
|
4. **Memory validation** checks `mem_request` against available RAM:
|
||||||
- `usable_memory = total_ram - reserved_memory_mb` (default 384MB reserved)
|
- `usable_memory = total_ram - reserved_memory_mb` (default 384MB reserved)
|
||||||
@@ -143,12 +144,31 @@ The `/apps/{slug}` page renders hero section, screenshots, setup guide, and opti
|
|||||||
| Stop | `docker compose stop` (blocked for protected stacks) |
|
| Stop | `docker compose stop` (blocked for protected stacks) |
|
||||||
| Restart | `docker compose restart` |
|
| Restart | `docker compose restart` |
|
||||||
| Update | `docker compose pull` + `docker compose up -d` |
|
| Update | `docker compose pull` + `docker compose up -d` |
|
||||||
| Delete | `docker compose down --rmi local --volumes` + optional HDD data cleanup |
|
| Remove | `docker compose down --volumes` + remove `app.yaml` + optional HDD/backup cleanup; template preserved for redeploy |
|
||||||
|
| Delete | `docker compose down --rmi local --volumes` + optional HDD data cleanup (orphaned stacks only) |
|
||||||
|
|
||||||
**Protected stacks** (traefik, cloudflared, felhom-controller) cannot be stopped or deleted from the UI. Restart is allowed.
|
**Remove vs Delete**: "Eltávolítás" (Remove) is for deployed catalog stacks — it reverts the stack to "Nincs telepítve" state while keeping the template for easy redeployment. "Törlés" (Delete) is for orphaned stacks — it removes the entire stack directory including templates. Both require stopping the stack first.
|
||||||
|
|
||||||
|
**Remove modal** shows three sections: (1) always-removed items (Docker volumes, app.yaml, cross-drive schedule), (2) optional HDD data deletion with reimport warning, (3) optional backup data deletion (DB dumps + cross-drive rsync) with restic retention note.
|
||||||
|
|
||||||
|
**Protected stacks** (traefik, cloudflared, felhom-controller) cannot be stopped, removed, or deleted from the UI. Restart is allowed.
|
||||||
|
|
||||||
**Orphan detection**: Deployed stacks with no matching catalog template are marked as orphaned with an "Elavult" badge and can be safely deleted.
|
**Orphan detection**: Deployed stacks with no matching catalog template are marked as orphaned with an "Elavult" badge and can be safely deleted.
|
||||||
|
|
||||||
|
#### Missing Field Injection (`deploy.go`)
|
||||||
|
|
||||||
|
When app templates are updated (e.g., a new `APP_KEY` secret is added to `.felhom.yml`), existing deployed apps need the new field in their `app.yaml`. The controller handles this automatically:
|
||||||
|
|
||||||
|
- **On startup**: `InjectMissingFields()` runs for all deployed stacks
|
||||||
|
- **After sync**: the post-sync hook runs for stacks whose templates were updated
|
||||||
|
- For each deployed stack, compares `.felhom.yml` `deploy_fields` against `app.yaml` env vars
|
||||||
|
- Missing `secret` fields: auto-generated using the field's generator spec (`password:N`, `hex:N`, `base64key:N`)
|
||||||
|
- Missing `domain` fields: filled with the customer's configured domain
|
||||||
|
- Other field types (e.g., `text`, `select`): logged as warning for manual configuration
|
||||||
|
- Locked fields are added to the locked list automatically
|
||||||
|
|
||||||
|
**Generator types**: `password:N` (alphanumeric), `hex:N` (hex-encoded random bytes), `base64key:N` (`base64:` + N random bytes base64-encoded, for Laravel APP_KEY etc.), `static:VALUE` (literal value).
|
||||||
|
|
||||||
#### Container State Display
|
#### Container State Display
|
||||||
|
|
||||||
| State | Color | Label | Meaning |
|
| State | Color | Label | Meaning |
|
||||||
@@ -813,8 +833,8 @@ controller/
|
|||||||
│ ├── stacks/
|
│ ├── stacks/
|
||||||
│ │ ├── manager.go # Stack scanning, compose ops, container status
|
│ │ ├── manager.go # Stack scanning, compose ops, container status
|
||||||
│ │ ├── metadata.go # Parse .felhom.yml app metadata
|
│ │ ├── metadata.go # Parse .felhom.yml app metadata
|
||||||
│ │ ├── deploy.go # First-deploy: secret gen, app.yaml, compose up
|
│ │ ├── deploy.go # First-deploy: secret gen, app.yaml, compose up; missing field injection
|
||||||
│ │ └── delete.go # Stack deletion + HDD data cleanup
|
│ │ └── delete.go # Stack deletion/removal + HDD/backup data cleanup
|
||||||
│ ├── sync/sync.go # Git sync: clone/pull app catalog, content-hash copy
|
│ ├── sync/sync.go # Git sync: clone/pull app catalog, content-hash copy
|
||||||
│ ├── storage/
|
│ ├── storage/
|
||||||
│ │ ├── scan.go, scan_linux.go # Disk detection via lsblk + blkid
|
│ │ ├── scan.go, scan_linux.go # Disk detection via lsblk + blkid
|
||||||
@@ -935,7 +955,7 @@ Auto-managed by the controller. Contains password hash overrides, notification p
|
|||||||
|
|
||||||
### Per-app config (`app.yaml`)
|
### Per-app config (`app.yaml`)
|
||||||
|
|
||||||
Auto-generated during deployment. Contains env vars, locked fields list, deploy timestamp. Secret fields are locked (read-only after first deploy).
|
Auto-generated during deployment. Contains env vars, locked fields list, deploy timestamp. Secret fields are locked (read-only after first deploy). Missing fields from updated templates are auto-injected on startup and after sync (see Missing Field Injection).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -977,7 +997,9 @@ All daily jobs use Europe/Budapest timezone. Skip-if-running prevents concurrent
|
|||||||
| POST | `/api/stacks/{name}/optional-config` | Update optional env vars |
|
| POST | `/api/stacks/{name}/optional-config` | Update optional env vars |
|
||||||
| GET | `/api/stacks/{name}/logs` | Container logs (`?raw=1` for plain text) |
|
| GET | `/api/stacks/{name}/logs` | Container logs (`?raw=1` for plain text) |
|
||||||
| GET | `/api/stacks/{name}/hdd-data` | HDD data paths + sizes |
|
| GET | `/api/stacks/{name}/hdd-data` | HDD data paths + sizes |
|
||||||
| DELETE | `/api/stacks/{name}` | Delete stack |
|
| GET | `/api/stacks/{name}/backup-data` | Backup data paths + sizes (DB dumps, cross-drive rsync) |
|
||||||
|
| POST | `/api/stacks/{name}/remove` | Remove deployed stack (revert to "not deployed") |
|
||||||
|
| DELETE | `/api/stacks/{name}` | Delete orphaned stack |
|
||||||
| POST | `/api/sync` | Trigger catalog sync |
|
| POST | `/api/sync` | Trigger catalog sync |
|
||||||
| GET | `/api/system/info` | System info + sync status |
|
| GET | `/api/system/info` | System info + sync status |
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user