feat: add /health endpoint on port 8091
All checks were successful
build-and-push-ext / build_push (push) Successful in 1m28s
All checks were successful
build-and-push-ext / build_push (push) Successful in 1m28s
- Add HTTP health server on port 8091 - Add CI workflow for dev4 branch with ext tag - Health endpoint returns {"status":"ok"} for monitoring ci: docker_tag=ext
This commit is contained in:
parent
a056d44cbf
commit
72bbffb31c
73
.gitea/workflows/build-ext.yml
Normal file
73
.gitea/workflows/build-ext.yml
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
name: build-and-push-ext
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- dev4
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build_push:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Prepare SSH agent (optional)
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
eval "$(ssh-agent -s)"
|
||||||
|
if [ -n "${{ secrets.SSH_PRIVATE_KEY || '' }}" ]; then
|
||||||
|
echo "${{ secrets.SSH_PRIVATE_KEY }}" | tr -d '\r' | ssh-add - >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
ssh-keyscan git.4nkweb.com >> ~/.ssh/known_hosts 2>/dev/null || true
|
||||||
|
echo "SSH agent ready: $SSH_AUTH_SOCK"
|
||||||
|
# Rendre l'agent dispo aux steps suivants
|
||||||
|
echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" >> "$GITHUB_ENV"
|
||||||
|
echo "SSH_AGENT_PID=$SSH_AGENT_PID" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
|
- name: Compute Docker tag from commit message or fallback
|
||||||
|
id: tag
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
msg=$(git log -1 --pretty=%B)
|
||||||
|
if [[ "$msg" =~ ci:\ docker_tag=([a-zA-Z0-9._:-]+) ]]; then
|
||||||
|
tag="${BASH_REMATCH[1]}"
|
||||||
|
else
|
||||||
|
tag="dev-test"
|
||||||
|
fi
|
||||||
|
echo "TAG=$tag" | tee -a $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Docker login (git.4nkweb.com)
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
REG_USER: ${{ secrets.USER }}
|
||||||
|
REG_TOKEN: ${{ secrets.TOKEN }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
echo "$REG_TOKEN" | docker login git.4nkweb.com -u "$REG_USER" --password-stdin
|
||||||
|
|
||||||
|
- name: Build image (target ext)
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
DOCKER_BUILDKIT: "1"
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
if [ -n "${SSH_AUTH_SOCK:-}" ]; then
|
||||||
|
docker build --ssh default \
|
||||||
|
-t git.4nkweb.com/4nk/sdk_relay:${{ steps.tag.outputs.TAG }} \
|
||||||
|
-f Dockerfile .
|
||||||
|
else
|
||||||
|
echo "SSH_AUTH_SOCK non défini: l'agent SSH n'est pas disponible. Assurez-vous de définir secrets.SSH_PRIVATE_KEY."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Push image
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
docker push git.4nkweb.com/4nk/sdk_relay:${{ steps.tag.outputs.TAG }}
|
37
docs/ANALYSE.md
Normal file
37
docs/ANALYSE.md
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
## Analyse détaillée
|
||||||
|
|
||||||
|
### Périmètre
|
||||||
|
|
||||||
|
Service Rust `sdk_relay` interfaçant Bitcoin (RPC), Blindbit et WebSocket, avec configuration injectée.
|
||||||
|
|
||||||
|
### Stack
|
||||||
|
|
||||||
|
- **Langage**: Rust 2021
|
||||||
|
- **Dépendances**: `tokio`, `tokio-tungstenite`, `zeromq`, `bitcoincore-rpc`, `serde[_json]`, `env_logger`, `futures-util`, `sdk_common` (git, branche `dev`, features `parallel`, `blindbit-backend`).
|
||||||
|
|
||||||
|
### Build et image
|
||||||
|
|
||||||
|
- Docker multi‑étapes: build dans `rust:latest` avec SSH pour deps privées, exécution `debian:bookworm-slim`.
|
||||||
|
- Binaire: `/usr/local/bin/sdk_relay`.
|
||||||
|
- Conf: build‑arg `CONF` écrit dans `/home/bitcoin/.conf`.
|
||||||
|
- Volumes: `/home/bitcoin/.4nk`, `/home/bitcoin/.bitcoin`.
|
||||||
|
|
||||||
|
### Réseau et healthcheck
|
||||||
|
|
||||||
|
- Ports: 8090, 8091 (exposés). Health: `GET /health` (via compose parent).
|
||||||
|
|
||||||
|
### Logs
|
||||||
|
|
||||||
|
- `RUST_LOG` géré par env; dans `lecoffre_node`, sortie tee vers `/home/bitcoin/.4nk/logs/sdk_relay.log`.
|
||||||
|
|
||||||
|
### Risques et points d’attention
|
||||||
|
|
||||||
|
- Dépendance `sdk_common` via git/branche `dev`: geler par tag/commit pour reproductibilité.
|
||||||
|
- Image d’exécution embarque `strace`; vérifier nécessité en prod.
|
||||||
|
- Permissions volume Windows: note de chown partiel dans compose parent.
|
||||||
|
|
||||||
|
### Actions proposées
|
||||||
|
|
||||||
|
- 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.
|
26
src/main.rs
26
src/main.rs
@ -49,6 +49,7 @@ use tokio::net::{TcpListener, TcpStream};
|
|||||||
use tokio::sync::mpsc::{unbounded_channel, UnboundedSender};
|
use tokio::sync::mpsc::{unbounded_channel, UnboundedSender};
|
||||||
use tokio_stream::wrappers::UnboundedReceiverStream;
|
use tokio_stream::wrappers::UnboundedReceiverStream;
|
||||||
use tokio_tungstenite::tungstenite::Message;
|
use tokio_tungstenite::tungstenite::Message;
|
||||||
|
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||||
|
|
||||||
use anyhow::{Error, Result};
|
use anyhow::{Error, Result};
|
||||||
use zeromq::{Socket, SocketRecv};
|
use zeromq::{Socket, SocketRecv};
|
||||||
@ -412,6 +413,28 @@ async fn handle_zmq(zmq_url: String, blindbit_url: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
let listener = match TcpListener::bind(format!("0.0.0.0:{}", port)).await {
|
||||||
|
Ok(listener) => listener,
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("Failed to bind health server on port {}: {}", port, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
log::info!("Health server listening on port {}", port);
|
||||||
|
|
||||||
|
while let Ok((stream, _)) = listener.accept().await {
|
||||||
|
tokio::spawn(handle_health_endpoint(stream));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main(flavor = "multi_thread")]
|
#[tokio::main(flavor = "multi_thread")]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
@ -590,6 +613,9 @@ async fn main() -> Result<()> {
|
|||||||
|
|
||||||
tokio::spawn(MessageCache::clean_up());
|
tokio::spawn(MessageCache::clean_up());
|
||||||
|
|
||||||
|
// Start health server on port 8091
|
||||||
|
tokio::spawn(start_health_server(8091));
|
||||||
|
|
||||||
// Let's spawn the handling of each connection in a separate task.
|
// Let's spawn the handling of each connection in a separate task.
|
||||||
while let Ok((stream, addr)) = listener.accept().await {
|
while let Ok((stream, addr)) = listener.accept().await {
|
||||||
tokio::spawn(handle_connection(stream, addr, our_sp_address));
|
tokio::spawn(handle_connection(stream, addr, our_sp_address));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user