persistant ssh

This commit is contained in:
2026-01-13 12:37:10 +00:00
parent ab077d45eb
commit 3c023582c2

View File

@@ -2,11 +2,13 @@ package main
import ( import (
"bytes" "bytes"
"crypto/sha1"
"errors" "errors"
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"runtime"
"strings" "strings"
"github.com/pelletier/go-toml/v2" "github.com/pelletier/go-toml/v2"
@@ -55,6 +57,7 @@ func runDeploy() error {
if serverIP == "" { if serverIP == "" {
return fmt.Errorf("pb.toml missing [server].ip") return fmt.Errorf("pb.toml missing [server].ip")
} }
defer closeSSHControlMaster(serverIP)
domain := cfg.Server.Domain domain := cfg.Server.Domain
if domain == "" { if domain == "" {
@@ -310,7 +313,8 @@ func syncLocalDirectories(server, remoteBase string, dirs []string) error {
} }
remotePath := fmt.Sprintf("root@%s:%s/%s", server, remoteBase, dir) remotePath := fmt.Sprintf("root@%s:%s/%s", server, remoteBase, dir)
cmd := exec.Command("rsync", "-e", "ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new", "-az", "--delete", localPath+"/", remotePath) rsyncCmd := rsyncSSHCommand(server)
cmd := exec.Command("rsync", "-e", rsyncCmd, "-az", "--delete", localPath+"/", remotePath)
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {
@@ -320,10 +324,44 @@ func syncLocalDirectories(server, remoteBase string, dirs []string) error {
return nil return nil
} }
func rsyncSSHCommand(server string) string {
args := append([]string(nil), sshSharedArgs(server)...)
args = append(args, fmt.Sprintf("root@%s", server))
return fmt.Sprintf("ssh %s", strings.Join(args, " "))
}
func sshArgs(server string) []string { func sshArgs(server string) []string {
args := append([]string(nil), sshSharedArgs(server)...)
return append(args, fmt.Sprintf("root@%s", server))
}
func sshSharedArgs(server string) []string {
return []string{ return []string{
"-o", "BatchMode=yes", "-o", "BatchMode=yes",
"-o", "StrictHostKeyChecking=accept-new", "-o", "StrictHostKeyChecking=accept-new",
fmt.Sprintf("root@%s", server), "-o", "ControlMaster=auto",
"-o", fmt.Sprintf("ControlPath=%s", sshControlPath(server)),
"-o", "ControlPersist=5m",
} }
} }
func sshControlPath(server string) string {
sum := sha1.Sum([]byte(server))
return filepath.Join(sshControlDir(), fmt.Sprintf("pb-ssh-%x.sock", sum))
}
func sshControlDir() string {
if dir := os.Getenv("PB_SSH_CONTROL_DIR"); dir != "" {
return dir
}
if runtime.GOOS == "windows" {
return os.TempDir()
}
return "/tmp"
}
func closeSSHControlMaster(server string) {
args := append([]string(nil), sshSharedArgs(server)...)
args = append(args, "-O", "exit", fmt.Sprintf("root@%s", server))
_ = exec.Command("ssh", args...).Run()
}