@@ -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 data map [string ][]byte
446
446
if obj .Spec .SecretRef != nil {
447
447
// Attempt to retrieve secret
448
448
name := types.NamespacedName {
@@ -459,12 +459,29 @@ 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
+ data = 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
473
+ }
474
+
475
+ // Configure authentication strategy to access the source
476
+ authOpts , err := git .NewAuthOptions (* u , data )
477
+
478
+ if err != nil {
479
+ e := serror .NewGeneric (
480
+ fmt .Errorf ("failed to configure authentication options: %w" , err ),
481
+ sourcev1 .AuthenticationFailedReason ,
482
+ )
483
+ conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , e .Reason , e .Err .Error ())
484
+ return sreconcile .ResultEmpty , e
468
485
}
469
486
if err != nil {
470
487
e := serror .NewGeneric (
@@ -725,59 +742,49 @@ func (r *GitRepositoryReconciler) reconcileInclude(ctx context.Context,
725
742
func (r * GitRepositoryReconciler ) gitCheckout (ctx context.Context ,
726
743
obj * sourcev1.GitRepository , authOpts * git.AuthOptions , dir string , optimized bool ) (* git.Commit , error ) {
727
744
// Configure checkout strategy.
728
- checkoutOpts := git.CheckoutOptions {RecurseSubmodules : obj .Spec .RecurseSubmodules }
745
+ cloneOpts := git.CloneOptions {
746
+ RecurseSubmodules : obj .Spec .RecurseSubmodules ,
747
+ ShallowClone : true ,
748
+ }
729
749
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
750
+ cloneOpts .Branch = ref .Branch
751
+ cloneOpts .Commit = ref .Commit
752
+ cloneOpts .Tag = ref .Tag
753
+ cloneOpts .SemVer = ref .SemVer
734
754
}
735
755
736
756
// Only if the object has an existing artifact in storage, attempt to
737
757
// short-circuit clone operation. reconcileStorage has already verified
738
758
// that the artifact exists.
739
759
if optimized && conditions .IsTrue (obj , sourcev1 .ArtifactInStorageCondition ) {
740
760
if artifact := obj .GetArtifact (); artifact != nil {
741
- checkoutOpts . LastRevision = artifact .Revision
761
+ cloneOpts . LastObservedCommit = artifact .Revision
742
762
}
743
763
}
744
764
745
765
gitCtx , cancel := context .WithTimeout (ctx , obj .Spec .Timeout .Duration )
746
766
defer cancel ()
747
767
748
- checkoutStrategy , err := strategy .CheckoutStrategyForImplementation (gitCtx ,
749
- git .Implementation (obj .Spec .GitImplementation ), checkoutOpts )
768
+ var gitReader git.RepositoryReader
769
+ var err error
770
+
771
+ if obj .Spec .GitImplementation == libgit2 .ClientName {
772
+ gitReader , err = libgit2 .NewClient (dir , authOpts )
773
+ } else {
774
+ gitReader , err = gogit .NewClient (dir , authOpts )
775
+ }
750
776
if err != nil {
751
777
// Do not return err as recovery without changes is impossible.
752
778
e := & serror.Stalling {
753
- Err : fmt .Errorf ("failed to configure checkout strategy for Git implementation '%s': %w" , obj .Spec .GitImplementation , err ),
779
+ Err : fmt .Errorf ("failed to create Git client for implementation '%s': %w" , obj .Spec .GitImplementation , err ),
754
780
Reason : sourcev1 .GitOperationFailedReason ,
755
781
}
756
782
conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , e .Reason , e .Err .Error ())
757
783
return nil , e
758
784
}
785
+ defer gitReader .Close ()
759
786
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 )
787
+ commit , err := gitReader .Clone (gitCtx , obj .Spec .URL , cloneOpts )
781
788
if err != nil {
782
789
e := serror .NewGeneric (
783
790
fmt .Errorf ("failed to checkout and determine revision: %w" , err ),
@@ -786,6 +793,7 @@ func (r *GitRepositoryReconciler) gitCheckout(ctx context.Context,
786
793
conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , e .Reason , e .Err .Error ())
787
794
return nil , e
788
795
}
796
+
789
797
return commit , nil
790
798
}
791
799
0 commit comments