fix: rsync double SSH spec in RunRemote, restore dropped flags in Run
- Fix Bug A: RunRemote was re-prefixing destination with user@host: when engine.go:135 already pre-prefixed it for remote-to-remote, causing "admin@host:admin@host:/path" to be passed to rsync - Fix Bug B: Run used args[1:] when inserting -e ssh, silently dropping the first rsync flag (e.g. -aP became flag-less) - Fix Bug C: RunRemote extracted source/dest in wrong order for pull direction (buildArgs reverses them but RunRemote assumed push order) - Add rsync_runner_test.go covering buildArgs, RunRemote prefixing, and flag preservation
This commit is contained in:
@@ -40,16 +40,19 @@ func NewRsyncRunner(sshDir, privKey string) *RsyncRunner {
|
||||
}
|
||||
|
||||
func (r *RsyncRunner) Run(ctx context.Context, pair *SyncPairConfig, onLine func(stream string, line string)) (*RsyncResult, error) {
|
||||
args := r.buildArgs(pair)
|
||||
cmd := r.buildRsyncCmd(pair)
|
||||
return r.runCmd(ctx, cmd, onLine)
|
||||
}
|
||||
|
||||
cmd := exec.CommandContext(ctx, "rsync", args...)
|
||||
func (r *RsyncRunner) buildRsyncCmd(pair *SyncPairConfig) *exec.Cmd {
|
||||
args := r.buildArgs(pair)
|
||||
cmd := exec.CommandContext(context.Background(), "rsync", args...)
|
||||
if r.privKey != "" {
|
||||
sshCmd := fmt.Sprintf("ssh -i %s -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=%s",
|
||||
r.privKey, strings.TrimRight(r.sshDir, "/")+"/known_hosts")
|
||||
cmd.Args = append([]string{"rsync", "-e", sshCmd}, args[1:]...)
|
||||
cmd.Args = append([]string{"rsync", "-e", sshCmd}, args...)
|
||||
}
|
||||
|
||||
return r.runCmd(ctx, cmd, onLine)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (r *RsyncRunner) buildArgs(pair *SyncPairConfig) []string {
|
||||
@@ -93,17 +96,39 @@ func (r *RsyncRunner) RunRemote(ctx context.Context, pair *SyncPairConfig, src *
|
||||
destKey = filepath.Join(r.sshDir, "id_ed25519")
|
||||
}
|
||||
|
||||
destUserHost := fmt.Sprintf("%s@%s", dst.SSHUser, dst.Host)
|
||||
srcUserHost := fmt.Sprintf("%s@%s", src.SSHUser, src.Host)
|
||||
args := r.buildArgs(pair)
|
||||
|
||||
innerSSH := fmt.Sprintf("ssh -i %s -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=%s",
|
||||
destKey, filepath.Join(r.sshDir, "known_hosts"))
|
||||
rsyncFlags := strings.Join(args[:len(args)-2], " ")
|
||||
sourcePath := args[len(args)-2]
|
||||
destPath := args[len(args)-1]
|
||||
|
||||
var sourcePath, destPath string
|
||||
if pair.Direction == "pull" {
|
||||
sourcePath = args[len(args)-1]
|
||||
destPath = args[len(args)-2]
|
||||
} else {
|
||||
sourcePath = args[len(args)-2]
|
||||
destPath = args[len(args)-1]
|
||||
}
|
||||
|
||||
var remoteSrc, remoteDst string
|
||||
if pair.Direction == "pull" {
|
||||
remoteSrc = sourcePath
|
||||
remoteDst = destPath
|
||||
if !strings.Contains(destPath, "@") {
|
||||
remoteDst = fmt.Sprintf("%s@%s:%s", dst.SSHUser, dst.Host, destPath)
|
||||
}
|
||||
} else {
|
||||
remoteDst = destPath
|
||||
if !strings.Contains(destPath, "@") {
|
||||
remoteDst = fmt.Sprintf("%s@%s:%s", dst.SSHUser, dst.Host, destPath)
|
||||
}
|
||||
remoteSrc = fmt.Sprintf("%s:%s", srcUserHost, sourcePath)
|
||||
}
|
||||
|
||||
remoteCmd := fmt.Sprintf("rsync %s -e %q %s %s",
|
||||
rsyncFlags, innerSSH, sourcePath, destUserHost+":"+destPath)
|
||||
rsyncFlags, innerSSH, remoteSrc, remoteDst)
|
||||
|
||||
sshArgs := []string{
|
||||
"-i", src.PrivKey,
|
||||
|
||||
Reference in New Issue
Block a user