**Motivations:** - Export Signet and mining wallet backups to git with only 2 versions kept - Document and add backup/restore scripts for signet and mining wallet **Correctifs:** - Backup-to-git uses SSH URL for passwordless cron; copy timestamped files only; prune to 2 versions; remove *-latest from backup repo **Evolutions:** - data/backup-to-git-cron.sh: daily export to git.4nkweb.com/4nk/backup - save-signet-datadir-backup.sh, restore-signet-from-backup.sh, export-mining-wallet.sh, import-mining-wallet.sh - features/backup-to-git-daily-cron.md, docs/MAINTENANCE.md backup section - .gitignore: data/backup-to-git.log **Pages affectées:** - .gitignore, data/backup-to-git-cron.sh, docs/MAINTENANCE.md, features/backup-to-git-daily-cron.md - save-signet-datadir-backup.sh, restore-signet-from-backup.sh, export-mining-wallet.sh, import-mining-wallet.sh - Plus autres fichiers modifiés ou non suivis déjà présents dans le working tree
295 lines
9.0 KiB
Bash
Executable File
295 lines
9.0 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# Script de mise à jour du Bitcoin Signet Custom
|
|
# Auteur: Équipe 4NK
|
|
# Date: 2026-01-09
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
cd "$SCRIPT_DIR"
|
|
|
|
# Couleurs pour les messages
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Fonction d'affichage
|
|
info() {
|
|
echo -e "${BLUE}[INFO]${NC} $1"
|
|
}
|
|
|
|
success() {
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
}
|
|
|
|
warning() {
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
}
|
|
|
|
error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
# Vérification des prérequis
|
|
check_prerequisites() {
|
|
info "Vérification des prérequis..."
|
|
|
|
if ! command -v docker &> /dev/null; then
|
|
error "Docker n'est pas installé"
|
|
exit 1
|
|
fi
|
|
|
|
if ! sudo docker ps &> /dev/null; then
|
|
error "Impossible d'accéder à Docker. Vérifiez les permissions."
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f ".env" ]; then
|
|
error "Le fichier .env n'existe pas"
|
|
exit 1
|
|
fi
|
|
|
|
success "Prérequis vérifiés"
|
|
}
|
|
|
|
# Récupération de la version actuelle
|
|
get_current_version() {
|
|
if [ -f ".bitcoin-version" ]; then
|
|
cat .bitcoin-version
|
|
else
|
|
grep -oP 'BITCOIN_VERSION=\$\{BITCOIN_VERSION:-?\K[0-9]+\.[0-9]+' Dockerfile | head -1 || echo "unknown"
|
|
fi
|
|
}
|
|
|
|
# Récupération de la dernière version disponible
|
|
get_latest_version() {
|
|
local version
|
|
|
|
# Essayer plusieurs méthodes pour récupérer la version
|
|
version=$(curl -s https://api.github.com/repos/bitcoin/bitcoin/releases/latest 2>/dev/null | \
|
|
grep -oP '"tag_name": "\Kv?[0-9]+\.[0-9]+\.[0-9]+' | head -1 | sed 's/^v//')
|
|
|
|
if [ -z "$version" ]; then
|
|
version=$(curl -s https://bitcoincore.org/bin/ 2>/dev/null | \
|
|
grep -oP 'bitcoin-core-\K[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -1)
|
|
fi
|
|
|
|
if [ -z "$version" ]; then
|
|
# Version par défaut si aucune méthode ne fonctionne
|
|
version="30.2"
|
|
warning "Impossible de récupérer la version automatiquement, utilisation de la version par défaut: $version"
|
|
fi
|
|
|
|
echo "$version"
|
|
}
|
|
|
|
# Sauvegarde avant mise à jour
|
|
backup_data() {
|
|
info "Sauvegarde des données avant mise à jour..."
|
|
|
|
local backup_dir="backups"
|
|
local backup_file="${backup_dir}/signet-backup-$(date +%Y%m%d-%H%M%S).tar.gz"
|
|
|
|
mkdir -p "$backup_dir"
|
|
|
|
if sudo docker ps | grep -q bitcoin-signet-instance; then
|
|
info "Sauvegarde des données du conteneur..."
|
|
sudo docker exec bitcoin-signet-instance tar czf /tmp/bitcoin-backup.tar.gz /root/.bitcoin/ 2>/dev/null || true
|
|
sudo docker cp bitcoin-signet-instance:/tmp/bitcoin-backup.tar.gz "$backup_file" 2>/dev/null || true
|
|
fi
|
|
|
|
# Sauvegarder le .env
|
|
cp .env "${backup_dir}/.env.backup-$(date +%Y%m%d-%H%M%S)"
|
|
|
|
success "Sauvegarde effectuée: $backup_file"
|
|
}
|
|
|
|
# Mise à jour du Dockerfile
|
|
update_dockerfile() {
|
|
local new_version=$1
|
|
|
|
info "Mise à jour du Dockerfile avec Bitcoin Core $new_version..."
|
|
|
|
# Mettre à jour la version dans le Dockerfile
|
|
sed -i "s/ARG BITCOIN_VERSION=\${BITCOIN_VERSION:-[0-9]\+\.[0-9]\+}/ARG BITCOIN_VERSION=\${BITCOIN_VERSION:-${new_version}}/" Dockerfile
|
|
|
|
success "Dockerfile mis à jour"
|
|
}
|
|
|
|
# Reconstruction de l'image
|
|
rebuild_image() {
|
|
info "Reconstruction de l'image Docker..."
|
|
|
|
if sudo docker build -t bitcoin-signet .; then
|
|
success "Image reconstruite avec succès"
|
|
else
|
|
error "Échec de la reconstruction de l'image"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Volume persistant : même que restore-signet-from-backup.sh (une seule chaîne pour Mempool, dashboard, APIs)
|
|
VOLUME_NAME="signet-bitcoin-data"
|
|
|
|
# Volume contenant la chaîne Signet complète (~11530 blocs). Utilisé par défaut s'il existe pour éviter de repartir sur une chaîne vide.
|
|
# Voir docs/MAINTENANCE.md et fixKnowledge/dashboard-anchor-wrong-chain-insufficient-balance.md
|
|
SIGNET_VOLUME_FULL_CHAIN="4b5dca4d940b9f6e5db67b460f40f230a5ef1195a3769e5f91fa02be6edde649"
|
|
|
|
# Redémarrage du conteneur
|
|
restart_container() {
|
|
info "Redémarrage du conteneur..."
|
|
|
|
# Arrêter le conteneur existant
|
|
if sudo docker ps | grep -q bitcoin-signet-instance; then
|
|
info "Arrêt du conteneur existant..."
|
|
sudo docker stop bitcoin-signet-instance
|
|
sudo docker rm bitcoin-signet-instance
|
|
fi
|
|
|
|
# Utiliser le volume "chaîne complète" s'il existe, sinon le volume nommé (créé si besoin)
|
|
local volume_to_use="$VOLUME_NAME"
|
|
if sudo docker volume inspect "$SIGNET_VOLUME_FULL_CHAIN" &>/dev/null; then
|
|
volume_to_use="$SIGNET_VOLUME_FULL_CHAIN"
|
|
info "Utilisation du volume chaîne complète (signet ~11530 blocs)"
|
|
else
|
|
sudo docker volume create "$VOLUME_NAME" 2>/dev/null || true
|
|
fi
|
|
|
|
# Démarrer le nouveau conteneur avec volume persistant (une seule chaîne pour tous les services)
|
|
info "Démarrage du nouveau conteneur (volume $volume_to_use)..."
|
|
sudo docker run --env-file .env -d \
|
|
--name bitcoin-signet-instance \
|
|
-v "$volume_to_use":/root/.bitcoin \
|
|
-p 38332:38332 \
|
|
-p 38333:38333 \
|
|
-p 28332:28332 \
|
|
-p 28333:28333 \
|
|
-p 28334:28334 \
|
|
bitcoin-signet
|
|
|
|
success "Conteneur redémarré"
|
|
}
|
|
|
|
# Vérification post-mise à jour
|
|
verify_update() {
|
|
info "Vérification de la mise à jour..."
|
|
|
|
sleep 10
|
|
|
|
# Vérifier que le conteneur est en cours d'exécution
|
|
if ! sudo docker ps | grep -q bitcoin-signet-instance; then
|
|
error "Le conteneur n'est pas en cours d'exécution"
|
|
return 1
|
|
fi
|
|
|
|
# Vérifier la version de Bitcoin (datadir = BITCOIN_DIR du conteneur)
|
|
local bitcoin_datadir
|
|
bitcoin_datadir=$(sudo docker exec bitcoin-signet-instance printenv BITCOIN_DIR 2>/dev/null || echo "/root/.bitcoin")
|
|
local version_info
|
|
version_info=$(sudo docker exec bitcoin-signet-instance bitcoin-cli -datadir="$bitcoin_datadir" -version 2>/dev/null || \
|
|
sudo docker exec bitcoin-signet-instance bitcoin-cli -datadir="$bitcoin_datadir" getnetworkinfo 2>/dev/null | grep -oP '"subversion": "\K[^"]+' || echo "unknown")
|
|
|
|
if [ "$version_info" != "unknown" ]; then
|
|
success "Version Bitcoin détectée: $version_info"
|
|
else
|
|
warning "Impossible de vérifier la version, mais le conteneur fonctionne"
|
|
fi
|
|
|
|
# Vérifier l'état de la blockchain
|
|
local blockchain_info
|
|
blockchain_info=$(sudo docker exec bitcoin-signet-instance bitcoin-cli -datadir="$bitcoin_datadir" getblockchaininfo 2>/dev/null | grep -oP '"chain": "\K[^"]+' || echo "unknown")
|
|
|
|
if [ "$blockchain_info" = "signet" ]; then
|
|
success "Blockchain signet opérationnelle"
|
|
else
|
|
warning "État de la blockchain: $blockchain_info"
|
|
fi
|
|
}
|
|
|
|
# Fonction principale
|
|
main() {
|
|
local target_version="${1:-}"
|
|
local current_version
|
|
local latest_version
|
|
|
|
echo "=========================================="
|
|
echo " Mise à jour du Bitcoin Signet Custom"
|
|
echo "=========================================="
|
|
echo ""
|
|
|
|
check_prerequisites
|
|
|
|
current_version=$(get_current_version)
|
|
info "Version actuelle: $current_version"
|
|
|
|
if [ -n "$target_version" ]; then
|
|
latest_version="$target_version"
|
|
info "Version cible spécifiée: $latest_version"
|
|
else
|
|
info "Récupération de la dernière version disponible..."
|
|
latest_version=$(get_latest_version)
|
|
info "Dernière version disponible: $latest_version"
|
|
fi
|
|
|
|
if [ "$current_version" = "$latest_version" ]; then
|
|
success "Déjà à jour (version $current_version)"
|
|
exit 0
|
|
fi
|
|
|
|
echo ""
|
|
warning "ATTENTION: Cette mise à jour va:"
|
|
warning " 1. Arrêter le conteneur actuel"
|
|
warning " 2. Reconstruire l'image Docker"
|
|
warning " 3. Redémarrer le conteneur"
|
|
echo ""
|
|
read -p "Continuer? (o/N): " -n 1 -r
|
|
echo ""
|
|
|
|
if [[ ! $REPLY =~ ^[OoYy]$ ]]; then
|
|
info "Mise à jour annulée"
|
|
exit 0
|
|
fi
|
|
|
|
echo ""
|
|
backup_data
|
|
echo ""
|
|
update_dockerfile "$latest_version"
|
|
echo ""
|
|
rebuild_image
|
|
echo ""
|
|
restart_container
|
|
echo ""
|
|
verify_update
|
|
echo ""
|
|
|
|
# Enregistrer la nouvelle version
|
|
echo "$latest_version" > .bitcoin-version
|
|
success "Version enregistrée: $latest_version"
|
|
|
|
echo ""
|
|
success "Mise à jour terminée avec succès!"
|
|
info "Pour voir les logs: sudo docker logs -f bitcoin-signet-instance"
|
|
info "Pour vérifier l'état: sudo docker exec bitcoin-signet-instance bitcoin-cli -datadir=\$(docker exec bitcoin-signet-instance printenv BITCOIN_DIR 2>/dev/null || echo /root/.bitcoin) getblockchaininfo"
|
|
}
|
|
|
|
# Gestion des arguments
|
|
if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then
|
|
echo "Usage: $0 [VERSION]"
|
|
echo ""
|
|
echo "Mise à jour du Bitcoin Signet Custom"
|
|
echo ""
|
|
echo "Arguments:"
|
|
echo " VERSION Version spécifique de Bitcoin Core (ex: 27.0)"
|
|
echo " Si non spécifié, utilise la dernière version disponible"
|
|
echo ""
|
|
echo "Options:"
|
|
echo " -h, --help Affiche cette aide"
|
|
echo ""
|
|
exit 0
|
|
fi
|
|
|
|
# Exécution du script principal
|
|
main "$@"
|