Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Commit 102d4b5

Browse files
authored
Merge pull request #423 from smola/ssh-options
transport/ssh: allow passing SSH options
2 parents 5354ebc + 7368129 commit 102d4b5

File tree

1 file changed

+36
-3
lines changed

1 file changed

+36
-3
lines changed

plumbing/transport/ssh/common.go

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package ssh
33

44
import (
55
"fmt"
6+
"reflect"
67

78
"gopkg.in/src-d/go-git.v4/plumbing/transport"
89
"gopkg.in/src-d/go-git.v4/plumbing/transport/internal/common"
@@ -11,7 +12,12 @@ import (
1112
)
1213

1314
// DefaultClient is the default SSH client.
14-
var DefaultClient = common.NewClient(&runner{})
15+
var DefaultClient = NewClient(nil)
16+
17+
// NewClient creates a new SSH client with an optional *ssh.ClientConfig.
18+
func NewClient(config *ssh.ClientConfig) transport.Transport {
19+
return common.NewClient(&runner{config: config})
20+
}
1521

1622
// DefaultAuthBuilder is the function used to create a default AuthMethod, when
1723
// the user doesn't provide any.
@@ -21,10 +27,12 @@ var DefaultAuthBuilder = func(user string) (AuthMethod, error) {
2127

2228
const DefaultPort = 22
2329

24-
type runner struct{}
30+
type runner struct {
31+
config *ssh.ClientConfig
32+
}
2533

2634
func (r *runner) Command(cmd string, ep transport.Endpoint, auth transport.AuthMethod) (common.Command, error) {
27-
c := &command{command: cmd, endpoint: ep}
35+
c := &command{command: cmd, endpoint: ep, config: r.config}
2836
if auth != nil {
2937
c.setAuth(auth)
3038
}
@@ -42,6 +50,7 @@ type command struct {
4250
endpoint transport.Endpoint
4351
client *ssh.Client
4452
auth AuthMethod
53+
config *ssh.ClientConfig
4554
}
4655

4756
func (c *command) setAuth(auth transport.AuthMethod) error {
@@ -95,6 +104,8 @@ func (c *command) connect() error {
95104
return err
96105
}
97106

107+
overrideConfig(c.config, config)
108+
98109
c.client, err = ssh.Dial("tcp", c.getHostWithPort(), config)
99110
if err != nil {
100111
return err
@@ -129,3 +140,25 @@ func (c *command) setAuthFromEndpoint() error {
129140
func endpointToCommand(cmd string, ep transport.Endpoint) string {
130141
return fmt.Sprintf("%s '%s'", cmd, ep.Path())
131142
}
143+
144+
func overrideConfig(overrides *ssh.ClientConfig, c *ssh.ClientConfig) {
145+
if overrides == nil {
146+
return
147+
}
148+
149+
vo := reflect.ValueOf(*overrides)
150+
vc := reflect.ValueOf(*c)
151+
for i := 0; i < vc.Type().NumField(); i++ {
152+
vcf := vc.Field(i)
153+
vof := vo.Field(i)
154+
if isZeroValue(vcf) {
155+
vcf.Set(vof)
156+
}
157+
}
158+
159+
*c = vc.Interface().(ssh.ClientConfig)
160+
}
161+
162+
func isZeroValue(v reflect.Value) bool {
163+
return reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface())
164+
}

0 commit comments

Comments
 (0)