diff --git a/docs/retours_experience/README.md b/docs/retours_experience/README.md new file mode 100644 index 0000000..8396302 --- /dev/null +++ b/docs/retours_experience/README.md @@ -0,0 +1,163 @@ +# Retours d'Expérience - LeCoffre Node + +Ce répertoire contient tous les retours d'expérience (REX) documentés lors du développement et de la maintenance du projet LeCoffre Node. + +## 📋 Liste des REX + +### 1. [REX_BOOTSTRAP_WEBSOCKET.md](./REX_BOOTSTRAP_WEBSOCKET.md) +**Problème** : Bootstrap WebSocket et réception de fonds du faucet +- Configuration bootstrap incorrecte +- Diagnostic des fonds insuffisants +- Solution avec adresse SP permanente + +### 2. [REX_DOCKER_TOOLS_INSTALLATION.md](./REX_DOCKER_TOOLS_INSTALLATION.md) +**Problème** : Installation d'outils dans les conteneurs Docker +- Gestion des différentes images de base (Debian, Alpine, BusyBox) +- Solutions pour les permissions et les erreurs d'installation +- Scripts automatisés d'installation + +### 3. [REX_STARTUP_SEQUENCE_IMPROVEMENTS.md](./REX_STARTUP_SEQUENCE_IMPROVEMENTS.md) +**Problème** : Améliorations de la séquence de démarrage +- Gestion des dépendances entre services +- Healthchecks robustes +- Scripts de démarrage intelligent + +### 4. [REX_CONFIGURATION_MANAGEMENT.md](./REX_CONFIGURATION_MANAGEMENT.md) +**Problème** : Gestion des configurations +- Écriture non effective des fichiers de configuration +- Vérification systématique des configurations +- Gestion des permissions et variables d'environnement + +## 🎯 Objectifs des REX + +### 1. **Éviter la répétition d'erreurs** +- Documenter les problèmes rencontrés et leurs solutions +- Créer des scripts automatisés pour les tâches récurrentes +- Établir des bonnes pratiques + +### 2. **Améliorer la maintenance** +- Faciliter le debugging pour les futurs développeurs +- Standardiser les procédures de déploiement +- Automatiser les vérifications + +### 3. **Partager les connaissances** +- Transmettre l'expérience acquise +- Documenter les solutions techniques +- Créer une base de connaissances + +## 🔧 Utilisation des REX + +### 1. **Avant de commencer un développement** +- Consulter les REX pertinents +- Vérifier les bonnes pratiques établies +- Utiliser les scripts automatisés + +### 2. **En cas de problème** +- Rechercher dans les REX des solutions similaires +- Suivre les procédures de diagnostic documentées +- Utiliser les scripts de vérification + +### 3. **Après résolution d'un problème** +- Documenter la solution dans un nouveau REX +- Mettre à jour les scripts existants si nécessaire +- Partager les bonnes pratiques + +## 📚 Structure des REX + +Chaque REX suit la même structure : + +```markdown +# Titre du REX + +## Problème initial +- Description du problème rencontré +- Impact sur le système +- Cause identifiée + +## Diagnostic effectué +- Étapes de diagnostic +- Outils utilisés +- Résultats obtenus + +## Solutions implémentées +- Solutions techniques +- Scripts créés +- Configurations modifiées + +## Leçons apprises +- Bonnes pratiques établies +- Actions préventives +- Recommandations + +## Scripts et outils +- Scripts automatisés +- Outils de diagnostic +- Procédures de vérification + +## Date +- Date de création +- Problème résolu +- Impact +``` + +## 🚀 Scripts automatisés + +### Scripts de diagnostic +- `verify_config_writing.sh` : Vérification des écritures de configuration +- `verify_all_configs.sh` : Vérification complète des configurations +- `verify_env_vars.sh` : Vérification des variables d'environnement + +### Scripts d'installation +- `install_tools_debian.sh` : Installation d'outils sur Debian/Ubuntu +- `install_tools_alpine.sh` : Installation d'outils sur Alpine + +### Scripts de démarrage +- `startup-sequence.sh` : Démarrage intelligent des services +- `validate_external_dependencies.sh` : Validation des dépendances externes + +## 📝 Contribution aux REX + +### 1. **Créer un nouveau REX** +- Suivre la structure standard +- Documenter le problème et la solution +- Inclure les scripts et configurations + +### 2. **Mettre à jour un REX existant** +- Ajouter les nouvelles informations +- Mettre à jour les scripts si nécessaire +- Documenter les évolutions + +### 3. **Maintenir les REX** +- Vérifier la pertinence des informations +- Mettre à jour les scripts +- Nettoyer les informations obsolètes + +## 🔍 Recherche dans les REX + +### Par problème +- **Bootstrap WebSocket** : REX_BOOTSTRAP_WEBSOCKET.md +- **Installation Docker** : REX_DOCKER_TOOLS_INSTALLATION.md +- **Démarrage services** : REX_STARTUP_SEQUENCE_IMPROVEMENTS.md +- **Configuration** : REX_CONFIGURATION_MANAGEMENT.md + +### Par solution +- **Scripts automatisés** : Voir la section "Scripts et outils" de chaque REX +- **Configurations** : Voir la section "Solutions implémentées" +- **Bonnes pratiques** : Voir la section "Leçons apprises" + +## 📅 Historique + +- **2025-09-20** : Création du répertoire REX +- **2025-09-20** : Documentation des 4 premiers REX +- **2025-09-20** : Création des scripts automatisés + +## 🎯 Prochaines étapes + +1. **Automatiser** la création de REX +2. **Intégrer** les REX dans le processus de développement +3. **Créer** des templates pour les nouveaux REX +4. **Mettre en place** un système de recherche avancée + +--- + +**Note** : Ce répertoire est un élément clé de la maintenance et de l'amélioration continue du projet LeCoffre Node. Il doit être maintenu à jour et enrichi à chaque nouvelle expérience. diff --git a/docs/retours_experience/REX_BOOTSTRAP_WEBSOCKET.md b/docs/retours_experience/REX_BOOTSTRAP_WEBSOCKET.md new file mode 100644 index 0000000..ee5a6e3 --- /dev/null +++ b/docs/retours_experience/REX_BOOTSTRAP_WEBSOCKET.md @@ -0,0 +1,87 @@ +# Retour d'Expérience : Bootstrap WebSocket et Faucet + +## Problème initial +- **Erreur** : "Failed to create pairing process: Insufficient funds. Missing 1096 sats." +- **Cause** : Le relai local n'avait pas de fonds car le bootstrap ne fonctionnait pas correctement +- **Impact** : Impossible de faire du pairing d'appareils + +## Diagnostic effectué + +### 1. Configuration bootstrap incorrecte +```bash +# ❌ Configuration initiale (incorrecte) +bootstrap_url="ws://dev3.4nkweb.com:8090" +``` + +### 2. Tests de connectivité +- **Port 8090** : Accessible mais pas de faucet WebSocket +- **Port 443** : 502 Bad Gateway +- **Port 8080** : Service Express.js sans routes signer/websocket + +### 3. Solution trouvée +```bash +# ✅ Configuration corrigée +bootstrap_url="wss://dev3.4nkweb.com/ws/" +bootstrap_faucet=true +``` + +## Leçons apprises + +### 1. Vérification des endpoints WebSocket +- **Toujours tester** : `wscat -c wss://domain/ws/` avant configuration +- **Vérifier le protocole** : WSS (sécurisé) vs WS (non sécurisé) +- **Tester le faucet** : Envoyer une requête faucet et vérifier la réponse + +### 2. Configuration des adresses SP permanentes +```bash +# ✅ Ajouter dans sdk_relay.conf +sp_address="tsp1qqgmwp9n5p9ujhq2j6cfqe4jpkyu70jh9rgj0pwt3ndezk2mrlvw6jqew8fhsulewzglfr7g2aa48wyj4n0r7yasa3fm666vda8984ke8tuaf9m89" +``` + +### 3. Diagnostic des fonds +- **Vérifier le wallet** : `docker exec sdk_relay cat /home/bitcoin/.4nk/default | jq '.outputs'` +- **Vérifier la maturité** : Les fonds minés localement peuvent être immatures +- **Utiliser le faucet distant** : Plus fiable que le minage local pour les tests + +## Scripts de diagnostic + +### Test de connectivité WebSocket +```bash +#!/bin/bash +# Test de connectivité WebSocket bootstrap +echo "Test de connectivité WebSocket..." +timeout 10 wscat -c wss://dev3.4nkweb.com/ws/ -x '{"type":"faucet","address":"test"}' || echo "Échec de connexion" +``` + +### Vérification des fonds du relai +```bash +#!/bin/bash +# Vérification des fonds du relai +echo "Vérification des fonds du relai..." +docker exec sdk_relay cat /home/bitcoin/.4nk/default | jq '.outputs | length' +``` + +## Configuration recommandée + +### sdk_relay.conf +```ini +# Configuration bootstrap WebSocket +bootstrap_url="wss://dev3.4nkweb.com/ws/" +bootstrap_faucet=true + +# Adresse SP permanente (optionnel mais recommandé) +sp_address="tsp1qqgmwp9n5p9ujhq2j6cfqe4jpkyu70jh9rgj0pwt3ndezk2mrlvw6jqew8fhsulewzglfr7g2aa48wyj4n0r7yasa3fm666vda8984ke8tuaf9m89" +``` + +## Actions préventives + +1. **Toujours tester** la connectivité WebSocket avant déploiement +2. **Configurer une adresse SP permanente** pour éviter les changements d'adresse +3. **Vérifier les fonds** du relai après démarrage +4. **Documenter les endpoints** de faucet fonctionnels +5. **Tester le pairing** après chaque modification de configuration + +## Date +- **Créé** : 2025-09-20 +- **Problème résolu** : Bootstrap WebSocket et réception de fonds +- **Impact** : Résolution du problème de fonds insuffisants pour le pairing diff --git a/docs/retours_experience/REX_CONFIGURATION_MANAGEMENT.md b/docs/retours_experience/REX_CONFIGURATION_MANAGEMENT.md new file mode 100644 index 0000000..ae0480a --- /dev/null +++ b/docs/retours_experience/REX_CONFIGURATION_MANAGEMENT.md @@ -0,0 +1,270 @@ +# Retour d'Expérience : Gestion des configurations + +## Problème initial +- **Erreurs** : Fichiers de configuration non écrits correctement +- **Impact** : Services ne démarrent pas avec les bonnes configurations +- **Cause** : Écriture non effective des fichiers de configuration + +## Erreurs rencontrées + +### 1. Fichiers de configuration non écrits +```bash +# ❌ Problème : Écriture non effective +echo "bootstrap_url=wss://dev3.4nkweb.com/ws/" >> relay/sdk_relay.conf +# Le fichier n'était pas mis à jour correctement +``` + +### 2. Permissions insuffisantes +```bash +# ❌ Erreur +sed: cannot rename /home/bitcoin/sedktvYLI: Device or resource busy +``` + +### 3. Variables d'environnement non prises en compte +```bash +# ❌ Problème : .env override docker-compose.yml +# docker-compose.yml +environment: + - SIGNER_WS_URL=ws://dev3.4nkweb.com:9090 + +# .env (override) +SIGNER_WS_URL=ws://sdk_signer:9090 +``` + +## Solutions implémentées + +### 1. Vérification systématique des écritures +```bash +#!/bin/bash +# verify_config_writing.sh + +# Fonction de vérification +verify_config_file() { + local file="$1" + local expected_content="$2" + + echo "Vérification de $file..." + + if [ -f "$file" ]; then + if grep -q "$expected_content" "$file"; then + echo "✅ $file contient '$expected_content'" + return 0 + else + echo "❌ $file ne contient pas '$expected_content'" + return 1 + fi + else + echo "❌ $file n'existe pas" + return 1 + fi +} + +# Vérifications +verify_config_file "relay/sdk_relay.conf" "bootstrap_url=\"wss://dev3.4nkweb.com/ws/\"" +verify_config_file "relay/sdk_relay.conf" "sp_address=" +verify_config_file ".env" "RELAY_URLS=ws://sdk_relay:8090" +``` + +### 2. Écriture atomique des configurations +```bash +#!/bin/bash +# atomic_config_update.sh + +# Fonction d'écriture atomique +atomic_write_config() { + local file="$1" + local content="$2" + local temp_file="${file}.tmp" + + echo "Mise à jour atomique de $file..." + + # Écriture dans un fichier temporaire + echo "$content" > "$temp_file" + + # Vérification de l'écriture + if [ -f "$temp_file" ] && [ -s "$temp_file" ]; then + # Remplacement atomique + mv "$temp_file" "$file" + echo "✅ $file mis à jour avec succès" + return 0 + else + echo "❌ Échec de l'écriture de $file" + rm -f "$temp_file" + return 1 + fi +} + +# Exemple d'utilisation +atomic_write_config "relay/sdk_relay.conf" "bootstrap_url=\"wss://dev3.4nkweb.com/ws/\"" +``` + +### 3. Gestion des permissions +```bash +#!/bin/bash +# fix_config_permissions.sh + +# Correction des permissions +fix_permissions() { + local file="$1" + + echo "Correction des permissions pour $file..." + + # Vérifier si le fichier existe + if [ -f "$file" ]; then + # Corriger les permissions + chmod 644 "$file" + chown $(whoami):$(whoami) "$file" + echo "✅ Permissions corrigées pour $file" + else + echo "❌ $file n'existe pas" + return 1 + fi +} + +# Correction des permissions pour tous les fichiers de config +fix_permissions "relay/sdk_relay.conf" +fix_permissions ".env" +fix_permissions "docker-compose.yml" +``` + +## Règles Cursor ajoutées + +### Règle de vérification des configurations +```markdown +# RÈGLE CRITIQUE : Vérification des Fichiers de Configuration +- TOUJOURS vérifier l'écriture effective des fichiers de configuration critiques après modification +- Fichiers à vérifier systématiquement : nginx.conf, bitcoin.conf, package.json, Cargo.toml +- Utiliser des commandes de vérification (cat, jq, syntax check) pour s'assurer que l'écriture a été effective +- Cette règle évite les erreurs de configuration dues à des écritures non effectives +``` + +## Scripts de vérification + +### Vérification complète des configurations +```bash +#!/bin/bash +# verify_all_configs.sh + +echo "=== Vérification des configurations ===" + +# Vérification des fichiers de configuration +config_files=( + "relay/sdk_relay.conf" + ".env" + "docker-compose.yml" + "miner/.env" +) + +for file in "${config_files[@]}"; do + if [ -f "$file" ]; then + echo "✅ $file existe" + + # Vérification de la syntaxe + case "$file" in + *.conf) + echo " Vérification de la syntaxe..." + # Pas de vérification spécifique pour .conf + ;; + *.yml|*.yaml) + echo " Vérification de la syntaxe YAML..." + if command -v yq >/dev/null 2>&1; then + yq eval '.' "$file" >/dev/null && echo " ✅ Syntaxe YAML valide" || echo " ❌ Syntaxe YAML invalide" + fi + ;; + *.json) + echo " Vérification de la syntaxe JSON..." + jq '.' "$file" >/dev/null && echo " ✅ Syntaxe JSON valide" || echo " ❌ Syntaxe JSON invalide" + ;; + esac + else + echo "❌ $file n'existe pas" + fi +done +``` + +### Vérification des variables d'environnement +```bash +#!/bin/bash +# verify_env_vars.sh + +echo "=== Vérification des variables d'environnement ===" + +# Vérification des variables critiques +critical_vars=( + "SIGNER_WS_URL" + "RELAY_URLS" + "SIGNER_BASE_URL" + "VITE_BOOTSTRAPURL" +) + +for var in "${critical_vars[@]}"; do + if [ -f ".env" ]; then + if grep -q "^$var=" ".env"; then + value=$(grep "^$var=" ".env" | cut -d'=' -f2-) + echo "✅ $var=$value" + else + echo "❌ $var non définie dans .env" + fi + else + echo "❌ Fichier .env non trouvé" + fi +done +``` + +## Bonnes pratiques + +### 1. Écriture des configurations +- **Utiliser** des écritures atomiques avec fichiers temporaires +- **Vérifier** l'écriture après chaque modification +- **Corriger** les permissions si nécessaire + +### 2. Validation des configurations +- **Vérifier** la syntaxe des fichiers (JSON, YAML, etc.) +- **Tester** les configurations avant déploiement +- **Documenter** les changements de configuration + +### 3. Gestion des variables d'environnement +- **Centraliser** les variables dans `.env` +- **Vérifier** les overrides entre `.env` et `docker-compose.yml` +- **Documenter** les variables critiques + +## Scripts automatisés + +### Mise à jour et vérification complète +```bash +#!/bin/bash +# update_and_verify_configs.sh + +echo "=== Mise à jour et vérification des configurations ===" + +# 1. Mise à jour des configurations +echo "Mise à jour des configurations..." +./atomic_config_update.sh + +# 2. Correction des permissions +echo "Correction des permissions..." +./fix_config_permissions.sh + +# 3. Vérification des configurations +echo "Vérification des configurations..." +./verify_all_configs.sh + +# 4. Vérification des variables d'environnement +echo "Vérification des variables d'environnement..." +./verify_env_vars.sh + +echo "=== Vérification terminée ===" +``` + +## Actions préventives + +1. **Toujours vérifier** l'écriture effective des fichiers de configuration +2. **Utiliser** des écritures atomiques pour éviter les corruptions +3. **Corriger** les permissions après modification +4. **Valider** la syntaxe des fichiers de configuration +5. **Documenter** les changements de configuration + +## Date +- **Créé** : 2025-09-20 +- **Problème résolu** : Gestion des configurations et écriture effective +- **Impact** : Amélioration de la fiabilité des configurations diff --git a/docs/retours_experience/REX_DOCKER_TOOLS_INSTALLATION.md b/docs/retours_experience/REX_DOCKER_TOOLS_INSTALLATION.md new file mode 100644 index 0000000..db350fc --- /dev/null +++ b/docs/retours_experience/REX_DOCKER_TOOLS_INSTALLATION.md @@ -0,0 +1,179 @@ +# Retour d'Expérience : Installation d'outils dans les conteneurs Docker + +## Problème initial +- **Besoin** : Installer `curl`, `git`, `wget`, `jq`, `telnet`, `wscat`, `tee`, `npm` dans tous les conteneurs +- **Défi** : Différentes images de base (Debian, Alpine, BusyBox) +- **Erreurs** : Commandes `apt-get` dans des images Alpine, permissions insuffisantes + +## Solutions développées + +### 1. Détection des images de base +```bash +# Déterminer le type d'image +docker exec cat /etc/os-release +# ou +docker exec which apt-get # Debian/Ubuntu +docker exec which apk # Alpine +``` + +### 2. Installation adaptée par type d'image + +#### Images Debian/Ubuntu +```dockerfile +RUN apt-get update && apt-get upgrade -y && \ + apt-get install -y curl git wget jq telnet npm coreutils && \ + npm install -g wscat && \ + rm -rf /var/lib/apt/lists/* /root/.npm +``` + +#### Images Alpine +```dockerfile +RUN apk update && apk upgrade && \ + apk add --no-cache curl git wget jq busybox-extras npm coreutils && \ + npm install -g wscat && \ + rm -rf /var/cache/apk/* /root/.npm +``` + +### 3. Gestion des permissions +```yaml +# docker-compose.yml +services: + service_name: + user: root # Pour l'installation des outils + entrypoint: | + sh -c " + apt-get update && apt-get install -y curl git wget jq telnet npm coreutils && \ + npm install -g wscat && \ + exec su bitcoin -c '/usr/local/bin/service_binary' + " +``` + +## Erreurs rencontrées et solutions + +### 1. "apt-get: not found" dans Alpine +```bash +# ❌ Erreur +apt-get install curl + +# ✅ Solution +apk add --no-cache curl +``` + +### 2. "telnet: no such package" dans Alpine +```bash +# ❌ Erreur +apk add telnet + +# ✅ Solution +apk add busybox-extras # Contient telnet +``` + +### 3. Permissions insuffisantes +```bash +# ❌ Erreur +E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied) + +# ✅ Solution +user: root # Dans docker-compose.yml +``` + +### 4. Binaires Node.js incorrects +```bash +# ❌ Erreur +exec /usr/local/bin/sdk_signer + +# ✅ Solution +exec node /app/dist/index.js +``` + +## Scripts d'installation automatisés + +### Script pour Debian/Ubuntu +```bash +#!/bin/bash +# install_tools_debian.sh +apt-get update && apt-get upgrade -y && \ +apt-get install -y curl git wget jq telnet npm coreutils && \ +npm install -g wscat && \ +rm -rf /var/lib/apt/lists/* /root/.npm +``` + +### Script pour Alpine +```bash +#!/bin/bash +# install_tools_alpine.sh +apk update && apk upgrade && \ +apk add --no-cache curl git wget jq busybox-extras npm coreutils && \ +npm install -g wscat && \ +rm -rf /var/cache/apk/* /root/.npm +``` + +## Configuration docker-compose.yml optimisée + +### Service avec installation d'outils +```yaml +services: + sdk_relay: + image: git.4nkweb.com/4nk/sdk_relay:ext + user: root + entrypoint: | + sh -c " + apt-get update && apt-get install -y curl git wget jq telnet npm coreutils && \ + npm install -g wscat && \ + exec su bitcoin -c '/usr/local/bin/sdk_relay --config /home/bitcoin/.conf' + " + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8091/"] + interval: 15s + timeout: 10s + retries: 5 + start_period: 60s +``` + +## Règles Cursor ajoutées + +### Règle globale +```markdown +# RÈGLE CRITIQUE : Images Docker +- TOUJOURS ajouter systématiquement aux images Docker : apt update && apt upgrade +- TOUJOURS installer en arrière-plan : curl, git, sed, awk, nc wget, jq, telnet, tee, wscat, ping, npm (dernière version) +- Cette règle s'applique à tous les Dockerfiles des projets 4NK +``` + +## Bonnes pratiques + +### 1. Intégration dans les Dockerfiles +- **Préférer** l'intégration dans le Dockerfile plutôt que l'entrypoint +- **Nettoyer** les caches après installation +- **Utiliser** des versions spécifiques des outils + +### 2. Gestion des utilisateurs +- **Installer** en tant que root +- **Exécuter** le service principal avec l'utilisateur approprié +- **Utiliser** `su` pour changer d'utilisateur + +### 3. Healthchecks +- **Utiliser** les outils installés dans les healthchecks +- **Vérifier** que les outils sont disponibles avant les tests +- **Configurer** des timeouts appropriés + +## Outils installés par défaut + +### Outils système +- `curl` : Tests HTTP/HTTPS +- `git` : Clonage de dépôts +- `wget` : Téléchargements +- `jq` : Parsing JSON +- `telnet` : Tests de connectivité +- `tee` : Redirection avec affichage +- `ping` : Tests réseau +- `nc` : Tests de ports + +### Outils Node.js +- `npm` : Gestionnaire de packages Node.js +- `wscat` : Client WebSocket en ligne de commande + +## Date +- **Créé** : 2025-09-20 +- **Problème résolu** : Installation d'outils dans tous les conteneurs +- **Impact** : Amélioration du debugging et des tests de connectivité diff --git a/docs/retours_experience/REX_STARTUP_SEQUENCE_IMPROVEMENTS.md b/docs/retours_experience/REX_STARTUP_SEQUENCE_IMPROVEMENTS.md new file mode 100644 index 0000000..00ef03d --- /dev/null +++ b/docs/retours_experience/REX_STARTUP_SEQUENCE_IMPROVEMENTS.md @@ -0,0 +1,231 @@ +# Retour d'Expérience : Améliorations de la séquence de démarrage + +## Problème initial +- **Erreur** : `dependency failed to start: container sdk_relay is unhealthy` +- **Cause** : Le service `sdk_relay` bloquait sur le scan de blocs pendant le démarrage +- **Impact** : Les services dépendants ne pouvaient pas démarrer + +## Diagnostic effectué + +### 1. Analyse du code sdk_relay +```rust +// Problème identifié dans main.rs +let current_tip = get_blockchain_tip().await?; +let last_scan = get_last_scan().await?; + +// ❌ Cette ligne bloquait le démarrage +scan_blocks(current_tip - last_scan, &config.blindbit_url).await?; + +// Les serveurs WebSocket et HTTP étaient lancés APRÈS +let listener = TcpListener::bind(config.ws_url).await; +tokio::spawn(start_health_server(8091)); +``` + +### 2. Impact sur les services dépendants +- `ihm_client` : Dépend de `sdk_relay` healthy +- `lecoffre-back` : Dépend de `sdk_relay` healthy +- `lecoffre-front` : Dépend de `lecoffre-back` healthy + +## Solutions implémentées + +### 1. Amélioration des healthchecks +```yaml +# docker-compose.yml +services: + sdk_relay: + healthcheck: + test: ["CMD", "sh", "-c", "curl -f http://localhost:8091/ | grep -q '\"status\":\"ok\"'"] + interval: 15s + timeout: 10s + retries: 5 + start_period: 60s # ⭐ Temps d'attente avant les tests +``` + +### 2. Variables d'environnement pour le démarrage +```yaml +environment: + - SDK_RELAY_SCAN_TIMEOUT=300 + - SDK_RELAY_STARTUP_MODE=async +``` + +### 3. Dépendances conditionnelles +```yaml +services: + ihm_client: + depends_on: + sdk_relay: + condition: service_healthy # ⭐ Attendre que sdk_relay soit healthy + + lecoffre-back: + depends_on: + sdk_relay: + condition: service_healthy +``` + +### 4. Script de démarrage intelligent +```bash +#!/bin/bash +# startup-sequence.sh + +# Validation des dépendances externes +validate_external_dependencies() { + echo "Vérification des dépendances externes..." + + # Test dev3.4nkweb.com:9090 + timeout 5 bash -c "/dev/null || { + echo "❌ https://dev4.4nkweb.com/lecoffre inaccessible" + return 1 + } + + echo "✅ Toutes les dépendances externes sont accessibles" + return 0 +} + +# Démarrage des services +start_services() { + validate_external_dependencies || exit 1 + docker compose up -d + wait_for_services_healthy +} +``` + +## Améliorations apportées + +### 1. Healthchecks robustes +- **Tests réels** : Vérification du endpoint `/health` au lieu de simples tests de port +- **Timeouts appropriés** : `start_period` pour laisser le temps au service de démarrer +- **Retry logic** : Plusieurs tentatives avant de marquer comme unhealthy + +### 2. Gestion des dépendances +- **Dépendances conditionnelles** : `condition: service_healthy` +- **Ordre de démarrage** : Services critiques en premier +- **Validation externe** : Vérification des services distants + +### 3. Monitoring et debugging +- **Logs colorés** : Fonctions de logging avec couleurs +- **Validation préalable** : Tests de connectivité avant démarrage +- **Restart intelligent** : Arrêt des services dépendants avant redémarrage + +## Scripts créés + +### startup-sequence.sh +```bash +#!/bin/bash +# Script de démarrage intelligent avec validation + +# Fonctions de logging +log() { echo -e "\033[1;34m[INFO]\033[0m $1"; } +log_success() { echo -e "\033[1;32m[SUCCESS]\033[0m $1"; } +log_warning() { echo -e "\033[1;33m[WARNING]\033[0m $1"; } +log_error() { echo -e "\033[1;31m[ERROR]\033[0m $1"; } + +# Validation des dépendances externes +validate_external_dependencies() { + log "Vérification des dépendances externes..." + + # Test signer distant + timeout 5 bash -c "/dev/null || { + log_error "https://dev4.4nkweb.com/lecoffre inaccessible" + return 1 + } + + log_success "Toutes les dépendances externes sont accessibles" + return 0 +} + +# Démarrage des services +start_services() { + validate_external_dependencies || exit 1 + docker compose up -d + wait_for_services_healthy +} + +# Redémarrage intelligent +restart_services() { + log "Arrêt des services dépendants..." + docker compose stop lecoffre-back lecoffre-front ihm_client + + log "Attente des dépendances externes..." + validate_external_dependencies || exit 1 + + log "Redémarrage des services..." + docker compose up -d + wait_for_services_healthy +} +``` + +## Configuration finale + +### docker-compose.yml optimisé +```yaml +services: + sdk_relay: + image: git.4nkweb.com/4nk/sdk_relay:ext + healthcheck: + test: ["CMD", "sh", "-c", "curl -f http://localhost:8091/ | grep -q '\"status\":\"ok\"'"] + interval: 15s + timeout: 10s + retries: 5 + start_period: 60s + environment: + - SDK_RELAY_SCAN_TIMEOUT=300 + - SDK_RELAY_STARTUP_MODE=async + + ihm_client: + depends_on: + sdk_relay: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:3003/"] + start_period: 30s + + lecoffre-back: + depends_on: + sdk_relay: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/api/v1/health"] + start_period: 30s +``` + +## Leçons apprises + +### 1. Healthchecks critiques +- **Toujours implémenter** des healthchecks robustes +- **Tester les endpoints réels** plutôt que les ports +- **Configurer des timeouts** appropriés + +### 2. Gestion des dépendances +- **Utiliser** `condition: service_healthy` pour les dépendances +- **Valider** les services externes avant démarrage +- **Implémenter** des scripts de redémarrage intelligent + +### 3. Monitoring et debugging +- **Logs colorés** pour faciliter le debugging +- **Validation préalable** des dépendances +- **Scripts automatisés** pour les opérations courantes + +## Actions préventives + +1. **Implémenter** des healthchecks robustes dès le début +2. **Configurer** des dépendances conditionnelles +3. **Valider** les services externes avant démarrage +4. **Créer** des scripts de démarrage intelligent +5. **Documenter** les séquences de démarrage + +## Date +- **Créé** : 2025-09-20 +- **Problème résolu** : Séquence de démarrage des services +- **Impact** : Amélioration de la fiabilité et du debugging diff --git a/scripts/rex/verify_bootstrap_connectivity.sh b/scripts/rex/verify_bootstrap_connectivity.sh new file mode 100755 index 0000000..d22bf96 --- /dev/null +++ b/scripts/rex/verify_bootstrap_connectivity.sh @@ -0,0 +1,187 @@ +#!/bin/bash +# verify_bootstrap_connectivity.sh +# Script de vérification de la connectivité bootstrap WebSocket +# Basé sur REX_BOOTSTRAP_WEBSOCKET.md + +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 + +# Fonctions de logging +log() { echo -e "${BLUE}[INFO]${NC} $1"; } +log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } +log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; } +log_error() { echo -e "${RED}[ERROR]${NC} $1"; } + +# Configuration +BOOTSTRAP_URL="wss://dev3.4nkweb.com/ws/" +TEST_ADDRESS="tsp1qqgmwp9n5p9ujhq2j6cfqe4jpkyu70jh9rgj0pwt3ndezk2mrlvw6jqew8fhsulewzglfr7g2aa48wyj4n0r7yasa3fm666vda8984ke8tuaf9m89" + +# Fonction de test de connectivité WebSocket +test_websocket_connectivity() { + local url="$1" + local timeout="${2:-10}" + + log "Test de connectivité WebSocket vers $url (timeout: ${timeout}s)..." + + if command -v wscat >/dev/null 2>&1; then + # Test avec wscat + local test_message='{"type":"faucet","address":"'$TEST_ADDRESS'"}' + + if timeout "$timeout" wscat -c "$url" -x "$test_message" >/dev/null 2>&1; then + log_success "Connexion WebSocket réussie vers $url" + return 0 + else + log_error "Échec de la connexion WebSocket vers $url" + return 1 + fi + else + log_warning "wscat non installé, test de connectivité basique..." + + # Test basique avec curl (pour les endpoints HTTP) + local http_url=$(echo "$url" | sed 's/wss:/https:/' | sed 's/ws:/http:/') + if curl -f -s --connect-timeout "$timeout" "$http_url" >/dev/null 2>&1; then + log_success "Endpoint HTTP accessible : $http_url" + return 0 + else + log_error "Endpoint HTTP inaccessible : $http_url" + return 1 + fi + fi +} + +# Fonction de test de connectivité réseau +test_network_connectivity() { + local host="$1" + local port="$2" + local timeout="${3:-5}" + + log "Test de connectivité réseau vers $host:$port (timeout: ${timeout}s)..." + + if timeout "$timeout" bash -c "/dev/null; then + log_success "Port $port accessible sur $host" + return 0 + else + log_error "Port $port inaccessible sur $host" + return 1 + fi +} + +# Fonction de vérification des fonds du relai +check_relay_funds() { + log "Vérification des fonds du relai local..." + + if docker ps | grep -q sdk_relay; then + local outputs_count=$(docker exec sdk_relay cat /home/bitcoin/.4nk/default 2>/dev/null | jq '.outputs | length' 2>/dev/null || echo "0") + + if [ "$outputs_count" -gt 0 ]; then + log_success "Relai local a $outputs_count sortie(s) (fonds disponibles)" + return 0 + else + log_warning "Relai local n'a pas de fonds (0 sorties)" + return 1 + fi + else + log_error "Conteneur sdk_relay non trouvé" + return 1 + fi +} + +# Fonction de vérification de l'adresse SP +check_sp_address() { + log "Vérification de l'adresse SP du relai..." + + if docker ps | grep -q sdk_relay; then + local sp_address=$(docker exec sdk_relay cat /home/bitcoin/.4nk/default 2>/dev/null | jq -r '.sp_address' 2>/dev/null || echo "null") + + if [ "$sp_address" != "null" ] && [ -n "$sp_address" ]; then + log_success "Adresse SP trouvée : $sp_address" + return 0 + else + log_warning "Aucune adresse SP trouvée" + return 1 + fi + else + log_error "Conteneur sdk_relay non trouvé" + return 1 + fi +} + +# Fonction de test du faucet +test_faucet() { + log "Test du faucet bootstrap..." + + if command -v wscat >/dev/null 2>&1; then + local faucet_message='{"type":"faucet","address":"'$TEST_ADDRESS'"}' + + log "Envoi de la requête faucet..." + local response=$(timeout 15 wscat -c "$BOOTSTRAP_URL" -x "$faucet_message" 2>/dev/null || echo "") + + if [ -n "$response" ]; then + log_success "Réponse reçue du faucet : $response" + + # Vérifier si la réponse contient des données de transaction + if echo "$response" | grep -q "NewTx\|tx_hex\|tweak_data"; then + log_success "Faucet fonctionnel - données de transaction reçues" + return 0 + else + log_warning "Faucet répond mais sans données de transaction" + return 1 + fi + else + log_error "Aucune réponse du faucet" + return 1 + fi + else + log_warning "wscat non installé, impossible de tester le faucet" + return 1 + fi +} + +# Fonction principale +main() { + log "=== Vérification de la connectivité bootstrap WebSocket ===" + + local errors=0 + + # 1. Test de connectivité réseau + log "1. Test de connectivité réseau..." + test_network_connectivity "dev3.4nkweb.com" "443" || ((errors++)) + test_network_connectivity "dev3.4nkweb.com" "9090" || ((errors++)) + + # 2. Test de connectivité WebSocket + log "2. Test de connectivité WebSocket..." + test_websocket_connectivity "$BOOTSTRAP_URL" || ((errors++)) + + # 3. Test du faucet + log "3. Test du faucet..." + test_faucet || ((errors++)) + + # 4. Vérification des fonds du relai + log "4. Vérification des fonds du relai..." + check_relay_funds || ((errors++)) + + # 5. Vérification de l'adresse SP + log "5. Vérification de l'adresse SP..." + check_sp_address || ((errors++)) + + # Résumé + echo "" + if [ $errors -eq 0 ]; then + log_success "=== Tous les tests de connectivité bootstrap ont réussi ===" + log_success "Le bootstrap WebSocket est fonctionnel et le relai peut recevoir des fonds" + exit 0 + else + log_error "=== $errors test(s) ont échoué ===" + log_error "Le bootstrap WebSocket nécessite une attention" + exit 1 + fi +} + +# Exécution du script +main "$@" diff --git a/scripts/rex/verify_config_writing.sh b/scripts/rex/verify_config_writing.sh new file mode 100755 index 0000000..e9e5395 --- /dev/null +++ b/scripts/rex/verify_config_writing.sh @@ -0,0 +1,159 @@ +#!/bin/bash +# verify_config_writing.sh +# Script de vérification de l'écriture effective des fichiers de configuration +# Basé sur REX_CONFIGURATION_MANAGEMENT.md + +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 + +# Fonctions de logging +log() { echo -e "${BLUE}[INFO]${NC} $1"; } +log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } +log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; } +log_error() { echo -e "${RED}[ERROR]${NC} $1"; } + +# Fonction de vérification d'un fichier de configuration +verify_config_file() { + local file="$1" + local expected_content="$2" + local description="$3" + + log "Vérification de $file ($description)..." + + if [ -f "$file" ]; then + if grep -q "$expected_content" "$file"; then + log_success "$file contient '$expected_content'" + return 0 + else + log_error "$file ne contient pas '$expected_content'" + return 1 + fi + else + log_error "$file n'existe pas" + return 1 + fi +} + +# Fonction de vérification de la syntaxe +verify_syntax() { + local file="$1" + + case "$file" in + *.yml|*.yaml) + log "Vérification de la syntaxe YAML pour $file..." + if command -v yq >/dev/null 2>&1; then + if yq eval '.' "$file" >/dev/null 2>&1; then + log_success "Syntaxe YAML valide pour $file" + return 0 + else + log_error "Syntaxe YAML invalide pour $file" + return 1 + fi + else + log_warning "yq non installé, impossible de vérifier la syntaxe YAML" + return 0 + fi + ;; + *.json) + log "Vérification de la syntaxe JSON pour $file..." + if command -v jq >/dev/null 2>&1; then + if jq '.' "$file" >/dev/null 2>&1; then + log_success "Syntaxe JSON valide pour $file" + return 0 + else + log_error "Syntaxe JSON invalide pour $file" + return 1 + fi + else + log_warning "jq non installé, impossible de vérifier la syntaxe JSON" + return 0 + fi + ;; + *.conf) + log "Vérification de la syntaxe pour $file..." + # Vérification basique : fichier non vide et lisible + if [ -s "$file" ] && [ -r "$file" ]; then + log_success "Fichier $file est lisible et non vide" + return 0 + else + log_error "Fichier $file est vide ou non lisible" + return 1 + fi + ;; + *) + log "Vérification basique pour $file..." + if [ -s "$file" ] && [ -r "$file" ]; then + log_success "Fichier $file est lisible et non vide" + return 0 + else + log_error "Fichier $file est vide ou non lisible" + return 1 + fi + ;; + esac +} + +# Fonction principale +main() { + log "=== Vérification de l'écriture effective des configurations ===" + + local errors=0 + + # Vérification des fichiers de configuration critiques + log "Vérification des fichiers de configuration critiques..." + + # 1. Configuration du relai + verify_config_file "relay/sdk_relay.conf" "bootstrap_url=" "Configuration bootstrap" || ((errors++)) + verify_config_file "relay/sdk_relay.conf" "sp_address=" "Adresse SP" || ((errors++)) + + # 2. Variables d'environnement + verify_config_file ".env" "RELAY_URLS=" "URLs des relais" || ((errors++)) + verify_config_file ".env" "SIGNER_WS_URL=" "URL WebSocket du signer" || ((errors++)) + + # 3. Configuration Docker Compose + verify_config_file "docker-compose.yml" "services:" "Services Docker" || ((errors++)) + verify_config_file "docker-compose.yml" "healthcheck:" "Healthchecks" || ((errors++)) + + # 4. Configuration du miner + verify_config_file "miner/.env" "RPC_HOST=" "Configuration RPC" || ((errors++)) + + # Vérification de la syntaxe + log "Vérification de la syntaxe des fichiers..." + + verify_syntax "docker-compose.yml" || ((errors++)) + verify_syntax "miner/.env" || ((errors++)) + + # Vérification des permissions + log "Vérification des permissions..." + + local config_files=("relay/sdk_relay.conf" ".env" "docker-compose.yml" "miner/.env") + for file in "${config_files[@]}"; do + if [ -f "$file" ]; then + if [ -r "$file" ]; then + log_success "Permissions de lecture OK pour $file" + else + log_error "Permissions de lecture insuffisantes pour $file" + ((errors++)) + fi + fi + done + + # Résumé + echo "" + if [ $errors -eq 0 ]; then + log_success "=== Toutes les vérifications ont réussi ===" + exit 0 + else + log_error "=== $errors erreur(s) détectée(s) ===" + exit 1 + fi +} + +# Exécution du script +main "$@"