ci: docker_tag=ext
All checks were successful
build-and-push-ext / build_push (push) Successful in 1m28s

- 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
This commit is contained in:
4NK Dev 2025-09-19 15:09:51 +00:00
parent 72bbffb31c
commit 25ac6eb808
9 changed files with 153 additions and 52 deletions

View File

@ -1,7 +1,9 @@
core_url="" core_url="http://bitcoin:38332"
ws_url="" ws_url="0.0.0.0:8090"
wallet_name="default" wallet_name="default"
network="signet" network="signet"
electrum_url="tcp://localhost:60601" blindbit_url="http://blindbit:8000"
blindbit_url="tcp://localhost:8000" zmq_url="tcp://bitcoin:29000"
zmq_url="" storage="https://demo.4nkweb.com/storage"
data_dir="/home/bitcoin/.4nk"
bitcoin_data_dir="/home/bitcoin/.bitcoin"

10
.dockerignore Normal file
View File

@ -0,0 +1,10 @@
.git
node_modules
.next
coverage
dist
.DS_Store
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.env*

View File

@ -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 }}

7
debian.code-workspace Normal file
View File

@ -0,0 +1,7 @@
{
"folders": [
{
"path": ".."
}
]
}

View File

@ -18,7 +18,36 @@ Service Rust `sdk_relay` interfaçant Bitcoin (RPC), Blindbit et WebSocket, avec
### Réseau et healthcheck ### 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 ### 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. - Pinner `sdk_common` sur un commit ou tag; documenter politique de mise à jour.
- Séparer images `-dev` et `-prod` si `strace` non requis. - Séparer images `-dev` et `-prod` si `strace` non requis.
- Documenter format du fichier de conf (`sdk_relay.conf`) et valeurs par défaut. - Documenter format du fichier de conf (`sdk_relay.conf`) et valeurs par défaut.
### CI / Image
- Pipeline `build-and-push-ext` construit et pousse limage avec un tag calculé depuis le message de commit (préfixe `ci: docker_tag=` sinon `dev-test`).
- Limage 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
```

40
docs/VALIDATION.md Normal file
View File

@ -0,0 +1,40 @@
## Validation opérationnelle
### Prérequis
- Image `git.4nkweb.com/4nk/sdk_relay:<tag>` 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 linstance 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 quil 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 dajout et confirmer la mise à jour de létat et la diffusion côté WS.
### Attendus CI/CD
- La CI construit automatiquement limage incluant lendpoint `/health` et pousse avec le tag calculé (préfixe commit `ci: docker_tag=...`, sinon `dev-test`).
- Une fois limage disponible (tag `ext` si prévu), redémarrer le service pour résoudre les problèmes de connexion.
### Dépannage
- Port occupé: vérifier quaucun 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 lutilisateur `bitcoin`.

View File

@ -427,9 +427,9 @@ async fn start_health_server(port: u16) {
return; return;
} }
}; };
log::info!("Health server listening on port {}", port); log::info!("Health server listening on port {}", port);
while let Ok((stream, _)) = listener.accept().await { while let Ok((stream, _)) = listener.accept().await {
tokio::spawn(handle_health_endpoint(stream)); tokio::spawn(handle_health_endpoint(stream));
} }

23
tests/health_check.sh Normal file
View File

@ -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"

18
tests/ws_connect.rs Normal file
View File

@ -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"),
}
}