node update sync wip

This commit is contained in:
partisan 2024-06-30 23:20:52 +02:00
parent f7abef253e
commit 9f5ef7a1ef
5 changed files with 189 additions and 45 deletions

36
init.go
View file

@ -2,17 +2,22 @@ package main
import ( import (
"bufio" "bufio"
"crypto/rand"
"encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
"log" "log"
"os" "os"
"strconv" "strconv"
"strings"
) )
// Configuration structure // Configuration structure
type Config struct { type Config struct {
Port int Port int
OpenSearch OpenSearchConfig ConnectionCode string
Peers []string
OpenSearch OpenSearchConfig
} }
type OpenSearchConfig struct { type OpenSearchConfig struct {
@ -37,6 +42,9 @@ func main() {
return return
} }
// This is stupid
loadNodeConfig()
// Start the main application // Start the main application
runServer() runServer()
} }
@ -74,6 +82,21 @@ func createConfig() error {
if domain != "\n" { if domain != "\n" {
config.OpenSearch.Domain = domain[:len(domain)-1] config.OpenSearch.Domain = domain[:len(domain)-1]
} }
fmt.Print("Do you want to connect to other nodes? (yes/no): ")
connectNodes, _ := reader.ReadString('\n')
if strings.TrimSpace(connectNodes) == "yes" {
fmt.Println("Enter peer addresses (comma separated, e.g., http://localhost:5000,http://localhost:5001): ")
peersStr, _ := reader.ReadString('\n')
if peersStr != "\n" {
config.Peers = strings.Split(strings.TrimSpace(peersStr), ",")
}
}
}
if config.ConnectionCode == "" {
config.ConnectionCode = generateStrongRandomString(32)
fmt.Printf("Generated connection code: %s\n", config.ConnectionCode)
} }
saveConfig(config) saveConfig(config)
@ -114,3 +137,12 @@ func loadConfig() Config {
return config return config
} }
func generateStrongRandomString(length int) string {
bytes := make([]byte, length)
_, err := rand.Read(bytes)
if err != nil {
log.Fatalf("Error generating random string: %v", err)
}
return base64.URLEncoding.EncodeToString(bytes)[:length]
}

View file

@ -140,9 +140,12 @@ func runServer() {
config := loadConfig() config := loadConfig()
generateOpenSearchXML(config) generateOpenSearchXML(config)
fmt.Printf("Server is listening on http://localhost:%d\n", config.Port)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", config.Port), nil))
// Start node communication client // Start node communication client
go startNodeClient(peers) go startNodeClient(peers)
fmt.Printf("Server is listening on http://localhost:%d\n", config.Port) // Start automatic update checker
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", config.Port), nil)) go checkForUpdates()
} }

23
node-update.go Normal file
View file

@ -0,0 +1,23 @@
package main
import (
"fmt"
"log"
"time"
)
// Function to sync updates across all nodes
func nodeUpdateSync() {
fmt.Println("Syncing updates across all nodes...")
for _, peer := range peers {
fmt.Printf("Notifying node %s about update...\n", peer)
err := sendMessage(peer, connCode, "update", "Start update process")
if err != nil {
log.Printf("Failed to notify node %s: %v\n", peer, err)
continue
}
fmt.Printf("Node %s notified. Waiting for it to update...\n", peer)
time.Sleep(30 * time.Second) // Adjust sleep time as needed to allow for updates
}
fmt.Println("All nodes have been updated.")
}

116
node.go
View file

@ -1,21 +1,32 @@
package main package main
import ( import (
"bytes"
"encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"strings"
"sync" "sync"
"time" "time"
) )
const ( var (
connCode = "secretcode123" connCode string
testMsg = "This is a test message" peers []string
connCodeMutex sync.Mutex
) )
var connCodeMutex sync.Mutex type Message struct {
var peers = []string{"localhost:50002", "localhost:5000"} // Example peer addresses ID string `json:"id"`
Type string `json:"type"`
Content string `json:"content"`
}
func loadNodeConfig() {
config := loadConfig()
connCode = config.ConnectionCode
peers = config.Peers
}
func handleNodeRequest(w http.ResponseWriter, r *http.Request) { func handleNodeRequest(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost { if r.Method != http.MethodPost {
@ -33,55 +44,78 @@ func handleNodeRequest(w http.ResponseWriter, r *http.Request) {
} }
defer r.Body.Close() defer r.Body.Close()
receivedCode := strings.TrimSpace(string(body)) var msg Message
if err := json.Unmarshal(body, &msg); err != nil {
http.Error(w, "Error parsing JSON", http.StatusBadRequest)
return
}
if receivedCode != connCode { if msg.ID != connCode {
http.Error(w, "Authentication failed", http.StatusUnauthorized) http.Error(w, "Authentication failed", http.StatusUnauthorized)
return return
} }
fmt.Println("Authentication successful") interpretMessage(msg)
fmt.Fprintln(w, testMsg) fmt.Fprintln(w, "Message received")
}
func interpretMessage(msg Message) {
switch msg.Type {
case "test":
fmt.Println("Received test message:", msg.Content)
case "get-version":
fmt.Println("Received get-version message")
// Handle get-version logic here
case "update":
fmt.Println("Received update message:", msg.Content)
// Handle update logic here
go update()
default:
fmt.Println("Received unknown message type:", msg.Type)
}
}
func sendMessage(address, id, msgType, content string) error {
msg := Message{
ID: id,
Type: msgType,
Content: content,
}
msgBytes, err := json.Marshal(msg)
if err != nil {
return err
}
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/node", address), bytes.NewBuffer(msgBytes))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := ioutil.ReadAll(resp.Body)
return fmt.Errorf("failed to send message: %s", body)
}
return nil
} }
func startNodeClient(addresses []string) { func startNodeClient(addresses []string) {
for _, address := range addresses { for _, address := range addresses {
go func(addr string) { go func(addr string) {
for { for {
url := fmt.Sprintf("http://%s/node", addr) err := sendMessage(addr, connCode, "test", "This is a test message")
req, err := http.NewRequest(http.MethodPost, url, strings.NewReader(connCode))
if err != nil { if err != nil {
fmt.Println("Error creating request:", err) fmt.Println("Error sending test message to", addr, ":", err)
time.Sleep(5 * time.Second)
continue continue
} }
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error connecting to", addr, ":", err)
time.Sleep(5 * time.Second)
continue
}
if resp.StatusCode != http.StatusOK {
fmt.Println("Authentication failed:", resp.Status)
resp.Body.Close()
time.Sleep(5 * time.Second)
continue
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading response:", err)
resp.Body.Close()
time.Sleep(5 * time.Second)
continue
}
resp.Body.Close()
testMsg := strings.TrimSpace(string(body))
fmt.Println("Received test message from", addr, ":", testMsg)
time.Sleep(10 * time.Second) time.Sleep(10 * time.Second)
} }
}(address) }(address)

52
update.go Normal file
View file

@ -0,0 +1,52 @@
package main
import (
"fmt"
"os"
"os/exec"
"time"
)
// Function to check for updates and restart the server if an update is found
func checkForUpdates() {
repoURL := "https://weforgecode.xyz/Spitfire/Search.git"
localDir := "." // Assume the repository is cloned in the current directory
for {
err := gitPull(repoURL, localDir)
if err != nil {
fmt.Println("Error checking for updates:", err)
time.Sleep(10 * time.Minute)
continue
}
fmt.Println("Update found. Syncing updates...")
nodeUpdateSync()
fmt.Println("Restarting server to apply updates...")
update()
time.Sleep(10 * time.Minute)
}
}
// Function to pull updates from the Git repository
func gitPull(repoURL, localDir string) error {
cmd := exec.Command("git", "-C", localDir, "pull", repoURL)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
// Function to download updates and restart the server
func update() {
cmd := exec.Command("sh", "run.sh")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Start()
if err != nil {
fmt.Println("Error starting the server:", err)
return
}
os.Exit(0)
}