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.

Single script to run with curl command to run the osprey demo (#120)

1. Add a demo script that runs with a single curl command to install osprey, start services and the example event generator. It will check for existing docker services and port collisions. This overlaps a bit with start.sh. Command:

curl -sSL https://raw.githubusercontent.com/roostorg/osprey/main/demo.sh | bash

2. Removed bigtable
3. Fix a bug in kafka rename

authored by

Vinay Rao and committed by
GitHub
2a4b964b 2d4f0b8d

+332 -7
+331
demo.sh
··· 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 + 10 + set -e 11 + 12 + REPO_URL="https://github.com/roostorg/osprey.git" 13 + DEMO_DIR="osprey-demo" 14 + COMPOSE_FILE="docker-compose.yaml" 15 + 16 + # Colors for output 17 + RED='\033[0;31m' 18 + GREEN='\033[0;32m' 19 + YELLOW='\033[1;33m' 20 + BLUE='\033[0;34m' 21 + NC='\033[0m' # No Color 22 + 23 + print_banner() { 24 + echo -e "${BLUE}========================================${NC}" 25 + echo -e "${BLUE} Osprey Demo Setup Script ${NC}" 26 + echo -e "${BLUE}========================================${NC}" 27 + echo "" 28 + } 29 + 30 + check_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 + 58 + check_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 + 69 + check_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 + 95 + check_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 + 135 + setup_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 169 + cleanup() { 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 178 + print_banner 179 + check_prerequisites 180 + check_existing_services 181 + setup_repo 182 + 183 + # Set up signal trap after we're in the repo (services may be started after this point) 184 + trap cleanup INT TERM 185 + 186 + # Function to check if a service is healthy via HTTP 187 + wait_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 207 + wait_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 234 + echo -e "${YELLOW}Step 1: Cleaning up existing services and volumes...${NC}" 235 + DOCKER_CLI_HINTS=false docker compose -f "$COMPOSE_FILE" --progress=quiet --profile test_data down -v 2>/dev/null || true 236 + DOCKER_CLI_HINTS=false docker compose --progress=quiet --profile test_data down -v 2>/dev/null || true # Also clean up old full compose 237 + echo -e "${GREEN}✓ Cleanup complete (volumes removed for fresh start)${NC}" 238 + echo "" 239 + 240 + # Step 1.5: Check ports are available after cleanup 241 + check_required_ports 242 + 243 + # Step 2: Pull Docker images 244 + echo -e "${YELLOW}Step 2: Pulling Docker images (this may take a few minutes on first run)...${NC}" 245 + DOCKER_CLI_HINTS=false docker compose -f "$COMPOSE_FILE" --progress=quiet pull --quiet 246 + echo -e "${GREEN}✓ Images pulled${NC}" 247 + echo "" 248 + 249 + # Step 3: Start core services (build if needed) 250 + echo -e "${YELLOW}Step 3: Starting core services (building images if needed)...${NC}" 251 + DOCKER_CLI_HINTS=false docker compose -f "$COMPOSE_FILE" --progress=quiet up -d --build --quiet-pull 252 + echo -e "${GREEN}✓ Core services starting${NC}" 253 + echo "" 254 + 255 + # Step 4: Wait for critical services 256 + echo -e "${YELLOW}Step 4: Waiting for services to be ready...${NC}" 257 + echo "" 258 + 259 + # Wait for infrastructure containers (use Docker health checks) 260 + wait_for_container "osprey-kafka" 90 || exit 1 261 + wait_for_container "postgres" 90 || exit 1 262 + wait_for_container "minio" 90 || exit 1 263 + 264 + # Wait for Druid broker (use HTTP check - no Docker health check configured) 265 + wait_for_http_service "Druid Broker" "http://localhost:8082/status" 180 || exit 1 266 + 267 + # Wait for osprey services (HTTP check) 268 + wait_for_http_service "Osprey UI API" "http://localhost:5004/config" 120 || exit 1 269 + wait_for_http_service "Osprey UI" "http://localhost:5002" 90 || exit 1 270 + 271 + echo "" 272 + echo -e "${GREEN}✓ All services are ready${NC}" 273 + echo "" 274 + 275 + # Step 5: Start test data generator 276 + echo -e "${YELLOW}Step 5: Starting test data generator...${NC}" 277 + DOCKER_CLI_HINTS=false docker compose -f "$COMPOSE_FILE" --progress=quiet --profile test_data up -d osprey-kafka-test-data-producer 278 + echo -e "${GREEN}✓ Test data generator started (1 event/second)${NC}" 279 + echo "" 280 + 281 + # Step 6: Wait for some events to be processed 282 + echo -e "${YELLOW}Step 6: Waiting for events to be processed...${NC}" 283 + sleep 15 284 + echo -e "${GREEN}✓ Events should now be in Druid${NC}" 285 + echo "" 286 + 287 + # Generate UI URL with date range 288 + START_DATE=$(date -u -v-1d +%Y-%m-%dT00:00:00.000Z 2>/dev/null || date -u -d "yesterday" +%Y-%m-%dT00:00:00.000Z) 289 + END_DATE=$(date -u +%Y-%m-%dT23:59:59.999Z 2>/dev/null || date -u +%Y-%m-%dT23:59:59.999Z) 290 + UI_URL="http://localhost:5002/?start=${START_DATE}&end=${END_DATE}&interval=day&queryFilter=&topn=UserId" 291 + 292 + echo -e "${BLUE}========================================${NC}" 293 + echo -e "${GREEN} Demo Ready! ${NC}" 294 + echo -e "${BLUE}========================================${NC}" 295 + echo "" 296 + echo -e "${BLUE}Available Interfaces:${NC}" 297 + echo -e " • Osprey UI: ${GREEN}${UI_URL}${NC}" 298 + echo -e " • Druid Console: ${GREEN}http://localhost:8888${NC}" 299 + echo -e " • Osprey API: ${GREEN}http://localhost:5004${NC}" 300 + echo "" 301 + echo -e "${BLUE}Demo Rules Active:${NC}" 302 + echo -e " • ContainsHello - Bans users who say 'hello'" 303 + echo -e " • LazyPostRule - Labels posts with 'lazy' as low_effort" 304 + echo -e " • QuickPostRule - Labels posts with 'quick' as potential_bot" 305 + echo -e " • FoxPostRule - Bans users who say 'fox' (spam pattern)" 306 + echo "" 307 + echo -e "${BLUE}What to Demo:${NC}" 308 + echo -e " 1. Event Stream - See processed events with rule matches" 309 + echo -e " 2. TopN Panel - See users grouped by labels/bans" 310 + echo -e " 3. Timeseries - See event volume over time" 311 + echo -e " 4. Query Filter - Try: LazyPostRule == True" 312 + echo -e " 5. Rules Viz - View the rule dependency graph" 313 + echo "" 314 + echo -e "${YELLOW}Opening Osprey UI in browser...${NC}" 315 + 316 + # Open browser (works on macOS, Linux with xdg-open, or WSL) 317 + if command -v open &> /dev/null; then 318 + open "$UI_URL" 319 + elif command -v xdg-open &> /dev/null; then 320 + xdg-open "$UI_URL" 321 + elif command -v wslview &> /dev/null; then 322 + wslview "$UI_URL" 323 + else 324 + echo -e "${YELLOW}Please open this URL manually: ${UI_URL}${NC}" 325 + fi 326 + 327 + echo "" 328 + echo -e "${BLUE}To stop the demo:${NC}" 329 + echo -e " cd $(pwd) && docker compose --profile test_data down -v" 330 + echo "" 331 + echo -e "${GREEN}Demo is running! Press Ctrl+C to exit this script (services will keep running)${NC}"
-6
docker-compose.yaml
··· 94 94 condition: service_healthy 95 95 osprey-kafka-topic-creator: 96 96 condition: service_completed_successfully 97 - bigtable: 98 - condition: service_healthy 99 - bigtable-initializer: 100 - condition: service_completed_successfully 101 97 minio: 102 98 condition: service_healthy 103 99 minio-bucket-init: ··· 146 142 - druid-broker 147 143 - postgres 148 144 - snowflake-id-worker 149 - - bigtable 150 - - bigtable-initializer 151 145 ports: 152 146 - "127.0.0.1:5004:5004" 153 147 command: ["osprey-ui-api"]
+1 -1
druid/specs/execution_results.json
··· 4 4 "ioConfig": { 5 5 "type": "kafka", 6 6 "consumerProperties": { 7 - "bootstrap.servers": "kafka:29092", 7 + "bootstrap.servers": "osprey-kafka:29092", 8 8 "auto.offset.reset": "latest" 9 9 }, 10 10 "topic": "osprey.execution_results",