JSON-parsefout in de browser bij het toevoegen van een netwerk.
De live beoordeling die bij elke toetsaanslag afgaat, bouwde een lijst van alle
bruikbare adressen in het bereik. Tijdens het intypen van 192.168.1.0/24 is de
tussenstand 192.168.1.0/2 een geldig netwerk met 1.073.741.824 adressen; het
verzoek liep daarop vast en de browser kreeg geen JSON terug.
- review() rekent eerste adres, laatste adres en aantal nu uit via
num_addresses in plaats van hosts() te doorlopen. Alle prefixes van /1 tot
/32 antwoorden binnen 0,05 seconde.
- suggest_range() had hetzelfde probleem: die somde alle /28-blokken op, bij
een /8 ruim een miljoen. Rekent nu van achteren naar voren, hoogstens
zestien stappen.
- Waarschuwing bij meer dan 4096 adressen in het bereik; dat is vrijwel altijd
een typefout in het prefix.
- Tests met /1 t/m /32, inclusief een vergelijking van _bruikbaar_bereik() met
de uitkomst van hosts() uit de stdlib, en tijdslimieten zodat een
herintroductie meteen opvalt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
- Automatische detectie van het hostnetwerk: interface, subnet, gateway en een
voorgestelde vrije IP-range worden bovenaan het formulier getoond en vullen
met een klik alles in.
- Detectie gebeurt via een kortstondige container in de netwerknamespace van de
host, die de routetabel uitleest. Dat repareert meteen een fout: de vorige
host_interfaces() las /sys/class/net binnen de container en toonde dus de
bridge-interface van de container in plaats van de netwerkkaart van de host.
- Live beoordeling terwijl je typt (nieuwe endpoint /api/networks/review): laat
zien hoeveel adressen je overhoudt en welke, en legt in gewone taal uit wat er
niet klopt. Onderscheid tussen blokkerende fouten en waarschuwingen.
- Knop die een vrij blok voorstelt op basis van het subnet, met de gateway
ontweken.
- Uitklapbare uitleg in het formulier over hoe subnet, gateway, IP-range en
host-interface samenhangen, met voorbeeld.
- docs/netwerken.md uitgebreid met een schema van de adresverdeling, een tabel
met veelgebruikte ranges, en de nadruk op het punt dat het instellen van de
range in Server Up niets aan de router doet: daar moet het DHCP-bereik zelf
verkleind worden.
- Bijgesteld tijdens het testen: een gateway binnen het subnet is de normale
situatie en gold ten onrechte als fout wanneer er geen eigen range was
opgegeven. Nu alleen een waarschuwing bij een expliciete range.
- 248 tests (21 nieuwe).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
Rollen per gebruiker:
- Drie rollen: beheerder (alles), operator (stacks, containers en backups) en
alleen lezen. Afgedwongen in de before_request-guard, niet alleen in de UI.
- Eigen wachtwoord wijzigen mag iedereen; de laatste beheerder kan niet
gedegradeerd of verwijderd worden.
- Proxy-gebruikers zonder eigen account krijgen AUTH.proxy_role; bestaat er wel
een lokaal account met die naam, dan wint dat account.
- Accounts van voor deze versie hebben geen rol en gelden als beheerder.
Rechtenescalatie verholpen:
- set_password verving het hele gebruikersrecord, waardoor het role-veld
wegviel. Een ontbrekende rol geldt als beheerder (nodig voor bestaande
accounts), dus elke operator of viewer kon zichzelf tot beheerder promoveren
door zijn eigen wachtwoord te wijzigen. Gevonden bij het naspelen van de
rollenflow tegen een draaiende instantie.
Geplande backups draaiden nooit:
- De scheduler stempelde ook taken af die zichzelf hadden overgeslagen. De
backup-taak bewaakt zelf het ingestelde uur, dus die werd afgestempeld op het
moment van de eerste tick; 24 uur later viel het volgende moment op precies
dat verkeerde tijdstip. Een taak stempelt nu alleen af bij True. De
backup-taak draait op een kort interval en beslist zelf, zodat een gewijzigde
planning meteen werkt. BACKUP_SCHEDULE_DAY toegevoegd voor wekelijks.
Verder:
- Zoekveld en tagfilters in de app store; repo's zonder treffers vallen weg.
- Opstartcontrole op de meegeleverde front-end-bestanden: mislukt het downloaden
tijdens de image-build, dan laadde de UI zonder opmaak terwijl de server prima
leek te draaien. Nu een duidelijke melding in het log.
- 227 tests (15 nieuwe voor rollen, 15 voor de scheduler).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
Backups (core/backups.py, core/scheduler.py):
- Terugzetten met een klik: stack stoppen, huidige map opzij, uitpakken,
starten. Mislukt het uitpakken, dan wordt de oude situatie teruggeplaatst.
- Bewaarbeleid: aantal per stack en/of maximale leeftijd; de nieuwste backup
van een stack blijft altijd staan.
- Geplande backups (dagelijks/wekelijks) via een eigen planner in de app, geen
cron. Een gemiste ronde loopt bij de eerstvolgende gelegenheid alsnog.
- Automatisch een backup voor het bijwerken of verwijderen van een stack.
Mislukt die, dan gaat de actie door - anders kun je een kapotte stack niet
meer opruimen.
- Uitpakken met tarfile + filter="data": absolute paden en ..-ingangen worden
geweigerd. Met een kaal `tar xzf` kon een geprepareerd archief buiten de
stackmap schrijven.
- Twee bugs in de oude implementatie: de returncode van tar werd genegeerd
(mislukte backup gold als succes) en backups binnen dezelfde seconde
overschreven elkaar.
Updates per app (core/stackupdates.py, core/registry.py):
- Badge op de stackkaart als er een nieuwer image is; bijwerken doet de
bestaande update-knop.
- Vergelijking via de Registry API v2 (Docker-Content-Digest) in plaats van
`docker manifest inspect`: dat laatste geeft per platform een aparte digest
terwijl RepoDigests de manifest-list-digest bevat, wat bij elk multi-arch
image permanent "update beschikbaar" zou opleveren.
- Drie statussen: update / current / unknown. Lokaal gebouwd, nog niet gepulld
of registry onbereikbaar geeft unknown en dus geen badge.
- Dagelijkse achtergrondcheck, resultaten 6 uur gecached.
Verder:
- docs/backups.md, met nadruk op wat er niet in een backup zit: de
Docker-volumes met de eigenlijke appdata.
- Backup-instellingen onder Instellingen; backup-geschiedenis per stack.
- 197 tests groen (40 nieuwe).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
- Update-kanalen stable/beta in plaats van het vinkje "pre-releases meenemen".
Stable ziet alleen releases, beta ook pre-releases; een release telt hoger
dan zijn eigen beta (0.5.10-beta1 < 0.5.10). UPDATE_INCLUDE_PRERELEASE
migreert automatisch naar het beta-kanaal.
- Nieuw core/selfupdate.py: image uit de registry ophalen, SU_TAG wegschrijven
en de eigen container laten hercreeren door een korte helper-container die op
het nieuwe image draait (bevat de docker- en compose-CLI al). Een container
kan zichzelf niet hercreeren, vandaar de helper.
- Deploy-map wordt uitgelezen uit de compose-labels van de eigen container.
Ontbreken die, draait de container niet vanaf een registry-image of is de
docker-socket er niet, dan meldt de UI waarom bijwerken niet kan.
- Vorige tag wordt onthouden; terugrolknop in de instellingen.
- Update-check een uur gecached, met geforceerde check via de knop; eerder deed
elke paginalading een netwerkverzoek. Laatst-gecontroleerd zichtbaar.
- Registry-inloggegevens instelbaar; het token komt net als de git-tokens nooit
terug via de API en leeg laten betekent ongewijzigd.
- docker-compose.yml gebruikt ${SU_IMAGE:-server-up}:${SU_TAG:-latest}; zonder
SU_IMAGE blijft lokaal bouwen werken zoals voorheen.
- deploy-prod.yml bouwt en pusht het image in dezelfde job wanneer SU_IMAGE
ingesteld is; build.yml is nu alleen handmatig. Bewust geen aparte
build-workflow op dezelfde tag: bij een runner met een job tegelijk zou de
deploy wachten op een build die zelf nog in de wachtrij staat.
- docs/updates.md: werking, complete Forgejo-instelling (registry, tokens,
variables, secrets, runners), release-procedure voor stable en beta,
terugrollen en probleemoplossing.
- Tests uitgebreid naar 148 (kanaallogica, cache, image-afleiding incl.
registry-poortnummers, tag-validatie, .env-schrijven, tokenlek).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
- Beheer per container: de stackkaart klapt uit naar de losse containers, met
start/stop/herstart, logs en live CPU-/geheugengebruik per container. De
containernaam wordt getoetst aan compose_ps van díé stack, zodat de route
geen willekeurige container op de host kan raken.
- Stacks met een eigen IP-adres (macvlan/ipvlan): netwerkbeheer onder
Instellingen → Netwerken, netwerkkeuze in de installatiemodal met voorstel
voor het eerstvolgende vrije adres, en automatische omzetting van het
gerenderde compose-bestand (poortmappings eruit, ipv4_address erin). De
templates in apps/ blijven ongewijzigd.
- Toegekende IP's worden vastgehouden in .serverup.json en getoond op de
stackkaart, zodat een volgende installatie ze niet opnieuw uitdeelt.
- Vrije poort voorstellen bij installeren: next_free_port() bestond al maar
werd nergens gebruikt. Bezette poorten worden in de UI gemeld.
- Genereerknop voor velden die op een geheim wijzen (token/password/secret),
lokaal gegenereerd via crypto.getRandomValues.
- Compose valideren met `docker compose config` vóór het wegschrijven, zowel
bij de editor als na het renderen bij installatie. Ontbreekt de compose-CLI,
dan blokkeert dat een installatie niet.
- Uitloggen in de zijbalk; gebruikersbeheer en wachtwoord wijzigen onder
Instellingen → Beveiliging.
- docs/netwerken.md (incl. de shim-interface die de host nodig heeft om zijn
eigen macvlan-containers te bereiken) en docs/beveiliging.md toegevoegd.
- CHANGELOG bijgewerkt; testsuite uitgebreid naar 112 tests.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb