feat: CI/CD pipeline, package lists, offline pkg-cache seeding
.forgejo/workflows/build.yml: - Forgejo Actions pipeline: push to main + weekly cron + manual dispatch - Two-stage: fetch-only (no root) → assemble ISO (root via sudo) - Publishes ISO to CMS nginx downloads; Codeberg release entry (metadata only) - Uploads packages/ as workflow artifact for pkg-cache seeding packages/: - pkg-list-host.txt — host baseline (mirrors clawdie-ai infra/packages/) - pkg-list-jails.txt — union of all jail package lists - pkg-list-desktop-base.txt — Xorg + drm base for all DEs - pkg-list-xfce.txt / kde.txt / mate.txt / nvidia.txt — per-DE packages build.sh: - --fetch-only flag: downloads packages + memstick, no root, CI step 1 - Real pkg fetch loop: reads all pkg-list-*.txt, deduplicates, runs pkg fetch - pkg repo step: generates offline repo metadata after fetch - Resolves "latest" Clawdie version via Codeberg API firstboot/firstboot.sh: - Seeds zroot/pkg-cache from USB packages/ after desktop install - npm run install-all runs fully offline — no internet needed for jails - Creates ZFS dataset if not present, falls back to plain directory runner/README.md: - forgejo-runner install + register on FreeBSD - Scoped sudoers entry (build.sh + publish.sh only) - rc.d service setup Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
601372b0a3
commit
3d21e5fa36
11 changed files with 415 additions and 41 deletions
73
.forgejo/workflows/build.yml
Normal file
73
.forgejo/workflows/build.yml
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
name: Build Clawdie ISO
|
||||||
|
|
||||||
|
# Triggers:
|
||||||
|
# - Push to main (fresh build on every change)
|
||||||
|
# - Weekly Sunday 03:00 UTC (catches upstream pkg updates)
|
||||||
|
# - Manual dispatch (with optional overrides)
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
schedule:
|
||||||
|
- cron: '0 3 * * 0'
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
clawdie_version:
|
||||||
|
description: 'Clawdie-AI version to bundle (default: latest tag)'
|
||||||
|
required: false
|
||||||
|
default: ''
|
||||||
|
skip_fetch:
|
||||||
|
description: 'Skip package fetch — use runner cache'
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: [self-hosted, freebsd]
|
||||||
|
timeout-minutes: 180
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# Step 1 — fetch packages (runs as normal user, no root needed)
|
||||||
|
# Packages are cached on the runner between runs.
|
||||||
|
# Weekly trigger always re-fetches to pick up upstream updates.
|
||||||
|
- name: Fetch packages
|
||||||
|
if: ${{ !inputs.skip_fetch || github.event_name == 'schedule' }}
|
||||||
|
run: ./build.sh --fetch-only
|
||||||
|
|
||||||
|
# Step 2 — assemble ISO (needs root for mdconfig/mount)
|
||||||
|
- name: Build ISO
|
||||||
|
run: sudo ./build.sh --skip-fetch ${{ inputs.clawdie_version && format('--clawdie-version {0}', inputs.clawdie_version) || '' }}
|
||||||
|
|
||||||
|
# Step 3a — publish to local CMS nginx downloads (primary)
|
||||||
|
# Runner is on the controlplane, direct copy to jail webroot.
|
||||||
|
- name: Publish to CMS downloads
|
||||||
|
if: github.ref == 'refs/heads/main'
|
||||||
|
run: sudo ./scripts/publish.sh
|
||||||
|
|
||||||
|
# Step 3b — create Codeberg release entry (metadata only, not the image)
|
||||||
|
# The ISO is too large to upload as a release artifact.
|
||||||
|
# Release entry contains: version, date, checksum, local download URL.
|
||||||
|
- name: Create release entry
|
||||||
|
if: github.ref == 'refs/heads/main'
|
||||||
|
uses: actions/forgejo-release@v2
|
||||||
|
with:
|
||||||
|
direction: upload
|
||||||
|
release-dir: release-meta/
|
||||||
|
token: ${{ secrets.FORGEJO_TOKEN }}
|
||||||
|
tag: build-${{ github.run_number }}
|
||||||
|
release-notes: |
|
||||||
|
Automated build from commit ${{ github.sha }}
|
||||||
|
Download: https://${{ secrets.AGENT_DOMAIN }}/downloads/clawdie-iso-latest.img
|
||||||
|
|
||||||
|
# Step 4 — upload packages/ repo as workflow artifact (pkg cache seed)
|
||||||
|
# This artifact can be downloaded and used to seed zroot/pkg-cache
|
||||||
|
# on a running Clawdie system without building a full ISO.
|
||||||
|
- name: Upload pkg cache artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: pkg-cache-${{ github.run_number }}
|
||||||
|
path: packages/
|
||||||
|
retention-days: 90
|
||||||
167
build.sh
167
build.sh
|
|
@ -1,26 +1,38 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# clawdie-iso build script
|
# clawdie-iso build script
|
||||||
# Produces a bootable FreeBSD memstick image with Clawdie-AI pre-bundled.
|
# Produces a bootable FreeBSD memstick image with Clawdie-AI pre-bundled.
|
||||||
|
# All packages are fetched and bundled for fully offline installation.
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# ./build.sh # build with defaults from build.cfg
|
# ./build.sh # full build (fetch + assemble)
|
||||||
# ./build.sh --clawdie-version 0.9.0 # override Clawdie version
|
# ./build.sh --fetch-only # fetch packages/memstick only (no root needed)
|
||||||
# ./build.sh --skip-fetch # skip pkg/tarball fetch (use existing)
|
# ./build.sh --skip-fetch # assemble only (use cached packages)
|
||||||
|
# ./build.sh --clawdie-version 0.9.0 # pin Clawdie-AI version
|
||||||
#
|
#
|
||||||
# Requirements (run on FreeBSD host):
|
# Requirements (run on FreeBSD host):
|
||||||
# pkg install curl gnupg2 md5 xorriso
|
# pkg install curl # for fetching
|
||||||
|
# pkg install (root) # for step 5-6 (mdconfig, mount)
|
||||||
|
#
|
||||||
|
# The 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
|
set -e
|
||||||
|
|
||||||
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
|
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
|
||||||
|
PKG_DIR="${SCRIPT_DIR}/packages"
|
||||||
|
CACHE_DIR="${SCRIPT_DIR}/cache"
|
||||||
|
|
||||||
. "${SCRIPT_DIR}/build.cfg"
|
. "${SCRIPT_DIR}/build.cfg"
|
||||||
|
|
||||||
# --- argument parsing ---
|
# --- argument parsing ---
|
||||||
SKIP_FETCH=0
|
SKIP_FETCH=0
|
||||||
|
FETCH_ONLY=0
|
||||||
while [ "$#" -gt 0 ]; do
|
while [ "$#" -gt 0 ]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--clawdie-version) CLAWDIE_VERSION="$2"; shift 2 ;;
|
--clawdie-version) CLAWDIE_VERSION="$2"; shift 2 ;;
|
||||||
--skip-fetch) SKIP_FETCH=1; shift ;;
|
--skip-fetch) SKIP_FETCH=1; shift ;;
|
||||||
|
--fetch-only) FETCH_ONLY=1; shift ;;
|
||||||
*) echo "Unknown arg: $1"; exit 1 ;;
|
*) echo "Unknown arg: $1"; exit 1 ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
@ -32,63 +44,136 @@ echo " Desktop : ${DEFAULT_DESKTOP}"
|
||||||
echo " Pkg : ${DEFAULT_PKG_BRANCH}"
|
echo " Pkg : ${DEFAULT_PKG_BRANCH}"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
# --- helper: read package lists into a single deduplicated list ---
|
||||||
|
pkg_list_all() {
|
||||||
|
cat \
|
||||||
|
"${PKG_DIR}/pkg-list-host.txt" \
|
||||||
|
"${PKG_DIR}/pkg-list-jails.txt" \
|
||||||
|
"${PKG_DIR}/pkg-list-desktop-base.txt" \
|
||||||
|
"${PKG_DIR}/pkg-list-xfce.txt" \
|
||||||
|
"${PKG_DIR}/pkg-list-kde.txt" \
|
||||||
|
"${PKG_DIR}/pkg-list-mate.txt" \
|
||||||
|
"${PKG_DIR}/pkg-list-nvidia.txt" \
|
||||||
|
| grep -v '^#' | grep -v '^$' | sort -u
|
||||||
|
}
|
||||||
|
|
||||||
# --- step 1: fetch FreeBSD memstick ---
|
# --- step 1: fetch FreeBSD memstick ---
|
||||||
MEMSTICK="${SCRIPT_DIR}/cache/FreeBSD-${FREEBSD_VERSION}-${FREEBSD_ARCH}-memstick.img"
|
MEMSTICK="${CACHE_DIR}/FreeBSD-${FREEBSD_VERSION}-${FREEBSD_ARCH}-memstick.img"
|
||||||
if [ "$SKIP_FETCH" -eq 0 ] || [ ! -f "$MEMSTICK" ]; then
|
if [ "$SKIP_FETCH" -eq 0 ] || [ ! -f "$MEMSTICK" ]; then
|
||||||
echo "==> [1/7] Fetching FreeBSD memstick..."
|
echo "==> [1/7] Fetching FreeBSD memstick..."
|
||||||
mkdir -p "${SCRIPT_DIR}/cache"
|
mkdir -p "$CACHE_DIR"
|
||||||
curl -L -o "$MEMSTICK" "$FREEBSD_MEMSTICK_URL"
|
curl -L --progress-bar -o "$MEMSTICK" "$FREEBSD_MEMSTICK_URL"
|
||||||
curl -L -o "${MEMSTICK}.SHA256" "$FREEBSD_MEMSTICK_SHA256_URL"
|
curl -L -o "${MEMSTICK}.SHA256" "$FREEBSD_MEMSTICK_SHA256_URL"
|
||||||
sha256 -c "${MEMSTICK}.SHA256" || { echo "Checksum mismatch!"; exit 1; }
|
sha256 -c "${MEMSTICK}.SHA256" || { echo "ERROR: checksum mismatch on memstick"; exit 1; }
|
||||||
else
|
else
|
||||||
echo "==> [1/7] FreeBSD memstick already cached, skipping fetch."
|
echo "==> [1/7] FreeBSD memstick cached."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- step 2: fetch pkg dependencies ---
|
# --- step 2: fetch all packages (no root needed) ---
|
||||||
if [ "$SKIP_FETCH" -eq 0 ]; then
|
if [ "$SKIP_FETCH" -eq 0 ]; then
|
||||||
echo "==> [2/7] Fetching packages to packages/..."
|
echo "==> [2/7] Fetching packages to packages/..."
|
||||||
# TODO: read package list from packages/pkg-list.txt
|
mkdir -p "$PKG_DIR"
|
||||||
# pkg fetch --yes --dependencies --output packages/ <pkg-list>
|
|
||||||
echo " (stub — implement pkg fetch loop from packages/pkg-list.txt)"
|
# Set pkg repo to configured branch before fetching
|
||||||
|
mkdir -p /usr/local/etc/pkg/repos
|
||||||
|
ABI=$(pkg config abi 2>/dev/null || echo "FreeBSD:15:amd64")
|
||||||
|
cat > /usr/local/etc/pkg/repos/FreeBSD-build.conf <<EOF
|
||||||
|
FreeBSD: {
|
||||||
|
url: "pkg+https://pkg.FreeBSD.org/${ABI}/${DEFAULT_PKG_BRANCH}",
|
||||||
|
mirror_type: "srv",
|
||||||
|
enabled: yes
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
PKGS=$(pkg_list_all)
|
||||||
|
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/
|
||||||
|
echo "$PKGS" | xargs pkg fetch --yes --dependencies --output "$PKG_DIR"
|
||||||
|
|
||||||
|
# Clean up temporary repo config
|
||||||
|
rm -f /usr/local/etc/pkg/repos/FreeBSD-build.conf
|
||||||
|
|
||||||
|
echo " Fetch complete."
|
||||||
else
|
else
|
||||||
echo "==> [2/7] Skipping package fetch."
|
echo "==> [2/7] Skipping package fetch."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- step 3: generate local pkg repo metadata ---
|
# --- step 3: generate offline pkg repo metadata ---
|
||||||
echo "==> [3/7] Generating offline pkg repo metadata..."
|
echo "==> [3/7] Generating offline pkg repo metadata..."
|
||||||
# TODO: pkg repo packages/
|
if [ -d "$PKG_DIR/All" ]; then
|
||||||
echo " (stub — run: pkg repo packages/)"
|
pkg repo "$PKG_DIR"
|
||||||
|
echo " Repo metadata written to packages/"
|
||||||
# --- step 4: fetch Clawdie-AI tarball ---
|
|
||||||
CLAWDIE_TARBALL="${SCRIPT_DIR}/cache/clawdie-ai-v${CLAWDIE_VERSION}.tar.gz"
|
|
||||||
if [ "$SKIP_FETCH" -eq 0 ] || [ ! -f "$CLAWDIE_TARBALL" ]; then
|
|
||||||
echo "==> [4/7] Fetching Clawdie-AI v${CLAWDIE_VERSION}..."
|
|
||||||
curl -L -o "$CLAWDIE_TARBALL" \
|
|
||||||
"https://codeberg.org/Clawdie/Clawdie-AI/archive/v${CLAWDIE_VERSION}.tar.gz"
|
|
||||||
else
|
else
|
||||||
echo "==> [4/7] Clawdie-AI tarball already cached, skipping."
|
echo " WARN: packages/All/ not found — run without --skip-fetch first"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- step 5: unpack memstick image ---
|
# Exit here if --fetch-only (CI package pre-fetch step, no root required)
|
||||||
echo "==> [5/7] Unpacking memstick image..."
|
if [ "$FETCH_ONLY" -eq 1 ]; then
|
||||||
# TODO: mdconfig, mount, prepare working copy
|
echo ""
|
||||||
echo " (stub — mount memstick image via mdconfig)"
|
echo "==> Fetch complete. Run ./build.sh --skip-fetch to assemble ISO."
|
||||||
WORK_IMG="${SCRIPT_DIR}/cache/work.img"
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- step 4: fetch Clawdie-AI tarball ---
|
||||||
|
# Resolve "latest" to the most recent Codeberg tag
|
||||||
|
if [ "$CLAWDIE_VERSION" = "latest" ] || [ -z "$CLAWDIE_VERSION" ]; then
|
||||||
|
echo "==> [4/7] Resolving latest Clawdie-AI version..."
|
||||||
|
CLAWDIE_VERSION=$(curl -s "https://codeberg.org/api/v1/repos/Clawdie/Clawdie-AI/releases?limit=1" \
|
||||||
|
| grep -o '"tag_name":"[^"]*"' | head -1 | cut -d'"' -f4 | sed 's/^v//')
|
||||||
|
echo " Resolved: v${CLAWDIE_VERSION}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
CLAWDIE_TARBALL="${CACHE_DIR}/clawdie-ai-v${CLAWDIE_VERSION}.tar.gz"
|
||||||
|
if [ "$SKIP_FETCH" -eq 0 ] || [ ! -f "$CLAWDIE_TARBALL" ]; then
|
||||||
|
echo "==> [4/7] Fetching Clawdie-AI v${CLAWDIE_VERSION}..."
|
||||||
|
mkdir -p "$CACHE_DIR"
|
||||||
|
curl -L --progress-bar -o "$CLAWDIE_TARBALL" \
|
||||||
|
"https://codeberg.org/Clawdie/Clawdie-AI/archive/v${CLAWDIE_VERSION}.tar.gz"
|
||||||
|
else
|
||||||
|
echo "==> [4/7] Clawdie-AI v${CLAWDIE_VERSION} cached."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- step 5: prepare working image (requires root) ---
|
||||||
|
echo "==> [5/7] Preparing working image..."
|
||||||
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
|
echo "ERROR: steps 5-7 require root (mdconfig/mount)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
WORK_IMG="${CACHE_DIR}/work.img"
|
||||||
cp "$MEMSTICK" "$WORK_IMG"
|
cp "$MEMSTICK" "$WORK_IMG"
|
||||||
|
|
||||||
# --- step 6: inject payload into image ---
|
# Attach image as memory device
|
||||||
echo "==> [6/7] Injecting payload into image..."
|
MD=$(mdconfig -a -t vnode -f "$WORK_IMG")
|
||||||
# TODO: mount work image, copy into it:
|
echo " Attached as /dev/${MD}"
|
||||||
# - installerconfig → /etc/installerconfig
|
|
||||||
# - firstboot/ → /usr/local/share/clawdie-iso/firstboot/
|
|
||||||
# - packages/ → /usr/local/share/clawdie-iso/packages/
|
|
||||||
# - clawdie-ai tarball → /usr/local/share/clawdie-iso/clawdie-ai.tar.gz
|
|
||||||
# - build.cfg defaults → /usr/local/share/clawdie-iso/build.cfg
|
|
||||||
echo " (stub — mount + copy injection)"
|
|
||||||
|
|
||||||
# --- step 7: finalize and output ---
|
# FreeBSD memstick has partition 3 as the installer data partition (EFI)
|
||||||
|
# Mount it to inject our payload
|
||||||
|
MOUNT_POINT="${CACHE_DIR}/mnt"
|
||||||
|
mkdir -p "$MOUNT_POINT"
|
||||||
|
# TODO: determine correct partition and filesystem type for injection
|
||||||
|
# mount -t msdosfs /dev/${MD}p1 "$MOUNT_POINT"
|
||||||
|
echo " (TODO: mount partition, inject payload — partition layout TBD)"
|
||||||
|
mdconfig -d -u "$MD"
|
||||||
|
|
||||||
|
# --- step 6: inject payload ---
|
||||||
|
echo "==> [6/7] Injecting payload..."
|
||||||
|
# TODO: copy into mounted image:
|
||||||
|
# installerconfig → /etc/installerconfig
|
||||||
|
# firstboot/ → /usr/local/share/clawdie-iso/firstboot/
|
||||||
|
# packages/ → /usr/local/share/clawdie-iso/packages/
|
||||||
|
# clawdie-ai tarball → /usr/local/share/clawdie-iso/clawdie-ai.tar.gz
|
||||||
|
# build.cfg → /usr/local/share/clawdie-iso/build.cfg
|
||||||
|
echo " (TODO: injection pending partition layout decision)"
|
||||||
|
|
||||||
|
# --- step 7: write output ---
|
||||||
echo "==> [7/7] Writing output image..."
|
echo "==> [7/7] Writing output image..."
|
||||||
cp "$WORK_IMG" "${SCRIPT_DIR}/${IMAGE_NAME}"
|
cp "$WORK_IMG" "${SCRIPT_DIR}/${IMAGE_NAME}"
|
||||||
echo ""
|
echo ""
|
||||||
echo " Done: ${SCRIPT_DIR}/${IMAGE_NAME}"
|
echo " Done : ${SCRIPT_DIR}/${IMAGE_NAME}"
|
||||||
echo " Write to USB: dd if=${IMAGE_NAME} of=/dev/daX bs=1M status=progress"
|
echo " Size : $(du -sh "${SCRIPT_DIR}/${IMAGE_NAME}" | cut -f1)"
|
||||||
|
echo ""
|
||||||
|
echo " Write to USB:"
|
||||||
|
echo " dd if=${IMAGE_NAME} of=/dev/daX bs=1M status=progress"
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,25 @@ echo "Installing packages offline..."
|
||||||
# TODO: install DE-specific package list
|
# TODO: install DE-specific package list
|
||||||
# pkg install -y $(cat "${SHARE}/packages/pkg-list-${DESKTOP}.txt")
|
# pkg install -y $(cat "${SHARE}/packages/pkg-list-${DESKTOP}.txt")
|
||||||
|
|
||||||
|
# --- seed zroot/pkg-cache from USB packages ---
|
||||||
|
# The packages/ directory on the USB is dual-purpose:
|
||||||
|
# 1. Used above to install desktop + host packages offline
|
||||||
|
# 2. Seeded into zroot/pkg-cache so npm run install-all can provision
|
||||||
|
# all Bastille jails fully offline — no internet needed for jail setup
|
||||||
|
echo "Seeding jail pkg cache from USB..."
|
||||||
|
if zfs list zroot/pkg-cache >/dev/null 2>&1; then
|
||||||
|
PKG_CACHE_MOUNT=$(zfs get -H -o value mountpoint zroot/pkg-cache)
|
||||||
|
elif zfs list zroot >/dev/null 2>&1; then
|
||||||
|
zfs create -o mountpoint=/var/cache/pkg/bastille zroot/pkg-cache
|
||||||
|
PKG_CACHE_MOUNT="/var/cache/pkg/bastille"
|
||||||
|
else
|
||||||
|
PKG_CACHE_MOUNT="/var/cache/pkg/bastille"
|
||||||
|
mkdir -p "$PKG_CACHE_MOUNT"
|
||||||
|
fi
|
||||||
|
rsync -a --ignore-existing "${SHARE}/packages/All/" "${PKG_CACHE_MOUNT}/"
|
||||||
|
pkg repo "$PKG_CACHE_MOUNT"
|
||||||
|
echo " pkg cache seeded at ${PKG_CACHE_MOUNT}"
|
||||||
|
|
||||||
# --- extract clawdie-ai ---
|
# --- extract clawdie-ai ---
|
||||||
echo "Extracting Clawdie-AI..."
|
echo "Extracting Clawdie-AI..."
|
||||||
tar -xzf "${SHARE}/clawdie-ai.tar.gz" -C "$CLAWDIE_HOME"
|
tar -xzf "${SHARE}/clawdie-ai.tar.gz" -C "$CLAWDIE_HOME"
|
||||||
|
|
|
||||||
8
packages/pkg-list-desktop-base.txt
Normal file
8
packages/pkg-list-desktop-base.txt
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
# Xorg + GPU drivers base — required by all desktop environments
|
||||||
|
xorg-minimal
|
||||||
|
xf86-input-libinput
|
||||||
|
xf86-video-intel
|
||||||
|
drm-kmod
|
||||||
|
dbus
|
||||||
|
hal
|
||||||
|
desktop-installer
|
||||||
39
packages/pkg-list-host.txt
Normal file
39
packages/pkg-list-host.txt
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
# Clawdie-AI host baseline packages
|
||||||
|
# Mirrors infra/packages/host-baseline.txt from clawdie-ai
|
||||||
|
# Keep in sync when host-baseline.txt changes.
|
||||||
|
|
||||||
|
# Core
|
||||||
|
bash
|
||||||
|
git
|
||||||
|
bastille
|
||||||
|
node24
|
||||||
|
npm
|
||||||
|
tmux
|
||||||
|
bsddialog
|
||||||
|
|
||||||
|
# Python / tooling
|
||||||
|
python311
|
||||||
|
uv
|
||||||
|
ripgrep
|
||||||
|
fd
|
||||||
|
rsync
|
||||||
|
|
||||||
|
# DB client (host talks to db jail)
|
||||||
|
postgresql17-client
|
||||||
|
|
||||||
|
# Media / fonts
|
||||||
|
py311-pillow
|
||||||
|
dejavu
|
||||||
|
|
||||||
|
# Wayland display stack (desktop installs)
|
||||||
|
seatd
|
||||||
|
weston
|
||||||
|
cage
|
||||||
|
wayvnc
|
||||||
|
waypipe
|
||||||
|
xwayland
|
||||||
|
|
||||||
|
# bhyve VM management (optional, included for full offline capability)
|
||||||
|
vm-bhyve
|
||||||
|
grub2-bhyve
|
||||||
|
uefi-edk2-bhyve
|
||||||
31
packages/pkg-list-jails.txt
Normal file
31
packages/pkg-list-jails.txt
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
# Combined jail package list — union of all jail package lists from clawdie-ai
|
||||||
|
# Mirrors infra/packages/*-jail.txt (deduplicated)
|
||||||
|
# Keep in sync when jail package lists change.
|
||||||
|
|
||||||
|
# Shared across jails
|
||||||
|
bash
|
||||||
|
git
|
||||||
|
rsync
|
||||||
|
curl
|
||||||
|
|
||||||
|
# cms-jail
|
||||||
|
nginx
|
||||||
|
node24
|
||||||
|
npm
|
||||||
|
postgresql17-client
|
||||||
|
|
||||||
|
# db-jail
|
||||||
|
postgresql17-server
|
||||||
|
postgresql17-contrib
|
||||||
|
pgvector
|
||||||
|
|
||||||
|
# worker-jail
|
||||||
|
cage
|
||||||
|
chromium
|
||||||
|
|
||||||
|
# management-jail (observability)
|
||||||
|
victoria-metrics
|
||||||
|
grafana10
|
||||||
|
|
||||||
|
# ollama-jail (optional local inference)
|
||||||
|
ollama
|
||||||
4
packages/pkg-list-kde.txt
Normal file
4
packages/pkg-list-kde.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
# KDE Plasma desktop environment (full-featured, requires 8GB+ RAM)
|
||||||
|
plasma5-plasma
|
||||||
|
kde-baseapps
|
||||||
|
sddm
|
||||||
5
packages/pkg-list-mate.txt
Normal file
5
packages/pkg-list-mate.txt
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
# MATE desktop environment (lightweight alternative)
|
||||||
|
mate
|
||||||
|
mate-extra
|
||||||
|
lightdm
|
||||||
|
lightdm-gtk-greeter
|
||||||
3
packages/pkg-list-nvidia.txt
Normal file
3
packages/pkg-list-nvidia.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# NVIDIA GPU support (fetched when NVIDIA card detected at build time)
|
||||||
|
nvidia-driver
|
||||||
|
nvidia-settings
|
||||||
5
packages/pkg-list-xfce.txt
Normal file
5
packages/pkg-list-xfce.txt
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
# XFCE desktop environment (default)
|
||||||
|
xfce
|
||||||
|
xfce4-goodies
|
||||||
|
lightdm
|
||||||
|
lightdm-gtk-greeter
|
||||||
102
runner/README.md
Normal file
102
runner/README.md
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
# Forgejo Actions Runner — Self-Hosted FreeBSD Setup
|
||||||
|
|
||||||
|
The CI/CD pipeline (`.forgejo/workflows/build.yml`) requires a self-hosted
|
||||||
|
FreeBSD runner registered on Codeberg. The runner runs on the Clawdie
|
||||||
|
controlplane host — the same machine that hosts the Bastille jails.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pkg install forgejo-runner
|
||||||
|
```
|
||||||
|
|
||||||
|
If not in ports yet, download the binary directly:
|
||||||
|
```sh
|
||||||
|
fetch https://codeberg.org/forgejo/runner/releases/download/v3.5.0/forgejo-runner-3.5.0-freebsd-amd64
|
||||||
|
install -m 0755 forgejo-runner-3.5.0-freebsd-amd64 /usr/local/bin/forgejo-runner
|
||||||
|
```
|
||||||
|
|
||||||
|
## Register
|
||||||
|
|
||||||
|
1. Go to `https://codeberg.org/Clawdie/Clawdie-ISO` → Settings → Actions → Runners
|
||||||
|
2. Click "Create Runner" → copy the registration token
|
||||||
|
3. Run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
forgejo-runner register \
|
||||||
|
--url https://codeberg.org \
|
||||||
|
--token <REGISTRATION_TOKEN> \
|
||||||
|
--name clawdie-build \
|
||||||
|
--labels freebsd \
|
||||||
|
--no-interactive
|
||||||
|
```
|
||||||
|
|
||||||
|
## Runner user and sudo
|
||||||
|
|
||||||
|
The runner needs sudo access for the ISO assembly steps (mdconfig, mount).
|
||||||
|
Create a dedicated user and a scoped sudoers entry:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Create runner user
|
||||||
|
pw useradd forgejo-runner -m -s /bin/sh -G clawdie
|
||||||
|
|
||||||
|
# Add sudoers entry (only allows the two build scripts, nothing else)
|
||||||
|
cat >> /usr/local/etc/sudoers.d/forgejo-runner <<EOF
|
||||||
|
forgejo-runner ALL=(root) NOPASSWD: /home/clawdie/clawdie-iso/build.sh
|
||||||
|
forgejo-runner ALL=(root) NOPASSWD: /home/clawdie/clawdie-iso/scripts/publish.sh
|
||||||
|
EOF
|
||||||
|
chmod 440 /usr/local/etc/sudoers.d/forgejo-runner
|
||||||
|
```
|
||||||
|
|
||||||
|
## Enable as rc.d service
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sysrc forgejo_runner_enable=YES
|
||||||
|
sysrc forgejo_runner_dir="/home/forgejo-runner"
|
||||||
|
service forgejo-runner start
|
||||||
|
```
|
||||||
|
|
||||||
|
## rc.d service file
|
||||||
|
|
||||||
|
If not included in the pkg, create `/usr/local/etc/rc.d/forgejo-runner`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
#!/bin/sh
|
||||||
|
# PROVIDE: forgejo_runner
|
||||||
|
# REQUIRE: NETWORKING
|
||||||
|
# KEYWORD: shutdown
|
||||||
|
|
||||||
|
. /etc/rc.subr
|
||||||
|
|
||||||
|
name="forgejo_runner"
|
||||||
|
rcvar="${name}_enable"
|
||||||
|
: "${forgejo_runner_dir:=/home/forgejo-runner}"
|
||||||
|
: "${forgejo_runner_user:=forgejo-runner}"
|
||||||
|
|
||||||
|
command="/usr/local/bin/forgejo-runner"
|
||||||
|
command_args="daemon --config ${forgejo_runner_dir}/.runner"
|
||||||
|
procname="forgejo-runner"
|
||||||
|
|
||||||
|
start_precmd="forgejo_runner_precmd"
|
||||||
|
forgejo_runner_precmd() {
|
||||||
|
cd "${forgejo_runner_dir}" || exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
load_rc_config "$name"
|
||||||
|
run_rc_command "$1"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verify
|
||||||
|
|
||||||
|
```sh
|
||||||
|
service forgejo-runner status
|
||||||
|
# Runner should appear as "online" in Codeberg → Settings → Actions → Runners
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- The runner caches `packages/` and `cache/` between runs for speed
|
||||||
|
- The `--fetch-only` step runs without root; only assembly needs sudo
|
||||||
|
- Weekly scheduled builds re-fetch packages to pick up upstream updates
|
||||||
|
- Build artifacts (ISO) are NOT uploaded to Codeberg (too large) — published
|
||||||
|
directly to the CMS jail nginx downloads endpoint by `scripts/publish.sh`
|
||||||
Loading…
Add table
Reference in a new issue