284 lines
8.9 KiB
Bash
Executable File
284 lines
8.9 KiB
Bash
Executable File
#!/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-43"
|
|
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
|