@@ -20,6 +20,7 @@ import (
2020 "context"
2121 "errors"
2222 "fmt"
23+ "net/url"
2324 "os"
2425 "path/filepath"
2526 "strings"
@@ -41,6 +42,9 @@ import (
4142 "sigs.k8s.io/controller-runtime/pkg/ratelimiter"
4243
4344 "github.com/fluxcd/pkg/apis/meta"
45+ "github.com/fluxcd/pkg/git"
46+ "github.com/fluxcd/pkg/git/gogit"
47+ "github.com/fluxcd/pkg/git/libgit2"
4448 "github.com/fluxcd/pkg/runtime/conditions"
4549 helper "github.com/fluxcd/pkg/runtime/controller"
4650 "github.com/fluxcd/pkg/runtime/events"
@@ -54,8 +58,6 @@ import (
5458 sreconcile "github.com/fluxcd/source-controller/internal/reconcile"
5559 "github.com/fluxcd/source-controller/internal/reconcile/summarize"
5660 "github.com/fluxcd/source-controller/internal/util"
57- "github.com/fluxcd/source-controller/pkg/git"
58- "github.com/fluxcd/source-controller/pkg/git/strategy"
5961)
6062
6163// gitRepositoryReadyCondition contains the information required to summarize a
@@ -440,9 +442,7 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context,
440442 conditions .Delete (obj , sourcev1 .SourceVerifiedCondition )
441443 }
442444
443- // Configure authentication strategy to access the source
444- var authOpts * git.AuthOptions
445- var err error
445+ var authData map [string ][]byte
446446 if obj .Spec .SecretRef != nil {
447447 // Attempt to retrieve secret
448448 name := types.NamespacedName {
@@ -459,20 +459,27 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context,
459459 // Return error as the world as observed may change
460460 return sreconcile .ResultEmpty , e
461461 }
462+ authData = secret .Data
463+ }
462464
463- // Configure strategy with secret
464- authOpts , err = git .AuthOptionsFromSecret (obj .Spec .URL , & secret )
465- } else {
466- // Set the minimal auth options for valid transport.
467- authOpts , err = git .AuthOptionsWithoutSecret (obj .Spec .URL )
465+ u , err := url .Parse (obj .Spec .URL )
466+ if err != nil {
467+ e := serror .NewStalling (
468+ fmt .Errorf ("failed to parse url '%s': %w" , obj .Spec .URL , err ),
469+ sourcev1 .URLInvalidReason ,
470+ )
471+ conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , e .Reason , e .Err .Error ())
472+ return sreconcile .ResultEmpty , e
468473 }
474+
475+ // Configure authentication strategy to access the source
476+ authOpts , err := git .NewAuthOptions (* u , authData )
469477 if err != nil {
470478 e := serror .NewGeneric (
471- fmt .Errorf ("failed to configure auth strategy for Git implementation '%s' : %w" , obj . Spec . GitImplementation , err ),
479+ fmt .Errorf ("failed to configure authentication options : %w" , err ),
472480 sourcev1 .AuthenticationFailedReason ,
473481 )
474482 conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , e .Reason , e .Err .Error ())
475- // Return error as the contents of the secret may change
476483 return sreconcile .ResultEmpty , e
477484 }
478485
@@ -725,59 +732,52 @@ func (r *GitRepositoryReconciler) reconcileInclude(ctx context.Context,
725732func (r * GitRepositoryReconciler ) gitCheckout (ctx context.Context ,
726733 obj * sourcev1.GitRepository , authOpts * git.AuthOptions , dir string , optimized bool ) (* git.Commit , error ) {
727734 // Configure checkout strategy.
728- checkoutOpts := git.CheckoutOptions {RecurseSubmodules : obj .Spec .RecurseSubmodules }
735+ cloneOpts := git.CloneOptions {
736+ RecurseSubmodules : obj .Spec .RecurseSubmodules ,
737+ ShallowClone : true ,
738+ }
729739 if ref := obj .Spec .Reference ; ref != nil {
730- checkoutOpts .Branch = ref .Branch
731- checkoutOpts .Commit = ref .Commit
732- checkoutOpts .Tag = ref .Tag
733- checkoutOpts .SemVer = ref .SemVer
740+ cloneOpts .Branch = ref .Branch
741+ cloneOpts .Commit = ref .Commit
742+ cloneOpts .Tag = ref .Tag
743+ cloneOpts .SemVer = ref .SemVer
734744 }
735745
736746 // Only if the object has an existing artifact in storage, attempt to
737747 // short-circuit clone operation. reconcileStorage has already verified
738748 // that the artifact exists.
739749 if optimized && conditions .IsTrue (obj , sourcev1 .ArtifactInStorageCondition ) {
740750 if artifact := obj .GetArtifact (); artifact != nil {
741- checkoutOpts . LastRevision = artifact .Revision
751+ cloneOpts . LastObservedCommit = artifact .Revision
742752 }
743753 }
744754
745755 gitCtx , cancel := context .WithTimeout (ctx , obj .Spec .Timeout .Duration )
746756 defer cancel ()
747757
748- checkoutStrategy , err := strategy .CheckoutStrategyForImplementation (gitCtx ,
749- git .Implementation (obj .Spec .GitImplementation ), checkoutOpts )
758+ var gitReader git.RepositoryReader
759+ var err error
760+
761+ switch obj .Spec .GitImplementation {
762+ case sourcev1 .LibGit2Implementation :
763+ gitReader , err = libgit2 .NewClient (dir , authOpts )
764+ case sourcev1 .GoGitImplementation :
765+ gitReader , err = gogit .NewClient (dir , authOpts )
766+ default :
767+ err = fmt .Errorf ("invalid Git implementation: %s" , obj .Spec .GitImplementation )
768+ }
750769 if err != nil {
751770 // Do not return err as recovery without changes is impossible.
752- e := & serror.Stalling {
753- Err : fmt .Errorf ("failed to configure checkout strategy for Git implementation '%s': %w" , obj .Spec .GitImplementation , err ),
754- Reason : sourcev1 .GitOperationFailedReason ,
755- }
771+ e := serror .NewStalling (
772+ fmt .Errorf ("failed to create Git client for implementation '%s': %w" , obj .Spec .GitImplementation , err ),
773+ sourcev1 .GitOperationFailedReason ,
774+ )
756775 conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , e .Reason , e .Err .Error ())
757776 return nil , e
758777 }
778+ defer gitReader .Close ()
759779
760- // this is needed only for libgit2, due to managed transport.
761- if obj .Spec .GitImplementation == sourcev1 .LibGit2Implementation {
762- // We set the TransportOptionsURL of this set of authentication options here by constructing
763- // a unique URL that won't clash in a multi tenant environment. This unique URL is used by
764- // libgit2 managed transports. This enables us to bypass the inbuilt credentials callback in
765- // libgit2, which is inflexible and unstable.
766- if strings .HasPrefix (obj .Spec .URL , "http" ) {
767- authOpts .TransportOptionsURL = fmt .Sprintf ("http://%s/%s/%d" , obj .Name , obj .UID , obj .Generation )
768- } else if strings .HasPrefix (obj .Spec .URL , "ssh" ) {
769- authOpts .TransportOptionsURL = fmt .Sprintf ("ssh://%s/%s/%d" , obj .Name , obj .UID , obj .Generation )
770- } else {
771- e := & serror.Stalling {
772- Err : fmt .Errorf ("git repository URL '%s' has invalid transport type, supported types are: http, https, ssh" , obj .Spec .URL ),
773- Reason : sourcev1 .URLInvalidReason ,
774- }
775- conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , e .Reason , e .Err .Error ())
776- return nil , e
777- }
778- }
779-
780- commit , err := checkoutStrategy .Checkout (gitCtx , dir , obj .Spec .URL , authOpts )
780+ commit , err := gitReader .Clone (gitCtx , obj .Spec .URL , cloneOpts )
781781 if err != nil {
782782 e := serror .NewGeneric (
783783 fmt .Errorf ("failed to checkout and determine revision: %w" , err ),
@@ -786,6 +786,7 @@ func (r *GitRepositoryReconciler) gitCheckout(ctx context.Context,
786786 conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , e .Reason , e .Err .Error ())
787787 return nil , e
788788 }
789+
789790 return commit , nil
790791}
791792
0 commit comments