diff --git a/Dockerfile.master b/Dockerfile.master index 530c173..b43f954 100644 --- a/Dockerfile.master +++ b/Dockerfile.master @@ -29,6 +29,9 @@ RUN apt-get update && apt-get upgrade -y && \ cron \ logrotate \ openssl \ + procps \ + ncurses-bin \ + ncurses-term \ && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* diff --git a/docker-compose.yml b/docker-compose.yml index 8198e34..e373b96 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,12 +4,13 @@ services: container_name: tor-proxy volumes: - ./logs/tor:/var/log/tor + - ./scripts/healthchecks:/scripts/healthchecks:ro networks: btcnet: aliases: - tor healthcheck: - test: ["CMD", "sh", "-c", "if test -f /var/log/tor/tor.log && test -s /var/log/tor/tor.log; then echo 'Tor ready: SOCKS proxy listening on port 9050'; exit 0; else echo 'Tor starting: SOCKS proxy not yet ready'; exit 1; fi"] + test: ["CMD", "sh", "/scripts/healthchecks/tor-progress.sh"] interval: 10s timeout: 5s retries: 50 @@ -25,6 +26,7 @@ services: - bitcoin_data:/home/bitcoin/.bitcoin - ./conf/bitcoin/bitcoin.conf:/etc/bitcoin/bitcoin.conf:ro - ./logs/bitcoin:/var/log/bitcoin + - ./scripts/healthchecks:/scripts/healthchecks:ro networks: btcnet: aliases: @@ -35,7 +37,7 @@ services: chown -R bitcoin:bitcoin /home/bitcoin/.bitcoin || echo 'warn: chown partiel (fichiers bind-mount Windows)'; exec su-exec bitcoin bitcoind -conf=/etc/bitcoin/bitcoin.conf -signet" healthcheck: - test: ["CMD", "sh", "-c", "if bitcoin-cli -conf=/etc/bitcoin/bitcoin.conf getblockchaininfo > /dev/null 2>&1; then echo 'Bitcoin ready: RPC responding'; exit 0; else echo 'Bitcoin starting: RPC not ready'; exit 1; fi"] + test: ["CMD", "sh", "/scripts/healthchecks/bitcoin-progress.sh"] interval: 30s timeout: 10s retries: 50 @@ -52,6 +54,7 @@ services: - ./blindbit/blindbit.toml:/tmp/blindbit.toml:ro - bitcoin_data:/home/bitcoin/.bitcoin - ./logs/blindbit:/var/log/blindbit + - ./scripts/healthchecks:/scripts/healthchecks:ro entrypoint: > sh -c "cp /tmp/blindbit.toml /root/.blindbit-oracle/blindbit.toml && ./main -datadir /root/.blindbit-oracle" @@ -62,7 +65,7 @@ services: ports: - "0.0.0.0:8000:8000" healthcheck: - test: ["CMD", "sh", "-c", "if wget -q --spider http://localhost:8000/tweaks/1; then echo 'BlindBit ready: Oracle service responding'; exit 0; else echo 'BlindBit starting: Oracle service not yet ready'; exit 1; fi"] + test: ["CMD", "sh", "/scripts/healthchecks/blindbit-progress.sh"] interval: 15s timeout: 5s retries: 50 @@ -80,6 +83,7 @@ services: - bitcoin_data:/app/.bitcoin - ./scripts/funds:/scripts/funds:ro - ./logs/sdk_relay:/var/log/sdk_relay + - ./scripts/healthchecks:/scripts/healthchecks:ro ports: - "0.0.0.0:8090:8090" - "0.0.0.0:8091:8091" @@ -107,7 +111,7 @@ services: - BOOTSTRAP_FAUCET=${SDK_RELAY_BOOTSTRAP_FAUCET} - RUST_LOG=INFO healthcheck: - test: ["CMD", "sh", "-c", "if curl -f http://localhost:8091/ >/dev/null 2>&1; then echo 'SDK Relay ready: WebSocket server responding'; exit 0; else echo 'SDK Relay IBD: Waiting for Bitcoin sync to complete'; exit 1; fi"] + test: ["CMD", "sh", "/scripts/healthchecks/sdk-relay-progress.sh"] interval: 30s timeout: 10s retries: 50 @@ -249,6 +253,7 @@ services: - "0.0.0.0:3001:9090" volumes: - ./logs/sdk_signer:/var/log/sdk_signer + - ./scripts/healthchecks:/scripts/healthchecks:ro networks: btcnet: aliases: @@ -259,7 +264,7 @@ services: condition: service_healthy command: ["node", "/app/dist/index.js"] healthcheck: - test: ["CMD", "sh", "-c", "if curl -f http://localhost:9090/ >/dev/null 2>&1; then echo 'SDK Signer ready: WebSocket server responding'; exit 0; else echo 'SDK Signer starting: WebSocket server not yet ready'; exit 1; fi"] + test: ["CMD", "sh", "/scripts/healthchecks/sdk-signer-progress.sh"] interval: 30s timeout: 10s retries: 50 diff --git a/docker-compose.yml.backup b/docker-compose.yml.backup index bf22264..8198e34 100644 --- a/docker-compose.yml.backup +++ b/docker-compose.yml.backup @@ -2,17 +2,25 @@ services: tor: image: btcpayserver/tor:0.4.8.10 container_name: tor-proxy + volumes: + - ./logs/tor:/var/log/tor networks: btcnet: aliases: - tor + healthcheck: + test: ["CMD", "sh", "-c", "if test -f /var/log/tor/tor.log && test -s /var/log/tor/tor.log; then echo 'Tor ready: SOCKS proxy listening on port 9050'; exit 0; else echo 'Tor starting: SOCKS proxy not yet ready'; exit 1; fi"] + interval: 10s + timeout: 5s + retries: 50 restart: unless-stopped bitcoin: image: git.4nkweb.com/4nk/bitcoin:latest container_name: bitcoin-signet depends_on: - - tor + tor: + condition: service_healthy volumes: - bitcoin_data:/home/bitcoin/.bitcoin - ./conf/bitcoin/bitcoin.conf:/etc/bitcoin/bitcoin.conf:ro @@ -27,10 +35,10 @@ services: chown -R bitcoin:bitcoin /home/bitcoin/.bitcoin || echo 'warn: chown partiel (fichiers bind-mount Windows)'; exec su-exec bitcoin bitcoind -conf=/etc/bitcoin/bitcoin.conf -signet" healthcheck: - test: ["CMD", "bitcoin-cli", "-conf=/etc/bitcoin/bitcoin.conf", "getblockchaininfo"] + test: ["CMD", "sh", "-c", "if bitcoin-cli -conf=/etc/bitcoin/bitcoin.conf getblockchaininfo > /dev/null 2>&1; then echo 'Bitcoin ready: RPC responding'; exit 0; else echo 'Bitcoin starting: RPC not ready'; exit 1; fi"] interval: 30s timeout: 10s - retries: 3 + retries: 50 restart: unless-stopped blindbit: @@ -54,10 +62,10 @@ services: ports: - "0.0.0.0:8000:8000" healthcheck: - test: ["CMD-SHELL", "code=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8000/tweaks/1); [ \"$$code\" != \"000\" ]"] + test: ["CMD", "sh", "-c", "if wget -q --spider http://localhost:8000/tweaks/1; then echo 'BlindBit ready: Oracle service responding'; exit 0; else echo 'BlindBit starting: Oracle service not yet ready'; exit 1; fi"] interval: 15s timeout: 5s - retries: 10 + retries: 50 restart: unless-stopped sdk_relay: @@ -67,9 +75,9 @@ services: blindbit: condition: service_healthy volumes: - - ./conf/relay/sdk_relay.conf:/home/bitcoin/.conf:ro - - sdk_data:/home/bitcoin/.4nk - - bitcoin_data:/home/bitcoin/.bitcoin + - ./conf/relay/sdk_relay.conf:/app/.conf:ro + - sdk_data:/app/.4nk + - bitcoin_data:/app/.bitcoin - ./scripts/funds:/scripts/funds:ro - ./logs/sdk_relay:/var/log/sdk_relay ports: @@ -85,21 +93,49 @@ services: max-size: "10m" max-file: "3" environment: - - NODE_OPTIONS=--max-old-space-size=2048 - - HOME=/home/bitcoin + - HOME=/app + - CORE_URL=${SDK_RELAY_CORE_URL} + - WS_URL=${SDK_RELAY_WS_URL} + - WALLET_NAME=${SDK_RELAY_WALLET_NAME} + - NETWORK=${SDK_RELAY_NETWORK} + - BLINDBIT_URL=${SDK_RELAY_BLINDBIT_URL} + - ZMQ_URL=${SDK_RELAY_ZMQ_URL} + - STORAGE=${SDK_RELAY_STORAGE} + - DATA_DIR=${SDK_RELAY_DATA_DIR} + - BITCOIN_DATA_DIR=${SDK_RELAY_BITCOIN_DATA_DIR} + - BOOTSTRAP_URL=${SDK_RELAY_BOOTSTRAP_URL} + - BOOTSTRAP_FAUCET=${SDK_RELAY_BOOTSTRAP_FAUCET} - RUST_LOG=INFO healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8091/"] + test: ["CMD", "sh", "-c", "if curl -f http://localhost:8091/ >/dev/null 2>&1; then echo 'SDK Relay ready: WebSocket server responding'; exit 0; else echo 'SDK Relay IBD: Waiting for Bitcoin sync to complete'; exit 1; fi"] interval: 30s timeout: 10s - retries: 3 + retries: 50 restart: unless-stopped lecoffre-back: image: git.4nkweb.com/4nk/lecoffre-back-mini:ext container_name: lecoffre-back - env_file: - - .env + environment: + - NODE_OPTIONS=${NODE_OPTIONS} + - NODE_ENV=${NODE_ENV} + - IDNOT_ANNUARY_BASE_URL=${IDNOT_ANNUARY_BASE_URL} + - IDNOT_REDIRECT_URI=${IDNOT_REDIRECT_URI} + - IDNOT_TOKEN_URL=${IDNOT_TOKEN_URL} + - IDNOT_API_BASE_URL=${IDNOT_API_BASE_URL} + - APP_HOST=${APP_HOST} + - API_BASE_URL=${API_BASE_URL} + - DEFAULT_STORAGE=${DEFAULT_STORAGE} + - STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY} + - STRIPE_PUBLISHABLE_KEY=${STRIPE_PUBLISHABLE_KEY} + - STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET} + - MAILCHIMP_API_KEY=${MAILCHIMP_API_KEY} + - MAILCHIMP_SERVER_PREFIX=${MAILCHIMP_SERVER_PREFIX} + - MAILCHIMP_LIST_ID=${MAILCHIMP_LIST_ID} + - OVH_APPLICATION_KEY=${OVH_APPLICATION_KEY} + - OVH_APPLICATION_SECRET=${OVH_APPLICATION_SECRET} + - OVH_CONSUMER_KEY=${OVH_CONSUMER_KEY} + - OVH_SERVICE_NAME=${OVH_SERVICE_NAME} ports: - "0.0.0.0:8080:8080" volumes: @@ -115,10 +151,10 @@ services: user: appuser command: ["node", "dist/server.js"] healthcheck: - test: ["CMD", "sh", "-c", "curl -f http://localhost:8080/api/v1/health || exit 1"] + test: ["CMD", "sh", "-c", "if curl -f http://localhost:8080/api/v1/health >/dev/null 2>&1; then echo 'LeCoffre Backend ready: API responding'; exit 0; else echo 'LeCoffre Backend starting: API not yet ready'; exit 1; fi"] interval: 30s timeout: 10s - retries: 5 + retries: 50 start_period: 60s labels: - "com.centurylinklabs.watchtower.enable=true" @@ -128,8 +164,18 @@ services: image: git.4nkweb.com/4nk/lecoffre-front:ext container_name: lecoffre-front working_dir: /leCoffre-front - env_file: - - .env + environment: + - NODE_OPTIONS=${NODE_OPTIONS} + - NODE_ENV=${NODE_ENV} + - NEXT_PUBLIC_4NK_URL=${NEXT_PUBLIC_4NK_URL} + - NEXT_PUBLIC_FRONT_APP_HOST=${NEXT_PUBLIC_FRONT_APP_HOST} + - NEXT_PUBLIC_IDNOT_BASE_URL=${NEXT_PUBLIC_IDNOT_BASE_URL} + - NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT=${NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT} + - NEXT_PUBLIC_BACK_API_PROTOCOL=${NEXT_PUBLIC_BACK_API_PROTOCOL} + - NEXT_PUBLIC_BACK_API_HOST=${NEXT_PUBLIC_BACK_API_HOST} + - NEXT_PUBLIC_BACK_API_PORT=${NEXT_PUBLIC_BACK_API_PORT} + - NEXT_PUBLIC_BACK_API_ROOT_URL=${NEXT_PUBLIC_BACK_API_ROOT_URL} + - NEXT_PUBLIC_BACK_API_VERSION=${NEXT_PUBLIC_BACK_API_VERSION} ports: - "0.0.0.0:3004:3000" volumes: @@ -141,13 +187,19 @@ services: depends_on: lecoffre-back: condition: service_healthy + ihm_client: + condition: service_healthy + sdk_storage: + condition: service_healthy + sdk_signer: + condition: service_healthy user: lecoffreuser command: ["node", "server.js"] healthcheck: - test: ["CMD", "sh", "-c", "ps aux | grep -v grep | grep next-server || exit 1"] + test: ["CMD", "sh", "-c", "if ps aux | grep -v grep | grep next-server >/dev/null 2>&1; then echo 'LeCoffre Frontend ready: Next.js server running'; exit 0; else echo 'LeCoffre Frontend starting: Next.js server not yet ready'; exit 1; fi"] interval: 30s timeout: 10s - retries: 3 + retries: 50 start_period: 30s labels: - "com.centurylinklabs.watchtower.enable=true" @@ -156,9 +208,12 @@ services: ihm_client: image: git.4nkweb.com/4nk/ihm_client:ext container_name: ihm_client - env_file: - - .env environment: + - VITE_JWT_SECRET_KEY=${VITE_JWT_SECRET_KEY} + - VITE_API_BASE_URL=${VITE_API_BASE_URL} + - VITE_WS_URL=${VITE_WS_URL} + - VITE_STORAGE_URL=${VITE_STORAGE_URL} + - VITE_SIGNER_URL=${VITE_SIGNER_URL} - VITE_BOOTSTRAPURL=wss://dev4.4nkweb.com/ws/ ports: - "0.0.0.0:3003:3003" @@ -171,13 +226,17 @@ services: depends_on: sdk_relay: condition: service_healthy + sdk_storage: + condition: service_healthy + sdk_signer: + condition: service_healthy user: root command: ["npm", "start"] healthcheck: - test: ["CMD", "sh", "-c", "curl -f http://localhost:3003/ || exit 1"] + test: ["CMD", "sh", "-c", "if curl -f http://localhost:3003/ >/dev/null 2>&1; then echo 'IHM Client ready: Vite dev server responding'; exit 0; else echo 'IHM Client starting: Vite dev server not yet ready'; exit 1; fi"] interval: 30s timeout: 10s - retries: 3 + retries: 50 start_period: 30s labels: - "com.centurylinklabs.watchtower.enable=true" @@ -195,14 +254,29 @@ services: aliases: - sdk_signer user: appuser + depends_on: + sdk_storage: + condition: service_healthy command: ["node", "/app/dist/index.js"] + healthcheck: + test: ["CMD", "sh", "-c", "if curl -f http://localhost:9090/ >/dev/null 2>&1; then echo 'SDK Signer ready: WebSocket server responding'; exit 0; else echo 'SDK Signer starting: WebSocket server not yet ready'; exit 1; fi"] + interval: 30s + timeout: 10s + retries: 50 + start_period: 30s labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped environment: + - PORT=${SIGNER_PORT} + - API_KEY=${SIGNER_API_KEY} + - DATABASE_PATH=${SIGNER_DATABASE_PATH} + - RELAY_URLS=${SIGNER_RELAY_URLS} + - AUTO_RESTART=${SIGNER_AUTO_RESTART} + - MAX_RESTARTS=${SIGNER_MAX_RESTARTS} + - LOG_LEVEL=${SIGNER_LOG_LEVEL} - SIGNER_WS_URL=ws://dev3.4nkweb.com:9090 - SIGNER_BASE_URL=https://dev3.4nkweb.com - - RELAY_URLS=wss://dev4.4nkweb.com/ws/,wss://dev3.4nkweb.com/ws/ sdk_storage: image: git.4nkweb.com/4nk/sdk_storage:ext @@ -212,10 +286,10 @@ services: volumes: - ./logs/sdk_storage:/var/log/sdk_storage healthcheck: - test: ["CMD", "sh", "-c", "curl -f http://localhost:8080/health || exit 1"] + test: ["CMD", "sh", "-c", "if curl -f http://localhost:8080/health >/dev/null 2>&1; then echo 'SDK Storage ready: API responding'; exit 0; else echo 'SDK Storage starting: API not yet ready'; exit 1; fi"] interval: 30s timeout: 10s - retries: 3 + retries: 50 start_period: 30s networks: btcnet: @@ -274,6 +348,17 @@ services: btcnet: aliases: - grafana + depends_on: + loki: + condition: service_healthy + promtail: + condition: service_healthy + healthcheck: + test: ["CMD", "sh", "-c", "if curl -f http://localhost:3000/api/health >/dev/null 2>&1; then echo 'Grafana ready: Dashboard service responding'; exit 0; else echo 'Grafana starting: Dashboard service not yet ready'; exit 1; fi"] + interval: 30s + timeout: 10s + retries: 50 + start_period: 60s labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped @@ -285,15 +370,22 @@ services: - "0.0.0.0:3100:3100" volumes: - loki_data:/loki - command: -config.file=/etc/loki/local-config.yaml + - ./conf/loki/loki-config.yaml:/etc/loki/loki-config.yaml:ro + command: -config.file=/etc/loki/loki-config.yaml networks: btcnet: aliases: - loki + healthcheck: + test: ["CMD", "wget", "-q", "--spider", "http://localhost:3100/ready"] + interval: 30s + timeout: 15s + retries: 50 + start_period: 120s restart: unless-stopped promtail: - image: grafana/promtail:latest + image: promtail-custom:ext container_name: promtail volumes: - ./logs:/var/log/lecoffre:ro @@ -304,6 +396,15 @@ services: btcnet: aliases: - promtail + depends_on: + loki: + condition: service_healthy + healthcheck: + test: ["CMD", "sh", "-c", "if [ -f /tmp/positions.yaml ]; then echo 'Promtail ready: Log collection service responding'; exit 0; else echo 'Promtail starting: Log collection service not yet ready'; exit 1; fi"] + interval: 30s + timeout: 10s + retries: 50 + start_period: 30s restart: unless-stopped # Service de statut des services @@ -320,6 +421,12 @@ services: btcnet: aliases: - status-api + healthcheck: + test: ["CMD", "sh", "-c", "if curl -f http://localhost:3006/api >/dev/null 2>&1; then echo 'Status API ready: Service monitoring API responding'; exit 0; else echo 'Status API starting: Service monitoring API not yet ready'; exit 1; fi"] + interval: 30s + timeout: 10s + retries: 50 + start_period: 30s labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped diff --git a/scripts/healthchecks/bitcoin-progress.sh b/scripts/healthchecks/bitcoin-progress.sh new file mode 100755 index 0000000..7b8d1d9 --- /dev/null +++ b/scripts/healthchecks/bitcoin-progress.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# Script de test de progression pour Bitcoin Signet +info=$(bitcoin-cli -signet -conf=/etc/bitcoin/bitcoin.conf getblockchaininfo 2>/dev/null || echo '{}') +blocks=$(echo "$info" | jq -r '.blocks // 0') +headers=$(echo "$info" | jq -r '.headers // 0') +ibd=$(echo "$info" | jq -r '.initialblockdownload // false') +verification_progress=$(echo "$info" | jq -r '.verificationprogress // 0') + +if [ "$ibd" = "false" ] || [ "$blocks" -eq "$headers" ]; then + echo "Bitcoin ready: Synced ($blocks blocks)" + exit 0 +else + remaining=$((headers - blocks)) + progress=$((blocks * 100 / headers)) + verification_percent=$(echo "$verification_progress * 100" | bc -l | cut -d. -f1) + echo "Bitcoin IBD: $blocks/$headers ($remaining remaining) - $progress% - Verification: $verification_percent%" + exit 1 +fi diff --git a/scripts/healthchecks/blindbit-progress.sh b/scripts/healthchecks/blindbit-progress.sh new file mode 100755 index 0000000..980af96 --- /dev/null +++ b/scripts/healthchecks/blindbit-progress.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# Script de test de progression pour BlindBit +# Vérifier si le processus BlindBit est en cours d'exécution +if pgrep blindbit > /dev/null 2>/dev/null; then + # Vérifier l'API + if wget -q --spider http://localhost:8000/tweaks/1 2>/dev/null; then + echo 'BlindBit ready: Oracle service responding' + exit 0 + else + # Récupérer les logs récents pour voir la progression + scan_logs=$(tail -20 /var/log/blindbit/blindbit.log 2>/dev/null | grep -E "(scanning|scan|blocks|tweaks|processing)" | tail -1 || echo "") + if [ -n "$scan_logs" ]; then + echo "BlindBit processing: $scan_logs" + exit 1 + else + echo 'BlindBit starting: Oracle service initializing' + exit 1 + fi + fi +else + echo 'BlindBit starting: Process not ready' + exit 1 +fi diff --git a/scripts/healthchecks/sdk-relay-progress.sh b/scripts/healthchecks/sdk-relay-progress.sh new file mode 100755 index 0000000..caf0b86 --- /dev/null +++ b/scripts/healthchecks/sdk-relay-progress.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# Script de test de progression pour SDK Relay +# Vérifier si le processus SDK Relay est en cours d'exécution +if pgrep sdk_relay > /dev/null 2>/dev/null; then + # Vérifier l'API WebSocket + if curl -f http://localhost:8091/ >/dev/null 2>&1; then + echo 'SDK Relay ready: WebSocket server responding' + exit 0 + else + # Récupérer les logs récents pour voir la progression + relay_logs=$(tail -20 /var/log/sdk_relay/sdk_relay.log 2>/dev/null | grep -E "(IBD|blocks|headers|waiting|scanning|connecting)" | tail -1 || echo "") + if [ -n "$relay_logs" ]; then + echo "SDK Relay sync: $relay_logs" + exit 1 + else + echo 'SDK Relay starting: WebSocket server initializing' + exit 1 + fi + fi +else + echo 'SDK Relay starting: Process not ready' + exit 1 +fi diff --git a/scripts/healthchecks/sdk-signer-progress.sh b/scripts/healthchecks/sdk-signer-progress.sh new file mode 100755 index 0000000..b833873 --- /dev/null +++ b/scripts/healthchecks/sdk-signer-progress.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# Script de test de progression pour SDK Signer +# Vérifier si le processus SDK Signer est en cours d'exécution +if pgrep sdk_signer > /dev/null 2>/dev/null; then + # Vérifier l'API WebSocket + if curl -f http://localhost:9090/ >/dev/null 2>&1; then + echo 'SDK Signer ready: WebSocket server responding' + exit 0 + else + # Récupérer les logs récents pour voir la progression + signer_logs=$(tail -20 /var/log/sdk_signer/sdk_signer.log 2>/dev/null | grep -E "(Disconnected|reconnect|error|connected|waiting|connecting)" | tail -1 || echo "") + if [ -n "$signer_logs" ]; then + echo "SDK Signer conn: $signer_logs" + exit 1 + else + echo 'SDK Signer starting: WebSocket server initializing' + exit 1 + fi + fi +else + echo 'SDK Signer starting: Process not ready' + exit 1 +fi diff --git a/scripts/healthchecks/tor-progress.sh b/scripts/healthchecks/tor-progress.sh new file mode 100755 index 0000000..3984194 --- /dev/null +++ b/scripts/healthchecks/tor-progress.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Script de test de progression pour Tor +# Vérifier si le processus Tor est en cours d'exécution +if pgrep tor > /dev/null; then + # Vérifier si le port SOCKS est ouvert + if ss -ln 2>/dev/null | grep -q ':9050' || netstat -ln 2>/dev/null | grep -q ':9050'; then + echo 'Tor ready: SOCKS proxy listening on port 9050' + exit 0 + else + # Récupérer les logs Docker pour voir la progression du bootstrap + bootstrap_log=$(docker logs tor-proxy --tail 20 2>/dev/null | grep 'Bootstrapped' | tail -1) + if [ -n "$bootstrap_log" ]; then + if echo "$bootstrap_log" | grep -q '100%'; then + echo 'Tor ready: Bootstrap complete (100%)' + exit 0 + else + progress=$(echo "$bootstrap_log" | grep -o '[0-9]\+%' | tail -1 || echo '0%') + stage=$(echo "$bootstrap_log" | grep -o '(.*)' | sed 's/[()]//g' || echo 'starting') + echo "Tor bootstrapping: $progress - $stage" + exit 1 + fi + else + echo 'Tor starting: Bootstrap in progress' + exit 1 + fi + fi +else + echo 'Tor starting: Process not ready' + exit 1 +fi diff --git a/scripts/logs-with-progress.sh b/scripts/logs-with-progress.sh deleted file mode 100755 index d644f92..0000000 --- a/scripts/logs-with-progress.sh +++ /dev/null @@ -1,254 +0,0 @@ -#!/bin/bash - -# Script pour afficher les logs des services avec la progression -# Affiche les logs en temps réel avec des informations de progression - -set -e - -# Couleurs pour l'affichage -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -PURPLE='\033[0;35m' -CYAN='\033[0;36m' -NC='\033[0m' # No Color - -# Fonction pour afficher l'aide -show_help() { - echo -e "${BLUE}Usage: $0 [service_name] [options]${NC}" - echo - echo -e "${PURPLE}Services disponibles:${NC}" - echo -e " ${CYAN}bitcoin${NC} - Bitcoin Signet (affiche la progression IBD)" - echo -e " ${CYAN}blindbit${NC} - BlindBit Oracle (affiche la progression du scan)" - echo -e " ${CYAN}sdk_relay${NC} - SDK Relay (affiche la progression du scan)" - echo -e " ${CYAN}sdk_storage${NC} - SDK Storage" - echo -e " ${CYAN}sdk_signer${NC} - SDK Signer" - echo -e " ${CYAN}lecoffre-back${NC} - LeCoffre Backend" - echo -e " ${CYAN}lecoffre-front${NC} - LeCoffre Frontend" - echo -e " ${CYAN}ihm_client${NC} - IHM Client" - echo -e " ${CYAN}grafana${NC} - Grafana" - echo -e " ${CYAN}loki${NC} - Loki" - echo -e " ${CYAN}promtail${NC} - Promtail" - echo -e " ${CYAN}status-api${NC} - Status API" - echo - echo -e "${PURPLE}Options:${NC}" - echo -e " ${CYAN}-f, --follow${NC} - Suivre les logs en temps réel (défaut)" - echo -e " ${CYAN}-n, --lines N${NC} - Afficher les N dernières lignes (défaut: 50)" - echo -e " ${CYAN}-p, --progress${NC} - Afficher la progression en plus des logs" - echo -e " ${CYAN}-h, --help${NC} - Afficher cette aide" - echo - echo -e "${PURPLE}Exemples:${NC}" - echo -e " ${CYAN}$0 bitcoin -p${NC} - Logs Bitcoin avec progression IBD" - echo -e " ${CYAN}$0 sdk_relay -n 100${NC} - 100 dernières lignes du SDK Relay" - echo -e " ${CYAN}$0 blindbit -f -p${NC} - Logs BlindBit en temps réel avec progression" -} - -# Fonction pour afficher la progression Bitcoin -show_bitcoin_progress() { - local container_name="bitcoin-signet" - if docker ps --format "table {{.Names}}" | grep -q "$container_name"; then - local info=$(docker exec "$container_name" bitcoin-cli -conf=/etc/bitcoin/bitcoin.conf getblockchaininfo 2>/dev/null || echo '{}') - local blocks=$(echo "$info" | jq -r '.blocks // 0') - local headers=$(echo "$info" | jq -r '.headers // 0') - local progress=0 - - if [ "$headers" -gt 0 ]; then - progress=$((blocks * 100 / headers)) - fi - - echo -e "${CYAN}Bitcoin Progress: $blocks/$headers blocks ($(($headers - $blocks)) remaining) - $progress%${NC}" - - # Afficher une barre de progression - local bar_length=50 - local filled_length=$((progress * bar_length / 100)) - local bar="" - for ((i=0; i/dev/null || echo "000") - case "$response" in - "200") - echo -e "${GREEN}BlindBit Progress: Oracle service ready${NC}" - ;; - "000") - echo -e "${YELLOW}BlindBit Progress: Oracle service starting${NC}" - ;; - *) - echo -e "${YELLOW}BlindBit Progress: Oracle scanning (code: $response)${NC}" - ;; - esac - echo - fi -} - -# Fonction pour afficher la progression SDK Relay -show_sdk_relay_progress() { - local container_name="sdk_relay" - if docker ps --format "table {{.Names}}" | grep -q "$container_name"; then - local logs=$(docker logs "$container_name" --tail 3 2>/dev/null | grep -E "(waiting for|blocks to download|IBD)" | tail -1 || echo "") - if [ -n "$logs" ]; then - echo -e "${YELLOW}SDK Relay Progress: $logs${NC}" - else - local response=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8091/ 2>/dev/null || echo "000") - if [ "$response" = "200" ]; then - echo -e "${GREEN}SDK Relay Progress: WebSocket server ready${NC}" - else - echo -e "${YELLOW}SDK Relay Progress: WebSocket server starting${NC}" - fi - fi - echo - fi -} - -# Fonction pour afficher les logs avec progression -show_logs_with_progress() { - local service_name="$1" - local container_name="$2" - local lines="${3:-50}" - local follow="${4:-true}" - - echo -e "${BLUE}========================================${NC}" - echo -e "${BLUE} Logs for $service_name${NC}" - echo -e "${BLUE}========================================${NC}" - echo - - # Afficher la progression selon le service - case "$service_name" in - "bitcoin") - show_bitcoin_progress - ;; - "blindbit") - show_blindbit_progress - ;; - "sdk_relay") - show_sdk_relay_progress - ;; - esac - - echo -e "${PURPLE}Recent logs:${NC}" - echo - - if [ "$follow" = "true" ]; then - docker logs -f --tail "$lines" "$container_name" 2>/dev/null || echo -e "${RED}Service $service_name not found or not running${NC}" - else - docker logs --tail "$lines" "$container_name" 2>/dev/null || echo -e "${RED}Service $container_name not found or not running${NC}" - fi -} - -# Fonction principale -main() { - local service_name="" - local container_name="" - local lines=50 - local follow=true - local show_progress=false - - # Parser les arguments - while [[ $# -gt 0 ]]; do - case $1 in - -f|--follow) - follow=true - shift - ;; - -n|--lines) - lines="$2" - shift 2 - ;; - -p|--progress) - show_progress=true - shift - ;; - -h|--help) - show_help - exit 0 - ;; - -*) - echo -e "${RED}Unknown option: $1${NC}" - show_help - exit 1 - ;; - *) - service_name="$1" - shift - ;; - esac - done - - # Déterminer le nom du conteneur - case "$service_name" in - "bitcoin") - container_name="bitcoin-signet" - ;; - "blindbit") - container_name="blindbit-oracle" - ;; - "sdk_relay") - container_name="sdk_relay" - ;; - "sdk_storage") - container_name="sdk_storage" - ;; - "sdk_signer") - container_name="sdk_signer" - ;; - "lecoffre-back") - container_name="lecoffre-back" - ;; - "lecoffre-front") - container_name="lecoffre-front" - ;; - "ihm_client") - container_name="ihm_client" - ;; - "grafana") - container_name="grafana" - ;; - "loki") - container_name="loki" - ;; - "promtail") - container_name="promtail" - ;; - "status-api") - container_name="status-api" - ;; - "") - echo -e "${RED}Please specify a service name${NC}" - show_help - exit 1 - ;; - *) - echo -e "${RED}Unknown service: $service_name${NC}" - show_help - exit 1 - ;; - esac - - # Afficher les logs - if [ "$show_progress" = "true" ]; then - show_logs_with_progress "$service_name" "$container_name" "$lines" "$follow" - else - echo -e "${BLUE}========================================${NC}" - echo -e "${BLUE} Logs for $service_name${NC}" - echo -e "${BLUE}========================================${NC}" - echo - - if [ "$follow" = "true" ]; then - docker logs -f --tail "$lines" "$container_name" 2>/dev/null || echo -e "${RED}Service $service_name not found or not running${NC}" - else - docker logs --tail "$lines" "$container_name" 2>/dev/null || echo -e "${RED}Service $service_name not found or not running${NC}" - fi - fi -} - -# Exécution -main "$@" diff --git a/scripts/monitor-progress.sh b/scripts/monitor-progress.sh deleted file mode 100755 index a1a4789..0000000 --- a/scripts/monitor-progress.sh +++ /dev/null @@ -1,207 +0,0 @@ -#!/bin/bash - -# Script de monitoring de la progression des services LeCoffre Node -# Affiche la progression des différents processus (IBD, scans, etc.) - -set -e - -# Couleurs pour l'affichage -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -PURPLE='\033[0;35m' -CYAN='\033[0;36m' -NC='\033[0m' # No Color - -# Fonction pour afficher un header -print_header() { - echo -e "${BLUE}========================================${NC}" - echo -e "${BLUE} LeCoffre Node - Monitoring Progress${NC}" - echo -e "${BLUE}========================================${NC}" - echo -} - -# Fonction pour afficher le statut d'un service -print_service_status() { - local service_name="$1" - local container_name="$2" - local status=$(docker inspect --format='{{.State.Health.Status}}' "$container_name" 2>/dev/null || echo "no-healthcheck") - local running=$(docker inspect --format='{{.State.Running}}' "$container_name" 2>/dev/null || echo "false") - - if [ "$running" = "true" ]; then - case "$status" in - "healthy") - echo -e " ${GREEN}✓${NC} $service_name: ${GREEN}Ready${NC}" - ;; - "unhealthy") - echo -e " ${YELLOW}⚠${NC} $service_name: ${YELLOW}Starting/Processing${NC}" - ;; - "starting") - echo -e " ${YELLOW}⏳${NC} $service_name: ${YELLOW}Starting${NC}" - ;; - "no-healthcheck") - echo -e " ${BLUE}ℹ${NC} $service_name: ${BLUE}Running (no healthcheck)${NC}" - ;; - esac - else - echo -e " ${RED}✗${NC} $service_name: ${RED}Stopped${NC}" - fi -} - -# Fonction pour afficher la progression Tor -show_tor_progress() { - local container_name="tor-proxy" - if docker ps --format "table {{.Names}}" | grep -q "$container_name"; then - echo -e "${CYAN}Tor Progress:${NC}" - local bootstrap_log=$(docker logs "$container_name" --tail 20 2>/dev/null | grep "Bootstrapped" | tail -1 || echo "") - if [ -n "$bootstrap_log" ]; then - local progress=$(echo "$bootstrap_log" | grep -o '[0-9]\+%' | tail -1 || echo "0%") - if echo "$bootstrap_log" | grep -q "100%"; then - echo -e " ${GREEN}✓ Tor ready: Bootstrap complete (100%)${NC}" - else - echo -e " ${YELLOW}⏳ Tor bootstrapping: $progress${NC}" - fi - else - echo -e " ${YELLOW}⏳ Tor starting: Bootstrap not yet started${NC}" - fi - echo - fi -} - -# Fonction pour afficher la progression Bitcoin -show_bitcoin_progress() { - local container_name="bitcoin-signet" - if docker ps --format "table {{.Names}}" | grep -q "$container_name"; then - echo -e "${CYAN}Bitcoin Progress:${NC}" - local info=$(docker exec "$container_name" bitcoin-cli -conf=/etc/bitcoin/bitcoin.conf getblockchaininfo 2>/dev/null || echo '{}') - local blocks=$(echo "$info" | jq -r '.blocks // 0') - local headers=$(echo "$info" | jq -r '.headers // 0') - local progress=0 - - if [ "$headers" -gt 0 ]; then - progress=$((blocks * 100 / headers)) - fi - - if [ "$blocks" -eq "$headers" ] && [ "$blocks" -gt 0 ]; then - echo -e " ${GREEN}✓ Bitcoin sync complete: $blocks blocks${NC}" - else - echo -e " ${YELLOW}⏳ Bitcoin IBD: $blocks/$headers blocks ($(($headers - $blocks)) remaining) - $progress%${NC}" - fi - echo - fi -} - -# Fonction pour afficher la progression BlindBit -show_blindbit_progress() { - local container_name="blindbit-oracle" - if docker ps --format "table {{.Names}}" | grep -q "$container_name"; then - echo -e "${CYAN}BlindBit Progress:${NC}" - local response=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8000/tweaks/1 2>/dev/null || echo "000") - case "$response" in - "200") - echo -e " ${GREEN}✓ BlindBit ready: Oracle service responding${NC}" - ;; - "000") - echo -e " ${YELLOW}⏳ BlindBit starting: Oracle service not yet ready${NC}" - ;; - *) - echo -e " ${YELLOW}⏳ BlindBit scanning: Oracle responding with code $response${NC}" - ;; - esac - echo - fi -} - -# Fonction pour afficher la progression SDK Relay -show_sdk_relay_progress() { - local container_name="sdk_relay" - if docker ps --format "table {{.Names}}" | grep -q "$container_name"; then - echo -e "${CYAN}SDK Relay Progress:${NC}" - local logs=$(docker logs "$container_name" --tail 5 2>/dev/null | grep -E "(waiting for|blocks to download|IBD)" | tail -1 || echo "") - if [ -n "$logs" ]; then - echo -e " ${YELLOW}⏳ SDK Relay IBD: $logs${NC}" - else - local response=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8091/ 2>/dev/null || echo "000") - if [ "$response" = "200" ]; then - echo -e " ${GREEN}✓ SDK Relay ready: WebSocket server responding${NC}" - else - echo -e " ${YELLOW}⏳ SDK Relay starting: WebSocket server not yet ready${NC}" - fi - fi - echo - fi -} - -# Fonction pour afficher la progression des autres services -show_other_services_progress() { - echo -e "${CYAN}Other Services Progress:${NC}" - - # SDK Storage - local storage_response=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8081/health 2>/dev/null || echo "000") - if [ "$storage_response" = "200" ]; then - echo -e " ${GREEN}✓ SDK Storage ready: API responding${NC}" - else - echo -e " ${YELLOW}⏳ SDK Storage starting: API not yet ready${NC}" - fi - - # SDK Signer - local signer_response=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:3001/ 2>/dev/null || echo "000") - if [ "$signer_response" = "101" ] || [ "$signer_response" = "426" ]; then - echo -e " ${GREEN}✓ SDK Signer ready: WebSocket server responding${NC}" - else - echo -e " ${YELLOW}⏳ SDK Signer starting: WebSocket server not yet ready${NC}" - fi - - # IHM Client - local ihm_response=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:3003/ 2>/dev/null || echo "000") - if [ "$ihm_response" = "200" ]; then - echo -e " ${GREEN}✓ IHM Client ready: Vite dev server responding${NC}" - else - echo -e " ${YELLOW}⏳ IHM Client starting: Vite dev server not yet ready${NC}" - fi - - # Grafana - local grafana_response=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:3005/api/health 2>/dev/null || echo "000") - if [ "$grafana_response" = "200" ]; then - echo -e " ${GREEN}✓ Grafana ready: Dashboard service responding${NC}" - else - echo -e " ${YELLOW}⏳ Grafana starting: Dashboard service not yet ready${NC}" - fi - - echo -} - -# Fonction principale -main() { - print_header - - echo -e "${PURPLE}Service Status:${NC}" - print_service_status "Tor Proxy" "tor-proxy" - print_service_status "Bitcoin Signet" "bitcoin-signet" - print_service_status "BlindBit Oracle" "blindbit-oracle" - print_service_status "SDK Storage" "sdk_storage" - print_service_status "SDK Relay" "sdk_relay" - print_service_status "SDK Signer" "sdk_signer" - print_service_status "LeCoffre Backend" "lecoffre-back" - print_service_status "LeCoffre Frontend" "lecoffre-front" - print_service_status "IHM Client" "ihm_client" - print_service_status "Grafana" "grafana" - print_service_status "Loki" "loki" - print_service_status "Promtail" "promtail" - print_service_status "Status API" "status-api" - echo - - show_tor_progress - show_bitcoin_progress - show_blindbit_progress - show_sdk_relay_progress - show_other_services_progress - - echo -e "${BLUE}========================================${NC}" - echo -e "${BLUE} Use 'docker logs ' for detailed logs${NC}" - echo -e "${BLUE}========================================${NC}" -} - -# Exécution -main "$@" diff --git a/scripts/start-monitoring.sh b/scripts/start-monitoring.sh deleted file mode 100755 index 8139ec2..0000000 --- a/scripts/start-monitoring.sh +++ /dev/null @@ -1,111 +0,0 @@ -#!/bin/bash - -# Script de démarrage des services de monitoring LeCoffre Node -# Démarre les services de monitoring dans l'ordre correct et indépendant - -set -e - -# Couleurs pour l'affichage -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -PURPLE='\033[0;35m' -CYAN='\033[0;36m' -NC='\033[0m' # No Color - -# Fonction pour afficher un message -print_message() { - echo -e "${BLUE}[$(date '+%H:%M:%S')]${NC} $1" -} - -# Fonction pour attendre qu'un service soit healthy -wait_for_service() { - local service_name="$1" - local container_name="$2" - local max_wait="${3:-120}" # 2 minutes par défaut - local wait_time=0 - - print_message "Waiting for $service_name to be healthy..." - - while [ $wait_time -lt $max_wait ]; do - local status=$(docker inspect --format='{{.State.Health.Status}}' "$container_name" 2>/dev/null || echo "no-healthcheck") - local running=$(docker inspect --format='{{.State.Running}}' "$container_name" 2>/dev/null || echo "false") - - if [ "$running" = "true" ] && [ "$status" = "healthy" ]; then - print_message "${GREEN}✓ $service_name is healthy${NC}" - return 0 - elif [ "$running" = "false" ]; then - print_message "${RED}✗ $service_name is not running${NC}" - return 1 - fi - - sleep 10 - wait_time=$((wait_time + 10)) - done - - print_message "${RED}✗ Timeout waiting for $service_name${NC}" - return 1 -} - -# Fonction pour démarrer un service -start_service() { - local service_name="$1" - print_message "Starting $service_name..." - - if docker compose --env-file .env.master up -d "$service_name"; then - print_message "${GREEN}✓ $service_name started${NC}" - return 0 - else - print_message "${RED}✗ Failed to start $service_name${NC}" - return 1 - fi -} - -# Fonction principale -main() { - echo -e "${BLUE}========================================${NC}" - echo -e "${BLUE} LeCoffre Node - Monitoring Services${NC}" - echo -e "${BLUE}========================================${NC}" - echo - - # Arrêter les services de monitoring existants - print_message "Stopping existing monitoring services..." - docker compose --env-file .env.master stop loki promtail grafana 2>/dev/null || true - docker compose --env-file .env.master rm -f loki promtail grafana 2>/dev/null || true - - # Démarrer les services de monitoring dans l'ordre correct - print_message "${PURPLE}Starting monitoring services in correct order...${NC}" - echo - - # 1. Loki (base de données de logs) - print_message "${CYAN}Step 1: Starting Loki (log database)...${NC}" - start_service "loki" - wait_for_service "Loki" "loki" 120 - - # 2. Promtail (collecte des logs) - print_message "${CYAN}Step 2: Starting Promtail (log collection)...${NC}" - start_service "promtail" - wait_for_service "Promtail" "promtail" 60 - - # 3. Grafana (visualisation) - print_message "${CYAN}Step 3: Starting Grafana (visualization)...${NC}" - start_service "grafana" - wait_for_service "Grafana" "grafana" 120 - - echo - print_message "${GREEN}✓ All monitoring services started successfully!${NC}" - echo - print_message "Monitoring URLs:" - print_message " - Grafana: https://dev4.4nkweb.com/grafana/" - print_message " - Loki API: https://dev4.4nkweb.com/loki/" - print_message " - Status: https://dev4.4nkweb.com/status/" - echo - print_message "Use './scripts/monitor-progress.sh' to monitor all services" - print_message "Use './scripts/watch-progress.sh' for real-time monitoring" - echo - print_message "${GREEN}Monitoring startup complete!${NC}" -} - -# Exécution -main "$@" diff --git a/scripts/start-with-progress.sh b/scripts/start-with-progress.sh deleted file mode 100755 index d029367..0000000 --- a/scripts/start-with-progress.sh +++ /dev/null @@ -1,258 +0,0 @@ -#!/bin/bash - -# Script de démarrage des services LeCoffre Node avec suivi de la progression -# Démarre les services dans l'ordre correct et affiche la progression - -set -e - -# Couleurs pour l'affichage -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -PURPLE='\033[0;35m' -CYAN='\033[0;36m' -NC='\033[0m' # No Color - -# Fonction pour afficher un message -print_message() { - echo -e "${BLUE}[$(date '+%H:%M:%S')]${NC} $1" -} - -# Fonction pour attendre qu'un service soit healthy -wait_for_service() { - local service_name="$1" - local container_name="$2" - local max_wait="${3:-300}" # 5 minutes par défaut - local wait_time=0 - local last_progress_time=0 - local progress_interval=30 # Afficher la progression toutes les 30 secondes - - print_message "Waiting for $service_name to be healthy (timeout: ${max_wait}s)..." - - while [ $wait_time -lt $max_wait ]; do - local status=$(docker inspect --format='{{.State.Health.Status}}' "$container_name" 2>/dev/null || echo "no-healthcheck") - local running=$(docker inspect --format='{{.State.Running}}' "$container_name" 2>/dev/null || echo "false") - - if [ "$running" = "true" ] && [ "$status" = "healthy" ]; then - print_message "${GREEN}✓ $service_name is healthy${NC}" - return 0 - elif [ "$running" = "false" ]; then - print_message "${RED}✗ $service_name is not running${NC}" - return 1 - fi - - # Afficher la progression pour Tor (timeout: 15 minutes) - if [ "$service_name" = "Tor Proxy" ]; then - if [ $((wait_time - last_progress_time)) -ge $progress_interval ]; then - local bootstrap_log=$(docker logs "$container_name" --tail 20 2>/dev/null | grep "Bootstrapped" | tail -1 || echo "") - if [ -n "$bootstrap_log" ]; then - local progress=$(echo "$bootstrap_log" | grep -o '[0-9]\+%' | tail -1 || echo "0%") - if echo "$bootstrap_log" | grep -q "100%"; then - print_message "${GREEN}✓ Tor ready: Bootstrap complete (100%)${NC}" - return 0 - else - print_message "${YELLOW}⏳ Tor bootstrapping: $progress (${wait_time}s elapsed)${NC}" - fi - else - print_message "${YELLOW}⏳ Tor starting: Bootstrap not yet started (${wait_time}s elapsed)${NC}" - fi - last_progress_time=$wait_time - fi - fi - - # Afficher la progression pour Bitcoin (timeout: 2 heures) - if [ "$service_name" = "Bitcoin Signet" ]; then - if [ $((wait_time - last_progress_time)) -ge $progress_interval ]; then - local info=$(docker exec "$container_name" bitcoin-cli -conf=/etc/bitcoin/bitcoin.conf getblockchaininfo 2>/dev/null || echo '{}') - local blocks=$(echo "$info" | jq -r '.blocks // 0') - local headers=$(echo "$info" | jq -r '.headers // 0') - local progress=0 - - if [ "$headers" -gt 0 ]; then - progress=$((blocks * 100 / headers)) - fi - - if [ "$blocks" -eq "$headers" ] && [ "$blocks" -gt 0 ]; then - print_message "${GREEN}✓ Bitcoin sync complete: $blocks blocks${NC}" - return 0 - else - local remaining=$((headers - blocks)) - local elapsed_min=$((wait_time / 60)) - print_message "${YELLOW}⏳ Bitcoin IBD: $blocks/$headers blocks ($remaining remaining) - $progress% (${elapsed_min}min elapsed)${NC}" - fi - last_progress_time=$wait_time - fi - fi - - # Afficher la progression pour BlindBit - if [ "$service_name" = "BlindBit Oracle" ]; then - if [ $((wait_time - last_progress_time)) -ge $progress_interval ]; then - local response=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8000/tweaks/1 2>/dev/null || echo "000") - case "$response" in - "200") - print_message "${GREEN}✓ BlindBit ready: Oracle service responding${NC}" - return 0 - ;; - "000") - print_message "${YELLOW}⏳ BlindBit starting: Oracle service not yet ready (${wait_time}s elapsed)${NC}" - ;; - *) - print_message "${YELLOW}⏳ BlindBit scanning: Oracle responding with code $response (${wait_time}s elapsed)${NC}" - ;; - esac - last_progress_time=$wait_time - fi - fi - - # Afficher la progression pour SDK Relay - if [ "$service_name" = "SDK Relay" ]; then - if [ $((wait_time - last_progress_time)) -ge $progress_interval ]; then - local logs=$(docker logs "$container_name" --tail 3 2>/dev/null | grep -E "(waiting for|blocks to download|IBD)" | tail -1 || echo "") - if [ -n "$logs" ]; then - print_message "${YELLOW}⏳ SDK Relay IBD: $logs (${wait_time}s elapsed)${NC}" - else - local response=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8091/ 2>/dev/null || echo "000") - if [ "$response" = "200" ]; then - print_message "${GREEN}✓ SDK Relay ready: WebSocket server responding${NC}" - return 0 - else - print_message "${YELLOW}⏳ SDK Relay starting: WebSocket server not yet ready (${wait_time}s elapsed)${NC}" - fi - fi - last_progress_time=$wait_time - fi - fi - - # Afficher la progression pour SDK Signer - if [ "$service_name" = "SDK Signer" ]; then - if [ $((wait_time - last_progress_time)) -ge $progress_interval ]; then - local logs=$(docker logs "$container_name" --tail 5 2>/dev/null | grep -E "(Disconnected from relay|Scheduling reconnect|WebSocket error)" | tail -1 || echo "") - if [ -n "$logs" ]; then - print_message "${YELLOW}⏳ SDK Signer: Waiting for relay connection (${wait_time}s elapsed)${NC}" - else - local response=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:3001/ 2>/dev/null || echo "000") - if [ "$response" = "101" ] || [ "$response" = "426" ]; then - print_message "${GREEN}✓ SDK Signer ready: WebSocket server responding${NC}" - return 0 - else - print_message "${YELLOW}⏳ SDK Signer starting: WebSocket server not yet ready (${wait_time}s elapsed)${NC}" - fi - fi - last_progress_time=$wait_time - fi - fi - - sleep 10 - wait_time=$((wait_time + 10)) - done - - print_message "${RED}✗ Timeout waiting for $service_name${NC}" - return 1 -} - -# Fonction pour démarrer un service -start_service() { - local service_name="$1" - print_message "Starting $service_name..." - - if docker compose --env-file .env.master up -d "$service_name"; then - print_message "${GREEN}✓ $service_name started${NC}" - return 0 - else - print_message "${RED}✗ Failed to start $service_name${NC}" - return 1 - fi -} - -# Fonction principale -main() { - echo -e "${BLUE}========================================${NC}" - echo -e "${BLUE} LeCoffre Node - Startup with Progress${NC}" - echo -e "${BLUE}========================================${NC}" - echo - - # Arrêter tous les services existants - print_message "Stopping existing services..." - docker compose --env-file .env.master down --remove-orphans - - # Démarrer les services dans l'ordre correct - print_message "Starting services in correct order..." - echo - - # Phase 1: Services de base (parallèle) - print_message "${PURPLE}Phase 1: Starting base services...${NC}" - start_service "tor" - start_service "sdk_storage" - start_service "sdk_signer" - start_service "status-api" - - # Attendre les services de base - wait_for_service "Tor Proxy" "tor-proxy" 900 # 15 minutes pour Tor bootstrap - wait_for_service "SDK Storage" "sdk_storage" 120 - wait_for_service "Status API" "status-api" 60 - - # SDK Signer peut démarrer même sans relay (il se reconnectera plus tard) - print_message "SDK Signer started (will connect to relay when available)" - - # Phase 2: Services blockchain (séquentiel) - print_message "${PURPLE}Phase 2: Starting blockchain services...${NC}" - start_service "bitcoin" - wait_for_service "Bitcoin Signet" "bitcoin-signet" 7200 # 2 heures pour Bitcoin IBD - - start_service "blindbit" - wait_for_service "BlindBit Oracle" "blindbit-oracle" 600 # 10 minutes pour BlindBit - - start_service "sdk_relay" - wait_for_service "SDK Relay" "sdk_relay" 1800 # 30 minutes pour SDK Relay IBD - - # Phase 3: Services applicatifs (séquentiel) - print_message "${PURPLE}Phase 3: Starting application services...${NC}" - start_service "lecoffre-back" - wait_for_service "LeCoffre Backend" "lecoffre-back" 120 - - start_service "lecoffre-front" - start_service "ihm_client" - wait_for_service "LeCoffre Frontend" "lecoffre-front" 120 - wait_for_service "IHM Client" "ihm_client" 120 - - # Phase 4: Services de monitoring (séquentiel, indépendant) - print_message "${PURPLE}Phase 4: Starting monitoring services...${NC}" - start_service "loki" - wait_for_service "Loki" "loki" 120 - - start_service "promtail" - wait_for_service "Promtail" "promtail" 60 - - start_service "grafana" - wait_for_service "Grafana" "grafana" 120 - - # Phase 5: Services utilitaires - print_message "${PURPLE}Phase 5: Starting utility services...${NC}" - start_service "watchtower" - - echo - print_message "${GREEN}✓ All services started successfully!${NC}" - echo - print_message "Use './scripts/monitor-progress.sh' to monitor progress" - print_message "Use './scripts/watch-progress.sh' for real-time monitoring" - echo - print_message "Testing external access..." - - # Tester l'accès externe - local services=("https://dev4.4nkweb.com/status/" "https://dev4.4nkweb.com/grafana/" "https://dev4.4nkweb.com/" "https://dev4.4nkweb.com/lecoffre/") - - for service in "${services[@]}"; do - if curl -s -o /dev/null -w '%{http_code}' "$service" | grep -q "200"; then - print_message "${GREEN}✓ $service is accessible${NC}" - else - print_message "${YELLOW}⚠ $service is not yet accessible${NC}" - fi - done - - echo - print_message "${GREEN}Startup complete!${NC}" -} - -# Exécution -main "$@" diff --git a/scripts/start.sh b/scripts/start.sh new file mode 100755 index 0000000..37e9d3f --- /dev/null +++ b/scripts/start.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# LeCoffre Node - Script de lancement simple +# Lance tous les services Docker Compose sans surveillance + +set -e + +# Couleurs pour l'affichage +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +echo -e "${BLUE}========================================${NC}" +echo -e "${BLUE} LeCoffre Node - Simple Startup${NC}" +echo -e "${BLUE}========================================${NC}" +echo + +# Arrêter les services existants +echo -e "${YELLOW}Stopping existing services...${NC}" +docker compose --env-file .env.master down --remove-orphans >/dev/null 2>&1 || true + +# Démarrer tous les services +echo -e "${YELLOW}Starting all services...${NC}" +docker compose --env-file .env.master up -d + +echo -e "${GREEN}✅ All services started!${NC}" +echo +echo -e "${BLUE}Services status:${NC}" +docker compose --env-file .env.master ps + +echo +echo -e "${BLUE}Useful commands:${NC}" +echo -e " ${YELLOW}docker compose --env-file .env.master logs -f${NC} # Voir les logs" +echo -e " ${YELLOW}docker compose --env-file .env.master down${NC} # Arrêter les services" +echo -e " ${YELLOW}docker compose --env-file .env.master ps${NC} # Voir le statut" +echo diff --git a/scripts/startup-sequence.sh b/scripts/startup-sequence.sh deleted file mode 100755 index 04942ce..0000000 --- a/scripts/startup-sequence.sh +++ /dev/null @@ -1,715 +0,0 @@ -#!/bin/bash - -# Script de démarrage amélioré pour lecoffre_node -# Utilise les healthchecks du docker-compose.yml pour une séquence optimisée -# Intègre la validation des dépendances externes - -set -e - -# Couleurs pour les logs -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -# Configuration -EXTERNAL_SIGNER_HOST="dev3.4nkweb.com" -EXTERNAL_SIGNER_PORT="9090" -PUBLIC_FRONT_URL="https://dev4.4nkweb.com/lecoffre" -PUBLIC_IHM_URL="https://dev4.4nkweb.com" - -# Projets avec Docker (images à construire) -DOCKER_PROJECTS=("sdk_relay" "sdk_storage" "sdk_signer" "ihm_client" "lecoffre-front" "lecoffre-back-mini") - -# Projets sans Docker (libraries/packages) -LIBRARY_PROJECTS=("sdk_client" "sdk_common" "sdk-signer-client") - -# Fonction de logging -log() { - echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1" -} - -log_success() { - echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] ✅${NC} $1" -} - -log_warning() { - echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] ⚠️${NC} $1" -} - -log_error() { - echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ❌${NC} $1" -} - -# Fonction de validation des dépendances externes -validate_external_dependencies() { - log "Validation des dépendances externes..." - - local all_ok=true - - # Test du signer distant - log "Test de connectivité vers le signer distant ($EXTERNAL_SIGNER_HOST:$EXTERNAL_SIGNER_PORT)..." - if timeout 10 bash -c "/dev/null; then - log_success "Signer distant accessible" - else - log_error "Signer distant non accessible" - all_ok=false - fi - - # Test des URLs publiques - log "Test de connectivité vers les URLs publiques..." - if curl -s --connect-timeout 10 --max-time 15 "$PUBLIC_FRONT_URL" >/dev/null 2>&1; then - log_success "LeCoffre Front accessible" - else - log_warning "LeCoffre Front non accessible (peut être normal si pas encore démarré)" - fi - - if curl -s --connect-timeout 10 --max-time 15 "$PUBLIC_IHM_URL" >/dev/null 2>&1; then - log_success "IHM Client accessible" - else - log_warning "IHM Client non accessible (peut être normal si pas encore démarré)" - fi - - return $([ "$all_ok" = true ] && echo 0 || echo 1) -} - -# Fonction pour attendre qu'un service soit prêt -wait_for_service() { - local service_name=$1 - local health_url=$2 - local timeout=${3:-300} - - echo "⏳ Attente de $service_name..." - local start_time=$(date +%s) - - while [ $(($(date +%s) - start_time)) -lt $timeout ]; do - if curl -f -s "$health_url" > /dev/null 2>&1; then - echo "✅ $service_name est prêt" - return 0 - fi - sleep 5 - done - - echo "❌ Timeout: $service_name n'est pas prêt après ${timeout}s" - return 1 -} - -# Fonction pour synchroniser les configurations -sync_configurations() { - log "Synchronisation des configurations centralisées..." - - if [[ -f "./scripts/sync-configs.sh" ]]; then - if ./scripts/sync-configs.sh; then - log_success "Configurations synchronisées" - else - log_warning "Échec de la synchronisation des configurations" - fi - else - log_warning "Script de synchronisation non trouvé" - fi -} - -# Fonction pour mettre à jour les dépendances d'un projet -update_project_dependencies() { - local project="$1" - local project_path="/home/debian/$project" - - log "Mise à jour des dépendances pour $project" - - if [[ ! -d "$project_path" ]]; then - log_error "Projet non trouvé: $project_path" - return 1 - fi - - cd "$project_path" - - # Rust projects - if [[ -f "Cargo.toml" ]]; then - log "Mise à jour des dépendances Rust..." - if cargo update; then - log_success "Dépendances Rust mises à jour" - else - log_warning "Échec de la mise à jour des dépendances Rust" - fi - fi - - # Node.js projects - if [[ -f "package.json" ]]; then - log "Mise à jour des dépendances Node.js..." - if npm update; then - log_success "Dépendances Node.js mises à jour" - else - log_warning "Échec de la mise à jour des dépendances Node.js" - fi - fi -} - -# Fonction pour vérifier les fichiers ignore d'un projet -check_project_ignore_files() { - local project="$1" - local project_path="/home/debian/$project" - - log "Vérification des fichiers ignore pour $project" - - if [[ ! -d "$project_path" ]]; then - log_error "Projet non trouvé: $project_path" - return 1 - fi - - cd "$project_path" - - # Vérifier .gitignore - if [[ ! -f ".gitignore" ]]; then - log_warning ".gitignore manquant pour $project" - else - log_success ".gitignore présent" - fi - - # Vérifier .dockerignore (pour les projets avec Docker) - if [[ " ${DOCKER_PROJECTS[@]} " =~ " ${project} " ]]; then - if [[ ! -f ".dockerignore" ]]; then - log_warning ".dockerignore manquant pour $project" - else - log_success ".dockerignore présent" - fi - fi - - # Vérifier .cursorignore - if [[ ! -f ".cursorignore" ]]; then - log_warning ".cursorignore manquant pour $project" - else - log_success ".cursorignore présent" - fi -} - -# Fonction pour nettoyer les fichiers non suivis d'un projet -clean_project_untracked() { - local project="$1" - local project_path="/home/debian/$project" - - log "Nettoyage des fichiers non suivis pour $project" - - if [[ ! -d "$project_path" ]]; then - log_error "Projet non trouvé: $project_path" - return 1 - fi - - cd "$project_path" - - # Lister les fichiers non suivis - local untracked_files - untracked_files=$(git ls-files --others --exclude-standard 2>/dev/null || true) - - if [[ -n "$untracked_files" ]]; then - log_info "Fichiers non suivis détectés:" - echo "$untracked_files" | while read -r file; do - echo " - $file" - done - - # Supprimer les fichiers non suivis - if git clean -fd; then - log_success "Fichiers non suivis supprimés" - else - log_warning "Échec du nettoyage des fichiers non suivis" - fi - else - log_success "Aucun fichier non suivi" - fi -} - -# Fonction pour compiler un projet -compile_project() { - local project="$1" - local project_path="/home/debian/$project" - - log "Compilation de $project" - - if [[ ! -d "$project_path" ]]; then - log_error "Projet non trouvé: $project_path" - return 1 - fi - - cd "$project_path" - - # Rust projects - if [[ -f "Cargo.toml" ]]; then - log "Compilation Rust..." - if cargo build --release; then - log_success "Compilation Rust réussie" - else - log_error "Échec de la compilation Rust" - return 1 - fi - - # WebAssembly pour sdk_client - if [[ "$project" == "sdk_client" ]]; then - log "Build WebAssembly..." - if wasm-pack build --target bundler --release; then - log_success "Build WebAssembly réussi" - else - log_error "Échec du build WebAssembly" - return 1 - fi - fi - fi - - # Node.js projects - if [[ -f "package.json" ]]; then - if grep -q '"build"' package.json; then - log "Build Node.js..." - if npm run build; then - log_success "Build Node.js réussi" - else - log_error "Échec du build Node.js" - return 1 - fi - fi - fi - - # TypeScript projects - if [[ -f "tsconfig.json" ]]; then - log "Vérification TypeScript..." - if npx tsc --noEmit; then - log_success "Vérification TypeScript réussie" - else - log_warning "Erreurs TypeScript détectées" - fi - fi -} - -# Fonction pour exécuter les tests d'un projet -test_project() { - local project="$1" - local project_path="/home/debian/$project" - - log "Exécution des tests pour $project" - - if [[ ! -d "$project_path" ]]; then - log_error "Projet non trouvé: $project_path" - return 1 - fi - - cd "$project_path" - - # Rust projects - if [[ -f "Cargo.toml" ]]; then - log "Tests Rust..." - if cargo test; then - log_success "Tests Rust réussis" - else - log_warning "Certains tests Rust ont échoué" - fi - fi - - # Node.js projects - if [[ -f "package.json" ]]; then - if grep -q '"test"' package.json; then - log "Tests Node.js..." - if npm test; then - log_success "Tests Node.js réussis" - else - log_warning "Certains tests Node.js ont échoué" - fi - fi - fi -} - -# Fonction pour déployer un projet -deploy_project() { - local project="$1" - local project_path="/home/debian/$project" - - log "Déploiement de $project" - - if [[ ! -d "$project_path" ]]; then - log_error "Projet non trouvé: $project_path" - return 1 - fi - - cd "$project_path" - - # Synchroniser les configurations si c'est un projet Docker - if [[ " ${DOCKER_PROJECTS[@]} " =~ " ${project} " ]]; then - if [[ -f "/home/debian/lecoffre_node/scripts/sync-configs.sh" ]]; then - log "Synchronisation des configurations..." - if /home/debian/lecoffre_node/scripts/sync-configs.sh "$project"; then - log_success "Configurations synchronisées" - else - log_warning "Échec de la synchronisation des configurations" - fi - fi - fi - - # Mettre à jour les dépendances - update_project_dependencies "$project" - - # Vérifier les fichiers ignore - check_project_ignore_files "$project" - - # Nettoyer les fichiers non suivis - clean_project_untracked "$project" - - # Compiler le projet - if ! compile_project "$project"; then - log_error "Échec de la compilation de $project" - return 1 - fi - - # Exécuter les tests - test_project "$project" - - # Push vers la branche ext - log "Push vers la branche ext..." - if git checkout ext; then - log_success "Basculement vers la branche ext" - else - log_error "Échec du basculement vers la branche ext" - return 1 - fi - - if git add .; then - log_success "Ajout des modifications" - else - log_error "Échec de l'ajout des modifications" - return 1 - fi - - if git commit -m "ci: docker_tag=ext - Mise à jour automatique des dépendances et compilation"; then - log_success "Commit des modifications" - else - log_warning "Aucune modification à committer" - fi - - if git push origin ext; then - log_success "Push vers la branche ext réussi" - else - log_error "Échec du push vers la branche ext" - return 1 - fi - - # Construire et pousser l'image Docker si c'est un projet Docker - if [[ " ${DOCKER_PROJECTS[@]} " =~ " ${project} " ]]; then - log "Construction de l'image Docker..." - if docker build -t "git.4nkweb.com/4nk/$project:ext" .; then - log_success "Image Docker construite" - - # Pousser l'image si demandé - if [[ "${PUSH_DOCKER_IMAGES:-false}" == "true" ]]; then - log "Push de l'image Docker..." - if docker push "git.4nkweb.com/4nk/$project:ext"; then - log_success "Image Docker poussée" - else - log_error "Échec du push de l'image Docker" - return 1 - fi - fi - else - log_error "Échec de la construction de l'image Docker" - return 1 - fi - fi - - log_success "Déploiement de $project terminé" -} - -# Fonction pour vérifier l'état du scan -check_scan_status() { - local sdk_relay_url="http://127.0.0.1:8091" - - echo "🔍 Vérification de l'état du scan..." - local response=$(curl -s "$sdk_relay_url" 2>/dev/null || echo "{}") - local scan_complete=$(echo "$response" | grep -o '"scan_complete":[^,]*' | cut -d: -f2 | tr -d ' "') - - if [ "$scan_complete" = "true" ]; then - echo "✅ Scan terminé avec succès" - return 0 - elif [ "$scan_complete" = "false" ]; then - echo "⚠️ Scan en cours, mais service disponible" - return 0 - else - echo "❓ État du scan inconnu" - return 1 - fi -} - -# Fonction principale de démarrage -start_services() { - log "🚀 Démarrage de lecoffre_node avec séquence optimisée" - - # Validation des dépendances externes avant démarrage - if ! validate_external_dependencies; then - log_error "Dépendances externes non disponibles. Arrêt du démarrage." - log "Utilisez './scripts/startup-sequence.sh restart' pour redémarrer après réparation" - exit 1 - fi - - # Préparation de l'environnement avant démarrage - log "🔧 Préparation de l'environnement..." - - # Synchroniser les configurations centralisées - if [ -f "./scripts/sync-configs.sh" ]; then - log "📋 Synchronisation des configurations..." - ./scripts/sync-configs.sh - fi - - # Préparation du build si nécessaire - if [ -f "./scripts/pre-build.sh" ]; then - log "🏗️ Préparation du build..." - ./scripts/pre-build.sh - fi - - # Démarrage simplifié utilisant les healthchecks du docker-compose.yml - log "📦 Démarrage de tous les services avec healthchecks..." - docker compose up -d - - log "⏳ Attente que tous les services soient prêts (utilise les healthchecks)..." - log " - sdk_relay: 60s start_period + healthcheck" - log " - ihm_client: 30s start_period + healthcheck" - log " - lecoffre-back: 30s start_period + healthcheck" - log " - lecoffre-front: 30s start_period + healthcheck" - - # Attendre que tous les services soient healthy - log "🔍 Vérification de l'état des services..." - sleep 10 - - # Vérifier l'état du scan de sdk_relay - check_scan_status - - # Étape 5: Vérification finale - log "🔍 Vérification finale de tous les services..." - - services=( - "tor:9050" - "bitcoin:8332" - "blindbit:8000" - "sdk_storage:8081" - "sdk_relay:8091" - "sdk_signer:8092" - "ihm_client:3003" - "lecoffre-back:8080" - "lecoffre-front:3004" - ) - - all_ready=true - for service in "${services[@]}"; do - name=$(echo $service | cut -d: -f1) - port=$(echo $service | cut -d: -f2) - - if curl -f -s "http://127.0.0.1:$port" > /dev/null 2>&1; then - log_success "$name est accessible" - else - log_warning "$name n'est pas accessible" - all_ready=false - fi - done - - if [ "$all_ready" = true ]; then - log_success "Tous les services sont prêts !" - log "📊 État des services:" - docker compose ps - else - log_warning "Certains services ne sont pas prêts" - log "📋 Logs des services problématiques:" - docker compose logs --tail=20 - exit 1 - fi -} - -# Fonction de redémarrage intelligent -restart_services() { - log "Redémarrage intelligent des services..." - - # Arrêter les services qui dépendent d'externes - log "Arrêt des services dépendants..." - docker stop lecoffre-back lecoffre-front ihm_client 2>/dev/null || true - - # Attendre que les dépendances externes soient disponibles - log "Attente de la disponibilité des dépendances externes..." - local max_attempts=30 - local attempt=0 - - while [ $attempt -lt $max_attempts ]; do - if validate_external_dependencies; then - log_success "Dépendances externes disponibles" - break - fi - - attempt=$((attempt + 1)) - log "Tentative $attempt/$max_attempts - Attente 10s..." - sleep 10 - done - - if [ $attempt -eq $max_attempts ]; then - log_error "Dépendances externes non disponibles après $max_attempts tentatives" - return 1 - fi - - # Redémarrer les services - log "Redémarrage des services..." - docker start lecoffre-back lecoffre-front ihm_client - - # Attendre que les services soient prêts - log "Attente de la disponibilité des services..." - sleep 15 - - log_success "Redémarrage terminé !" -} - -# Gestion des arguments -case "${1:-start}" in - "start") - start_services - ;; - "restart") - restart_services - ;; - "validate") - validate_external_dependencies - ;; - "monitor") - log "📊 Démarrage du monitoring continu..." - while true; do - sleep 60 - log "🔄 Vérification périodique..." - check_scan_status - done - ;; - "deploy") - log "🚀 Déploiement de tous les projets..." - - # Synchroniser les configurations centralisées - sync_configurations - - success_count=0 - total_count=0 - - # Déployer les projets sans Docker - log "📚 Déploiement des projets library..." - for project in "${LIBRARY_PROJECTS[@]}"; do - total_count=$((total_count + 1)) - if deploy_project "$project"; then - success_count=$((success_count + 1)) - fi - done - - # Déployer les projets avec Docker - log "🐳 Déploiement des projets Docker..." - for project in "${DOCKER_PROJECTS[@]}"; do - total_count=$((total_count + 1)) - if deploy_project "$project"; then - success_count=$((success_count + 1)) - fi - done - - # Déployer lecoffre_node - log "🏗️ Déploiement du projet principal..." - total_count=$((total_count + 1)) - cd "/home/debian/lecoffre_node" - if git checkout ext && git add . && git commit -m "ci: docker_tag=ext - Mise à jour des configurations centralisées" && git push origin ext; then - success_count=$((success_count + 1)) - log_success "Déploiement de lecoffre_node terminé" - else - log_error "Échec du déploiement de lecoffre_node" - fi - - # Résumé - log "📊 Résumé du déploiement:" - log " Projets déployés avec succès: $success_count/$total_count" - - if [[ $success_count -eq $total_count ]]; then - log_success "🎉 Tous les projets ont été déployés avec succès!" - else - log_error "❌ Certains projets ont échoué" - exit 1 - fi - ;; - "deploy-project") - if [[ -z "${2:-}" ]]; then - log_error "Usage: $0 deploy-project " - echo "Projets disponibles:" - echo " Docker: ${DOCKER_PROJECTS[*]}" - echo " Library: ${LIBRARY_PROJECTS[*]}" - exit 1 - fi - - local project="$2" - log "🚀 Déploiement du projet: $project" - - if deploy_project "$project"; then - log_success "Déploiement de $project terminé avec succès!" - else - log_error "Échec du déploiement de $project" - exit 1 - fi - ;; - "update-deps") - log "📦 Mise à jour des dépendances de tous les projets..." - - for project in "${DOCKER_PROJECTS[@]}" "${LIBRARY_PROJECTS[@]}"; do - update_project_dependencies "$project" - done - - log_success "Mise à jour des dépendances terminée" - ;; - "check-ignore") - log "🔍 Vérification des fichiers ignore de tous les projets..." - - for project in "${DOCKER_PROJECTS[@]}" "${LIBRARY_PROJECTS[@]}"; do - check_project_ignore_files "$project" - done - - log_success "Vérification des fichiers ignore terminée" - ;; - "clean-untracked") - log "🧹 Nettoyage des fichiers non suivis de tous les projets..." - - for project in "${DOCKER_PROJECTS[@]}" "${LIBRARY_PROJECTS[@]}"; do - clean_project_untracked "$project" - done - - log_success "Nettoyage des fichiers non suivis terminé" - ;; - "compile-all") - log "🔨 Compilation de tous les projets..." - - for project in "${DOCKER_PROJECTS[@]}" "${LIBRARY_PROJECTS[@]}"; do - compile_project "$project" - done - - log_success "Compilation de tous les projets terminée" - ;; - "test-all") - log "🧪 Exécution des tests de tous les projets..." - - for project in "${DOCKER_PROJECTS[@]}" "${LIBRARY_PROJECTS[@]}"; do - test_project "$project" - done - - log_success "Tests de tous les projets terminés" - ;; - *) - echo "Usage: $0 [COMMAND]" - echo "" - echo "COMMANDS:" - echo " start - Démarrage complet avec validation (défaut)" - echo " restart - Redémarrage intelligent après réparation" - echo " validate - Validation des dépendances externes uniquement" - echo " monitor - Monitoring continu" - echo "" - echo " deploy - Déploiement complet de tous les projets" - echo " deploy-project - Déploiement d'un projet spécifique" - echo " update-deps - Mise à jour des dépendances de tous les projets" - echo " check-ignore - Vérification des fichiers ignore" - echo " clean-untracked - Nettoyage des fichiers non suivis" - echo " compile-all - Compilation de tous les projets" - echo " test-all - Exécution des tests de tous les projets" - echo "" - echo "EXAMPLES:" - echo " $0 deploy # Déploie tous les projets" - echo " $0 deploy-project ihm_client # Déploie seulement ihm_client" - echo " $0 update-deps # Met à jour toutes les dépendances" - echo " PUSH_DOCKER_IMAGES=true $0 deploy # Déploie avec push des images Docker" - exit 1 - ;; -esac diff --git a/scripts/startup-with-funds-check.sh b/scripts/startup-with-funds-check.sh deleted file mode 100755 index 7ccfb21..0000000 --- a/scripts/startup-with-funds-check.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -# Script de démarrage avec vérification automatique des fonds -# Usage: ./startup-with-funds-check.sh - -set -e - -echo "=== DÉMARRAGE AVEC VÉRIFICATION DES FONDS ===" - -# Démarrer les services -echo "Démarrage des services..." -docker compose up -d - -# Attendre que les services soient prêts -echo "Attente du démarrage des services..." -sleep 60 - -# Vérifier et transférer les fonds si nécessaire -echo "Vérification des fonds..." -./scripts/funds/check_and_transfer_funds.sh 0.001 - -echo "=== DÉMARRAGE TERMINÉ ===" -echo "Services démarrés avec vérification des fonds automatique" diff --git a/scripts/startup.sh b/scripts/startup.sh deleted file mode 100755 index 3fb72ff..0000000 --- a/scripts/startup.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/bin/bash -set -euo pipefail - -echo "🚀 DÉMARRAGE AUTONOME LECOFFRE NODE" -echo "==================================" - -# Fonction de logging -log() { - echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" -} - -# Chargement des variables d'environnement -if [ -f /app/env.master ]; then - log "Chargement des variables d'environnement..." - export $(cat /app/env.master | grep -v '^#' | xargs) -fi - -# Vérification des prérequis -log "Vérification des prérequis..." - -# Vérifier que Docker est disponible -if ! command -v docker &> /dev/null; then - log "❌ Docker non disponible" - exit 1 -fi - -# Vérifier que docker-compose est disponible -if ! command -v docker-compose &> /dev/null; then - log "❌ Docker Compose non disponible" - exit 1 -fi - -log "✅ Prérequis validés" - -# Initialisation des répertoires -log "Initialisation des répertoires..." -mkdir -p /app/data /app/logs /app/backup /var/www/lecoffre/status /var/www/lecoffre/assets -chown -R appuser:appuser /app/data /app/logs /app/backup - -# Création du réseau Docker -log "Création du réseau Docker..." -docker network create ${DOCKER_NETWORK_NAME:-lecoffre_network} 2>/dev/null || true - -# Configuration des volumes Docker -log "Configuration des volumes Docker..." -docker volume create lecoffre_bitcoin_data 2>/dev/null || true -docker volume create lecoffre_blindbit_data 2>/dev/null || true -docker volume create lecoffre_sdk_data 2>/dev/null || true -docker volume create lecoffre_grafana_data 2>/dev/null || true -docker volume create lecoffre_loki_data 2>/dev/null || true - -# Démarrage des services -log "Démarrage des services Docker Compose..." -cd /app - -# Export des variables pour docker-compose -export COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME:-lecoffre} -export COMPOSE_FILE=${COMPOSE_FILE:-docker-compose.yml} - -# Démarrage en mode détaché -docker-compose up -d - -# Attente du démarrage des services -log "Attente du démarrage des services..." -sleep 30 - -# Vérification de l'état des services -log "Vérification de l'état des services..." -docker-compose ps - -# Vérification de la santé des services -log "Vérification de la santé des services..." -for service in bitcoin-signet blindbit-oracle sdk_relay lecoffre-back ihm_client; do - if docker-compose ps $service | grep -q "healthy\|Up"; then - log "✅ $service: OK" - else - log "⚠️ $service: Problème détecté" - fi -done - -# Test de connectivité -log "Test de connectivité..." -if curl -f -s http://localhost:8091/ > /dev/null; then - log "✅ SDK Relay: Accessible" -else - log "❌ SDK Relay: Inaccessible" -fi - -if curl -f -s http://localhost:8080/api/v1/health > /dev/null; then - log "✅ LeCoffre Back: Accessible" -else - log "❌ LeCoffre Back: Inaccessible" -fi - -if curl -f -s http://localhost:3003/ > /dev/null; then - log "✅ IHM Client: Accessible" -else - log "❌ IHM Client: Inaccessible" -fi - -log "✅ Démarrage autonome LeCoffre Node terminé" -log "📊 Services disponibles:" -log " - Nginx: http://localhost" -log " - Status: http://localhost/status/" -log " - Grafana: http://localhost/grafana/" -log " - LeCoffre Front: http://localhost/lecoffre/" -log " - IHM Client: http://localhost/" - -# Boucle de surveillance -log "Démarrage de la surveillance des services..." -while true; do - sleep 60 - - # Vérification périodique des services - for service in bitcoin-signet sdk_relay lecoffre-back; do - if ! docker-compose ps $service | grep -q "healthy\|Up"; then - log "⚠️ Service $service en problème, redémarrage..." - docker-compose restart $service - fi - done -done diff --git a/scripts/update-healthchecks.sh b/scripts/update-healthchecks.sh new file mode 100755 index 0000000..a9f4cd4 --- /dev/null +++ b/scripts/update-healthchecks.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +# Script pour mettre à jour les healthchecks avec des tests de progression + +set -e + +COMPOSE_FILE="/home/debian/4NK_env/lecoffre_node/docker-compose.yml" +BACKUP_FILE="/home/debian/4NK_env/lecoffre_node/docker-compose.yml.backup" + +echo "Mise à jour des healthchecks avec tests de progression..." + +# Créer une sauvegarde +cp "$COMPOSE_FILE" "$BACKUP_FILE" + +# Fonction pour remplacer un healthcheck +replace_healthcheck() { + local service_name="$1" + local old_test="$2" + local new_test="$3" + + echo "Mise à jour du healthcheck pour $service_name..." + + # Utiliser awk pour remplacer le test + awk -v service="$service_name" -v old_test="$old_test" -v new_test="$new_test" ' + BEGIN { in_service = 0; in_healthcheck = 0; replaced = 0 } + /^ [a-zA-Z_]+:/ { + if (in_healthcheck) in_healthcheck = 0 + if ($0 ~ "^ " service ":") in_service = 1 + else in_service = 0 + } + /^ healthcheck:/ { + if (in_service) in_healthcheck = 1 + } + /^ test:/ { + if (in_healthcheck && !replaced) { + print " test: " new_test + replaced = 1 + next + } + } + { print } + ' "$COMPOSE_FILE" > "$COMPOSE_FILE.tmp" && mv "$COMPOSE_FILE.tmp" "$COMPOSE_FILE" +} + +# Mettre à jour Tor +replace_healthcheck "tor" \ + '["CMD", "sh", "-c", "if test -f /var/log/tor/tor.log && test -s /var/log/tor/tor.log; then echo '\''Tor ready: SOCKS proxy listening on port 9050'\''; exit 0; else echo '\''Tor starting: SOCKS proxy not yet ready'\''; exit 1; fi"]' \ + '["CMD", "sh", "-c", "if test -f /var/log/tor/tor.log && test -s /var/log/tor/tor.log; then bootstrap_log=\$(tail -20 /var/log/tor/tor.log | grep '\''Bootstrapped'\'' | tail -1); if echo \"\$bootstrap_log\" | grep -q '\''100%'\''; then echo '\''Tor ready: Bootstrap complete (100%)'\''; exit 0; else progress=\$(echo \"\$bootstrap_log\" | grep -o '\''[0-9]\\\\+%'\'' | tail -1 || echo '\''0%'\''); echo \"Tor bootstrapping: \$progress\"; exit 1; fi; else echo '\''Tor starting: Bootstrap not yet started'\''; exit 1; fi"]' + +# Mettre à jour Bitcoin +replace_healthcheck "bitcoin" \ + '["CMD", "sh", "-c", "if bitcoin-cli -conf=/etc/bitcoin/bitcoin.conf getblockchaininfo > /dev/null 2>&1; then echo '\''Bitcoin ready: RPC responding'\''; exit 0; else echo '\''Bitcoin starting: RPC not ready'\''; exit 1; fi"]' \ + '["CMD", "sh", "-c", "info=\$(bitcoin-cli -conf=/etc/bitcoin/bitcoin.conf getblockchaininfo 2>/dev/null || echo '\''{}'\''); blocks=\$(echo \"\$info\" | jq -r '\''.blocks // 0'\''); headers=\$(echo \"\$info\" | jq -r '\''.headers // 0'\''); ibd=\$(echo \"\$info\" | jq -r '\''.initialblockdownload // false'\''); if [ \"\$ibd\" = \"false\" ] || [ \"\$blocks\" -eq \"\$headers\" ]; then echo \"Bitcoin ready: Synced (\$blocks blocks)\"; exit 0; else remaining=\$((headers - blocks)); progress=\$((blocks * 100 / headers)); echo \"Bitcoin IBD: \$blocks/\$headers (\$remaining remaining) - \$progress%\"; exit 1; fi"]' + +# Mettre à jour BlindBit +replace_healthcheck "blindbit" \ + '["CMD", "sh", "-c", "if wget -q --spider http://localhost:8000/tweaks/1; then echo '\''BlindBit ready: Oracle service responding'\''; exit 0; else echo '\''BlindBit starting: Oracle service not yet ready'\''; exit 1; fi"]' \ + '["CMD", "sh", "-c", "scan_logs=\$(tail -10 /var/log/blindbit/blindbit.log 2>/dev/null | grep -E \"(scanning|scan|blocks|tweaks)\" | tail -1 || echo \"\"); if [ -n \"\$scan_logs\" ]; then echo \"BlindBit scanning: \$scan_logs\"; exit 1; else if wget -q --spider http://localhost:8000/tweaks/1; then echo '\''BlindBit ready: Oracle service responding'\''; exit 0; else echo '\''BlindBit starting: Oracle service not yet ready'\''; exit 1; fi; fi"]' + +# Mettre à jour SDK Relay +replace_healthcheck "sdk_relay" \ + '["CMD", "sh", "-c", "if curl -f http://localhost:8091/ >/dev/null 2>&1; then echo '\''SDK Relay ready: WebSocket server responding'\''; exit 0; else echo '\''SDK Relay IBD: Waiting for Bitcoin sync to complete'\''; exit 1; fi"]' \ + '["CMD", "sh", "-c", "relay_logs=\$(tail -10 /var/log/sdk_relay/sdk_relay.log 2>/dev/null | grep -E \"(IBD|blocks|headers|waiting|scanning)\" | tail -1 || echo \"\"); if [ -n \"\$relay_logs\" ]; then echo \"SDK Relay sync: \$relay_logs\"; exit 1; else if curl -f http://localhost:8091/ >/dev/null 2>&1; then echo '\''SDK Relay ready: WebSocket server responding'\''; exit 0; else echo '\''SDK Relay starting: WebSocket server not yet ready'\''; exit 1; fi; fi"]' + +# Mettre à jour SDK Signer +replace_healthcheck "sdk_signer" \ + '["CMD", "sh", "-c", "if curl -f http://localhost:9090/ >/dev/null 2>&1; then echo '\''SDK Signer ready: WebSocket server responding'\''; exit 0; else echo '\''SDK Signer starting: WebSocket server not yet ready'\''; exit 1; fi"]' \ + '["CMD", "sh", "-c", "signer_logs=\$(tail -10 /var/log/sdk_signer/sdk_signer.log 2>/dev/null | grep -E \"(Disconnected|reconnect|error|connected|waiting)\" | tail -1 || echo \"\"); if [ -n \"\$signer_logs\" ]; then echo \"SDK Signer conn: \$signer_logs\"; exit 1; else if curl -f http://localhost:9090/ >/dev/null 2>&1; then echo '\''SDK Signer ready: WebSocket server responding'\''; exit 0; else echo '\''SDK Signer starting: WebSocket server not yet ready'\''; exit 1; fi; fi"]' + +echo "Healthchecks mis à jour avec succès!" +echo "Sauvegarde créée: $BACKUP_FILE" diff --git a/scripts/watch-progress.sh b/scripts/watch-progress.sh deleted file mode 100755 index b489e58..0000000 --- a/scripts/watch-progress.sh +++ /dev/null @@ -1,227 +0,0 @@ -#!/bin/bash - -# Script de surveillance en temps réel de la progression des services LeCoffre Node -# Affiche la progression des différents processus (IBD, scans, etc.) en continu -# Optimisé pour les processus longs (Tor: 15min, Bitcoin: 2h) - -set -e - -# Couleurs pour l'affichage -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -PURPLE='\033[0;35m' -CYAN='\033[0;36m' -NC='\033[0m' # No Color - -# Configuration des intervalles de mise à jour -BITCOIN_UPDATE_INTERVAL=60 # Bitcoin: toutes les minutes -TOR_UPDATE_INTERVAL=30 # Tor: toutes les 30 secondes -OTHER_UPDATE_INTERVAL=15 # Autres services: toutes les 15 secondes - -# Fonction pour effacer l'écran et afficher le header -clear_and_header() { - clear - echo -e "${BLUE}========================================${NC}" - echo -e "${BLUE} LeCoffre Node - Live Progress Monitor${NC}" - echo -e "${BLUE}========================================${NC}" - echo -e "${YELLOW}Last updated: $(date)${NC}" - echo -} - -# Fonction pour afficher la progression Bitcoin -show_bitcoin_progress() { - local container_name="bitcoin-signet" - if docker ps --format "table {{.Names}}" | grep -q "$container_name"; then - echo -e "${CYAN}Bitcoin Progress:${NC}" - local info=$(docker exec "$container_name" bitcoin-cli -conf=/etc/bitcoin/bitcoin.conf getblockchaininfo 2>/dev/null || echo '{}') - local blocks=$(echo "$info" | jq -r '.blocks // 0') - local headers=$(echo "$info" | jq -r '.headers // 0') - local progress=0 - - if [ "$headers" -gt 0 ]; then - progress=$((blocks * 100 / headers)) - fi - - if [ "$blocks" -eq "$headers" ] && [ "$blocks" -gt 0 ]; then - echo -e " ${GREEN}✓ Bitcoin sync complete: $blocks blocks${NC}" - else - # Calculer le temps écoulé depuis le démarrage - local start_time=$(docker inspect --format='{{.State.StartedAt}}' "$container_name" 2>/dev/null | xargs -I {} date -d {} +%s 2>/dev/null || echo "0") - local current_time=$(date +%s) - local elapsed_time=$((current_time - start_time)) - local elapsed_min=$((elapsed_time / 60)) - local elapsed_hour=$((elapsed_min / 60)) - - local time_str="" - if [ $elapsed_hour -gt 0 ]; then - time_str="${elapsed_hour}h ${elapsed_min}m" - else - time_str="${elapsed_min}m" - fi - - echo -e " ${YELLOW}⏳ Bitcoin IBD: $blocks/$headers blocks ($(($headers - $blocks)) remaining) - $progress% (${time_str} elapsed)${NC}" - - # Afficher une barre de progression - local bar_length=50 - local filled_length=$((progress * bar_length / 100)) - local bar="" - for ((i=0; i/dev/null | grep "Bootstrapped" | tail -1 || echo "") - if [ -n "$bootstrap_log" ]; then - local progress=$(echo "$bootstrap_log" | grep -o '[0-9]\+%' | tail -1 || echo "0%") - if echo "$bootstrap_log" | grep -q "100%"; then - echo -e " ${GREEN}✓ Tor ready: Bootstrap complete (100%)${NC}" - else - echo -e " ${YELLOW}⏳ Tor bootstrapping: $progress${NC}" - fi - else - echo -e " ${YELLOW}⏳ Tor starting: Bootstrap not yet started${NC}" - fi - echo - fi -} - -# Fonction pour afficher la progression SDK Relay -show_sdk_relay_progress() { - local container_name="sdk_relay" - if docker ps --format "table {{.Names}}" | grep -q "$container_name"; then - echo -e "${CYAN}SDK Relay Progress:${NC}" - local logs=$(docker logs "$container_name" --tail 3 2>/dev/null | grep -E "(waiting for|blocks to download|IBD)" | tail -1 || echo "") - if [ -n "$logs" ]; then - echo -e " ${YELLOW}⏳ SDK Relay IBD: $logs${NC}" - else - local response=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8091/ 2>/dev/null || echo "000") - if [ "$response" = "200" ]; then - echo -e " ${GREEN}✓ SDK Relay ready: WebSocket server responding${NC}" - else - echo -e " ${YELLOW}⏳ SDK Relay starting: WebSocket server not yet ready${NC}" - fi - fi - echo - fi -} - -# Fonction pour afficher le statut des services -show_services_status() { - echo -e "${PURPLE}Services Status:${NC}" - - # Services critiques - local services=("tor-proxy:Tor Proxy" "bitcoin-signet:Bitcoin Signet" "blindbit-oracle:BlindBit Oracle" "sdk_storage:SDK Storage" "sdk_relay:SDK Relay" "sdk_signer:SDK Signer" "ihm_client:IHM Client") - - for service in "${services[@]}"; do - local container_name="${service%%:*}" - local display_name="${service##*:}" - local status=$(docker inspect --format='{{.State.Health.Status}}' "$container_name" 2>/dev/null || echo "no-healthcheck") - local running=$(docker inspect --format='{{.State.Running}}' "$container_name" 2>/dev/null || echo "false") - - if [ "$running" = "true" ]; then - case "$status" in - "healthy") - echo -e " ${GREEN}✓${NC} $display_name: ${GREEN}Ready${NC}" - ;; - "unhealthy") - echo -e " ${YELLOW}⚠${NC} $display_name: ${YELLOW}Processing${NC}" - ;; - "starting") - echo -e " ${YELLOW}⏳${NC} $display_name: ${YELLOW}Starting${NC}" - ;; - "no-healthcheck") - echo -e " ${BLUE}ℹ${NC} $display_name: ${BLUE}Running${NC}" - ;; - esac - else - echo -e " ${RED}✗${NC} $display_name: ${RED}Stopped${NC}" - fi - done - echo -} - -# Fonction pour afficher les services en attente -show_waiting_services() { - echo -e "${PURPLE}Services Waiting for Dependencies:${NC}" - - # Vérifier les services LeCoffre - local lecoffre_back=$(docker inspect --format='{{.State.Running}}' "lecoffre-back" 2>/dev/null || echo "false") - local lecoffre_front=$(docker inspect --format='{{.State.Running}}' "lecoffre-front" 2>/dev/null || echo "false") - - if [ "$lecoffre_back" = "false" ]; then - echo -e " ${YELLOW}⏳ LeCoffre Backend: Waiting for SDK Relay${NC}" - fi - - if [ "$lecoffre_front" = "false" ]; then - echo -e " ${YELLOW}⏳ LeCoffre Frontend: Waiting for LeCoffre Backend${NC}" - fi - - echo -} - -# Fonction principale -main() { - local current_time=$(date +%s) - local bitcoin_should_update=$((current_time - last_bitcoin_update >= BITCOIN_UPDATE_INTERVAL)) - local tor_should_update=$((current_time - last_tor_update >= TOR_UPDATE_INTERVAL)) - local other_should_update=$((current_time - last_other_update >= OTHER_UPDATE_INTERVAL)) - - clear_and_header - - # Afficher la progression Bitcoin (toutes les minutes) - if [ $bitcoin_should_update -eq 1 ]; then - show_bitcoin_progress - last_bitcoin_update=$current_time - fi - - # Afficher la progression Tor (toutes les 30 secondes) - if [ $tor_should_update -eq 1 ]; then - show_tor_progress - last_tor_update=$current_time - fi - - # Afficher la progression SDK Relay (toutes les 15 secondes) - if [ $other_should_update -eq 1 ]; then - show_sdk_relay_progress - last_other_update=$current_time - fi - - # Toujours afficher le statut des services - show_services_status - show_waiting_services - - echo -e "${BLUE}========================================${NC}" - echo -e "${BLUE} Press Ctrl+C to stop monitoring${NC}" - echo -e "${BLUE} Bitcoin: ${BITCOIN_UPDATE_INTERVAL}s | Tor: ${TOR_UPDATE_INTERVAL}s | Others: ${OTHER_UPDATE_INTERVAL}s${NC}" - echo -e "${BLUE}========================================${NC}" -} - -# Fonction de nettoyage -cleanup() { - echo -e "\n${YELLOW}Monitoring stopped.${NC}" - exit 0 -} - -# Gestion des signaux -trap cleanup SIGINT SIGTERM - -# Initialiser les timestamps -last_bitcoin_update=0 -last_tor_update=0 -last_other_update=0 - -# Boucle principale -while true; do - main - sleep 15 # Rafraîchissement général toutes les 15 secondes -done