33800 Docs

← Retour
#!/usr/bin/env bash # ─────────────────────────────────────────────────────────────────────────── # hooks.sh - Pre/post deploy hooks for smart-deploy # Supports: http, wait_http, shell, ssh actions # ─────────────────────────────────────────────────────────────────────────── # Run all hooks for a given phase (pre_deploy or post_deploy) # Usage: run_hooks "pre_deploy" | run_hooks "post_deploy" run_hooks() { local phase="$1" local count_var="HOOKS_${phase}_COUNT" local count="${!count_var:-0}" if [[ $count -eq 0 ]]; then return 0 fi log_step "Execution des hooks ${phase} (${count} action(s))..." for ((i=0; i<count; i++)); do local action_var="HOOKS_${phase}_${i}_action" local desc_var="HOOKS_${phase}_${i}_description" local action="${!action_var:-}" local description="${!desc_var:-hook ${i}}" if [[ -z "$action" ]]; then log_warning "Hook ${phase}[${i}]: action manquante, ignoré" continue fi log_info " [${phase}] ${description}" case "$action" in http) _run_hook_http "$phase" "$i" ;; wait_http) _run_hook_wait_http "$phase" "$i" ;; shell) _run_hook_shell "$phase" "$i" ;; ssh) _run_hook_ssh "$phase" "$i" ;; *) log_warning "Hook ${phase}[${i}]: action inconnue '${action}', ignoré" continue ;; esac local rc=$? if [[ $rc -ne 0 ]]; then local optional_var="HOOKS_${phase}_${i}_optional" local is_optional="${!optional_var:-false}" if [[ "$is_optional" == "true" ]]; then log_warning "Hook ${phase}[${i}] echoue (${description}) - optionnel, deploiement continue" elif [[ "$phase" == "pre_deploy" ]]; then log_error "Hook ${phase}[${i}] echoue (${description}) - deploiement annule" return 1 else log_warning "Hook ${phase}[${i}] echoue (${description}) - deploiement continue" fi fi done log_success "Hooks ${phase} termines" return 0 } # ─── HTTP request (fire & forget) ─── _run_hook_http() { local phase="$1" local idx="$2" local method_var="HOOKS_${phase}_${idx}_method" local url_var="HOOKS_${phase}_${idx}_url" local body_var="HOOKS_${phase}_${idx}_body" local timeout_var="HOOKS_${phase}_${idx}_timeout" local method="${!method_var:-GET}" local url="${!url_var:-}" local body="${!body_var:-}" local timeout="${!timeout_var:-30}" if [[ -z "$url" ]]; then log_error "Hook http: url manquante" return 1 fi # Resolve relative URLs url=$(_resolve_hook_url "$url") local curl_args=(-s -S -X "$method" --connect-timeout 10 --max-time "$timeout") if [[ -n "$body" ]]; then curl_args+=(-H "Content-Type: application/json" -d "$body") fi local response response=$(curl "${curl_args[@]}" -w "\n%{http_code}" "$url" 2>&1) local http_code http_code=$(echo "$response" | tail -1) local body_response body_response=$(echo "$response" | head -n -1) if [[ "$http_code" -ge 200 ]] && [[ "$http_code" -lt 300 ]]; then log_info " -> HTTP ${http_code} OK" return 0 else log_error " -> HTTP ${http_code}: ${body_response}" return 1 fi } # ─── HTTP poll with jq condition ─── _run_hook_wait_http() { local phase="$1" local idx="$2" local method_var="HOOKS_${phase}_${idx}_method" local url_var="HOOKS_${phase}_${idx}_url" local jq_var="HOOKS_${phase}_${idx}_jq_condition" local timeout_var="HOOKS_${phase}_${idx}_timeout" local interval_var="HOOKS_${phase}_${idx}_interval" local method="${!method_var:-GET}" local url="${!url_var:-}" local jq_condition="${!jq_var:-}" local timeout="${!timeout_var:-60}" local interval="${!interval_var:-5}" if [[ -z "$url" ]]; then log_error "Hook wait_http: url manquante" return 1 fi if [[ -z "$jq_condition" ]]; then log_error "Hook wait_http: jq_condition manquante" return 1 fi # Check jq is available if ! command -v jq &>/dev/null; then log_error "Hook wait_http: 'jq' requis mais non installe" return 1 fi # Cap timeout at 300s if [[ $timeout -gt 300 ]]; then timeout=300 fi url=$(_resolve_hook_url "$url") local start_time start_time=$(date +%s) while true; do local elapsed=$(( $(date +%s) - start_time )) if [[ $elapsed -ge $timeout ]]; then log_error " -> Timeout apres ${timeout}s" return 1 fi local response response=$(curl -s -X "$method" --connect-timeout 5 --max-time 10 "$url" 2>/dev/null) if [[ -n "$response" ]]; then local check check=$(echo "$response" | jq -r "$jq_condition" 2>/dev/null) if [[ "$check" == "true" ]]; then log_info " -> Condition remplie apres ${elapsed}s" return 0 fi fi log_info " -> En attente... (${elapsed}/${timeout}s)" sleep "$interval" done } # ─── Shell command (local) ─── _run_hook_shell() { local phase="$1" local idx="$2" local cmd_var="HOOKS_${phase}_${idx}_command" local command="${!cmd_var:-}" if [[ -z "$command" ]]; then log_error "Hook shell: command manquante" return 1 fi eval "$command" return $? } # ─── SSH command (on target) ─── _run_hook_ssh() { local phase="$1" local idx="$2" local cmd_var="HOOKS_${phase}_${idx}_command" local command="${!cmd_var:-}" if [[ -z "$command" ]]; then log_error "Hook ssh: command manquante" return 1 fi if [[ -z "${TARGET_HOST:-}" ]] || [[ -z "${TARGET_USER:-}" ]]; then log_error "Hook ssh: TARGET_HOST/TARGET_USER non definis" return 1 fi ssh_exec "$TARGET_HOST" "$TARGET_USER" "$command" return $? } # ─── Resolve relative URLs ─── _resolve_hook_url() { local url="$1" if [[ "$url" =~ ^/ ]]; then # Relative URL: prefix with target host and port local host="${TARGET_HOST:-localhost}" local port="${CFG_port:-80}" echo "http://${host}:${port}${url}" else echo "$url" fi }