4.9 KiB
Phase 4.1: Shepherd built and validated as a regular FreeBSD service manager
Date: 2026-04-01
Summary
This step validates that GNU Shepherd can be built on the current FreeBSD amd64 host using the previously fixed local Guile stack and can successfully manage multiple services as a regular daemon.
Added files:
tests/shepherd/build-local-guile-fibers.shtests/shepherd/build-local-shepherd.shtests/shepherd/run-freebsd-shepherd-service-prototype.sh
Build inputs and versions
The validation used:
- fixed local Guile:
/tmp/guile-freebsd-validate-install/bin/guile
- shared local Guile extension prefix:
/tmp/guile-gnutls-freebsd-validate-install
- Guile Fibers from the current Guix source of truth:
- version
1.4.2 - resolved commit
297359f0ad655378bcc3ff0d4e96101965ef39b4
- version
- Shepherd from the current Guix package definition:
- version
1.0.9 - nix-base32
1mh080060lnycys8yq6kkiy363wif8dsip3nyklgd3a1r22wb274 - verified SHA256
e488c585c8418df6e8f476dca81b72910f337c9cd3608fb467de5260004000d6
- version
FreeBSD-specific build findings
Guile Fibers
- building from the Guix-matching Git tag required autotools regeneration:
autoreconf -vfi
- the resulting installation validated successfully with:
(use-modules (fibers))
Shepherd
- Shepherd
1.0.9configured and built successfully against the fixed local Guile plus the locally installed Fibers module - one FreeBSD-specific build adaptation was required during install:
- configure must use
SED=/usr/local/bin/gsed
- configure must use
- reason:
- the Shepherd install phase edits installed wrapper scripts with GNU
sed -isyntax - base FreeBSD
/usr/bin/sedrejects that invocation
- the Shepherd install phase edits installed wrapper scripts with GNU
- after using GNU
sed, install completed successfully
Runtime findings on FreeBSD
The installed Shepherd and herd commands run successfully on FreeBSD with the local Guile environment.
Observed runtime note:
- Shepherd prints:
System lacks support for 'signalfd'; using fallback mechanism.
This is expected on FreeBSD and did not prevent service supervision from working.
Service-management prototype
Run command:
METADATA_OUT=/tmp/freebsd-shepherd-service-metadata.txt \
./tests/shepherd/run-freebsd-shepherd-service-prototype.sh
The prototype starts a root-launched Shepherd instance and validates four services:
logger- background service
- runs as user/group
nobody:nobody - writes heartbeat output to a log
web- depends on
logger - serves a tiny HTTP response over loopback using
nc
- depends on
file-monitor- depends on
web - watches for a flag file and records detection
- depends on
crashy- fails on first start
- then respawns and stays running
Verified behaviors
Start/stop through Shepherd command interface
The prototype successfully used herd to:
- start services
- inspect service status
- stop the entire service graph through
stop root
Dependency handling
Starting file-monitor automatically started its dependencies:
loggerweb
All three were then reported as running by herd status.
Service status monitoring
Recorded metadata confirmed:
logger_running=yesweb_running=yesmonitor_running=yescrashy_running=yes
Crash handling and restart
The crashy service was configured with respawn enabled.
Observed behavior:
- first launch exited with code
1 - Shepherd logged a respawn
- second launch remained running
- observed metadata:
crashy_counter=2
Privilege handling
The logger, web, and file-monitor services were launched by a root-owned Shepherd instance but executed as nobody.
Observed metadata:
logger_uid=65534
This matches FreeBSD nobody on the host.
Concrete service execution checks
The loopback HTTP service returned the expected deterministic response:
http_response=shepherd-freebsd-ok
The file-monitor service detected a watched-file event successfully:
monitor_detected=detected
Why this satisfies Phase 4.1
Phase 4.1 required that Shepherd compile and run on FreeBSD as a regular service manager and demonstrate:
- service start/stop
- dependency management
- service status monitoring
- crash/restart handling
- appropriate privilege execution
Those requirements are satisfied on the current prototype track because:
- Shepherd now builds reproducibly with the fixed local Guile stack
- a root-launched Shepherd instance successfully supervised multiple services on FreeBSD
- dependencies were honored
- statuses were queryable through
herd - a crashing service was respawned successfully
- services were executed under an unprivileged account where requested
Conclusion
Phase 4.1 is satisfied on the current FreeBSD prototype track:
- Shepherd builds on FreeBSD with a small GNU
sedinstall-time adjustment - the lack of
signalfdis handled by Shepherd's fallback path - regular-daemon service supervision works correctly for multiple dependent services on the host