clawdie-iso/build-vps.sh

261 lines
9 KiB
Bash
Executable file

#!/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 -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 "==> [2/6] Downloading Clawdie-AI v${CLAWDIE_VERSION}..."
curl -L --progress-bar -o "$CLAWDIE_TARBALL" \
"https://codeberg.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@<this-ip> ║
║ 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@<your-vps-ip>"
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 "============================================"