Skip to content

Commit 6ebda2c

Browse files
committed
feat(cli/ssh): allow multiple remote forwards
1 parent 08b4eb3 commit 6ebda2c

File tree

2 files changed

+27
-30
lines changed

2 files changed

+27
-30
lines changed

cli/remoteforward.go

+3-10
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"fmt"
66
"io"
77
"net"
8-
"os"
98
"regexp"
109
"strconv"
1110

@@ -67,19 +66,13 @@ func parseRemoteForwardTCP(matches []string) (net.Addr, net.Addr, error) {
6766
return localAddr, remoteAddr, nil
6867
}
6968

69+
// parseRemoteForwardUnixSocket parses a remote forward flag. Note that
70+
// we don't verify that the local socket path exists because the user
71+
// may create it later. This behavior matches OpenSSH.
7072
func parseRemoteForwardUnixSocket(matches []string) (net.Addr, net.Addr, error) {
7173
remoteSocket := matches[1]
7274
localSocket := matches[2]
7375

74-
fileInfo, err := os.Stat(localSocket)
75-
if err != nil {
76-
return nil, nil, err
77-
}
78-
79-
if fileInfo.Mode()&os.ModeSocket == 0 {
80-
return nil, nil, xerrors.New("File is not a Unix domain socket file")
81-
}
82-
8376
remoteAddr := &net.UnixAddr{
8477
Name: remoteSocket,
8578
Net: "unix",

cli/ssh.go

+24-20
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func (r *RootCmd) ssh() *clibase.Cmd {
5353
waitEnum string
5454
noWait bool
5555
logDirPath string
56-
remoteForward string
56+
remoteForwards []string
5757
disableAutostart bool
5858
)
5959
client := new(codersdk.Client)
@@ -135,13 +135,15 @@ func (r *RootCmd) ssh() *clibase.Cmd {
135135
stack := newCloserStack(ctx, logger)
136136
defer stack.close(nil)
137137

138-
if remoteForward != "" {
139-
isValid := validateRemoteForward(remoteForward)
140-
if !isValid {
141-
return xerrors.Errorf(`invalid format of remote-forward, expected: remote_port:local_address:local_port`)
142-
}
143-
if isValid && stdio {
144-
return xerrors.Errorf(`remote-forward can't be enabled in the stdio mode`)
138+
if len(remoteForwards) > 0 {
139+
for _, remoteForward := range remoteForwards {
140+
isValid := validateRemoteForward(remoteForward)
141+
if !isValid {
142+
return xerrors.Errorf(`invalid format of remote-forward, expected: remote_port:local_address:local_port`)
143+
}
144+
if isValid && stdio {
145+
return xerrors.Errorf(`remote-forward can't be enabled in the stdio mode`)
146+
}
145147
}
146148
}
147149

@@ -311,18 +313,20 @@ func (r *RootCmd) ssh() *clibase.Cmd {
311313
}
312314
}
313315

314-
if remoteForward != "" {
315-
localAddr, remoteAddr, err := parseRemoteForward(remoteForward)
316-
if err != nil {
317-
return err
318-
}
316+
if len(remoteForwards) > 0 {
317+
for _, remoteForward := range remoteForwards {
318+
localAddr, remoteAddr, err := parseRemoteForward(remoteForward)
319+
if err != nil {
320+
return err
321+
}
319322

320-
closer, err := sshRemoteForward(ctx, inv.Stderr, sshClient, localAddr, remoteAddr)
321-
if err != nil {
322-
return xerrors.Errorf("ssh remote forward: %w", err)
323-
}
324-
if err = stack.push("sshRemoteForward", closer); err != nil {
325-
return err
323+
closer, err := sshRemoteForward(ctx, inv.Stderr, sshClient, localAddr, remoteAddr)
324+
if err != nil {
325+
return xerrors.Errorf("ssh remote forward: %w", err)
326+
}
327+
if err = stack.push("sshRemoteForward", closer); err != nil {
328+
return err
329+
}
326330
}
327331
}
328332

@@ -460,7 +464,7 @@ func (r *RootCmd) ssh() *clibase.Cmd {
460464
Description: "Enable remote port forwarding (remote_port:local_address:local_port).",
461465
Env: "CODER_SSH_REMOTE_FORWARD",
462466
FlagShorthand: "R",
463-
Value: clibase.StringOf(&remoteForward),
467+
Value: clibase.StringArrayOf(&remoteForwards),
464468
},
465469
sshDisableAutostartOption(clibase.BoolOf(&disableAutostart)),
466470
}

0 commit comments

Comments
 (0)