@@ -20,6 +20,7 @@ import (
20
20
"context"
21
21
"errors"
22
22
"fmt"
23
+ "net/url"
23
24
"os"
24
25
"path/filepath"
25
26
"strings"
@@ -41,6 +42,9 @@ import (
41
42
"sigs.k8s.io/controller-runtime/pkg/ratelimiter"
42
43
43
44
"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"
44
48
"github.com/fluxcd/pkg/runtime/conditions"
45
49
helper "github.com/fluxcd/pkg/runtime/controller"
46
50
"github.com/fluxcd/pkg/runtime/events"
@@ -54,8 +58,6 @@ import (
54
58
sreconcile "github.com/fluxcd/source-controller/internal/reconcile"
55
59
"github.com/fluxcd/source-controller/internal/reconcile/summarize"
56
60
"github.com/fluxcd/source-controller/internal/util"
57
- "github.com/fluxcd/source-controller/pkg/git"
58
- "github.com/fluxcd/source-controller/pkg/git/strategy"
59
61
)
60
62
61
63
// gitRepositoryReadyCondition contains the information required to summarize a
@@ -440,9 +442,7 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context,
440
442
conditions .Delete (obj , sourcev1 .SourceVerifiedCondition )
441
443
}
442
444
443
- // Configure authentication strategy to access the source
444
- var authOpts * git.AuthOptions
445
- var err error
445
+ var authData map [string ][]byte
446
446
if obj .Spec .SecretRef != nil {
447
447
// Attempt to retrieve secret
448
448
name := types.NamespacedName {
@@ -459,20 +459,27 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context,
459
459
// Return error as the world as observed may change
460
460
return sreconcile .ResultEmpty , e
461
461
}
462
+ authData = secret .Data
463
+ }
462
464
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
468
473
}
474
+
475
+ // Configure authentication strategy to access the source
476
+ authOpts , err := git .NewAuthOptions (* u , authData )
469
477
if err != nil {
470
478
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 ),
472
480
sourcev1 .AuthenticationFailedReason ,
473
481
)
474
482
conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , e .Reason , e .Err .Error ())
475
- // Return error as the contents of the secret may change
476
483
return sreconcile .ResultEmpty , e
477
484
}
478
485
@@ -725,59 +732,52 @@ func (r *GitRepositoryReconciler) reconcileInclude(ctx context.Context,
725
732
func (r * GitRepositoryReconciler ) gitCheckout (ctx context.Context ,
726
733
obj * sourcev1.GitRepository , authOpts * git.AuthOptions , dir string , optimized bool ) (* git.Commit , error ) {
727
734
// Configure checkout strategy.
728
- checkoutOpts := git.CheckoutOptions {RecurseSubmodules : obj .Spec .RecurseSubmodules }
735
+ cloneOpts := git.CloneOptions {
736
+ RecurseSubmodules : obj .Spec .RecurseSubmodules ,
737
+ ShallowClone : true ,
738
+ }
729
739
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
734
744
}
735
745
736
746
// Only if the object has an existing artifact in storage, attempt to
737
747
// short-circuit clone operation. reconcileStorage has already verified
738
748
// that the artifact exists.
739
749
if optimized && conditions .IsTrue (obj , sourcev1 .ArtifactInStorageCondition ) {
740
750
if artifact := obj .GetArtifact (); artifact != nil {
741
- checkoutOpts . LastRevision = artifact .Revision
751
+ cloneOpts . LastObservedCommit = artifact .Revision
742
752
}
743
753
}
744
754
745
755
gitCtx , cancel := context .WithTimeout (ctx , obj .Spec .Timeout .Duration )
746
756
defer cancel ()
747
757
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
+ }
750
769
if err != nil {
751
770
// 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
+ )
756
775
conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , e .Reason , e .Err .Error ())
757
776
return nil , e
758
777
}
778
+ defer gitReader .Close ()
759
779
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 )
781
781
if err != nil {
782
782
e := serror .NewGeneric (
783
783
fmt .Errorf ("failed to checkout and determine revision: %w" , err ),
@@ -786,6 +786,7 @@ func (r *GitRepositoryReconciler) gitCheckout(ctx context.Context,
786
786
conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , e .Reason , e .Err .Error ())
787
787
return nil , e
788
788
}
789
+
789
790
return commit , nil
790
791
}
791
792
0 commit comments