Mirror of https://github.com/roostorg/osprey github.com/roostorg/osprey
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 331 lines 12 kB view raw
1#!/bin/bash 2 3# Osprey Demo Script 4# This script starts all services, generates test data, and opens the UI 5# 6# Usage: 7# From repo: ./demo.sh 8# Standalone: curl -sSL https://raw.githubusercontent.com/roostorg/osprey/main/demo.sh | bash 9 10set -e 11 12REPO_URL="https://github.com/roostorg/osprey.git" 13DEMO_DIR="osprey-demo" 14COMPOSE_FILE="docker-compose.yaml" 15 16# Colors for output 17RED='\033[0;31m' 18GREEN='\033[0;32m' 19YELLOW='\033[1;33m' 20BLUE='\033[0;34m' 21NC='\033[0m' # No Color 22 23print_banner() { 24 echo -e "${BLUE}========================================${NC}" 25 echo -e "${BLUE} Osprey Demo Setup Script ${NC}" 26 echo -e "${BLUE}========================================${NC}" 27 echo "" 28} 29 30check_prerequisites() { 31 echo -e "${YELLOW}Checking prerequisites...${NC}" 32 33 # Check for Docker 34 if ! command -v docker &> /dev/null; then 35 echo -e "${RED}✗ Docker is not installed. Please install Docker first.${NC}" 36 echo " Visit: https://docs.docker.com/get-docker/" 37 exit 1 38 fi 39 echo -e "${GREEN}✓ Docker found${NC}" 40 41 # Check for Docker Compose v2 42 if ! docker compose version &> /dev/null; then 43 echo -e "${RED}✗ Docker Compose v2 is not available.${NC}" 44 echo " Please update Docker Desktop or install docker-compose-plugin" 45 exit 1 46 fi 47 echo -e "${GREEN}✓ Docker Compose found${NC}" 48 49 # Check if Docker daemon is running 50 if ! docker info &> /dev/null; then 51 echo -e "${RED}✗ Docker daemon is not running. Please start Docker.${NC}" 52 exit 1 53 fi 54 echo -e "${GREEN}✓ Docker daemon is running${NC}" 55 echo "" 56} 57 58check_port_available() { 59 local port=$1 60 local service=$2 61 if lsof -i :"$port" -sTCP:LISTEN >/dev/null 2>&1; then 62 echo -e "${RED}✗ Port $port is already in use (needed for $service)${NC}" 63 echo -e " Run: lsof -i :$port to see what's using it" 64 return 1 65 fi 66 return 0 67} 68 69check_existing_services() { 70 echo -e "${YELLOW}Checking for existing Osprey services...${NC}" 71 72 # Check for running containers from this compose project 73 local running_containers=$(docker ps --filter "name=osprey\|kafka\|postgres\|minio\|druid\|zookeeper\|snowflake" --format "{{.Names}}" 2>/dev/null | head -10) 74 75 if [ -n "$running_containers" ]; then 76 echo -e "${YELLOW}Found existing services that may conflict:${NC}" 77 echo "$running_containers" | while read -r container; do 78 echo -e "$container" 79 done 80 echo "" 81 echo -e "${YELLOW}Starting the demo will stop these services and remove their volumes (data will be lost).${NC}" 82 echo -n -e "${BLUE}Do you want to continue? [y/N]: ${NC}" 83 read -r response 84 if [[ ! "$response" =~ ^[Yy]$ ]]; then 85 echo -e "${RED}Aborted.${NC}" 86 exit 0 87 fi 88 echo "" 89 else 90 echo -e "${GREEN}✓ No conflicting services found${NC}" 91 fi 92 echo "" 93} 94 95check_required_ports() { 96 echo -e "${YELLOW}Checking required ports...${NC}" 97 98 local failed=0 99 100 # Infrastructure ports 101 check_port_available 9092 "Kafka" || failed=1 102 check_port_available 9000 "MinIO API" || failed=1 103 check_port_available 9001 "MinIO Console" || failed=1 104 check_port_available 5432 "PostgreSQL" || failed=1 105 check_port_available 8088 "Snowflake ID Worker" || failed=1 106 107 # Druid ports 108 check_port_available 2181 "Zookeeper" || failed=1 109 check_port_available 8081 "Druid Coordinator" || failed=1 110 check_port_available 8082 "Druid Broker" || failed=1 111 check_port_available 8083 "Druid Historical" || failed=1 112 check_port_available 8091 "Druid MiddleManager" || failed=1 113 check_port_available 8888 "Druid Router" || failed=1 114 115 # Druid MiddleManager task ports 116 for port in 8100 8101 8102 8103 8104 8105; do 117 check_port_available $port "Druid MiddleManager Tasks" || failed=1 118 done 119 120 # Osprey service ports 121 check_port_available 5001 "Osprey Worker" || failed=1 122 check_port_available 5002 "Osprey UI" || failed=1 123 check_port_available 5004 "Osprey UI API" || failed=1 124 125 if [ $failed -eq 1 ]; then 126 echo "" 127 echo -e "${RED}✗ Some required ports are in use. Please free them before running the demo.${NC}" 128 exit 1 129 fi 130 131 echo -e "${GREEN}✓ All required ports are available${NC}" 132 echo "" 133} 134 135setup_repo() { 136 # Check if we're already in the osprey repo 137 if [ -f "docker-compose.yaml" ] && grep -q "osprey-worker" "docker-compose.yaml" 2>/dev/null; then 138 echo -e "${GREEN}✓ Running from Osprey repository${NC}" 139 return 0 140 fi 141 142 # Check if we need to clone 143 echo -e "${YELLOW}Osprey repository not found. Setting up...${NC}" 144 145 if ! command -v git &> /dev/null; then 146 echo -e "${RED}✗ Git is not installed. Please install Git first.${NC}" 147 exit 1 148 fi 149 150 if [ -d "$DEMO_DIR" ]; then 151 echo -e "${YELLOW}Directory '$DEMO_DIR' already exists, using it${NC}" 152 cd "$DEMO_DIR" 153 echo -e "${YELLOW}Pulling latest changes...${NC}" 154 git pull 155 echo -e "${GREEN}✓ Repository updated${NC}" 156 echo "" 157 return 0 158 else 159 echo -e "${YELLOW}Cloning Osprey repository...${NC}" 160 git clone --depth 1 "$REPO_URL" "$DEMO_DIR" 161 fi 162 163 cd "$DEMO_DIR" 164 echo -e "${GREEN}✓ Repository ready${NC}" 165 echo "" 166} 167 168# Cleanup function for signal handling 169cleanup() { 170 echo "" 171 echo -e "${YELLOW}Caught interrupt signal. Cleaning up...${NC}" 172 DOCKER_CLI_HINTS=false docker compose -f "$COMPOSE_FILE" --progress=quiet --profile test_data down -v 2>/dev/null || true 173 echo -e "${GREEN}✓ Services stopped and volumes removed${NC}" 174 exit 1 175} 176 177# Run the functions we defined above 178print_banner 179check_prerequisites 180check_existing_services 181setup_repo 182 183# Set up signal trap after we're in the repo (services may be started after this point) 184trap cleanup INT TERM 185 186# Function to check if a service is healthy via HTTP 187wait_for_http_service() { 188 local service=$1 189 local url=$2 190 local max_attempts=${3:-60} 191 local attempt=1 192 193 echo -e "${YELLOW}Waiting for $service...${NC}" 194 while [ $attempt -le $max_attempts ]; do 195 if curl -s "$url" > /dev/null 2>&1; then 196 echo -e "${GREEN}$service is ready${NC}" 197 return 0 198 fi 199 sleep 2 200 attempt=$((attempt + 1)) 201 done 202 echo -e "${RED}$service failed to start${NC}" 203 return 1 204} 205 206# Function to check if a Docker container is healthy 207wait_for_container() { 208 local container=$1 209 local max_attempts=${2:-60} 210 local attempt=1 211 212 echo -e "${YELLOW}Waiting for $container...${NC}" 213 while [ $attempt -le $max_attempts ]; do 214 local status=$(docker inspect --format='{{.State.Health.Status}}' "$container" 2>/dev/null || echo "not_found") 215 if [ "$status" = "healthy" ]; then 216 echo -e "${GREEN}$container is ready${NC}" 217 return 0 218 elif [ "$status" = "not_found" ]; then 219 # Container doesn't have health check, check if running 220 local running=$(docker inspect --format='{{.State.Running}}' "$container" 2>/dev/null || echo "false") 221 if [ "$running" = "true" ]; then 222 echo -e "${GREEN}$container is running${NC}" 223 return 0 224 fi 225 fi 226 sleep 2 227 attempt=$((attempt + 1)) 228 done 229 echo -e "${RED}$container failed to start${NC}" 230 return 1 231} 232 233# Step 1: Stop any existing services and remove volumes for clean state 234echo -e "${YELLOW}Step 1: Cleaning up existing services and volumes...${NC}" 235DOCKER_CLI_HINTS=false docker compose -f "$COMPOSE_FILE" --progress=quiet --profile test_data down -v 2>/dev/null || true 236DOCKER_CLI_HINTS=false docker compose --progress=quiet --profile test_data down -v 2>/dev/null || true # Also clean up old full compose 237echo -e "${GREEN}✓ Cleanup complete (volumes removed for fresh start)${NC}" 238echo "" 239 240# Step 1.5: Check ports are available after cleanup 241check_required_ports 242 243# Step 2: Pull Docker images 244echo -e "${YELLOW}Step 2: Pulling Docker images (this may take a few minutes on first run)...${NC}" 245DOCKER_CLI_HINTS=false docker compose -f "$COMPOSE_FILE" --progress=quiet pull --quiet 246echo -e "${GREEN}✓ Images pulled${NC}" 247echo "" 248 249# Step 3: Start core services (build if needed) 250echo -e "${YELLOW}Step 3: Starting core services (building images if needed)...${NC}" 251DOCKER_CLI_HINTS=false docker compose -f "$COMPOSE_FILE" --progress=quiet up -d --build --quiet-pull 252echo -e "${GREEN}✓ Core services starting${NC}" 253echo "" 254 255# Step 4: Wait for critical services 256echo -e "${YELLOW}Step 4: Waiting for services to be ready...${NC}" 257echo "" 258 259# Wait for infrastructure containers (use Docker health checks) 260wait_for_container "osprey-kafka" 90 || exit 1 261wait_for_container "postgres" 90 || exit 1 262wait_for_container "minio" 90 || exit 1 263 264# Wait for Druid broker (use HTTP check - no Docker health check configured) 265wait_for_http_service "Druid Broker" "http://localhost:8082/status" 180 || exit 1 266 267# Wait for osprey services (HTTP check) 268wait_for_http_service "Osprey UI API" "http://localhost:5004/config" 120 || exit 1 269wait_for_http_service "Osprey UI" "http://localhost:5002" 90 || exit 1 270 271echo "" 272echo -e "${GREEN}✓ All services are ready${NC}" 273echo "" 274 275# Step 5: Start test data generator 276echo -e "${YELLOW}Step 5: Starting test data generator...${NC}" 277DOCKER_CLI_HINTS=false docker compose -f "$COMPOSE_FILE" --progress=quiet --profile test_data up -d osprey-kafka-test-data-producer 278echo -e "${GREEN}✓ Test data generator started (1 event/second)${NC}" 279echo "" 280 281# Step 6: Wait for some events to be processed 282echo -e "${YELLOW}Step 6: Waiting for events to be processed...${NC}" 283sleep 15 284echo -e "${GREEN}✓ Events should now be in Druid${NC}" 285echo "" 286 287# Generate UI URL with date range 288START_DATE=$(date -u -v-1d +%Y-%m-%dT00:00:00.000Z 2>/dev/null || date -u -d "yesterday" +%Y-%m-%dT00:00:00.000Z) 289END_DATE=$(date -u +%Y-%m-%dT23:59:59.999Z 2>/dev/null || date -u +%Y-%m-%dT23:59:59.999Z) 290UI_URL="http://localhost:5002/?start=${START_DATE}&end=${END_DATE}&interval=day&queryFilter=&topn=UserId" 291 292echo -e "${BLUE}========================================${NC}" 293echo -e "${GREEN} Demo Ready! ${NC}" 294echo -e "${BLUE}========================================${NC}" 295echo "" 296echo -e "${BLUE}Available Interfaces:${NC}" 297echo -e " • Osprey UI: ${GREEN}${UI_URL}${NC}" 298echo -e " • Druid Console: ${GREEN}http://localhost:8888${NC}" 299echo -e " • Osprey API: ${GREEN}http://localhost:5004${NC}" 300echo "" 301echo -e "${BLUE}Demo Rules Active:${NC}" 302echo -e " • ContainsHello - Bans users who say 'hello'" 303echo -e " • LazyPostRule - Labels posts with 'lazy' as low_effort" 304echo -e " • QuickPostRule - Labels posts with 'quick' as potential_bot" 305echo -e " • FoxPostRule - Bans users who say 'fox' (spam pattern)" 306echo "" 307echo -e "${BLUE}What to Demo:${NC}" 308echo -e " 1. Event Stream - See processed events with rule matches" 309echo -e " 2. TopN Panel - See users grouped by labels/bans" 310echo -e " 3. Timeseries - See event volume over time" 311echo -e " 4. Query Filter - Try: LazyPostRule == True" 312echo -e " 5. Rules Viz - View the rule dependency graph" 313echo "" 314echo -e "${YELLOW}Opening Osprey UI in browser...${NC}" 315 316# Open browser (works on macOS, Linux with xdg-open, or WSL) 317if command -v open &> /dev/null; then 318 open "$UI_URL" 319elif command -v xdg-open &> /dev/null; then 320 xdg-open "$UI_URL" 321elif command -v wslview &> /dev/null; then 322 wslview "$UI_URL" 323else 324 echo -e "${YELLOW}Please open this URL manually: ${UI_URL}${NC}" 325fi 326 327echo "" 328echo -e "${BLUE}To stop the demo:${NC}" 329echo -e " cd $(pwd) && docker compose --profile test_data down -v" 330echo "" 331echo -e "${GREEN}Demo is running! Press Ctrl+C to exit this script (services will keep running)${NC}"