From cf9359b3d76b2eb794af4c6d2161fac9d8c28e0e Mon Sep 17 00:00:00 2001 From: Mark Yen Date: Thu, 2 Sep 2021 15:26:18 -0700 Subject: [PATCH 1/2] copy: use SSHArgs if copying to a single remote host. This lets us use ControlPath with the connection, so that if a small number of copies run in parallel we can reuse the connection, rather than failing when too many connections are in flight. Signed-off-by: Mark Yen --- cmd/limactl/copy.go | 30 ++++++++++++++++++++++-------- pkg/sshutil/sshutil.go | 2 +- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/cmd/limactl/copy.go b/cmd/limactl/copy.go index 07c7595282c..4c1a0d70d6d 100644 --- a/cmd/limactl/copy.go +++ b/cmd/limactl/copy.go @@ -36,12 +36,8 @@ func copyAction(clicontext *cli.Context) error { return err } - const useDotSSH = false - args, err := sshutil.CommonArgs(useDotSSH) - if err != nil { - return err - } - args = append(args, "-3", "--") + instDirs := make(map[string]string) + args := []string{"-3", "--"} for _, arg := range clicontext.Args().Slice() { path := strings.Split(arg, ":") switch len(path) { @@ -60,15 +56,33 @@ func copyAction(clicontext *cli.Context) error { return fmt.Errorf("instance %q is stopped, run `limactl start %s` to start the instance", instName, instName) } args = append(args, fmt.Sprintf("scp://%s@127.0.0.1:%d/%s", u.Username, inst.SSHLocalPort, path[1])) + instDirs[instName] = inst.Dir default: return fmt.Errorf("Path %q contains multiple colons", arg) } } - cmd := exec.Command(arg0, args...) + + sshArgs := []string{} + if len(instDirs) == 1 { + for _, instDir := range instDirs { + sshArgs, err = sshutil.SSHArgs(instDir, false) + if err != nil { + return err + } + } + } else { + // Copying among multiple hosts; we can't pass in host-specific options. + sshArgs, err = sshutil.CommonArgs(false) + if err != nil { + return err + } + } + + cmd := exec.Command(arg0, append(sshArgs, args...)...) cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr - logrus.Debugf("executing scp (may take a long)): %+v", cmd.Args) + logrus.Debugf("executing scp (may take a long time)): %+v", cmd.Args) // TODO: use syscall.Exec directly (results in losing tty?) return cmd.Run() diff --git a/pkg/sshutil/sshutil.go b/pkg/sshutil/sshutil.go index b57590aff1d..b37a4fd0a71 100644 --- a/pkg/sshutil/sshutil.go +++ b/pkg/sshutil/sshutil.go @@ -172,7 +172,7 @@ func SSHArgs(instDir string, useDotSSH bool) ([]string, error) { return nil, err } args = append(args, - "-l", u.Username, // guest and host have the same username, but we should specify the username explicitly (#85) + "-o", fmt.Sprintf("User=%s", u.Username), // guest and host have the same username, but we should specify the username explicitly (#85) "-o", "ControlMaster=auto", "-o", fmt.Sprintf("ControlPath=\"%s\"", controlSock), "-o", "ControlPersist=5m", From 13d5197493798df84ef80e5fd155d828308cb573 Mon Sep 17 00:00:00 2001 From: Mark Yen Date: Thu, 2 Sep 2021 16:54:02 -0700 Subject: [PATCH 2/2] Copy: Add comment on why we want to use instance-specific args. https://github.com/lima-vm/lima/pull/194#pullrequestreview-745595685 Signed-off-by: Mark Yen --- cmd/limactl/copy.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/limactl/copy.go b/cmd/limactl/copy.go index 4c1a0d70d6d..2967521fde9 100644 --- a/cmd/limactl/copy.go +++ b/cmd/limactl/copy.go @@ -64,6 +64,9 @@ func copyAction(clicontext *cli.Context) error { sshArgs := []string{} if len(instDirs) == 1 { + // Only one (instance) host is involved; we can use the instance-specific + // arguments such as ControlPath. This is preferred as we can multiplex + // sessions without re-authenticating (MaxSessions permitting). for _, instDir := range instDirs { sshArgs, err = sshutil.SSHArgs(instDir, false) if err != nil {