feat: update IPFS configuration and enhance cluster secret management

- Changed default IPFS API URL to port 5001 for better compatibility.
- Enhanced the initialization process for IPFS and Cluster by adding support for bootstrap peers.
- Introduced user prompts for cluster secret and swarm key generation, improving user experience during setup.
- Updated service configuration to dynamically determine paths based on existing configuration files.
This commit is contained in:
anonpenguin23 2025-11-08 13:29:21 +02:00
parent a5c30d0141
commit c726dfc401
4 changed files with 277 additions and 32 deletions

View File

@ -13,6 +13,25 @@ The format is based on [Keep a Changelog][keepachangelog] and adheres to [Semant
### Deprecated
### Fixed
## [0.59.2] - 2025-11-08
### Added
- Added health checks to the installation script to verify the gateway and node services are running after setup or upgrade.
- The installation script now attempts to verify the downloaded binary using checksums.txt if available.
- Added checks in the CLI setup to ensure systemd is available before attempting to create service files.
### Changed
- Improved the installation script to detect existing installations, stop services before upgrading, and restart them afterward to minimize downtime.
- Enhanced the CLI setup process by detecting the VPS IP address earlier and improving validation feedback for cluster secrets and swarm keys.
- Modified directory setup to log warnings instead of exiting if `chown` fails, providing manual instructions for fixing ownership issues.
- Improved the HTTPS configuration flow to check for port 80/443 availability before prompting for a domain name.
### Deprecated
### Removed
### Fixed
\n
## [0.59.1] - 2025-11-08
### Added

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 install-hooks kill
VERSION := 0.59.1
VERSION := 0.59.2
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)'

View File

@ -1273,9 +1273,12 @@ func setupDirectories() {
fmt.Fprintf(os.Stderr, "❌ Failed to create %s: %v\n", dir, err)
os.Exit(1)
}
// Change ownership to debros
// Change ownership to debros (log failures but continue)
cmd := exec.Command("chown", "-R", "debros:debros", dir)
cmd.Run()
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "⚠️ Failed to set ownership for %s: %v\n", dir, err)
fmt.Fprintf(os.Stderr, " This may cause permission issues - consider running: sudo chown -R debros:debros %s\n", dir)
}
}
fmt.Printf(" ✓ Directories created\n")
@ -1373,6 +1376,16 @@ func generateConfigsInteractive(force bool) {
gatewayExists = true
}
// Get VPS IP early for port checking
vpsIP, err := getVPSIPv4Address()
if err != nil {
fmt.Fprintf(os.Stderr, "⚠️ Failed to detect IPv4 address: %v\n", err)
fmt.Fprintf(os.Stderr, " Using 0.0.0.0 as fallback. You may need to edit config files manually.\n")
vpsIP = "0.0.0.0"
} else {
fmt.Printf(" ✓ Detected IPv4 address: %s\n\n", vpsIP)
}
// If both configs exist and not forcing, skip configuration prompts
if nodeExists && gatewayExists && !force {
fmt.Printf(" Configuration files already exist (node.yaml and gateway.yaml)\n")
@ -1432,23 +1445,16 @@ func generateConfigsInteractive(force bool) {
return
}
// Get VPS IPv4 address
fmt.Printf("Detecting VPS IPv4 address...\n")
vpsIP, err := getVPSIPv4Address()
if err != nil {
fmt.Fprintf(os.Stderr, "⚠️ Failed to detect IPv4 address: %v\n", err)
fmt.Fprintf(os.Stderr, " Using 0.0.0.0 as fallback. You may need to edit config files manually.\n")
vpsIP = "0.0.0.0"
} else {
fmt.Printf(" ✓ Detected IPv4 address: %s\n\n", vpsIP)
}
// Create reader for prompts
reader := bufio.NewReader(os.Stdin)
// vpsIP was already obtained earlier, continue with configuration
// Ask about node type
fmt.Printf("What type of node is this?\n")
fmt.Printf(" 1. Bootstrap node (cluster leader)\n")
fmt.Printf(" 2. Regular node (joins existing cluster)\n")
fmt.Printf("Enter choice (1 or 2): ")
reader := bufio.NewReader(os.Stdin)
choice, _ := reader.ReadString('\n')
choice = strings.ToLower(strings.TrimSpace(choice))
@ -1563,7 +1569,8 @@ func generateConfigsInteractive(force bool) {
response = strings.ToLower(strings.TrimSpace(response))
if response == "yes" || response == "y" {
// Check if ports 80 and 443 are available
// Check if ports 80 and 443 are available BEFORE proceeding
fmt.Printf("\n Checking if ports 80 and 443 are available...\n")
portsAvailable, portIssues := checkPorts80And443()
if !portsAvailable {
fmt.Fprintf(os.Stderr, "\n⚠ Cannot enable HTTPS: %s is already in use\n", portIssues)
@ -1571,6 +1578,7 @@ func generateConfigsInteractive(force bool) {
fmt.Fprintf(os.Stderr, " Continuing without HTTPS configuration...\n\n")
enableHTTPS = false
} else {
fmt.Printf(" ✓ Ports 80 and 443 are available\n")
// Prompt for domain name
domain = promptDomainForHTTPS(reader, vpsIP)
if domain != "" {
@ -1873,7 +1881,7 @@ func promptClusterSecret(reader *bufio.Reader) (string, error) {
// Validate input (must be 64 hex characters)
input = strings.ToUpper(input)
if len(input) != 64 {
fmt.Printf(" ❌ Invalid: cluster secret must be exactly 64 hex characters\n")
fmt.Printf(" ❌ Invalid: cluster secret must be exactly 64 hex characters (got %d)\n", len(input))
continue
}
@ -1890,6 +1898,7 @@ func promptClusterSecret(reader *bufio.Reader) (string, error) {
continue
}
fmt.Printf(" ✓ Cluster secret validated (length: %d, all hex)\n", len(input))
return input, nil
}
}
@ -1952,7 +1961,7 @@ func promptSwarmKey(reader *bufio.Reader) ([]byte, error) {
// Validate input (must be 64 hex characters)
input = strings.ToUpper(input)
if len(input) != 64 {
fmt.Printf(" ❌ Invalid: swarm key must be exactly 64 hex characters\n")
fmt.Printf(" ❌ Invalid: swarm key must be exactly 64 hex characters (got %d)\n", len(input))
continue
}
@ -1970,6 +1979,7 @@ func promptSwarmKey(reader *bufio.Reader) ([]byte, error) {
}
// Format as IPFS swarm key file
fmt.Printf(" ✓ Swarm key validated (length: %d, all hex)\n", len(input))
content := fmt.Sprintf("/key/swarm/psk/1.0.0/\n/base16/\n%s\n", input)
return []byte(content), nil
}
@ -2281,6 +2291,14 @@ func generateClusterServiceConfig(nodeID, vpsIP, secret string, isBootstrap bool
func createSystemdServices() {
fmt.Printf("🔧 Creating systemd services...\n")
// Check if systemd is available
if _, err := os.Stat("/etc/systemd"); os.IsNotExist(err) {
fmt.Fprintf(os.Stderr, "⚠️ systemd not detected on this system\n")
fmt.Fprintf(os.Stderr, " Systemd service files cannot be created on non-systemd systems\n")
fmt.Fprintf(os.Stderr, " Please manually start services or use an alternative init system\n")
return
}
// IPFS service (runs on all nodes)
// Determine IPFS path based on config file
var ipfsPath string

View File

@ -11,7 +11,7 @@
# bash scripts/install-debros-network.sh
set -e
trap 'echo -e "${RED}An error occurred. Installation aborted.${NOCOLOR}"; exit 1' ERR
trap 'error "An error occurred. Installation aborted."; execute_traps; exit 1' ERR
# Color codes
RED='\033[0;31m'
@ -26,10 +26,33 @@ GITHUB_REPO="DeBrosOfficial/network"
GITHUB_API="https://api.github.com/repos/$GITHUB_REPO"
INSTALL_DIR="/usr/local/bin"
# Upgrade detection flags
PREVIOUS_INSTALL=false
SETUP_EXECUTED=false
PREVIOUS_VERSION=""
LATEST_VERSION=""
VERSION_CHANGED=false
# Cleanup handlers (for proper trap stacking)
declare -a CLEANUP_HANDLERS
log() { echo -e "${CYAN}[$(date '+%Y-%m-%d %H:%M:%S')]${NOCOLOR} $1"; }
error() { echo -e "${RED}[ERROR]${NOCOLOR} $1"; }
error() { echo -e "${RED}[ERROR]${NOCOLOR} $1" >&2; }
success() { echo -e "${GREEN}[SUCCESS]${NOCOLOR} $1"; }
warning() { echo -e "${YELLOW}[WARNING]${NOCOLOR} $1"; }
warning() { echo -e "${YELLOW}[WARNING]${NOCOLOR} $1" >&2; }
# Stack-based trap cleanup
push_trap() {
local handler="$1"
local signal="${2:-EXIT}"
CLEANUP_HANDLERS+=("$handler")
}
execute_traps() {
for ((i=${#CLEANUP_HANDLERS[@]}-1; i>=0; i--)); do
eval "${CLEANUP_HANDLERS[$i]}"
done
}
# REQUIRE INTERACTIVE MODE
if [ ! -t 0 ]; then
@ -133,13 +156,21 @@ check_dependencies() {
get_latest_release() {
log "Fetching latest release information..."
# Get latest release (exclude pre-releases and nightly)
# Check if jq is available for robust JSON parsing
if command -v jq &>/dev/null; then
# Use jq for structured JSON parsing
LATEST_RELEASE=$(curl -fsSL -H "Accept: application/vnd.github+json" "$GITHUB_API/releases" | \
jq -r '.[] | select(.prerelease == false and .draft == false) | .tag_name' | head -1)
else
# Fallback to grep-based parsing
log "Note: jq not available, using basic parsing (consider installing jq for robustness)"
LATEST_RELEASE=$(curl -fsSL "$GITHUB_API/releases" | \
grep -v "prerelease.*true" | \
grep -v "draft.*true" | \
grep '"tag_name"' | \
head -1 | \
cut -d'"' -f4)
fi
if [ -z "$LATEST_RELEASE" ]; then
error "Could not determine latest release"
@ -154,10 +185,11 @@ download_and_install() {
# Construct download URL
DOWNLOAD_URL="https://github.com/$GITHUB_REPO/releases/download/$LATEST_RELEASE/debros-network_${LATEST_RELEASE#v}_linux_${GITHUB_ARCH}.tar.gz"
CHECKSUM_URL="https://github.com/$GITHUB_REPO/releases/download/$LATEST_RELEASE/checksums.txt"
# Create temporary directory
TEMP_DIR=$(mktemp -d)
trap "rm -rf $TEMP_DIR" EXIT
push_trap "rm -rf $TEMP_DIR" EXIT
# Download
log "Downloading from: $DOWNLOAD_URL"
@ -166,6 +198,24 @@ download_and_install() {
exit 1
fi
# Try to download and verify checksum
CHECKSUM_FILE="$TEMP_DIR/checksums.txt"
if curl -fsSL -o "$CHECKSUM_FILE" "$CHECKSUM_URL" 2>/dev/null; then
log "Verifying checksum..."
cd "$TEMP_DIR"
if command -v sha256sum &>/dev/null; then
if sha256sum -c "$CHECKSUM_FILE" --ignore-missing >/dev/null 2>&1; then
success "Checksum verified"
else
warning "Checksum verification failed (continuing anyway)"
fi
else
log "sha256sum not available, skipping checksum verification"
fi
else
log "Checksums not available for this release (continuing without verification)"
fi
# Extract
log "Extracting network-cli..."
cd "$TEMP_DIR"
@ -179,6 +229,51 @@ download_and_install() {
success "network-cli installed successfully"
}
check_existing_installation() {
if command -v network-cli &>/dev/null 2>&1; then
PREVIOUS_INSTALL=true
PREVIOUS_VERSION=$(network-cli version 2>/dev/null | head -n1 || echo "unknown")
echo -e ""
echo -e "${YELLOW}⚠️ Existing installation detected: ${PREVIOUS_VERSION}${NOCOLOR}"
echo -e ""
# Version will be compared after fetching latest release
# If they match, we skip the service stop/restart to minimize downtime
else
log "No previous installation detected - performing fresh install"
fi
}
compare_versions() {
# Compare previous and latest versions
if [ "$PREVIOUS_INSTALL" = true ] && [ ! -z "$PREVIOUS_VERSION" ] && [ ! -z "$LATEST_VERSION" ]; then
if [ "$PREVIOUS_VERSION" = "$LATEST_VERSION" ]; then
VERSION_CHANGED=false
log "Installed version ($PREVIOUS_VERSION) matches latest release ($LATEST_VERSION)"
log "Skipping service restart - no upgrade needed"
return 0
else
VERSION_CHANGED=true
log "Version change detected: $PREVIOUS_VERSION$LATEST_VERSION"
log "Services will be stopped before updating."
echo -e ""
# Check if services are running
if sudo network-cli service status all >/dev/null 2>&1; then
log "Stopping DeBros services before upgrade..."
log "Note: Anon (if running) will not be stopped as it may be managed separately"
if sudo network-cli service stop all; then
success "DeBros services stopped successfully"
else
warning "Failed to stop some services (continuing anyway)"
fi
else
log "DeBros services already stopped or not running"
fi
fi
fi
}
verify_installation() {
if command -v network-cli &>/dev/null; then
INSTALLED_VERSION=$(network-cli version 2>/dev/null || echo "unknown")
@ -190,6 +285,28 @@ verify_installation() {
fi
}
# Check if port 9050 is in use (Anon SOCKS port)
is_anon_running() {
# Check if port 9050 is listening
if command -v ss &>/dev/null; then
if ss -tlnp 2>/dev/null | grep -q ":9050"; then
return 0
fi
elif command -v netstat &>/dev/null; then
if netstat -tlnp 2>/dev/null | grep -q ":9050"; then
return 0
fi
elif command -v lsof &>/dev/null; then
# Try to check without sudo first (in case of passwordless sudo issues)
if sudo -n lsof -i :9050 >/dev/null 2>&1; then
return 0
fi
fi
# Fallback: assume Anon is not running if we can't determine
return 1
}
install_anon() {
echo -e ""
echo -e "${BLUE}========================================${NOCOLOR}"
@ -197,16 +314,28 @@ install_anon() {
echo -e "${BLUE}========================================${NOCOLOR}"
echo -e ""
log "Installing Anyone relay for anonymous networking..."
log "Checking Anyone relay (Anon) status..."
# Check if anon is already installed
if command -v anon &>/dev/null; then
success "Anon already installed"
# Check if Anon is already running on port 9050
if is_anon_running; then
success "Anon is already running on port 9050"
log "Skipping Anon installation - using existing instance"
configure_anon_logs
configure_firewall_for_anon
return 0
fi
# Check if anon binary is already installed
if command -v anon &>/dev/null; then
success "Anon binary already installed"
log "Anon is installed but not running. You can start it manually if needed."
configure_anon_logs
configure_firewall_for_anon
return 0
fi
log "Installing Anyone relay for anonymous networking..."
# Install via APT (official method from docs.anyone.io)
log "Adding Anyone APT repository..."
@ -471,9 +600,47 @@ run_setup() {
echo -e ""
log "Running setup (requires sudo)..."
SETUP_EXECUTED=true
sudo network-cli setup
}
perform_health_check() {
echo -e ""
echo -e "${BLUE}========================================${NOCOLOR}"
log "Performing post-install health checks..."
echo -e "${BLUE}========================================${NOCOLOR}"
echo -e ""
local health_ok=true
# Give services a moment to start if they were just restarted
sleep 2
# Check gateway health
if curl -sf http://localhost:6001/health >/dev/null 2>&1; then
success "Gateway health check passed"
else
warning "Gateway health check failed - check logs with: sudo network-cli service logs gateway"
health_ok=false
fi
# Check if node is running (may not respond immediately)
if sudo network-cli service status node >/dev/null 2>&1; then
success "Node service is running"
else
warning "Node service is not running - check with: sudo network-cli service status node"
health_ok=false
fi
echo -e ""
if [ "$health_ok" = true ]; then
success "All health checks passed!"
else
warning "Some health checks failed - review logs and start services if needed"
fi
echo -e ""
}
show_completion() {
echo -e ""
echo -e "${BLUE}========================================================================${NOCOLOR}"
@ -496,6 +663,11 @@ show_completion() {
echo -e " • View Anon logs: ${CYAN}sudo tail -f /home/debros/.debros/logs/anon/notices.log${NOCOLOR}"
echo -e " • Proxy endpoint: ${CYAN}POST http://localhost:6001/v1/proxy/anon${NOCOLOR}"
echo -e ""
echo -e "${CYAN}🔐 Shared Secrets (for adding more nodes):${NOCOLOR}"
echo -e " • Swarm key: ${CYAN}cat /home/debros/.debros/swarm.key${NOCOLOR}"
echo -e " • Cluster secret: ${CYAN}sudo cat /home/debros/.debros/cluster-secret${NOCOLOR}"
echo -e " • Copy these to bootstrap node before setting up secondary nodes${NOCOLOR}"
echo -e ""
echo -e "${CYAN}Documentation: https://docs.debros.io${NOCOLOR}"
echo -e ""
}
@ -507,6 +679,9 @@ main() {
log "Starting DeBros Network installation..."
echo -e ""
# Check for existing installation and stop services if needed
check_existing_installation
detect_os
check_architecture
check_dependencies
@ -518,6 +693,11 @@ main() {
echo -e ""
get_latest_release
LATEST_VERSION="$LATEST_RELEASE"
# Compare versions and determine if upgrade is needed
compare_versions
download_and_install
# Verify installation
@ -531,6 +711,34 @@ main() {
# Run setup
run_setup
# If this was an upgrade and setup wasn't run, restart services
if [ "$PREVIOUS_INSTALL" = true ] && [ "$VERSION_CHANGED" = true ] && [ "$SETUP_EXECUTED" = false ]; then
echo -e ""
log "Restarting services that were stopped earlier..."
# Check services individually and provide detailed feedback
failed_services=()
if ! sudo network-cli service start all 2>&1 | tee /tmp/service-start.log; then
# Parse which services failed
while IFS= read -r line; do
if [[ $line =~ "Failed to start" ]]; then
service_name=$(echo "$line" | grep -oP '(?<=Failed to start\s)\S+(?=:)' || echo "unknown")
failed_services+=("$service_name")
fi
done < /tmp/service-start.log
if [ ${#failed_services[@]} -gt 0 ]; then
error "Failed to restart: ${failed_services[*]}"
error "Please check service status: sudo network-cli service status all"
fi
else
success "Services restarted successfully"
fi
fi
# Post-install health check
perform_health_check
# Show completion message
show_completion
}