mirror of
https://github.com/DeBrosOfficial/orama.git
synced 2026-03-17 10:26:57 +00:00
- Updated `clean-testnet.sh` to stop and disable legacy services. - Added `upload-source.sh` for streamlined source archive uploads. - Enhanced password input handling in `ssh.go` for better security. - Adjusted directory permissions in `validator.go` for improved security. - Simplified node configuration logic in `config.go`. - Removed unnecessary commands from `gateway.go` to streamline installation.
154 lines
3.7 KiB
Go
154 lines
3.7 KiB
Go
package install
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/DeBrosOfficial/network/pkg/inspector"
|
|
"golang.org/x/term"
|
|
)
|
|
|
|
const sourceArchivePath = "/tmp/network-source.tar.gz"
|
|
|
|
// resolveSSHCredentials finds SSH credentials for the given VPS IP.
|
|
// First checks remote-nodes.conf, then prompts interactively.
|
|
func resolveSSHCredentials(vpsIP string) (inspector.Node, error) {
|
|
confPath := findRemoteNodesConf()
|
|
if confPath != "" {
|
|
nodes, err := inspector.LoadNodes(confPath)
|
|
if err == nil {
|
|
for _, n := range nodes {
|
|
if n.Host == vpsIP {
|
|
// Expand ~ in SSH key path
|
|
if n.SSHKey != "" && strings.HasPrefix(n.SSHKey, "~") {
|
|
home, _ := os.UserHomeDir()
|
|
n.SSHKey = filepath.Join(home, n.SSHKey[1:])
|
|
}
|
|
return n, nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Not found in config — prompt interactively
|
|
return promptSSHCredentials(vpsIP), nil
|
|
}
|
|
|
|
// findRemoteNodesConf searches for the remote-nodes.conf file.
|
|
func findRemoteNodesConf() string {
|
|
candidates := []string{
|
|
"scripts/remote-nodes.conf",
|
|
"../scripts/remote-nodes.conf",
|
|
"network/scripts/remote-nodes.conf",
|
|
}
|
|
for _, c := range candidates {
|
|
if _, err := os.Stat(c); err == nil {
|
|
return c
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// promptSSHCredentials asks the user for SSH credentials interactively.
|
|
func promptSSHCredentials(vpsIP string) inspector.Node {
|
|
reader := bufio.NewReader(os.Stdin)
|
|
|
|
fmt.Printf("\nSSH credentials for %s\n", vpsIP)
|
|
fmt.Print(" SSH user (default: ubuntu): ")
|
|
user, _ := reader.ReadString('\n')
|
|
user = strings.TrimSpace(user)
|
|
if user == "" {
|
|
user = "ubuntu"
|
|
}
|
|
|
|
fmt.Print(" SSH password: ")
|
|
passwordBytes, err := term.ReadPassword(int(os.Stdin.Fd()))
|
|
fmt.Println() // newline after hidden input
|
|
if err != nil {
|
|
// Fall back to plain read if terminal is not available
|
|
password, _ := reader.ReadString('\n')
|
|
return inspector.Node{
|
|
User: user,
|
|
Host: vpsIP,
|
|
Password: strings.TrimSpace(password),
|
|
}
|
|
}
|
|
password := string(passwordBytes)
|
|
|
|
return inspector.Node{
|
|
User: user,
|
|
Host: vpsIP,
|
|
Password: password,
|
|
}
|
|
}
|
|
|
|
// uploadFile copies a local file to a remote host via SCP.
|
|
func uploadFile(node inspector.Node, localPath, remotePath string) error {
|
|
dest := fmt.Sprintf("%s@%s:%s", node.User, node.Host, remotePath)
|
|
|
|
var cmd *exec.Cmd
|
|
if node.SSHKey != "" {
|
|
cmd = exec.Command("scp",
|
|
"-o", "StrictHostKeyChecking=no",
|
|
"-o", "ConnectTimeout=10",
|
|
"-i", node.SSHKey,
|
|
localPath, dest,
|
|
)
|
|
} else {
|
|
if _, err := exec.LookPath("sshpass"); err != nil {
|
|
return fmt.Errorf("sshpass not found — install it: brew install hudochenkov/sshpass/sshpass")
|
|
}
|
|
cmd = exec.Command("sshpass", "-p", node.Password,
|
|
"scp",
|
|
"-o", "StrictHostKeyChecking=no",
|
|
"-o", "ConnectTimeout=10",
|
|
localPath, dest,
|
|
)
|
|
}
|
|
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
return fmt.Errorf("SCP failed: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// runSSHStreaming executes a command on a remote host via SSH,
|
|
// streaming stdout/stderr to the local terminal in real-time.
|
|
func runSSHStreaming(node inspector.Node, command string) error {
|
|
var cmd *exec.Cmd
|
|
if node.SSHKey != "" {
|
|
cmd = exec.Command("ssh",
|
|
"-o", "StrictHostKeyChecking=no",
|
|
"-o", "ConnectTimeout=10",
|
|
"-i", node.SSHKey,
|
|
fmt.Sprintf("%s@%s", node.User, node.Host),
|
|
command,
|
|
)
|
|
} else {
|
|
cmd = exec.Command("sshpass", "-p", node.Password,
|
|
"ssh",
|
|
"-o", "StrictHostKeyChecking=no",
|
|
"-o", "ConnectTimeout=10",
|
|
fmt.Sprintf("%s@%s", node.User, node.Host),
|
|
command,
|
|
)
|
|
}
|
|
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
cmd.Stdin = os.Stdin // Allow password prompts from remote sudo
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
return fmt.Errorf("SSH command failed: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|