furtka/CHANGELOG.md
Daniel Maksymilian Syrnicki 522ea06cd0
All checks were successful
CI / lint (pull_request) Successful in 1m10s
CI / test (pull_request) Successful in 2m17s
CI / validate-json (pull_request) Successful in 1m5s
CI / markdown-links (pull_request) Successful in 41s
fix(smoke): bump smoke-VM RAM to 8 GiB + make cores/memory configurable
pollux (192.168.178.165) wedged at the network level during an
end-to-end install test today — mkinitcpio on a 4 GiB smoke VM +
the cached 1.5 GB ISO + a busy runner container pushed the host into
OOM, taking pveproxy and the SSH path down with it. Recovered by
physical reset.

Smoke VM now defaults to 8192 MiB / 2 vCPU, configurable via
PVE_TEST_VM_MEMORY / PVE_TEST_VM_CORES. Host has 64 GiB, so one
smoke VM at 8 GiB is well within headroom.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 14:28:29 +02:00

94 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Changelog
All notable changes to Furtka will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
This project uses calendar versioning: `YY.N-stage` (e.g. `26.0-alpha` = 2026, release 0, alpha stage).
## [Unreleased]
## [26.4-alpha] - 2026-04-18
### Added
- **Local HTTPS via Caddy `tls internal`** on port 443. Caddy generates a per-box local root CA on first start; the Caddyfile now serves both `:80` and `:443` from the same routes. HTTP stays on by default — no regression for users who haven't trusted the CA yet. New "Local HTTPS" section in `/settings` shows the CA's SHA-256 fingerprint, offers a one-click download of `rootCA.crt`, links to the per-OS install guide at `/https-install/`, and exposes an opt-in "force HTTPS" toggle that only unhides itself once the current browser has already trusted the cert (so enabling it can't lock the user out of the settings page). Backend: `GET /api/furtka/https/status` and `POST /api/furtka/https/force` in `furtka.https`. The force toggle drops a Caddy import snippet into `/etc/caddy/furtka.d/redirect.caddyfile` and reloads Caddy; reload failure automatically rolls the snippet state back so a bad config can't wedge the next service start.
- **Impressum + Datenschutzerklärung on furtka.org** (both DE and EN) covering §5 DDG and Art. 13 GDPR. Linked from the site footer on every page; bilingual with DE as the legally binding version.
- **Auto-deploy of furtka.org on push-to-main.** New `.forgejo/workflows/deploy-site.yml` runs on the self-hosted runner (which *is* forge-runner-01 — the webserver host), so the deploy is just a local rsync + `hugo --minify` into `/var/www/furtka.org/`. No SSH, no secrets. Manual `website/deploy.sh` remains for out-of-band deploys.
- **Post-build smoke VM on Proxmox test host 192.168.178.165.** Every `build-iso` run boots the freshly built ISO in a throwaway VM on pollux (8 GiB RAM / 2 vCPU — the 4 GB default OOM-ed the host during mkinitcpio), then curls `:5000` to confirm the webinstaller is alive. VMs in VMID range 90009099 tagged with the commit SHA; last 5 kept for post-mortem debugging. Optional `workflow_dispatch` "Smoke latest ISO" re-tests the cached ISO in ~2 min without rebuilding. Step-level `continue-on-error` means a VM-side flake doesn't mark the ISO build red.
### Fixed
- **Settings page "Installed" field now refreshes after a self-update.** The `/api/furtka/update/check` response already carries `current` — the settings JS now drives `upd-current` from it the same way it drives `upd-latest`, so clicking "Check for updates" after a successful update reflects the new installed version without a force-reload.
- **Auto-reload on update completion is now reliable.** Clicking "Update now" arms a 45 s fallback `setTimeout(location.reload)` in addition to the existing `/update-state.json` polling loop. If the mid-apply API restart drops the poll connection before `stage: done` is ever observed (as seen on the 2026-04-16 VM test), the fallback still brings the page up on the new version. The fallback is cleared on `done` (5 s reload wins) or `rolled_back` (user needs the error visible).
- **Version string in the webinstaller footer** was pinned at `26.0-alpha` and didn't track releases. Bumped to `26.4-alpha` for this release; follow-up will make it render from `pyproject.toml` dynamically.
## [26.3-alpha] - 2026-04-16
### Fixed
- **Release workflow no longer depends on `jq`.** The previous `apt-get install -y jq` step hung on a slow mirror for 15+ minutes and stalled the 26.2-alpha publish. `publish-release.sh` now assembles the release-create payload via a tiny `python3 -c` block — Python is always available on the Forgejo Actions runner. `apt-get` path removed entirely.
## [26.2-alpha] - 2026-04-16
### Fixed
- **Updater "Check for updates" no longer 404s when every release is a pre-release.** `check_update()` queried Forgejo's `/releases/latest`, which silently excludes pre-releases (anything tagged `-alpha`/`-beta`/`-rc`) and returns 404 when there is no stable release. Switched to `/releases?limit=1`, which Forgejo sorts newest-first across all release kinds. During the alpha stage where every tag is a pre-release this is the only thing that works; once we tag a stable release, the same query still picks it up.
## [26.1-alpha] - 2026-04-16
### Added
- **Furtka self-update** (Phase 2). Tagging a release on main fires `.forgejo/workflows/release.yml`, which packages `furtka/` + `apps/` + a root-level `VERSION` file as `furtka-<tag>.tar.gz`, uploads it plus a `.sha256` + `release.json` to the Forgejo releases page, and makes the release available to running boxes. New CLI: `furtka update [--check]` + `furtka rollback`. New endpoints: `POST /api/furtka/update/check` + `/apply` + `GET /api/furtka/update/status`. UI: "Furtka updates" card on `/settings` shows installed vs latest, Update button runs the apply flow detached via `systemd-run`, progress polls `/update-state.json` served by Caddy so the mid-update API restart doesn't interrupt reporting. Atomic `/opt/furtka/current` symlink flip, auto-rollback on health-check failure post-restart, SHA256-verified downloads.
- **Per-app container image updates** (Phase 1). `POST /api/apps/<name>/update` runs `docker compose pull`, compares the running container's image digest to the just-pulled local image digest per service, and only restarts containers whose image actually changed. Update button on each installed-app row in `/apps`. Keeps `image: :latest` pins simple — no compose-file mutations.
- **Per-version install layout** on `/opt/furtka/`. Install now extracts the resource-manager payload to `/opt/furtka/versions/<VERSION>/` and creates `/opt/furtka/current` as an atomic symlink; updates flip the symlink in place and `systemctl link` every unit from the shipped `assets/systemd/` tree. Runtime JSON (`status.json`, `furtka.json`, `update-state.json`) moved to `/var/lib/furtka/` so self-updates never clobber it.
- **On-box UI uplevel** across three pages sharing one design system (`/style.css` served by Caddy). Redesigned landing page with a "Your apps" tile grid driven by `/api/apps`, a `fileshare` app tile that deep-links to `smb://<host>.local/files`, status tiles, and subtle "Coming next" links to `furtka.org`. `/apps` page renders real app icons inlined from each manifest's `icon.svg` (defensive SVG sanitiser — strips script/on*/javascript: content, 16 KB cap). New `/settings` page with About-this-box, Appearance, Furtka-updates, and Coming-next sections. Persistent top nav (Jakob's Law) on every page. Light-mode support via `prefers-color-scheme`.
- **Webinstaller step 2 (boot drive)** now shows size / type / health chips plus a "Recommended" badge on the auto-selected drive instead of a raw numeric score.
- **Forgejo branch protection on `main`** — no direct pushes except owner-whitelisted, required status checks (`CI / lint*`, `CI / test*`, `CI / validate-json*`), applied via the idempotent `ops/forgejo/apply-branch-protection.sh` script.
- **In-browser app settings**, so users no longer need SSH + `vim` to configure an app before first install. Manifest gains optional `settings` (name/label/description/type/required/default) and `description_long` fields. Installing a bundled app opens a form rendered from the manifest; installed apps grow a "Settings" button that edits merged values (password fields blank = keep current). API: `POST /api/apps/install` now accepts a `settings` object in the JSON body; new `GET`/`POST /api/apps/<name>/settings` for inspecting and updating an installed app. Password values never leave the server.
- `nano` added to the installer package list so users have a beginner-friendly editor at the console/SSH (was `vim`-only, which `command not found`'d under Arch 4.x because it was actually missing from the package set too).
- `openssh` added explicitly to the installer package list and `sshd` added to enabled services. `archinstall: true` in archinstall 4.x did not actually install openssh-server, so the documented recovery path (SSH → edit `.env`) silently failed.
- **Forgejo Actions runner** live on Proxmox VM (`forge-runner-01`, Ubuntu 24.04) with DinD sidecar — CI green end-to-end. Setup scripts in `ops/forgejo-runner/`.
- **Walking-skeleton live ISO** (`iso/build.sh`). Overlays an Arch `releng` profile with Flask + the webinstaller, bakes a systemd unit that auto-starts the wizard on boot, produces a hybrid BIOS/UEFI ISO via `mkarchiso` in a privileged `archlinux:latest` container. Tested booting under OVMF in Proxmox — wizard screens 13 respond at `http://<vm-ip>:5000`.
- **Public website at [furtka.org](https://furtka.org)** (`website/`). Hugo static site, English + German, served from `/var/www/furtka.org` on `forge-runner-01` via nginx. Upstream openresty proxy handles TLS. Intentionally minimal single-page copy while the project is pre-alpha. Deploy is `./website/deploy.sh` (rsync + remote Hugo build); one-time VM setup in `ops/nginx/setup-vm.sh`.
### Changed
- Every on-box asset (landing page, settings page, style.css, status/welcome scripts, systemd units, Caddyfile) moved from inline Python string constants in `webinstaller/app.py` into real files under `furtka/assets/`. The installer reads them from disk at install time; the self-updater ships them in the release tarball.
- Settings-button label went from "Einstellungen" (prototyping leftover) to "Settings" — rest of the UI chrome is English.
- Keyboard layout at the TTY now follows the chosen installer language (`de``de`, `pl``pl`, `en``us`) instead of hardcoding `us`. Previously German users couldn't type `/`, `-`, or `=` at the recovery console.
- `fileshare` app: `description_long` + `settings` (SMB_USER, SMB_PASSWORD) for the new settings form. Docker-level healthcheck from `dperson/samba` is disabled in the compose override — it timed out under normal operation and marked a working share "unhealthy" in `docker ps`.
- **Project name finalized: Furtka.** Working title "Homebase" retired. Domain `furtka.org` registered via Strato 2026-04-13.
- Managed gateway NS hostnames updated from `ns1.homebase.cloud` / `ns2.homebase.cloud` to `ns1.furtka.org` / `ns2.furtka.org`.
- Python package renamed from `homebase``furtka` in `pyproject.toml`.
## [26.0-alpha] - 2026-04-13
First tagged snapshot. Pre-alpha — the installer does not yet boot, but the design is locked and the prototype components are shaped.
### Added
- **Installer webapp prototype** (`webinstaller/`) — Flask app with 3-step wizard (hostname → drive → overview), serves drive list via `drives.py::list_scored_devices()`.
- **Drive scoring module** (`webinstaller/drives.py`) — scores attached disks by type (NVMe/SSD/HDD), SMART health (`smartctl -H`), and size. Consumed by the installer and usable as a CLI.
- **Base archinstall configuration** (`archinstall/user_configuration.json`) — systemd-boot, ext4, Docker + Compose preinstalled, server profile, SSH. Credentials template at `archinstall/user_credentials.example.json` (real credentials gitignored).
- **Installer wireframes** (`docs/installer-wireframes.md`) — Robert's hand-drawn 4-screen UX sketches.
- **Competitor analysis** (`docs/competitors.md`) — CasaOS, Umbrel, YunoHost reviewed across install flow, hardware detection, app store UX, reverse proxy/SSL, user complaints. Key finding: device-aware wizard + managed gateway are uncontested differentiators.
- **Wizard flow spec** (`docs/wizard-flow.md`) — 8-screen first-boot flow extending Robert's wireframe with YunoHost-style domain/SSL/diagnostic/confirm screens. Locked tech picks with rejected alternatives.
- **Project README** — vision, principles, architecture, key decisions, landscape, roadmap.
### Decisions locked
- **Reverse proxy:** Caddy (auto Let's Encrypt, simplest config)
- **Identity provider:** Authentik (bundled SSO, every app auto-wired at install)
- **Managed gateway DNS:** NS delegation to `ns1.furtka.org` / `ns2.furtka.org` (wildcard cert via Let's Encrypt DNS-01)
- **Local HTTPS:** Local CA installed by user once (no browser warnings on `*.proksi.local`)
- **Base OS:** Arch (rolling, Debian remains fallback)
- **Containers:** Docker + Compose
- **License:** AGPL-3.0
[Unreleased]: https://forgejo.sourcegate.online/daniel/furtka/compare/26.4-alpha...HEAD
[26.4-alpha]: https://forgejo.sourcegate.online/daniel/furtka/releases/tag/26.4-alpha
[26.3-alpha]: https://forgejo.sourcegate.online/daniel/furtka/releases/tag/26.3-alpha
[26.2-alpha]: https://forgejo.sourcegate.online/daniel/furtka/releases/tag/26.2-alpha
[26.1-alpha]: https://forgejo.sourcegate.online/daniel/furtka/releases/tag/26.1-alpha
[26.0-alpha]: https://forgejo.sourcegate.online/daniel/furtka/releases/tag/26.0-alpha