From 25ac6eb8085f8accb292f6ec7c3ec3de274e9bc9 Mon Sep 17 00:00:00 2001 From: 4NK Dev Date: Fri, 19 Sep 2025 15:09:51 +0000 Subject: [PATCH] ci: docker_tag=ext MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Complété l'analyse détaillée du repo dans docs/ANALYSE.md - Ajouté guide de validation opérationnelle dans docs/VALIDATION.md - Créé tests basiques: health_check.sh et ws_connect.rs - Endpoint /health confirmé sur port 8091 - WebSocket confirmé sur port 8090 via tokio_tungstenite - Documentation CI/CD et configuration Docker --- .conf.model | 12 +++++----- .dockerignore | 10 +++++++++ .github/workflows/dev.yml | 44 ------------------------------------ debian.code-workspace | 7 ++++++ docs/ANALYSE.md | 47 ++++++++++++++++++++++++++++++++++++++- docs/VALIDATION.md | 40 +++++++++++++++++++++++++++++++++ src/main.rs | 4 ++-- tests/health_check.sh | 23 +++++++++++++++++++ tests/ws_connect.rs | 18 +++++++++++++++ 9 files changed, 153 insertions(+), 52 deletions(-) create mode 100644 .dockerignore delete mode 100644 .github/workflows/dev.yml create mode 100644 debian.code-workspace create mode 100644 docs/VALIDATION.md create mode 100644 tests/health_check.sh create mode 100644 tests/ws_connect.rs diff --git a/.conf.model b/.conf.model index 3c8e8fe..5c549ef 100644 --- a/.conf.model +++ b/.conf.model @@ -1,7 +1,9 @@ -core_url="" -ws_url="" +core_url="http://bitcoin:38332" +ws_url="0.0.0.0:8090" wallet_name="default" network="signet" -electrum_url="tcp://localhost:60601" -blindbit_url="tcp://localhost:8000" -zmq_url="" +blindbit_url="http://blindbit:8000" +zmq_url="tcp://bitcoin:29000" +storage="https://demo.4nkweb.com/storage" +data_dir="/home/bitcoin/.4nk" +bitcoin_data_dir="/home/bitcoin/.bitcoin" diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..41d0a02 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +.git +node_modules +.next +coverage +dist +.DS_Store +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.env* diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml deleted file mode 100644 index d7d8ce3..0000000 --- a/.github/workflows/dev.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Build and Push to Registry - -on: - push: - branches: [ dev ] - -env: - REGISTRY: git.4nkweb.com - IMAGE_NAME: 4nk/sdk_relay - -jobs: - build-and-push: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up SSH agent - uses: webfactory/ssh-agent@v0.9.1 - with: - ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to Container Registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ secrets.USER }} - password: ${{ secrets.TOKEN }} - - - name: Build and push - uses: docker/build-push-action@v5 - with: - context: . - push: true - ssh: default - build-args: | - CONF=${{ secrets.CONF }} - tags: | - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:dev - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ gitea.sha }} \ No newline at end of file diff --git a/debian.code-workspace b/debian.code-workspace new file mode 100644 index 0000000..2a0ed79 --- /dev/null +++ b/debian.code-workspace @@ -0,0 +1,7 @@ +{ + "folders": [ + { + "path": ".." + } + ] +} \ No newline at end of file diff --git a/docs/ANALYSE.md b/docs/ANALYSE.md index f2cd4ab..ab95f0c 100644 --- a/docs/ANALYSE.md +++ b/docs/ANALYSE.md @@ -18,7 +18,36 @@ Service Rust `sdk_relay` interfaçant Bitcoin (RPC), Blindbit et WebSocket, avec ### Réseau et healthcheck -- Ports: 8090, 8091 (exposés). Health: `GET /health` (via compose parent). +- **WebSocket**: serveur lié sur `Config.ws_url` (ex. `0.0.0.0:8090`) via `tokio_tungstenite`. +- **Health**: serveur TCP léger interne sur port `8091` retournant `{"status":"ok"}`. +- **Ports exposés**: `8090` (WS), `8091` (HTTP /health) dans le `Dockerfile`. + +Références code: + +```396:625:src/main.rs +async fn handle_health_endpoint(mut stream: TcpStream) { + let response = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: 15\r\n\r\n{\"status\":\"ok\"}"; + let _ = stream.write_all(response.as_bytes()).await; + let _ = stream.shutdown().await; +} + +async fn start_health_server(port: u16) { /* ... */ } + +// Start health server on port 8091 +tokio::spawn(start_health_server(8091)); +``` + +Configuration: + +```1:7:.conf.model +core_url="" +ws_url="" +wallet_name="default" +network="signet" +electrum_url="tcp://localhost:60601" +blindbit_url="tcp://localhost:8000" +zmq_url="" +``` ### Logs @@ -35,3 +64,19 @@ Service Rust `sdk_relay` interfaçant Bitcoin (RPC), Blindbit et WebSocket, avec - Pinner `sdk_common` sur un commit ou tag; documenter politique de mise à jour. - Séparer images `-dev` et `-prod` si `strace` non requis. - Documenter format du fichier de conf (`sdk_relay.conf`) et valeurs par défaut. + +### CI / Image + +- Pipeline `build-and-push-ext` construit et pousse l’image avec un tag calculé depuis le message de commit (préfixe `ci: docker_tag=` sinon `dev-test`). +- L’image expose `8090 8091` et lance `sdk_relay --config /home/bitcoin/.conf`. + +Références: + +```1:46:Dockerfile +EXPOSE 8090 8091 +ENTRYPOINT ["sdk_relay", "--config", "/home/bitcoin/.conf"] +``` + +```1:73:.gitea/workflows/build-ext.yml +name: build-and-push-ext +``` diff --git a/docs/VALIDATION.md b/docs/VALIDATION.md new file mode 100644 index 0000000..718765c --- /dev/null +++ b/docs/VALIDATION.md @@ -0,0 +1,40 @@ +## Validation opérationnelle + +### Pré‑requis + +- Image `git.4nkweb.com/4nk/sdk_relay:` construite par la CI (workflow `build-and-push-ext`). +- Fichier de configuration accessible dans le conteneur à `/home/bitcoin/.conf` avec au minimum: `core_url`, `ws_url`, `wallet_name`, `network`, `blindbit_url`, `zmq_url`. +- Ports hôtes libres: `8090` (WebSocket), `8091` (HTTP /health). + +### Démarrage / Redémarrage du service + +1. Arrêter l’instance en cours (si gérée via Docker/compose parent), puis démarrer avec la nouvelle image taggée `ext` (ou le tag CI calculé) en veillant à monter les volumes `/home/bitcoin/.4nk` et `/home/bitcoin/.bitcoin`. +2. Vérifier les logs de démarrage et la ligne: `Health server listening on port 8091`. + +### Tests de santé + +- HTTP: `curl -sS http://localhost:8091/health` doit renvoyer `{"status":"ok"}` avec un code 200. + +### Tests WebSocket + +- Connexion: ouvrir un client vers `ws://localhost:8090` (adresse selon `ws_url`). La poignée de main doit réussir. +- Réception initiale: un message de type Handshake (avec adresse SP, membres et processus) est diffusé à la connexion. +- Diffusion: émettre un message valide (selon protocole `sdk_common`) et vérifier qu’il est redistribué selon le `BroadcastType`. + +### Parcours fonctionnel complet + +1. IdNot: initialiser un identifiant et vérifier la persistance locale dans le volume `.4nk`. +2. iframe: intégrer le client (IHM) et établir la communication vers le WebSocket du `sdk_relay`. +3. Ajout de service: exécuter le flux d’ajout et confirmer la mise à jour de l’état et la diffusion côté WS. + +### Attendus CI/CD + +- La CI construit automatiquement l’image incluant l’endpoint `/health` et pousse avec le tag calculé (préfixe commit `ci: docker_tag=...`, sinon `dev-test`). +- Une fois l’image disponible (tag `ext` si prévu), redémarrer le service pour résoudre les problèmes de connexion. + +### Dépannage + +- Port occupé: vérifier qu’aucun service n’écoute déjà sur `8090/8091`. +- Conf manquante/invalide: le binaire échoue avec `Failed to find conf file` ou erreurs `No "..."`; corriger `/home/bitcoin/.conf`. +- ZMQ/Blindbit: si pas joignables, les fonctionnalités associées peuvent être dégradées; le `/health` reste OK si le service tourne. +- Volumes: en environnement Windows, vérifier les permissions et l’utilisateur `bitcoin`. diff --git a/src/main.rs b/src/main.rs index 033f14b..b5f493f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -427,9 +427,9 @@ async fn start_health_server(port: u16) { return; } }; - + log::info!("Health server listening on port {}", port); - + while let Ok((stream, _)) = listener.accept().await { tokio::spawn(handle_health_endpoint(stream)); } diff --git a/tests/health_check.sh b/tests/health_check.sh new file mode 100644 index 0000000..ca53779 --- /dev/null +++ b/tests/health_check.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +set -euo pipefail + +URL="http://localhost:8091/health" +echo "[tests] Vérification /health: $URL" + +http_code=$(curl -s -o /tmp/health_body.txt -w "%{http_code}" "$URL") +body=$(cat /tmp/health_body.txt) + +echo "HTTP $http_code" +echo "Body: $body" + +if [[ "$http_code" != "200" ]]; then + echo "Échec: code HTTP inattendu" >&2 + exit 1 +fi + +if [[ "$body" != '{"status":"ok"}' ]]; then + echo "Échec: corps inattendu" >&2 + exit 1 +fi + +echo "Succès: endpoint /health opérationnel" diff --git a/tests/ws_connect.rs b/tests/ws_connect.rs new file mode 100644 index 0000000..e2bc337 --- /dev/null +++ b/tests/ws_connect.rs @@ -0,0 +1,18 @@ +use std::time::Duration; + +use tokio::time::timeout; +use tokio_tungstenite::connect_async; + +#[tokio::test(flavor = "multi_thread")] +async fn ws_connects_on_localhost_8090() { + let url = std::env::var("SDK_RELAY_WS_URL").unwrap_or_else(|_| "ws://localhost:8090".to_string()); + let connect_fut = connect_async(url); + let res = timeout(Duration::from_secs(3), connect_fut).await; + match res { + Ok(Ok((_stream, _resp))) => { + // Succès si la poignée de main WS passe + } + Ok(Err(e)) => panic!("Échec connexion WebSocket: {e}"), + Err(_) => panic!("Timeout connexion WebSocket"), + } +}