feat: build-bleeding.sh — Arch Linux Docker on Fedora VM for bleeding edge builds
VM: fc-bleeding (Fedora 41), Build: archlinux:latest Docker container Output: target/linux-x86_64-bleeding/ No conflict with fc-builder (build-linux.sh) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
283
warzone/scripts/build-bleeding.sh
Executable file
283
warzone/scripts/build-bleeding.sh
Executable file
@@ -0,0 +1,283 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Build featherChat Linux x86_64 bleeding-edge binaries on Hetzner Cloud.
|
||||
# Uses latest Fedora VM + Arch Linux Docker container for the actual build.
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/build-bleeding.sh --all Create VM + build + download
|
||||
# ./scripts/build-bleeding.sh --ship Build + deploy to all servers + destroy
|
||||
# ./scripts/build-bleeding.sh --prepare Create VM only
|
||||
# ./scripts/build-bleeding.sh --build Build in Arch Docker container
|
||||
# ./scripts/build-bleeding.sh --transfer Download binaries
|
||||
# ./scripts/build-bleeding.sh --destroy Delete VM
|
||||
|
||||
VM_NAME="fc-bleeding"
|
||||
SSH_KEY_NAME="wz"
|
||||
SSH_KEY_PATH="/Users/manwe/CascadeProjects/wzp"
|
||||
SERVER_TYPE="cx33"
|
||||
IMAGE="fedora-41"
|
||||
REMOTE_USER="root"
|
||||
OUTPUT_DIR="target/linux-x86_64-bleeding"
|
||||
PROJECT_DIR="/Users/manwe/CascadeProjects/featherChat/warzone"
|
||||
|
||||
SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=10"
|
||||
BINS="warzone-server warzone-client"
|
||||
|
||||
# Production servers (shared with build-linux.sh)
|
||||
PROD_SERVERS=("root@mequ" "root@kh3rad3ree")
|
||||
PROD_SERVICE="warzone-server"
|
||||
PROD_BIN_DIR="/home/warzone"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
get_vm_ip() {
|
||||
local ip
|
||||
ip=$(hcloud server list -o columns=name,ipv4 -o noheader 2>/dev/null | grep "$VM_NAME" | awk '{print $2}' | tr -d ' ')
|
||||
if [ -z "$ip" ]; then
|
||||
echo "ERROR: No VM '$VM_NAME' found. Run --prepare first." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "$ip"
|
||||
}
|
||||
|
||||
ssh_cmd() {
|
||||
local ip
|
||||
ip=$(get_vm_ip)
|
||||
ssh $SSH_OPTS -i "$SSH_KEY_PATH" "$REMOTE_USER@$ip" "$@"
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# --prepare: Create Fedora VM, install Docker
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
do_prepare() {
|
||||
local existing
|
||||
existing=$(hcloud server list -o columns=name -o noheader 2>/dev/null | grep "$VM_NAME" || true)
|
||||
if [ -n "$existing" ]; then
|
||||
echo "VM already exists: $existing"
|
||||
echo "Reusing it. Uploading fresh source..."
|
||||
do_upload
|
||||
return
|
||||
fi
|
||||
|
||||
echo "[1/5] Creating Hetzner VM: $VM_NAME ($SERVER_TYPE, $IMAGE)..."
|
||||
hcloud server create \
|
||||
--name "$VM_NAME" \
|
||||
--type "$SERVER_TYPE" \
|
||||
--image "$IMAGE" \
|
||||
--ssh-key "$SSH_KEY_NAME" \
|
||||
--location fsn1 \
|
||||
--quiet
|
||||
|
||||
local ip
|
||||
ip=$(get_vm_ip)
|
||||
echo " VM: $VM_NAME @ $ip"
|
||||
|
||||
echo "[2/5] Waiting for SSH..."
|
||||
for i in $(seq 1 30); do
|
||||
if ssh $SSH_OPTS -i "$SSH_KEY_PATH" "$REMOTE_USER@$ip" "echo ok" &>/dev/null; then
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "[3/5] Installing Docker on Fedora..."
|
||||
ssh_cmd "dnf install -y -q docker > /dev/null 2>&1 && systemctl start docker && systemctl enable docker" 2>/dev/null
|
||||
|
||||
echo "[4/5] Pulling Arch Linux Docker image..."
|
||||
ssh_cmd "docker pull archlinux:latest" 2>/dev/null
|
||||
|
||||
echo "[5/5] Uploading source..."
|
||||
do_upload
|
||||
|
||||
echo ""
|
||||
echo "=== VM Ready ==="
|
||||
echo "IP: $ip"
|
||||
echo "Next: ./scripts/build-bleeding.sh --build"
|
||||
}
|
||||
|
||||
do_upload() {
|
||||
echo " Creating source tarball..."
|
||||
tar czf /tmp/fc-bleeding-src.tar.gz \
|
||||
--exclude='target' \
|
||||
--exclude='.git' \
|
||||
--exclude='.claude' \
|
||||
--exclude='warzone-phone' \
|
||||
--exclude='notes' \
|
||||
-C "$PROJECT_DIR" . 2>/dev/null
|
||||
|
||||
local ip
|
||||
ip=$(get_vm_ip)
|
||||
local size
|
||||
size=$(du -h /tmp/fc-bleeding-src.tar.gz | cut -f1)
|
||||
echo " Uploading $size to VM..."
|
||||
scp $SSH_OPTS -i "$SSH_KEY_PATH" /tmp/fc-bleeding-src.tar.gz "$REMOTE_USER@$ip:/root/fc-bleeding-src.tar.gz" 2>/dev/null
|
||||
ssh_cmd "rm -rf /root/featherChat && mkdir -p /root/featherChat && tar xzf /root/fc-bleeding-src.tar.gz -C /root/featherChat" 2>/dev/null
|
||||
rm -f /tmp/fc-bleeding-src.tar.gz
|
||||
echo " Source uploaded."
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# --build: Build inside Arch Linux Docker container
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
do_build() {
|
||||
local ip
|
||||
ip=$(get_vm_ip)
|
||||
echo "=== Bleeding Edge Build on $ip ==="
|
||||
echo " Host: Fedora ($IMAGE)"
|
||||
echo " Build: Arch Linux (Docker, latest)"
|
||||
echo ""
|
||||
|
||||
echo "[1/3] Building in Arch Linux container..."
|
||||
ssh_cmd "docker run --rm -v /root/featherChat:/build -w /build archlinux:latest bash -c '
|
||||
# Install deps
|
||||
pacman -Sy --noconfirm base-devel pkg-config openssl rustup wasm-pack > /dev/null 2>&1
|
||||
rustup default stable 2>/dev/null
|
||||
rustup target add wasm32-unknown-unknown 2>/dev/null
|
||||
|
||||
# Build WASM
|
||||
echo \"[wasm] Building...\"
|
||||
wasm-pack build crates/warzone-wasm --target web --out-dir ../../wasm-pkg 2>&1 | tail -3
|
||||
|
||||
# Build release binaries
|
||||
echo \"[cargo] Building release...\"
|
||||
cargo build --release --bin warzone-server --bin warzone-client 2>&1
|
||||
'"
|
||||
|
||||
echo ""
|
||||
echo "[2/3] Verifying binaries..."
|
||||
ssh_cmd "ls -lh /root/featherChat/target/release/warzone-server /root/featherChat/target/release/warzone-client"
|
||||
|
||||
echo ""
|
||||
echo "[3/3] Checking linked libraries..."
|
||||
ssh_cmd "docker run --rm -v /root/featherChat:/build archlinux:latest ldd /build/target/release/warzone-server | head -10"
|
||||
|
||||
echo ""
|
||||
echo "=== Build Complete ==="
|
||||
echo "Next: ./scripts/build-bleeding.sh --transfer"
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# --transfer: Download binaries
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
do_transfer() {
|
||||
local ip
|
||||
ip=$(get_vm_ip)
|
||||
echo "=== Downloading bleeding-edge binaries from $ip ==="
|
||||
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
for bin in $BINS; do
|
||||
echo " $bin..."
|
||||
scp $SSH_OPTS -i "$SSH_KEY_PATH" "$REMOTE_USER@$ip:/root/featherChat/target/release/$bin" "$OUTPUT_DIR/$bin" 2>/dev/null
|
||||
done
|
||||
|
||||
# Copy federation example
|
||||
scp $SSH_OPTS -i "$SSH_KEY_PATH" "$REMOTE_USER@$ip:/root/featherChat/federation.example.json" "$OUTPUT_DIR/" 2>/dev/null || true
|
||||
|
||||
echo ""
|
||||
echo "=== Transfer Complete ==="
|
||||
ls -lh "$OUTPUT_DIR"/warzone-*
|
||||
echo ""
|
||||
echo "Built with: Arch Linux latest (bleeding edge)"
|
||||
echo "Deploy: scp $OUTPUT_DIR/warzone-server $OUTPUT_DIR/warzone-client user@server:~/warzone/"
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# --destroy
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
do_destroy() {
|
||||
local existing
|
||||
existing=$(hcloud server list -o columns=name -o noheader 2>/dev/null | grep "$VM_NAME" || true)
|
||||
if [ -z "$existing" ]; then
|
||||
echo "No VM '$VM_NAME' to destroy."
|
||||
return
|
||||
fi
|
||||
echo "Deleting VM: $VM_NAME"
|
||||
hcloud server delete "$VM_NAME"
|
||||
echo "Done."
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# --update-all / --ship
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
do_update() {
|
||||
local host="$1"
|
||||
echo "=== Updating $host (bleeding) ==="
|
||||
ssh "$host" "systemctl stop $PROD_SERVICE 2>/dev/null || true"
|
||||
scp "$OUTPUT_DIR/warzone-server" "$OUTPUT_DIR/warzone-client" "$host:$PROD_BIN_DIR/"
|
||||
ssh "$host" "chmod +x $PROD_BIN_DIR/warzone-server $PROD_BIN_DIR/warzone-client && systemctl start $PROD_SERVICE"
|
||||
sleep 1
|
||||
local status
|
||||
status=$(ssh "$host" "systemctl is-active $PROD_SERVICE 2>/dev/null" || true)
|
||||
echo " $host: $status"
|
||||
}
|
||||
|
||||
do_update_all() {
|
||||
for host in "${PROD_SERVERS[@]}"; do
|
||||
do_update "$host"
|
||||
done
|
||||
}
|
||||
|
||||
do_ship() {
|
||||
echo "========================================"
|
||||
echo " SHIPPING (bleeding edge) to production"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
do_prepare
|
||||
echo ""
|
||||
do_build
|
||||
echo ""
|
||||
do_transfer
|
||||
echo ""
|
||||
do_update_all
|
||||
echo ""
|
||||
do_destroy
|
||||
echo ""
|
||||
echo "========================================"
|
||||
echo " BLEEDING EDGE SHIP COMPLETE"
|
||||
echo "========================================"
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Main
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
case "${1:-}" in
|
||||
--prepare) do_prepare ;;
|
||||
--build) do_build ;;
|
||||
--transfer) do_transfer ;;
|
||||
--destroy) do_destroy ;;
|
||||
--upload) do_upload ;;
|
||||
--all)
|
||||
do_prepare
|
||||
do_build
|
||||
do_transfer
|
||||
echo "VM still running. Destroy: ./scripts/build-bleeding.sh --destroy"
|
||||
;;
|
||||
--ship) do_ship ;;
|
||||
--update-all) do_update_all ;;
|
||||
*)
|
||||
echo "Usage: $0 <command>"
|
||||
echo ""
|
||||
echo " --all Create Fedora VM + build in Arch Docker + download"
|
||||
echo " --ship Build + deploy to all servers + destroy VM"
|
||||
echo " --prepare Create VM, install Docker, upload source"
|
||||
echo " --build Build in Arch Linux Docker container"
|
||||
echo " --transfer Download binaries to $OUTPUT_DIR"
|
||||
echo " --destroy Delete the VM"
|
||||
echo " --upload Re-upload source to existing VM"
|
||||
echo " --update-all Deploy bleeding binaries to all servers"
|
||||
echo ""
|
||||
echo "Output: $OUTPUT_DIR/warzone-{server,client}"
|
||||
echo "Host VM: Fedora latest | Build: Arch Linux latest (Docker)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user