@@ -20,10 +20,13 @@ import (
20
20
"context"
21
21
"crypto/tls"
22
22
"fmt"
23
+ "io/ioutil"
23
24
"net/http"
24
25
"net/url"
25
26
"os"
27
+ "os/exec"
26
28
"path"
29
+ "path/filepath"
27
30
"strings"
28
31
"time"
29
32
@@ -42,9 +45,10 @@ import (
42
45
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
43
46
"k8s.io/apimachinery/pkg/types"
44
47
48
+ "github.com/fluxcd/pkg/apis/meta"
45
49
"github.com/fluxcd/pkg/gittestserver"
50
+ "github.com/fluxcd/pkg/untar"
46
51
47
- "github.com/fluxcd/pkg/apis/meta"
48
52
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
49
53
)
50
54
@@ -136,8 +140,6 @@ var _ = Describe("GitRepositoryReconciler", func() {
136
140
}})
137
141
Expect (err ).NotTo (HaveOccurred ())
138
142
139
- gitrepo .Worktree ()
140
-
141
143
for _ , ref := range t .createRefs {
142
144
hRef := plumbing .NewHashReference (plumbing .ReferenceName (ref ), commit )
143
145
err = gitrepo .Storer .SetReference (hRef )
@@ -410,5 +412,137 @@ var _ = Describe("GitRepositoryReconciler", func() {
410
412
gitImplementation : sourcev1 .GoGitImplementation ,
411
413
}),
412
414
)
415
+
416
+ Context ("recurse submodules" , func () {
417
+ It ("downloads submodules when asked" , func () {
418
+ Expect (gitServer .StartHTTP ()).To (Succeed ())
419
+ defer gitServer .StopHTTP ()
420
+
421
+ u , err := url .Parse (gitServer .HTTPAddress ())
422
+ Expect (err ).NotTo (HaveOccurred ())
423
+
424
+ subRepoURL := * u
425
+ subRepoURL .Path = path .Join (u .Path , fmt .Sprintf ("subrepository-%s.git" , randStringRunes (5 )))
426
+
427
+ // create the git repo to use as a submodule
428
+ fs := memfs .New ()
429
+ subRepo , err := git .Init (memory .NewStorage (), fs )
430
+ Expect (err ).NotTo (HaveOccurred ())
431
+
432
+ wt , err := subRepo .Worktree ()
433
+ Expect (err ).NotTo (HaveOccurred ())
434
+
435
+ ff , _ := fs .Create ("fixture" )
436
+ _ = ff .Close ()
437
+ _ , err = wt .Add (fs .Join ("fixture" ))
438
+ Expect (err ).NotTo (HaveOccurred ())
439
+
440
+ _ , err = wt .Commit ("Sample" , & git.CommitOptions {Author : & object.Signature {
441
+ Name : "John Doe" ,
442
+ Email : "john@example.com" ,
443
+ When : time .Now (),
444
+ }})
445
+ Expect (err ).NotTo (HaveOccurred ())
446
+
447
+ remote , err := subRepo .CreateRemote (& config.RemoteConfig {
448
+ Name : "origin" ,
449
+ URLs : []string {subRepoURL .String ()},
450
+ })
451
+ Expect (err ).NotTo (HaveOccurred ())
452
+
453
+ err = remote .Push (& git.PushOptions {
454
+ RefSpecs : []config.RefSpec {"refs/heads/*:refs/heads/*" , "refs/tags/*:refs/tags/*" },
455
+ })
456
+ Expect (err ).NotTo (HaveOccurred ())
457
+
458
+ // this one is linked to a real directory, so that I can
459
+ // exec `git submodule add` later
460
+ tmp , err := ioutil .TempDir ("" , "flux-test" )
461
+ Expect (err ).NotTo (HaveOccurred ())
462
+ defer os .RemoveAll (tmp )
463
+
464
+ repoDir := filepath .Join (tmp , "git" )
465
+ repo , err := git .PlainInit (repoDir , false )
466
+ Expect (err ).NotTo (HaveOccurred ())
467
+
468
+ wt , err = repo .Worktree ()
469
+ Expect (err ).NotTo (HaveOccurred ())
470
+ _ , err = wt .Commit ("Initial revision" , & git.CommitOptions {
471
+ Author : & object.Signature {
472
+ Name : "John Doe" ,
473
+ Email : "john@example.com" ,
474
+ When : time .Now (),
475
+ }})
476
+ Expect (err ).NotTo (HaveOccurred ())
477
+
478
+ submodAdd := exec .Command ("git" , "submodule" , "add" , "-b" , "master" , subRepoURL .String (), "sub" )
479
+ submodAdd .Dir = repoDir
480
+ out , err := submodAdd .CombinedOutput ()
481
+ os .Stdout .Write (out )
482
+ Expect (err ).NotTo (HaveOccurred ())
483
+
484
+ _ , err = wt .Commit ("Add submodule" , & git.CommitOptions {
485
+ Author : & object.Signature {
486
+ Name : "John Doe" ,
487
+ Email : "john@example.com" ,
488
+ When : time .Now (),
489
+ }})
490
+ Expect (err ).NotTo (HaveOccurred ())
491
+
492
+ mainRepoURL := * u
493
+ mainRepoURL .Path = path .Join (u .Path , fmt .Sprintf ("repository-%s.git" , randStringRunes (5 )))
494
+ remote , err = repo .CreateRemote (& config.RemoteConfig {
495
+ Name : "origin" ,
496
+ URLs : []string {mainRepoURL .String ()},
497
+ })
498
+ Expect (err ).NotTo (HaveOccurred ())
499
+
500
+ err = remote .Push (& git.PushOptions {
501
+ RefSpecs : []config.RefSpec {"refs/heads/*:refs/heads/*" , "refs/tags/*:refs/tags/*" },
502
+ })
503
+ Expect (err ).NotTo (HaveOccurred ())
504
+
505
+ key := types.NamespacedName {
506
+ Name : fmt .Sprintf ("git-ref-test-%s" , randStringRunes (5 )),
507
+ Namespace : namespace .Name ,
508
+ }
509
+ created := & sourcev1.GitRepository {
510
+ ObjectMeta : metav1.ObjectMeta {
511
+ Name : key .Name ,
512
+ Namespace : key .Namespace ,
513
+ },
514
+ Spec : sourcev1.GitRepositorySpec {
515
+ URL : mainRepoURL .String (),
516
+ Interval : metav1.Duration {Duration : indexInterval },
517
+ Reference : & sourcev1.GitRepositoryRef {Branch : "master" },
518
+ GitImplementation : sourcev1 .GoGitImplementation , // only works with go-git
519
+ RecurseSubmodules : true ,
520
+ },
521
+ }
522
+ Expect (k8sClient .Create (context .Background (), created )).Should (Succeed ())
523
+ defer k8sClient .Delete (context .Background (), created )
524
+
525
+ got := & sourcev1.GitRepository {}
526
+ Eventually (func () bool {
527
+ _ = k8sClient .Get (context .Background (), key , got )
528
+ for _ , c := range got .Status .Conditions {
529
+ if c .Reason == sourcev1 .GitOperationSucceedReason {
530
+ return true
531
+ }
532
+ }
533
+ return false
534
+ }, timeout , interval ).Should (BeTrue ())
535
+
536
+ // check that the downloaded artifact includes the
537
+ // file from the submodule
538
+ res , err := http .Get (got .Status .URL )
539
+ Expect (err ).NotTo (HaveOccurred ())
540
+ Expect (res .StatusCode ).To (Equal (http .StatusOK ))
541
+
542
+ _ , err = untar .Untar (res .Body , filepath .Join (tmp , "tar" ))
543
+ Expect (err ).NotTo (HaveOccurred ())
544
+ Expect (filepath .Join (tmp , "tar" , "sub" , "fixture" )).To (BeAnExistingFile ())
545
+ })
546
+ })
413
547
})
414
548
})
0 commit comments