@@ -6,6 +6,7 @@ package provider
6
6
import (
7
7
"bufio"
8
8
"context"
9
+ "fmt"
9
10
"io"
10
11
"os"
11
12
"path/filepath"
@@ -14,19 +15,45 @@ import (
14
15
"testing"
15
16
16
17
"github.com/coder/terraform-provider-envbuilder/testutil/registrytest"
18
+ "github.com/go-git/go-git/v5"
19
+ "github.com/go-git/go-git/v5/plumbing"
20
+ "github.com/go-git/go-git/v5/plumbing/object"
17
21
"github.com/hashicorp/terraform-plugin-framework/providerserver"
18
22
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
19
23
20
24
"github.com/docker/docker/api/types/container"
21
25
"github.com/docker/docker/api/types/image"
22
26
"github.com/docker/docker/client"
27
+ "github.com/docker/go-connections/nat"
23
28
"github.com/stretchr/testify/require"
24
29
)
25
30
26
31
const (
27
32
testContainerLabel = "terraform-provider-envbuilder-test"
28
33
)
29
34
35
+ // nolint:gosec // Throw-away key for testing. DO NOT REUSE.
36
+ const (
37
+ testSSHHostKey = `-----BEGIN OPENSSH PRIVATE KEY-----
38
+ b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
39
+ QyNTUxOQAAACDBC7DRHALRN3JJrkDQETyL2Vg5O6QsWTE2YWAt9bIZiAAAAKj5O8yU+TvM
40
+ lAAAAAtzc2gtZWQyNTUxOQAAACDBC7DRHALRN3JJrkDQETyL2Vg5O6QsWTE2YWAt9bIZiA
41
+ AAAED9b0qGgjoDx9YiyCHGBE6ogdnD6IbQsgfaFDI0aE+x3cELsNEcAtE3ckmuQNARPIvZ
42
+ WDk7pCxZMTZhYC31shmIAAAAInRlcnJhZm9ybS1wcm92aWRlci1lbnZidWlsZGVyLXRlc3
43
+ QBAgM=
44
+ -----END OPENSSH PRIVATE KEY-----`
45
+ testSSHHostPubKey = `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMELsNEcAtE3ckmuQNARPIvZWDk7pCxZMTZhYC31shmI terraform-provider-envbuilder-test`
46
+ testSSHUserKey = `-----BEGIN OPENSSH PRIVATE KEY-----
47
+ b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
48
+ QyNTUxOQAAACCtxz9h0yXzi/HqZBpSkA2xFo28v5W8O4HimI0ZzNpQkwAAAKhv/+X2b//l
49
+ 9gAAAAtzc2gtZWQyNTUxOQAAACCtxz9h0yXzi/HqZBpSkA2xFo28v5W8O4HimI0ZzNpQkw
50
+ AAAED/G0HuohvSa8q6NzkZ+wRPW0PhPpo9Th8fvcBQDaxCia3HP2HTJfOL8epkGlKQDbEW
51
+ jby/lbw7geKYjRnM2lCTAAAAInRlcnJhZm9ybS1wcm92aWRlci1lbnZidWlsZGVyLXRlc3
52
+ QBAgM=
53
+ -----END OPENSSH PRIVATE KEY-----`
54
+ testSSHUserPubKey = `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK3HP2HTJfOL8epkGlKQDbEWjby/lbw7geKYjRnM2lCT terraform-provider-envbuilder-test`
55
+ )
56
+
30
57
// testAccProtoV6ProviderFactories are used to instantiate a provider during
31
58
// acceptance testing. The factory function will be invoked for every Terraform
32
59
// CLI command executed to create a provider server to which the CLI can
@@ -45,6 +72,8 @@ type testDependencies struct {
45
72
BuilderImage string
46
73
RepoDir string
47
74
CacheRepo string
75
+ GitImage string
76
+ SSHDir string
48
77
}
49
78
50
79
func setup (t testing.TB , files map [string ]string ) testDependencies {
@@ -53,44 +82,93 @@ func setup(t testing.TB, files map[string]string) testDependencies {
53
82
envbuilderImage := getEnvOrDefault ("ENVBUILDER_IMAGE" , "ghcr.io/coder/envbuilder-preview" )
54
83
envbuilderVersion := getEnvOrDefault ("ENVBUILDER_VERSION" , "latest" )
55
84
envbuilderImageRef := envbuilderImage + ":" + envbuilderVersion
85
+ gitImageRef := "rockstorm/git-server:2.45"
56
86
57
87
// TODO: envbuilder creates /.envbuilder/bin/envbuilder owned by root:root which we are unable to clean up.
58
88
// This causes tests to fail.
59
89
repoDir := t .TempDir ()
60
90
regDir := t .TempDir ()
61
91
reg := registrytest .New (t , regDir )
62
92
writeFiles (t , files , repoDir )
93
+ initGitRepo (t , repoDir )
94
+
95
+ sshDir := t .TempDir ()
96
+ writeFiles (t , map [string ]string {
97
+ "id_ed25516" : testSSHUserKey ,
98
+ "authorized_keys" : testSSHUserPubKey ,
99
+ }, sshDir )
100
+
63
101
return testDependencies {
64
102
BuilderImage : envbuilderImageRef ,
65
103
CacheRepo : reg + "/test" ,
66
104
RepoDir : repoDir ,
105
+ GitImage : gitImageRef ,
106
+ SSHDir : sshDir ,
67
107
}
68
108
}
69
109
70
110
func seedCache (ctx context.Context , t testing.TB , deps testDependencies ) {
71
111
cli , err := client .NewClientWithOpts (client .FromEnv , client .WithAPIVersionNegotiation ())
72
112
require .NoError (t , err , "init docker client" )
73
113
t .Cleanup (func () { _ = cli .Close () })
114
+
115
+ ensureImage (ctx , t , cli , deps .GitImage )
74
116
ensureImage (ctx , t , cli , deps .BuilderImage )
117
+
118
+ // TODO(mafredri): Use a dynamic port?
119
+ sshPort := "2222"
120
+
121
+ gitCtr , err := cli .ContainerCreate (ctx , & container.Config {
122
+ Image : deps .GitImage ,
123
+ Env : []string {
124
+ "SSH_AUTH_METHODS=publickey" ,
125
+ },
126
+ Labels : map [string ]string {
127
+ testContainerLabel : "true" ,
128
+ },
129
+ }, & container.HostConfig {
130
+ PortBindings : nat.PortMap {
131
+ "22/tcp" : []nat.PortBinding {{HostIP : "localhost" , HostPort : sshPort }},
132
+ },
133
+ Binds : []string {
134
+ deps .RepoDir + ":/srv/git/repo.git" ,
135
+ deps .SSHDir + ":/home/git/.ssh" ,
136
+ },
137
+ }, nil , nil , "" )
138
+ require .NoError (t , err , "failed to run git server" )
139
+ t .Cleanup (func () {
140
+ _ = cli .ContainerRemove (ctx , gitCtr .ID , container.RemoveOptions {
141
+ RemoveVolumes : true ,
142
+ Force : true ,
143
+ })
144
+ })
145
+ err = cli .ContainerStart (ctx , gitCtr .ID , container.StartOptions {})
146
+ require .NoError (t , err )
147
+
75
148
// Run envbuilder using this dir as a local layer cache
76
149
ctr , err := cli .ContainerCreate (ctx , & container.Config {
77
150
Image : deps .BuilderImage ,
78
151
Env : []string {
79
152
"ENVBUILDER_CACHE_REPO=" + deps .CacheRepo ,
80
- "ENVBUILDER_DEVCONTAINER_DIR=" + deps .RepoDir ,
81
153
"ENVBUILDER_EXIT_ON_BUILD_FAILURE=true" ,
82
154
"ENVBUILDER_INIT_SCRIPT=exit" ,
155
+ fmt .Sprintf ("ENVBUILDER_GIT_URL=ssh://git@localhost:%s/srv/git/repo.git" , sshPort ),
156
+ "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH=/tmp/ssh/id_ed25516" ,
83
157
// FIXME: Enabling this options causes envbuilder to add its binary to the image under the path
84
158
// /.envbuilder/bin/envbuilder. This file will have ownership root:root and permissions 0o755.
85
159
// Because of this, t.Cleanup() will be unable to delete the temp dir, causing the test to fail.
86
160
// "ENVBUILDER_PUSH_IMAGE=true",
87
161
},
88
162
Labels : map [string ]string {
89
163
testContainerLabel : "true" ,
90
- }}, & container.HostConfig {
164
+ },
165
+ }, & container.HostConfig {
91
166
NetworkMode : container .NetworkMode ("host" ),
92
- Binds : []string {deps .RepoDir + ":" + deps .RepoDir },
167
+ Binds : []string {
168
+ deps .SSHDir + ":/tmp/ssh" ,
169
+ },
93
170
}, nil , nil , "" )
171
+
94
172
require .NoError (t , err , "failed to run envbuilder to seed cache" )
95
173
t .Cleanup (func () {
96
174
_ = cli .ContainerRemove (ctx , ctr .ID , container.RemoveOptions {
@@ -126,7 +204,6 @@ SCANLOGS:
126
204
}
127
205
}
128
206
}
129
-
130
207
}
131
208
132
209
func getEnvOrDefault (env , defVal string ) string {
@@ -137,6 +214,8 @@ func getEnvOrDefault(env, defVal string) string {
137
214
}
138
215
139
216
func writeFiles (t testing.TB , files map [string ]string , destPath string ) {
217
+ t .Helper ()
218
+
140
219
for relPath , content := range files {
141
220
absPath := filepath .Join (destPath , relPath )
142
221
d := filepath .Dir (absPath )
@@ -165,3 +244,26 @@ func ensureImage(ctx context.Context, t testing.TB, cli *client.Client, ref stri
165
244
_ , err = io .ReadAll (resp )
166
245
require .NoError (t , err )
167
246
}
247
+
248
+ func initGitRepo (t testing.TB , dir string ) {
249
+ t .Helper ()
250
+
251
+ repo , err := git .PlainInitWithOptions (dir , & git.PlainInitOptions {
252
+ InitOptions : git.InitOptions {
253
+ DefaultBranch : plumbing .ReferenceName ("refs/heads/main" ),
254
+ },
255
+ })
256
+ require .NoError (t , err , "init git repo" )
257
+ wt , err := repo .Worktree ()
258
+ require .NoError (t , err , "get worktree" )
259
+ _ , err = wt .Add ("." )
260
+ require .NoError (t , err , "add files" )
261
+ _ , err = wt .Commit ("initial commit" , & git.CommitOptions {
262
+ Author : & object.Signature {
263
+ Name : "test" ,
264
+
265
+ },
266
+ })
267
+ require .NoError (t , err , "commit files" )
268
+ t .Logf ("initialized git repo at %s" , dir )
269
+ }
0 commit comments