Merge branch 'main' into nightly

This commit is contained in:
anonpenguin 2025-10-25 13:05:00 +03:00 committed by GitHub
commit 5939cf413e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 573 additions and 348 deletions

2
.gitignore vendored
View File

@ -73,3 +73,5 @@ data/bootstrap/rqlite/
.env.*
configs/
.dev/

View File

@ -8,14 +8,38 @@ The format is based on [Keep a Changelog][keepachangelog] and adheres to [Semant
### Added
- One-command `make dev` target to start full development stack (bootstrap + node2 + node3 + gateway in background)
- New `network-cli config init` (no --type) generates complete development stack with all configs and identities
- Full stack initialization with auto-generated peer identities for bootstrap and all nodes
- Explicit control over LibP2P listen addresses for better localhost/development support
- Production/development mode detection for NAT services (disabled for localhost, enabled for production)
- Process management with .dev/pids directory for background process tracking
- Centralized logging to ~/.debros/logs/ for all network services
### Changed
- Simplified Makefile: removed legacy dev commands, replaced with unified `make dev` target
- Updated README with clearer getting started instructions (single `make dev` command)
- Simplified `network-cli config init` behavior: defaults to generating full stack instead of single node
- `network-cli config init` now handles bootstrap peer discovery and join addresses automatically
- LibP2P configuration: removed always-on NAT services for development environments
- Code formatting in pkg/node/node.go (indentation fixes in bootstrapPeerSource)
### Deprecated
### Removed
- Removed legacy Makefile targets: run-example, show-bootstrap, run-cli, cli-health, cli-peers, cli-status, cli-storage-test, cli-pubsub-test
- Removed verbose dev-setup, dev-cluster, and old dev workflow targets
### Fixed
- Fixed indentation in bootstrapPeerSource function for consistency
- Fixed gateway.yaml generation with correct YAML indentation for bootstrap_peers
- Fixed script for running and added gateway running as well
### Security
## [0.51.6] - 2025-10-24
### Added

145
Makefile
View File

@ -21,7 +21,7 @@ test-e2e:
.PHONY: build clean test run-node run-node2 run-node3 run-example deps tidy fmt vet lint clear-ports
VERSION := 0.51.6-beta
VERSION := 0.51.7-beta
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ)
LDFLAGS := -X 'main.version=$(VERSION)' -X 'main.commit=$(COMMIT)' -X 'main.date=$(DATE)'
@ -77,110 +77,45 @@ run-gateway:
@echo "Generate it with: network-cli config init --type gateway"
go run ./cmd/gateway
# Run basic usage example
run-example:
@echo "Running basic usage example..."
go run examples/basic_usage.go
# Show how to run with flags
show-bootstrap:
@echo "Provide join address via flags, e.g.:"
@echo " make run-node2 JOINADDR=/ip4/127.0.0.1/tcp/5001 HTTP=5002 RAFT=7002 P2P=4002"
# Run network CLI
run-cli:
@echo "Running network CLI help..."
./bin/network-cli help
# Network CLI helper commands
cli-health:
@echo "Checking network health..."
./bin/network-cli health
cli-peers:
@echo "Listing network peers..."
./bin/network-cli peers
cli-status:
@echo "Getting network status..."
./bin/network-cli status
cli-storage-test:
@echo "Testing storage operations..."
@./bin/network-cli storage put test-key "Hello Network" || echo "Storage test requires running network"
@./bin/network-cli storage get test-key || echo "Storage test requires running network"
@./bin/network-cli storage list || echo "Storage test requires running network"
cli-pubsub-test:
@echo "Testing pub/sub operations..."
@./bin/network-cli pubsub publish test-topic "Hello World" || echo "PubSub test requires running network"
@./bin/network-cli pubsub topics || echo "PubSub test requires running network"
# Download dependencies
deps:
@echo "Downloading dependencies..."
go mod download
# Tidy dependencies
tidy:
@echo "Tidying dependencies..."
go mod tidy
# Format code
fmt:
@echo "Formatting code..."
go fmt ./...
# Vet code
vet:
@echo "Vetting code..."
go vet ./...
# Lint alias (lightweight for now)
lint: fmt vet
@echo "Linting complete (fmt + vet)"
# Clear common development ports
clear-ports:
@echo "Clearing common dev ports (4001/4002, 5001/5002, 7001/7002)..."
@chmod +x scripts/clear-ports.sh || true
@scripts/clear-ports.sh
# Development setup
dev-setup: deps
@echo "Setting up development environment..."
@mkdir -p data/bootstrap data/node data/node2 data/node3
@mkdir -p data/test-bootstrap data/test-node1 data/test-node2
@echo "Development setup complete!"
# Start development cluster (requires multiple terminals)
dev-cluster:
@echo "To start a development cluster with 3 nodes:"
# One-command dev: Start bootstrap, node2, node3, and gateway in background
# Requires: configs already exist in ~/.debros
dev: build
@echo "🚀 Starting development network stack..."
@mkdir -p .dev/pids
@mkdir -p $$HOME/.debros/logs
@echo "Starting bootstrap node..."
@nohup ./bin/node --config bootstrap.yaml > $$HOME/.debros/logs/bootstrap.log 2>&1 & echo $$! > .dev/pids/bootstrap.pid
@sleep 2
@echo "Starting node2..."
@nohup ./bin/node --config node2.yaml > $$HOME/.debros/logs/node2.log 2>&1 & echo $$! > .dev/pids/node2.pid
@sleep 1
@echo "Starting node3..."
@nohup ./bin/node --config node3.yaml > $$HOME/.debros/logs/node3.log 2>&1 & echo $$! > .dev/pids/node3.pid
@sleep 1
@echo "Starting gateway..."
@nohup ./bin/gateway --config gateway.yaml > $$HOME/.debros/logs/gateway.log 2>&1 & echo $$! > .dev/pids/gateway.pid
@echo ""
@echo "1. Generate config files in ~/.debros:"
@echo " make build"
@echo " ./bin/network-cli config init --type bootstrap"
@echo " ./bin/network-cli config init --type node --name node.yaml --bootstrap-peers '<bootstrap_peer_multiaddr>'"
@echo " ./bin/network-cli config init --type node --name node2.yaml --bootstrap-peers '<bootstrap_peer_multiaddr>'"
@echo "============================================================"
@echo "✅ Development stack started!"
@echo "============================================================"
@echo ""
@echo "2. Run in separate terminals:"
@echo " Terminal 1: make run-node # Start bootstrap node (bootstrap.yaml)"
@echo " Terminal 2: make run-node2 # Start node 1 (node.yaml)"
@echo " Terminal 3: make run-node3 # Start node 2 (node2.yaml)"
@echo " Terminal 4: make run-gateway # Start gateway"
@echo "Processes:"
@echo " Bootstrap: PID=$$(cat .dev/pids/bootstrap.pid)"
@echo " Node2: PID=$$(cat .dev/pids/node2.pid)"
@echo " Node3: PID=$$(cat .dev/pids/node3.pid)"
@echo " Gateway: PID=$$(cat .dev/pids/gateway.pid)"
@echo ""
@echo "3. Or run custom node with any config file:"
@echo " go run ./cmd/node --config custom-node.yaml"
@echo "Ports:"
@echo " Bootstrap P2P: 4001, HTTP: 5001, Raft: 7001"
@echo " Node2 P2P: 4002, HTTP: 5002, Raft: 7002"
@echo " Node3 P2P: 4003, HTTP: 5003, Raft: 7003"
@echo " Gateway: 6001"
@echo ""
@echo "4. Test:"
@echo " make cli-health # Check network health"
@echo " make cli-peers # List peers"
@echo " make cli-storage-test # Test storage"
@echo " make cli-pubsub-test # Test messaging"
# Full development workflow
dev: clean build test
@echo "Development workflow complete!"
@echo "Press Ctrl+C to stop all processes"
@echo "============================================================"
@echo ""
@trap 'echo "Stopping all processes..."; kill $$(cat .dev/pids/*.pid) 2>/dev/null; rm -f .dev/pids/*.pid; exit 0' INT; \
tail -f $$HOME/.debros/logs/bootstrap.log $$HOME/.debros/logs/node2.log $$HOME/.debros/logs/node3.log $$HOME/.debros/logs/gateway.log
# Help
help:
@ -189,12 +124,14 @@ help:
@echo " clean - Clean build artifacts"
@echo " test - Run tests"
@echo ""
@echo "Development:"
@echo " dev - Start full dev stack (bootstrap + 2 nodes + gateway)"
@echo " Requires: configs in ~/.debros (run 'network-cli config init' first)"
@echo ""
@echo "Configuration (NEW):"
@echo " First, generate config files in ~/.debros with:"
@echo " make build # Build CLI first"
@echo " ./bin/network-cli config init --type bootstrap # Generate bootstrap config"
@echo " ./bin/network-cli config init --type node --bootstrap-peers '<peer_multiaddr>'"
@echo " ./bin/network-cli config init --type gateway"
@echo " ./bin/network-cli config init # Generate full stack"
@echo ""
@echo "Network Targets (requires config files in ~/.debros):"
@echo " run-node - Start bootstrap node"

126
README.md
View File

@ -174,23 +174,36 @@ cd network
make build
```
### 3. Start a Bootstrap Node
### 3. Generate Configuration Files
```bash
make run-node
# Or manually:
go run ./cmd/node --config configs/node.yaml
# Generate all configs (bootstrap, node2, node3, gateway) with one command
./bin/network-cli config init
```
### 4. Start Additional Nodes
This creates:
- `~/.debros/bootstrap.yaml` - Bootstrap node
- `~/.debros/node2.yaml` - Regular node 2
- `~/.debros/node3.yaml` - Regular node 3
- `~/.debros/gateway.yaml` - HTTP Gateway
Plus auto-generated identities for each node.
### 4. Start the Complete Network Stack
```bash
make run-node2
# Or manually:
go run ./cmd/node --config configs/node.yaml
make dev
```
### 5. Test with CLI
This starts:
- Bootstrap node (P2P: 4001, RQLite HTTP: 5001, Raft: 7001)
- Node 2 (P2P: 4002, RQLite HTTP: 5002, Raft: 7002)
- Node 3 (P2P: 4003, RQLite HTTP: 5003, Raft: 7003)
- Gateway (HTTP: 6001)
Logs stream to terminal. Press **Ctrl+C** to stop all processes.
### 5. Test with CLI (in another terminal)
```bash
./bin/network-cli health
@ -261,100 +274,103 @@ The system will **only** load config from `~/.debros/` and will error if require
Use the `network-cli config init` command to generate configuration files:
#### Generate a Node Config
### Generate Complete Stack (Recommended)
```bash
# Generate bootstrap, node2, node3, and gateway configs in one command
./bin/network-cli config init
# Force regenerate (overwrites existing configs)
./bin/network-cli config init --force
```
This is the **recommended way** to get started with a local development network.
### Generate Individual Configs (Advanced)
For custom setups or production deployments, you can generate individual configs:
#### Generate a Single Node Config
```bash
# Generate basic node config with bootstrap peers
network-cli config init --type node --bootstrap-peers "/ip4/127.0.0.1/tcp/4001/p2p/QmXxx,/ip4/127.0.0.1/tcp/4002/p2p/QmYyy"
./bin/network-cli config init --type node --bootstrap-peers "/ip4/127.0.0.1/tcp/4001/p2p/QmXxx"
# With custom ports
network-cli config init --type node --name node2.yaml --listen-port 4002 --rqlite-http-port 5002 --rqlite-raft-port 7002 --join localhost:5001 --bootstrap-peers "/ip4/127.0.0.1/tcp/4001/p2p/QmXxx"
./bin/network-cli config init --type node --name node2.yaml \
--listen-port 4002 --rqlite-http-port 5002 --rqlite-raft-port 7002 \
--join localhost:5001 --bootstrap-peers "/ip4/127.0.0.1/tcp/4001/p2p/QmXxx"
# Force overwrite existing config
network-cli config init --type node --force
./bin/network-cli config init --type node --force
```
#### Generate a Bootstrap Node Config
```bash
# Generate bootstrap node (no join address required)
network-cli config init --type bootstrap
./bin/network-cli config init --type bootstrap
# With custom ports
network-cli config init --type bootstrap --listen-port 4001 --rqlite-http-port 5001 --rqlite-raft-port 7001
./bin/network-cli config init --type bootstrap --listen-port 4001 --rqlite-http-port 5001 --rqlite-raft-port 7001
```
#### Generate a Gateway Config
```bash
# Generate gateway config
network-cli config init --type gateway
./bin/network-cli config init --type gateway
# With bootstrap peers
network-cli config init --type gateway --bootstrap-peers "/ip4/127.0.0.1/tcp/4001/p2p/QmXxx"
./bin/network-cli config init --type gateway --bootstrap-peers "/ip4/127.0.0.1/tcp/4001/p2p/QmXxx"
```
### Running Multiple Nodes on the Same Machine
### Running the Network
You can run multiple nodes on a single machine by creating separate configuration files and using the `--config` flag:
#### Create Multiple Node Configs
Once configs are generated, start the complete stack with:
```bash
# Node 1
./bin/network-cli config init --type node --name node1.yaml \
--listen-port 4001 --rqlite-http-port 5001 --rqlite-raft-port 7001 \
--bootstrap-peers "/ip4/127.0.0.1/tcp/4001/p2p/<BOOTSTRAP_ID>"
# Node 2
./bin/network-cli config init --type node --name node2.yaml \
--listen-port 4002 --rqlite-http-port 5002 --rqlite-raft-port 7002 \
--join localhost:5001 \
--bootstrap-peers "/ip4/127.0.0.1/tcp/4001/p2p/<BOOTSTRAP_ID>"
# Node 3
./bin/network-cli config init --type node --name node3.yaml \
--listen-port 4003 --rqlite-http-port 5003 --rqlite-raft-port 7003 \
--join localhost:5001 \
--bootstrap-peers "/ip4/127.0.0.1/tcp/4001/p2p/<BOOTSTRAP_ID>"
make dev
```
#### Run Multiple Nodes in Separate Terminals
Or start individual components (in separate terminals):
```bash
# Terminal 1 - Bootstrap node
go run ./cmd/node --config bootstrap.yaml
# Terminal 2 - Node 1
go run ./cmd/node --config node1.yaml
# Terminal 3 - Node 2
# Terminal 2 - Node 2
go run ./cmd/node --config node2.yaml
# Terminal 4 - Node 3
# Terminal 3 - Node 3
go run ./cmd/node --config node3.yaml
# Terminal 4 - Gateway
go run ./cmd/gateway --config gateway.yaml
```
#### Or Use Makefile Targets
### Running Multiple Nodes on the Same Machine
The default `make dev` creates a 3-node setup. For additional nodes, generate individual configs:
```bash
# Terminal 1
make run-node # Runs: go run ./cmd/node --config bootstrap.yaml
# Generate additional node configs with unique ports
./bin/network-cli config init --type node --name node4.yaml \
--listen-port 4004 --rqlite-http-port 5004 --rqlite-raft-port 7004 \
--join localhost:5001 \
--bootstrap-peers "/ip4/127.0.0.1/tcp/4001/p2p/<BOOTSTRAP_ID>"
# Terminal 2
make run-node2 # Runs: go run ./cmd/node --config node.yaml
# Terminal 3
make run-node3 # Runs: go run ./cmd/node --config node2.yaml
# Start the additional node
go run ./cmd/node --config node4.yaml
```
#### Key Points for Multiple Nodes
- **Each node needs unique ports**: P2P port, RQLite HTTP port, and RQLite Raft port must all be different
- **Join address**: Non-bootstrap nodes need `rqlite_join_address` pointing to the bootstrap or an existing node
- **Join address**: Non-bootstrap nodes need `rqlite_join_address` pointing to the bootstrap or an existing node (use Raft port)
- **Bootstrap peers**: All nodes need the bootstrap node's multiaddr in `discovery.bootstrap_peers`
- **Config files**: Store all configs in `~/.debros/` with different filenames
- **--config flag**: Specify which config file to load (defaults to `node.yaml`)
- **--config flag**: Specify which config file to load
⚠️ **Common Mistake - Same Ports:**
If all nodes use the same ports (e.g., 5001, 7001), they will try to bind to the same addresses and fail to communicate. Verify each node has unique ports:
@ -365,11 +381,11 @@ grep "rqlite_port\|rqlite_raft_port" ~/.debros/bootstrap.yaml
# Should show: rqlite_port: 5001, rqlite_raft_port: 7001
# Node 2
grep "rqlite_port\|rqlite_raft_port" ~/.debros/node.yaml
grep "rqlite_port\|rqlite_raft_port" ~/.debros/node2.yaml
# Should show: rqlite_port: 5002, rqlite_raft_port: 7002
# Node 3
grep "rqlite_port\|rqlite_raft_port" ~/.debros/node2.yaml
grep "rqlite_port\|rqlite_raft_port" ~/.debros/node3.yaml
# Should show: rqlite_port: 5003, rqlite_raft_port: 7003
```

View File

@ -15,6 +15,7 @@ import (
"github.com/DeBrosOfficial/network/pkg/auth"
"github.com/DeBrosOfficial/network/pkg/client"
"github.com/DeBrosOfficial/network/pkg/config"
"github.com/DeBrosOfficial/network/pkg/encryption"
"github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"
)
@ -607,30 +608,35 @@ func showConfigHelp() {
fmt.Printf("Config Management Commands\n\n")
fmt.Printf("Usage: network-cli config <subcommand> [options]\n\n")
fmt.Printf("Subcommands:\n")
fmt.Printf(" init - Generate configuration files in ~/.debros\n")
fmt.Printf(" init - Generate full network stack in ~/.debros (bootstrap + 2 nodes + gateway)\n")
fmt.Printf(" validate --name <file> - Validate a config file\n\n")
fmt.Printf("Init Default Behavior (no --type):\n")
fmt.Printf(" Generates bootstrap.yaml, node2.yaml, node3.yaml, gateway.yaml with:\n")
fmt.Printf(" - Auto-generated identities for bootstrap, node2, node3\n")
fmt.Printf(" - Correct bootstrap_peers and join addresses\n")
fmt.Printf(" - Default ports: P2P 4001-4003, HTTP 5001-5003, Raft 7001-7003\n\n")
fmt.Printf("Init Options:\n")
fmt.Printf(" --type <type> - Config type: node, bootstrap, gateway (default: node)\n")
fmt.Printf(" --name <file> - Output filename (default: node.yaml)\n")
fmt.Printf(" --type <type> - Single config type: node, bootstrap, gateway (skips stack generation)\n")
fmt.Printf(" --name <file> - Output filename (default: depends on --type or 'stack' for full stack)\n")
fmt.Printf(" --force - Overwrite existing config/stack files\n\n")
fmt.Printf("Single Config Options (with --type):\n")
fmt.Printf(" --id <id> - Node ID for bootstrap peers\n")
fmt.Printf(" --listen-port <port> - LibP2P listen port (default: 4001)\n")
fmt.Printf(" --rqlite-http-port <port> - RQLite HTTP port (default: 5001)\n")
fmt.Printf(" --rqlite-raft-port <port> - RQLite Raft port (default: 7001)\n")
fmt.Printf(" --join <host:port> - RQLite address to join (required for non-bootstrap)\n")
fmt.Printf(" --bootstrap-peers <peers> - Comma-separated bootstrap peer multiaddrs\n")
fmt.Printf(" --force - Overwrite existing config\n\n")
fmt.Printf(" --bootstrap-peers <peers> - Comma-separated bootstrap peer multiaddrs\n\n")
fmt.Printf("Examples:\n")
fmt.Printf(" network-cli config init\n")
fmt.Printf(" network-cli config init --type node --bootstrap-peers /ip4/127.0.0.1/tcp/4001/p2p/QmXxx,/ip4/127.0.0.1/tcp/4002/p2p/QmYyy\n")
fmt.Printf(" network-cli config init --type bootstrap\n")
fmt.Printf(" network-cli config init --type gateway\n")
fmt.Printf(" network-cli config init # Generate full stack\n")
fmt.Printf(" network-cli config init --force # Overwrite existing stack\n")
fmt.Printf(" network-cli config init --type bootstrap # Single bootstrap config (legacy)\n")
fmt.Printf(" network-cli config validate --name node.yaml\n")
}
func handleConfigInit(args []string) {
// Parse flags
var (
cfgType = "node"
cfgType = ""
name = "" // Will be set based on type if not provided
id string
listenPort = 4001
@ -694,6 +700,13 @@ func handleConfigInit(args []string) {
}
}
// If --type is not specified, generate full stack
if cfgType == "" {
initFullStack(force)
return
}
// Otherwise, continue with single-file generation
// Validate type
if cfgType != "node" && cfgType != "bootstrap" && cfgType != "gateway" {
fmt.Fprintf(os.Stderr, "Invalid --type: %s (expected: node, bootstrap, or gateway)\n", cfgType)
@ -799,6 +812,192 @@ func handleConfigValidate(args []string) {
fmt.Printf("✅ Config is valid: %s\n", configPath)
}
func initFullStack(force bool) {
fmt.Printf("🚀 Initializing full network stack...\n")
// Ensure ~/.debros directory exists
homeDir, err := os.UserHomeDir()
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to get home directory: %v\n", err)
os.Exit(1)
}
debrosDir := filepath.Join(homeDir, ".debros")
if err := os.MkdirAll(debrosDir, 0755); err != nil {
fmt.Fprintf(os.Stderr, "Failed to create ~/.debros directory: %v\n", err)
os.Exit(1)
}
// Step 1: Generate bootstrap identity
bootstrapIdentityDir := filepath.Join(debrosDir, "bootstrap")
bootstrapIdentityPath := filepath.Join(bootstrapIdentityDir, "identity.key")
if !force {
if _, err := os.Stat(bootstrapIdentityPath); err == nil {
fmt.Fprintf(os.Stderr, "Bootstrap identity already exists at %s (use --force to overwrite)\n", bootstrapIdentityPath)
os.Exit(1)
}
}
bootstrapInfo, err := encryption.GenerateIdentity()
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to generate bootstrap identity: %v\n", err)
os.Exit(1)
}
if err := os.MkdirAll(bootstrapIdentityDir, 0755); err != nil {
fmt.Fprintf(os.Stderr, "Failed to create bootstrap data directory: %v\n", err)
os.Exit(1)
}
if err := encryption.SaveIdentity(bootstrapInfo, bootstrapIdentityPath); err != nil {
fmt.Fprintf(os.Stderr, "Failed to save bootstrap identity: %v\n", err)
os.Exit(1)
}
fmt.Printf("✅ Generated bootstrap identity: %s (Peer ID: %s)\n", bootstrapIdentityPath, bootstrapInfo.PeerID.String())
// Construct bootstrap multiaddr
bootstrapMultiaddr := fmt.Sprintf("/ip4/127.0.0.1/tcp/4001/p2p/%s", bootstrapInfo.PeerID.String())
fmt.Printf(" Bootstrap multiaddr: %s\n", bootstrapMultiaddr)
// Step 2: Generate bootstrap.yaml
bootstrapName := "bootstrap.yaml"
bootstrapPath := filepath.Join(debrosDir, bootstrapName)
if !force {
if _, err := os.Stat(bootstrapPath); err == nil {
fmt.Fprintf(os.Stderr, "Bootstrap config already exists at %s (use --force to overwrite)\n", bootstrapPath)
os.Exit(1)
}
}
bootstrapContent := generateBootstrapConfig(bootstrapName, "", 4001, 5001, 7001)
if err := os.WriteFile(bootstrapPath, []byte(bootstrapContent), 0644); err != nil {
fmt.Fprintf(os.Stderr, "Failed to write bootstrap config: %v\n", err)
os.Exit(1)
}
fmt.Printf("✅ Generated bootstrap config: %s\n", bootstrapPath)
// Step 3: Generate node2 identity and config
node2IdentityDir := filepath.Join(debrosDir, "node2")
node2IdentityPath := filepath.Join(node2IdentityDir, "identity.key")
if !force {
if _, err := os.Stat(node2IdentityPath); err == nil {
fmt.Fprintf(os.Stderr, "Node2 identity already exists at %s (use --force to overwrite)\n", node2IdentityPath)
os.Exit(1)
}
}
node2Info, err := encryption.GenerateIdentity()
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to generate node2 identity: %v\n", err)
os.Exit(1)
}
if err := os.MkdirAll(node2IdentityDir, 0755); err != nil {
fmt.Fprintf(os.Stderr, "Failed to create node2 data directory: %v\n", err)
os.Exit(1)
}
if err := encryption.SaveIdentity(node2Info, node2IdentityPath); err != nil {
fmt.Fprintf(os.Stderr, "Failed to save node2 identity: %v\n", err)
os.Exit(1)
}
fmt.Printf("✅ Generated node2 identity: %s (Peer ID: %s)\n", node2IdentityPath, node2Info.PeerID.String())
node2Name := "node2.yaml"
node2Path := filepath.Join(debrosDir, node2Name)
if !force {
if _, err := os.Stat(node2Path); err == nil {
fmt.Fprintf(os.Stderr, "Node2 config already exists at %s (use --force to overwrite)\n", node2Path)
os.Exit(1)
}
}
node2Content := generateNodeConfig(node2Name, "", 4002, 5002, 7002, "127.0.0.1:7001", bootstrapMultiaddr)
if err := os.WriteFile(node2Path, []byte(node2Content), 0644); err != nil {
fmt.Fprintf(os.Stderr, "Failed to write node2 config: %v\n", err)
os.Exit(1)
}
fmt.Printf("✅ Generated node2 config: %s\n", node2Path)
// Step 4: Generate node3 identity and config
node3IdentityDir := filepath.Join(debrosDir, "node3")
node3IdentityPath := filepath.Join(node3IdentityDir, "identity.key")
if !force {
if _, err := os.Stat(node3IdentityPath); err == nil {
fmt.Fprintf(os.Stderr, "Node3 identity already exists at %s (use --force to overwrite)\n", node3IdentityPath)
os.Exit(1)
}
}
node3Info, err := encryption.GenerateIdentity()
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to generate node3 identity: %v\n", err)
os.Exit(1)
}
if err := os.MkdirAll(node3IdentityDir, 0755); err != nil {
fmt.Fprintf(os.Stderr, "Failed to create node3 data directory: %v\n", err)
os.Exit(1)
}
if err := encryption.SaveIdentity(node3Info, node3IdentityPath); err != nil {
fmt.Fprintf(os.Stderr, "Failed to save node3 identity: %v\n", err)
os.Exit(1)
}
fmt.Printf("✅ Generated node3 identity: %s (Peer ID: %s)\n", node3IdentityPath, node3Info.PeerID.String())
node3Name := "node3.yaml"
node3Path := filepath.Join(debrosDir, node3Name)
if !force {
if _, err := os.Stat(node3Path); err == nil {
fmt.Fprintf(os.Stderr, "Node3 config already exists at %s (use --force to overwrite)\n", node3Path)
os.Exit(1)
}
}
node3Content := generateNodeConfig(node3Name, "", 4003, 5003, 7003, "127.0.0.1:7001", bootstrapMultiaddr)
if err := os.WriteFile(node3Path, []byte(node3Content), 0644); err != nil {
fmt.Fprintf(os.Stderr, "Failed to write node3 config: %v\n", err)
os.Exit(1)
}
fmt.Printf("✅ Generated node3 config: %s\n", node3Path)
// Step 5: Generate gateway.yaml
gatewayName := "gateway.yaml"
gatewayPath := filepath.Join(debrosDir, gatewayName)
if !force {
if _, err := os.Stat(gatewayPath); err == nil {
fmt.Fprintf(os.Stderr, "Gateway config already exists at %s (use --force to overwrite)\n", gatewayPath)
os.Exit(1)
}
}
gatewayContent := generateGatewayConfig(bootstrapMultiaddr)
if err := os.WriteFile(gatewayPath, []byte(gatewayContent), 0644); err != nil {
fmt.Fprintf(os.Stderr, "Failed to write gateway config: %v\n", err)
os.Exit(1)
}
fmt.Printf("✅ Generated gateway config: %s\n", gatewayPath)
// Print summary
fmt.Printf("\n" + strings.Repeat("=", 60) + "\n")
fmt.Printf("✅ Full network stack initialized successfully!\n")
fmt.Printf(strings.Repeat("=", 60) + "\n\n")
fmt.Printf("Configuration files created in: %s\n\n", debrosDir)
fmt.Printf("Bootstrap Node:\n")
fmt.Printf(" Config: %s\n", bootstrapPath)
fmt.Printf(" Peer ID: %s\n", bootstrapInfo.PeerID.String())
fmt.Printf(" Ports: P2P=4001, HTTP=5001, Raft=7001\n\n")
fmt.Printf("Node2:\n")
fmt.Printf(" Config: %s\n", node2Path)
fmt.Printf(" Ports: P2P=4002, HTTP=5002, Raft=7002\n")
fmt.Printf(" Join: 127.0.0.1:7001\n\n")
fmt.Printf("Node3:\n")
fmt.Printf(" Config: %s\n", node3Path)
fmt.Printf(" Ports: P2P=4003, HTTP=5003, Raft=7003\n")
fmt.Printf(" Join: 127.0.0.1:7001\n\n")
fmt.Printf("Gateway:\n")
fmt.Printf(" Config: %s\n\n", gatewayPath)
fmt.Printf("To start the network:\n")
fmt.Printf(" Terminal 1: ./bin/node --config bootstrap.yaml\n")
fmt.Printf(" Terminal 2: ./bin/node --config node2.yaml\n")
fmt.Printf(" Terminal 3: ./bin/node --config node3.yaml\n")
fmt.Printf(" Terminal 4: ./bin/gateway --config gateway.yaml\n")
fmt.Printf("\n" + strings.Repeat("=", 60) + "\n")
}
func generateNodeConfig(name, id string, listenPort, rqliteHTTPPort, rqliteRaftPort int, joinAddr, bootstrapPeers string) string {
nodeID := id
if nodeID == "" {
@ -923,11 +1122,11 @@ func generateGatewayConfig(bootstrapPeers string) string {
var peersYAML strings.Builder
if len(peers) == 0 {
peersYAML.WriteString(" bootstrap_peers: []")
peersYAML.WriteString("bootstrap_peers: []")
} else {
peersYAML.WriteString(" bootstrap_peers:\n")
peersYAML.WriteString("bootstrap_peers:\n")
for _, p := range peers {
fmt.Fprintf(&peersYAML, " - \"%s\"\n", p)
fmt.Fprintf(&peersYAML, " - \"%s\"\n", p)
}
}

View File

@ -84,35 +84,35 @@ func (n *Node) startRQLite(ctx context.Context) error {
// bootstrapPeerSource returns a PeerSource that yields peers from BootstrapPeers.
func bootstrapPeerSource(bootstrapAddrs []string, logger *zap.Logger) func(context.Context, int) <-chan peer.AddrInfo {
return func(ctx context.Context, num int) <-chan peer.AddrInfo {
out := make(chan peer.AddrInfo, num)
go func() {
defer close(out)
count := 0
for _, s := range bootstrapAddrs {
if count >= num {
return
}
ma, err := multiaddr.NewMultiaddr(s)
if err != nil {
logger.Debug("invalid bootstrap multiaddr", zap.String("addr", s), zap.Error(err))
continue
}
ai, err := peer.AddrInfoFromP2pAddr(ma)
if err != nil {
logger.Debug("failed to parse bootstrap peer", zap.String("addr", s), zap.Error(err))
continue
}
select {
case out <- *ai:
count++
case <-ctx.Done():
return
}
}
}()
return out
}
return func(ctx context.Context, num int) <-chan peer.AddrInfo {
out := make(chan peer.AddrInfo, num)
go func() {
defer close(out)
count := 0
for _, s := range bootstrapAddrs {
if count >= num {
return
}
ma, err := multiaddr.NewMultiaddr(s)
if err != nil {
logger.Debug("invalid bootstrap multiaddr", zap.String("addr", s), zap.Error(err))
continue
}
ai, err := peer.AddrInfoFromP2pAddr(ma)
if err != nil {
logger.Debug("failed to parse bootstrap peer", zap.String("addr", s), zap.Error(err))
continue
}
select {
case out <- *ai:
count++
case <-ctx.Done():
return
}
}
}()
return out
}
}
// hasBootstrapConnections checks if we're connected to any bootstrap peers
@ -250,21 +250,52 @@ func (n *Node) startLibP2P() error {
return fmt.Errorf("failed to load identity: %w", err)
}
// Create LibP2P host with NAT traversal support
// Create LibP2P host with explicit listen addresses
var opts []libp2p.Option
opts = append(opts,
libp2p.Identity(identity),
libp2p.Security(noise.ID, noise.New),
libp2p.DefaultMuxers,
libp2p.EnableNATService(),
libp2p.EnableAutoNATv2(),
libp2p.EnableRelay(),
libp2p.NATPortMap(),
libp2p.EnableAutoRelayWithPeerSource(
bootstrapPeerSource(n.config.Discovery.BootstrapPeers, n.logger.Logger),
),
)
// Add explicit listen addresses from config
if len(n.config.Node.ListenAddresses) > 0 {
listenAddrs := make([]multiaddr.Multiaddr, 0, len(n.config.Node.ListenAddresses))
for _, addr := range n.config.Node.ListenAddresses {
ma, err := multiaddr.NewMultiaddr(addr)
if err != nil {
return fmt.Errorf("invalid listen address %s: %w", addr, err)
}
listenAddrs = append(listenAddrs, ma)
}
opts = append(opts, libp2p.ListenAddrs(listenAddrs...))
n.logger.ComponentInfo(logging.ComponentLibP2P, "Configured listen addresses",
zap.Strings("addrs", n.config.Node.ListenAddresses))
}
// For localhost/development, disable NAT services
// For production, these would be enabled
isLocalhost := len(n.config.Node.ListenAddresses) > 0 &&
(strings.Contains(n.config.Node.ListenAddresses[0], "127.0.0.1") ||
strings.Contains(n.config.Node.ListenAddresses[0], "localhost"))
if isLocalhost {
n.logger.ComponentInfo(logging.ComponentLibP2P, "Localhost detected - disabling NAT services for local development")
// Don't add NAT/AutoRelay options for localhost
} else {
// Production: enable NAT traversal
n.logger.ComponentInfo(logging.ComponentLibP2P, "Production mode - enabling NAT services")
opts = append(opts,
libp2p.EnableNATService(),
libp2p.EnableAutoNATv2(),
libp2p.EnableRelay(),
libp2p.NATPortMap(),
libp2p.EnableAutoRelayWithPeerSource(
bootstrapPeerSource(n.config.Discovery.BootstrapPeers, n.logger.Logger),
),
)
}
h, err := libp2p.New(opts...)
if err != nil {
return err

View File

@ -1,8 +1,8 @@
#!/bin/bash
# DeBros Network Node Installation Script (Modern Node-Only Setup)
# Installs, configures, and manages a DeBros network node with secure defaults.
# Supports update-in-place, systemd service, and CLI management.
# DeBros Network Production Installation Script
# Installs and configures a complete DeBros network node (bootstrap) with gateway.
# Supports idempotent updates and secure systemd service management.
set -e
trap 'echo -e "${RED}An error occurred. Installation aborted.${NOCOLOR}"; exit 1' ERR
@ -25,6 +25,7 @@ GATEWAY_PORT="6001"
RAFT_PORT="7001"
UPDATE_MODE=false
NON_INTERACTIVE=false
DEBROS_USER="debros"
log() { echo -e "${CYAN}[$(date '+%Y-%m-%d %H:%M:%S')]${NOCOLOR} $1"; }
error() { echo -e "${RED}[ERROR]${NOCOLOR} $1"; }
@ -115,7 +116,7 @@ check_existing_installation() {
remove_existing_installation() {
log "Removing existing installation..."
for service in debros-node; do
for service in debros-node debros-gateway; do
if systemctl list-unit-files | grep -q "$service.service"; then
log "Stopping $service service..."
sudo systemctl stop $service.service 2>/dev/null || true
@ -128,8 +129,8 @@ remove_existing_installation() {
sudo rm -rf "$INSTALL_DIR"
log "Removed installation directory"
fi
if id "debros" &>/dev/null; then
sudo userdel debros 2>/dev/null || true
if id "$DEBROS_USER" &>/dev/null; then
sudo userdel "$DEBROS_USER" 2>/dev/null || true
log "Removed debros user"
fi
success "Existing installation removed"
@ -260,50 +261,24 @@ check_ports() {
success "All required ports are available"
}
configuration_wizard() {
log "${BLUE}==================================================${NOCOLOR}"
log "${GREEN} DeBros Network Configuration Wizard ${NOCOLOR}"
log "${BLUE}==================================================${NOCOLOR}"
if [ "$NON_INTERACTIVE" = true ]; then
log "Non-interactive mode: using default configuration"
SOLANA_WALLET="11111111111111111111111111111111"
CONFIGURE_FIREWALL="yes"
log "Installation Directory: $INSTALL_DIR"
log "Firewall Configuration: $CONFIGURE_FIREWALL"
success "Configuration completed with defaults"
return 0
fi
log "${GREEN}Enter your Solana wallet address 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
read -rp "Installation directory [default: $INSTALL_DIR]: " CUSTOM_INSTALL_DIR
if [[ -n "$CUSTOM_INSTALL_DIR" ]]; then INSTALL_DIR="$CUSTOM_INSTALL_DIR"; fi
read -rp "Configure firewall automatically? (yes/no) [default: yes]: " CONFIGURE_FIREWALL
CONFIGURE_FIREWALL="${CONFIGURE_FIREWALL:-yes}"
success "Configuration completed"
}
setup_directories() {
log "Setting up directories and permissions..."
if ! id "debros" &>/dev/null; then
sudo useradd -r -s /bin/false -d "$INSTALL_DIR" debros
if ! id "$DEBROS_USER" &>/dev/null; then
sudo useradd -r -s /usr/sbin/nologin -d "$INSTALL_DIR" "$DEBROS_USER"
log "Created debros user"
else
log "User 'debros' already exists"
fi
sudo mkdir -p "$INSTALL_DIR"/{bin,configs,keys,data,logs,src}
sudo mkdir -p "$INSTALL_DIR/keys/node"
sudo mkdir -p "$INSTALL_DIR/data/node"/{rqlite,storage}
sudo chown -R debros:debros "$INSTALL_DIR"
sudo mkdir -p "$INSTALL_DIR"/{bin,src}
sudo chown -R "$DEBROS_USER:$DEBROS_USER" "$INSTALL_DIR"
sudo chmod 755 "$INSTALL_DIR"
sudo chmod 700 "$INSTALL_DIR/keys"
sudo chmod 700 "$INSTALL_DIR/keys/node"
sudo chmod 755 "$INSTALL_DIR/data"
sudo chmod 755 "$INSTALL_DIR/logs"
sudo chmod 755 "$INSTALL_DIR/configs"
sudo chmod 755 "$INSTALL_DIR/bin"
# Create ~/.debros for the debros user
DEBROS_HOME=$(sudo -u "$DEBROS_USER" sh -c 'echo ~')
sudo -u "$DEBROS_USER" mkdir -p "$DEBROS_HOME/.debros"
sudo chmod 0700 "$DEBROS_HOME/.debros"
success "Directory structure ready"
}
@ -312,39 +287,20 @@ setup_source_code() {
if [ -d "$INSTALL_DIR/src/.git" ]; then
log "Updating existing repository..."
cd "$INSTALL_DIR/src"
sudo -u debros git pull
sudo -u "$DEBROS_USER" git pull
else
log "Cloning repository..."
sudo -u debros git clone "$REPO_URL" "$INSTALL_DIR/src"
sudo -u "$DEBROS_USER" git clone "$REPO_URL" "$INSTALL_DIR/src"
cd "$INSTALL_DIR/src"
fi
success "Source code ready"
}
generate_identity() {
local identity_file="$INSTALL_DIR/keys/node/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..."
cd "$INSTALL_DIR/src"
export PATH=$PATH:/usr/local/go/bin
sudo -u debros env "PATH=$PATH:/usr/local/go/bin" go run ./cmd/identity -output "$identity_file"
success "Node identity generated"
}
build_binaries() {
log "Building DeBros Network binaries..."
cd "$INSTALL_DIR/src"
export PATH=$PATH:/usr/local/go/bin
sudo -u debros env "PATH=$PATH:/usr/local/go/bin" make build
local services_were_running=()
if [ "$UPDATE_MODE" = true ]; then
log "Update mode: checking for running services before binary update..."
@ -353,13 +309,22 @@ build_binaries() {
sudo systemctl stop debros-node.service
services_were_running+=("debros-node")
fi
if systemctl is-active --quiet debros-gateway.service 2>/dev/null; then
log "Stopping debros-gateway service to update binaries..."
sudo systemctl stop debros-gateway.service
services_were_running+=("debros-gateway")
fi
if [ ${#services_were_running[@]} -gt 0 ]; then
log "Waiting for services to stop completely..."
sleep 3
fi
fi
sudo -u "$DEBROS_USER" env "PATH=$PATH:/usr/local/go/bin" make build
sudo cp bin/* "$INSTALL_DIR/bin/"
sudo chown debros:debros "$INSTALL_DIR/bin/"*
sudo chown "$DEBROS_USER:$DEBROS_USER" "$INSTALL_DIR/bin/"*
sudo chmod 755 "$INSTALL_DIR/bin/"*
if [ "$UPDATE_MODE" = true ] && [ ${#services_were_running[@]} -gt 0 ]; then
log "Restarting previously running services..."
for service in "${services_were_running[@]}"; do
@ -371,81 +336,76 @@ build_binaries() {
}
generate_configs() {
log "Generating configuration files..."
cat > /tmp/node.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_PORT
rqlite_raft_port: $RAFT_PORT
logging:
level: "info"
file: "$INSTALL_DIR/logs/node.log"
EOF
sudo mv /tmp/node.yaml "$INSTALL_DIR/configs/node.yaml"
sudo chown debros:debros "$INSTALL_DIR/configs/node.yaml"
log "Generating configuration files via network-cli..."
DEBROS_HOME=$(sudo -u "$DEBROS_USER" sh -c 'echo ~')
# Generate bootstrap config
log "Generating bootstrap.yaml..."
sudo -u "$DEBROS_USER" "$INSTALL_DIR/bin/network-cli" config init --type bootstrap --force
# Generate gateway config
log "Generating gateway.yaml..."
sudo -u "$DEBROS_USER" "$INSTALL_DIR/bin/network-cli" config init --type gateway --force
success "Configuration files generated"
}
configure_firewall() {
if [[ "$CONFIGURE_FIREWALL" == "yes" ]]; then
log "Configuring firewall rules..."
if command -v ufw &> /dev/null; then
log "Adding UFW rules for DeBros Network ports..."
for port in $NODE_PORT $RQLITE_PORT $RAFT_PORT $GATEWAY_PORT; do
if ! sudo ufw allow $port; then
error "Failed to allow port $port"
exit 1
fi
log "Added UFW rule: allow port $port"
done
UFW_STATUS=$(sudo ufw status | grep -o "Status: [a-z]\+" | awk '{print $2}' || echo "inactive")
if [[ "$UFW_STATUS" == "active" ]]; then
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"
log "Configuring firewall rules..."
if command -v ufw &> /dev/null; then
log "Adding UFW rules for DeBros Network ports..."
for port in $NODE_PORT $RQLITE_PORT $RAFT_PORT $GATEWAY_PORT; do
if ! sudo ufw allow $port 2>/dev/null; then
error "Failed to allow port $port"
exit 1
fi
log "Added UFW rule: allow port $port"
done
UFW_STATUS=$(sudo ufw status | grep -o "Status: [a-z]\+" | awk '{print $2}' || echo "inactive")
if [[ "$UFW_STATUS" == "active" ]]; then
success "Firewall rules added and active"
else
warning "UFW not found. Please configure firewall manually."
log "Required ports to allow:"
log " - Port $NODE_PORT (Node)"
log " - Port $RQLITE_PORT (RQLite)"
log " - Port $RAFT_PORT (Raft)"
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
else
warning "UFW not found. Please configure firewall manually."
log "Required ports to allow:"
log " - Port $NODE_PORT (Node P2P)"
log " - Port $RQLITE_PORT (RQLite HTTP)"
log " - Port $RAFT_PORT (RQLite Raft)"
log " - Port $GATEWAY_PORT (Gateway)"
fi
}
create_systemd_service() {
local service_file="/etc/systemd/system/debros-node.service"
if [ -f "$service_file" ]; then
create_systemd_services() {
log "Creating systemd service units..."
# Node service
local node_service_file="/etc/systemd/system/debros-node.service"
if [ -f "$node_service_file" ]; then
log "Cleaning up existing node service..."
sudo systemctl stop debros-node.service 2>/dev/null || true
sudo systemctl disable debros-node.service 2>/dev/null || true
sudo rm -f "$service_file"
sudo rm -f "$node_service_file"
fi
sudo systemctl daemon-reload
log "Creating new systemd service..."
local exec_start="$INSTALL_DIR/bin/node --config $INSTALL_DIR/configs/node.yaml"
cat > /tmp/debros-node.service << EOF
[Unit]
Description=DeBros Network Node
After=network.target
Description=DeBros Network Node (Bootstrap)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=debros
Group=debros
WorkingDirectory=$INSTALL_DIR
Environment=ENVIRONMENT=production
ExecStart=$exec_start
WorkingDirectory=/opt/debros/src
ExecStart=/opt/debros/bin/node --config bootstrap.yaml
Restart=always
RestartSec=10
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=debros-node
@ -454,26 +414,78 @@ NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=$INSTALL_DIR
ReadWritePaths=/opt/debros
[Install]
WantedBy=multi-user.target
EOF
sudo mv /tmp/debros-node.service "$service_file"
sudo mv /tmp/debros-node.service "$node_service_file"
# Gateway service
local gateway_service_file="/etc/systemd/system/debros-gateway.service"
if [ -f "$gateway_service_file" ]; then
log "Cleaning up existing gateway service..."
sudo systemctl stop debros-gateway.service 2>/dev/null || true
sudo systemctl disable debros-gateway.service 2>/dev/null || true
sudo rm -f "$gateway_service_file"
fi
log "Creating debros-gateway.service..."
cat > /tmp/debros-gateway.service << 'EOF'
[Unit]
Description=DeBros Gateway (HTTP/WebSocket)
After=debros-node.service
Wants=debros-node.service
[Service]
Type=simple
User=debros
Group=debros
WorkingDirectory=/opt/debros/src
ExecStart=/opt/debros/bin/gateway
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=debros-gateway
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/opt/debros
[Install]
WantedBy=multi-user.target
EOF
sudo mv /tmp/debros-gateway.service "$gateway_service_file"
sudo systemctl daemon-reload
sudo systemctl enable debros-node.service
success "Systemd service ready"
sudo systemctl enable debros-gateway.service
success "Systemd services ready"
}
start_service() {
log "Starting DeBros Network service..."
start_services() {
log "Starting DeBros Network services..."
sudo systemctl start debros-node.service
sleep 3
if systemctl is-active --quiet debros-node.service; then
success "DeBros Network service started successfully"
success "DeBros Node service started successfully"
else
error "Failed to start DeBros Network service"
log "Check logs with: sudo journalctl -u debros-node.service"
error "Failed to start DeBros Node service"
log "Check logs with: sudo journalctl -u debros-node.service -f"
exit 1
fi
sleep 2
sudo systemctl start debros-gateway.service
sleep 2
if systemctl is-active --quiet debros-gateway.service; then
success "DeBros Gateway service started successfully"
else
error "Failed to start DeBros Gateway service"
log "Check logs with: sudo journalctl -u debros-gateway.service -f"
exit 1
fi
}
@ -501,14 +513,8 @@ main() {
if ! check_go_installation; then install_go; fi
install_dependencies
install_rqlite
if [ "$UPDATE_MODE" != true ]; then configuration_wizard; else
log "Update mode: skipping configuration wizard"
SOLANA_WALLET="11111111111111111111111111111111"
CONFIGURE_FIREWALL="yes"
fi
setup_directories
setup_source_code
generate_identity
build_binaries
if [ "$UPDATE_MODE" != true ]; then
generate_configs
@ -516,8 +522,11 @@ main() {
else
log "Update mode: keeping existing configuration"
fi
create_systemd_service
start_service
create_systemd_services
start_services
DEBROS_HOME=$(sudo -u "$DEBROS_USER" sh -c 'echo ~')
log "${BLUE}==================================================${NOCOLOR}"
if [ "$UPDATE_MODE" = true ]; then
log "${GREEN} Update Complete! ${NOCOLOR}"
@ -526,21 +535,28 @@ main() {
fi
log "${BLUE}==================================================${NOCOLOR}"
log "${GREEN}Installation Directory:${NOCOLOR} ${CYAN}$INSTALL_DIR${NOCOLOR}"
log "${GREEN}Configuration:${NOCOLOR} ${CYAN}$INSTALL_DIR/configs/node.yaml${NOCOLOR}"
log "${GREEN}Logs:${NOCOLOR} ${CYAN}$INSTALL_DIR/logs/node.log${NOCOLOR}"
log "${GREEN}Config Directory:${NOCOLOR} ${CYAN}$DEBROS_HOME/.debros${NOCOLOR}"
log "${GREEN}LibP2P Port:${NOCOLOR} ${CYAN}$NODE_PORT${NOCOLOR}"
log "${GREEN}RQLite Port:${NOCOLOR} ${CYAN}$RQLITE_PORT${NOCOLOR}"
log "${GREEN}Gateway Port:${NOCOLOR} ${CYAN}$GATEWAY_PORT${NOCOLOR}"
log "${GREEN}Raft Port:${NOCOLOR} ${CYAN}$RAFT_PORT${NOCOLOR}"
log "${BLUE}==================================================${NOCOLOR}"
log "${GREEN}Management Commands:${NOCOLOR}"
log "${CYAN} - sudo systemctl status debros-node${NOCOLOR} (Check status)"
log "${CYAN} - sudo systemctl restart debros-node${NOCOLOR} (Restart service)"
log "${CYAN} - sudo systemctl stop debros-node${NOCOLOR} (Stop service)"
log "${CYAN} - sudo systemctl start debros-node${NOCOLOR} (Start service)"
log "${CYAN} - sudo journalctl -u debros-node.service -f${NOCOLOR} (View logs)"
log "${CYAN} - $INSTALL_DIR/bin/network-cli${NOCOLOR} (Use CLI tools)"
log "${GREEN}Service Management:${NOCOLOR}"
log "${CYAN} - sudo systemctl status debros-node${NOCOLOR} (Check node status)"
log "${CYAN} - sudo systemctl status debros-gateway${NOCOLOR} (Check gateway status)"
log "${CYAN} - sudo systemctl restart debros-node${NOCOLOR} (Restart node)"
log "${CYAN} - sudo systemctl restart debros-gateway${NOCOLOR} (Restart gateway)"
log "${CYAN} - sudo systemctl stop debros-node${NOCOLOR} (Stop node)"
log "${CYAN} - sudo systemctl stop debros-gateway${NOCOLOR} (Stop gateway)"
log "${CYAN} - sudo journalctl -u debros-node.service -f${NOCOLOR} (View node logs)"
log "${CYAN} - sudo journalctl -u debros-gateway.service -f${NOCOLOR} (View gateway logs)"
log "${BLUE}==================================================${NOCOLOR}"
log "${GREEN}Verify Installation:${NOCOLOR}"
log "${CYAN} - Node health: curl http://127.0.0.1:5001/status${NOCOLOR}"
log "${CYAN} - Gateway health: curl http://127.0.0.1:6001/health${NOCOLOR}"
log "${CYAN} - Show bootstrap peer: cat $DEBROS_HOME/.debros/bootstrap/peer.info${NOCOLOR}"
log "${BLUE}==================================================${NOCOLOR}"
if [ "$UPDATE_MODE" = true ]; then
success "DeBros Network has been updated and is running!"
else