diff --git a/.gitignore b/.gitignore index 49b5cf9..4200858 100644 --- a/.gitignore +++ b/.gitignore @@ -70,4 +70,4 @@ data/* ./node data/bootstrap/rqlite/ -.env \ No newline at end of file +.env.* \ No newline at end of file diff --git a/cmd/cli/main.go b/cmd/cli/main.go index e0afdfb..6a56a3f 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -11,12 +11,14 @@ import ( "time" "git.debros.io/DeBros/network/pkg/client" + "git.debros.io/DeBros/network/pkg/constants" ) var ( bootstrapPeer = "/ip4/127.0.0.1/tcp/4001" timeout = 30 * time.Second format = "table" + useProduction = false ) func main() { @@ -80,6 +82,8 @@ func parseGlobalFlags(args []string) { timeout = d } } + case "--production": + useProduction = true } } } @@ -348,14 +352,26 @@ func handleConnect(peerAddr string) { } func createClient() (client.NetworkClient, error) { - // Try to discover the bootstrap peer from saved peer info - discoveredPeer := discoverBootstrapPeer() - if discoveredPeer != "" { - bootstrapPeer = discoveredPeer + var bootstrapPeers []string + + if useProduction { + // Set environment to production to trigger production bootstrap peers + os.Setenv("ENVIRONMENT", "production") + bootstrapPeers = constants.GetBootstrapPeers() + if format != "json" { + fmt.Printf("🔗 Using production bootstrap peers\n") + } + } else { + // Try to discover the bootstrap peer from saved peer info + discoveredPeer := discoverBootstrapPeer() + if discoveredPeer != "" { + bootstrapPeer = discoveredPeer + } + bootstrapPeers = []string{bootstrapPeer} } config := client.DefaultClientConfig("network-cli") - config.BootstrapPeers = []string{bootstrapPeer} + config.BootstrapPeers = bootstrapPeers config.ConnectTimeout = timeout config.QuietMode = true // Suppress debug/info logs for CLI @@ -441,10 +457,12 @@ func showHelp() { fmt.Printf("Global Flags:\n") fmt.Printf(" -b, --bootstrap - Bootstrap peer address (default: /ip4/127.0.0.1/tcp/4001)\n") fmt.Printf(" -f, --format - Output format: table, json (default: table)\n") - fmt.Printf(" -t, --timeout - Operation timeout (default: 30s)\n\n") + fmt.Printf(" -t, --timeout - Operation timeout (default: 30s)\n") + fmt.Printf(" --production - Connect to production bootstrap peers\n\n") fmt.Printf("Examples:\n") fmt.Printf(" network-cli health\n") fmt.Printf(" network-cli peers --format json\n") + fmt.Printf(" network-cli peers --production\n") fmt.Printf(" network-cli storage put user:123 '{\"name\":\"Alice\"}'\n") fmt.Printf(" network-cli pubsub subscribe notifications 1m\n") } diff --git a/pkg/client/implementations.go b/pkg/client/implementations.go index 8b6d0fb..e8a2402 100644 --- a/pkg/client/implementations.go +++ b/pkg/client/implementations.go @@ -3,6 +3,7 @@ package client import ( "context" "fmt" + "os" "strings" "sync" "time" @@ -169,14 +170,8 @@ func (d *DatabaseClientImpl) getRQLiteConnection() (*gorqlite.Connection, error) // connectToAvailableNode tries to connect to any available RQLite node func (d *DatabaseClientImpl) connectToAvailableNode() (*gorqlite.Connection, error) { - // List of RQLite nodes to try (bootstrap, node1, node2, etc.) - rqliteNodes := []string{ - "http://localhost:5001", // bootstrap - "http://localhost:5002", // node1 - "http://localhost:5003", // node2 - "http://localhost:5004", // node3 (if exists) - "http://localhost:5005", // node4 (if exists) - } + // Get RQLite nodes from environment or use defaults + rqliteNodes := d.getRQLiteNodes() var lastErr error @@ -201,6 +196,32 @@ func (d *DatabaseClientImpl) connectToAvailableNode() (*gorqlite.Connection, err return nil, fmt.Errorf("failed to connect to any RQLite instance. Last error: %w", lastErr) } +// getRQLiteNodes returns a list of RQLite node URLs from environment or defaults +func (d *DatabaseClientImpl) getRQLiteNodes() []string { + // Try to get RQLite nodes from environment variable + if envNodes := os.Getenv("RQLITE_NODES"); envNodes != "" { + return strings.Split(envNodes, ",") + } + + // Check if we're in production environment + if env := os.Getenv("ENVIRONMENT"); env == "production" { + // Use production servers with RQLite HTTP API ports (network port + 1000) + return []string{ + "http://57.129.81.31:5001", // production server 1 + "http://38.242.250.186:5001", // production server 2 + } + } + + // Fallback to localhost for development + return []string{ + "http://localhost:5001", // bootstrap + "http://localhost:5002", // node1 + "http://localhost:5003", // node2 + "http://localhost:5004", // node3 (if exists) + "http://localhost:5005", // node4 (if exists) + } +} + // testConnection performs a health check on the RQLite connection func (d *DatabaseClientImpl) testConnection(conn *gorqlite.Connection) error { // Try a simple read query first (works even without leadership) diff --git a/pkg/constants/bootstrap.go b/pkg/constants/bootstrap.go index 33a5309..c03b3c4 100644 --- a/pkg/constants/bootstrap.go +++ b/pkg/constants/bootstrap.go @@ -87,15 +87,25 @@ func loadEnvironmentConfig() { // setDefaultBootstrapConfig sets default bootstrap configuration func setDefaultBootstrapConfig() { - BootstrapPeerIDs = []string{ - "12D3KooWN3AQHuxAzXfu98tiFYw7W3N2SyDwdxDRANXJp3ktVf8j", - "12D3KooWQRK2duw5B5LXi8gA7HBBFiCsLvwyph2ZU9VBmvbE1Nei", - "12D3KooWGbdnA22bN24X2gyY1o9jozwTBq9wbfvwtJ7G4XQ9JgFm", - } - BootstrapAddresses = []string{ - "/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWN3AQHuxAzXfu98tiFYw7W3N2SyDwdxDRANXJp3ktVf8j", - "/ip4/57.129.81.31/tcp/4001/p2p/12D3KooWQRK2duw5B5LXi8gA7HBBFiCsLvwyph2ZU9VBmvbE1Nei", - "/ip4/38.242.250.186/tcp/4001/p2p/12D3KooWGbdnA22bN24X2gyY1o9jozwTBq9wbfvwtJ7G4XQ9JgFm", + // Check if we're in production environment + if env := os.Getenv("ENVIRONMENT"); env == "production" { + // Production: only use live production peers + BootstrapPeerIDs = []string{ + "12D3KooWQRK2duw5B5LXi8gA7HBBFiCsLvwyph2ZU9VBmvbE1Nei", + "12D3KooWGbdnA22bN24X2gyY1o9jozwTBq9wbfvwtJ7G4XQ9JgFm", + } + BootstrapAddresses = []string{ + "/ip4/57.129.81.31/tcp/4001/p2p/12D3KooWQRK2duw5B5LXi8gA7HBBFiCsLvwyph2ZU9VBmvbE1Nei", + "/ip4/38.242.250.186/tcp/4001/p2p/12D3KooWGbdnA22bN24X2gyY1o9jozwTBq9wbfvwtJ7G4XQ9JgFm", + } + } else { + // Development: only use localhost bootstrap + BootstrapPeerIDs = []string{ + "12D3KooWN3AQHuxAzXfu98tiFYw7W3N2SyDwdxDRANXJp3ktVf8j", + } + BootstrapAddresses = []string{ + "/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWN3AQHuxAzXfu98tiFYw7W3N2SyDwdxDRANXJp3ktVf8j", + } } BootstrapPort = 4001 } diff --git a/scripts/install-debros-network.sh b/scripts/install-debros-network.sh index a652384..0da33b1 100755 --- a/scripts/install-debros-network.sh +++ b/scripts/install-debros-network.sh @@ -706,6 +706,7 @@ Type=simple User=debros Group=debros WorkingDirectory=$INSTALL_DIR +Environment=ENVIRONMENT=production ExecStart=$exec_start Restart=always RestartSec=10