Compare commits
No commits in common. "main" and "v0.12.5-beta" have entirely different histories.
main
...
v0.12.5-be
66
README.md
66
README.md
@ -2,68 +2,6 @@
|
|||||||
|
|
||||||
A distributed peer-to-peer network built with Go and LibP2P, providing decentralized database capabilities with RQLite consensus and replication.
|
A distributed peer-to-peer network built with Go and LibP2P, providing decentralized database capabilities with RQLite consensus and replication.
|
||||||
|
|
||||||
## Table of Contents
|
|
||||||
|
|
||||||
- [Features](#features)
|
|
||||||
- [System Requirements](#system-requirements)
|
|
||||||
- [Software Dependencies](#software-dependencies)
|
|
||||||
- [Installation](#installation)
|
|
||||||
- [macOS](#macos)
|
|
||||||
- [Ubuntu/Debian](#ubuntudebian)
|
|
||||||
- [Windows](#windows)
|
|
||||||
- [Hardware Requirements](#hardware-requirements)
|
|
||||||
- [Network Ports](#network-ports)
|
|
||||||
- [Quick Start](#quick-start)
|
|
||||||
- [1. Clone and Setup Environment](#1-clone-and-setup-environment)
|
|
||||||
- [2. Generate Bootstrap Identity (Development Only)](#2-generate-bootstrap-identity-development-only)
|
|
||||||
- [3. Build the Project](#3-build-the-project)
|
|
||||||
- [4. Start the Network](#4-start-the-network)
|
|
||||||
- [5. Test with CLI](#5-test-with-cli)
|
|
||||||
- [6. Test Anchat Messaging](#6-test-anchat-messaging)
|
|
||||||
- [Deployment](#deployment)
|
|
||||||
- [Production Installation Script](#production-installation-script)
|
|
||||||
- [One-Command Installation](#one-command-installation)
|
|
||||||
- [What the Script Does](#what-the-script-does)
|
|
||||||
- [Directory Structure](#directory-structure)
|
|
||||||
- [Node Types](#node-types)
|
|
||||||
- [Service Management](#service-management)
|
|
||||||
- [Configuration Files](#configuration-files)
|
|
||||||
- [Security Features](#security-features)
|
|
||||||
- [Network Discovery](#network-discovery)
|
|
||||||
- [Updates and Maintenance](#updates-and-maintenance)
|
|
||||||
- [Monitoring and Troubleshooting](#monitoring-and-troubleshooting)
|
|
||||||
- [Environment Configuration](#environment-configuration)
|
|
||||||
- [Bootstrap Peers Configuration](#bootstrap-peers-configuration)
|
|
||||||
- [Setup for Development](#setup-for-development)
|
|
||||||
- [Configuration Files](#configuration-files-1)
|
|
||||||
- [Multiple Bootstrap Peers](#multiple-bootstrap-peers)
|
|
||||||
- [Checking Configuration](#checking-configuration)
|
|
||||||
- [CLI Commands](#cli-commands)
|
|
||||||
- [Network Operations](#network-operations)
|
|
||||||
- [Storage Operations](#storage-operations)
|
|
||||||
- [Database Operations](#database-operations)
|
|
||||||
- [Pub/Sub Messaging](#pubsub-messaging)
|
|
||||||
- [CLI Options](#cli-options)
|
|
||||||
- [Development](#development)
|
|
||||||
- [Project Structure](#project-structure)
|
|
||||||
- [Building and Testing](#building-and-testing)
|
|
||||||
- [Development Workflow](#development-workflow)
|
|
||||||
- [Environment Setup](#environment-setup)
|
|
||||||
- [Configuration System](#configuration-system)
|
|
||||||
- [Client Library Usage](#client-library-usage)
|
|
||||||
- [Anchat - Decentralized Messaging Application](#anchat---decentralized-messaging-application)
|
|
||||||
- [Features](#features-1)
|
|
||||||
- [Quick Start with Anchat](#quick-start-with-anchat)
|
|
||||||
- [Anchat Commands](#anchat-commands)
|
|
||||||
- [Anchat Configuration](#anchat-configuration)
|
|
||||||
- [Troubleshooting](#troubleshooting)
|
|
||||||
- [Common Issues](#common-issues)
|
|
||||||
- [Debug Commands](#debug-commands)
|
|
||||||
- [Environment-specific Issues](#environment-specific-issues)
|
|
||||||
- [Configuration Validation](#configuration-validation)
|
|
||||||
- [Logs and Data](#logs-and-data)
|
|
||||||
- [License](#license)
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- **Peer-to-Peer Networking**: Built on LibP2P for robust P2P communication
|
- **Peer-to-Peer Networking**: Built on LibP2P for robust P2P communication
|
||||||
@ -274,7 +212,7 @@ For production deployments on Linux servers, we provide an automated installatio
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Download and run the installation script
|
# Download and run the installation script
|
||||||
curl -sSL https://git.debros.io/DeBros/network/raw/branch/main/scripts/install-debros-network.sh | bash
|
curl -sSL https://raw.githubusercontent.com/DeBrosOfficial/debros-network/main/scripts/install-debros-network.sh | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
#### What the Script Does
|
#### What the Script Does
|
||||||
@ -441,7 +379,7 @@ The installation script implements production security best practices:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Update to latest version (re-run the installation script)
|
# Update to latest version (re-run the installation script)
|
||||||
curl -sSL https://git.debros.io/DeBros/network/raw/branch/main/scripts/install-debros-network.sh | bash
|
curl -sSL https://raw.githubusercontent.com/DeBrosOfficial/debros-network/main/scripts/install-debros-network.sh | bash
|
||||||
|
|
||||||
# Manual source update
|
# Manual source update
|
||||||
cd /opt/debros/src
|
cd /opt/debros/src
|
||||||
|
554
install-debros-network.sh
Executable file
554
install-debros-network.sh
Executable file
@ -0,0 +1,554 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e # Exit on any error
|
||||||
|
trap 'echo -e "${RED}An error occurred. Installation aborted.${NOCOLOR}"; exit 1' ERR
|
||||||
|
|
||||||
|
# Color codes
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
CYAN='\033[0;36m'
|
||||||
|
BLUE='\033[38;2;2;128;175m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NOCOLOR='\033[0m'
|
||||||
|
|
||||||
|
# Default values
|
||||||
|
INSTALL_DIR="/opt/debros"
|
||||||
|
REPO_URL="https://github.com/DeBrosOfficial/debros-network.git"
|
||||||
|
MIN_GO_VERSION="1.19"
|
||||||
|
BOOTSTRAP_PORT="4001"
|
||||||
|
NODE_PORT="4002"
|
||||||
|
RQLITE_BOOTSTRAP_PORT="5001"
|
||||||
|
RQLITE_NODE_PORT="5002"
|
||||||
|
RAFT_BOOTSTRAP_PORT="7001"
|
||||||
|
RAFT_NODE_PORT="7002"
|
||||||
|
|
||||||
|
log() {
|
||||||
|
echo -e "${CYAN}[$(date '+%Y-%m-%d %H:%M:%S')]${NOCOLOR} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
echo -e "${RED}[ERROR]${NOCOLOR} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
success() {
|
||||||
|
echo -e "${GREEN}[SUCCESS]${NOCOLOR} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
warning() {
|
||||||
|
echo -e "${YELLOW}[WARNING]${NOCOLOR} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if running as root
|
||||||
|
if [[ $EUID -eq 0 ]]; then
|
||||||
|
error "This script should not be run as root. Please run as a regular user with sudo privileges."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if sudo is available
|
||||||
|
if ! command -v sudo &>/dev/null; then
|
||||||
|
error "sudo command not found. Please ensure you have sudo privileges."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Detect OS
|
||||||
|
detect_os() {
|
||||||
|
if [ -f /etc/os-release ]; then
|
||||||
|
. /etc/os-release
|
||||||
|
OS=$ID
|
||||||
|
VERSION=$VERSION_ID
|
||||||
|
else
|
||||||
|
error "Cannot detect operating system"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $OS in
|
||||||
|
ubuntu|debian)
|
||||||
|
PACKAGE_MANAGER="apt"
|
||||||
|
;;
|
||||||
|
centos|rhel|fedora)
|
||||||
|
PACKAGE_MANAGER="yum"
|
||||||
|
if command -v dnf &> /dev/null; then
|
||||||
|
PACKAGE_MANAGER="dnf"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
error "Unsupported operating system: $OS"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
log "Detected OS: $OS $VERSION"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check Go installation and version
|
||||||
|
check_go_installation() {
|
||||||
|
if command -v go &> /dev/null; then
|
||||||
|
GO_VERSION=$(go version | awk '{print $3}' | sed 's/go//')
|
||||||
|
log "Found Go version: $GO_VERSION"
|
||||||
|
|
||||||
|
# Compare versions (simplified)
|
||||||
|
if [ "$(printf '%s\n' "$MIN_GO_VERSION" "$GO_VERSION" | sort -V | head -n1)" = "$MIN_GO_VERSION" ]; then
|
||||||
|
success "Go version is sufficient"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
warning "Go version $GO_VERSION is too old. Minimum required: $MIN_GO_VERSION"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log "Go not found on system"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install Go
|
||||||
|
install_go() {
|
||||||
|
log "Installing Go..."
|
||||||
|
|
||||||
|
case $PACKAGE_MANAGER in
|
||||||
|
apt)
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install -y wget
|
||||||
|
;;
|
||||||
|
yum|dnf)
|
||||||
|
sudo $PACKAGE_MANAGER install -y wget
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Download and install Go
|
||||||
|
GO_TARBALL="go1.21.0.linux-amd64.tar.gz"
|
||||||
|
ARCH=$(uname -m)
|
||||||
|
|
||||||
|
if [ "$ARCH" = "aarch64" ]; then
|
||||||
|
GO_TARBALL="go1.21.0.linux-arm64.tar.gz"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd /tmp
|
||||||
|
wget -q "https://golang.org/dl/$GO_TARBALL"
|
||||||
|
sudo rm -rf /usr/local/go
|
||||||
|
sudo tar -C /usr/local -xzf "$GO_TARBALL"
|
||||||
|
|
||||||
|
# Add Go to PATH
|
||||||
|
if ! grep -q "/usr/local/go/bin" ~/.bashrc; then
|
||||||
|
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
|
||||||
|
fi
|
||||||
|
|
||||||
|
export PATH=$PATH:/usr/local/go/bin
|
||||||
|
success "Go installed successfully"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install system dependencies
|
||||||
|
install_dependencies() {
|
||||||
|
log "Installing system dependencies..."
|
||||||
|
|
||||||
|
case $PACKAGE_MANAGER in
|
||||||
|
apt)
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install -y git make build-essential curl
|
||||||
|
;;
|
||||||
|
yum|dnf)
|
||||||
|
sudo $PACKAGE_MANAGER groupinstall -y "Development Tools"
|
||||||
|
sudo $PACKAGE_MANAGER install -y git make curl
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
success "System dependencies installed"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check port availability
|
||||||
|
check_ports() {
|
||||||
|
local ports=($BOOTSTRAP_PORT $NODE_PORT $RQLITE_BOOTSTRAP_PORT $RQLITE_NODE_PORT $RAFT_BOOTSTRAP_PORT $RAFT_NODE_PORT)
|
||||||
|
|
||||||
|
for port in "${ports[@]}"; do
|
||||||
|
if sudo netstat -tuln 2>/dev/null | grep -q ":$port " || ss -tuln 2>/dev/null | grep -q ":$port "; then
|
||||||
|
error "Port $port is already in use. Please free it up and try again."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
success "All required ports are available"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Configuration wizard
|
||||||
|
configuration_wizard() {
|
||||||
|
log "${BLUE}==================================================${NOCOLOR}"
|
||||||
|
log "${GREEN} DeBros Network Configuration Wizard ${NOCOLOR}"
|
||||||
|
log "${BLUE}==================================================${NOCOLOR}"
|
||||||
|
|
||||||
|
# Node type selection
|
||||||
|
while true; do
|
||||||
|
echo -e "${GREEN}Select node type:${NOCOLOR}"
|
||||||
|
echo -e "${CYAN}1) Bootstrap Node (Network entry point)${NOCOLOR}"
|
||||||
|
echo -e "${CYAN}2) Regular Node (Connects to existing network)${NOCOLOR}"
|
||||||
|
read -rp "Enter your choice (1 or 2): " NODE_TYPE_CHOICE
|
||||||
|
|
||||||
|
case $NODE_TYPE_CHOICE in
|
||||||
|
1)
|
||||||
|
NODE_TYPE="bootstrap"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
NODE_TYPE="regular"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
error "Invalid choice. Please enter 1 or 2."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Solana wallet address
|
||||||
|
log "${GREEN}Enter your Solana wallet address to be eligible for node operator rewards:${NOCOLOR}"
|
||||||
|
while true; do
|
||||||
|
read -rp "Solana Wallet Address: " SOLANA_WALLET
|
||||||
|
if [[ -n "$SOLANA_WALLET" && ${#SOLANA_WALLET} -ge 32 ]]; then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
error "Please enter a valid Solana wallet address"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Data directory
|
||||||
|
read -rp "Installation directory [default: $INSTALL_DIR]: " CUSTOM_INSTALL_DIR
|
||||||
|
if [[ -n "$CUSTOM_INSTALL_DIR" ]]; then
|
||||||
|
INSTALL_DIR="$CUSTOM_INSTALL_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Firewall configuration
|
||||||
|
read -rp "Configure firewall automatically? (yes/no) [default: yes]: " CONFIGURE_FIREWALL
|
||||||
|
CONFIGURE_FIREWALL="${CONFIGURE_FIREWALL:-yes}"
|
||||||
|
|
||||||
|
success "Configuration completed"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create user and directories
|
||||||
|
setup_directories() {
|
||||||
|
log "Setting up directories and permissions..."
|
||||||
|
|
||||||
|
# Create debros user if it doesn't exist
|
||||||
|
if ! id "debros" &>/dev/null; then
|
||||||
|
sudo useradd -r -s /bin/false -d "$INSTALL_DIR" debros
|
||||||
|
log "Created debros user"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create directory structure
|
||||||
|
sudo mkdir -p "$INSTALL_DIR"/{bin,configs,keys,data,logs}
|
||||||
|
sudo mkdir -p "$INSTALL_DIR/keys/$NODE_TYPE"
|
||||||
|
sudo mkdir -p "$INSTALL_DIR/data/$NODE_TYPE"/{rqlite,storage}
|
||||||
|
|
||||||
|
# Set ownership and permissions
|
||||||
|
sudo chown -R debros:debros "$INSTALL_DIR"
|
||||||
|
sudo chmod 755 "$INSTALL_DIR"
|
||||||
|
sudo chmod 700 "$INSTALL_DIR/keys"
|
||||||
|
sudo chmod 600 "$INSTALL_DIR/keys/$NODE_TYPE" 2>/dev/null || true
|
||||||
|
|
||||||
|
success "Directory structure created"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Clone or update repository
|
||||||
|
setup_source_code() {
|
||||||
|
log "Setting up source code..."
|
||||||
|
|
||||||
|
if [ -d "$INSTALL_DIR/src" ]; then
|
||||||
|
log "Updating existing repository..."
|
||||||
|
cd "$INSTALL_DIR/src"
|
||||||
|
sudo -u debros git pull
|
||||||
|
else
|
||||||
|
log "Cloning repository..."
|
||||||
|
sudo -u debros git clone "$REPO_URL" "$INSTALL_DIR/src"
|
||||||
|
cd "$INSTALL_DIR/src"
|
||||||
|
fi
|
||||||
|
|
||||||
|
success "Source code ready"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate identity key
|
||||||
|
generate_identity() {
|
||||||
|
log "Generating node identity..."
|
||||||
|
|
||||||
|
cd "$INSTALL_DIR/src"
|
||||||
|
|
||||||
|
# Create a temporary Go program for key generation
|
||||||
|
cat > /tmp/generate_identity.go << 'EOF'
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/libp2p/go-libp2p/core/crypto"
|
||||||
|
"github.com/libp2p/go-libp2p/core/peer"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) != 2 {
|
||||||
|
fmt.Println("Usage: go run generate_identity.go <key_file_path>")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
keyFile := os.Args[1]
|
||||||
|
|
||||||
|
// Generate identity
|
||||||
|
priv, pub, err := crypto.GenerateKeyPairWithReader(crypto.Ed25519, 2048, rand.Reader)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get peer ID
|
||||||
|
peerID, err := peer.IDFromPublicKey(pub)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marshal private key
|
||||||
|
data, err := crypto.MarshalPrivateKey(priv)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create directory
|
||||||
|
if err := os.MkdirAll(filepath.Dir(keyFile), 0700); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save identity
|
||||||
|
if err := os.WriteFile(keyFile, data, 0600); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Generated Peer ID: %s\n", peerID.String())
|
||||||
|
fmt.Printf("Identity saved to: %s\n", keyFile)
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Generate the identity key
|
||||||
|
sudo -u debros go run /tmp/generate_identity.go "$INSTALL_DIR/keys/$NODE_TYPE/identity.key"
|
||||||
|
rm /tmp/generate_identity.go
|
||||||
|
|
||||||
|
success "Node identity generated"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build binaries
|
||||||
|
build_binaries() {
|
||||||
|
log "Building DeBros Network binaries..."
|
||||||
|
|
||||||
|
cd "$INSTALL_DIR/src"
|
||||||
|
|
||||||
|
# Build all binaries
|
||||||
|
sudo -u debros make build
|
||||||
|
|
||||||
|
# Copy binaries to installation directory
|
||||||
|
sudo cp bin/* "$INSTALL_DIR/bin/"
|
||||||
|
sudo chown debros:debros "$INSTALL_DIR/bin/"*
|
||||||
|
|
||||||
|
success "Binaries built and installed"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate configuration files
|
||||||
|
generate_configs() {
|
||||||
|
log "Generating configuration files..."
|
||||||
|
|
||||||
|
if [ "$NODE_TYPE" = "bootstrap" ]; then
|
||||||
|
cat > /tmp/config.yaml << EOF
|
||||||
|
node:
|
||||||
|
data_dir: "$INSTALL_DIR/data/bootstrap"
|
||||||
|
key_file: "$INSTALL_DIR/keys/bootstrap/identity.key"
|
||||||
|
listen_addresses:
|
||||||
|
- "/ip4/0.0.0.0/tcp/$BOOTSTRAP_PORT"
|
||||||
|
solana_wallet: "$SOLANA_WALLET"
|
||||||
|
|
||||||
|
database:
|
||||||
|
rqlite_port: $RQLITE_BOOTSTRAP_PORT
|
||||||
|
rqlite_raft_port: $RAFT_BOOTSTRAP_PORT
|
||||||
|
|
||||||
|
logging:
|
||||||
|
level: "info"
|
||||||
|
file: "$INSTALL_DIR/logs/bootstrap.log"
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
cat > /tmp/config.yaml << EOF
|
||||||
|
node:
|
||||||
|
data_dir: "$INSTALL_DIR/data/node"
|
||||||
|
key_file: "$INSTALL_DIR/keys/node/identity.key"
|
||||||
|
listen_addresses:
|
||||||
|
- "/ip4/0.0.0.0/tcp/$NODE_PORT"
|
||||||
|
solana_wallet: "$SOLANA_WALLET"
|
||||||
|
|
||||||
|
database:
|
||||||
|
rqlite_port: $RQLITE_NODE_PORT
|
||||||
|
rqlite_raft_port: $RAFT_NODE_PORT
|
||||||
|
|
||||||
|
logging:
|
||||||
|
level: "info"
|
||||||
|
file: "$INSTALL_DIR/logs/node.log"
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
sudo mv /tmp/config.yaml "$INSTALL_DIR/configs/$NODE_TYPE.yaml"
|
||||||
|
sudo chown debros:debros "$INSTALL_DIR/configs/$NODE_TYPE.yaml"
|
||||||
|
|
||||||
|
success "Configuration files generated"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Configure firewall
|
||||||
|
configure_firewall() {
|
||||||
|
if [[ "$CONFIGURE_FIREWALL" == "yes" ]]; then
|
||||||
|
log "Configuring firewall..."
|
||||||
|
|
||||||
|
if command -v ufw &> /dev/null; then
|
||||||
|
if [ "$NODE_TYPE" = "bootstrap" ]; then
|
||||||
|
sudo ufw allow $BOOTSTRAP_PORT
|
||||||
|
sudo ufw allow $RQLITE_BOOTSTRAP_PORT
|
||||||
|
sudo ufw allow $RAFT_BOOTSTRAP_PORT
|
||||||
|
else
|
||||||
|
sudo ufw allow $NODE_PORT
|
||||||
|
sudo ufw allow $RQLITE_NODE_PORT
|
||||||
|
sudo ufw allow $RAFT_NODE_PORT
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Enable ufw if not already active
|
||||||
|
UFW_STATUS=$(sudo ufw status | grep -o "Status: [a-z]*" | awk '{print $2}' || echo "inactive")
|
||||||
|
if [[ "$UFW_STATUS" != "active" ]]; then
|
||||||
|
echo "y" | sudo ufw enable
|
||||||
|
fi
|
||||||
|
|
||||||
|
success "Firewall configured"
|
||||||
|
else
|
||||||
|
warning "UFW not found. Please configure firewall manually."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create systemd service
|
||||||
|
create_systemd_service() {
|
||||||
|
log "Creating systemd service..."
|
||||||
|
|
||||||
|
cat > /tmp/debros-$NODE_TYPE.service << EOF
|
||||||
|
[Unit]
|
||||||
|
Description=DeBros Network $NODE_TYPE Node
|
||||||
|
After=network.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=debros
|
||||||
|
Group=debros
|
||||||
|
WorkingDirectory=$INSTALL_DIR
|
||||||
|
ExecStart=$INSTALL_DIR/bin/$NODE_TYPE -config $INSTALL_DIR/configs/$NODE_TYPE.yaml
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
SyslogIdentifier=debros-$NODE_TYPE
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
NoNewPrivileges=yes
|
||||||
|
PrivateTmp=yes
|
||||||
|
ProtectSystem=strict
|
||||||
|
ProtectHome=yes
|
||||||
|
ReadWritePaths=$INSTALL_DIR
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo mv /tmp/debros-$NODE_TYPE.service /etc/systemd/system/
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable debros-$NODE_TYPE.service
|
||||||
|
|
||||||
|
success "Systemd service created and enabled"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start the service
|
||||||
|
start_service() {
|
||||||
|
log "Starting DeBros Network $NODE_TYPE node..."
|
||||||
|
|
||||||
|
sudo systemctl start debros-$NODE_TYPE.service
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
if systemctl is-active --quiet debros-$NODE_TYPE.service; then
|
||||||
|
success "DeBros Network $NODE_TYPE node started successfully"
|
||||||
|
else
|
||||||
|
error "Failed to start DeBros Network $NODE_TYPE node"
|
||||||
|
log "Check logs with: sudo journalctl -u debros-$NODE_TYPE.service"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Display banner
|
||||||
|
display_banner() {
|
||||||
|
echo -e "${BLUE}========================================================================${NOCOLOR}"
|
||||||
|
echo -e "${CYAN}
|
||||||
|
____ ____ _ _ _ _
|
||||||
|
| _ \ ___| __ ) _ __ ___ ___ | \ | | ___| |___ _____ _ __| | __
|
||||||
|
| | | |/ _ \ _ \| __/ _ \/ __| | \| |/ _ \ __\ \ /\ / / _ \| __| |/ /
|
||||||
|
| |_| | __/ |_) | | | (_) \__ \ | |\ | __/ |_ \ V V / (_) | | | <
|
||||||
|
|____/ \___|____/|_| \___/|___/ |_| \_|\___|\__| \_/\_/ \___/|_| |_|\_\\
|
||||||
|
${NOCOLOR}"
|
||||||
|
echo -e "${BLUE}========================================================================${NOCOLOR}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main installation function
|
||||||
|
main() {
|
||||||
|
display_banner
|
||||||
|
|
||||||
|
log "${BLUE}==================================================${NOCOLOR}"
|
||||||
|
log "${GREEN} Starting DeBros Network Installation ${NOCOLOR}"
|
||||||
|
log "${BLUE}==================================================${NOCOLOR}"
|
||||||
|
|
||||||
|
detect_os
|
||||||
|
check_ports
|
||||||
|
|
||||||
|
# Check and install Go if needed
|
||||||
|
if ! check_go_installation; then
|
||||||
|
install_go
|
||||||
|
fi
|
||||||
|
|
||||||
|
install_dependencies
|
||||||
|
configuration_wizard
|
||||||
|
setup_directories
|
||||||
|
setup_source_code
|
||||||
|
generate_identity
|
||||||
|
build_binaries
|
||||||
|
generate_configs
|
||||||
|
configure_firewall
|
||||||
|
create_systemd_service
|
||||||
|
start_service
|
||||||
|
|
||||||
|
# Display completion information
|
||||||
|
log "${BLUE}==================================================${NOCOLOR}"
|
||||||
|
log "${GREEN} Installation Complete! ${NOCOLOR}"
|
||||||
|
log "${BLUE}==================================================${NOCOLOR}"
|
||||||
|
|
||||||
|
log "${GREEN}Node Type:${NOCOLOR} ${CYAN}$NODE_TYPE${NOCOLOR}"
|
||||||
|
log "${GREEN}Installation Directory:${NOCOLOR} ${CYAN}$INSTALL_DIR${NOCOLOR}"
|
||||||
|
log "${GREEN}Configuration:${NOCOLOR} ${CYAN}$INSTALL_DIR/configs/$NODE_TYPE.yaml${NOCOLOR}"
|
||||||
|
log "${GREEN}Logs:${NOCOLOR} ${CYAN}$INSTALL_DIR/logs/$NODE_TYPE.log${NOCOLOR}"
|
||||||
|
|
||||||
|
if [ "$NODE_TYPE" = "bootstrap" ]; then
|
||||||
|
log "${GREEN}Bootstrap Port:${NOCOLOR} ${CYAN}$BOOTSTRAP_PORT${NOCOLOR}"
|
||||||
|
log "${GREEN}RQLite Port:${NOCOLOR} ${CYAN}$RQLITE_BOOTSTRAP_PORT${NOCOLOR}"
|
||||||
|
log "${GREEN}Raft Port:${NOCOLOR} ${CYAN}$RAFT_BOOTSTRAP_PORT${NOCOLOR}"
|
||||||
|
else
|
||||||
|
log "${GREEN}Node Port:${NOCOLOR} ${CYAN}$NODE_PORT${NOCOLOR}"
|
||||||
|
log "${GREEN}RQLite Port:${NOCOLOR} ${CYAN}$RQLITE_NODE_PORT${NOCOLOR}"
|
||||||
|
log "${GREEN}Raft Port:${NOCOLOR} ${CYAN}$RAFT_NODE_PORT${NOCOLOR}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "${BLUE}==================================================${NOCOLOR}"
|
||||||
|
log "${GREEN}Management Commands:${NOCOLOR}"
|
||||||
|
log "${CYAN} - sudo systemctl status debros-$NODE_TYPE${NOCOLOR} (Check status)"
|
||||||
|
log "${CYAN} - sudo systemctl restart debros-$NODE_TYPE${NOCOLOR} (Restart service)"
|
||||||
|
log "${CYAN} - sudo systemctl stop debros-$NODE_TYPE${NOCOLOR} (Stop service)"
|
||||||
|
log "${CYAN} - sudo systemctl start debros-$NODE_TYPE${NOCOLOR} (Start service)"
|
||||||
|
log "${CYAN} - sudo journalctl -u debros-$NODE_TYPE.service -f${NOCOLOR} (View logs)"
|
||||||
|
log "${CYAN} - $INSTALL_DIR/bin/cli${NOCOLOR} (Use CLI tools)"
|
||||||
|
log "${BLUE}==================================================${NOCOLOR}"
|
||||||
|
|
||||||
|
success "DeBros Network $NODE_TYPE node is now running!"
|
||||||
|
log "${CYAN}For documentation visit: https://docs.debros.io${NOCOLOR}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run main function
|
||||||
|
main "$@"
|
@ -13,7 +13,7 @@ NOCOLOR='\033[0m'
|
|||||||
|
|
||||||
# Default values
|
# Default values
|
||||||
INSTALL_DIR="/opt/debros"
|
INSTALL_DIR="/opt/debros"
|
||||||
REPO_URL="https://git.debros.io/DeBros/network.git"
|
REPO_URL="https://github.com/DeBrosOfficial/debros-network.git"
|
||||||
MIN_GO_VERSION="1.19"
|
MIN_GO_VERSION="1.19"
|
||||||
BOOTSTRAP_PORT="4001"
|
BOOTSTRAP_PORT="4001"
|
||||||
NODE_PORT="4002"
|
NODE_PORT="4002"
|
||||||
@ -21,19 +21,11 @@ RQLITE_BOOTSTRAP_PORT="5001"
|
|||||||
RQLITE_NODE_PORT="5002"
|
RQLITE_NODE_PORT="5002"
|
||||||
RAFT_BOOTSTRAP_PORT="7001"
|
RAFT_BOOTSTRAP_PORT="7001"
|
||||||
RAFT_NODE_PORT="7002"
|
RAFT_NODE_PORT="7002"
|
||||||
UPDATE_MODE=false
|
|
||||||
NON_INTERACTIVE=false
|
|
||||||
|
|
||||||
log() {
|
log() {
|
||||||
echo -e "${CYAN}[$(date '+%Y-%m-%d %H:%M:%S')]${NOCOLOR} $1"
|
echo -e "${CYAN}[$(date '+%Y-%m-%d %H:%M:%S')]${NOCOLOR} $1"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if running non-interactively (piped from curl)
|
|
||||||
if [ ! -t 0 ]; then
|
|
||||||
NON_INTERACTIVE=true
|
|
||||||
log "Running in non-interactive mode"
|
|
||||||
fi
|
|
||||||
|
|
||||||
error() {
|
error() {
|
||||||
echo -e "${RED}[ERROR]${NOCOLOR} $1"
|
echo -e "${RED}[ERROR]${NOCOLOR} $1"
|
||||||
}
|
}
|
||||||
@ -88,97 +80,6 @@ detect_os() {
|
|||||||
log "Detected OS: $OS $VERSION"
|
log "Detected OS: $OS $VERSION"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if DeBros Network is already installed
|
|
||||||
check_existing_installation() {
|
|
||||||
if [ -d "$INSTALL_DIR" ] && [ -f "$INSTALL_DIR/bin/bootstrap" ] && [ -f "$INSTALL_DIR/bin/node" ]; then
|
|
||||||
log "Found existing DeBros Network installation at $INSTALL_DIR"
|
|
||||||
|
|
||||||
# Check if services are running
|
|
||||||
BOOTSTRAP_RUNNING=false
|
|
||||||
NODE_RUNNING=false
|
|
||||||
|
|
||||||
if systemctl is-active --quiet debros-bootstrap.service 2>/dev/null; then
|
|
||||||
BOOTSTRAP_RUNNING=true
|
|
||||||
log "Bootstrap service is currently running"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if systemctl is-active --quiet debros-node.service 2>/dev/null; then
|
|
||||||
NODE_RUNNING=true
|
|
||||||
log "Node service is currently running"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$NON_INTERACTIVE" = true ]; then
|
|
||||||
log "Non-interactive mode: updating existing installation"
|
|
||||||
UPDATE_MODE=true
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "${YELLOW}Existing installation detected!${NOCOLOR}"
|
|
||||||
echo -e "${CYAN}Options:${NOCOLOR}"
|
|
||||||
echo -e "${CYAN}1) Update existing installation${NOCOLOR}"
|
|
||||||
echo -e "${CYAN}2) Remove and reinstall${NOCOLOR}"
|
|
||||||
echo -e "${CYAN}3) Exit installer${NOCOLOR}"
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
read -rp "Enter your choice (1, 2, or 3): " EXISTING_CHOICE
|
|
||||||
case $EXISTING_CHOICE in
|
|
||||||
1)
|
|
||||||
UPDATE_MODE=true
|
|
||||||
log "Will update existing installation"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
2)
|
|
||||||
log "Will remove and reinstall"
|
|
||||||
remove_existing_installation
|
|
||||||
UPDATE_MODE=false
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
3)
|
|
||||||
log "Installation cancelled by user"
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
error "Invalid choice. Please enter 1, 2, or 3."
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
else
|
|
||||||
UPDATE_MODE=false
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Remove existing installation
|
|
||||||
remove_existing_installation() {
|
|
||||||
log "Removing existing installation..."
|
|
||||||
|
|
||||||
# Stop services if they exist
|
|
||||||
for service in debros-bootstrap debros-node; do
|
|
||||||
if systemctl list-unit-files | grep -q "$service.service"; then
|
|
||||||
log "Stopping $service service..."
|
|
||||||
sudo systemctl stop $service.service 2>/dev/null || true
|
|
||||||
sudo systemctl disable $service.service 2>/dev/null || true
|
|
||||||
sudo rm -f /etc/systemd/system/$service.service
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
sudo systemctl daemon-reload
|
|
||||||
|
|
||||||
# Remove installation directory
|
|
||||||
if [ -d "$INSTALL_DIR" ]; then
|
|
||||||
sudo rm -rf "$INSTALL_DIR"
|
|
||||||
log "Removed installation directory"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Remove debros user
|
|
||||||
if id "debros" &>/dev/null; then
|
|
||||||
sudo userdel debros 2>/dev/null || true
|
|
||||||
log "Removed debros user"
|
|
||||||
fi
|
|
||||||
|
|
||||||
success "Existing installation removed"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check Go installation and version
|
# Check Go installation and version
|
||||||
check_go_installation() {
|
check_go_installation() {
|
||||||
if command -v go &> /dev/null; then
|
if command -v go &> /dev/null; then
|
||||||
@ -226,140 +127,31 @@ install_go() {
|
|||||||
sudo rm -rf /usr/local/go
|
sudo rm -rf /usr/local/go
|
||||||
sudo tar -C /usr/local -xzf "$GO_TARBALL"
|
sudo tar -C /usr/local -xzf "$GO_TARBALL"
|
||||||
|
|
||||||
# Add Go to system-wide PATH
|
# Add Go to PATH
|
||||||
if ! grep -q "/usr/local/go/bin" /etc/environment 2>/dev/null; then
|
|
||||||
echo 'PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/local/go/bin"' | sudo tee /etc/environment > /dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Also add to current user's bashrc for compatibility
|
|
||||||
if ! grep -q "/usr/local/go/bin" ~/.bashrc; then
|
if ! grep -q "/usr/local/go/bin" ~/.bashrc; then
|
||||||
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
|
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Update current session PATH
|
|
||||||
export PATH=$PATH:/usr/local/go/bin
|
export PATH=$PATH:/usr/local/go/bin
|
||||||
|
|
||||||
success "Go installed successfully"
|
success "Go installed successfully"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Install system dependencies
|
# Install system dependencies
|
||||||
install_dependencies() {
|
install_dependencies() {
|
||||||
log "Checking system dependencies..."
|
log "Installing system dependencies..."
|
||||||
|
|
||||||
# Check which dependencies are missing
|
|
||||||
MISSING_DEPS=()
|
|
||||||
|
|
||||||
case $PACKAGE_MANAGER in
|
case $PACKAGE_MANAGER in
|
||||||
apt)
|
apt)
|
||||||
# Check for required packages
|
sudo apt update
|
||||||
for pkg in git make build-essential curl; do
|
sudo apt install -y git make build-essential curl
|
||||||
if ! dpkg -l | grep -q "^ii $pkg "; then
|
|
||||||
MISSING_DEPS+=($pkg)
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ ${#MISSING_DEPS[@]} -gt 0 ]; then
|
|
||||||
log "Installing missing dependencies: ${MISSING_DEPS[*]}"
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y "${MISSING_DEPS[@]}"
|
|
||||||
else
|
|
||||||
success "All system dependencies already installed"
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
yum|dnf)
|
yum|dnf)
|
||||||
# Check for required packages
|
sudo $PACKAGE_MANAGER groupinstall -y "Development Tools"
|
||||||
for pkg in git make curl; do
|
sudo $PACKAGE_MANAGER install -y git make curl
|
||||||
if ! rpm -q $pkg &>/dev/null; then
|
|
||||||
MISSING_DEPS+=($pkg)
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Check for development tools
|
|
||||||
if ! rpm -q gcc &>/dev/null; then
|
|
||||||
MISSING_DEPS+=("Development Tools")
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ${#MISSING_DEPS[@]} -gt 0 ]; then
|
|
||||||
log "Installing missing dependencies: ${MISSING_DEPS[*]}"
|
|
||||||
if [[ " ${MISSING_DEPS[*]} " =~ " Development Tools " ]]; then
|
|
||||||
sudo $PACKAGE_MANAGER groupinstall -y "Development Tools"
|
|
||||||
fi
|
|
||||||
# Remove "Development Tools" from array for individual package installation
|
|
||||||
MISSING_DEPS=($(printf '%s\n' "${MISSING_DEPS[@]}" | grep -v "Development Tools"))
|
|
||||||
if [ ${#MISSING_DEPS[@]} -gt 0 ]; then
|
|
||||||
sudo $PACKAGE_MANAGER install -y "${MISSING_DEPS[@]}"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
success "All system dependencies already installed"
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
success "System dependencies ready"
|
success "System dependencies installed"
|
||||||
}
|
|
||||||
|
|
||||||
# Install RQLite
|
|
||||||
install_rqlite() {
|
|
||||||
# Check if RQLite is already installed
|
|
||||||
if command -v rqlited &> /dev/null; then
|
|
||||||
RQLITE_VERSION=$(rqlited -version | head -n1 | awk '{print $2}')
|
|
||||||
log "Found RQLite version: $RQLITE_VERSION"
|
|
||||||
success "RQLite already installed"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
log "Installing RQLite..."
|
|
||||||
|
|
||||||
# Determine architecture
|
|
||||||
ARCH=$(uname -m)
|
|
||||||
case $ARCH in
|
|
||||||
x86_64)
|
|
||||||
RQLITE_ARCH="amd64"
|
|
||||||
;;
|
|
||||||
aarch64|arm64)
|
|
||||||
RQLITE_ARCH="arm64"
|
|
||||||
;;
|
|
||||||
armv7l)
|
|
||||||
RQLITE_ARCH="arm"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
error "Unsupported architecture: $ARCH"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Download and install RQLite
|
|
||||||
RQLITE_VERSION="8.30.0"
|
|
||||||
RQLITE_TARBALL="rqlite-v${RQLITE_VERSION}-linux-${RQLITE_ARCH}.tar.gz"
|
|
||||||
RQLITE_URL="https://github.com/rqlite/rqlite/releases/download/v${RQLITE_VERSION}/${RQLITE_TARBALL}"
|
|
||||||
|
|
||||||
cd /tmp
|
|
||||||
if ! wget -q "$RQLITE_URL"; then
|
|
||||||
error "Failed to download RQLite from $RQLITE_URL"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Extract and install RQLite binaries
|
|
||||||
tar -xzf "$RQLITE_TARBALL"
|
|
||||||
RQLITE_DIR="rqlite-v${RQLITE_VERSION}-linux-${RQLITE_ARCH}"
|
|
||||||
|
|
||||||
# Install RQLite binaries to system PATH
|
|
||||||
sudo cp "$RQLITE_DIR/rqlited" /usr/local/bin/
|
|
||||||
sudo cp "$RQLITE_DIR/rqlite" /usr/local/bin/
|
|
||||||
sudo chmod +x /usr/local/bin/rqlited
|
|
||||||
sudo chmod +x /usr/local/bin/rqlite
|
|
||||||
|
|
||||||
# Cleanup
|
|
||||||
rm -rf "$RQLITE_TARBALL" "$RQLITE_DIR"
|
|
||||||
|
|
||||||
# Verify installation
|
|
||||||
if command -v rqlited &> /dev/null; then
|
|
||||||
INSTALLED_VERSION=$(rqlited -version | head -n1 | awk '{print $2}')
|
|
||||||
success "RQLite v$INSTALLED_VERSION installed successfully"
|
|
||||||
else
|
|
||||||
error "RQLite installation failed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check port availability
|
# Check port availability
|
||||||
@ -382,18 +174,6 @@ configuration_wizard() {
|
|||||||
log "${GREEN} DeBros Network Configuration Wizard ${NOCOLOR}"
|
log "${GREEN} DeBros Network Configuration Wizard ${NOCOLOR}"
|
||||||
log "${BLUE}==================================================${NOCOLOR}"
|
log "${BLUE}==================================================${NOCOLOR}"
|
||||||
|
|
||||||
if [ "$NON_INTERACTIVE" = true ]; then
|
|
||||||
log "Non-interactive mode: using default configuration"
|
|
||||||
NODE_TYPE="bootstrap"
|
|
||||||
SOLANA_WALLET="11111111111111111111111111111111" # Placeholder wallet
|
|
||||||
CONFIGURE_FIREWALL="yes"
|
|
||||||
log "Node Type: $NODE_TYPE"
|
|
||||||
log "Installation Directory: $INSTALL_DIR"
|
|
||||||
log "Firewall Configuration: $CONFIGURE_FIREWALL"
|
|
||||||
success "Configuration completed with defaults"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Node type selection
|
# Node type selection
|
||||||
while true; do
|
while true; do
|
||||||
echo -e "${GREEN}Select node type:${NOCOLOR}"
|
echo -e "${GREEN}Select node type:${NOCOLOR}"
|
||||||
@ -448,8 +228,6 @@ setup_directories() {
|
|||||||
if ! id "debros" &>/dev/null; then
|
if ! id "debros" &>/dev/null; then
|
||||||
sudo useradd -r -s /bin/false -d "$INSTALL_DIR" debros
|
sudo useradd -r -s /bin/false -d "$INSTALL_DIR" debros
|
||||||
log "Created debros user"
|
log "Created debros user"
|
||||||
else
|
|
||||||
log "User 'debros' already exists"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create directory structure
|
# Create directory structure
|
||||||
@ -457,19 +235,13 @@ setup_directories() {
|
|||||||
sudo mkdir -p "$INSTALL_DIR/keys/$NODE_TYPE"
|
sudo mkdir -p "$INSTALL_DIR/keys/$NODE_TYPE"
|
||||||
sudo mkdir -p "$INSTALL_DIR/data/$NODE_TYPE"/{rqlite,storage}
|
sudo mkdir -p "$INSTALL_DIR/data/$NODE_TYPE"/{rqlite,storage}
|
||||||
|
|
||||||
# Set ownership first, then permissions
|
# Set ownership and permissions
|
||||||
sudo chown -R debros:debros "$INSTALL_DIR"
|
sudo chown -R debros:debros "$INSTALL_DIR"
|
||||||
sudo chmod 755 "$INSTALL_DIR"
|
sudo chmod 755 "$INSTALL_DIR"
|
||||||
sudo chmod 700 "$INSTALL_DIR/keys"
|
sudo chmod 700 "$INSTALL_DIR/keys"
|
||||||
sudo chmod 700 "$INSTALL_DIR/keys/$NODE_TYPE"
|
sudo chmod 600 "$INSTALL_DIR/keys/$NODE_TYPE" 2>/dev/null || true
|
||||||
|
|
||||||
# Ensure the debros user can write to the keys directory
|
success "Directory structure created"
|
||||||
sudo chmod 755 "$INSTALL_DIR/data"
|
|
||||||
sudo chmod 755 "$INSTALL_DIR/logs"
|
|
||||||
sudo chmod 755 "$INSTALL_DIR/configs"
|
|
||||||
sudo chmod 755 "$INSTALL_DIR/bin"
|
|
||||||
|
|
||||||
success "Directory structure ready"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Clone or update repository
|
# Clone or update repository
|
||||||
@ -491,30 +263,16 @@ setup_source_code() {
|
|||||||
|
|
||||||
# Generate identity key
|
# Generate identity key
|
||||||
generate_identity() {
|
generate_identity() {
|
||||||
local identity_file="$INSTALL_DIR/keys/$NODE_TYPE/identity.key"
|
|
||||||
|
|
||||||
if [ -f "$identity_file" ]; then
|
|
||||||
if [ "$UPDATE_MODE" = true ]; then
|
|
||||||
log "Identity key already exists, keeping existing key"
|
|
||||||
success "Using existing node identity"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
log "Identity key already exists, regenerating..."
|
|
||||||
sudo rm -f "$identity_file"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
log "Generating node identity..."
|
log "Generating node identity..."
|
||||||
|
|
||||||
cd "$INSTALL_DIR/src"
|
cd "$INSTALL_DIR/src"
|
||||||
|
|
||||||
# Create a custom identity generation script with output path support
|
# Create a temporary Go program for key generation
|
||||||
cat > /tmp/generate_identity_custom.go << 'EOF'
|
cat > /tmp/generate_identity.go << 'EOF'
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"flag"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -524,15 +282,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var outputPath string
|
if len(os.Args) != 2 {
|
||||||
flag.StringVar(&outputPath, "output", "", "Output path for identity key")
|
fmt.Println("Usage: go run generate_identity.go <key_file_path>")
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
if outputPath == "" {
|
|
||||||
fmt.Println("Usage: go run generate_identity_custom.go -output <path>")
|
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
keyFile := os.Args[1]
|
||||||
|
|
||||||
// Generate identity
|
// Generate identity
|
||||||
priv, pub, err := crypto.GenerateKeyPairWithReader(crypto.Ed25519, 2048, rand.Reader)
|
priv, pub, err := crypto.GenerateKeyPairWithReader(crypto.Ed25519, 2048, rand.Reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -552,24 +308,23 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create directory
|
// Create directory
|
||||||
if err := os.MkdirAll(filepath.Dir(outputPath), 0700); err != nil {
|
if err := os.MkdirAll(filepath.Dir(keyFile), 0700); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save identity
|
// Save identity
|
||||||
if err := os.WriteFile(outputPath, data, 0600); err != nil {
|
if err := os.WriteFile(keyFile, data, 0600); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Generated Peer ID: %s\n", peerID.String())
|
fmt.Printf("Generated Peer ID: %s\n", peerID.String())
|
||||||
fmt.Printf("Identity saved to: %s\n", outputPath)
|
fmt.Printf("Identity saved to: %s\n", keyFile)
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Ensure Go is in PATH and generate the identity key
|
# Generate the identity key
|
||||||
export PATH=$PATH:/usr/local/go/bin
|
sudo -u debros go run /tmp/generate_identity.go "$INSTALL_DIR/keys/$NODE_TYPE/identity.key"
|
||||||
sudo -u debros env "PATH=$PATH:/usr/local/go/bin" "GOMOD=$(pwd)" go run /tmp/generate_identity_custom.go -output "$identity_file"
|
rm /tmp/generate_identity.go
|
||||||
rm /tmp/generate_identity_custom.go
|
|
||||||
|
|
||||||
success "Node identity generated"
|
success "Node identity generated"
|
||||||
}
|
}
|
||||||
@ -580,9 +335,8 @@ build_binaries() {
|
|||||||
|
|
||||||
cd "$INSTALL_DIR/src"
|
cd "$INSTALL_DIR/src"
|
||||||
|
|
||||||
# Ensure Go is in PATH and build all binaries
|
# Build all binaries
|
||||||
export PATH=$PATH:/usr/local/go/bin
|
sudo -u debros make build
|
||||||
sudo -u debros env "PATH=$PATH:/usr/local/go/bin" make build
|
|
||||||
|
|
||||||
# Copy binaries to installation directory
|
# Copy binaries to installation directory
|
||||||
sudo cp bin/* "$INSTALL_DIR/bin/"
|
sudo cp bin/* "$INSTALL_DIR/bin/"
|
||||||
@ -640,85 +394,35 @@ EOF
|
|||||||
# Configure firewall
|
# Configure firewall
|
||||||
configure_firewall() {
|
configure_firewall() {
|
||||||
if [[ "$CONFIGURE_FIREWALL" == "yes" ]]; then
|
if [[ "$CONFIGURE_FIREWALL" == "yes" ]]; then
|
||||||
log "Configuring firewall rules..."
|
log "Configuring firewall..."
|
||||||
|
|
||||||
if command -v ufw &> /dev/null; then
|
if command -v ufw &> /dev/null; then
|
||||||
# Add firewall rules regardless of UFW status
|
|
||||||
# This allows the rules to be ready when UFW is enabled
|
|
||||||
log "Adding UFW rules for DeBros Network ports..."
|
|
||||||
|
|
||||||
# Add ports based on node type with error handling
|
|
||||||
if [ "$NODE_TYPE" = "bootstrap" ]; then
|
if [ "$NODE_TYPE" = "bootstrap" ]; then
|
||||||
for port in $BOOTSTRAP_PORT $RQLITE_BOOTSTRAP_PORT $RAFT_BOOTSTRAP_PORT; do
|
sudo ufw allow $BOOTSTRAP_PORT
|
||||||
if ! sudo ufw allow $port; then
|
sudo ufw allow $RQLITE_BOOTSTRAP_PORT
|
||||||
error "Failed to allow port $port"
|
sudo ufw allow $RAFT_BOOTSTRAP_PORT
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
log "Added UFW rule: allow port $port"
|
|
||||||
done
|
|
||||||
else
|
else
|
||||||
for port in $NODE_PORT $RQLITE_NODE_PORT $RAFT_NODE_PORT; do
|
sudo ufw allow $NODE_PORT
|
||||||
if ! sudo ufw allow $port; then
|
sudo ufw allow $RQLITE_NODE_PORT
|
||||||
error "Failed to allow port $port"
|
sudo ufw allow $RAFT_NODE_PORT
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
log "Added UFW rule: allow port $port"
|
|
||||||
done
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check UFW status and inform user
|
# Enable ufw if not already active
|
||||||
UFW_STATUS=$(sudo ufw status | grep -o "Status: [a-z]\+" | awk '{print $2}' || echo "inactive")
|
UFW_STATUS=$(sudo ufw status | grep -o "Status: [a-z]*" | awk '{print $2}' || echo "inactive")
|
||||||
|
if [[ "$UFW_STATUS" != "active" ]]; then
|
||||||
if [[ "$UFW_STATUS" == "active" ]]; then
|
echo "y" | sudo ufw enable
|
||||||
success "Firewall rules added and active"
|
|
||||||
else
|
|
||||||
success "Firewall rules added (UFW is inactive - rules will take effect when UFW is enabled)"
|
|
||||||
log "To enable UFW with current rules: sudo ufw enable"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
success "Firewall configured"
|
||||||
else
|
else
|
||||||
warning "UFW not found. Please configure firewall manually."
|
warning "UFW not found. Please configure firewall manually."
|
||||||
log "Required ports to allow:"
|
|
||||||
if [ "$NODE_TYPE" = "bootstrap" ]; then
|
|
||||||
log " - Port $BOOTSTRAP_PORT (Bootstrap)"
|
|
||||||
log " - Port $RQLITE_BOOTSTRAP_PORT (RQLite)"
|
|
||||||
log " - Port $RAFT_BOOTSTRAP_PORT (Raft)"
|
|
||||||
else
|
|
||||||
log " - Port $NODE_PORT (Node)"
|
|
||||||
log " - Port $RQLITE_NODE_PORT (RQLite)"
|
|
||||||
log " - Port $RAFT_NODE_PORT (Raft)"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create systemd service
|
# Create systemd service
|
||||||
create_systemd_service() {
|
create_systemd_service() {
|
||||||
local service_file="/etc/systemd/system/debros-$NODE_TYPE.service"
|
log "Creating systemd service..."
|
||||||
|
|
||||||
# Always clean up any existing service files to ensure fresh start
|
|
||||||
for service in debros-bootstrap debros-node; do
|
|
||||||
if [ -f "/etc/systemd/system/$service.service" ]; then
|
|
||||||
log "Cleaning up existing $service service..."
|
|
||||||
sudo systemctl stop $service.service 2>/dev/null || true
|
|
||||||
sudo systemctl disable $service.service 2>/dev/null || true
|
|
||||||
sudo rm -f /etc/systemd/system/$service.service
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
sudo systemctl daemon-reload
|
|
||||||
log "Creating new systemd service..."
|
|
||||||
|
|
||||||
# Determine the correct ExecStart command based on node type
|
|
||||||
local exec_start=""
|
|
||||||
if [ "$NODE_TYPE" = "bootstrap" ]; then
|
|
||||||
exec_start="$INSTALL_DIR/bin/bootstrap -data $INSTALL_DIR/data/bootstrap -port $BOOTSTRAP_PORT"
|
|
||||||
else
|
|
||||||
# For regular nodes, we need to specify the bootstrap peer
|
|
||||||
# This should be configured based on the bootstrap node's address
|
|
||||||
exec_start="$INSTALL_DIR/bin/node -data $INSTALL_DIR/data/node -port $NODE_PORT"
|
|
||||||
# Note: Bootstrap peer address would need to be configured separately
|
|
||||||
# exec_start="$INSTALL_DIR/bin/node -data $INSTALL_DIR/data/node -port $NODE_PORT -bootstrap /ip4/BOOTSTRAP_IP/tcp/$BOOTSTRAP_PORT/p2p/BOOTSTRAP_PEER_ID"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cat > /tmp/debros-$NODE_TYPE.service << EOF
|
cat > /tmp/debros-$NODE_TYPE.service << EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
@ -731,7 +435,7 @@ Type=simple
|
|||||||
User=debros
|
User=debros
|
||||||
Group=debros
|
Group=debros
|
||||||
WorkingDirectory=$INSTALL_DIR
|
WorkingDirectory=$INSTALL_DIR
|
||||||
ExecStart=$exec_start
|
ExecStart=$INSTALL_DIR/bin/$NODE_TYPE -config $INSTALL_DIR/configs/$NODE_TYPE.yaml
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=10
|
RestartSec=10
|
||||||
StandardOutput=journal
|
StandardOutput=journal
|
||||||
@ -749,11 +453,11 @@ ReadWritePaths=$INSTALL_DIR
|
|||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
sudo mv /tmp/debros-$NODE_TYPE.service "$service_file"
|
sudo mv /tmp/debros-$NODE_TYPE.service /etc/systemd/system/
|
||||||
sudo systemctl daemon-reload
|
sudo systemctl daemon-reload
|
||||||
sudo systemctl enable debros-$NODE_TYPE.service
|
sudo systemctl enable debros-$NODE_TYPE.service
|
||||||
|
|
||||||
success "Systemd service ready"
|
success "Systemd service created and enabled"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Start the service
|
# Start the service
|
||||||
@ -794,7 +498,6 @@ main() {
|
|||||||
log "${BLUE}==================================================${NOCOLOR}"
|
log "${BLUE}==================================================${NOCOLOR}"
|
||||||
|
|
||||||
detect_os
|
detect_os
|
||||||
check_existing_installation
|
|
||||||
check_ports
|
check_ports
|
||||||
|
|
||||||
# Check and install Go if needed
|
# Check and install Go if needed
|
||||||
@ -803,48 +506,19 @@ main() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
install_dependencies
|
install_dependencies
|
||||||
install_rqlite
|
configuration_wizard
|
||||||
|
|
||||||
# Skip configuration wizard in update mode
|
|
||||||
if [ "$UPDATE_MODE" != true ]; then
|
|
||||||
configuration_wizard
|
|
||||||
else
|
|
||||||
log "Update mode: skipping configuration wizard"
|
|
||||||
# Detect existing node type
|
|
||||||
if [ -f "$INSTALL_DIR/configs/bootstrap.yaml" ]; then
|
|
||||||
NODE_TYPE="bootstrap"
|
|
||||||
elif [ -f "$INSTALL_DIR/configs/node.yaml" ]; then
|
|
||||||
NODE_TYPE="node"
|
|
||||||
else
|
|
||||||
error "Cannot determine existing node type"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
log "Detected existing node type: $NODE_TYPE"
|
|
||||||
fi
|
|
||||||
|
|
||||||
setup_directories
|
setup_directories
|
||||||
setup_source_code
|
setup_source_code
|
||||||
generate_identity
|
generate_identity
|
||||||
build_binaries
|
build_binaries
|
||||||
|
generate_configs
|
||||||
# Only generate new configs if not in update mode
|
configure_firewall
|
||||||
if [ "$UPDATE_MODE" != true ]; then
|
|
||||||
generate_configs
|
|
||||||
configure_firewall
|
|
||||||
else
|
|
||||||
log "Update mode: keeping existing configuration"
|
|
||||||
fi
|
|
||||||
|
|
||||||
create_systemd_service
|
create_systemd_service
|
||||||
start_service
|
start_service
|
||||||
|
|
||||||
# Display completion information
|
# Display completion information
|
||||||
log "${BLUE}==================================================${NOCOLOR}"
|
log "${BLUE}==================================================${NOCOLOR}"
|
||||||
if [ "$UPDATE_MODE" = true ]; then
|
log "${GREEN} Installation Complete! ${NOCOLOR}"
|
||||||
log "${GREEN} Update Complete! ${NOCOLOR}"
|
|
||||||
else
|
|
||||||
log "${GREEN} Installation Complete! ${NOCOLOR}"
|
|
||||||
fi
|
|
||||||
log "${BLUE}==================================================${NOCOLOR}"
|
log "${BLUE}==================================================${NOCOLOR}"
|
||||||
|
|
||||||
log "${GREEN}Node Type:${NOCOLOR} ${CYAN}$NODE_TYPE${NOCOLOR}"
|
log "${GREEN}Node Type:${NOCOLOR} ${CYAN}$NODE_TYPE${NOCOLOR}"
|
||||||
@ -869,14 +543,10 @@ main() {
|
|||||||
log "${CYAN} - sudo systemctl stop debros-$NODE_TYPE${NOCOLOR} (Stop service)"
|
log "${CYAN} - sudo systemctl stop debros-$NODE_TYPE${NOCOLOR} (Stop service)"
|
||||||
log "${CYAN} - sudo systemctl start debros-$NODE_TYPE${NOCOLOR} (Start service)"
|
log "${CYAN} - sudo systemctl start debros-$NODE_TYPE${NOCOLOR} (Start service)"
|
||||||
log "${CYAN} - sudo journalctl -u debros-$NODE_TYPE.service -f${NOCOLOR} (View logs)"
|
log "${CYAN} - sudo journalctl -u debros-$NODE_TYPE.service -f${NOCOLOR} (View logs)"
|
||||||
log "${CYAN} - $INSTALL_DIR/bin/network-cli${NOCOLOR} (Use CLI tools)"
|
log "${CYAN} - $INSTALL_DIR/bin/cli${NOCOLOR} (Use CLI tools)"
|
||||||
log "${BLUE}==================================================${NOCOLOR}"
|
log "${BLUE}==================================================${NOCOLOR}"
|
||||||
|
|
||||||
if [ "$UPDATE_MODE" = true ]; then
|
success "DeBros Network $NODE_TYPE node is now running!"
|
||||||
success "DeBros Network $NODE_TYPE node has been updated and is running!"
|
|
||||||
else
|
|
||||||
success "DeBros Network $NODE_TYPE node is now running!"
|
|
||||||
fi
|
|
||||||
log "${CYAN}For documentation visit: https://docs.debros.io${NOCOLOR}"
|
log "${CYAN}For documentation visit: https://docs.debros.io${NOCOLOR}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user