From 0421155594a92d2e9f6af23dedc1f3ff0c325f02 Mon Sep 17 00:00:00 2001 From: anonpenguin23 Date: Wed, 12 Nov 2025 10:07:40 +0200 Subject: [PATCH] refactor: improve Olric server configuration logic and enhance bootstrap peer handling - Updated the logic for determining Olric server addresses in the gateway configuration, differentiating between bootstrap and non-bootstrap nodes for better connectivity. - Introduced a new function to parse bootstrap host and port from the API URL, improving clarity and flexibility in handling different network configurations. - Enhanced the handling of IP protocols (IPv4 and IPv6) when constructing bootstrap peer addresses, ensuring compatibility across various network environments. --- CHANGELOG.md | 14 ++++++ Makefile | 2 +- pkg/environments/production/orchestrator.go | 41 ++++++++++++------ pkg/ipfs/cluster.go | 48 +++++++++++++++++++-- 4 files changed, 89 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0daf671..306a1f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,20 @@ The format is based on [Keep a Changelog][keepachangelog] and adheres to [Semant ### Deprecated ### Fixed +## [0.69.7] - 2025-11-12 + +### Added +\n +### Changed +- Improved logic for determining Olric server addresses during configuration generation, especially for bootstrap and non-bootstrap nodes. +- Enhanced IPFS cluster configuration to correctly handle IPv6 addresses when updating bootstrap peers. + +### Deprecated + +### Removed + +### Fixed +\n ## [0.69.6] - 2025-11-12 ### Added diff --git a/Makefile b/Makefile index f642e05..c1580ce 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,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.69.6 +VERSION := 0.69.7 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)' diff --git a/pkg/environments/production/orchestrator.go b/pkg/environments/production/orchestrator.go index 1577a79..be730c7 100644 --- a/pkg/environments/production/orchestrator.go +++ b/pkg/environments/production/orchestrator.go @@ -369,20 +369,36 @@ func (ps *ProductionSetup) Phase4GenerateConfigs(isBootstrap bool, bootstrapPeer } ps.logf(" ✓ Node config generated: %s", configFile) - // Gateway config - infer Olric servers from bootstrap peers or use localhost - olricServers := []string{"127.0.0.1:3320"} // Default to localhost for single-node - if len(bootstrapPeers) > 0 { - // Try to infer Olric servers from bootstrap peers - bootstrapIP := inferBootstrapIP(bootstrapPeers, vpsIP) - if bootstrapIP != "" { - // Add bootstrap Olric server (use net.JoinHostPort for IPv6 support) - olricServers = []string{net.JoinHostPort(bootstrapIP, "3320")} - // If this is not bootstrap and vpsIP is provided, add local Olric server too - if !isBootstrap && vpsIP != "" { - olricServers = append(olricServers, net.JoinHostPort(vpsIP, "3320")) + // Determine Olric servers for gateway config + // Olric will bind to 0.0.0.0 (all interfaces) but gateway needs specific addresses + var olricServers []string + + if isBootstrap { + // Bootstrap node: gateway should connect to vpsIP if provided, otherwise localhost + if vpsIP != "" { + olricServers = []string{net.JoinHostPort(vpsIP, "3320")} + } else { + olricServers = []string{"127.0.0.1:3320"} + } + } else { + // Non-bootstrap node: include bootstrap server and local server + olricServers = []string{"127.0.0.1:3320"} // Default to localhost for single-node + if len(bootstrapPeers) > 0 { + // Try to infer Olric servers from bootstrap peers + bootstrapIP := inferBootstrapIP(bootstrapPeers, vpsIP) + if bootstrapIP != "" { + // Add bootstrap Olric server (use net.JoinHostPort for IPv6 support) + olricServers = []string{net.JoinHostPort(bootstrapIP, "3320")} + // Add local Olric server too + if vpsIP != "" { + olricServers = append(olricServers, net.JoinHostPort(vpsIP, "3320")) + } else { + olricServers = append(olricServers, "127.0.0.1:3320") + } } } } + gatewayConfig, err := ps.configGenerator.GenerateGatewayConfig(bootstrapPeers, enableHTTPS, domain, olricServers) if err != nil { return fmt.Errorf("failed to generate gateway config: %w", err) @@ -393,7 +409,8 @@ func (ps *ProductionSetup) Phase4GenerateConfigs(isBootstrap bool, bootstrapPeer } ps.logf(" ✓ Gateway config generated") - // Olric config - use 0.0.0.0 to bind on all interfaces + // Olric config - bind to 0.0.0.0 to listen on all interfaces + // Gateway will connect using the specific address from olricServers list above olricConfig, err := ps.configGenerator.GenerateOlricConfig("0.0.0.0", 3320, 3322) if err != nil { return fmt.Errorf("failed to generate olric config: %w", err) diff --git a/pkg/ipfs/cluster.go b/pkg/ipfs/cluster.go index 2cbb972..effbee6 100644 --- a/pkg/ipfs/cluster.go +++ b/pkg/ipfs/cluster.go @@ -7,6 +7,7 @@ import ( "encoding/json" "fmt" "io" + "net" "net/http" "net/url" "os" @@ -232,15 +233,24 @@ func (cm *ClusterConfigManager) UpdateBootstrapPeers(bootstrapAPIURL string) err return nil } - // Extract bootstrap cluster port from URL - _, clusterPort, err := parseClusterPorts(bootstrapAPIURL) + // Extract bootstrap host and cluster port from URL + bootstrapHost, clusterPort, err := parseBootstrapHostAndPort(bootstrapAPIURL) if err != nil { return fmt.Errorf("failed to parse bootstrap cluster API URL: %w", err) } // Bootstrap listens on clusterPort + 2 (same pattern) bootstrapClusterPort := clusterPort + 2 - bootstrapPeerAddr := fmt.Sprintf("/ip4/127.0.0.1/tcp/%d/p2p/%s", bootstrapClusterPort, peerID) + + // Determine IP protocol (ip4 or ip6) based on the host + var ipProtocol string + if net.ParseIP(bootstrapHost).To4() != nil { + ipProtocol = "ip4" + } else { + ipProtocol = "ip6" + } + + bootstrapPeerAddr := fmt.Sprintf("/%s/%s/tcp/%d/p2p/%s", ipProtocol, bootstrapHost, bootstrapClusterPort, peerID) // Load current config serviceJSONPath := filepath.Join(cm.clusterPath, "service.json") @@ -467,6 +477,38 @@ func ensureRequiredSection(parent map[string]interface{}, key string, defaults m } } +// parseBootstrapHostAndPort extracts host and REST API port from bootstrap API URL +func parseBootstrapHostAndPort(bootstrapAPIURL string) (host string, restAPIPort int, err error) { + u, err := url.Parse(bootstrapAPIURL) + if err != nil { + return "", 0, err + } + + host = u.Hostname() + if host == "" { + return "", 0, fmt.Errorf("no host in URL: %s", bootstrapAPIURL) + } + + portStr := u.Port() + if portStr == "" { + // Default port based on scheme + if u.Scheme == "http" { + portStr = "9094" + } else if u.Scheme == "https" { + portStr = "443" + } else { + return "", 0, fmt.Errorf("unknown scheme: %s", u.Scheme) + } + } + + _, err = fmt.Sscanf(portStr, "%d", &restAPIPort) + if err != nil { + return "", 0, fmt.Errorf("invalid port: %s", portStr) + } + + return host, restAPIPort, nil +} + // parseClusterPorts extracts cluster port and REST API port from ClusterAPIURL func parseClusterPorts(clusterAPIURL string) (clusterPort, restAPIPort int, err error) { u, err := url.Parse(clusterAPIURL)