| Age | Commit message (Collapse) | Author |
|
Verified on the VM: service pf start auto-loads the kernel module itself
(required_modules="pf" in /etc/rc.d/pf, which rc.subr honors for start
specifically) - service pf check and bare pfctl don't get the same
treatment, so kldload is only necessary if you want to dry-run the
ruleset before committing to it. The previous wording implied it was
needed either way.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
Replaces the sketch (bare ifconfig alias, isolated nat line) with what we
verified end-to-end on a real VM: the alias persisted via rc.conf, a full
pf.conf modeled on a plain host's firewall, and the pfctl/kldload steps
needed to load and check it safely.
Also documents a real bug hit along the way: `nat ... -> ($ext_if)` is
ambiguous once the interface carries more than one address (the public
IP and the private jail range both live on it) - pf can silently NAT
through the wrong one. The public IP needs to be written explicitly.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
The --ip same-subnet rule from earlier is necessary but not sufficient
once a host only has one public address: jails shouldn't get public IPs
at all (only nginx needs one), but a private range aliased onto the same
interface needs its own outbound NAT rule for jail builds to reach the
internet - nothing upstream translates it the way a NAT'd virtual network
(like the dev VM) does for free. Skipping it fails the same silent way as
the out-of-subnet case: packets leave the jail, nothing answers.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
"ready" read as a status word rather than a label for what's actually a
mutable pointer to "the current recommended base image," re-tagged as it
evolves - the exact operation we did twice this session. "default" names
that role directly: it's the value --base-snapshot falls back to, nothing
more claimed.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
FreeBSD's lang/go is a real meta-port (installs as package name "go")
that depends on whichever goNNN is current and installs the go/gofmt
symlinks itself, tracked and upgradeable - `pkg install go` replaces both
the go125 install and the manual `ln -sf` steps in one command. Verified
against a real base image and rebuild: same resulting symlinks, now
pkg-owned instead of orphaned files pkg doesn't know about.
Docs updated to check for an unversioned meta-port first, falling back to
a manual symlink only when a toolchain doesn't have one.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
Its only caller was the post-receive hook skiff itself generates, so
"hook parity" meant matching a convention we invented and fully control -
there's no external contract keeping it around. deploy.Run never read it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
Replaces the single server_name string in meta.json with a domain list
(one primary, others redirect to it) and TLSDomains tracking what the
app's certificate actually covers. Certs are issued/expanded via certbot
certonly (webroot, never the --nginx plugin, since Skiff owns and
regenerates skiff.d/*.conf itself) as one SAN cert per app, matching how
a real multi-domain vhost is normally issued.
Domain/TLS changes never touch the jail - no restart, no health check -
since they only affect nginx and the certificate. `add` is safe to retry
if DNS isn't ready yet; `remove` never calls certbot at all, so it can't
fail on an ACME/network problem.
Also updates README/USER_GUIDE for the new command surface, one-time TLS
host setup (certbot register, renewal cron, reload hook), the --ip
same-subnet requirement for jails to reach the network at build time, and
the actual base-image provisioning sequence (pkg needs an explicit
bootstrap after bsdinstall; versioned port names like go125 need a
default symlink) - all found and fixed live while getting this working
end-to-end on a real FreeBSD VM.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
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>
|
|
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.
|
|
Builds previously ran as a bare host process, sharing one host-wide
toolchain across every app - a Go/gcc upgrade on the host silently
changed what the next deploy of any app picked up, and cgo builds
needed the exact right headers/compiler on the host regardless of
what each app actually targets. Routing the build through jexec, the
same mechanism release.Run already uses for the release phase, gives
each app's own persistent jail an independently-managed toolchain
instead.
|
|
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.
|
|
- Extract deploy.Run's snapshot -> apply -> restart -> health-check ->
rollback-on-failure sequence into deploy.GuardedApply, shared with
cmd/skiff's applyConfigChange, which duplicated it verbatim.
- Clean up the worktree and snapshot a deploy creates when it fails
before cutover (e.g. a failing release-phase migration), so retrying
the same sha no longer needs manual cleanup.
- Make checkout and snapshotting idempotent for a same-sha retry after
a cutover that later got rolled back on a failed health check, where
the release dir and snapshot are deliberately left behind by design.
- Document the actual cause of a jail not surviving a host reboot:
FreeBSD ships no /etc/jail.conf, so boot-time `service jail start`
finds nothing to start regardless of jail.conf.d - only name-targeted
starts read jail.conf.d directly, which is why manual starts worked.
|
|
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.
|
|
- 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.
|
|
|