From 65ea26f6dac9c04ca41d49acd4db30dac201de21 Mon Sep 17 00:00:00 2001 From: jedarden Date: Wed, 17 Jun 2026 00:29:29 -0400 Subject: [PATCH] Replace setup-r2.sh with setup-b2.sh - Delete scripts/setup-r2.sh (Cloudflare R2 is not the storage provider) - Create scripts/setup-b2.sh that documents B2 CDN setup: - Prints B2 bucket endpoint (us-west-002) - Prints CNAME target for b2.aicodebattle.com - Verifies B2 credentials when env vars are set - Informational/verification-only (no destructive operations) - Update scripts/cloudflare-setup.sh: - Remove R2 bucket creation steps - Add note that B2 setup is separate (see setup-b2.sh) Acceptance criteria met: - scripts/setup-r2.sh does not exist - scripts/setup-b2.sh exists, is executable, and runs without error - No references to setup-r2 remain in scripts/ --- scripts/cloudflare-setup.sh | 28 +++--- scripts/setup-b2.sh | 161 +++++++++++++++++++++++++++++++ scripts/setup-r2.sh | 184 ------------------------------------ 3 files changed, 172 insertions(+), 201 deletions(-) create mode 100755 scripts/setup-b2.sh delete mode 100755 scripts/setup-r2.sh diff --git a/scripts/cloudflare-setup.sh b/scripts/cloudflare-setup.sh index ec049c2..9e6cf0d 100755 --- a/scripts/cloudflare-setup.sh +++ b/scripts/cloudflare-setup.sh @@ -33,16 +33,6 @@ echo "=== Step 2: Deploying web/dist to Pages ===" ~/.local/bin/wrangler pages deploy web/dist --project-name=aicodebattle --commit-dirty=true echo "" -# Step 3: Create R2 bucket -echo "=== Step 3: Creating R2 bucket 'acb-data' ===" -if ~/.local/bin/wrangler r2 bucket list 2>/dev/null | grep -q "acb-data"; then - echo "R2 bucket 'acb-data' already exists." -else - echo "Creating R2 bucket..." - ~/.local/bin/wrangler r2 bucket create acb-data -fi -echo "" - echo "=== Automated setup complete! ===" echo "" echo "=== MANUAL STEPS REQUIRED (Cloudflare Dashboard) ===" @@ -52,15 +42,19 @@ echo " - Go to: Workers & Pages > aicodebattle > Settings > Custom domains" echo " - Add domain: aicodebattle.com" echo " - This auto-configures DNS CNAME" echo "" -echo "2. Configure Custom Domain for R2:" -echo " - Go to: R2 > acb-data > Settings > Custom Domains" -echo " - Add domain: r2.aicodebattle.com" -echo " - This auto-configures DNS CNAME" -echo "" -echo "3. Configure API DNS (requires Traefik LoadBalancer IP):" +echo "2. Configure API DNS (requires Traefik LoadBalancer IP):" echo " - Go to: DNS > Records" echo " - Add A record: api.aicodebattle.com -> (proxied)" echo "" -echo "4. Get Traefik IP from Kubernetes:" +echo "3. Get Traefik IP from Kubernetes:" echo " kubectl --server=http://kubectl-apexalgo-iad:8001 get svc -n traefik" echo "" +echo "=== B2 CDN Setup (Separate from Cloudflare) ===" +echo "" +echo "B2 storage setup is documented separately. See ./scripts/setup-b2.sh for:" +echo " - B2 bucket endpoint information" +echo " - CNAME configuration for b2.aicodebattle.com" +echo " - B2 API authentication verification" +echo "" +echo "Run: ./scripts/setup-b2.sh" +echo "" diff --git a/scripts/setup-b2.sh b/scripts/setup-b2.sh new file mode 100755 index 0000000..af58513 --- /dev/null +++ b/scripts/setup-b2.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env bash +# B2 CDN Setup Information for AI Code Battle +# Prints B2 bucket endpoint, CNAME target, and verifies credentials +# +# Prerequisites: +# - B2_ENDPOINT environment variable set (or reads from cluster secret) +# - B2_KEY_ID environment variable set +# - B2_APPLICATION_KEY environment variable set +# - kubectl configured with access to apexalgo-iad cluster (for secret fallback) +# +# Usage: +# ./scripts/setup-b2.sh + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Configuration +BUCKET_NAME="acb-data" +REGION="us-west-002" +B2_ENDPOINT="${B2_ENDPOINT:-https://s3.us-west-002.backblazeb2.com}" +CUSTOM_DOMAIN="b2.aicodebattle.com" +CNAME_TARGET="${BUCKET_NAME}.s3.${REGION}.backblazeb2.com" + +echo -e "${BLUE}=== AI Code Battle - B2 CDN Setup Information ===${NC}" +echo "" + +# Try to get credentials from environment variables first +if [ -n "$B2_KEY_ID" ] && [ -n "$B2_APPLICATION_KEY" ]; then + echo -e "${GREEN}✓ Using B2 credentials from environment variables${NC}" + USE_ENV_CREDENTIALS=true +else + echo -e "${YELLOW}⚠ B2_KEY_ID and B2_APPLICATION_KEY not set in environment${NC}" + echo "Attempting to read from cluster secret..." + USE_ENV_CREDENTIALS=false + + # Try to read from Kubernetes secret (requires cluster access) + if kubectl --server=http://traefik-apexalgo-iad:8001 get secret backblaze-secret -n ai-code-battle &>/dev/null; then + echo -e "${YELLOW}⚠ Cannot read secret values via read-only kubectl proxy${NC}" + echo " To test B2 API authentication, set environment variables:" + echo " export B2_KEY_ID=" + echo " export B2_APPLICATION_KEY=" + echo "" + fi +fi + +# Step 1: Print B2 bucket endpoint +echo -e "${BLUE}Step 1: B2 Bucket Endpoint${NC}" +echo "" +echo " Bucket Name: ${BUCKET_NAME}" +echo " Region: ${REGION}" +echo " S3 Endpoint: ${B2_ENDPOINT}" +echo " Friendly Endpoint: f002.backblazeb2.com" +echo "" + +# Step 2: Print CNAME configuration +echo -e "${BLUE}Step 2: Required CNAME Configuration${NC}" +echo "" +echo " Type: CNAME" +echo " Name: ${CUSTOM_DOMAIN}" +echo " Target: ${CNAME_TARGET}" +echo " Proxy: On (orange cloud) ← REQUIRED for Bandwidth Alliance" +echo " TTL: Auto (3600)" +echo "" + +# Step 3: Verify B2 credentials (if available) +echo -e "${BLUE}Step 3: B2 API Authentication Verification${NC}" +echo "" + +if [ "$USE_ENV_CREDENTIALS" = true ]; then + echo "Testing B2 API authentication..." + AUTH_RESPONSE=$(curl -s -u "${B2_KEY_ID}:${B2_APPLICATION_KEY}" "${B2_ENDPOINT}/b2api/v2/b2_authorize_account" 2>&1) + + if echo "$AUTH_RESPONSE" | jq -e '.accountId' > /dev/null 2>&1; then + echo -e "${GREEN}✓ B2 API authentication successful${NC}" + echo "" + echo "Account Details:" + echo " Account ID: $(echo "$AUTH_RESPONSE" | jq -r '.accountId')" + echo " API URL: $(echo "$AUTH_RESPONSE" | jq -r '.apiUrl')" + echo " Download URL: $(echo "$AUTH_RESPONSE" | jq -r '.downloadUrl')" + echo "" + echo "Allowed Capabilities:" + echo "$AUTH_RESPONSE" | jq -r '.allowed.capabilities[]' | sed 's/^/ - /' + else + echo -e "${RED}✗ B2 API authentication failed${NC}" + echo "Response:" + echo "$AUTH_RESPONSE" + exit 1 + fi +else + echo -e "${YELLOW}⚠ Skipping authentication test (credentials not available)${NC}" + echo "" + echo "To test B2 API authentication, set the following environment variables:" + echo " export B2_ENDPOINT=${B2_ENDPOINT}" + echo " export B2_KEY_ID=" + echo " export B2_APPLICATION_KEY=" + echo "" + echo "Then run this script again." +fi + +echo "" + +# Step 4: Print expected URLs +echo -e "${BLUE}Step 4: Expected URLs After Configuration${NC}" +echo "" +echo "Once the CNAME is configured and public access is enabled:" +echo "" +echo " Replay files:" +echo " https://${CUSTOM_DOMAIN}/replays/{match_id}.json.gz" +echo "" +echo " Match metadata:" +echo " https://${CUSTOM_DOMAIN}/matches/{match_id}.json" +echo "" +echo " Evolution feed:" +echo " https://${CUSTOM_DOMAIN}/evolution/live.json" +echo "" +echo " Bot cards:" +echo " https://${CUSTOM_DOMAIN}/bots/{bot_id}.json" +echo "" + +# Step 5: Print manual setup steps +echo -e "${BLUE}Step 5: Manual Setup Steps${NC}" +echo "" +echo "This script is informational only. To complete B2 CDN setup:" +echo "" +echo "1. Enable Public Access on B2 Bucket:" +echo " - Go to: https://secure.backblaze.com/sign_in.htm" +echo " - Navigate to: B2 Cloud Storage > Buckets > ${BUCKET_NAME}" +echo " - Settings > Bucket Info > Files in Bucket are: Public" +echo "" +echo "2. Create CNAME Record in Cloudflare:" +echo " - Type: CNAME" +echo " - Name: b2" +echo " - Target: ${CNAME_TARGET}" +echo " - Proxy: On (orange cloud) ← REQUIRED for Bandwidth Alliance" +echo "" +echo "3. Verify CNAME Resolution:" +echo " dig +short ${CUSTOM_DOMAIN}" +echo " # Expected: ${CNAME_TARGET}" +echo "" +echo "4. Test CDN Access:" +echo " curl -I https://${CUSTOM_DOMAIN}/" +echo " # Should return 404 from B2 (bucket public but file not found)" +echo "" +echo "5. Verify Bandwidth Alliance:" +echo " - Cloudflare Dashboard → Traffic → Bandwidth Alliance" +echo " - Should show Backblaze as active partner" +echo "" + +echo -e "${BLUE}=== B2 CDN Setup Information Complete ===${NC}" +echo "" +echo -e "${GREEN}Next Steps:${NC}" +echo " 1. Enable public access on B2 bucket" +echo " 2. Create CNAME record in Cloudflare DNS" +echo " 3. Test CDN access with curl" +echo "" diff --git a/scripts/setup-r2.sh b/scripts/setup-r2.sh deleted file mode 100755 index cd1259d..0000000 --- a/scripts/setup-r2.sh +++ /dev/null @@ -1,184 +0,0 @@ -#!/bin/bash -# R2 Bucket Setup Script for AI Code Battle -# Creates R2 bucket and configures custom domain -# -# Prerequisites: -# - wrangler CLI installed and authenticated -# - CLOUDFLARE_API_TOKEN set (for custom domain configuration) -# - CLOUDFLARE_ACCOUNT_ID set (optional, will auto-detect) -# -# Usage: -# ./scripts/setup-r2.sh - -set -e - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -# Configuration -BUCKET_NAME="acb-data" -CUSTOM_DOMAIN="r2.aicodebattle.com" -DOMAIN="aicodebattle.com" - -echo -e "${BLUE}=== AI Code Battle - R2 Bucket Setup ===${NC}" -echo "" - -# Step 1: Check wrangler authentication -echo -e "${BLUE}Step 1: Checking wrangler authentication...${NC}" -if ! ~/.local/bin/wrangler whoami &>/dev/null; then - echo -e "${RED}ERROR: Not authenticated with Cloudflare.${NC}" - echo "Run: ~/.local/bin/wrangler login" - exit 1 -fi - -echo -e "${GREEN}Authenticated as:${NC}" -~/.local/bin/wrangler whoami -echo "" - -# Get account ID -ACCOUNT_ID=$(~/.local/bin/wrangler whoami 2>/dev/null | grep "Account ID" | awk '{print $3}' | tr -d '()"') -if [ -z "$ACCOUNT_ID" ]; then - # Try alternative parsing - ACCOUNT_ID=$(~/.local/bin/wrangler whoami 2>/dev/null | grep -oP 'Account ID:\s*\K[0-9a-f-]+' || true) -fi - -if [ -n "$ACCOUNT_ID" ]; then - echo -e "${GREEN}Account ID: $ACCOUNT_ID${NC}" -else - echo -e "${YELLOW}Could not auto-detect Account ID${NC}" - if [ -z "$CLOUDFLARE_ACCOUNT_ID" ]; then - echo "Set CLOUDFLARE_ACCOUNT_ID environment variable to proceed." - else - ACCOUNT_ID="$CLOUDFLARE_ACCOUNT_ID" - echo -e "${GREEN}Using CLOUDFLARE_ACCOUNT_ID: $ACCOUNT_ID${NC}" - fi -fi -echo "" - -# Step 2: Create R2 bucket -echo -e "${BLUE}Step 2: Creating R2 bucket '$BUCKET_NAME'...${NC}" -if ~/.local/bin/wrangler r2 bucket list 2>/dev/null | grep -q "$BUCKET_NAME"; then - echo -e "${YELLOW}R2 bucket '$BUCKET_NAME' already exists.${NC}" -else - echo "Creating R2 bucket..." - ~/.local/bin/wrangler r2 bucket create "$BUCKET_NAME" - echo -e "${GREEN}✓ R2 bucket '$BUCKET_NAME' created.${NC}" -fi -echo "" - -# Step 3: Configure custom domain -echo -e "${BLUE}Step 3: Configuring custom domain '$CUSTOM_DOMAIN'...${NC}" - -if [ -z "$CLOUDFLARE_API_TOKEN" ]; then - echo -e "${YELLOW}WARNING: CLOUDFLARE_API_TOKEN not set${NC}" - echo "Custom domain configuration requires manual setup via Cloudflare Dashboard:" - echo "" - echo "1. Go to: https://dash.cloudflare.com/" - echo "2. Navigate to: R2 > $BUCKET_NAME > Settings > Custom Domains" - echo "3. Add domain: $CUSTOM_DOMAIN" - echo "" - echo "Get your API token from: https://dash.cloudflare.com/profile/api-tokens" - echo "Required permissions: Account > Cloudflare Pages > Edit" - echo "" - echo "Then run: CLOUDFLARE_API_TOKEN=your_token $0" - echo "" -else - echo "Using Cloudflare API to configure custom domain..." - - # Cloudflare API base URL - CF_API="https://api.cloudflare.com/client/v4" - - # Use the account ID we found - if [ -z "$ACCOUNT_ID" ]; then - echo -e "${RED}ERROR: Could not determine Account ID${NC}" - echo "Set CLOUDFLARE_ACCOUNT_ID environment variable." - exit 1 - fi - - # Function to make authenticated API calls - cf_api() { - local method=$1 - local endpoint=$2 - local data=$3 - - if [ -n "$data" ]; then - curl -s -X "$method" "${CF_API}${endpoint}" \ - -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ - -H "Content-Type: application/json" \ - -d "$data" - else - curl -s -X "$method" "${CF_API}${endpoint}" \ - -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ - -H "Content-Type: application/json" - fi - } - - # Check if custom domain already exists for this bucket - echo "Checking existing custom domains..." - EXISTING_DOMAINS=$(cf_api GET "/accounts/$ACCOUNT_ID/r2/buckets/$BUCKET_NAME/custom_domains") - - # Check if our domain is already configured - if echo "$EXISTING_DOMAINS" | jq -e '.result[] | select(.domain == "'$CUSTOM_DOMAIN'")' > /dev/null 2>&1; then - echo -e "${YELLOW}Custom domain '$CUSTOM_DOMAIN' already configured.${NC}" - - # Get current status - STATUS=$(echo "$EXISTING_DOMAINS" | jq -r '.result[] | select(.domain == "'$CUSTOM_DOMAIN'") | .status // "unknown"') - echo "Status: $STATUS" - - if [ "$STATUS" = "active" ]; then - echo -e "${GREEN}✓ Custom domain is active and ready!${NC}" - else - echo -e "${YELLOW}Custom domain configuration in progress. Check dashboard for status.${NC}" - fi - else - echo "Adding custom domain '$CUSTOM_DOMAIN' to bucket '$BUCKET_NAME'..." - - # Add custom domain via API - RESPONSE=$(cf_api POST "/accounts/$ACCOUNT_ID/r2/buckets/$BUCKET_NAME/custom_domains" \ - "{\"domain\": \"$CUSTOM_DOMAIN\"}") - - SUCCESS=$(echo "$RESPONSE" | jq -r '.success // false') - if [ "$SUCCESS" = "true" ]; then - echo -e "${GREEN}✓ Custom domain '$CUSTOM_DOMAIN' configured successfully!${NC}" - echo "" - echo "DNS Configuration:" - echo " CNAME: $CUSTOM_DOMAIN -> $BUCKET_NAME.r2.cloudflarestorage.com" - echo "" - echo "The custom domain will be ready once DNS propagates." - echo "Check status at: https://dash.cloudflare.com/$ACCOUNT_ID/r2/$BUCKET_NAME/custom_domains" - else - ERRORS=$(echo "$RESPONSE" | jq -r '.errors[0].message // "Unknown error"') - echo -e "${RED}✗ Failed to configure custom domain: $ERRORS${NC}" - echo "" - echo "Manual configuration required:" - echo "1. Go to: R2 > $BUCKET_NAME > Settings > Custom Domains" - echo "2. Add domain: $CUSTOM_DOMAIN" - fi - fi -fi - -echo "" -echo -e "${BLUE}=== R2 Bucket Setup Summary ===${NC}" -echo "" -echo "Bucket: $BUCKET_NAME" -echo "Custom Domain: $CUSTOM_DOMAIN" -echo "" -echo "Expected R2 data layout:" -echo " replays/{match_id}.json.gz - Recent replay files" -echo " matches/{match_id}.json - Recent per-match metadata" -echo " thumbnails/{match_id}.png - Match thumbnails" -echo " cards/{bot_id}.png - Bot profile cards" -echo " evolution/live.json - Evolution live feed" -echo "" -echo "Public URL: https://$CUSTOM_DOMAIN/" -echo "" -echo -e "${GREEN}=== Setup Complete! ===${NC}" -echo "" -echo "Verification commands:" -echo " ~/.local/bin/wrangler r2 bucket list" -echo " curl -I https://$CUSTOM_DOMAIN/" -echo ""