mirror of
https://github.com/DeBrosOfficial/network.git
synced 2026-01-30 16:03:02 +00:00
- Updated the API gateway documentation to reflect changes in architecture and functionality, emphasizing its role as a multi-functional entry point for decentralized services. - Refactored CLI commands to utilize utility functions for better code organization and maintainability. - Introduced new utility functions for handling peer normalization, service management, and port validation, enhancing the overall CLI experience. - Added a new production installation script to streamline the setup process for users, including detailed dry-run summaries for better visibility. - Enhanced validation mechanisms for configuration files and swarm keys, ensuring robust error handling and user feedback during setup.
99 lines
3.3 KiB
Go
99 lines
3.3 KiB
Go
package node
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
database "github.com/DeBrosOfficial/network/pkg/rqlite"
|
|
"go.uber.org/zap"
|
|
"time"
|
|
)
|
|
|
|
// startRQLite initializes and starts the RQLite database
|
|
func (n *Node) startRQLite(ctx context.Context) error {
|
|
n.logger.Info("Starting RQLite database")
|
|
|
|
// Determine node identifier for log filename - use node ID for unique filenames
|
|
nodeID := n.config.Node.ID
|
|
if nodeID == "" {
|
|
// Default to "node" if ID is not set
|
|
nodeID = "node"
|
|
}
|
|
|
|
// Create RQLite manager
|
|
n.rqliteManager = database.NewRQLiteManager(&n.config.Database, &n.config.Discovery, n.config.Node.DataDir, n.logger.Logger)
|
|
n.rqliteManager.SetNodeType(nodeID)
|
|
|
|
// Initialize cluster discovery service if LibP2P host is available
|
|
if n.host != nil && n.discoveryManager != nil {
|
|
// Create cluster discovery service (all nodes are unified)
|
|
n.clusterDiscovery = database.NewClusterDiscoveryService(
|
|
n.host,
|
|
n.discoveryManager,
|
|
n.rqliteManager,
|
|
n.config.Node.ID,
|
|
"node", // Unified node type
|
|
n.config.Discovery.RaftAdvAddress,
|
|
n.config.Discovery.HttpAdvAddress,
|
|
n.config.Node.DataDir,
|
|
n.logger.Logger,
|
|
)
|
|
|
|
// Set discovery service on RQLite manager BEFORE starting RQLite
|
|
// This is critical for pre-start cluster discovery during recovery
|
|
n.rqliteManager.SetDiscoveryService(n.clusterDiscovery)
|
|
|
|
// Start cluster discovery (but don't trigger initial sync yet)
|
|
if err := n.clusterDiscovery.Start(ctx); err != nil {
|
|
return fmt.Errorf("failed to start cluster discovery: %w", err)
|
|
}
|
|
|
|
// Publish initial metadata (with log_index=0) so peers can discover us during recovery
|
|
// The metadata will be updated with actual log index after RQLite starts
|
|
n.clusterDiscovery.UpdateOwnMetadata()
|
|
|
|
n.logger.Info("Cluster discovery service started (waiting for RQLite)")
|
|
}
|
|
|
|
// If node-to-node TLS is configured, wait for certificates to be provisioned
|
|
// This ensures RQLite can start with TLS when joining through the SNI gateway
|
|
if n.config.Database.NodeCert != "" && n.config.Database.NodeKey != "" && n.certReady != nil {
|
|
n.logger.Info("RQLite node TLS configured, waiting for certificates to be provisioned...",
|
|
zap.String("node_cert", n.config.Database.NodeCert),
|
|
zap.String("node_key", n.config.Database.NodeKey))
|
|
|
|
// Wait for certificate ready signal with timeout
|
|
certTimeout := 5 * time.Minute
|
|
select {
|
|
case <-n.certReady:
|
|
n.logger.Info("Certificates ready, proceeding with RQLite startup")
|
|
case <-time.After(certTimeout):
|
|
return fmt.Errorf("timeout waiting for TLS certificates after %v - ensure HTTPS is configured and ports 80/443 are accessible for ACME challenges", certTimeout)
|
|
case <-ctx.Done():
|
|
return fmt.Errorf("context cancelled while waiting for certificates: %w", ctx.Err())
|
|
}
|
|
}
|
|
|
|
// Start RQLite FIRST before updating metadata
|
|
if err := n.rqliteManager.Start(ctx); err != nil {
|
|
return err
|
|
}
|
|
|
|
// NOW update metadata after RQLite is running
|
|
if n.clusterDiscovery != nil {
|
|
n.clusterDiscovery.UpdateOwnMetadata()
|
|
n.clusterDiscovery.TriggerSync() // Do initial cluster sync now that RQLite is ready
|
|
n.logger.Info("RQLite metadata published and cluster synced")
|
|
}
|
|
|
|
// Create adapter for sql.DB compatibility
|
|
adapter, err := database.NewRQLiteAdapter(n.rqliteManager)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create RQLite adapter: %w", err)
|
|
}
|
|
n.rqliteAdapter = adapter
|
|
|
|
return nil
|
|
}
|
|
|