Implements comprehensive automated system for weekly transaction freeze periods with priority-based contested player resolution. New Features: - Weekly freeze/thaw task (Monday 00:00 freeze, Saturday 00:00 thaw) - Priority resolution for contested transactions (worst teams get first priority) - Admin league management commands (/freeze-begin, /freeze-end, /advance-week) - Enhanced API client to handle string-based transaction IDs (moveids) - Service layer methods for transaction cancellation, unfreezing, and bulk operations - Offseason mode configuration flag to disable freeze operations Technical Changes: - api/client.py: URL-encode object_id parameter to handle colons in moveids - bot.py: Initialize and shutdown transaction freeze task - config.py: Add offseason_flag to BotConfig - services/league_service.py: Add update_current_state() for week/freeze updates - services/transaction_service.py: Add cancel/unfreeze methods with bulk support - tasks/transaction_freeze.py: Main freeze/thaw automation with error recovery - commands/admin/league_management.py: Manual admin controls for freeze system Infrastructure: - .gitlab-ci.yml and .gitlab/: GitLab CI/CD pipeline configuration - .mcp.json: MCP server configuration - Dockerfile.versioned: Versioned Docker build support - .dockerignore: Added .gitlab/ to ignore list Testing: - tests/test_tasks_transaction_freeze.py: Comprehensive freeze task tests The system uses team standings to fairly resolve contested players (multiple teams trying to acquire the same player), with worst-record teams getting priority. Includes comprehensive error handling, GM notifications, and admin reporting. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
11 KiB
11 KiB
VPS Helper Scripts
Collection of useful scripts for managing the Discord bot on your VPS.
📍 Script Locations
All scripts should be placed in /opt/discord-bot/ on your VPS.
/opt/discord-bot/
├── docker-compose.yml
├── .env.production
├── rollback.sh # Rollback to previous version
├── deploy-manual.sh # Manual deployment script
├── health-check.sh # Check bot health
├── logs-view.sh # View logs easily
├── cleanup.sh # Clean up old Docker images
└── deployments.log # Auto-generated deployment history
🔄 rollback.sh
Already created during setup. For reference:
#!/bin/bash
set -e
COMPOSE_FILE="docker-compose.yml"
LOG_FILE="deployments.log"
echo "=== Discord Bot Rollback ==="
echo ""
# Show recent deployments
echo "Recent deployments:"
tail -n 10 $LOG_FILE | column -t -s '|'
echo ""
# Show current version
CURRENT=$(grep "image:" $COMPOSE_FILE | awk '{print $2}')
echo "Current version: $CURRENT"
echo ""
# Show last version
if [ -f .last_version ]; then
LAST=$(cat .last_version)
echo "Last version: $LAST"
echo ""
read -p "Rollback to this version? (y/N): " confirm
if [ "$confirm" != "y" ]; then
echo "Rollback cancelled."
exit 0
fi
# Perform rollback
echo "Rolling back..."
sed -i "s|image:.*|image: $LAST|" $COMPOSE_FILE
docker-compose up -d
# Record rollback
echo "$(date -Iseconds) | ROLLBACK | $LAST" >> $LOG_FILE
echo "✅ Rollback complete!"
else
echo "❌ No previous version found!"
exit 1
fi
🚀 deploy-manual.sh
For manual deployments (bypassing GitLab):
#!/bin/bash
set -e
COMPOSE_FILE="docker-compose.yml"
LOG_FILE="deployments.log"
IMAGE="yourusername/discord-bot-v2"
echo "=== Manual Discord Bot Deployment ==="
echo ""
# Show available versions
echo "Available versions on Docker Hub:"
echo "(Showing last 10 tags)"
curl -s "https://hub.docker.com/v2/repositories/${IMAGE}/tags?page_size=10" | \
grep -o '"name":"[^"]*' | \
grep -o '[^"]*$'
echo ""
# Prompt for version
read -p "Enter version to deploy (or 'latest'): " VERSION
if [ -z "$VERSION" ]; then
echo "❌ No version specified!"
exit 1
fi
# Backup current version
docker inspect discord-bot --format='{{.Image}}' > .last_version || true
# Update docker-compose
sed -i "s|image: ${IMAGE}:.*|image: ${IMAGE}:${VERSION}|" $COMPOSE_FILE
# Pull and deploy
echo "Pulling ${IMAGE}:${VERSION}..."
docker-compose pull
echo "Deploying..."
docker-compose up -d
# Wait for health check
echo "Waiting for health check..."
sleep 10
if docker-compose ps | grep -q "Up (healthy)"; then
echo "✅ Deployment successful!"
echo "$(date -Iseconds) | MANUAL | ${VERSION} | Manual deployment" >> $LOG_FILE
docker image prune -f
else
echo "❌ Health check failed! Rolling back..."
LAST_VERSION=$(cat .last_version)
sed -i "s|image: ${IMAGE}:.*|image: ${LAST_VERSION}|" $COMPOSE_FILE
docker-compose up -d
exit 1
fi
Usage:
cd /opt/discord-bot
./deploy-manual.sh
🏥 health-check.sh
Comprehensive health check:
#!/bin/bash
echo "=== Discord Bot Health Check ==="
echo ""
# Container status
echo "📦 Container Status:"
docker-compose ps
echo ""
# Bot health
BOT_HEALTH=$(docker inspect discord-bot --format '{{.State.Health.Status}}' 2>/dev/null || echo "unknown")
echo "🤖 Bot Health: $BOT_HEALTH"
# Redis health
REDIS_HEALTH=$(docker exec discord-redis redis-cli ping 2>/dev/null || echo "unreachable")
echo "💾 Redis Health: $REDIS_HEALTH"
echo ""
# Uptime
BOT_STARTED=$(docker inspect discord-bot --format '{{.State.StartedAt}}' 2>/dev/null || echo "unknown")
echo "⏱️ Bot Started: $BOT_STARTED"
echo ""
# Resource usage
echo "💻 Resource Usage:"
docker stats --no-stream discord-bot discord-redis
echo ""
# Recent errors
echo "⚠️ Recent Errors (last 10):"
docker-compose logs --tail=100 bot 2>&1 | grep -i error | tail -10 || echo "No recent errors"
echo ""
# Deployment history
echo "📜 Recent Deployments:"
tail -5 deployments.log | column -t -s '|'
echo ""
# Summary
echo "=== Summary ==="
if [ "$BOT_HEALTH" = "healthy" ] && [ "$REDIS_HEALTH" = "PONG" ]; then
echo "✅ All systems operational"
exit 0
else
echo "❌ Issues detected"
exit 1
fi
Usage:
cd /opt/discord-bot
./health-check.sh
Cron for daily checks:
# Run health check daily at 6 AM
0 6 * * * /opt/discord-bot/health-check.sh | mail -s "Bot Health Report" you@email.com
📋 logs-view.sh
Easy log viewing:
#!/bin/bash
echo "Discord Bot Logs Viewer"
echo ""
echo "Select option:"
echo "1) Live bot logs (follow)"
echo "2) Last 100 bot logs"
echo "3) Last 50 error logs"
echo "4) All logs (bot + redis)"
echo "5) Deployment history"
echo "6) Search logs"
echo ""
read -p "Choice [1-6]: " choice
case $choice in
1)
echo "Following live logs (Ctrl+C to exit)..."
docker-compose logs -f --tail=50 bot
;;
2)
docker-compose logs --tail=100 bot
;;
3)
docker-compose logs --tail=500 bot | grep -i error | tail -50
;;
4)
docker-compose logs --tail=100
;;
5)
cat deployments.log | column -t -s '|'
;;
6)
read -p "Search term: " term
docker-compose logs bot | grep -i "$term" | tail -50
;;
*)
echo "Invalid option"
exit 1
;;
esac
Usage:
cd /opt/discord-bot
./logs-view.sh
🧹 cleanup.sh
Clean up old Docker images and data:
#!/bin/bash
set -e
echo "=== Discord Bot Cleanup ==="
echo ""
# Show current disk usage
echo "💾 Current Disk Usage:"
df -h /var/lib/docker
echo ""
# Show Docker disk usage
echo "🐳 Docker Disk Usage:"
docker system df
echo ""
read -p "Proceed with cleanup? (y/N): " confirm
if [ "$confirm" != "y" ]; then
echo "Cleanup cancelled."
exit 0
fi
# Stop containers temporarily
echo "Stopping containers..."
docker-compose down
# Prune images (keep recent ones)
echo "Pruning old images..."
docker image prune -a -f --filter "until=720h" # Keep images from last 30 days
# Prune volumes (be careful!)
# Uncomment if you want to clean volumes
# echo "Pruning unused volumes..."
# docker volume prune -f
# Prune build cache
echo "Pruning build cache..."
docker builder prune -f
# Restart containers
echo "Restarting containers..."
docker-compose up -d
# Show new disk usage
echo ""
echo "✅ Cleanup complete!"
echo ""
echo "💾 New Disk Usage:"
df -h /var/lib/docker
echo ""
docker system df
Usage:
cd /opt/discord-bot
./cleanup.sh
Cron for monthly cleanup:
# Run cleanup first Sunday of month at 3 AM
0 3 1-7 * 0 /opt/discord-bot/cleanup.sh
🔍 version-info.sh
Show detailed version information:
#!/bin/bash
echo "=== Version Information ==="
echo ""
# Docker image version
echo "🐳 Docker Image:"
docker inspect discord-bot --format '{{.Config.Image}}'
echo ""
# Image labels
echo "🏷️ Build Metadata:"
docker inspect discord-bot --format '{{json .Config.Labels}}' | jq '.'
echo ""
# Environment variables (version info only)
echo "🔧 Environment:"
docker inspect discord-bot --format '{{range .Config.Env}}{{println .}}{{end}}' | grep BOT_
echo ""
# Currently deployed
echo "📦 Currently Deployed:"
cat .deployed_version 2>/dev/null || echo "Unknown"
echo ""
# Last deployment
echo "📅 Last Deployment:"
tail -1 deployments.log | column -t -s '|'
echo ""
# Available for rollback
echo "⏮️ Available for Rollback:"
cat .last_version 2>/dev/null || echo "None"
Usage:
cd /opt/discord-bot
./version-info.sh
📊 status-dashboard.sh
Combined status dashboard:
#!/bin/bash
clear
echo "╔════════════════════════════════════════════╗"
echo "║ Discord Bot Status Dashboard ║"
echo "╚════════════════════════════════════════════╝"
echo ""
# Version
echo "📦 Version: $(cat .deployed_version 2>/dev/null || echo 'Unknown')"
echo ""
# Health
BOT_HEALTH=$(docker inspect discord-bot --format '{{.State.Health.Status}}' 2>/dev/null || echo "down")
REDIS_HEALTH=$(docker exec discord-redis redis-cli ping 2>/dev/null || echo "DOWN")
if [ "$BOT_HEALTH" = "healthy" ]; then
echo "✅ Bot: $BOT_HEALTH"
else
echo "❌ Bot: $BOT_HEALTH"
fi
if [ "$REDIS_HEALTH" = "PONG" ]; then
echo "✅ Redis: UP"
else
echo "❌ Redis: $REDIS_HEALTH"
fi
echo ""
# Uptime
STARTED=$(docker inspect discord-bot --format '{{.State.StartedAt}}' 2>/dev/null || echo "unknown")
echo "⏱️ Uptime: $STARTED"
echo ""
# Resource usage
echo "💻 Resources:"
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}" discord-bot discord-redis
echo ""
# Recent deployments
echo "📜 Recent Deployments:"
tail -3 deployments.log | column -t -s '|'
echo ""
# Errors
ERROR_COUNT=$(docker-compose logs --tail=1000 bot 2>&1 | grep -ic error || echo 0)
echo "⚠️ Errors (last 1000 lines): $ERROR_COUNT"
echo ""
echo "╚════════════════════════════════════════════╝"
echo "Press Ctrl+C to exit, or run with 'watch' for live updates"
Usage:
# One-time view
cd /opt/discord-bot
./status-dashboard.sh
# Live updating (every 2 seconds)
watch -n 2 /opt/discord-bot/status-dashboard.sh
🚀 Quick Setup
Install all scripts at once:
ssh user@vps << 'EOF'
cd /opt/discord-bot
# Make scripts executable
chmod +x rollback.sh
chmod +x deploy-manual.sh
chmod +x health-check.sh
chmod +x logs-view.sh
chmod +x cleanup.sh
chmod +x version-info.sh
chmod +x status-dashboard.sh
echo "✅ All scripts are ready!"
ls -lah *.sh
EOF
🎯 Useful Aliases
Add to ~/.bashrc on VPS:
# Discord Bot aliases
alias bot-status='cd /opt/discord-bot && ./status-dashboard.sh'
alias bot-logs='cd /opt/discord-bot && ./logs-view.sh'
alias bot-health='cd /opt/discord-bot && ./health-check.sh'
alias bot-rollback='cd /opt/discord-bot && ./rollback.sh'
alias bot-deploy='cd /opt/discord-bot && ./deploy-manual.sh'
alias bot-restart='cd /opt/discord-bot && docker-compose restart bot'
alias bot-down='cd /opt/discord-bot && docker-compose down'
alias bot-up='cd /opt/discord-bot && docker-compose up -d'
# Quick status
alias bs='bot-status'
alias bl='bot-logs'
Then:
source ~/.bashrc
# Now you can use:
bs # Status dashboard
bl # View logs
bot-health # Health check
Tip: Create a README.txt in /opt/discord-bot/ listing all available scripts and their purposes!