@@ -22,6 +22,7 @@ import (
22
22
"path/filepath"
23
23
"strings"
24
24
"syscall"
25
+ "time"
25
26
26
27
"github.com/golang/glog"
27
28
@@ -31,10 +32,15 @@ import (
31
32
)
32
33
33
34
var (
34
- teardownCluster = flag .Bool ("teardown-cluster" , true , "teardown the cluster after the e2e test" )
35
- stagingImage = flag .String ("staging-image" , "" , "name of image to stage to" )
36
- kubeVersion = flag .String ("kube-version" , "master" , "version of Kubernetes to download and use" )
37
- inProw = flag .Bool ("run-in-prow" , false , "is the test running in PROW" )
35
+ teardownCluster = flag .Bool ("teardown-cluster" , true , "teardown the cluster after the e2e test" )
36
+ teardownDriver = flag .Bool ("teardown-driver" , true , "teardown the driver after the e2e test" )
37
+ bringupCluster = flag .Bool ("bringup-cluster" , true , "build kubernetes and bringup a cluster" )
38
+ stagingImage = flag .String ("staging-image" , "" , "name of image to stage to" )
39
+ kubeVersion = flag .String ("kube-version" , "master" , "version of Kubernetes to download and use" )
40
+ inProw = flag .Bool ("run-in-prow" , false , "is the test running in PROW" )
41
+ saFile = flag .String ("service-account-file" , "" , "path of service account file" )
42
+ deployOverlayName = flag .String ("deploy-overlay-name" , "" , "which kustomize overlay to deploy the driver with" )
43
+ localK8sDir = flag .String ("local-k8s-dir" , "" , "local kubernetes/kubernetes directory to run e2e tests from" )
38
44
)
39
45
40
46
func init () {
@@ -47,6 +53,14 @@ func main() {
47
53
glog .Fatalf ("staging-image is a required flag, please specify the name of image to stage to" )
48
54
}
49
55
56
+ if len (* saFile ) == 0 {
57
+ glog .Fatalf ("service-account-file is a required flag" )
58
+ }
59
+
60
+ if len (* deployOverlayName ) == 0 {
61
+ glog .Fatalf ("deploy-overlay-name is a required flag" )
62
+ }
63
+
50
64
err := handle ()
51
65
if err != nil {
52
66
glog .Fatalf ("Failed to run integration test: %v" , err )
@@ -86,7 +100,15 @@ func handle() error {
86
100
}
87
101
}()
88
102
89
- * stagingImage = fmt .Sprintf ("gcr.io/%s/csi/gce-pd-driver" , project )
103
+ * stagingImage = fmt .Sprintf ("gcr.io/%s/gcp-persistent-disk-csi-driver" , project )
104
+
105
+ // TODO: once https://github.com/kubernetes-sigs/kustomize/issues/402 is implemented,
106
+ // we no longer need to do this templating work and can just edit the image registry directly.
107
+ overlayDir := getOverlayDir (pkgDir , * deployOverlayName )
108
+ err = fillinOverlayTemplate (overlayDir , * stagingImage )
109
+ if err != nil {
110
+ return fmt .Errorf ("tmpOverlayDir setup failed: %v" , err )
111
+ }
90
112
91
113
if _ , ok := os .LookupEnv ("USER" ); ! ok {
92
114
err = os .Setenv ("USER" , "prow" )
@@ -101,31 +123,31 @@ func handle() error {
101
123
return fmt .Errorf ("failed pushing image: %v" , err )
102
124
}
103
125
defer func () {
104
- err = deleteImage (* stagingImage , stagingVersion )
105
- if err != nil {
106
- glog .Errorf ("failed to delete image: %v" , err )
126
+ if * teardownCluster {
127
+ err = deleteImage (* stagingImage , stagingVersion )
128
+ if err != nil {
129
+ glog .Errorf ("failed to delete image: %v" , err )
130
+ }
107
131
}
108
132
}()
109
133
110
- err = downloadKubernetesSource (pkgDir , k8sIoDir , * kubeVersion )
111
- if err != nil {
112
- return fmt .Errorf ("failed to download Kubernetes source: %v" , err )
113
- }
134
+ if * bringupCluster {
135
+ err = downloadKubernetesSource (pkgDir , k8sIoDir , * kubeVersion )
136
+ if err != nil {
137
+ return fmt .Errorf ("failed to download Kubernetes source: %v" , err )
138
+ }
114
139
115
- err = prepareManifests ( pkgDir , k8sDir , * stagingImage , stagingVersion )
116
- if err != nil {
117
- return fmt .Errorf ("failed to prepare manifests : %v" , err )
118
- }
140
+ err = buildKubernetes ( k8sDir )
141
+ if err != nil {
142
+ return fmt .Errorf ("failed to build Kubernetes : %v" , err )
143
+ }
119
144
120
- err = buildKubernetes (k8sDir )
121
- if err != nil {
122
- return fmt .Errorf ("failed to build Kubernetes: %v" , err )
145
+ err = clusterUp (k8sDir )
146
+ if err != nil {
147
+ return fmt .Errorf ("failed to cluster up: %v" , err )
148
+ }
123
149
}
124
150
125
- err = clusterUp (k8sDir )
126
- if err != nil {
127
- return fmt .Errorf ("failed to cluster up: %v" , err )
128
- }
129
151
if * teardownCluster {
130
152
defer func () {
131
153
err = clusterDown (k8sDir )
@@ -135,6 +157,22 @@ func handle() error {
135
157
}()
136
158
}
137
159
160
+ err = installDriver (goPath , pkgDir , k8sDir , * stagingImage , stagingVersion , * deployOverlayName )
161
+ if * teardownDriver {
162
+ defer func () {
163
+ // TODO (#140): collect driver logs
164
+ if teardownErr := deleteDriver (goPath , pkgDir , * deployOverlayName ); teardownErr != nil {
165
+ glog .Errorf ("failed to delete driver: %v" , teardownErr )
166
+ }
167
+ }()
168
+ }
169
+ if err != nil {
170
+ return fmt .Errorf ("failed to install CSI Driver: %v" , err )
171
+ }
172
+
173
+ if len (* localK8sDir ) != 0 {
174
+ k8sDir = * localK8sDir
175
+ }
138
176
err = runTests (k8sDir )
139
177
if err != nil {
140
178
return fmt .Errorf ("failed to run tests: %v" , err )
@@ -161,21 +199,23 @@ func runTests(k8sDir string) error {
161
199
if err != nil {
162
200
return err
163
201
}
164
- testArgs := "--test_args=--ginkgo.focus=CSI\\ sdriver:\\ sgcePD "
202
+ testArgs := "--test_args=--ginkgo.focus=CSI\\ sdriver:.*gcePD-external "
165
203
cmd := exec .Command ("go" , "run" , "hack/e2e.go" , "--" , "--check-version-skew=false" , "--test" , testArgs )
166
- err = runLongRunningCommand ("Running Tests" , cmd )
204
+ err = runCommand ("Running Tests" , cmd )
167
205
if err != nil {
168
206
return fmt .Errorf ("failed to run tests on e2e cluster: %v" , err )
169
207
}
170
208
171
209
return nil
172
210
}
173
211
174
- func runLongRunningCommand (action string , cmd * exec.Cmd ) error {
212
+ func runCommand (action string , cmd * exec.Cmd ) error {
175
213
cmd .Stdout = os .Stdout
176
214
cmd .Stdin = os .Stdin
177
215
cmd .Stderr = os .Stderr
178
216
217
+ fmt .Printf ("%s\n " , action )
218
+
179
219
err := cmd .Start ()
180
220
if err != nil {
181
221
return err
@@ -190,7 +230,7 @@ func runLongRunningCommand(action string, cmd *exec.Cmd) error {
190
230
191
231
func clusterDown (k8sDir string ) error {
192
232
cmd := exec .Command (filepath .Join (k8sDir , "hack" , "e2e-internal" , "e2e-down.sh" ))
193
- err := runLongRunningCommand ("Bringing Down E2E Cluster" , cmd )
233
+ err := runCommand ("Bringing Down E2E Cluster" , cmd )
194
234
if err != nil {
195
235
return fmt .Errorf ("failed to bring down kubernetes e2e cluster: %v" , err )
196
236
}
@@ -199,7 +239,7 @@ func clusterDown(k8sDir string) error {
199
239
200
240
func buildKubernetes (k8sDir string ) error {
201
241
cmd := exec .Command ("make" , "-C" , k8sDir , "quick-release" )
202
- err := runLongRunningCommand ("Building Kubernetes" , cmd )
242
+ err := runCommand ("Building Kubernetes" , cmd )
203
243
if err != nil {
204
244
return fmt .Errorf ("failed to build Kubernetes: %v" , err )
205
245
}
@@ -208,63 +248,113 @@ func buildKubernetes(k8sDir string) error {
208
248
209
249
func clusterUp (k8sDir string ) error {
210
250
cmd := exec .Command (filepath .Join (k8sDir , "hack" , "e2e-internal" , "e2e-up.sh" ))
211
- err := runLongRunningCommand ("Starting E2E Cluster" , cmd )
251
+ err := runCommand ("Starting E2E Cluster" , cmd )
212
252
if err != nil {
213
253
return fmt .Errorf ("failed to bring up kubernetes e2e cluster: %v" , err )
214
254
}
215
255
216
256
return nil
217
257
}
218
258
219
- func prepareManifests (pkgDir , k8sDir , stagingImage , stagingVersion string ) error {
220
- // Copy manifests to manifest directory
221
- controllerFile := filepath .Join (pkgDir , "deploy" , "kubernetes" , "dev" , "controller.yaml" )
222
- nodeFile := filepath .Join (pkgDir , "deploy" , "kubernetes" , "dev" , "node.yaml" )
223
-
224
- kubeManifestDir := filepath .Join (k8sDir , "test" , "e2e" , "testing-manifests" , "storage-csi" , "gce-pd" )
259
+ func getOverlayDir (pkgDir , deployOverlayName string ) string {
260
+ return filepath .Join (pkgDir , "deploy" , "kubernetes" , "overlays" , deployOverlayName )
261
+ }
225
262
226
- out , err := exec .Command ("cp" , controllerFile , filepath .Join (kubeManifestDir , "controller_ss.yaml" )).CombinedOutput ()
263
+ func installDriver (goPath , pkgDir , k8sDir , stagingImage , stagingVersion , deployOverlayName string ) error {
264
+ // Install kustomize
265
+ out , err := exec .Command (filepath .Join (pkgDir , "deploy" , "kubernetes" , "install-kustomize.sh" )).CombinedOutput ()
227
266
if err != nil {
228
- return fmt .Errorf ("failed to copy controller manifest : %s, err: %v" , out , err )
267
+ return fmt .Errorf ("failed to install kustomize : %s, err: %v" , out , err )
229
268
}
230
269
231
- out , err = exec .Command ("cp" , nodeFile , filepath .Join (kubeManifestDir , "node_ds.yaml" )).CombinedOutput ()
270
+ // Edit ci kustomization to use given image tag
271
+ overlayDir := getOverlayDir (pkgDir , deployOverlayName )
272
+ err = os .Chdir (overlayDir )
232
273
if err != nil {
233
- return fmt .Errorf ("failed to copy node manifest : %s, err: %v" , out , err )
274
+ return fmt .Errorf ("failed to change to overlay directory : %s, err: %v" , out , err )
234
275
}
235
276
236
- // Change manifest container to staging image and version
237
- err = mutateManifests (filepath .Join (kubeManifestDir , "node_ds.yaml" ), filepath .Join (kubeManifestDir , "controller_ss.yaml" ), stagingImage , stagingVersion )
277
+ // TODO (#138): in a local environment this is going to modify the actual kustomize files.
278
+ // maybe a copy should be made instead
279
+ out , err = exec .Command (
280
+ filepath .Join (pkgDir , "bin" , "kustomize" ),
281
+ "edit" ,
282
+ "set" ,
283
+ "imagetag" ,
284
+ fmt .Sprintf ("%s:%s" , stagingImage , stagingVersion )).CombinedOutput ()
238
285
if err != nil {
239
- return err
286
+ return fmt . Errorf ( "failed to edit kustomize: %s, err: %v" , out , err )
240
287
}
241
- return nil
242
- }
243
288
244
- func mutateManifests (nodeFile , controllerFile , stagingImage , stagingVersion string ) error {
245
- // TODO: Make this existing image configurable, ideally we aren't actually reliant on
246
- // a hardcoded image to replace.
289
+ // setup service account file for secret creation
290
+ tmpSaFile := fmt .Sprintf ("/tmp/%s/cloud-sa.json" , string (uuid .NewUUID ()))
247
291
248
- // The actual solution we need to look into doing this is using Kustomize
249
- // to mutate the YAML files
250
- existingImage := "gcr.io/dyzz-csi-staging/csi/gce-pd-driver:latest"
292
+ os .MkdirAll (filepath .Dir (tmpSaFile ), 0750 )
293
+ defer os .Remove (filepath .Dir (tmpSaFile ))
251
294
252
- escapedImage := strings .Replace (stagingImage , "/" , "\\ /" , - 1 )
253
- escapedVersion := strings .Replace (stagingVersion , "/" , "\\ /" , - 1 )
254
- escapedExistingImage := strings .Replace (existingImage , "/" , "\\ /" , - 1 )
295
+ // Need to copy it to name the file "cloud-sa.json"
296
+ out , err = exec .Command ("cp" , * saFile , tmpSaFile ).CombinedOutput ()
297
+ if err != nil {
298
+ return fmt .Errorf ("error copying service account key: %s, err: %v" , out , err )
299
+ }
300
+ defer shredFile (tmpSaFile )
301
+
302
+ // deploy driver
303
+ deployCmd := exec .Command (filepath .Join (pkgDir , "deploy" , "kubernetes" , "deploy-driver.sh" ), "--skip-sa-check" )
304
+ deployCmd .Env = append (os .Environ (),
305
+ fmt .Sprintf ("GOPATH=%s" , goPath ),
306
+ fmt .Sprintf ("GCE_PD_SA_DIR=%s" , filepath .Dir (tmpSaFile )),
307
+ fmt .Sprintf ("GCE_PD_DRIVER_VERSION=%s" , deployOverlayName ),
308
+ )
309
+ err = runCommand ("Deploying driver" , deployCmd )
310
+ if err != nil {
311
+ return fmt .Errorf ("failed to deploy driver: %v" , err )
312
+ }
255
313
256
- sedCommand := fmt .Sprintf ("s/%s/%s:%s/g" , escapedExistingImage , escapedImage , escapedVersion )
314
+ // TODO (#139): wait for driver to be running
315
+ time .Sleep (10 * time .Second )
316
+ statusCmd := exec .Command ("kubectl" , "describe" , "pods" , "-n" , "default" )
317
+ err = runCommand ("Checking driver pods" , statusCmd )
318
+ if err != nil {
319
+ return fmt .Errorf ("failed to check driver pods: %v" , err )
320
+ }
257
321
258
- out , err := exec .Command ("sed" , "-i" , "-e" , sedCommand , nodeFile ).CombinedOutput ()
322
+ return nil
323
+ }
324
+
325
+ func deleteDriver (goPath , pkgDir , deployOverlayName string ) error {
326
+ deleteCmd := exec .Command (filepath .Join (pkgDir , "deploy" , "kubernetes" , "delete-driver.sh" ))
327
+ deleteCmd .Env = append (os .Environ (),
328
+ fmt .Sprintf ("GOPATH=%s" , goPath ),
329
+ fmt .Sprintf ("GCE_PD_DRIVER_VERSION=%s" , deployOverlayName ),
330
+ )
331
+ err := runCommand ("Deleting driver" , deleteCmd )
259
332
if err != nil {
260
- return fmt .Errorf ("failed to sed node file %s : %s, err: %v" , nodeFile , out , err )
333
+ return fmt .Errorf ("failed to delete driver : %v" , err )
261
334
}
262
- out , err = exec .Command ("sed" , "-i" , "-e" , sedCommand , controllerFile ).CombinedOutput ()
335
+ return nil
336
+ }
337
+
338
+ func shredFile (filePath string ) {
339
+ if _ , err := os .Stat (filePath ); os .IsNotExist (err ) {
340
+ glog .V (4 ).Infof ("File %v was not found, skipping shredding" , filePath )
341
+ return
342
+ }
343
+ glog .V (4 ).Infof ("Shredding file %v" , filePath )
344
+ out , err := exec .Command ("shred" , "--remove" , filePath ).CombinedOutput ()
263
345
if err != nil {
264
- return fmt .Errorf ("failed to sed controller file %s: %s, err: %v" , controllerFile , out , err )
346
+ glog .V (4 ).Infof ("Failed to shred file %v: %v\n Output:%v" , filePath , err , out )
347
+ }
348
+ if _ , err := os .Stat (filePath ); os .IsNotExist (err ) {
349
+ glog .V (4 ).Infof ("File %v successfully shredded" , filePath )
350
+ return
265
351
}
266
352
267
- return nil
353
+ // Shred failed Try to remove the file for good meausure
354
+ err = os .Remove (filePath )
355
+ if err != nil {
356
+ glog .V (4 ).Infof ("Failed to remove service account file %s: %v" , filePath , err )
357
+ }
268
358
}
269
359
270
360
func downloadKubernetesSource (pkgDir , k8sIoDir , kubeVersion string ) error {
@@ -335,7 +425,7 @@ func pushImage(pkgDir, stagingImage, stagingVersion string) error {
335
425
cmd := exec .Command ("make" , "-C" , pkgDir , "push-container" ,
336
426
fmt .Sprintf ("GCE_PD_CSI_STAGING_VERSION=%s" , stagingVersion ),
337
427
fmt .Sprintf ("GCE_PD_CSI_STAGING_IMAGE=%s" , stagingImage ))
338
- err = runLongRunningCommand ("Pushing GCP Container" , cmd )
428
+ err = runCommand ("Pushing GCP Container" , cmd )
339
429
if err != nil {
340
430
return fmt .Errorf ("failed to run make command: err: %v" , err )
341
431
}
@@ -344,9 +434,24 @@ func pushImage(pkgDir, stagingImage, stagingVersion string) error {
344
434
345
435
func deleteImage (stagingImage , stagingVersion string ) error {
346
436
cmd := exec .Command ("gcloud" , "container" , "images" , "delete" , fmt .Sprintf ("%s:%s" , stagingImage , stagingVersion ), "--quiet" )
347
- err := runLongRunningCommand ("Deleting GCR Container" , cmd )
437
+ err := runCommand ("Deleting GCR Container" , cmd )
348
438
if err != nil {
349
439
return fmt .Errorf ("failed to delete container image %s:%s: %s" , stagingImage , stagingVersion , err )
350
440
}
351
441
return nil
352
442
}
443
+
444
+ func fillinOverlayTemplate (overlayDir , stagingImage string ) error {
445
+ // Substitute the PROW_GCEPD_IMAGE env with stagingImage for every file in the directory
446
+ escapedStagingImage := strings .Replace (stagingImage , "/" , "\\ /" , - 1 )
447
+ out , err := exec .Command (
448
+ "bash" ,
449
+ "-c" ,
450
+ fmt .Sprintf ("find %s -name *.yaml | xargs %s" ,
451
+ overlayDir ,
452
+ fmt .Sprintf ("sed -i -e 's/PROW_GCEPD_IMAGE/%s/g'" , escapedStagingImage ))).CombinedOutput ()
453
+ if err != nil {
454
+ return fmt .Errorf ("error substituting staging image env: %s, err: %v" , out , err )
455
+ }
456
+ return nil
457
+ }
0 commit comments