Add Poudriere build server plan #23
1 changed files with 243 additions and 0 deletions
243
docs/POUDRIERE-BUILD-SERVER.md
Normal file
243
docs/POUDRIERE-BUILD-SERVER.md
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
# Poudriere Build Server Plan — v1.0.0
|
||||
|
||||
> Build colibri/clawdie as proper FreeBSD packages instead of raw `cargo build`
|
||||
> binaries 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 colibri` on deployed machines
|
||||
- No Rust toolchain needed on the ISO build host
|
||||
- Proper `pkg info colibri` metadata
|
||||
|
||||
## 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
|
||||
|
||||
```sh
|
||||
# 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
|
||||
|
||||
```sh
|
||||
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
|
||||
|
||||
```sh
|
||||
# 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
|
||||
|
||||
```sh
|
||||
pkg install poudriere
|
||||
```
|
||||
|
||||
### 2.2 Configure
|
||||
|
||||
```sh
|
||||
# /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
|
||||
|
||||
```sh
|
||||
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):
|
||||
```makefile
|
||||
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
|
||||
|
||||
```sh
|
||||
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
|
||||
|
||||
```sh
|
||||
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:
|
||||
```sh
|
||||
# /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:
|
||||
|
||||
```sh
|
||||
# build.sh — install colibri packages during ISO build
|
||||
pkg -r ${MOUNT_POINT} install colibri
|
||||
```
|
||||
|
||||
This gives us:
|
||||
- `colibri`
|
||||
- `colibri-daemon`
|
||||
- `colibri-tui`
|
||||
- `colibri-smoke-agent`
|
||||
|
||||
All with proper pkg metadata, upgradeable, with dependencies tracked.
|
||||
|
||||
## Phase 5 — self-hosted clawdie
|
||||
|
||||
Once the server builds itself:
|
||||
|
||||
```sh
|
||||
# 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-freebsd` stays — that's the compiler triple.
|
||||
The package name is `colibri` (or `clawdie-colibri`), no "unknown" in
|
||||
package branding.
|
||||
- Poudriere builds each package in a clean jail — no host Rust toolchain
|
||||
pollution. The jail installs `lang/rust` from 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.
|
||||
Loading…
Add table
Reference in a new issue