Merge pull request 'combined/iso-poudriere-livepower' (#75) from combined/iso-poudriere-livepower into main

Reviewed-on: #75
This commit is contained in:
clawdie 2026-06-20 17:24:36 +02:00
commit 352a1d6da9
6 changed files with 387 additions and 68 deletions

View file

@ -1,11 +1,21 @@
# Poudriere + bhyve Build Server Plan — v1.0.0
# Poudriere + bhyve Build Server Plan — v2.0.0
> Build colibri/clawdie as proper FreeBSD packages instead of raw `cargo build`
> binaries copied into the ISO. Plus bhyve virtualization for build test VMs.
> Target: HPE ML350p Gen8, 32GB RAM, Xeon E5-2400.
> Target: the **`mother-build`** host (FreeBSD VPS) serving **`pkg.clawdie.si`** —
> the package half of the trusted supply chain (layered-soul `HIVE-ONBOARDING.md §10`).
**Date:** 4 Jun 2026
**Target server:** HPE ProLiant ML350p Gen8 (iLO at 10.0.0.2)
**Date:** 4 Jun 2026 (v1.0.0) · retargeted 20 Jun 2026 (v2.0.0)
**Target server:** `mother-build` — a FreeBSD VPS with a ZFS pool (OVHcloud candidate;
see layered-soul `HOST-MATRIX.md`). The original ML350p Gen8 target is **retired**
(boot-looping); host provisioning is now provider-specific, not iLO/IPMI. Hardware-
specific sizing below (32 GB split, Xeon VT-x) is kept only as **reference numbers**
from the ML350p — scale them to the chosen `mother-build` plan.
**Scripts:** the reproducible Phase 23 steps are implemented in
[`../scripts/poudriere/`](../scripts/poudriere/) — `poudriere-setup.sh`,
`poudriere-build.sh`, `clawdie-repo.conf.in`. This doc is the rationale, host-
provisioning context, and the manual reference those scripts encode.
---
@ -23,10 +33,10 @@ colibri host (dev machine)
Proposed flow:
```
ml350p build server (Poudriere)
mother-build server (Poudriere)
→ FreeBSD port: sysutils/colibri
→ poudriere builds .pkg files in clean jail
pkg repo hosted at pkg.clawdie.home.arpa
signed pkg repo hosted at pkg.clawdie.si
→ ISO build does: pkg install colibri
```
@ -38,9 +48,11 @@ Benefits:
- No Rust toolchain needed on the ISO build host
- Proper `pkg info colibri` metadata
## Memory split
## Memory split (reference sizing — ML350p 32 GB)
32GB total — 16GB host, 16GB bhyve:
These numbers are the original ML350p reference; on a smaller cloud `mother-build`
plan, poudriere alone needs little (drop `USE_TMPFS` if RAM is tight) and the bhyve
guests are optional. 32GB total — 16GB host, 16GB bhyve:
```
Host (16GB):
@ -63,7 +75,7 @@ With 8-10 cores, 2 vCPUs per guest is comfortable.
```
┌──────────────────────────────────────────────────┐
HPE ML350p Gen8 (FreeBSD 15)
mother-build host (FreeBSD 15)
│ │
│ ZFS pool: zroot │
│ zroot/ROOT/default ← base system │
@ -82,17 +94,14 @@ With 8-10 cores, 2 vCPUs per guest is comfortable.
└──────────────────────────────────────────────────┘
```
## Phase 1 - server provision
## Phase 1 - server provision (provider-specific)
### 1.1 Boot FreeBSD from ISO
### 1.1 Get a booted FreeBSD host
```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
```
Host provisioning is **provider-specific** and out of scope for the scripts. On
OVHcloud, install FreeBSD via the rescue system or a FreeBSD template/image; the
old ML350p iLO/IPMI virtual-media path is retired. The poudriere scripts assume you
already have a **booted FreeBSD host with a ZFS pool** (default `zroot`).
### 1.2 Disk survey + ZFS
@ -117,6 +126,12 @@ zfs create -o mountpoint=/usr/local/poudriere zroot/poudriere/root
## Phase 2 - Poudriere setup
> **Scripted (DONE).** `poudriere-setup.sh` performs 2.12.3 idempotently
> (install, `poudriere.conf` incl. `PKG_REPO_SIGNING_KEY`, signing-key generation,
> jail, ports tree) after validating root / version / pool. `poudriere-build.sh`
> performs 2.5 (bulk + automatic repo signing). The steps below are the reference
> they encode; only 2.4 (creating the `sysutils/colibri` port) is still manual.
### 2.1 Install Poudriere
```sh
@ -142,8 +157,9 @@ 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
# poudriere-setup.sh does this with these names by default:
poudriere jail -c -j clawdie-amd64 -v 15.0-RELEASE -a amd64
poudriere ports -c -p clawdie -m git -B main
```
### 2.4 Create colibri port
@ -160,35 +176,27 @@ sysutils/colibri/
**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}
The port files are maintained in the **colibri** repo (source-of-truth, kept
with the code) at `packaging/freebsd/port/sysutils/colibri/``Makefile`,
`pkg-descr`, `pkg-plist`, plus a README covering generation. Don't hand-copy a
Makefile here; drop that directory into the ports tree. Key facts:
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>
```
- `LICENSE= AGPLv3` (per `colibri/Cargo.toml`**not** MIT).
- `USES= cargo`; source from the Forgejo archive (tagged `v${DISTVERSION}`).
- Ships 6 binaries: `clawdie`, `colibri`, `colibri-daemon`, `colibri-mcp`,
`colibri-test-agent`, `colibri-tui`.
- `CARGO_CRATES` and `distinfo` are generated on the build host
(`make cargo-crates`, `make makesum`).
### 2.5 Build
```sh
cd /usr/local/poudriere/ports/default/sysutils/colibri
cd /usr/local/poudriere/ports/clawdie/sysutils/colibri
make makesum # generate distinfo
make cargo-crates > Makefile.crates # generate crate list
poudriere bulk -j 150-amd64 -p default sysutils/colibri
# then build via the wrapper (validates + signs):
poudriere-build.sh --jail clawdie-amd64 --ports clawdie sysutils/colibri
```
## Phase 3 - pkg repository
@ -198,7 +206,9 @@ poudriere bulk -j 150-amd64 -p default sysutils/colibri
```sh
pkg install nginx
# /usr/local/etc/nginx/nginx.conf:
# server { listen 80; root /usr/local/poudriere/data/packages/150-amd64-default; autoindex on; }
# server { listen 443 ssl; server_name pkg.clawdie.si;
# root /usr/local/poudriere/data/packages/clawdie-amd64-clawdie; autoindex on; }
# TLS via acme.sh (osa/mother-build already carry nginx + acme).
service nginx enable
service nginx start
@ -206,16 +216,19 @@ service nginx start
### 3.2 Client config
On ISO builds and deployed machines:
On ISO builds and deployed jails, generate from
[`../scripts/poudriere/clawdie-repo.conf.in`](../scripts/poudriere/clawdie-repo.conf.in)
and ship the **public** key from Phase 2. The repo is **signed**, so clients verify:
```sh
# /usr/local/etc/pkg/repos/clawdie.conf
clawdie: {
url: "http://pkg.clawdie.home.arpa/",
enabled: yes,
}
sed "s#__PKG_URL__#https://pkg.clawdie.si/#; s#__PUBKEY_PATH__#/usr/share/keys/pkg/clawdie.pub#" \
clawdie-repo.conf.in > /usr/local/etc/pkg/repos/clawdie.conf
install -m 0444 /usr/local/etc/ssl/clawdie-pkg.pub /usr/share/keys/pkg/clawdie.pub
```
For first-party-only (paid) tenants, lower the stock FreeBSD repo priority so
resolution prefers signed Clawdie packages.
## Phase 4 - ISO integration
Instead of `stage-colibri-iso.sh` copying raw binaries:
@ -241,7 +254,7 @@ Once the deployed-system service implementation lands and the server builds
itself:
```sh
# The ml350p runs its own deployed-system clawdie service
# The mother-build host runs its own deployed-system clawdie service
service clawdie enable
service clawdie start
@ -254,6 +267,16 @@ The current live USB does not stage `service clawdie`; it runs
## Phase 6 — bhyve test VMs
> **Largely DONE (on the ISO-build host, not yet on `mother-build`).** The
> ISO-boot test VM exists and is wired as a **build gate**:
> [`../scripts/bhyve-test.sh`](../scripts/bhyve-test.sh) boots the built image in
> bhyve with `com1,stdio`, and [`../scripts/run-bhyve-test.sh`](../scripts/run-bhyve-test.sh)
> scans the serial console for required boot markers / forbidden failures (panics,
> restart loops, the colibri permission-denied regression) and exits non-zero on a
> critical miss. [`../scripts/bhyve-pf-allow.sh`](../scripts/bhyve-pf-allow.sh) opens
> the guest network. What remains: replicate this on `mother-build` and add the
> Linux cross-compile / poudriere-validation guests (6.4) if wanted.
### 6.1 Enable bhyve kernel module
```sh
@ -313,17 +336,18 @@ vm-bhyve
## 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 |
| 7. bhyve + test VMs | ~30m | base system + ZFS |
| Step | Effort | Status / depends on |
| -------------------------------------- | -------------- | --------------------------------------------------- |
| 1. Provision `mother-build` host | ~1h | PENDING — OVH FreeBSD VPS + ZFS pool (cost-gated) |
| 2. Poudriere setup | ~30m | **SCRIPTED**`poudriere-setup.sh`; needs the host |
| 3. colibri port creation | ~1h | PENDING — write `sysutils/colibri` (manual, §2.4) |
| 4. First pkg build | ~30m (compile) | **SCRIPTED**`poudriere-build.sh`; needs the port |
| 5. pkg repo + nginx (`pkg.clawdie.si`) | ~15m | PENDING — nginx + acme + DNS |
| 6. ISO integration | ~15m | PENDING — `pkg install` in `build.sh` (Phase 4) |
| 7. bhyve ISO-boot test gate | done | **DONE**`bhyve-test.sh` + `run-bhyve-test.sh` |
**Total: ~4h** once iLO password is available.
**Critical path:** provision `mother-build` → write the colibri port → run the two
scripts → stand up nginx/DNS. The host purchase is gated on the HOST-MATRIX cost rows.
## Notes
@ -332,9 +356,9 @@ vm-bhyve
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).
- `USE_TMPFS=yes` keeps builds in RAM (fast, no SSD wear) when the host has the
memory; drop it on a small cloud plan.
- Tailscale mesh means the operator USB can install packages from this
server even after deploying to a different machine.
- Xeon E5-2400 has VT-x + EPT — full hardware virt acceleration.
- bhyve guests can run concurrently with Poudriere builds (16GB reserved
for VMs, 16GB for host).
- bhyve needs a host with VT-x + EPT (the ML350p's Xeon E5-2400 had it; confirm
the chosen OVH plan exposes nested virt before relying on Phase 6 there).

View file

@ -1,14 +1,22 @@
#!/bin/sh
# PROVIDE: clawdie_live_power
# REQUIRE: FILESYSTEMS syslogd
# BEFORE: LOGIN
# KEYWORD: nojail
#
# Clawdie operator USB live power baseline.
# Applies the rc.conf power_profile C-state policy once at boot. FreeBSD's
# power_profile service is marked nostart and normally runs only when devd sees
# an AC-line transition, so a live USB can otherwise sit at the firmware/default
# C-state until AC is unplugged/replugged.
# PROVIDE: clawdie_live_power
# REQUIRE: FILESYSTEMS syslogd
# BEFORE: LOGIN
# KEYWORD: nojail
#
# Scope: this selects a CPU C-state/frequency profile ONLY. It never suspends,
# sleeps, blanks the screen, or enables DPMS (screen-blank is handled separately
# by the no-blank stack: xorg.conf.d/40-clawdie-noblank.conf + the power-manager
# skel + clawdie-noblank-guard.sh). Both branches are wake-safe: rc.conf pins
# performance_cx_lowest AND economy_cx_lowest to C3, so neither the AC (0x01) nor
# battery (0x00) profile can drop into a deeper C-state that breaks the
# USB-backed resume path. Keep both at C3 on the live USB — do not deepen.
. /etc/rc.subr

View file

@ -0,0 +1,58 @@
# First-party package build server (`pkg.clawdie.si`)
Lean scripts that turn the manual Phase 23 runbook in
[`../../docs/POUDRIERE-BUILD-SERVER.md`](../../docs/POUDRIERE-BUILD-SERVER.md) into
repeatable, idempotent steps. They run on the **`mother-build`** host (FreeBSD) and
produce the **first-party, signed** package repo that paid tenants pull from instead
of public mirrors — the package half of the trusted supply chain
([layered-soul `HIVE-ONBOARDING.md §10`](https://code.smilepowered.org/clawdie/layered-soul)).
These scripts deliberately do not provision the host (ZFS pool, base system,
networking) — that is hardware-specific and stays in the runbook. They assume a
FreeBSD host with a ZFS pool already present.
## Flow
```
poudriere-setup.sh → poudriere-build.sh → serve + client config
(config, key, jail, (build ports into the (nginx over the repo dir;
ports tree) signed repo) clawdie-repo.conf.in)
```
1. **Set up** (idempotent; re-run anytime):
```sh
mdo -u root ./poudriere-setup.sh --zpool zroot
```
Generates `/usr/local/etc/ssl/clawdie-pkg.{key,pub}`, writes
`/usr/local/etc/poudriere.conf` (only if absent), and creates the build jail and
ports tree. The **public** key is what clients trust.
2. **Build** (signs the repo automatically via `PKG_REPO_SIGNING_KEY`):
```sh
mdo -u root ./poudriere-build.sh --jail clawdie-amd64 --ports clawdie sysutils/colibri
```
The `sysutils/colibri` port itself (Makefile/distinfo/pkg-plist) is created in the
ports tree per the runbook's Phase 2.4.
3. **Serve + clients.** Point nginx at
`/usr/local/poudriere/data/packages/clawdie-amd64-clawdie` for `https://pkg.clawdie.si/`
(osa/mother-build already carry `nginx` + `acme`). Generate each client's repo config
from the template and ship the public key:
```sh
sed "s#__PKG_URL__#https://pkg.clawdie.si/#; s#__PUBKEY_PATH__#/usr/share/keys/pkg/clawdie.pub#" \
clawdie-repo.conf.in > /usr/local/etc/pkg/repos/clawdie.conf
install -m 0444 /usr/local/etc/ssl/clawdie-pkg.pub /usr/share/keys/pkg/clawdie.pub
```
## Conventions
- POSIX `sh`, `set -u`, fixed `PATH`, `usage()` + strict arg parsing, **verify-then-act**
(inputs and environment are validated before anything is created). Matches
`live/operator-session/hw-report`.
- Idempotent: existing config, key, jail, and ports tree are left untouched.
- Defaults are overridable by flag or `POUDRIERE_*` env var.

View file

@ -0,0 +1,18 @@
# First-party Clawdie package repo. Install on clients (ISO build root and
# deployed jails) as /usr/local/etc/pkg/repos/clawdie.conf, after substituting
# __PKG_URL__ and shipping the public key to __PUBKEY_PATH__.
#
# sed "s#__PKG_URL__#https://pkg.clawdie.si/#" clawdie-repo.conf.in > clawdie.conf
# install -m 0444 clawdie-pkg.pub __PUBKEY_PATH__ # from poudriere-setup.sh
#
# For first-party-only (paid) tenants, also set the stock FreeBSD repo to a
# lower priority (or disabled) so resolution prefers signed Clawdie packages.
clawdie: {
url: "__PKG_URL__",
mirror_type: "none",
signature_type: "pubkey",
pubkey: "__PUBKEY_PATH__",
priority: 100,
enabled: yes
}

View file

@ -0,0 +1,72 @@
#!/bin/sh
# Build one or more ports into the first-party repo with poudriere, then refresh
# repo metadata (signed via PKG_REPO_SIGNING_KEY in poudriere.conf). Validates
# the jail, ports tree, and each origin before building. Run as root.
set -u
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
export PATH
BASEFS="${POUDRIERE_BASEFS:-/usr/local/poudriere}"
JAIL="${POUDRIERE_JAIL:-clawdie-amd64}"
PTREE="${POUDRIERE_PTREE:-clawdie}"
usage() {
cat <<EOF
Usage: poudriere-build.sh [--jail NAME] [--ports NAME] ORIGIN [ORIGIN ...]
Builds each ORIGIN (category/name, e.g. sysutils/colibri) in the clean jail and
publishes signed packages to the first-party repo.
Options (or POUDRIERE_* env):
--jail NAME build jail (default: ${JAIL})
--ports NAME ports tree (default: ${PTREE})
-h, --help show this help
EOF
}
die() {
echo "ERROR: $*" >&2
exit 1
}
have() {
command -v "$1" >/dev/null 2>&1
}
while [ "$#" -gt 0 ]; do
case "$1" in
--jail) JAIL="${2:?--jail needs a value}"; shift 2 ;;
--ports) PTREE="${2:?--ports needs a value}"; shift 2 ;;
-h|--help) usage; exit 0 ;;
--) shift; break ;;
-*) echo "ERROR: unknown option: $1" >&2; usage >&2; exit 2 ;;
*) break ;;
esac
done
[ "$#" -ge 1 ] || { echo "ERROR: need at least one ORIGIN" >&2; usage >&2; exit 2; }
# --- verify, then act -------------------------------------------------------
[ "$(id -u)" -eq 0 ] || die "must run as root."
have poudriere || die "poudriere not found; run poudriere-setup.sh first."
poudriere jail -i -j "${JAIL}" >/dev/null 2>&1 || die "jail '${JAIL}' not found; run poudriere-setup.sh."
poudriere ports -l | awk 'NR>1 {print $1}' | grep -Fxq "${PTREE}" || die "ports tree '${PTREE}' not found."
_ports_root="${BASEFS}/ports/${PTREE}"
for _origin in "$@"; do
case "${_origin}" in
*/*) ;;
*) die "origin '${_origin}' must be category/name (e.g. sysutils/colibri)." ;;
esac
[ -f "${_ports_root}/${_origin}/Makefile" ] || \
die "port '${_origin}' not found under ${_ports_root}."
done
poudriere bulk -j "${JAIL}" -p "${PTREE}" "$@" || die "bulk build failed."
echo ""
echo "Build complete. Signed repo at:"
echo " ${BASEFS}/data/packages/${JAIL}-${PTREE}"
echo "Serve that directory over nginx at pkg.clawdie.si (see README.md)."

View file

@ -0,0 +1,139 @@
#!/bin/sh
# Set up a first-party FreeBSD package build server (poudriere) for
# pkg.clawdie.si. Idempotent: safe to re-run. Validates the environment and
# inputs first, then acts. Run on the mother-build host as root.
#
# After this: build with poudriere-build.sh, serve the repo over nginx, and
# hand clients clawdie-repo.conf.in. See README.md.
set -u
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
export PATH
ZPOOL="${POUDRIERE_ZPOOL:-zroot}"
ZROOTFS="${POUDRIERE_ZROOTFS:-/poudriere}"
BASEFS="${POUDRIERE_BASEFS:-/usr/local/poudriere}"
VERSION="${POUDRIERE_VERSION:-15.0-RELEASE}"
ARCH="${POUDRIERE_ARCH:-amd64}"
JAIL="${POUDRIERE_JAIL:-clawdie-${ARCH}}"
PTREE="${POUDRIERE_PTREE:-clawdie}"
PORTS_BRANCH="${POUDRIERE_PORTS_BRANCH:-main}"
KEYDIR="${POUDRIERE_KEYDIR:-/usr/local/etc/ssl}"
KEY="${KEYDIR}/clawdie-pkg.key"
PUB="${KEYDIR}/clawdie-pkg.pub"
CONF="/usr/local/etc/poudriere.conf"
usage() {
cat <<EOF
Usage: poudriere-setup.sh [options]
Idempotently prepares poudriere on this host: config, signing key, build jail,
and a ports tree. Re-running skips anything already present.
Options (or set the matching POUDRIERE_* env var):
--zpool NAME ZFS pool poudriere stores under (default: ${ZPOOL})
--version VER FreeBSD jail version (default: ${VERSION})
--arch ARCH jail architecture (default: ${ARCH})
--jail NAME build jail name (default: ${JAIL})
--ports NAME ports tree name (default: ${PTREE})
-h, --help show this help
EOF
}
die() {
echo "ERROR: $*" >&2
exit 1
}
have() {
command -v "$1" >/dev/null 2>&1
}
info() {
printf '==> %s\n' "$*"
}
while [ "$#" -gt 0 ]; do
case "$1" in
--zpool) ZPOOL="${2:?--zpool needs a value}"; shift 2 ;;
--version) VERSION="${2:?--version needs a value}"; shift 2 ;;
--arch) ARCH="${2:?--arch needs a value}"; shift 2 ;;
--jail) JAIL="${2:?--jail needs a value}"; shift 2 ;;
--ports) PTREE="${2:?--ports needs a value}"; shift 2 ;;
-h|--help) usage; exit 0 ;;
*) echo "ERROR: unknown option: $1" >&2; usage >&2; exit 2 ;;
esac
done
# --- verify, then act -------------------------------------------------------
[ "$(id -u)" -eq 0 ] || die "must run as root (poudriere setup creates jails)."
case "${VERSION}" in
[0-9]*.[0-9]*-RELEASE|[0-9]*.[0-9]*-STABLE|[0-9]*.[0-9]*-CURRENT) ;;
*) die "invalid --version '${VERSION}' (expected e.g. 15.0-RELEASE)." ;;
esac
have pkg || die "pkg not found; run on a FreeBSD host."
have openssl || die "openssl not found (needed to generate the repo signing key)."
zpool list "${ZPOOL}" >/dev/null 2>&1 || die "ZFS pool '${ZPOOL}' not found; create it or pass --zpool."
# --- act --------------------------------------------------------------------
if ! have poudriere; then
info "installing poudriere"
env ASSUME_ALWAYS_YES=yes pkg install -y poudriere || die "pkg install poudriere failed."
fi
if [ ! -f "${KEY}" ]; then
info "generating repo signing key: ${KEY}"
mkdir -p "${KEYDIR}"
( umask 077; openssl genrsa -out "${KEY}" 4096 ) || die "failed to generate signing key."
openssl rsa -in "${KEY}" -pubout -out "${PUB}" || die "failed to derive public key."
chmod 0400 "${KEY}"
fi
if [ ! -f "${CONF}" ]; then
info "writing ${CONF}"
cat > "${CONF}" <<EOF
# Clawdie first-party package build server. Managed by poudriere-setup.sh.
ZPOOL=${ZPOOL}
ZROOTFS=${ZROOTFS}
BASEFS=${BASEFS}
FREEBSD_HOST=download.freebsd.org
RESOLV_CONF=/etc/resolv.conf
DISTFILES_CACHE=${BASEFS}/distfiles
USE_TMPFS=yes
# poudriere signs the repo catalog with this key on every bulk run; clients
# trust the matching public key (${PUB}). See clawdie-repo.conf.in.
PKG_REPO_SIGNING_KEY=${KEY}
EOF
else
info "${CONF} exists; leaving it untouched"
fi
if poudriere jail -i -j "${JAIL}" >/dev/null 2>&1; then
info "jail '${JAIL}' exists; skipping"
else
info "creating jail '${JAIL}' (${VERSION} ${ARCH})"
poudriere jail -c -j "${JAIL}" -v "${VERSION}" -a "${ARCH}" || die "jail create failed."
fi
if poudriere ports -l | awk 'NR>1 {print $1}' | grep -Fxq "${PTREE}"; then
info "ports tree '${PTREE}' exists; skipping"
else
info "creating ports tree '${PTREE}' (git ${PORTS_BRANCH})"
poudriere ports -c -p "${PTREE}" -m git -B "${PORTS_BRANCH}" || die "ports tree create failed."
fi
cat <<EOF
Poudriere is ready.
jail: ${JAIL}
ports tree: ${PTREE}
signing key: ${KEY}
public key: ${PUB} <-- ship this to clients (see clawdie-repo.conf.in)
Next:
./poudriere-build.sh --jail ${JAIL} --ports ${PTREE} sysutils/colibri
EOF