6 KiB
6 KiB
Poudriere Build Server Plan — v1.0.0
Build colibri/clawdie as proper FreeBSD packages instead of raw
cargo buildbinaries copied into the ISO. Target: HPE ML350p Gen8, 32GB RAM.
Date: 4 Jun 2026
Target server: HPE ProLiant ML350p Gen8 (iLO at 10.0.0.2)
Why
Current build flow:
colibri host (dev machine)
cargo build --release
→ stage-colibri-iso.sh copies binaries to ISO
→ no version tracking, no pkg metadata, manual
Proposed flow:
ml350p build server (Poudriere)
→ FreeBSD port: sysutils/colibri
→ poudriere builds .pkg files in clean jail
→ pkg repo hosted at pkg.clawdie.home.arpa
→ ISO build does: pkg install colibri
Benefits:
- Versioned packages with dependencies
- Clean-room builds (no host contamination)
pkg upgrade colibrion deployed machines- No Rust toolchain needed on the ISO build host
- Proper
pkg info colibrimetadata
Architecture
┌─────────────────────────────────────────┐
│ HPE ML350p Gen8 (FreeBSD 15) │
│ │
│ ZFS pool: zroot │
│ zroot/ROOT/default ← base system │
│ zroot/poudriere ← build jails │
│ zroot/poudriere/data ← packages │
│ zroot/poudriere/ports ← ports tree │
│ │
│ Services: │
│ poudriere (bulk builder) │
│ nginx (pkg repo) │
│ clawdie agent (self-hosting) │
│ tailscale (mesh) │
└─────────────────────────────────────────┘
Phase 1 — server provision
1.1 Boot FreeBSD from ISO
# iLO virtual media mount + boot
ipmitool -H 10.0.0.2 -U Administrator -P <pw> power status
ipmitool -H 10.0.0.2 -U Administrator -P <pw> chassis bootdev cdrom
# Mount clawdie-iso via iLO virtual media
ipmitool -H 10.0.0.2 -U Administrator -P <pw> power reset
1.2 Disk survey + ZFS
camcontrol devlist
geom disk list
# Single disk or mirror
zpool create -o ashift=12 zroot /dev/ada0
zfs create -o mountpoint=/ zroot/ROOT/default
zfs create zroot/poudriere
zfs create -o mountpoint=/usr/local/poudriere zroot/poudriere/root
1.3 Install base system
# Install FreeBSD 15 base + kernel to zroot
# Set up /boot, /etc, clawdie service
# Configure network (DHCP, tailscale)
Phase 2 — Poudriere setup
2.1 Install Poudriere
pkg install poudriere
2.2 Configure
# /usr/local/etc/poudriere.conf
ZPOOL=zroot
ZROOTFS=/poudriere
FREEBSD_HOST=download.freebsd.org
RESOLV_CONF=/etc/resolv.conf
BASEFS=/usr/local/poudriere
USE_TMPFS=yes # build in RAM (we have 32GB)
MAX_MEMORY=4 # limit per-jail RAM
MAX_FILES=2048
DISTFILES_CACHE=/usr/local/poudriere/distfiles
PARALLEL_JOBS=8
2.3 Create jail + ports tree
poudriere jail -c -j 150-amd64 -v 15.0-RELEASE -a amd64
poudriere ports -c -p default -m git -B main
2.4 Create colibri port
Create sysutils/colibri/ in the ports tree:
sysutils/colibri/
├── Makefile
├── distinfo
├── pkg-descr
└── pkg-plist
Makefile (Rust port pattern):
PORTNAME= colibri
PORTVERSION= 0.0.1
CATEGORIES= sysutils
MASTER_SITES= https://code.smilepowered.org/clawdie/colibri/archive/
DISTNAME= ${PORTNAME}-${PORTVERSION}
MAINTAINER= hello@clawdie.si
COMMENT= Colibri control plane — agent supervision, skills, tasks
WWW= https://code.smilepowered.org/clawdie/colibri
LICENSE= MIT
USES= cargo
USE_GITHUB= no
CARGO_CRATES= ... # generated by make cargo-crates
.include <bsd.port.mk>
2.5 Build
cd /usr/local/poudriere/ports/default/sysutils/colibri
make makesum # generate distinfo
make cargo-crates > Makefile.crates # generate crate list
poudriere bulk -j 150-amd64 -p default sysutils/colibri
Phase 3 — pkg repository
3.1 Nginx pkg repo
pkg install nginx
# /usr/local/etc/nginx/nginx.conf:
# server { listen 80; root /usr/local/poudriere/data/packages/150-amd64-default; autoindex on; }
service nginx enable
service nginx start
3.2 Client config
On ISO builds and deployed machines:
# /usr/local/etc/pkg/repos/clawdie.conf
clawdie: {
url: "http://pkg.clawdie.home.arpa/",
enabled: yes,
}
Phase 4 — ISO integration
Instead of stage-colibri-iso.sh copying raw binaries:
# build.sh — install colibri packages during ISO build
pkg -r ${MOUNT_POINT} install colibri
This gives us:
colibricolibri-daemoncolibri-tuicolibri-smoke-agent
All with proper pkg metadata, upgradeable, with dependencies tracked.
Phase 5 — self-hosted clawdie
Once the server builds itself:
# The ml350p runs its own clawdie agent
service clawdie enable
service clawdie start
# clawdie monitors build jails, runs periodic rebuilds
# clawdie skills include "rebuild-colibri" and "poudriere-status"
Timeline
| Step | Effort | Depends on |
|---|---|---|
| 1. Server provision (ZFS, base system) | ~1h | iLO password, ISO boots |
| 2. Poudriere setup | ~30m | base system running |
| 3. colibri port creation | ~1h | Poudriere running |
| 4. First pkg build | ~30m (compile) | port ready |
| 5. pkg repo + nginx | ~15m | packages built |
| 6. ISO integration | ~15m | repo hosted |
Total: ~3.5h once iLO password is available.
Notes
- Rust target
x86_64-unknown-freebsdstays — that's the compiler triple. The package name iscolibri(orclawdie-colibri), no "unknown" in package branding. - Poudriere builds each package in a clean jail — no host Rust toolchain
pollution. The jail installs
lang/rustfrom ports automatically. - 32GB RAM + tmpfs means builds stay in memory (fast, no SSD wear).
- Tailscale mesh means the operator USB can install packages from this server even after deploying to a different machine.