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