@@ -21,11 +21,18 @@ import (
2121 "crypto/sha256"
2222 "encoding/hex"
2323 "io"
24+ "net/url"
2425 "os"
2526 "path"
27+ "path/filepath"
2628 "testing"
29+ "time"
2730
31+ "github.com/fluxcd/pkg/gittestserver"
32+ "github.com/fluxcd/pkg/ssh"
2833 git2go "github.com/libgit2/git2go/v31"
34+ . "github.com/onsi/gomega"
35+ corev1 "k8s.io/api/core/v1"
2936
3037 "github.com/fluxcd/source-controller/pkg/git"
3138)
@@ -77,3 +84,73 @@ func TestCheckoutTagSemVer_Checkout(t *testing.T) {
7784 t .Errorf ("expected semver hash %s, got %s" , cTag .Hash (), cSemVer .Hash ())
7885 }
7986}
87+
88+ // This test is specifically to detect regression in libgit2's ED25519 key
89+ // support.
90+ // Refer: https://github.com/fluxcd/source-controller/issues/399
91+ func TestCheckout_ED25519 (t * testing.T ) {
92+ g := NewWithT (t )
93+ timeout := 5 * time .Second
94+
95+ // Create a git test server.
96+ server , err := gittestserver .NewTempGitServer ()
97+ g .Expect (err ).ToNot (HaveOccurred ())
98+ defer os .RemoveAll (server .Root ())
99+ server .Auth ("test-user" , "test-pswd" )
100+ server .AutoCreate ()
101+
102+ server .KeyDir (filepath .Join (server .Root (), "keys" ))
103+ g .Expect (server .ListenSSH ()).To (Succeed ())
104+
105+ go func () {
106+ server .StartSSH ()
107+ }()
108+ defer server .StopSSH ()
109+
110+ repoPath := "test.git"
111+
112+ err = server .InitRepo ("testdata/git/repo" , git .DefaultBranch , repoPath )
113+ g .Expect (err ).NotTo (HaveOccurred ())
114+
115+ sshURL := server .SSHAddress ()
116+ repoURL := sshURL + "/" + repoPath
117+
118+ // Fetch host key.
119+ u , err := url .Parse (sshURL )
120+ g .Expect (err ).NotTo (HaveOccurred ())
121+ g .Expect (u .Host ).ToNot (BeEmpty ())
122+ knownHosts , err := ssh .ScanHostKey (u .Host , timeout )
123+ g .Expect (err ).ToNot (HaveOccurred ())
124+
125+ kp , err := ssh .NewEd25519Generator ().Generate ()
126+ g .Expect (err ).ToNot (HaveOccurred ())
127+
128+ secret := corev1.Secret {
129+ Data : map [string ][]byte {
130+ "identity" : kp .PrivateKey ,
131+ "known_hosts" : knownHosts ,
132+ },
133+ }
134+
135+ authStrategy , err := AuthSecretStrategyForURL (repoURL )
136+ g .Expect (err ).ToNot (HaveOccurred ())
137+ gitAuth , err := authStrategy .Method (secret )
138+ g .Expect (err ).ToNot (HaveOccurred ())
139+
140+ // Prepare for checkout.
141+ branchCheckoutStrat := & CheckoutBranch {branch : git .DefaultBranch }
142+ tmpDir , _ := os .MkdirTemp ("" , "test" )
143+ defer os .RemoveAll (tmpDir )
144+
145+ ctx , cancel := context .WithTimeout (context .TODO (), timeout )
146+ defer cancel ()
147+
148+ // Checkout the repo.
149+ // This should always fail because the generated key above isn't present in
150+ // the git server.
151+ _ , _ , err = branchCheckoutStrat .Checkout (ctx , tmpDir , repoURL , gitAuth )
152+ g .Expect (err ).To (HaveOccurred ())
153+ // NOTE: libgit2 v1.2+ supports ED25519. Flip this condition after updating
154+ // to libgit2 v1.2+.
155+ g .Expect (err .Error ()).To (ContainSubstring ("Unable to extract public key from private key" ))
156+ }
0 commit comments