clawdie-iso/BUILD.md

7.4 KiB
Raw Blame History

Clawdie ISO (bundles Clawdie-AI v1.0.2) — ISO Builder

Building a bootable Clawdie ISO installer with offline package support. Supports two targets: --target baremetal (Lumina desktop) and --target vps (headless).

Prerequisites

On your build host (FreeBSD 15.0+):

pkg install curl

Tailscale auth key (recommended):

Tailscale provides secure remote access without exposing SSH publicly.

Why Tailscale?

  • Zero-config VPN (no port forwarding, firewall rules)
  • Works behind NAT, dynamic IPs, CGNAT
  • Encrypted WireGuard tunnels
  • Access from anywhere (phone, laptop, tablet)

Setup (recommended):

  1. Sign up free at https://tailscale.com (free up to 100 devices)
  2. Admin console → Settings → Keys → Generate auth key (check "Reusable" for multi-deploy)
  3. Export before building: export TAILSCALE_AUTHKEY="tskey-auth-..."

Without Tailscale:

  • Build will continue with a warning
  • SSH will be exposed on public port 22
  • You are responsible for securing network access

USB Key Requirements:

USB Size Recommended Spare Space Notes
64GB Minimum ~14GB Default build.cfg (50GB image)
128GB Recommended ~28GB Comfortable for offline setup
256GB Extra ~56GB Future expansion room

⚠️ Do not use USB keys smaller than 64GB

Quick Start

# Recommended: Set Tailscale auth key for secure remote access
export TAILSCALE_AUTHKEY="tskey-auth-..."

# Alternative: Build without Tailscale (SSH exposed publicly)
# unset TAILSCALE_AUTHKEY
# ./build.sh will warn but continue

Step 1: Fetch packages (no root needed)

./build.sh --fetch-only

This downloads:

  • FreeBSD 15.0-RELEASE memstick
  • All packages (host + jails + desktop + GPU)
  • Clawdie-AI v1.0.2 tarball

Takes ~30 min on fast connection. Can be interrupted/resumed.

Step 2: Build ISO (requires root)

# Unified ISO (works on VPS and baremetal):
sudo ./build.sh --skip-fetch

Creates 50GB image with:

  • FreeBSD base system
  • Offline package repository (pre-cached for jail provisioning)
  • Clawdie-AI tarball + firstboot modules
  • Installer config
  • All packages included (desktop + GPU drivers)

Output: tmp/output/clawdie-iso-unified-DD.MMM.YYYY.img (or current date)

Step 3: Write to USB

# Identify USB device: da0, da1, etc (NOT da0s1 or da0a)
sudo dd if=tmp/output/clawdie-iso-24.mar.2026.img of=/dev/daX bs=1M status=progress
sudo sync

Build Configuration

Edit build.cfg to customize:

FREEBSD_VERSION="15.0-RELEASE"      # Kernel/base version
FREEBSD_ARCH="amd64"                # x86-64 (arm64 not yet supported)
IMAGE_SIZE="50G"                    # For 64GB USB; set to 100G for 128GB USB
CLAWDIE_VERSION="0.8.2"             # Pin Clawdie-AI version
DEFAULT_DESKTOP="lumina"            # Desktop environment (Lumina only)
DEFAULT_PKG_BRANCH="latest"         # Package branch (latest or quarterly)

Advanced Options

# Fetch only (for CI pre-download step, no root)
./build.sh --fetch-only

# Build from cached packages (no download)
./build.sh --skip-fetch

# Build targets
./build.sh --target baremetal    # Lumina desktop (default)
./build.sh --target vps          # Headless + cage/wayvnc

# Override Clawdie version
./build.sh --clawdie-version 1.0.2

# Combine flags
./build.sh --fetch-only
# ... later ...
./build.sh --skip-fetch --target vps --clawdie-version 1.0.2

# Build without Tailscale (SSH publicly exposed)
unset TAILSCALE_AUTHKEY
./build.sh  # Will warn but continue

Build Process (7 steps)

  1. Fetch FreeBSD memstick — Downloads base OS image
  2. Fetch packages — Fetches all .pkg files + dependencies
  3. Generate repo metadata — Creates offline pkg repository index
  4. Fetch Clawdie-AI — Downloads tarball from Codeberg
  5. Prepare 25GB image — Creates working image with proper partitioning
    • Allocates 50GB disk space
    • Creates MBR partition table + BSD label
    • Creates UFS filesystem
    • Mounts and extracts FreeBSD base
  6. Inject payload — Copies packages, scripts, Clawdie-AI to image
  7. Write output — Copies working image to final .img file

Each step idempotent — can resume if interrupted.

First Boot Flow

When you boot a machine from the USB:

  1. bsdinstall runs FreeBSD installer (standard workflow)
  2. installerconfig hook (post-install) injects firstboot payload to HDD
  3. clawdie-firstboot service runs on first HDD boot
  4. firstboot.sh wizard guides user through (baremetal):
    • Screen 1: Tailscale (recommended, can be skipped)
    • Screen 2: Identity (assistant name, domain, timezone)
    • Screen 3: SSH key (optional)
    • Screen 4: Summary (review + confirm)
    • Package repo config (online + offline USB)
    • GPU detection + driver selection
    • System config (hostname, services, PF firewall)
    • Clawdie-AI deployment + jail setup
  5. VPS: no wizard — all config pre-baked in build.cfg at build time

Tailscale behavior:

  • With auth key: Automatically connects to your tailnet
  • Without auth key: Installed but not connected (run tailscale up later)
  • Disabled: SSH exposed on public port 22 (not recommended)

See firstboot/MODULE-MANIFEST.md for wizard architecture.

Testing the Built ISO

Before writing to USB, test the ISO in a virtual machine:

Module Integration Test (5 min, no root)

# Quick validation: all 8 core shell modules execute with state handoff
sh firstboot/integration-test.sh

Expected result: "Integration test passed: All 8 modules executed with state handoff"

Full Bhyve Boot Test (2025 min, interactive)

# Boot the ISO in bhyve VM (includes bsdinstall + firstboot)
cd /home/clawdie/clawdie-iso
# Optional: allow guest internet (writes /etc/pf.bhyve.conf and reloads PF)
sudo ./scripts/bhyve-pf-allow.sh
sudo ./scripts/bhyve-test.sh

# Follow installer prompts
# Then verify: GPU detection, package repos, Clawdie deployment
# Login to Lumina desktop when ready

See TESTING.md for detailed test procedures and troubleshooting.


Troubleshooting

"Insufficient space on /mnt"

  • Your USB key is too small (< 64GB)
  • Use lsblk on Linux or gpart list on FreeBSD to verify

"pkg: error: Cannot access the database"

  • Offline package repo may be corrupted
  • 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
  • Increase IMAGE_SIZE if building on same disk as packages

SSH key auth failing in firstboot

  • Verify SSH key in /home/clawdie/.ssh/codeberg-clawdie
  • Check Codeberg account has SSH key registered

Build Environment Notes

  • 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 under tmp/ (for image + packages + cache)

Size Breakdown (50GB image)

Component Size
FreeBSD base ~2.5GB
Packages offline repo ~8GB
Clawdie-AI tarball ~400MB
firstboot scripts ~1MB
Free space ~39GB
Total image 50GB

Free space is reserved for:

  • Package cache seeding during jail setup
  • User data and logs
  • Future offline updates

Next: See firstboot/MODULE-MANIFEST.md for Phase 2.1 (wizard implementation) and AGENTS.md for operator instructions.