Files
irs/registries-v4.sh
2026-05-03 12:47:48 +00:00

219 lines
8.7 KiB
Bash
Executable File

#!/bin/bash
# Color codes for better output readability
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# Array of registries to test
mapfile -t registries < <(
curl -fsSL "https://gitamin.ir/smx/irs/raw/branch/main/registries.md" \
| grep -oP '"\Khttps?://[^"]+' \
| sed 's|^https://||'
)
# Timeout in seconds
# Warn if no timeout provided
if [ -z "$TIMEOUT" ] && [ -z "$1" ]; then
echo "Warning: No timeout specified, using default 14 seconds"
echo "Usage: TIMEOUT=30 curl ... | bash"
echo " or: curl ... | bash -s -- 30"
fi
TIMEOUT="${TIMEOUT:-${1:-14}}"
timeout $TIMEOUT
# Function to format time with milliseconds
format_time() {
local seconds=$1
if (( $(echo "$seconds < 0.1" | bc -l 2>/dev/null || echo "0") )); then
printf "%.0fms" "$(echo "$seconds * 1000" | bc 2>/dev/null || echo "0")"
else
printf "%.2fs" "$seconds"
fi
}
# Function to test a single registry
test_registry() {
local registry=$1
local timeout=$2
echo -e "\n${CYAN}Testing:${NC} ${YELLOW}${registry}${NC}"
echo "──────────────────────────────────────────────"
# Create temporary file for response headers and body
local temp_file=$(mktemp)
local headers_file=$(mktemp)
# Measure time and capture response
local start_time=$(date +%s.%N)
# Attempt connection with detailed output capture
local http_code=$(curl -s -w "%{http_code}" \
-o "$temp_file" \
-D "$headers_file" \
--max-time "$timeout" \
--connect-timeout "$timeout" \
"${registry}/v2/" 2>&1)
local end_time=$(date +%s.%N)
local elapsed=$(echo "$end_time - $start_time" | bc 2>/dev/null || echo "0")
local formatted_time=$(format_time "$elapsed")
# Check if curl succeeded or failed
local curl_exit_code=$?
# Parse response
if [ $curl_exit_code -eq 0 ]; then
# Success - got HTTP response
echo -e " ${BLUE}Response Time:${NC} ${formatted_time}"
echo -e " ${BLUE}HTTP Status:${NC} ${http_code}"
# Check for Docker-Distribution-API-Version header
local api_version=$(grep -i "^Docker-Distribution-Api-Version:" "$headers_file" | cut -d' ' -f2 | tr -d '\r')
if [ -n "$api_version" ]; then
echo -e " ${BLUE}API Version:${NC} ${api_version}"
fi
# Analyze response based on HTTP code
case $http_code in
200)
echo -e " ${GREEN}✓ Status:${NC} Registry is fully accessible (no auth required)"
echo -e " ${GREEN}✓ Message:${NC} Connection successful - ready to pull"
rm -f "$temp_file" "$headers_file"
return 0
;;
401)
echo -e " ${GREEN}✓ Status:${NC} Registry is accessible (authentication required)"
# Check for WWW-Authenticate header
local auth_header=$(grep -i "^WWW-Authenticate:" "$headers_file" | cut -d' ' -f2- | tr -d '\r')
if [ -n "$auth_header" ]; then
echo -e " ${BLUE}Auth Method:${NC} ${auth_header:0:50}..."
fi
echo -e " ${GREEN}✓ Message:${NC} Ready to pull (login required)"
rm -f "$temp_file" "$headers_file"
return 0
;;
403)
echo -e " ${YELLOW}⚠ Status:${NC} Access forbidden"
local body=$(cat "$temp_file" | head -c 200)
if [ -n "$body" ]; then
echo -e " ${YELLOW}⚠ Message:${NC} ${body}"
else
echo -e " ${YELLOW}⚠ Message:${NC} Authentication required or IP restricted"
fi
rm -f "$temp_file" "$headers_file"
return 1
;;
404)
echo -e " ${RED}✗ Status:${NC} Registry API endpoint not found"
echo -e " ${RED}✗ Message:${NC} This may not be a valid Docker registry or /v2/ endpoint is disabled"
rm -f "$temp_file" "$headers_file"
return 1
;;
50[0-9])
echo -e " ${RED}✗ Status:${NC} Registry server error"
echo -e " ${RED}✗ Message:${NC} Registry is experiencing issues (HTTP $http_code)"
rm -f "$temp_file" "$headers_file"
return 1
;;
*)
echo -e " ${YELLOW}⚠ Status:${NC} Unexpected HTTP response"
echo -e " ${YELLOW}⚠ Message:${NC} HTTP $http_code - check registry configuration"
rm -f "$temp_file" "$headers_file"
return 1
;;
esac
else
# Curl failed - connection issue
echo -e " ${BLUE}Response Time:${NC} ${formatted_time}"
echo -e " ${BLUE}HTTP Status:${NC} ${RED}Connection Failed${NC}"
case $curl_exit_code in
6)
echo -e " ${RED}✗ Error:${NC} Could not resolve hostname (DNS failure)"
echo -e " ${RED}✗ Message:${NC} Check registry URL or DNS configuration"
;;
7)
echo -e " ${RED}✗ Error:${NC} Failed to connect to host"
echo -e " ${RED}✗ Message:${NC} Firewall blocking or registry is down"
;;
28)
echo -e " ${RED}✗ Error:${NC} Connection timeout after ${timeout}s"
echo -e " ${RED}✗ Message:${NC} Network too slow or registry unresponsive"
;;
35)
echo -e " ${RED}✗ Error:${NC} SSL/TLS connection failed"
echo -e " ${RED}✗ Message:${NC} Certificate issue or registry requires different SSL settings"
;;
60)
echo -e " ${RED}✗ Error:${NC} SSL certificate problem"
echo -e " ${RED}✗ Message:${NC} Certificate is invalid or self-signed"
;;
*)
echo -e " ${RED}✗ Error:${NC} Connection failed (curl exit code: $curl_exit_code)"
echo -e " ${RED}✗ Message:${NC} Unknown connection error"
;;
esac
# Try to get more details if available
if [ -s "$temp_file" ]; then
local error_output=$(cat "$temp_file" | head -c 200)
if [ -n "$error_output" ]; then
echo -e " ${BLUE}Details:${NC} $error_output"
fi
fi
rm -f "$temp_file" "$headers_file"
return 1
fi
}
# Main execution
echo -e "${CYAN}╔══════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║ Docker Registry Connectivity Test Script ║${NC}"
echo -e "${CYAN}╚══════════════════════════════════════════════════════════╝${NC}"
echo -e "${BLUE}Timeout setting:${NC} ${TIMEOUT}s"
echo -e "${BLUE}Started at:${NC} $(date '+%Y-%m-%d %H:%M:%S')\n"
# Test all registries
total=${#registries[@]}
successful=0
failed=0
declare -a failed_registries
for reg in "${registries[@]}"; do
if test_registry "$reg" "$TIMEOUT"; then
((successful++))
else
((failed++))
failed_registries+=("$reg")
fi
done
# Summary report
echo -e "\n${CYAN}════════════════════════════════════════════════════════════${NC}"
echo -e "${CYAN} SUMMARY REPORT ${NC}"
echo -e "${CYAN}════════════════════════════════════════════════════════════${NC}"
echo -e "${BLUE}Total Registries Tested:${NC} $total"
echo -e "${GREEN}✓ Successfully Reachable:${NC} $successful"
echo -e "${RED}✗ Failed/Unreachable:${NC} $failed"
if [ $failed -gt 0 ]; then
echo -e "\n${RED}Failed Registries:${NC}"
for failed_reg in "${failed_registries[@]}"; do
echo -e " ${RED}${NC} $failed_reg"
done
echo -e "\n${YELLOW}⚠ WARNING:${NC} $failed registry/ies are unreachable"
echo -e "${YELLOW}Recommendation:${NC} Check network connectivity or registry status before pulling images"
exit 1
else
echo -e "\n${GREEN}✓ SUCCESS:${NC} All registries are reachable!"
echo -e "${GREEN}✓ Ready to proceed with Docker pulls${NC}"
exit 0
fi