Skip to content

Commit 5b15bb7

Browse files
author
Paulo Gomes
committed
Implement Managed Transport for libgit2
libgit2 network operations are blocking and do not provide timeout nor context capabilities, leading to several reports of the controllers hanging indefinitely. By using managed transport, golang primitives such as http.Transport and net.Dial can be used to ensure timeouts are enforced. Signed-off-by: Paulo Gomes <[email protected]>
1 parent 4d8ebe6 commit 5b15bb7

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

controllers/imageupdateautomation_controller.go

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ import (
6262
sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
6363
"github.com/fluxcd/source-controller/pkg/git"
6464
gitlibgit2 "github.com/fluxcd/source-controller/pkg/git/libgit2"
65+
"github.com/fluxcd/source-controller/pkg/git/libgit2/managed"
6566
gitstrat "github.com/fluxcd/source-controller/pkg/git/strategy"
6667

6768
imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta1"
@@ -247,6 +248,34 @@ func (r *ImageUpdateAutomationReconciler) Reconcile(ctx context.Context, req ctr
247248
return failWithError(err)
248249
}
249250

251+
repositoryURL := origin.Spec.URL
252+
if managed.Enabled() {
253+
// At present only HTTP connections have the ability to define remote options.
254+
// Although this can be easily extended by ensuring that the fake URL below uses the
255+
// target ssh scheme, and the libgit2/managed/ssh.go pulls that information accordingly.
256+
//
257+
// This is due to the fact the key libgit2 remote callbacks do not take place for HTTP
258+
// whilst most still work for SSH.
259+
if strings.HasPrefix(repositoryURL, "http") {
260+
if access.auth != nil && len(access.auth.CAFile) > 0 {
261+
// Due to the lack of the callback feature, a fake target URL is created to allow
262+
// for the smart sub transport be able to pick the options specific for this
263+
// GitRepository object.
264+
// The URL should use unique information that do not collide in a multi tenant
265+
// deployment.
266+
repositoryURL = fmt.Sprintf("http://%s/%s/%d", auto.Name, auto.UID, auto.Generation)
267+
managed.AddTransportOptions(repositoryURL,
268+
managed.TransportOptions{
269+
TargetURL: repositoryURL,
270+
CABundle: access.auth.CAFile,
271+
})
272+
273+
// We remove the options from memory, to avoid accumulating unused options over time.
274+
defer managed.RemoveTransportOptions(repositoryURL)
275+
}
276+
}
277+
}
278+
250279
// Use the git operations timeout for the repo.
251280
cloneCtx, cancel := context.WithTimeout(ctx, origin.Spec.Timeout.Duration)
252281
defer cancel()
@@ -470,12 +499,6 @@ func (r *ImageUpdateAutomationReconciler) automationsForImagePolicy(obj client.O
470499
return reqs
471500
}
472501

473-
// --- git ops
474-
475-
// Note: libgit2 is always used for network operations; for cloning,
476-
// it will do a non-shallow clone, and for anything else, it doesn't
477-
// matter what is used.
478-
479502
type repoAccess struct {
480503
auth *git.AuthOptions
481504
url string

main.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ import (
4040
sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
4141

4242
imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta1"
43+
"github.com/fluxcd/source-controller/pkg/git/libgit2/managed"
44+
4345
// +kubebuilder:scaffold:imports
4446
"github.com/fluxcd/image-automation-controller/controllers"
4547
)
@@ -137,6 +139,10 @@ func main() {
137139
}
138140
// +kubebuilder:scaffold:builder
139141

142+
if managed.Enabled() {
143+
managed.InitManagedTransport()
144+
}
145+
140146
setupLog.Info("starting manager")
141147
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
142148
setupLog.Error(err, "problem running manager")

0 commit comments

Comments
 (0)