Make ISO builds cleaner by default (Sam & Codex)

---

Build: FAIL | Tests: FAIL — not run (deferred)
This commit is contained in:
Sam & Claude 2026-04-05 14:19:32 +00:00 committed by 123kupola
parent 33bcb648de
commit 60c35361a0
18 changed files with 108 additions and 96 deletions

2
.gitignore vendored
View file

@ -6,6 +6,8 @@ cache/
packages/*.pkg
packages/*.txz
packages/.repo/
packages/All/
packages/meta*
# Temporary files
/tmp/

View file

@ -42,12 +42,12 @@ Creates 50GB image with:
- Clawdie-AI tarball + firstboot modules
- Installer config
Output: `clawdie-iso-24.mar.2026.img` (or current date)
Output: `tmp/output/clawdie-iso-24.mar.2026.img` (or current date)
### Step 3: Write to USB
```bash
# Identify USB device: da0, da1, etc (NOT da0s1 or da0a)
sudo dd if=clawdie-iso-24.mar.2026.img of=/dev/daX bs=1M status=progress
sudo dd if=tmp/output/clawdie-iso-24.mar.2026.img of=/dev/daX bs=1M status=progress
sudo sync
```
@ -153,11 +153,11 @@ sudo ./scripts/bhyve-test.sh
**"pkg: error: Cannot access the database"**
- Offline package repo may be corrupted
- Re-run with `--skip-fetch` and clean old `packages/All`
- Re-run with `--skip-fetch` and clean old `tmp/packages/All`
**"Cannot attach mdconfig"**
- Verify you're running as root
- Check available disk space: `df -h /tmp`
- Check available disk space: `df -h ./tmp`
- Increase `IMAGE_SIZE` if building on same disk as packages
**SSH key auth failing in firstboot**
@ -169,7 +169,7 @@ sudo ./scripts/bhyve-test.sh
- Tested on FreeBSD 15.0-RELEASE-p4 (amd64)
- Requires root for steps 5-7 (mdconfig, gpart, newfs, mount)
- Steps 1-4 can run as unprivileged user
- Build requires ~150GB free disk space (for image + packages + cache)
- Build requires ~150GB free disk space under `tmp/` (for image + packages + cache)
## Size Breakdown (50GB image)

View file

@ -187,7 +187,10 @@ clawdie-iso/
│ ├── pkg-list-lumina.txt ← NEW (not old xfce/kde/mate variants)
│ ├── pkg-list-jails.txt ← unchanged
│ ├── pkg-list-nvidia.txt ← unchanged
│ └── ... (pre-fetched .pkg files built by build.sh)
│ └── ... (pkg lists only; build artifacts live under tmp/packages/)
├── tmp/
│ └── packages/ ← pre-fetched .pkg files built by build.sh
├── CLAWDIE-ISO.md ← archive (this is the old plan)
├── CLAWDIE-ISO-REFACTORED.md ← THIS FILE

View file

@ -308,20 +308,23 @@ clawdie-iso/
│ ├── rc.d/
│ │ └── clawdie-firstboot ← FreeBSD rc.d service (runs once)
│ └── gpu-detect.sh ← pciconf → kld table lookup
├── packages/ ← pre-fetched .pkg files (gitignored, fetched by build.sh)
│ ├── .repo/ ← generated by pkg repo
│ └── *.pkg
├── packages/ ← pkg list inputs (tracked)
│ └── pkg-list-*.txt
├── tmp/
│ └── packages/ ← pre-fetched .pkg files (build artifacts)
│ ├── .repo/ ← generated by pkg repo
│ └── *.pkg
└── CLAWDIE-ISO.md ← this document (copy)
```
`build.sh` responsibilities:
1. Fetch FreeBSD memstick installer image (verified checksum)
2. Fetch all required .pkg files to `packages/` (node24, bastille, desktop-installer deps, etc.)
3. Run `pkg repo packages/` to generate repo metadata
2. Fetch all required .pkg files to `tmp/packages/` (node24, bastille, desktop-installer deps, etc.)
3. Run `pkg repo tmp/packages/` to generate repo metadata
4. Unpack memstick image
5. Inject into memstick: `installerconfig`, `firstboot/` tree, `packages/` repo, `clawdie-ai.tar.gz`
6. Repack image
7. Output: `clawdie-iso-YYYYMMDD.img`
7. Output: `tmp/output/clawdie-iso-<variant>-DD.mmm.YYYY.img`
---

View file

@ -253,7 +253,7 @@ server {
# From controlplane host — access via jail filesystem path directly (no SSH needed)
rsync -a --delete \
/usr/local/bastille/jails/poudriere/root/usr/local/poudriere/data/packages/15amd64-clawdie/.latest/ \
/home/clawdie/clawdie-iso/packages/All/
/home/clawdie/clawdie-iso/tmp/packages/All/
```
### 5.2 Update build.sh in clawdie-iso
@ -263,12 +263,12 @@ via `pkg fetch`) and `--skip-fetch` (use cached packages). When Poudriere is
active, add a pre-fetch step that syncs Poudriere output before the stock fetch:
```bash
# scripts/build-packages.sh syncs Poudriere output into packages/
# scripts/build-packages.sh syncs Poudriere output into tmp/packages/
# before ./build.sh --fetch-only runs the stock pkg fetch on top.
# pkg priority 100 for Clawdie packages ensures they win over stock.
# Poudriere output lands in packages/All/ alongside stock packages.
# pkg repo packages/ generates a single unified repo from both.
# Poudriere output lands in tmp/packages/All/ alongside stock packages.
# pkg repo tmp/packages/ generates a single unified repo from both.
```
The `--fetch-only` stage in the Forgejo Actions pipeline should run
@ -316,10 +316,10 @@ jexec poudriere poudriere bulk -j 15amd64 -p clawdie -f /usr/local/etc/poudriere
# Sync to git jail
rsync -a --delete \
/usr/local/bastille/jails/poudriere/root/usr/local/poudriere/data/packages/15amd64-clawdie/.latest/ \
/home/clawdie/clawdie-iso/packages/All/
/home/clawdie/clawdie-iso/tmp/packages/All/
echo "=== Package build complete ==="
echo "Packages available at: /srv/git/clawdie-iso/packages/"
echo "Packages available at: /srv/git/clawdie-iso/tmp/packages/"
```
### 6.2 Scheduling
@ -352,7 +352,7 @@ jexec poudriere poudriere bulk -j 15amd64 -p clawdie -f /usr/local/etc/poudriere
# 3. Sync to git jail
rsync -a \
/usr/local/bastille/jails/poudriere/root/usr/local/poudriere/data/packages/15amd64-clawdie/.latest/ \
/home/clawdie/clawdie-iso/packages/All/
/home/clawdie/clawdie-iso/tmp/packages/All/
# 4. Rebuild ISO
cd /srv/git/clawdie-iso && ./build.sh
@ -389,7 +389,7 @@ cd /srv/git/clawdie-iso && ./build.sh
| `clawdie-pkglist` | poudriere jail:/usr/local/etc/poudriere.d/ | Package list |
| `15amd64-clawdie-make.conf` | poudriere jail:/usr/local/etc/poudriere.d/ | Build options |
| `build-packages.sh` | clawdie-iso repo | Build automation |
| `packages/` | git jail:/srv/git/clawdie-iso/ | Built packages |
| `tmp/packages/` | git jail:/srv/git/clawdie-iso/tmp/ | Built packages |
---

View file

@ -43,14 +43,14 @@ cd Clawdie-ISO
# Assemble ISO (requires root for mdconfig/mount)
doas ./build.sh
# Output: clawdie-iso-<variant>-DD.mmm.YYYY.img (~50 GB, configurable in build.cfg)
# Output: tmp/output/clawdie-iso-<variant>-DD.mmm.YYYY.img (~50 GB, configurable in build.cfg)
```
### Install on Hardware
1. **Write to USB:**
```bash
doas dd if=clawdie-iso-<variant>-DD.mmm.YYYY.img of=/dev/da0 bs=1M
doas dd if=tmp/output/clawdie-iso-<variant>-DD.mmm.YYYY.img of=/dev/da0 bs=1M
# (replace da0 with your USB device)
```
@ -174,7 +174,7 @@ cd Clawdie-ISO
# Build ISO (requires root)
doas ./build.sh
# Output: clawdie-iso-<variant>-DD.mmm.YYYY.img
# Output: tmp/output/clawdie-iso-<variant>-DD.mmm.YYYY.img
```
See [CLAWDIE-SHELL.md](CLAWDIE-SHELL.md) for full specification.

View file

@ -308,7 +308,7 @@ $ # On next login, select XFCE session
# Verify ISO builds without error
./build.sh --skip-fetch
# Verify shell modules are copied
ls -la cache/*/firstboot/clawdie-lib-*.sh
ls -la tmp/cache/*/firstboot/clawdie-lib-*.sh
```
### Phase 2: First Boot Test
@ -413,4 +413,3 @@ After refactoring, the ISO should:
- **Lumina Desktop:** https://lumina-desktop.org/
- **bsddialog:** https://man.freebsd.org/bsddialog/8
- **FreeBSD Jails:** https://docs.freebsd.org/en/books/handbook/jails/

View file

@ -249,11 +249,11 @@ Or press `Ctrl-C` in the bhyve console (may not work cleanly; destroy is cleaner
**Fix:**
```bash
# Verify ISO
file /home/clawdie/clawdie-iso/clawdie-iso-baremetal-*.img
file /home/clawdie/clawdie-iso/tmp/output/clawdie-iso-baremetal-*.img
# Should show: DOS/MBR boot sector
# Check size
ls -lh /home/clawdie/clawdie-iso/clawdie-iso-baremetal-*.img
ls -lh /home/clawdie/clawdie-iso/tmp/output/clawdie-iso-baremetal-*.img
# Should be ~25G
# Rebuild if needed
@ -328,7 +328,7 @@ Before marking test as passed, verify:
## Next Steps
**If all tests pass:**
- Commit ISO to git: `git add clawdie-iso-baremetal-*.img && git commit -m "build: Final ISO for v0.9.0"`
- Publish ISO from `tmp/output/` (do not commit build artifacts)
- Test on real hardware (Intel, AMD, NVIDIA systems)
- Begin Phase 3 (clawdie-admin.sh UI)

View file

@ -6,7 +6,7 @@
# ./build-vps.sh --skip-fetch # use cached files
# ./build-vps.sh --clawdie-version 0.9.0
#
# Output: clawdie-vps-YYYYMMDD.iso
# Output: tmp/output/clawdie-vps-DD.mmm.YYYY.iso
#
# This ISO can be uploaded to:
# - Vultr (Custom ISO)
@ -20,12 +20,14 @@
set -e
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
CACHE_DIR="${SCRIPT_DIR}/cache"
PKG_DIR="${SCRIPT_DIR}/packages"
OUTPUT_DIR="${SCRIPT_DIR}/output"
ISO_WORK="${CACHE_DIR}/iso-work"
TMP_DIR="${SCRIPT_DIR}/tmp"
CACHE_DIR="${TMP_DIR}/cache"
PKG_REPO_DIR="${TMP_DIR}/packages"
OUTPUT_DIR="${TMP_DIR}/output"
ISO_WORK="${TMP_DIR}/iso-work"
. "${SCRIPT_DIR}/build.cfg"
mkdir -p "$TMP_DIR"
# --- VPS-specific config ---
MFSBSD_ISO_URL="https://depenguin.me/files/mfsbsd-15.0-RELEASE-amd64.iso"
@ -78,7 +80,7 @@ else
fi
# --- step 3: fetch packages (if not already done) ---
if [ "$SKIP_FETCH" -eq 0 ] && [ ! -d "$PKG_DIR/All" ]; then
if [ "$SKIP_FETCH" -eq 0 ] && [ ! -d "$PKG_REPO_DIR/All" ]; then
echo "==> [3/6] Packages not fetched. Run ./build.sh --fetch-only first."
echo " Skipping package bundle (ISO will require internet for pkg install)."
PKG_BUNDLE=0
@ -132,8 +134,8 @@ fi
cp "$CLAWDIE_TARBALL" "${CLAWDIE_SHARE}/clawdie-ai.tar.gz"
# Copy packages if available
if [ "$PKG_BUNDLE" -eq 1 ] && [ -d "$PKG_DIR/All" ]; then
cp -r "$PKG_DIR" "${CLAWDIE_SHARE}/"
if [ "$PKG_BUNDLE" -eq 1 ] && [ -d "$PKG_REPO_DIR/All" ]; then
cp -r "$PKG_REPO_DIR" "${CLAWDIE_SHARE}/"
fi
# Create rc.local to auto-start SSH and show instructions
@ -205,7 +207,8 @@ echo " Payload injected."
echo "==> [6/6] Repacking ISO..."
mkdir -p "$OUTPUT_DIR"
OUTPUT_ISO="${OUTPUT_DIR}/clawdie-vps-$(date +%Y%m%d).iso"
DATE_STAMP="$(LC_TIME=C date +%d.%b.%Y | tr 'A-Z' 'a-z')"
OUTPUT_ISO="${OUTPUT_DIR}/clawdie-vps-${DATE_STAMP}.iso"
# Use genisoimage (Linux) or mkisofs (FreeBSD)
if command -v genisoimage >/dev/null 2>&1; then

View file

@ -13,15 +13,18 @@
# pkg install curl # for fetching
# pkg install (root) # for step 5-6 (mdconfig, mount)
#
# The packages/ directory produced here is dual-purpose:
# The tmp/packages/ directory produced here is dual-purpose:
# 1. Bundled into the ISO for offline installation
# 2. Used to seed zroot/pkg-cache on the installed system for offline jail provisioning
set -e
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
PKG_DIR="${SCRIPT_DIR}/packages"
CACHE_DIR="${SCRIPT_DIR}/cache"
TMP_DIR="${SCRIPT_DIR}/tmp"
PKG_LIST_DIR="${SCRIPT_DIR}/packages"
PKG_REPO_DIR="${TMP_DIR}/packages"
CACHE_DIR="${TMP_DIR}/cache"
OUTPUT_DIR="${TMP_DIR}/output"
. "${SCRIPT_DIR}/build.cfg"
@ -79,31 +82,32 @@ case "${TARGET:-baremetal}" in
*) VARIANT="${GPU_DRIVER:-baremetal}" ;;
esac
IMAGE_NAME="clawdie-iso-${VARIANT}-$(LC_TIME=C date +%d.%b.%Y | tr 'A-Z' 'a-z').img"
mkdir -p "$TMP_DIR"
# --- helper: read package lists into a single deduplicated list ---
pkg_list_all() {
# Cloud: headless, no desktop, no GPU drivers
if [ "${TARGET:-baremetal}" = "cloud" ]; then
cat \
"${PKG_DIR}/pkg-list-host.txt" \
"${PKG_DIR}/pkg-list-jails.txt" \
"${PKG_LIST_DIR}/pkg-list-host.txt" \
"${PKG_LIST_DIR}/pkg-list-jails.txt" \
| grep -v '^#' | grep -v '^$' | sort -u
return 0
fi
# Baremetal: desktop + optional GPU packages
case "${GPU_DRIVER:-}" in
nvidia-590) GPU_PKG="${PKG_DIR}/pkg-list-nvidia-590.txt" ;;
nvidia-470) GPU_PKG="${PKG_DIR}/pkg-list-nvidia-470.txt" ;;
nvidia-390) GPU_PKG="${PKG_DIR}/pkg-list-nvidia-390.txt" ;;
nvidia-590) GPU_PKG="${PKG_LIST_DIR}/pkg-list-nvidia-590.txt" ;;
nvidia-470) GPU_PKG="${PKG_LIST_DIR}/pkg-list-nvidia-470.txt" ;;
nvidia-390) GPU_PKG="${PKG_LIST_DIR}/pkg-list-nvidia-390.txt" ;;
*) GPU_PKG="" ;;
esac
cat \
"${PKG_DIR}/pkg-list-host.txt" \
"${PKG_DIR}/pkg-list-jails.txt" \
"${PKG_DIR}/pkg-list-desktop-base.txt" \
"${PKG_DIR}/pkg-list-lumina.txt" \
"${PKG_LIST_DIR}/pkg-list-host.txt" \
"${PKG_LIST_DIR}/pkg-list-jails.txt" \
"${PKG_LIST_DIR}/pkg-list-desktop-base.txt" \
"${PKG_LIST_DIR}/pkg-list-lumina.txt" \
${GPU_PKG:+"$GPU_PKG"} \
| grep -v '^#' | grep -v '^$' | sort -u
}
@ -122,12 +126,12 @@ fi
# --- step 2: fetch all packages (no root needed) ---
if [ "$SKIP_FETCH" -eq 0 ]; then
echo "==> [2/7] Fetching packages to packages/..."
mkdir -p "$PKG_DIR"
echo "==> [2/7] Fetching packages to tmp/packages/..."
mkdir -p "$PKG_REPO_DIR"
# Set pkg repo to configured branch before fetching
# Use temporary user-level config to avoid requiring root
PKG_CONFIG_DIR=$(mktemp -d)
PKG_CONFIG_DIR=$(mktemp -d "${TMP_DIR}/pkg-repo.XXXXXX")
trap "rm -rf $PKG_CONFIG_DIR" EXIT
ABI=$(pkg config abi 2>/dev/null || echo "FreeBSD:15:amd64")
mkdir -p "$PKG_CONFIG_DIR"
@ -143,10 +147,10 @@ EOF
PKG_COUNT=$(echo "$PKGS" | wc -l | tr -d ' ')
echo " Fetching ${PKG_COUNT} packages (with dependencies)..."
# pkg fetch downloads .pkg files and all dependencies to packages/
# pkg fetch downloads .pkg files and all dependencies to tmp/packages/
# Use PKG_REPOS_DIR to override system repos with our temporary config
export PKG_REPOS_DIR="$PKG_CONFIG_DIR"
echo "$PKGS" | xargs pkg fetch --yes --dependencies --output "$PKG_DIR"
echo "$PKGS" | xargs pkg fetch --yes --dependencies --output "$PKG_REPO_DIR"
echo " Fetch complete."
else
@ -155,11 +159,11 @@ fi
# --- step 3: generate offline pkg repo metadata ---
echo "==> [3/7] Generating offline pkg repo metadata..."
if [ -d "$PKG_DIR/All" ]; then
pkg repo "$PKG_DIR"
echo " Repo metadata written to packages/"
if [ -d "$PKG_REPO_DIR/All" ]; then
pkg repo "$PKG_REPO_DIR"
echo " Repo metadata written to tmp/packages/"
else
echo " WARN: packages/All/ not found — run without --skip-fetch first"
echo " WARN: tmp/packages/All/ not found — run without --skip-fetch first"
fi
# Exit here if --fetch-only (CI package pre-fetch step, no root required)
@ -279,7 +283,7 @@ mkdir -p "$USB_SHARE"
# Copy payload
cp "${SCRIPT_DIR}/installerconfig" "${MOUNT_POINT}/etc/installerconfig"
cp -r "${SCRIPT_DIR}/firstboot" "${USB_SHARE}/"
cp -r "${PKG_DIR}" "${USB_SHARE}/"
cp -r "${PKG_REPO_DIR}" "${USB_SHARE}/"
cp "${CACHE_DIR}/clawdie-ai-v${CLAWDIE_VERSION}.tar.gz" "${USB_SHARE}/clawdie-ai.tar.gz"
cp "${SCRIPT_DIR}/build.cfg" "${USB_SHARE}/"
@ -318,10 +322,11 @@ fi
# --- step 7: write output ---
echo "==> [7/7] Writing output image..."
cp "$WORK_IMG" "${SCRIPT_DIR}/${IMAGE_NAME}"
mkdir -p "$OUTPUT_DIR"
cp "$WORK_IMG" "${OUTPUT_DIR}/${IMAGE_NAME}"
echo ""
echo " Done : ${SCRIPT_DIR}/${IMAGE_NAME}"
echo " Size : $(du -sh "${SCRIPT_DIR}/${IMAGE_NAME}" | cut -f1)"
echo " Done : ${OUTPUT_DIR}/${IMAGE_NAME}"
echo " Size : $(du -sh "${OUTPUT_DIR}/${IMAGE_NAME}" | cut -f1)"
echo ""
echo " Write to USB:"
echo " dd if=${IMAGE_NAME} of=/dev/daX bs=1M status=progress"

View file

@ -143,7 +143,7 @@ For fully offline installs, you can build a custom mfsBSD ISO with Clawdie pre-b
```bash
cd clawdie-iso
./build-vps.sh
# Output: output/clawdie-vps-YYYYMMDD.iso
# Output: tmp/output/clawdie-vps-DD.mmm.YYYY.iso
```
This requires more setup and is optional — the script approach above is simpler.

View file

@ -1,7 +0,0 @@
version = 2;
packing_format = "tzst";
manifests = "packagesite.yaml";
data = "data";
filesite = "filesite.yaml";
manifests_archive = "packagesite";
filesite_archive = "filesite";

View file

@ -1,7 +0,0 @@
version = 2;
packing_format = "tzst";
manifests = "packagesite.yaml";
data = "data";
filesite = "filesite.yaml";
manifests_archive = "packagesite";
filesite_archive = "filesite";

View file

@ -14,6 +14,7 @@ DISK_SIZE="25G"
MEM="2G"
CPUS="2"
ISO_DIR="$(cd "$(dirname "$0")/.." && pwd)"
ISO_OUTPUT_DIR="${ISO_DIR}/tmp/output"
# bhyve network — isolated from warden0 (jail bridge)
BHYVE_BRIDGE="bhyve0"
@ -41,12 +42,17 @@ done
# Auto-detect newest baremetal image if no ISO given
if [ -z "$ISO" ]; then
ISO="$(ls -t "${ISO_DIR}"/clawdie-iso-baremetal-*.img 2>/dev/null | head -1)"
if [ -d "$ISO_OUTPUT_DIR" ]; then
ISO="$(ls -t "${ISO_OUTPUT_DIR}"/clawdie-iso-baremetal-*.img 2>/dev/null | head -1)"
fi
if [ -z "$ISO" ]; then
ISO="$(ls -t "${ISO_DIR}"/clawdie-iso-baremetal-*.img 2>/dev/null | head -1)"
fi
fi
if [ -z "$ISO" ] || [ ! -f "$ISO" ]; then
echo "ERROR: No ISO found. Pass path as argument or place a"
echo " clawdie-iso-baremetal-*.img in ${ISO_DIR}/"
echo " clawdie-iso-baremetal-*.img in ${ISO_OUTPUT_DIR}/"
exit 1
fi

View file

@ -14,14 +14,15 @@
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
TMP_DIR="${SCRIPT_DIR}/tmp"
WEBROOT="/usr/local/www/clawdie/docs"
BUILD_DATE="$(date '+%Y-%m-%d')"
BUILD_TS="$(date '+%Y-%m-%d %H:%M:%S %Z')"
LOG_TMP="/tmp/clawdie-iso-build-$$.log"
LOG_TMP="${TMP_DIR}/clawdie-iso-build-$$.log"
HTML_LATEST="${WEBROOT}/iso-build-log.html"
HTML_DATED="${WEBROOT}/iso-build-${BUILD_DATE}.html"
mkdir -p "${WEBROOT}"
mkdir -p "${WEBROOT}" "${TMP_DIR}"
echo "=== Clawdie-ISO Build ==="
echo "Started: ${BUILD_TS}"

View file

@ -13,6 +13,7 @@ set -e
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
PARENT_DIR="$(dirname "$SCRIPT_DIR")"
OUTPUT_DIR="${PARENT_DIR}/tmp/output"
. "${PARENT_DIR}/build.cfg"
# CMS jail location (customize if different)
@ -20,10 +21,10 @@ CMS_JAIL_ROOT="/jails/cms"
CMS_DOWNLOADS="${CMS_JAIL_ROOT}/usr/local/nginx/html/downloads"
# Find the most recent built ISO
ISO_FILE=$(ls -t "${PARENT_DIR}"/clawdie-iso-*.img 2>/dev/null | head -1)
ISO_FILE=$(ls -t "${OUTPUT_DIR}"/clawdie-iso-*.img 2>/dev/null | head -1)
if [ -z "$ISO_FILE" ]; then
echo "ERROR: No ISO file found in ${PARENT_DIR}"
echo "ERROR: No ISO file found in ${OUTPUT_DIR}"
exit 1
fi

View file

@ -81,18 +81,18 @@ jexec <AGENT_NAME>-cms install -d -m 0755 /usr/local/www/<AGENT_DOMAIN>/download
```sh
# On host, clone from git jail's bare repo into a working directory
git clone file:///usr/local/bastille/jails/<AGENT_NAME>-git/root/srv/git/clawdie-iso \
/tmp/clawdie-iso-build
./tmp/clawdie-iso-build
# Or update an existing clone
git -C /tmp/clawdie-iso-build pull
git -C ./tmp/clawdie-iso-build pull
```
### Step 2 — Run build.sh
```sh
cd /tmp/clawdie-iso-build
cd ./tmp/clawdie-iso-build
sudo ./build.sh
# Output: clawdie-iso-YYYYMMDD.img (~4-8 GB)
# Output: tmp/output/clawdie-iso-<variant>-DD.mmm.YYYY.img (~4-8 GB)
```
Monitor progress — build takes 1540 minutes depending on bandwidth (fetching
@ -105,12 +105,12 @@ sudo ./build.sh --skip-fetch
```sh
# Copy into CMS jail webroot
sudo cp /tmp/clawdie-iso-build/clawdie-iso-*.img \
sudo cp ./tmp/clawdie-iso-build/tmp/output/clawdie-iso-*.img \
/usr/local/bastille/jails/<AGENT_NAME>-cms/root/usr/local/www/<AGENT_DOMAIN>/downloads/clawdie-iso-latest.img
# Symlink with date stamp for archive
sudo ln -sf clawdie-iso-latest.img \
"/usr/local/bastille/jails/<AGENT_NAME>-cms/root/usr/local/www/<AGENT_DOMAIN>/downloads/clawdie-iso-$(date +%Y%m%d).img"
"/usr/local/bastille/jails/<AGENT_NAME>-cms/root/usr/local/www/<AGENT_DOMAIN>/downloads/clawdie-iso-$(LC_TIME=C date +%d.%b.%Y | tr 'A-Z' 'a-z').img"
```
### Step 4 — Verify and report
@ -126,10 +126,10 @@ Report the download URL and file size to the operator.
```sh
# Remove build working directory after successful publish
rm -rf /tmp/clawdie-iso-build
rm -rf ./tmp/clawdie-iso-build
```
The `cache/` directory inside the build tree is gitignored and expensive to
The `tmp/cache/` directory inside the build tree is gitignored and expensive to
re-fetch. If disk space permits, keep it: `sudo ./build.sh --skip-fetch` on
the next run will be significantly faster.
@ -138,9 +138,9 @@ the next run will be significantly faster.
| Symptom | Cause | Fix |
|---------|-------|-----|
| `mdconfig: no devices left` | Too many loopback devices open | `mdconfig -d -u X` to free stale devices |
| `pkg repo` fails | packages/ is empty | Re-run without `--skip-fetch` |
| `pkg repo` fails | tmp/packages/ is empty | Re-run without `--skip-fetch` |
| nginx 404 on /downloads/ | Location block missing | Add location block (see above), reload nginx |
| Checksum mismatch on memstick | Interrupted download | Delete `cache/FreeBSD-*.img` and rebuild |
| Checksum mismatch on memstick | Interrupted download | Delete `tmp/cache/FreeBSD-*.img` and rebuild |
| `git clone` from jail fails | Git jail not running | `bastille start <AGENT_NAME>-git` |
## Version history

View file

@ -12,6 +12,7 @@ set -e
SKILL_DIR="$(dirname "$(realpath "$0")")/.."
CLAWDIE_AI="$(realpath "${SKILL_DIR}/../..")"
ISO_ROOT="$(realpath "${SKILL_DIR}/../../..")"
# Load .env
if [ -f "${CLAWDIE_AI}/.env" ]; then
@ -25,7 +26,7 @@ GIT_JAIL="${AGENT_NAME}-git"
CMS_JAIL="${AGENT_NAME}-cms"
GIT_STORAGE="/usr/local/bastille/jails/${GIT_JAIL}/root/srv/git"
WEBROOT="/usr/local/bastille/jails/${CMS_JAIL}/root/usr/local/www/${AGENT_DOMAIN}"
BUILD_DIR="/tmp/clawdie-iso-build"
BUILD_DIR="${ISO_ROOT}/tmp/clawdie-iso-build"
SKIP_FETCH=0
NO_PUBLISH=0
@ -58,6 +59,7 @@ fi
# --- step 1: clone / update working copy ---
echo "==> [1/4] Syncing clawdie-iso from git jail..."
mkdir -p "${ISO_ROOT}/tmp"
if [ -d "$BUILD_DIR" ]; then
git -C "$BUILD_DIR" pull
else
@ -72,7 +74,8 @@ cd "$BUILD_DIR"
sh build.sh $BUILD_ARGS
# Find the output image
IMG=$(ls -t "${BUILD_DIR}"/clawdie-iso-*.img 2>/dev/null | head -1)
IMG_DIR="${BUILD_DIR}/tmp/output"
IMG=$(ls -t "${IMG_DIR}"/clawdie-iso-*.img 2>/dev/null | head -1)
if [ -z "$IMG" ]; then
echo "ERROR: build produced no .img file"
exit 1
@ -97,7 +100,7 @@ fi
DOWNLOADS="${WEBROOT}/downloads"
install -d -m 0755 "$DOWNLOADS"
DATESTAMP=$(date +%Y%m%d)
DATESTAMP=$(LC_TIME=C date +%d.%b.%Y | tr 'A-Z' 'a-z')
DEST_DATED="${DOWNLOADS}/clawdie-iso-${DATESTAMP}.img"
DEST_LATEST="${DOWNLOADS}/clawdie-iso-latest.img"