#!/bin/sh # build-vps.sh — Build mfsBSD ISO with Clawdie-AI payload for VPS providers # # Usage: # ./build-vps.sh # full build # ./build-vps.sh --skip-fetch # use cached files # ./build-vps.sh --clawdie-version 0.9.0 # # Output: tmp/output/clawdie-vps-DD.mmm.YYYY.iso # # This ISO can be uploaded to: # - Vultr (Custom ISO) # - Any provider with ISO mount support # # After boot: # ssh -p 1022 mfsbsd@your-ip # Password: clawdie2026 # /usr/local/share/clawdie-iso/firstboot.sh set -e SCRIPT_DIR="$(dirname "$(realpath "$0")")" 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" MFSBSD_PASSWORD="clawdie2026" SSH_PORT="1022" # --- argument parsing --- SKIP_FETCH=0 while [ "$#" -gt 0 ]; do case "$1" in --clawdie-version) CLAWDIE_VERSION="$2"; shift 2 ;; --skip-fetch) SKIP_FETCH=1; shift ;; *) echo "Unknown arg: $1"; exit 1 ;; esac done echo "==> Clawdie-VPS ISO Build" echo " FreeBSD : mfsBSD 15.0-RELEASE" echo " Clawdie : v${CLAWDIE_VERSION}" echo " Password: ${MFSBSD_PASSWORD}" echo " SSH Port: ${SSH_PORT}" echo "" # --- step 1: fetch mfsBSD ISO --- MFSBSD_ISO="${CACHE_DIR}/mfsbsd-15.0-RELEASE-amd64.iso" if [ "$SKIP_FETCH" -eq 0 ] || [ ! -f "$MFSBSD_ISO" ]; then echo "==> [1/6] Downloading mfsBSD ISO..." mkdir -p "$CACHE_DIR" curl -L --progress-bar -o "$MFSBSD_ISO" "$MFSBSD_ISO_URL" echo " Done: $(du -sh "$MFSBSD_ISO" | cut -f1)" else echo "==> [1/6] mfsBSD ISO cached." fi # --- step 2: fetch Clawdie-AI tarball --- if [ "$CLAWDIE_VERSION" = "latest" ] || [ -z "$CLAWDIE_VERSION" ]; then echo "==> [2/6] Resolving latest Clawdie-AI version..." CLAWDIE_VERSION=$( curl -fsS "https://code.smilepowered.org/api/v1/repos/clawdie/clawdie-ai/releases?limit=20" 2>/dev/null \ | grep -o '"tag_name":"[^"]*"' \ | head -1 \ | cut -d'"' -f4 \ | sed 's/^v//' ) if [ -z "$CLAWDIE_VERSION" ]; then CLAWDIE_VERSION=$( git ls-remote --tags "https://code.smilepowered.org/clawdie/clawdie-ai.git" 2>/dev/null \ | awk -F/ '$2 == "tags" && $3 ~ /^v[0-9]+\.[0-9]+\.[0-9]+$/ { print $3 }' \ | sed 's/^v//' \ | sort -t. -k1,1n -k2,2n -k3,3n \ | tail -n 1 \ | sed 's/^v//' ) fi if [ -z "$CLAWDIE_VERSION" ]; then echo "ERROR: could not resolve latest Clawdie-AI release/tag from Forgejo." echo " Pin --clawdie-version X.Y.Z explicitly." exit 1 fi 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 "==> [2/6] Downloading Clawdie-AI v${CLAWDIE_VERSION}..." curl -L --progress-bar -o "$CLAWDIE_TARBALL" \ "https://code.smilepowered.org/clawdie/clawdie-ai/archive/v${CLAWDIE_VERSION}.tar.gz" else echo "==> [2/6] Clawdie-AI cached." fi # --- step 3: fetch packages (if not already done) --- 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 else echo "==> [3/6] Package bundle ready." PKG_BUNDLE=1 fi # --- step 4: extract and modify mfsBSD --- echo "==> [4/6] Extracting mfsBSD..." rm -rf "$ISO_WORK" mkdir -p "$ISO_WORK" # mfsBSD ISO is a standard ISO9660 - extract with bsdtar or mount # On FreeBSD: mdconfig + mount -t cd9660 # On Linux: mount -o loop if [ "$(uname)" = "FreeBSD" ]; then MD=$(mdconfig -f "$MFSBSD_ISO") mount -t cd9660 "/dev/${MD}" "${ISO_WORK}/mnt" cp -a "${ISO_WORK}/mnt/"* "${ISO_WORK}/" umount "${ISO_WORK}/mnt" mdconfig -d -u "$MD" else # Linux: use bsdtar to extract ISO tar -xf "$MFSBSD_ISO" -C "${ISO_WORK}" fi echo " Extracted to ${ISO_WORK}" # --- step 5: inject Clawdie payload --- echo "==> [5/6] Injecting Clawdie payload..." # Create clawdie-iso directory structure CLAWDIE_SHARE="${ISO_WORK}/usr/local/share/clawdie-iso" mkdir -p "$CLAWDIE_SHARE" # Copy firstboot scripts (both USB and VPS versions) cp -r "${SCRIPT_DIR}/firstboot" "${CLAWDIE_SHARE}/" cp "${SCRIPT_DIR}/build.cfg" "${CLAWDIE_SHARE}/" # Copy VPS-specific files if [ -d "${SCRIPT_DIR}/vps" ]; then cp "${SCRIPT_DIR}/vps/firstboot-vps.sh" "${CLAWDIE_SHARE}/firstboot-vps.sh" chmod +x "${CLAWDIE_SHARE}/firstboot-vps.sh" [ -f "${SCRIPT_DIR}/vps/setup.txt.tpl" ] && \ cp "${SCRIPT_DIR}/vps/setup.txt.tpl" "${CLAWDIE_SHARE}/setup.txt.tpl" [ -f "${SCRIPT_DIR}/vps/clawdie.conf.tpl" ] && \ cp "${SCRIPT_DIR}/vps/clawdie.conf.tpl" "${CLAWDIE_SHARE}/clawdie.conf.tpl" fi # Copy Clawdie-AI tarball cp "$CLAWDIE_TARBALL" "${CLAWDIE_SHARE}/clawdie-ai.tar.gz" # Copy packages if available 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 cat > "${ISO_WORK}/etc/rc.local" <<'EOF' #!/bin/sh # Clawdie-VPS rc.local - runs on mfsBSD boot # Ensure SSH is running service sshd onestart 2>/dev/null || /etc/rc.d/sshd onestart 2>/dev/null || true # Show welcome message on console cat > /etc/motd <<'MOTD' ╔═══════════════════════════════════════════════════════════════╗ ║ Clawdie-VPS (mfsBSD) ║ ╠═══════════════════════════════════════════════════════════════╣ ║ ║ ║ SSH: ssh -p 1022 mfsbsd@ ║ ║ Pass: clawdie2026 ║ ║ ║ ║ Then run the installer: ║ ║ /usr/local/share/clawdie-iso/firstboot-vps.sh ║ ║ ║ ║ For headless install, copy setup.txt.tpl to setup.txt ║ ║ and edit before running firstboot-vps.sh ║ ║ ║ ║ This will install FreeBSD + Clawdie-AI to disk. ║ ║ ALL DATA ON DISK WILL BE ERASED. ║ ║ ║ ╚═══════════════════════════════════════════════════════════════╝ MOTD # Also log to console echo "" echo "Clawdie-VPS ready. SSH to port 1022, password: clawdie2026" echo "Run: /usr/local/share/clawdie-iso/firstboot-vps.sh" echo "" EOF chmod +x "${ISO_WORK}/etc/rc.local" # Set root password in mfsBSD # mfsBSD uses /etc/master.passwd - we need to hash the password if [ "$(uname)" = "FreeBSD" ]; then HASH=$(encrypt -p "$MFSBSD_PASSWORD" | tail -1) else # Linux: use openssl HASH=$(openssl passwd -6 "$MFSBSD_PASSWORD") fi # Portable sed -i: FreeBSD requires '' as separate arg, GNU does not if [ "$(uname)" = "FreeBSD" ]; then _sed_i() { sed -i '' "$@"; } else _sed_i() { sed -i "$@"; } fi # Update password in mfsBSD's password file if [ -f "${ISO_WORK}/etc/master.passwd" ]; then _sed_i "s|^root:[^:]*:|root:${HASH}:|" "${ISO_WORK}/etc/master.passwd" fi # Configure SSH to listen on port 1022 if [ -f "${ISO_WORK}/etc/ssh/sshd_config" ]; then _sed_i 's/^#*Port .*/Port 1022/' "${ISO_WORK}/etc/ssh/sshd_config" grep -q "^Port " "${ISO_WORK}/etc/ssh/sshd_config" || echo "Port 1022" >> "${ISO_WORK}/etc/ssh/sshd_config" fi # Enable SSH in rc.conf echo 'sshd_enable="YES"' >> "${ISO_WORK}/etc/rc.conf" echo " Payload injected." # --- step 6: repack ISO --- echo "==> [6/6] Repacking ISO..." mkdir -p "$OUTPUT_DIR" 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 genisoimage -o "$OUTPUT_ISO" -b boot/cdboot -no-emul-boot \ -J -R -V "CLAWDIE_VPS" "$ISO_WORK" elif command -v mkisofs >/dev/null 2>&1; then mkisofs -o "$OUTPUT_ISO" -b boot/cdboot -no-emul-boot \ -J -R -V "CLAWDIE_VPS" "$ISO_WORK" else echo "ERROR: Neither genisoimage nor mkisofs found." echo "Install: apt install genisoimage OR pkg install cdrtools" exit 1 fi # Cleanup rm -rf "$ISO_WORK" echo "" echo "============================================" echo " Build complete!" echo "" echo " Output: ${OUTPUT_ISO}" echo " Size: $(du -sh "$OUTPUT_ISO" | cut -f1)" echo "" echo " Upload to Vultr:" echo " 1. Go to Server → Settings → Custom ISO" echo " 2. Upload ${OUTPUT_ISO}" echo " 3. Reboot server" echo "" echo " After boot:" echo " ssh -p 1022 mfsbsd@" echo " Password: ${MFSBSD_PASSWORD}" echo "" echo " Then run:" echo " /usr/local/share/clawdie-iso/firstboot-vps.sh" echo "" echo " For headless install:" echo " cp /usr/local/share/clawdie-iso/setup.txt.tpl \\" echo " /usr/local/share/clawdie-iso/setup.txt" echo " # Edit setup.txt, then:" echo " /usr/local/share/clawdie-iso/firstboot-vps.sh" echo "============================================"