Files
sless/test_pearlharbor_push.sh
T

125 lines
4.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# 2026-03-11 12:30
# Наборный тест: собирает образ, выполняет несколько пушей с разными тегами
# и выводит статистику (количество успешных/проваленных, время и попытки).
set -euo pipefail
SECRETS_FILE="secrets/pearlharbor_registry.txt"
if [ ! -f "$SECRETS_FILE" ]; then
echo "secrets file not found: $SECRETS_FILE" >&2
exit 1
fi
NUM_PUSHES=${NUM_PUSHES:-5}
RETRIES_PER_PUSH=${RETRIES_PER_PUSH:-3}
BACKOFF=${BACKOFF:-2}
PROJECT=${PROJECT:-pearlharbor}
REGISTRY_USER=${REGISTRY_USER:-admin}
CREATE_PROJECT=${CREATE_PROJECT:-false}
CLEANUP=${CLEANUP:-false}
connection_url=$(grep -E '^connection_url=' "$SECRETS_FILE" | cut -d'=' -f2-)
admin_pass=$(grep -E '^admin_pass=' "$SECRETS_FILE" | cut -d'=' -f2-)
registry=$(echo "$connection_url" | sed -E 's~https?://~~' | sed -E 's~/$~~')
if ! command -v docker >/dev/null 2>&1; then
echo "docker not found" >&2
exit 2
fi
echo "Registry: $registry"
echo "Project: $PROJECT"
echo "Pushes: $NUM_PUSHES, retries per push: $RETRIES_PER_PUSH"
echo "Building local image..."
docker build -t sless-sample:local -f examples/push-sample/Dockerfile examples/push-sample
if [ "$CREATE_PROJECT" = "true" ]; then
echo "Ensuring project $PROJECT exists..."
create_code=$(curl -s -u "$REGISTRY_USER:$admin_pass" -o /dev/null -w "%{http_code}" -X POST "https://$registry/api/v2.0/projects" -H 'Content-Type: application/json' -d "{\"project_name\":\"$PROJECT\",\"metadata\":{\"public\":\"true\"}}") || create_code=0
echo "Project create response: $create_code"
fi
echo "Logging in to registry..."
if ! echo "$admin_pass" | docker login "$registry" -u "$REGISTRY_USER" --password-stdin >/dev/null 2>&1; then
echo "docker login failed" >&2
exit 3
fi
results=()
pushed_tags=()
start_all=$(date +%s.%N)
for i in $(seq 1 "$NUM_PUSHES"); do
tag="test-$(date +%Y%m%d%H%M%S)-$i"
remote="$registry/$PROJECT/sless-sample:$tag"
echo "\n=== Push $i/$NUM_PUSHES -> $remote ==="
docker tag sless-sample:local "$remote"
attempt=0
success=0
t_start=$(date +%s.%N)
last_err=""
while [ $attempt -lt $RETRIES_PER_PUSH ]; do
attempt=$((attempt+1))
echo "Attempt $attempt for $remote"
if docker push "$remote"; then
success=1
break
else
last_err="push failed on attempt $attempt"
sleep_time=$((BACKOFF ** attempt))
echo "push failed, sleeping $sleep_time s"
sleep $sleep_time
fi
done
t_end=$(date +%s.%N)
elapsed=$(printf "%.3f" "$(echo "$t_end - $t_start" | bc -l)")
results+=("$remote|$success|$attempt|$elapsed|$last_err")
pushed_tags+=("$tag")
done
end_all=$(date +%s.%N)
total_time=$(printf "%.3f" "$(echo "$end_all - $start_all" | bc -l)")
echo "\n=== Summary ==="
echo "Total pushes: $NUM_PUSHES, total time: ${total_time}s"
printf "%s\n" "TAG | SUCCESS | ATTEMPTS | TIME_S | MESSAGE"
for r in "${results[@]}"; do
IFS='|' read -r tag ok attempts time msg <<< "$r"
if [ "$ok" -eq 1 ]; then ok_str="OK"; else ok_str="FAIL"; fi
printf "%s | %s | %s | %s | %s\n" "$tag" "$ok_str" "$attempts" "$time" "${msg:--}"
done
fail_count=0
for r in "${results[@]}"; do
IFS='|' read -r tag ok attempts time msg <<< "$r"
if [ "$ok" -ne 1 ]; then fail_count=$((fail_count+1)); fi
done
echo "Failures: $fail_count / $NUM_PUSHES"
if [ "$CLEANUP" = "true" ]; then
echo "\nCleaning up pushed tags..."
del_fail=0
for t in "${pushed_tags[@]}"; do
echo "Deleting tag: $t"
code=$(curl -s -u "$REGISTRY_USER:$admin_pass" -o /dev/null -w "%{http_code}" -X DELETE "https://$registry/api/v2.0/projects/$PROJECT/repositories/sless-sample/artifacts/$t" ) || code=0
if [ "$code" = "200" ] || [ "$code" = "202" ] || [ "$code" = "204" ]; then
echo " -> deleted (HTTP $code)"
else
echo " -> delete failed (HTTP $code)"
del_fail=1
fi
done
if [ $del_fail -ne 0 ]; then
echo "Cleanup had failures" >&2
else
echo "Cleanup completed"
fi
fi
if [ "$fail_count" -ne 0 ]; then
exit 4
fi
exit 0