summaryrefslogtreecommitdiff
path: root/internal/layout
AgeCommit message (Collapse)Author
2026-08-25Split per-app dataset into OS/data layers, add skiff rebuildMike Wild
Each app now gets two ZFS datasets - a disposable OS layer (zroot/skiff/appbase/<app>) cloned from base, and a persistent data layer (zroot/skiff/appdata/<app>) holding releases/current/env/ meta.json/data.db. `skiff rebuild --app|--all` discards and reclones the OS layer to pick up an OS/toolchain/config-template upgrade, guarded by the same snapshot-and-rollback safety net as deploy and config changes; the data layer is never touched. Also fixes stale docs (builds already run via jexec inside the jail, not on the host; --iface already auto-aliases the jail's IP, so the manual ifconfig step and its troubleshooting entry are gone) found while updating the same sections for this feature. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25new-app: configure jail mail relay and persist the jail's network aliasClaude
Two provisioning gaps in new-app: - The jail's dma.conf inherited the base image's shared SMARTHOST/ PORT/AUTHPATH, but never got a per-app MAILNAME - without one, dma can misroute mail for recipients on the jail's own apex domain as local delivery. EnableMail appends a MAILNAME of <app>.skiff.local, which can't collide with any real domain an app sends to or from. - A classic jail's ip4.addr is only a bind restriction, not a route, until something aliases it onto a host interface. jail.conf.tmpl never set jail(8)'s own `interface` parameter, so nothing ever created that alias - confirmed on skiff-freebsd, where the address had twice been made to work via an ad hoc `ifconfig alias` that didn't survive a reboot. Setting `interface` lets jail(8) manage the alias itself, including on every boot.
2026-08-07Add per-app flock locking around deploy, config change, rollback, new-appClaude
Nothing previously serialized these against each other, so concurrent invocations for the same app (a manual config change racing an in-flight deploy, a double git push, a rollback mid-deploy) could interleave snapshot/apply/restart/rollback sequences against the same dataset and jail. The lock file lives under a new LocksDir, outside any per-app ZFS dataset, since those datasets get rolled back on a failed health check or a manual rollback.
2026-08-06Add skiff config set/unset/list, backed by /app/env in the app's datasetClaude
Config vars are plain env vars, injected into both the running app (via rc.d) and the release phase, and versioned on the same ZFS snapshot timeline as deploys - a bad config change gets the same automatic snapshot/restart/health-check/rollback guarantee a bad deploy already gets. Extracts deploy.go's health check into internal/health so both paths share it. Verified end-to-end against a FreeBSD VM: config set/unset, automatic rollback on a health-check failure, and explicit `skiff rollback` all correctly carry the env file along with the rest of the dataset.
2026-08-05Simplify: centralize paths in layout, dedup zfs snapshot refs, remove dead codeClaude
- Add layout.Config methods (ReleasesDir, PostReceiveHookPath, RCScriptPath, RCConfPath) so main.go and jailmgr no longer hand-build paths that layout already owns. - Extract zfsutil.snapRef to replace three inline dataset@tag Sprintfs. - Remove seven unused exported functions (zfsutil.Exists, jailmgr.Stop, sh.RunWithStdinFile, and four dead layout.Config path methods) and their now-unused imports.
2026-08-05Initial commit of skiff scaffoldingClaude