Skip to content

Commit 4b3e0f9

Browse files
author
Paulo Gomes
authored
Merge pull request #740 from pjbgf/ssh-context
libgit2: enforce context timeout
2 parents 7953d0e + 978148e commit 4b3e0f9

File tree

5 files changed

+34
-12
lines changed

5 files changed

+34
-12
lines changed

controllers/gitrepository_controller.go

+4-5
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,10 @@ func (r *GitRepositoryReconciler) gitCheckout(ctx context.Context,
721721
}
722722
}
723723

724-
checkoutStrategy, err := strategy.CheckoutStrategyForImplementation(ctx,
724+
gitCtx, cancel := context.WithTimeout(ctx, obj.Spec.Timeout.Duration)
725+
defer cancel()
726+
727+
checkoutStrategy, err := strategy.CheckoutStrategyForImplementation(gitCtx,
725728
git.Implementation(obj.Spec.GitImplementation), checkoutOpts)
726729
if err != nil {
727730
// Do not return err as recovery without changes is impossible.
@@ -753,10 +756,6 @@ func (r *GitRepositoryReconciler) gitCheckout(ctx context.Context,
753756
}
754757
}
755758

756-
// Checkout HEAD of reference in object
757-
gitCtx, cancel := context.WithTimeout(ctx, obj.Spec.Timeout.Duration)
758-
defer cancel()
759-
760759
commit, err := checkoutStrategy.Checkout(gitCtx, dir, obj.Spec.URL, authOpts)
761760
if err != nil {
762761
e := serror.NewGeneric(

pkg/git/libgit2/checkout.go

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ func (c *CheckoutBranch) Checkout(ctx context.Context, path, url string, opts *g
9191
TargetURL: url,
9292
AuthOpts: opts,
9393
ProxyOptions: &git2go.ProxyOptions{Type: git2go.ProxyTypeAuto},
94+
Context: ctx,
9495
})
9596
url = opts.TransportOptionsURL
9697
remoteCallBacks := managed.RemoteCallbacks()

pkg/git/libgit2/managed/options.go

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package managed
1818

1919
import (
20+
"context"
2021
"sync"
2122

2223
"github.com/fluxcd/source-controller/pkg/git"
@@ -29,6 +30,7 @@ type TransportOptions struct {
2930
TargetURL string
3031
AuthOpts *git.AuthOptions
3132
ProxyOptions *git2go.ProxyOptions
33+
Context context.Context
3234
}
3335

3436
var (

pkg/git/libgit2/managed/ssh.go

+26-6
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ type sshSmartSubtransport struct {
9292
currentStream *sshSmartSubtransportStream
9393
addr string
9494
connected bool
95+
ctx context.Context
9596
}
9697

9798
func (t *sshSmartSubtransport) Action(transportOptionsURL string, action git2go.SmartServiceAction) (git2go.SmartSubtransportStream, error) {
@@ -103,6 +104,8 @@ func (t *sshSmartSubtransport) Action(transportOptionsURL string, action git2go.
103104
return nil, fmt.Errorf("could not find transport options for object: %s", transportOptionsURL)
104105
}
105106

107+
t.ctx = opts.Context
108+
106109
u, err := url.Parse(opts.TargetURL)
107110
if err != nil {
108111
return nil, err
@@ -206,16 +209,33 @@ func (t *sshSmartSubtransport) Action(transportOptionsURL string, action git2go.
206209
// xref: https://github.com/golang/crypto/blob/eb4f295cb31f7fb5d52810411604a2638c9b19a2/ssh/session.go#L553-L558
207210
go func() error {
208211
defer w.Close()
212+
213+
var cancel context.CancelFunc
214+
ctx := t.ctx
215+
216+
// When context is nil, creates a new with internal SSH connection timeout.
217+
if ctx == nil {
218+
ctx, cancel = context.WithTimeout(context.Background(), sshConnectionTimeOut)
219+
defer cancel()
220+
}
221+
209222
for {
210-
if !t.connected {
223+
select {
224+
case <-ctx.Done():
225+
t.Close()
211226
return nil
212-
}
213227

214-
_, err := io.Copy(w, reader)
215-
if err != nil {
216-
return err
228+
default:
229+
if !t.connected {
230+
return nil
231+
}
232+
233+
_, err := io.Copy(w, reader)
234+
if err != nil {
235+
return err
236+
}
237+
time.Sleep(5 * time.Millisecond)
217238
}
218-
time.Sleep(5 * time.Millisecond)
219239
}
220240
}()
221241

pkg/git/strategy/proxy/strategy_proxy_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
292292

293293
return nil, func() {}
294294
},
295-
shortTimeout: false,
295+
shortTimeout: true,
296296
wantUsedProxy: false,
297297
wantError: true,
298298
},

0 commit comments

Comments
 (0)