mirror of
https://github.com/DeBrosOfficial/orama.git
synced 2026-03-17 06:43:01 +00:00
- load nodes from active sandbox state for env=sandbox - extract fanoutArchive for efficient server-to-server distribution
85 lines
3.1 KiB
Go
85 lines
3.1 KiB
Go
package sandbox
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
"sync"
|
|
|
|
"github.com/DeBrosOfficial/network/pkg/cli/remotessh"
|
|
"github.com/DeBrosOfficial/network/pkg/inspector"
|
|
)
|
|
|
|
// fanoutArchive uploads a binary archive to the first server, then fans out
|
|
// server-to-server in parallel to all remaining servers. This is much faster
|
|
// than uploading from the local machine to each node individually.
|
|
// After distribution, the archive is extracted on all nodes.
|
|
func fanoutArchive(servers []ServerState, sshKeyPath, archivePath string) error {
|
|
remotePath := "/tmp/" + filepath.Base(archivePath)
|
|
extractCmd := fmt.Sprintf("mkdir -p /opt/orama && tar xzf %s -C /opt/orama && rm -f %s",
|
|
remotePath, remotePath)
|
|
|
|
// Step 1: Upload from local machine to first node
|
|
first := servers[0]
|
|
firstNode := inspector.Node{User: "root", Host: first.IP, SSHKey: sshKeyPath}
|
|
|
|
fmt.Printf(" Uploading to %s...\n", first.Name)
|
|
if err := remotessh.UploadFile(firstNode, archivePath, remotePath, remotessh.WithNoHostKeyCheck()); err != nil {
|
|
return fmt.Errorf("upload to %s: %w", first.Name, err)
|
|
}
|
|
|
|
// Step 2: Fan out from first node to remaining nodes in parallel (server-to-server)
|
|
if len(servers) > 1 {
|
|
fmt.Printf(" Fanning out from %s to %d nodes...\n", first.Name, len(servers)-1)
|
|
|
|
// Temporarily upload SSH key for server-to-server SCP
|
|
remoteKeyPath := "/tmp/.sandbox_key"
|
|
if err := remotessh.UploadFile(firstNode, sshKeyPath, remoteKeyPath, remotessh.WithNoHostKeyCheck()); err != nil {
|
|
return fmt.Errorf("upload SSH key to %s: %w", first.Name, err)
|
|
}
|
|
defer remotessh.RunSSHStreaming(firstNode, fmt.Sprintf("rm -f %s", remoteKeyPath), remotessh.WithNoHostKeyCheck())
|
|
|
|
if err := remotessh.RunSSHStreaming(firstNode, fmt.Sprintf("chmod 600 %s", remoteKeyPath), remotessh.WithNoHostKeyCheck()); err != nil {
|
|
return fmt.Errorf("chmod SSH key on %s: %w", first.Name, err)
|
|
}
|
|
|
|
var wg sync.WaitGroup
|
|
errs := make([]error, len(servers))
|
|
|
|
for i := 1; i < len(servers); i++ {
|
|
wg.Add(1)
|
|
go func(idx int, srv ServerState) {
|
|
defer wg.Done()
|
|
// SCP from first node to target
|
|
scpCmd := fmt.Sprintf("scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i %s %s root@%s:%s",
|
|
remoteKeyPath, remotePath, srv.IP, remotePath)
|
|
if err := remotessh.RunSSHStreaming(firstNode, scpCmd, remotessh.WithNoHostKeyCheck()); err != nil {
|
|
errs[idx] = fmt.Errorf("fanout to %s: %w", srv.Name, err)
|
|
return
|
|
}
|
|
// Extract on target
|
|
targetNode := inspector.Node{User: "root", Host: srv.IP, SSHKey: sshKeyPath}
|
|
if err := remotessh.RunSSHStreaming(targetNode, extractCmd, remotessh.WithNoHostKeyCheck()); err != nil {
|
|
errs[idx] = fmt.Errorf("extract on %s: %w", srv.Name, err)
|
|
return
|
|
}
|
|
fmt.Printf(" Distributed to %s\n", srv.Name)
|
|
}(i, servers[i])
|
|
}
|
|
wg.Wait()
|
|
|
|
for _, err := range errs {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
// Step 3: Extract on first node
|
|
fmt.Printf(" Extracting on %s...\n", first.Name)
|
|
if err := remotessh.RunSSHStreaming(firstNode, extractCmd, remotessh.WithNoHostKeyCheck()); err != nil {
|
|
return fmt.Errorf("extract on %s: %w", first.Name, err)
|
|
}
|
|
|
|
return nil
|
|
}
|