-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·347 lines (302 loc) · 11.8 KB
/
Copy pathinstall.sh
File metadata and controls
executable file
·347 lines (302 loc) · 11.8 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
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
#!/bin/bash
# Install script for Stigix All-in-One (Migration Draft)
# Usage: ./install-stigix.sh [options]
set -e
# Default values
INSTALL_MODE="both"
DRY_RUN=false
REPO_URL="https://raw.githubusercontent.com/jsuzanne/stigix/main"
COMPOSE_URL="$REPO_URL/docker-compose.yml"
show_help() {
echo "🚀 Stigix All-in-One - Installation Script"
echo "Usage: ./install-stigix.sh [options]"
echo ""
echo "Options:"
echo " --mode <target|source|both> Set the deployment mode (Default: both)"
echo " --dry-run, -d Download files and show what would happen without starting Docker"
echo " --help, -h Show this help message"
echo ""
echo "Examples:"
echo " curl -sfL https://raw.githubusercontent.com/jsuzanne/stigix/main/install-stigix.sh | bash -s -- --mode both"
echo " curl -sfL https://raw.githubusercontent.com/jsuzanne/stigix/main/install-stigix.sh | bash -s -- --mode target --dry-run"
exit 0
}
find_free_port() {
local port=$1
local max_port=$2
while [ "$port" -le "$max_port" ]; do
local in_use=false
if [ "$in_use" = false ] && command -v lsof &> /dev/null; then
if lsof -i :$port > /dev/null 2>&1; then
in_use=true
fi
fi
if [ "$in_use" = false ] && command -v ss &> /dev/null; then
if ss -tln | grep -q -E "(^|:)$port($|[^0-9])"; then
in_use=true
fi
fi
if [ "$in_use" = false ] && command -v netstat &> /dev/null; then
if netstat -an | grep -E "(^|[^0-9])$port($|[^0-9])" | grep -q -i listen; then
in_use=true
fi
fi
if [ "$in_use" = false ] && command -v curl &> /dev/null; then
# Curl returns exit code 7 if connection is refused (port is closed).
# Any other exit code (like 52 empty reply, 0 success, etc.) means port is open.
curl -s --connect-timeout 1 http://127.0.0.1:$port >/dev/null 2>&1
local curl_exit=$?
if [ "$curl_exit" -ne 7 ]; then
in_use=true
fi
fi
if [ "$in_use" = false ]; then
echo "$port"
return 0
fi
port=$((port+1))
done
return 1
}
print_progress_bar() {
local val=$1
local max=$2
local text=$3
local width=30
local pct=$(( val * 100 / max ))
local num_filled=$(( val * width / max ))
local num_empty=$(( width - num_filled ))
local bar=""
local k
for ((k=0; k<num_filled; k++)); do bar="${bar}█"; done
for ((k=0; k<num_empty; k++)); do bar="${bar}░"; done
printf "\r [%s] %3d%% - %s" "$bar" "$pct" "$text"
}
dump_process_on_port() {
local port=$1
echo " [Process info for port $port]:"
# Windows Git Bash check
if [[ "$OS_TYPE" =~ MINGW|MSYS|CYGWIN ]]; then
local win_ns=$(netstat -ano | grep -E ":$port " 2>/dev/null)
if [ -n "$win_ns" ]; then
echo "$win_ns" | sed 's/^/ /'
return 0
fi
fi
if command -v lsof &> /dev/null; then
local lsof_out=$(lsof -i :$port 2>/dev/null)
if [ -n "$lsof_out" ]; then
echo "$lsof_out" | sed 's/^/ /'
return 0
fi
fi
if command -v ss &> /dev/null; then
local ss_out=$(ss -tlnp | grep -E ":$port " 2>/dev/null)
if [ -n "$ss_out" ]; then
echo "$ss_out" | sed 's/^/ /'
return 0
fi
fi
if command -v netstat &> /dev/null; then
local ns_out=$(netstat -anp 2>/dev/null | grep -E ":$port " 2>/dev/null)
if [ -n "$ns_out" ]; then
echo "$ns_out" | sed 's/^/ /'
return 0
fi
fi
echo " (Could not retrieve process info; it might be owned by root or running in docker. Try running: sudo lsof -i :$port)"
}
# Parse command line arguments
while [[ "$#" -gt 0 ]]; do
case $1 in
--mode|-m) INSTALL_MODE="$2"; shift 2 ;;
--dry-run|-d) DRY_RUN=true; shift ;;
--help|-h) show_help ;;
*) echo "Unknown parameter passed: $1"; show_help ;;
esac
done
echo "🚀 Stigix (All-in-One) - Installation"
echo "=========================================="
# 1. Prerequisite Check: Docker
if ! command -v docker &> /dev/null; then
echo "❌ Error: Docker is not installed."
echo "Please install Docker first: https://docs.docker.com/get-docker/"
exit 1
fi
if ! docker info &> /dev/null; then
echo "❌ Error: Docker is installed but not running."
echo "Please start the Docker Desktop / Daemon and try again."
exit 1
fi
echo "✅ Docker is running."
# OS Detection — Linux gets host mode, macOS/Windows get bridge mode
OS_TYPE=$(uname)
if [[ "$OS_TYPE" == "Linux" ]] && ! grep -qi microsoft /proc/version 2>/dev/null; then
echo "🐧 Platform: Native Linux detected. (Using host mode for full features)"
COMPOSE_URL="$REPO_URL/docker-compose.yml"
elif [[ "$OS_TYPE" == "Darwin" ]]; then
echo "🍎 Platform: macOS detected. (Host mode not supported on macOS, using bridge mode)"
COMPOSE_URL="$REPO_URL/docker-compose.bridge.yml"
else
echo "🪟 Platform: WSL/Windows or unknown detected. (Using bridge mode)"
COMPOSE_URL="$REPO_URL/docker-compose.bridge.yml"
fi
INSTALL_DIR="stigix"
mkdir -p "$INSTALL_DIR"
cd "$INSTALL_DIR"
# 3. Download Configuration
echo "📦 Downloading Base Configuration from GitHub..."
curl -sSL -o docker-compose.yml "$COMPOSE_URL"
# Align the volume mount filename to 'docker-compose.yml' on the host
if [ -f docker-compose.yml ]; then
if command -v sed &> /dev/null; then
sed -i.bak -E 's|-[[:space:]]+\./docker-compose.*:/app/docker-compose\.yml|- ./docker-compose.yml:/app/docker-compose.yml|g' docker-compose.yml && rm -f docker-compose.yml.bak
fi
fi
# 4. Mode-specific adjustments (Creating the right docker-compose/env)
# Generate a unique JWT secret for this installation
JWT_SECRET=$(openssl rand -hex 32 2>/dev/null || cat /proc/sys/kernel/random/uuid 2>/dev/null | tr -d '-' || date +%s%N | sha256sum | head -c 64)
PORT=8080
if [ "$INSTALL_MODE" != "target" ]; then
echo "🔍 Checking for a free port for the Web Dashboard (range 8080-8090)..."
FREE_PORT=$(find_free_port 8080 8090)
if [ -n "$FREE_PORT" ]; then
PORT=$FREE_PORT
if [ "$PORT" -ne 8080 ]; then
echo "⚠️ Port 8080 is in use."
dump_process_on_port 8080
if [ -t 0 ]; then
read -p "Would you like to proceed with alternative port $PORT? [Y/n]: " PROMPT_CHOICE
PROMPT_CHOICE=${PROMPT_CHOICE:-Y}
if [[ "$PROMPT_CHOICE" =~ ^[Nn] ]]; then
echo "❌ Installation cancelled."
exit 1
fi
echo "✅ Proceeding with port $PORT."
else
echo "⚠️ Auto-selected alternative port: $PORT"
fi
else
echo "✅ Port 8080 is free."
fi
else
echo "❌ Error: All ports in the range 8080-8090 are in use."
exit 1
fi
fi
echo "STIGIX_ROLE=$INSTALL_MODE" > .env
echo "JWT_SECRET=$JWT_SECRET" >> .env
echo "PORT=$PORT" >> .env
echo "BETA=false" >> .env
echo "" >> .env
echo "# --- Docker Image Tag (Uncomment to lock version/tag) ---" >> .env
echo "# TAG=stable" >> .env
# Base UI/Traffic Gen Config
if [ "$INSTALL_MODE" == "both" ] || [ "$INSTALL_MODE" == "source" ]; then
echo "AUTO_START_TRAFFIC=true" >> .env
echo "SLEEP_BETWEEN_REQUESTS=1" >> .env
fi
# 5. Add Commented Templates for common configurations
cat <<EOF >> .env
# --- Prisma SD-WAN Integration (Optional) ---
# PRISMA_SDWAN_TSGID=YOUR_TSG_ID
# PRISMA_SDWAN_REGION=Germany
# PRISMA_SDWAN_CLIENT_ID="your-client-id@tsgid.iam.panserviceaccount.com"
# PRISMA_SDWAN_CLIENT_SECRET="your-client-secret"
# --- Registry & Autodiscovery (Optional) ---
# STIGIX_REGISTRY_ENABLED=true
# STIGIX_REGISTRY_URL=https://registry.stigix.io
# STIGIX_INSTANCE_ID=local-node-$(hostname | cut -d'.' -f1)
# --- Stigix Cloud Probes (Signed URLs) ---
# The Target Worker URL where scenarios are hosted
STIGIX_TARGET_BASE_URL=https://target.stigix.io
# Master Key for target worker auth (must match MASTER_SIGNATURE_KEY on Cloudflare Worker)
# Key is derived per request as SHA256(PRISMA_SDWAN_TSGID:STIGIX_TARGET_MASTER_KEY)
# Leave commented if the worker runs in open-access mode (no key configured on CF side)
# STIGIX_TARGET_MASTER_KEY=
# Site name for dashboard display
STIGIX_SITE_NAME=$(hostname | cut -d'.' -f1)
EOF
# Adjust the docker-compose.yml based on mode if needed
if [ "$INSTALL_MODE" == "target" ]; then
echo "🔧 Adjusting docker-compose for TARGET mode..."
# You could use sed to remove exposed ports like 8080 or 3100 if we wanted,
# but since network_mode is host, ports are bound by the apps directly.
echo "TARGET_ONLY=true" >> .env
elif [ "$INSTALL_MODE" == "source" ]; then
echo "🔧 Adjusting docker-compose for SOURCE mode..."
echo "SOURCE_ONLY=true" >> .env
fi
mkdir -p ./config ./logs ./mcp-data
# Pre-create CLI persistence files so Docker mounts them as files (not dirs)
touch ./.stigix-cli.history ./.stigix-cli.json
echo "✅ Files prepared in $PWD"
# 5. Dry Run or Execution
if [ "$DRY_RUN" = true ]; then
echo ""
echo "🛑 [DRY RUN] Mode enabled. No containers were started."
echo "📂 The following files have been created:"
ls -la
echo ""
echo "🔍 To start the environment manually, run:"
echo " cd $(pwd)"
echo " docker compose pull"
echo " docker compose up -d"
echo "=========================================="
exit 0
fi
# 6. Start Services
echo "🔧 Pulling images and starting Stigix All-in-One..."
docker compose pull || echo "⚠️ Pull failed, trying to start anyway..."
docker compose up -d
echo ""
echo "🔍 Running post-installation diagnostics..."
sleep 5
CONTAINER_RUNNING=false
if [ "$(docker inspect -f '{{.State.Running}}' stigix 2>/dev/null)" = "true" ]; then
CONTAINER_RUNNING=true
echo "✓ Container 'stigix' is running."
else
echo "❌ Error: Container 'stigix' is not running."
echo "💡 Diagnostics: Check container logs by running 'docker logs stigix'"
exit 1
fi
if [ "$INSTALL_MODE" != "target" ]; then
echo "🔍 Checking HTTP responsiveness at http://localhost:$PORT..."
HTTP_OK=false
MAX_ATTEMPTS=15
for ((i=1; i<=MAX_ATTEMPTS; i++)); do
if curl -sfI "http://localhost:$PORT" > /dev/null 2>&1; then
HTTP_OK=true
print_progress_bar $MAX_ATTEMPTS $MAX_ATTEMPTS "Web Dashboard is fully responsive! "
echo ""
break
fi
print_progress_bar $i $MAX_ATTEMPTS "Waiting for Dashboard (attempt $i/$MAX_ATTEMPTS)..."
sleep 2
done
if [ "$HTTP_OK" = false ]; then
echo ""
echo "⚠️ Warning: Web Dashboard is not responding yet."
echo "💡 Diagnostics: The server might still be initializing. Run 'docker logs stigix' to verify."
fi
fi
echo ""
echo "=========================================="
echo "✅ Stigix All-in-One Installation complete!"
echo ""
# Show installed version
INSTALLED_VERSION=$(docker exec stigix cat /app/VERSION 2>/dev/null || echo "")
if [ -n "$INSTALLED_VERSION" ]; then
echo "📦 Installed version: $INSTALLED_VERSION"
fi
if [ "$INSTALL_MODE" == "target" ]; then
echo "🎯 Target Site is active (XFR: 9000, Voice: 6100, Probes: 6200, iPerf: 5201)."
else
echo "📊 Dashboard: http://localhost:$PORT"
echo "🔑 Login: admin / admin"
echo "💻 Console CLI (for headless/terminal control): docker exec -it stigix stigix-cli"
echo "💡 Note: To change the Web UI port later, edit 'PORT' in stigix/.env and run: cd stigix && docker compose up -d"
fi
echo "📝 Check logs: cd stigix && docker compose logs -f"
echo "=========================================="