mirror of
https://github.com/DeBrosOfficial/orama.git
synced 2026-03-17 21:46:57 +00:00
Replaces plaintext password-based SSH authentication (sshpass) across the entire Go CLI with wallet-derived ed25519 keys via RootWallet. - Add `rw vault ssh agent-load` command to RootWallet CLI for SSH agent forwarding in push fanout - Create wallet.go bridge: PrepareNodeKeys resolves keys from `rw vault ssh get --priv`, writes temp PEMs (0600), zero-overwrites on cleanup - Remove Password field from Node struct, update config parser to new 3-field format (env|user@host|role) - Remove all sshpass branches from inspector/ssh.go and remotessh/ssh.go, require SSHKey on all SSH paths - Add WithAgentForward() option to RunSSHStreaming for hub fanout - Add PrepareNodeKeys + defer cleanup to all 7 entry points: inspect, monitor, push, upgrade, clean, recover, install - Update push fanout to use SSH agent forwarding instead of sshpass on hub - Delete install/ssh.go duplicate, replace with remotessh calls - Create nodes.conf from remote-nodes.conf (topology only, no secrets) - Update all config defaults and help text from remote-nodes.conf to nodes.conf - Use StrictHostKeyChecking=accept-new consistently everywhere
76 lines
2.1 KiB
Go
76 lines
2.1 KiB
Go
package upgrade
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/DeBrosOfficial/network/pkg/cli/remotessh"
|
|
"github.com/DeBrosOfficial/network/pkg/inspector"
|
|
)
|
|
|
|
// RemoteUpgrader handles rolling upgrades across remote nodes.
|
|
type RemoteUpgrader struct {
|
|
flags *Flags
|
|
}
|
|
|
|
// NewRemoteUpgrader creates a new remote upgrader.
|
|
func NewRemoteUpgrader(flags *Flags) *RemoteUpgrader {
|
|
return &RemoteUpgrader{flags: flags}
|
|
}
|
|
|
|
// Execute runs the remote rolling upgrade.
|
|
func (r *RemoteUpgrader) Execute() error {
|
|
nodes, err := remotessh.LoadEnvNodes(r.flags.Env)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
cleanup, err := remotessh.PrepareNodeKeys(nodes)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer cleanup()
|
|
|
|
// Filter to single node if specified
|
|
if r.flags.NodeFilter != "" {
|
|
nodes = remotessh.FilterByIP(nodes, r.flags.NodeFilter)
|
|
if len(nodes) == 0 {
|
|
return fmt.Errorf("node %s not found in %s environment", r.flags.NodeFilter, r.flags.Env)
|
|
}
|
|
}
|
|
|
|
fmt.Printf("Rolling upgrade: %s (%d nodes, %ds delay)\n\n", r.flags.Env, len(nodes), r.flags.Delay)
|
|
|
|
// Print execution plan
|
|
for i, node := range nodes {
|
|
fmt.Printf(" %d. %s (%s)\n", i+1, node.Host, node.Role)
|
|
}
|
|
fmt.Println()
|
|
|
|
for i, node := range nodes {
|
|
fmt.Printf("[%d/%d] Upgrading %s (%s)...\n", i+1, len(nodes), node.Host, node.Role)
|
|
|
|
if err := r.upgradeNode(node); err != nil {
|
|
return fmt.Errorf("upgrade failed on %s: %w\nStopping rollout — remaining nodes not upgraded", node.Host, err)
|
|
}
|
|
|
|
fmt.Printf(" ✓ %s upgraded\n", node.Host)
|
|
|
|
// Wait between nodes (except after the last one)
|
|
if i < len(nodes)-1 && r.flags.Delay > 0 {
|
|
fmt.Printf(" Waiting %ds before next node...\n\n", r.flags.Delay)
|
|
time.Sleep(time.Duration(r.flags.Delay) * time.Second)
|
|
}
|
|
}
|
|
|
|
fmt.Printf("\n✓ Rolling upgrade complete (%d nodes)\n", len(nodes))
|
|
return nil
|
|
}
|
|
|
|
// upgradeNode runs `orama node upgrade --restart` on a single remote node.
|
|
func (r *RemoteUpgrader) upgradeNode(node inspector.Node) error {
|
|
sudo := remotessh.SudoPrefix(node)
|
|
cmd := fmt.Sprintf("%sorama node upgrade --restart", sudo)
|
|
return remotessh.RunSSHStreaming(node, cmd)
|
|
}
|