forked from tphakala/birdnet-go
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsupport.sh
More file actions
executable file
Β·554 lines (456 loc) Β· 22.5 KB
/
support.sh
File metadata and controls
executable file
Β·554 lines (456 loc) Β· 22.5 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
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
#!/bin/bash
# BirdNET-Go Support Data Collection Script
# This script collects diagnostic information to help troubleshoot BirdNET-Go issues
# It masks sensitive information such as passwords, tokens, and IP addresses
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to print colored messages
print_message() {
if [ "$3" = "nonewline" ]; then
echo -en "${2}${1}${NC}"
else
echo -e "${2}${1}${NC}"
fi
}
# Print banner
cat << "EOF"
____ _ _ _ _ _____ _____ ____
| __ )(_)_ __ __| | \ | | ____|_ _| / ___| ___
| _ \| | '__/ _` | \| | _| | | | | _ / _ \
| |_) | | | | (_| | |\ | |___ | | | |_| | (_) |
|____/|_|_| \__,_|_| \_|_____| |_| \____|\___/
Support Data Collection Tool
EOF
# Check if running as root
if [ "$EUID" -ne 0 ]; then
print_message "β οΈ This script needs to be run as root to collect all necessary information." "$YELLOW"
print_message "Please run with sudo: sudo bash $0" "$YELLOW"
exit 1
fi
# Verify available disk space before starting
REQUIRED_SPACE=100000 # 100MB in KB
AVAILABLE_SPACE=$(df -k /tmp | awk 'NR==2 {print $4}')
if [ "$AVAILABLE_SPACE" -lt "$REQUIRED_SPACE" ]; then
print_message "β Not enough disk space in /tmp. Need at least 100MB." "$RED"
print_message "Available: $((AVAILABLE_SPACE / 1024))MB, Required: $((REQUIRED_SPACE / 1024))MB" "$YELLOW"
exit 1
fi
# Create secure temporary directory
OUTPUT_DIR=$(mktemp -d)
if [ ! -d "$OUTPUT_DIR" ]; then
print_message "β Failed to create secure temporary directory" "$RED"
exit 1
fi
# Generate timestamp for the final tarball
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
OUTPUT_FILE="/tmp/birdnet-go-support-$TIMESTAMP.tar.gz"
print_message "π Created temporary directory for diagnostic data: $OUTPUT_DIR" "$GREEN"
# Clean up function to handle unexpected exits
cleanup() {
local exit_code=$?
if [ -d "$OUTPUT_DIR" ]; then
print_message "\nπ§Ή Cleaning up temporary files..." "$YELLOW"
rm -rf "$OUTPUT_DIR"
fi
if [ $exit_code -ne 0 ]; then
print_message "β Script execution terminated with errors." "$RED"
fi
exit $exit_code
}
# Set trap to ensure cleanup on script exit
trap cleanup EXIT INT TERM
# Function to mask sensitive information in a file
mask_sensitive_data() {
local input_file="$1"
local output_file="$2"
# Make a copy of the input file
cp "$input_file" "$output_file"
# Mask passwords, tokens, keys, etc.
sed -i 's/\(password: \)"\([^"]*\)"/\1"[REDACTED]"/g' "$output_file"
sed -i 's/\(Password: \)"\([^"]*\)"/\1"[REDACTED]"/g' "$output_file"
sed -i 's/\(apikey: \)"\([^"]*\)"/\1"[REDACTED]"/g' "$output_file"
sed -i 's/\(APIKey: \)"\([^"]*\)"/\1"[REDACTED]"/g' "$output_file"
sed -i 's/\(token: \)"\([^"]*\)"/\1"[REDACTED]"/g' "$output_file"
sed -i 's/\(Token: \)"\([^"]*\)"/\1"[REDACTED]"/g' "$output_file"
sed -i 's/\(secret: \)"\([^"]*\)"/\1"[REDACTED]"/g' "$output_file"
sed -i 's/\(Secret: \)"\([^"]*\)"/\1"[REDACTED]"/g' "$output_file"
sed -i 's/\(ClientSecret: \)"\([^"]*\)"/\1"[REDACTED]"/g' "$output_file"
sed -i 's/\(clientsecret: \)"\([^"]*\)"/\1"[REDACTED]"/g' "$output_file"
sed -i 's/\(sessionsecret: \)"\([^"]*\)"/\1"[REDACTED]"/g' "$output_file"
# Mask IP addresses
sed -i 's/\([0-9]\{1,3\}\.\)[0-9]\{1,3\}\(\.[0-9]\{1,3\}\)\(\.[0-9]\{1,3\}\)/\1xxx\2\3/g' "$output_file"
}
# Function to collect system information
collect_system_info() {
print_message "π₯οΈ Collecting system information..." "$BLUE"
# Create system info directory
mkdir -p "$OUTPUT_DIR/system"
# Basic system info
uname -a > "$OUTPUT_DIR/system/uname.txt"
cat /etc/os-release > "$OUTPUT_DIR/system/os-release.txt"
lscpu > "$OUTPUT_DIR/system/cpu-info.txt"
free -h > "$OUTPUT_DIR/system/memory.txt"
df -h > "$OUTPUT_DIR/system/disk-space.txt"
# Check if lshw is installed
if command -v lshw &> /dev/null; then
lshw -short > "$OUTPUT_DIR/system/hardware.txt" 2>/dev/null
else
echo "lshw not installed" > "$OUTPUT_DIR/system/hardware.txt"
fi
# Network info (masked)
ip a | sed 's/inet [0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/inet xxx.xxx.xxx.xxx/g' > "$OUTPUT_DIR/system/network.txt"
# Kernel modules related to sound
lsmod | grep -E 'snd|sound' > "$OUTPUT_DIR/system/sound-modules.txt"
# Environment variables (masked)
env | grep -v -E 'PASSWORD|TOKEN|KEY|SECRET' > "$OUTPUT_DIR/system/environment.txt"
}
# Function to collect Docker information
collect_docker_info() {
print_message "π³ Collecting Docker information..." "$BLUE"
# Create docker info directory
mkdir -p "$OUTPUT_DIR/docker"
# Check if Docker is installed
if ! command -v docker &> /dev/null; then
echo "Docker is not installed" > "$OUTPUT_DIR/docker/not-installed.txt"
print_message "β Docker not found" "$RED"
return
fi
# Check if Docker daemon is running
if ! docker info &>/dev/null; then
echo "Docker daemon is not running" > "$OUTPUT_DIR/docker/not-running.txt"
print_message "β Docker daemon is not running" "$RED"
systemctl status docker.service > "$OUTPUT_DIR/docker/docker-service-status.txt" 2>&1
return
fi
# Docker version
docker version > "$OUTPUT_DIR/docker/version.txt" 2>&1
docker info > "$OUTPUT_DIR/docker/info.txt" 2>&1
# Docker images (all and then BirdNET-specific)
docker images > "$OUTPUT_DIR/docker/images-all.txt" 2>&1
docker images | grep -E 'birdnet-go|ghcr.io/tphakala/birdnet-go' > "$OUTPUT_DIR/docker/images-birdnet.txt" 2>&1
# Docker containers
docker ps -a > "$OUTPUT_DIR/docker/containers-all.txt" 2>&1
docker ps -a | grep -E 'birdnet-go|ghcr.io/tphakala/birdnet-go' > "$OUTPUT_DIR/docker/containers-birdnet.txt" 2>&1
# Check for multiple BirdNET containers
CONTAINER_COUNT=$(docker ps -a | grep -c -E 'birdnet-go|ghcr.io/tphakala/birdnet-go')
if [ "$CONTAINER_COUNT" -gt 0 ]; then
# List all container IDs
mapfile -t CONTAINER_IDS < <(docker ps -a | grep -E 'birdnet-go|ghcr.io/tphakala/birdnet-go' | awk '{print $1}')
# Information about each container
echo "Found $CONTAINER_COUNT BirdNET-Go containers" > "$OUTPUT_DIR/docker/container-count.txt"
# Process each container
for i in "${!CONTAINER_IDS[@]}"; do
CONTAINER_ID="${CONTAINER_IDS[$i]}"
CONTAINER_DIR="$OUTPUT_DIR/docker/container-$((i+1))"
mkdir -p "$CONTAINER_DIR"
# Basic container info
docker inspect "$CONTAINER_ID" > "$CONTAINER_DIR/inspect.txt" 2>&1
# Container status
docker ps -a --filter "id=$CONTAINER_ID" --format "{{.ID}} {{.Image}} {{.Status}} {{.Names}}" > "$CONTAINER_DIR/status.txt"
# Only collect logs for running containers
if docker ps --filter "id=$CONTAINER_ID" | grep -q "$CONTAINER_ID"; then
# Container logs (filtered to remove sensitive info and limited to 1000 lines)
docker logs "$CONTAINER_ID" 2>&1 | grep -v -E 'password|token|key|secret' | head -n 1000 > "$CONTAINER_DIR/logs.txt"
# Add a note if logs were truncated
if [ "$(docker logs "$CONTAINER_ID" 2>/dev/null | wc -l)" -gt 1000 ]; then
echo -e "\n... Log truncated (showing first 1000 lines only) ..." >> "$CONTAINER_DIR/logs.txt"
fi
# Get container name for journald logs
CONTAINER_NAME=$(docker inspect --format='{{.Name}}' "$CONTAINER_ID" | sed 's/^\///')
# Collect journald logs for this container if available
if command -v journalctl &>/dev/null; then
journalctl -u docker.service --no-pager -n 1000 | grep -E "$CONTAINER_ID|$CONTAINER_NAME" > "$CONTAINER_DIR/journald-logs.txt" 2>&1
if [ -s "$CONTAINER_DIR/journald-logs.txt" ]; then
echo "Collected journald logs for container $CONTAINER_NAME ($CONTAINER_ID)" >> "$CONTAINER_DIR/logs-summary.txt"
else
echo "No journald logs found for container $CONTAINER_NAME ($CONTAINER_ID)" >> "$CONTAINER_DIR/logs-summary.txt"
rm -f "$CONTAINER_DIR/journald-logs.txt"
fi
fi
else
echo "Container not running - no logs collected" > "$CONTAINER_DIR/logs.txt"
fi
# Get container configuration details
docker inspect --format='{{.Config.Cmd}}' "$CONTAINER_ID" > "$CONTAINER_DIR/cmd.txt" 2>&1
docker inspect --format='{{.HostConfig.Devices}}' "$CONTAINER_ID" > "$CONTAINER_DIR/devices.txt" 2>&1
docker inspect --format='{{.HostConfig.Binds}}' "$CONTAINER_ID" > "$CONTAINER_DIR/volumes.txt" 2>&1
docker inspect --format='{{.HostConfig.PortBindings}}' "$CONTAINER_ID" > "$CONTAINER_DIR/ports.txt" 2>&1
docker inspect --format='{{.State.Status}}' "$CONTAINER_ID" > "$CONTAINER_DIR/state.txt" 2>&1
# Get container environment variables (masked)
docker inspect --format='{{range .Config.Env}}{{.}}{{"\n"}}{{end}}' "$CONTAINER_ID" | grep -v -E 'PASSWORD|TOKEN|KEY|SECRET' > "$CONTAINER_DIR/environment.txt" 2>&1
done
else
echo "No BirdNET-Go container found" > "$OUTPUT_DIR/docker/no-container.txt"
print_message "β οΈ No BirdNET-Go container found" "$YELLOW"
fi
}
# Function to collect BirdNET-Go configuration
collect_birdnet_config() {
print_message "π Collecting BirdNET-Go configuration..." "$BLUE"
# Create config directory
mkdir -p "$OUTPUT_DIR/config"
# Common config paths
CONFIG_PATHS=(
"/home/*/birdnet-go-app/config/config.yaml"
"/root/.config/birdnet-go/config.yaml"
"/config/config.yaml" # Docker volume common path
)
# Find config files
CONFIG_FOUND=false
for CONFIG_PATH in "${CONFIG_PATHS[@]}"; do
for CONFIG_FILE in $CONFIG_PATH; do
if [ -f "$CONFIG_FILE" ]; then
mask_sensitive_data "$CONFIG_FILE" "$OUTPUT_DIR/config/config.yaml"
echo "Found config at: $CONFIG_FILE" >> "$OUTPUT_DIR/config/path.txt"
CONFIG_FOUND=true
# Also check for backup configs
BACKUP_DIR=$(dirname "$CONFIG_FILE")
if ls "$BACKUP_DIR"/config.yaml.*.backup &>/dev/null; then
mkdir -p "$OUTPUT_DIR/config/backups"
for BACKUP in "$BACKUP_DIR"/config.yaml.*.backup; do
BACKUP_NAME=$(basename "$BACKUP")
mask_sensitive_data "$BACKUP" "$OUTPUT_DIR/config/backups/$BACKUP_NAME"
echo "Found backup config: $BACKUP" >> "$OUTPUT_DIR/config/path.txt"
done
fi
fi
done
done
# Try to find any birdnet-go config files if not found in common locations
if [ "$CONFIG_FOUND" = false ]; then
while IFS= read -r file; do
if [ -n "$file" ]; then
# Create directory based on parent dir name
CONFIG_DIR="$OUTPUT_DIR/config/$(basename "$(dirname "$file")")"
mkdir -p "$CONFIG_DIR"
# Safely mask and copy the file
mask_sensitive_data "$file" "$CONFIG_DIR/config.yaml"
echo "Found config at: $file" >> "$OUTPUT_DIR/config/path.txt"
CONFIG_FOUND=true
fi
done < <(find / -name "config.yaml" -path "*birdnet-go*" -o -path "*/.config/birdnet-go/*" 2>/dev/null)
fi
if [ "$CONFIG_FOUND" = false ]; then
echo "No BirdNET-Go configuration files found" > "$OUTPUT_DIR/config/not-found.txt"
print_message "β οΈ No BirdNET-Go configuration files found" "$YELLOW"
fi
}
# Function to collect systemd service information
collect_systemd_info() {
print_message "π Collecting systemd service information..." "$BLUE"
# Create systemd directory
mkdir -p "$OUTPUT_DIR/systemd"
# Check if journalctl is available and collect tagged logs
if command -v journalctl &>/dev/null; then
journalctl -t birdnet-go --no-pager -n 1000 > "$OUTPUT_DIR/systemd/birdnet-go-tagged-logs.txt" 2>&1
if [ ! -s "$OUTPUT_DIR/systemd/birdnet-go-tagged-logs.txt" ]; then
# Remove empty file
rm "$OUTPUT_DIR/systemd/birdnet-go-tagged-logs.txt"
echo "No logs found with tag 'birdnet-go'" > "$OUTPUT_DIR/systemd/birdnet-go-tagged-logs-status.txt"
else
echo "Collected logs tagged with 'birdnet-go'" > "$OUTPUT_DIR/systemd/birdnet-go-tagged-logs-status.txt"
fi
else
echo "journalctl command not found, cannot collect tagged logs" > "$OUTPUT_DIR/systemd/journalctl-not-found.txt"
fi
# Check for BirdNET-Go service file specifically
if systemctl list-unit-files | grep -q birdnet-go.service; then
# Service status
systemctl status birdnet-go.service > "$OUTPUT_DIR/systemd/status.txt" 2>&1
# Service logs (limit to 1000 lines) using -u
if command -v journalctl &>/dev/null; then
journalctl -u birdnet-go.service --no-pager -n 1000 > "$OUTPUT_DIR/systemd/service-unit-logs.txt" 2>&1
if [ ! -s "$OUTPUT_DIR/systemd/service-unit-logs.txt" ]; then
# Remove empty file
rm "$OUTPUT_DIR/systemd/service-unit-logs.txt"
fi
fi
# Service configuration file
SERVICE_FILE_PATH=$(systemctl show -p FragmentPath birdnet-go.service | cut -d= -f2)
if [ -n "$SERVICE_FILE_PATH" ] && [ -f "$SERVICE_FILE_PATH" ]; then
cp "$SERVICE_FILE_PATH" "$OUTPUT_DIR/systemd/service-file.txt" 2>/dev/null
echo "Copied service file from $SERVICE_FILE_PATH" >> "$OUTPUT_DIR/systemd/service-file-status.txt"
elif [ -f /etc/systemd/system/birdnet-go.service ]; then
# Fallback to common location
cp /etc/systemd/system/birdnet-go.service "$OUTPUT_DIR/systemd/service-file.txt" 2>/dev/null
echo "Copied service file from /etc/systemd/system/birdnet-go.service" >> "$OUTPUT_DIR/systemd/service-file-status.txt"
else
echo "Could not find or copy systemd service file" > "$OUTPUT_DIR/systemd/service-file-status.txt"
fi
else
echo "BirdNET-Go systemd service unit file not found" > "$OUTPUT_DIR/systemd/service-unit-not-found.txt"
print_message "βΉοΈ BirdNET-Go systemd service unit file not found (this is expected for Docker installs)" "$BLUE"
fi
# Check Docker service status (always useful)
if systemctl list-unit-files | grep -q docker.service; then
systemctl status docker.service > "$OUTPUT_DIR/systemd/docker-status.txt" 2>&1
if command -v journalctl &>/dev/null; then
journalctl -u docker.service --no-pager -n 100 > "$OUTPUT_DIR/systemd/docker-logs.txt" 2>&1
if [ ! -s "$OUTPUT_DIR/systemd/docker-logs.txt" ]; then
# Remove empty file
rm "$OUTPUT_DIR/systemd/docker-logs.txt"
fi
fi
fi
}
# Function to collect audio device information
collect_audio_info() {
print_message "π€ Collecting audio device information..." "$BLUE"
# Create audio directory
mkdir -p "$OUTPUT_DIR/audio"
# Check if arecord is installed
if command -v arecord &> /dev/null; then
# Force English locale for consistent output
LC_ALL=C arecord -l > "$OUTPUT_DIR/audio/devices.txt" 2>&1
LC_ALL=C arecord -L > "$OUTPUT_DIR/audio/device-list.txt" 2>&1
else
echo "arecord not installed" > "$OUTPUT_DIR/audio/not-installed.txt"
fi
# Get audio groups and users
getent group audio > "$OUTPUT_DIR/audio/audio-group.txt" 2>&1
# ALSA config
if [ -f /etc/asound.conf ]; then
cp /etc/asound.conf "$OUTPUT_DIR/audio/asound.conf" 2>/dev/null
fi
# PulseAudio/PipeWire info if available
if command -v pactl &> /dev/null; then
pactl info > "$OUTPUT_DIR/audio/pulseaudio-info.txt" 2>&1
pactl list sources > "$OUTPUT_DIR/audio/pulseaudio-sources.txt" 2>&1
fi
# Check access to audio devices
ls -la /dev/snd/ > "$OUTPUT_DIR/audio/snd-devices.txt" 2>&1
}
# Function to collect install script information
collect_install_info() {
print_message "π¦ Collecting installation information..." "$BLUE"
# Create install directory
mkdir -p "$OUTPUT_DIR/install"
# Look for install.sh in common locations
INSTALL_PATHS=(
"/home/*/install.sh"
"/root/install.sh"
"/tmp/install.sh"
"/home/*/go/src/github.com/tphakala/birdnet-go/install.sh" # Common dev location
)
INSTALL_FOUND=false
for INSTALL_PATH in "${INSTALL_PATHS[@]}"; do
for INSTALL_FILE in $INSTALL_PATH; do
if [ -f "$INSTALL_FILE" ]; then
cp "$INSTALL_FILE" "$OUTPUT_DIR/install/install.sh" 2>/dev/null
echo "Found install.sh at: $INSTALL_FILE" >> "$OUTPUT_DIR/install/path.txt"
# Check install.sh version by looking for a version string
if grep -q "BIRDNET_GO_VERSION=" "$INSTALL_FILE"; then
grep "BIRDNET_GO_VERSION=" "$INSTALL_FILE" > "$OUTPUT_DIR/install/version.txt"
fi
INSTALL_FOUND=true
fi
done
done
# Check when install.sh was run
if [ -f /var/log/auth.log ]; then
grep -E "sudo.*install.sh|bash.*install.sh" /var/log/auth.log > "$OUTPUT_DIR/install/auth-log-entries.txt" 2>/dev/null
fi
if [ "$INSTALL_FOUND" = false ]; then
echo "No install.sh file found" > "$OUTPUT_DIR/install/not-found.txt"
print_message "β οΈ No install.sh file found" "$YELLOW"
fi
}
# Function to collect BirdNET-Go application logs
collect_birdnet_logs() {
print_message "π Collecting BirdNET-Go application logs..." "$BLUE"
# Create log directory
mkdir -p "$OUTPUT_DIR/birdnet-logs"
# Potential log directories
POTENTIAL_LOG_DIRS=(
"$HOME/.config/birdnet-go/logs"
"/etc/birdnet-go/logs"
# Add other potential common locations if known
)
LOGS_FOUND=false
for log_dir in "${POTENTIAL_LOG_DIRS[@]}"; do
# Expand tilde if present
expanded_log_dir=$(eval echo "$log_dir")
if [ -d "$expanded_log_dir" ]; then
print_message " Checking directory: $expanded_log_dir" "$BLUE" "nonewline"
# Check if directory contains .log files
if find "$expanded_log_dir" -maxdepth 1 -name '*.log' -print -quit | grep -q .; then
echo " - Found logs."
# Copy log files
cp -a "$expanded_log_dir"/*.log "$OUTPUT_DIR/birdnet-logs/" 2>/dev/null
# Add source information
echo "Copied *.log files from: $expanded_log_dir" >> "$OUTPUT_DIR/birdnet-logs/sources.txt"
LOGS_FOUND=true
else
echo " - No .log files found."
fi
fi
done
if [ "$LOGS_FOUND" = false ]; then
echo "No BirdNET-Go application log files found in standard locations." > "$OUTPUT_DIR/birdnet-logs/not-found.txt"
print_message "β οΈ No BirdNET-Go application log files found." "$YELLOW"
fi
}
# Function to bundle everything into a tarball
create_support_bundle() {
print_message "π¦ Creating support bundle..." "$BLUE"
# Add a README file
cat > "$OUTPUT_DIR/README.txt" << EOF
BirdNET-Go Support Data
=======================
Collected on: $(date)
Hostname: $(hostname)
System: $(grep PRETTY_NAME /etc/os-release | cut -d'"' -f2)
This archive contains diagnostic information for troubleshooting BirdNET-Go issues.
Sensitive information such as passwords, tokens, and IP addresses has been masked.
Contents:
- system/: System information (OS, CPU, memory, etc.)
- docker/: Docker configuration and logs
- config/: BirdNET-Go configuration files
- systemd/: Systemd service information
- audio/: Audio device information
- install/: Installation information
Please share this file with the BirdNET-Go developers.
EOF
# Create tarball with error checking
if ! tar -czf "$OUTPUT_FILE" -C "$(dirname "$OUTPUT_DIR")" "$(basename "$OUTPUT_DIR")"; then
print_message "β Failed to create support bundle tarball." "$RED"
print_message "Please check disk space and permissions." "$YELLOW"
# Don't remove the output directory so data isn't lost
trap - EXIT
exit 1
fi
# Set permissions so normal user can access it
if ! chmod 644 "$OUTPUT_FILE"; then
print_message "β οΈ Failed to set permissions on support bundle." "$YELLOW"
print_message "The bundle was created at $OUTPUT_FILE but may have restricted permissions." "$YELLOW"
fi
# Clean up
rm -rf "$OUTPUT_DIR"
print_message "β
Support bundle created: $OUTPUT_FILE" "$GREEN"
print_message "π Please share this file with the BirdNET-Go developers." "$GREEN"
# Prevent cleanup function from running since we manually cleaned up
trap - EXIT
}
# Main execution
print_message "π Starting data collection process..." "$GREEN"
# Create a flag file to track successful script completion
touch "$OUTPUT_DIR/.collection_in_progress"
# Catch errors during collection
set -e
collect_system_info || { print_message "β Error collecting system information" "$RED"; }
collect_docker_info || { print_message "β Error collecting Docker information" "$RED"; }
collect_birdnet_config || { print_message "β Error collecting BirdNET configuration" "$RED"; }
collect_systemd_info || { print_message "β Error collecting systemd information" "$RED"; }
collect_audio_info || { print_message "β Error collecting audio information" "$RED"; }
collect_install_info || { print_message "β Error collecting installation information" "$RED"; }
collect_birdnet_logs || { print_message "β Error collecting BirdNET-Go application logs" "$RED"; }
# Return to normal error handling
set +e
create_support_bundle
print_message "\nβ
Data collection complete!" "$GREEN"
print_message "π¦ Support bundle: $OUTPUT_FILE" "$BLUE"
print_message "π Thank you for helping improve BirdNET-Go!" "$GREEN"