diff --git a/controllers/gitrepository_controller.go b/controllers/gitrepository_controller.go index f19e39793..1c2ca7b96 100644 --- a/controllers/gitrepository_controller.go +++ b/controllers/gitrepository_controller.go @@ -56,7 +56,6 @@ import ( "github.com/fluxcd/source-controller/internal/reconcile/summarize" "github.com/fluxcd/source-controller/internal/util" "github.com/fluxcd/source-controller/pkg/git" - "github.com/fluxcd/source-controller/pkg/git/libgit2/managed" "github.com/fluxcd/source-controller/pkg/git/strategy" "github.com/fluxcd/source-controller/pkg/sourceignore" ) @@ -117,14 +116,18 @@ type GitRepositoryReconciler struct { Storage *Storage ControllerName string - requeueDependency time.Duration - features map[string]bool + libgit2TransportInitialized func() bool + requeueDependency time.Duration + features map[string]bool } type GitRepositoryReconcilerOptions struct { - MaxConcurrentReconciles int - DependencyRequeueInterval time.Duration - RateLimiter ratelimiter.RateLimiter + MaxConcurrentReconciles int + DependencyRequeueInterval time.Duration + RateLimiter ratelimiter.RateLimiter + // Libgit2TransportInitialized lets the reconciler know whether + // libgit2 transport was intialized successfully. + Libgit2TransportInitialized func() bool } // gitRepositoryReconcileFunc is the function type for all the @@ -137,6 +140,7 @@ func (r *GitRepositoryReconciler) SetupWithManager(mgr ctrl.Manager) error { func (r *GitRepositoryReconciler) SetupWithManagerAndOptions(mgr ctrl.Manager, opts GitRepositoryReconcilerOptions) error { r.requeueDependency = opts.DependencyRequeueInterval + r.libgit2TransportInitialized = opts.Libgit2TransportInitialized if r.features == nil { r.features = map[string]bool{} @@ -236,7 +240,6 @@ func (r *GitRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Reques r.reconcileInclude, r.reconcileArtifact, } - recResult, retErr = r.reconcile(ctx, obj, reconcilers) return } @@ -430,8 +433,7 @@ func (r *GitRepositoryReconciler) reconcileStorage(ctx context.Context, func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, obj *sourcev1.GitRepository, commit *git.Commit, includes *artifactSet, dir string) (sreconcile.Result, error) { // Exit early, if we need to use libgit2 AND managed transport hasn't been intialized. - if !managed.Enabled() && obj.Spec.GitImplementation == sourcev1.LibGit2Implementation { - fmt.Println(managed.Enabled()) + if !r.libgit2TransportInitialized() && obj.Spec.GitImplementation == sourcev1.LibGit2Implementation { return sreconcile.ResultEmpty, serror.NewStalling( errors.New("libgit2 managed transport not initialized"), "Libgit2TransportNotEnabled", ) diff --git a/controllers/gitrepository_controller_test.go b/controllers/gitrepository_controller_test.go index addd25cac..f32365959 100644 --- a/controllers/gitrepository_controller_test.go +++ b/controllers/gitrepository_controller_test.go @@ -149,6 +149,14 @@ var ( testGitImplementations = []string{sourcev1.GoGitImplementation, sourcev1.LibGit2Implementation} ) +func transportNotInitialized() bool { + return false +} + +func transportInitialized() bool { + return true +} + func TestGitRepositoryReconciler_Reconcile(t *testing.T) { g := NewWithT(t) @@ -499,10 +507,11 @@ func TestGitRepositoryReconciler_reconcileSource_authStrategy(t *testing.T) { } r := &GitRepositoryReconciler{ - Client: builder.Build(), - EventRecorder: record.NewFakeRecorder(32), - Storage: testStorage, - features: features.FeatureGates(), + Client: builder.Build(), + EventRecorder: record.NewFakeRecorder(32), + Storage: testStorage, + features: features.FeatureGates(), + libgit2TransportInitialized: transportInitialized, } for _, i := range testGitImplementations { @@ -539,6 +548,39 @@ func TestGitRepositoryReconciler_reconcileSource_authStrategy(t *testing.T) { } } +func TestGitRepositoryReconciler_reconcileSource_libgit2Transport(t *testing.T) { + g := NewWithT(t) + + r := &GitRepositoryReconciler{ + Client: fakeclient.NewClientBuilder().WithScheme(runtime.NewScheme()).Build(), + EventRecorder: record.NewFakeRecorder(32), + Storage: testStorage, + features: features.FeatureGates(), + libgit2TransportInitialized: transportNotInitialized, + } + + obj := &sourcev1.GitRepository{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "libgit2-transport", + }, + Spec: sourcev1.GitRepositorySpec{ + Interval: metav1.Duration{Duration: interval}, + Timeout: &metav1.Duration{Duration: timeout}, + Reference: &sourcev1.GitRepositoryRef{ + Branch: git.DefaultBranch, + }, + GitImplementation: sourcev1.LibGit2Implementation, + }, + } + + tmpDir := t.TempDir() + var commit git.Commit + var includes artifactSet + _, err := r.reconcileSource(ctx, obj, &commit, &includes, tmpDir) + g.Expect(err).To(HaveOccurred()) + g.Expect(err.Error()).To(Equal("libgit2 managed transport not initialized")) +} + func TestGitRepositoryReconciler_reconcileSource_checkoutStrategy(t *testing.T) { g := NewWithT(t) @@ -697,10 +739,11 @@ func TestGitRepositoryReconciler_reconcileSource_checkoutStrategy(t *testing.T) } r := &GitRepositoryReconciler{ - Client: fakeclient.NewClientBuilder().WithScheme(runtime.NewScheme()).Build(), - EventRecorder: record.NewFakeRecorder(32), - Storage: testStorage, - features: features.FeatureGates(), + Client: fakeclient.NewClientBuilder().WithScheme(runtime.NewScheme()).Build(), + EventRecorder: record.NewFakeRecorder(32), + Storage: testStorage, + features: features.FeatureGates(), + libgit2TransportInitialized: transportInitialized, } for _, tt := range tests { @@ -1558,10 +1601,11 @@ func TestGitRepositoryReconciler_ConditionsUpdate(t *testing.T) { builder := fakeclient.NewClientBuilder().WithScheme(testEnv.GetScheme()).WithObjects(obj) r := &GitRepositoryReconciler{ - Client: builder.Build(), - EventRecorder: record.NewFakeRecorder(32), - Storage: testStorage, - features: features.FeatureGates(), + Client: builder.Build(), + EventRecorder: record.NewFakeRecorder(32), + Storage: testStorage, + features: features.FeatureGates(), + libgit2TransportInitialized: transportInitialized, } key := client.ObjectKeyFromObject(obj) diff --git a/controllers/suite_test.go b/controllers/suite_test.go index 43053e2d3..3be74c56a 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -205,7 +205,9 @@ func TestMain(m *testing.M) { panic(fmt.Sprintf("Failed to create a test registry server: %v", err)) } - managed.InitManagedTransport() + if err = managed.InitManagedTransport(); err != nil { + panic(fmt.Sprintf("Failed to initialize libgit2 managed transport: %v", err)) + } if err := (&GitRepositoryReconciler{ Client: testEnv, @@ -213,7 +215,9 @@ func TestMain(m *testing.M) { Metrics: testMetricsH, Storage: testStorage, features: features.FeatureGates(), - }).SetupWithManager(testEnv); err != nil { + }).SetupWithManagerAndOptions(testEnv, GitRepositoryReconcilerOptions{ + Libgit2TransportInitialized: transportInitialized, + }); err != nil { panic(fmt.Sprintf("Failed to start GitRepositoryReconciler: %v", err)) } diff --git a/main.go b/main.go index 2fc351fbc..aacd2c04a 100644 --- a/main.go +++ b/main.go @@ -204,6 +204,11 @@ func main() { } storage := mustInitStorage(storagePath, storageAdvAddr, artifactRetentionTTL, artifactRetentionRecords, setupLog) + if err = managed.InitManagedTransport(); err != nil { + // Log the error, but don't exit so as to not block reconcilers that are healthy. + setupLog.Error(err, "unable to initialize libgit2 managed transport") + } + if err = (&controllers.GitRepositoryReconciler{ Client: mgr.GetClient(), EventRecorder: eventRecorder, @@ -211,9 +216,10 @@ func main() { Storage: storage, ControllerName: controllerName, }).SetupWithManagerAndOptions(mgr, controllers.GitRepositoryReconcilerOptions{ - MaxConcurrentReconciles: concurrent, - DependencyRequeueInterval: requeueDependency, - RateLimiter: helper.GetRateLimiter(rateLimiterOptions), + MaxConcurrentReconciles: concurrent, + DependencyRequeueInterval: requeueDependency, + RateLimiter: helper.GetRateLimiter(rateLimiterOptions), + Libgit2TransportInitialized: managed.Enabled, }); err != nil { setupLog.Error(err, "unable to create controller", "controller", sourcev1.GitRepositoryKind) os.Exit(1) @@ -310,11 +316,6 @@ func main() { startFileServer(storage.BasePath, storageAddr, setupLog) }() - if err = managed.InitManagedTransport(); err != nil { - // Log the error, but don't exit so as to not block reconcilers that are healthy. - setupLog.Error(err, "unable to initialize libgit2 managed transport") - } - setupLog.Info("starting manager") if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { setupLog.Error(err, "problem running manager")