261 lines
9 KiB
Bash
Executable file
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 "============================================"
|