refactor: rename DeBros to Orama and update configuration paths

- Replaced all instances of DeBros with Orama throughout the codebase, including CLI commands and configuration paths.
- Updated documentation to reflect the new naming convention and paths for configuration files.
- Removed the outdated PRODUCTION_INSTALL.md file and added new scripts for local domain setup and testing.
- Introduced a new interactive TUI installer for Orama Network, enhancing the installation experience.
- Improved logging and error handling across various components to provide clearer feedback during operations.
This commit is contained in:
anonpenguin23 2025-11-26 16:14:19 +02:00
parent b983066016
commit d8994b1e4f
11 changed files with 128 additions and 125 deletions

View File

@ -13,6 +13,23 @@ The format is based on [Keep a Changelog][keepachangelog] and adheres to [Semant
### Deprecated
### Fixed
## [0.70.0] - 2025-11-26
### Added
\n
### Changed
- The HTTP Gateway is now embedded directly within each network node, simplifying deployment and removing the need for a separate gateway service.
- The configuration for the full API Gateway (including Auth, PubSub, and internal service routing) is now part of the main node configuration.
- Development environment setup no longer generates a separate `gateway.yaml` file or starts a standalone gateway process.
- Updated local environment descriptions and default gateway fallback to reflect the node-1 designation.
### Deprecated
### Removed
### Fixed
- Updated the installation instructions in the README to reflect the correct APT repository URL.
## [0.69.22] - 2025-11-26
### Added

View File

@ -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.22
VERSION := 0.70.0
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

@ -200,8 +200,8 @@ make build
```bash
# Install via APT
curl -fsSL https://apt.orama.network/gpg | sudo gpg --dearmor -o /usr/share/keyrings/orama.gpg
echo "deb [signed-by=/usr/share/keyrings/orama.gpg] https://apt.orama.network stable main" | sudo tee /etc/apt/sources.list.d/orama.list
echo "deb https://debrosficial.github.io/network/apt stable main" | sudo tee /etc/apt/sources.list.d/debros.list
sudo apt update && sudo apt install orama
# Interactive installation (recommended)

View File

@ -174,6 +174,6 @@ func getGatewayURL() string {
return env.GatewayURL
}
// Fallback to default
// Fallback to default (node-1)
return "http://localhost:6001"
}

View File

@ -28,7 +28,7 @@ var DefaultEnvironments = []Environment{
{
Name: "local",
GatewayURL: "http://localhost:6001",
Description: "Local development environment",
Description: "Local development environment (node-1)",
IsActive: true,
},
{

View File

@ -106,6 +106,15 @@ type HTTPGatewayConfig struct {
Routes map[string]RouteConfig `yaml:"routes"` // Service routes
HTTPS HTTPSConfig `yaml:"https"` // HTTPS/TLS configuration
SNI SNIConfig `yaml:"sni"` // SNI-based TCP routing configuration
// Full gateway configuration (for API, auth, pubsub)
ClientNamespace string `yaml:"client_namespace"` // Namespace for network client
RQLiteDSN string `yaml:"rqlite_dsn"` // RQLite database DSN
OlricServers []string `yaml:"olric_servers"` // List of Olric server addresses
OlricTimeout time.Duration `yaml:"olric_timeout"` // Timeout for Olric operations
IPFSClusterAPIURL string `yaml:"ipfs_cluster_api_url"` // IPFS Cluster API URL
IPFSAPIURL string `yaml:"ipfs_api_url"` // IPFS API URL
IPFSTimeout time.Duration `yaml:"ipfs_timeout"` // Timeout for IPFS operations
}
// HTTPSConfig contains HTTPS/TLS configuration for the gateway
@ -216,10 +225,17 @@ func DefaultConfig() *Config {
Format: "console",
},
HTTPGateway: HTTPGatewayConfig{
Enabled: true,
ListenAddr: ":8080",
NodeName: "default",
Routes: make(map[string]RouteConfig),
Enabled: true,
ListenAddr: ":8080",
NodeName: "default",
Routes: make(map[string]RouteConfig),
ClientNamespace: "default",
RQLiteDSN: "http://localhost:5001",
OlricServers: []string{"localhost:3320"},
OlricTimeout: 10 * time.Second,
IPFSClusterAPIURL: "http://localhost:9094",
IPFSAPIURL: "http://localhost:5001",
IPFSTimeout: 60 * time.Second,
},
}
}

View File

@ -62,10 +62,8 @@ func (ce *ConfigEnsurer) EnsureAll() error {
}
}
// Ensure gateway config
if err := ce.ensureGateway(peerAddrs); err != nil {
return fmt.Errorf("failed to ensure gateway: %w", err)
}
// Gateway configuration is now embedded in each node's config
// No separate gateway.yaml needed anymore
// Ensure Olric config
if err := ce.ensureOlric(); err != nil {
@ -171,34 +169,8 @@ func (ce *ConfigEnsurer) ensureNodeConfig(nodeSpec NodeSpec, peerAddrs []string)
return nil
}
// ensureGateway creates gateway config
func (ce *ConfigEnsurer) ensureGateway(peerAddrs []string) error {
configPath := filepath.Join(ce.oramaDir, "gateway.yaml")
// Get first node's cluster API port for default
topology := DefaultTopology()
firstNode := topology.GetFirstNode()
data := templates.GatewayConfigData{
ListenPort: topology.GatewayPort,
BootstrapPeers: peerAddrs,
OlricServers: []string{fmt.Sprintf("127.0.0.1:%d", topology.OlricHTTPPort)},
ClusterAPIPort: firstNode.ClusterAPIPort,
IPFSAPIPort: firstNode.IPFSAPIPort,
}
config, err := templates.RenderGatewayConfig(data)
if err != nil {
return fmt.Errorf("failed to render gateway config: %w", err)
}
if err := os.WriteFile(configPath, []byte(config), 0644); err != nil {
return fmt.Errorf("failed to write gateway config: %w", err)
}
fmt.Printf("✓ Generated gateway.yaml\n")
return nil
}
// Gateway configuration is now embedded in each node's config
// ensureGateway is no longer needed - each node runs its own embedded gateway
// ensureOlric creates Olric config
func (ce *ConfigEnsurer) ensureOlric() error {

View File

@ -67,7 +67,7 @@ func (pm *ProcessManager) StartAll(ctx context.Context) error {
{"Olric", pm.startOlric},
{"Anon", pm.startAnon},
{"Nodes (Network)", pm.startNodes},
{"Gateway", pm.startGateway},
// Gateway is now per-node (embedded in each node) - no separate main gateway needed
}
for _, svc := range services {
@ -238,7 +238,7 @@ func (pm *ProcessManager) Status(ctx context.Context) {
}
fmt.Fprintf(pm.logWriter, "\nConfiguration files in %s:\n", pm.oramaDir)
configFiles := []string{"node-1.yaml", "node-2.yaml", "node-3.yaml", "node-4.yaml", "node-5.yaml", "gateway.yaml", "olric-config.yaml"}
configFiles := []string{"node-1.yaml", "node-2.yaml", "node-3.yaml", "node-4.yaml", "node-5.yaml", "olric-config.yaml"}
for _, f := range configFiles {
path := filepath.Join(pm.oramaDir, f)
if _, err := os.Stat(path); err == nil {

View File

@ -3,7 +3,6 @@ package production
import (
"fmt"
"io"
"net"
"os"
"os/exec"
"path/filepath"
@ -376,34 +375,8 @@ func (ps *ProductionSetup) Phase4GenerateConfigs(peerAddresses []string, vpsIP s
}
ps.logf(" ✓ Node config generated: %s", configFile)
// Determine Olric servers for gateway config
// Olric binds to localhost, gateway connects locally
var olricServers []string
// Start with local Olric server
if vpsIP != "" {
olricServers = []string{net.JoinHostPort(vpsIP, "3320")}
} else {
olricServers = []string{"127.0.0.1:3320"}
}
// If joining existing cluster, also include peer Olric servers
if len(peerAddresses) > 0 {
peerIP := inferPeerIP(peerAddresses, "")
if peerIP != "" && peerIP != vpsIP {
olricServers = append(olricServers, net.JoinHostPort(peerIP, "3320"))
}
}
gatewayConfig, err := ps.configGenerator.GenerateGatewayConfig(peerAddresses, enableHTTPS, domain, olricServers)
if err != nil {
return fmt.Errorf("failed to generate gateway config: %w", err)
}
if err := ps.secretGenerator.SaveConfig("gateway.yaml", gatewayConfig); err != nil {
return fmt.Errorf("failed to save gateway config: %w", err)
}
ps.logf(" ✓ Gateway config generated")
// Gateway configuration is now embedded in each node's config
// No separate gateway.yaml needed - each node runs its own embedded gateway
// Olric config - bind to localhost for security
// External access goes through the HTTP gateway
@ -472,19 +445,12 @@ func (ps *ProductionSetup) Phase5CreateSystemdServices() error {
}
ps.logf(" ✓ Olric service created")
// Node service (unified)
// Node service (unified - includes embedded gateway)
nodeUnit := ps.serviceGenerator.GenerateNodeService()
if err := ps.serviceController.WriteServiceUnit("debros-node.service", nodeUnit); err != nil {
return fmt.Errorf("failed to write Node service: %w", err)
}
ps.logf(" ✓ Node service created: debros-node.service")
// Gateway service
gatewayUnit := ps.serviceGenerator.GenerateGatewayService()
if err := ps.serviceController.WriteServiceUnit("debros-gateway.service", gatewayUnit); err != nil {
return fmt.Errorf("failed to write Gateway service: %w", err)
}
ps.logf(" ✓ Gateway service created")
ps.logf(" ✓ Node service created: debros-node.service (with embedded gateway)")
// Anyone Client service (SOCKS5 proxy)
anyoneUnit := ps.serviceGenerator.GenerateAnyoneClientService()
@ -500,7 +466,8 @@ func (ps *ProductionSetup) Phase5CreateSystemdServices() error {
ps.logf(" ✓ Systemd daemon reloaded")
// Enable services (unified names - no bootstrap/node distinction)
services := []string{"debros-ipfs.service", "debros-ipfs-cluster.service", "debros-olric.service", "debros-node.service", "debros-gateway.service", "debros-anyone-client.service"}
// Note: debros-gateway.service is no longer needed - each node has an embedded gateway
services := []string{"debros-ipfs.service", "debros-ipfs-cluster.service", "debros-olric.service", "debros-node.service", "debros-anyone-client.service"}
for _, svc := range services {
if err := ps.serviceController.EnableService(svc); err != nil {
ps.logf(" ⚠️ Failed to enable %s: %v", svc, err)

View File

@ -46,30 +46,16 @@ http_gateway:
enabled: true
listen_addr: ":{{.UnifiedGatewayPort}}"
node_name: "{{.NodeID}}"
routes:
# Node internal services - accessible on unified gateway port
rqlite_http:
path_prefix: "/rqlite/http"
backend_url: "http://localhost:{{.RQLiteHTTPPort}}"
timeout: "30s"
websocket: false
rqlite_raft:
path_prefix: "/rqlite/raft"
backend_url: "http://localhost:{{.RQLiteRaftPort}}"
timeout: "30s"
websocket: false
ipfs_api:
path_prefix: "/ipfs/api"
backend_url: "http://localhost:{{.IPFSAPIPort}}"
timeout: "60s"
websocket: true
ipfs_swarm:
path_prefix: "/ipfs/swarm"
backend_url: "http://localhost:4102"
timeout: "30s"
websocket: false
cluster_api:
path_prefix: "/cluster"
backend_url: "http://localhost:{{.ClusterAPIPort}}"
timeout: "30s"
websocket: false
# Full gateway configuration (for API, auth, pubsub, and internal service routing)
client_namespace: "default"
rqlite_dsn: "http://localhost:{{.RQLiteHTTPPort}}"
olric_servers:
- "127.0.0.1:3320"
olric_timeout: "10s"
ipfs_cluster_api_url: "http://localhost:{{.ClusterAPIPort}}"
ipfs_api_url: "http://localhost:{{.IPFSAPIPort}}"
ipfs_timeout: "60s"
# Routes for internal service reverse proxy (kept for backwards compatibility but not used by full gateway)
routes: {}

View File

@ -5,6 +5,7 @@ import (
"fmt"
mathrand "math/rand"
"net"
"net/http"
"os"
"path/filepath"
"strings"
@ -52,8 +53,9 @@ type Node struct {
// IPFS Cluster config manager
clusterConfigManager *ipfs.ClusterConfigManager
// HTTP reverse proxy gateway
httpGateway *gateway.HTTPGateway
// Full gateway (for API, auth, pubsub, and internal service routing)
apiGateway *gateway.Gateway
apiGatewayServer *http.Server
}
// NewNode creates a new network node
@ -632,9 +634,16 @@ func (n *Node) stopPeerDiscovery() {
func (n *Node) Stop() error {
n.logger.ComponentInfo(logging.ComponentNode, "Stopping network node")
// Stop HTTP Gateway
if n.httpGateway != nil {
_ = n.httpGateway.Stop()
// Stop HTTP Gateway server
if n.apiGatewayServer != nil {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
_ = n.apiGatewayServer.Shutdown(ctx)
}
// Close Gateway client
if n.apiGateway != nil {
n.apiGateway.Close()
}
// Stop cluster discovery
@ -667,14 +676,14 @@ func (n *Node) Stop() error {
return nil
}
// startHTTPGateway initializes and starts the HTTP reverse proxy gateway
// startHTTPGateway initializes and starts the full API gateway with auth, pubsub, and API endpoints
func (n *Node) startHTTPGateway(ctx context.Context) error {
if !n.config.HTTPGateway.Enabled {
n.logger.ComponentInfo(logging.ComponentNode, "HTTP Gateway disabled in config")
return nil
}
// Create separate logger for unified gateway
// Create separate logger for gateway
logFile := filepath.Join(os.ExpandEnv(n.config.Node.DataDir), "..", "logs", fmt.Sprintf("gateway-%s.log", n.config.HTTPGateway.NodeName))
// Ensure logs directory exists
@ -683,21 +692,57 @@ func (n *Node) startHTTPGateway(ctx context.Context) error {
return fmt.Errorf("failed to create logs directory: %w", err)
}
httpGatewayLogger, err := logging.NewFileLogger(logging.ComponentGeneral, logFile, false)
gatewayLogger, err := logging.NewFileLogger(logging.ComponentGeneral, logFile, false)
if err != nil {
return fmt.Errorf("failed to create HTTP gateway logger: %w", err)
return fmt.Errorf("failed to create gateway logger: %w", err)
}
// Create and start HTTP gateway with its own logger
n.httpGateway, err = gateway.NewHTTPGateway(httpGatewayLogger, &n.config.HTTPGateway)
if err != nil {
return fmt.Errorf("failed to create HTTP gateway: %w", err)
// Create full API Gateway for auth, pubsub, rqlite, and API endpoints
// This replaces both the old reverse proxy gateway and the standalone gateway
gwCfg := &gateway.Config{
ListenAddr: n.config.HTTPGateway.ListenAddr,
ClientNamespace: n.config.HTTPGateway.ClientNamespace,
BootstrapPeers: n.config.Discovery.BootstrapPeers,
RQLiteDSN: n.config.HTTPGateway.RQLiteDSN,
OlricServers: n.config.HTTPGateway.OlricServers,
OlricTimeout: n.config.HTTPGateway.OlricTimeout,
IPFSClusterAPIURL: n.config.HTTPGateway.IPFSClusterAPIURL,
IPFSAPIURL: n.config.HTTPGateway.IPFSAPIURL,
IPFSTimeout: n.config.HTTPGateway.IPFSTimeout,
}
// Start gateway in a goroutine (it handles its own lifecycle)
apiGateway, err := gateway.New(gatewayLogger, gwCfg)
if err != nil {
return fmt.Errorf("failed to create full API gateway: %w", err)
}
n.apiGateway = apiGateway
// Start API Gateway in a goroutine
go func() {
if err := n.httpGateway.Start(ctx); err != nil {
n.logger.ComponentError(logging.ComponentNode, "HTTP Gateway error", zap.Error(err))
n.logger.ComponentInfo(logging.ComponentNode, "Starting full API gateway",
zap.String("listen_addr", gwCfg.ListenAddr),
)
server := &http.Server{
Addr: gwCfg.ListenAddr,
Handler: apiGateway.Routes(),
}
n.apiGatewayServer = server
// Try to bind listener
ln, err := net.Listen("tcp", gwCfg.ListenAddr)
if err != nil {
n.logger.ComponentError(logging.ComponentNode, "failed to bind API gateway listener", zap.Error(err))
return
}
n.logger.ComponentInfo(logging.ComponentNode, "API gateway listener bound", zap.String("listen_addr", ln.Addr().String()))
// Serve HTTP
if err := server.Serve(ln); err != nil && err != http.ErrServerClosed {
n.logger.ComponentError(logging.ComponentNode, "API Gateway error", zap.Error(err))
}
}()