release-26.4-alpha #7

Merged
daniel merged 2 commits from release-26.4-alpha into main 2026-04-18 14:29:20 +02:00
7 changed files with 22 additions and 8 deletions

View file

@ -7,14 +7,20 @@ This project uses calendar versioning: `YY.N-stage` (e.g. `26.0-alpha` = 2026, r
## [Unreleased] ## [Unreleased]
## [26.4-alpha] - 2026-04-18
### Added ### 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. - **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 ### 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. - **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). - **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 ## [26.3-alpha] - 2026-04-16
@ -80,7 +86,8 @@ First tagged snapshot. Pre-alpha — the installer does not yet boot, but the de
- **Containers:** Docker + Compose - **Containers:** Docker + Compose
- **License:** AGPL-3.0 - **License:** AGPL-3.0
[Unreleased]: https://forgejo.sourcegate.online/daniel/furtka/compare/26.3-alpha...HEAD [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.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.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.1-alpha]: https://forgejo.sourcegate.online/daniel/furtka/releases/tag/26.1-alpha

View file

@ -1,6 +1,6 @@
[project] [project]
name = "furtka" name = "furtka"
version = "26.0-alpha" version = "26.4-alpha"
description = "Open-source home server OS — simple enough for everyone." description = "Open-source home server OS — simple enough for everyone."
requires-python = ">=3.11" requires-python = ">=3.11"
readme = "README.md" readme = "README.md"

View file

@ -18,6 +18,11 @@
# PVE_TEST_VMID_MAX default 9099 # PVE_TEST_VMID_MAX default 9099
# PVE_TEST_KEEP how many past smoke VMs to retain (default 5) # PVE_TEST_KEEP how many past smoke VMs to retain (default 5)
# PVE_TEST_BOOT_TIMEOUT seconds to wait for :5000 (default 180) # PVE_TEST_BOOT_TIMEOUT seconds to wait for :5000 (default 180)
# PVE_TEST_VM_MEMORY MiB of RAM for the smoke VM (default 8192). Bumped
# from 4096 on 2026-04-18 — mkinitcpio on 4 GB VMs
# OOM-ed the pollux host mid-install, pulling pveproxy
# + the runner connection down with it.
# PVE_TEST_VM_CORES vCPU count for the smoke VM (default 2)
# SMOKE_SHA commit SHA used in name/tag/MAC; defaults to git HEAD # SMOKE_SHA commit SHA used in name/tag/MAC; defaults to git HEAD
# #
# Exits 0 iff the ISO booted and :5000 returned 200. Prunes old VMs + ISOs # Exits 0 iff the ISO booted and :5000 returned 200. Prunes old VMs + ISOs
@ -37,6 +42,8 @@ VMID_MIN="${PVE_TEST_VMID_MIN:-9000}"
VMID_MAX="${PVE_TEST_VMID_MAX:-9099}" VMID_MAX="${PVE_TEST_VMID_MAX:-9099}"
KEEP="${PVE_TEST_KEEP:-5}" KEEP="${PVE_TEST_KEEP:-5}"
BOOT_TIMEOUT="${PVE_TEST_BOOT_TIMEOUT:-180}" BOOT_TIMEOUT="${PVE_TEST_BOOT_TIMEOUT:-180}"
VM_MEMORY="${PVE_TEST_VM_MEMORY:-8192}"
VM_CORES="${PVE_TEST_VM_CORES:-2}"
SHA="${SMOKE_SHA:-$(git rev-parse HEAD 2>/dev/null || echo unknownunknown)}" SHA="${SMOKE_SHA:-$(git rev-parse HEAD 2>/dev/null || echo unknownunknown)}"
SHORT_SHA="${SHA:0:12}" SHORT_SHA="${SHA:0:12}"
@ -110,8 +117,8 @@ api --request POST "$API/nodes/$NODE/qemu" \
--data-urlencode "vmid=$VMID" \ --data-urlencode "vmid=$VMID" \
--data-urlencode "name=furtka-smoke-${SHORT_SHA}" \ --data-urlencode "name=furtka-smoke-${SHORT_SHA}" \
--data-urlencode "tags=furtka;smoke;sha-${SHORT_SHA}" \ --data-urlencode "tags=furtka;smoke;sha-${SHORT_SHA}" \
--data-urlencode "cores=2" \ --data-urlencode "cores=${VM_CORES}" \
--data-urlencode "memory=4096" \ --data-urlencode "memory=${VM_MEMORY}" \
--data-urlencode "bios=ovmf" \ --data-urlencode "bios=ovmf" \
--data-urlencode "machine=q35" \ --data-urlencode "machine=q35" \
--data-urlencode "ostype=l26" \ --data-urlencode "ostype=l26" \

View file

@ -30,7 +30,7 @@
<footer class="site-footer"> <footer class="site-footer">
<div class="container"> <div class="container">
<p class="kicker">Furtka 26.0-alpha · AGPL-3.0</p> <p class="kicker">Furtka 26.4-alpha · AGPL-3.0</p>
<p class="kicker"><a href="https://furtka.org" style="color: inherit; text-decoration: none">furtka.org</a></p> <p class="kicker"><a href="https://furtka.org" style="color: inherit; text-decoration: none">furtka.org</a></p>
</div> </div>
</footer> </footer>

View file

@ -1,7 +1,7 @@
--- ---
title: "Furtka" title: "Furtka"
description: "Offenes Heimserver-Betriebssystem — einfach genug für alle." description: "Offenes Heimserver-Betriebssystem — einfach genug für alle."
status: "<span class=\"mono\">26.0-alpha</span> — in Arbeit" status: "<span class=\"mono\">26.4-alpha</span> — in Arbeit"
--- ---
**Furtka** ist ein offenes Heimserver-Betriebssystem. **Furtka** ist ein offenes Heimserver-Betriebssystem.

View file

@ -1,7 +1,7 @@
--- ---
title: "Furtka" title: "Furtka"
description: "Open-source home server OS — simple enough for everyone." description: "Open-source home server OS — simple enough for everyone."
status: "<span class=\"mono\">26.0-alpha</span> — work in progress" status: "<span class=\"mono\">26.4-alpha</span> — work in progress"
--- ---
**Furtka** is an open-source home server OS. **Furtka** is an open-source home server OS.

View file

@ -6,7 +6,7 @@ enableRobotsTXT = true
[params] [params]
description = "Open-source home server OS — simple enough for everyone." description = "Open-source home server OS — simple enough for everyone."
version = "26.0-alpha" version = "26.4-alpha"
contactEmail = "hallo@furtka.org" contactEmail = "hallo@furtka.org"
[markup.goldmark.renderer] [markup.goldmark.renderer]