Skip to content

Commit 4b57bc6

Browse files
committed
add rsync flag option to copy files using rsync
Signed-off-by: olalekan odukoya <odukoyaonline@gmail.com>
1 parent b2121e5 commit 4b57bc6

File tree

1 file changed

+41
-7
lines changed

1 file changed

+41
-7
lines changed

cmd/limactl/copy.go

+41-7
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ func newCopyCommand() *cobra.Command {
3434

3535
copyCommand.Flags().BoolP("recursive", "r", false, "copy directories recursively")
3636
copyCommand.Flags().BoolP("verbose", "v", false, "enable verbose output")
37+
copyCommand.Flags().BoolP("rsync", "", false, "use rsync for copying instead of scp")
3738

3839
return copyCommand
3940
}
@@ -49,10 +50,24 @@ func copyAction(cmd *cobra.Command, args []string) error {
4950
return err
5051
}
5152

52-
arg0, err := exec.LookPath("scp")
53+
useRsync, err := cmd.Flags().GetBool("rsync")
5354
if err != nil {
5455
return err
5556
}
57+
58+
var arg0 string
59+
if useRsync {
60+
arg0, err = exec.LookPath("rsync")
61+
if err != nil {
62+
return err
63+
}
64+
} else {
65+
arg0, err = exec.LookPath("scp")
66+
if err != nil {
67+
return err
68+
}
69+
}
70+
5671
instances := make(map[string]*store.Instance)
5772
scpFlags := []string{}
5873
scpArgs := []string{}
@@ -67,6 +82,9 @@ func copyAction(cmd *cobra.Command, args []string) error {
6782

6883
if verbose {
6984
scpFlags = append(scpFlags, "-v")
85+
if useRsync {
86+
scpFlags = append(scpFlags, "--progress")
87+
}
7088
} else {
7189
scpFlags = append(scpFlags, "-q")
7290
}
@@ -93,11 +111,15 @@ func copyAction(cmd *cobra.Command, args []string) error {
93111
if inst.Status == store.StatusStopped {
94112
return fmt.Errorf("instance %q is stopped, run `limactl start %s` to start the instance", instName, instName)
95113
}
96-
if legacySSH {
97-
scpFlags = append(scpFlags, "-P", fmt.Sprintf("%d", inst.SSHLocalPort))
114+
if useRsync {
98115
scpArgs = append(scpArgs, fmt.Sprintf("%s@127.0.0.1:%s", *inst.Config.User.Name, path[1]))
99116
} else {
100-
scpArgs = append(scpArgs, fmt.Sprintf("scp://%s@127.0.0.1:%d/%s", *inst.Config.User.Name, inst.SSHLocalPort, path[1]))
117+
if legacySSH {
118+
scpFlags = append(scpFlags, "-P", fmt.Sprintf("%d", inst.SSHLocalPort))
119+
scpArgs = append(scpArgs, fmt.Sprintf("%s@127.0.0.1:%s", *inst.Config.User.Name, path[1]))
120+
} else {
121+
scpArgs = append(scpArgs, fmt.Sprintf("scp://%s@127.0.0.1:%d/%s", *inst.Config.User.Name, inst.SSHLocalPort, path[1]))
122+
}
101123
}
102124
instances[instName] = inst
103125
default:
@@ -107,7 +129,9 @@ func copyAction(cmd *cobra.Command, args []string) error {
107129
if legacySSH && len(instances) > 1 {
108130
return errors.New("more than one (instance) host is involved in this command, this is only supported for openSSH v8.0 or higher")
109131
}
110-
scpFlags = append(scpFlags, "-3", "--")
132+
if !useRsync {
133+
scpFlags = append(scpFlags, "-3", "--")
134+
}
111135
scpArgs = append(scpFlags, scpArgs...)
112136

113137
var sshOpts []string
@@ -128,13 +152,23 @@ func copyAction(cmd *cobra.Command, args []string) error {
128152
return err
129153
}
130154
}
155+
156+
var cmdArgs []string
131157
sshArgs := sshutil.SSHArgsFromOpts(sshOpts)
158+
if useRsync {
159+
// for rsync, add the -e flag with SSH options
160+
scpFlags = append(scpFlags, "-e", fmt.Sprintf("ssh %s", strings.Join(sshArgs, " ")))
161+
cmdArgs = append(cmdArgs, append(scpFlags, scpArgs...)...)
162+
} else {
163+
// for scp, append SSH options and scpArgs
164+
cmdArgs = append(cmdArgs, append(sshArgs, scpArgs...)...)
165+
}
132166

133-
sshCmd := exec.Command(arg0, append(sshArgs, scpArgs...)...)
167+
sshCmd := exec.Command(arg0, cmdArgs...)
134168
sshCmd.Stdin = cmd.InOrStdin()
135169
sshCmd.Stdout = cmd.OutOrStdout()
136170
sshCmd.Stderr = cmd.ErrOrStderr()
137-
logrus.Debugf("executing scp (may take a long time): %+v", sshCmd.Args)
171+
logrus.Debugf("executing %s (may take a long time): %+v", arg0, sshCmd.Args)
138172

139173
// TODO: use syscall.Exec directly (results in losing tty?)
140174
return sshCmd.Run()

0 commit comments

Comments
 (0)