@@ -20,6 +20,7 @@ import (
20
20
"context"
21
21
"flag"
22
22
"fmt"
23
+ "io/ioutil"
23
24
"math/rand"
24
25
"net/http"
25
26
"os"
@@ -29,6 +30,7 @@ import (
29
30
30
31
"k8s.io/apimachinery/pkg/util/uuid"
31
32
"k8s.io/apimachinery/pkg/util/wait"
33
+ gce "sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/gce-cloud-provider"
32
34
"sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/test/remote/remote"
33
35
34
36
"github.com/golang/glog"
@@ -268,7 +270,7 @@ func createInstance(serviceAccount string) (string, error) {
268
270
myuuid := string (uuid .NewUUID ())
269
271
glog .V (2 ).Infof ("Creating instance: %v" , name )
270
272
271
- imageURL := "https://www.googleapis.com/compute/v1/projects/eip -images/global/images/debian-9-drawfork-v20180423 "
273
+ imageURL := "https://www.googleapis.com/compute/v1/projects/ml -images/global/images/debian-9-tf-1-9-v20180626 "
272
274
i := & compute.Instance {
273
275
Name : name ,
274
276
MachineType : machineType ("" ),
@@ -303,8 +305,9 @@ func createInstance(serviceAccount string) (string, error) {
303
305
}
304
306
305
307
var err error
306
- if _ , err = computeService .Instances .Get (* project , * zone , i .Name ).Do (); err != nil {
308
+ if gotInstance , err : = computeService .Instances .Get (* project , * zone , i .Name ).Do (); err != nil {
307
309
op , err := computeService .Instances .Insert (* project , * zone , i ).Do ()
310
+ glog .V (4 ).Infof ("Inserted instance in project %v, zone %v: %#v" , * project , * zone , i )
308
311
if err != nil {
309
312
ret := fmt .Sprintf ("could not create instance %s: API error: %v" , name , err )
310
313
if op != nil {
@@ -314,10 +317,24 @@ func createInstance(serviceAccount string) (string, error) {
314
317
} else if op .Error != nil {
315
318
return "" , fmt .Errorf ("could not create instance %s: %+v" , name , op .Error )
316
319
}
320
+ } else {
321
+ glog .V (4 ).Infof ("Compute service GOT instance %v, skipping instance creation: %#v" , i .Name , gotInstance )
322
+ }
323
+
324
+ pubkey , ok := os .LookupEnv ("JENKINS_GCE_SSH_PUBLIC_KEY_FILE" )
325
+ if ok {
326
+ glog .Infof ("Running on Jenkins and JENKINS_GCE_SSH_PUBLIC_KEY_FILE set" )
327
+ // If we're on CI add public SSH keys to the instance
328
+ err = addPubKeyToInstance (* project , * zone , i .Name , pubkey )
329
+ if err != nil {
330
+ return "" , fmt .Errorf ("could not add Jenkins public key %v to instance %v: %v" , pubkey , i .Name , err )
331
+ }
332
+ } else {
333
+ glog .V (4 ).Infof ("JENKINS_GCE_SSH_PUBLIC_KEY_FILE not set, not adding SSH public key to instance" )
317
334
}
318
335
319
336
then := time .Now ()
320
- err = wait .Poll (15 * time .Second , 10 * time .Minute , func () (bool , error ) {
337
+ err = wait .Poll (10 * time .Second , 5 * time .Minute , func () (bool , error ) {
321
338
glog .V (2 ).Infof ("Waiting for instance %v to come up. %v elapsed" , name , time .Since (then ))
322
339
var instance * compute.Instance
323
340
instance , err = computeService .Instances .Get (* project , * zone , name ).Do ()
@@ -337,9 +354,9 @@ func createInstance(serviceAccount string) (string, error) {
337
354
remote .AddHostnameIP (name , externalIP )
338
355
}
339
356
340
- if _ , err = remote .SSHNoSudo (name , "echo" ); err != nil {
357
+ if sshOut , err : = remote .SSHNoSudo (name , "echo" ); err != nil {
341
358
err = fmt .Errorf ("Instance %v in state RUNNING but not available by SSH: %v" , name , err )
342
- glog .Error ( err )
359
+ glog .Errorf ( "SSH encountered an error: %v, output: %v" , err , sshOut )
343
360
return false , nil
344
361
}
345
362
@@ -355,6 +372,54 @@ func createInstance(serviceAccount string) (string, error) {
355
372
return name , nil
356
373
}
357
374
375
+ func addPubKeyToInstance (project , zone , name , pubKeyFile string ) error {
376
+ newKeys := ""
377
+ i , err := computeService .Instances .Get (project , zone , name ).Do ()
378
+ if err != nil {
379
+ return err
380
+ }
381
+ fingerprint := i .Metadata .Fingerprint
382
+ items := i .Metadata .Items
383
+ for _ , item := range items {
384
+ if item .Key == "ssh-keys" {
385
+ glog .V (2 ).Infof ("Found existing ssh-keys, prepending to new key string" )
386
+ newKeys += * item .Value
387
+ break
388
+ }
389
+ }
390
+ publicKeyByte , err := ioutil .ReadFile (pubKeyFile )
391
+ if err != nil {
392
+ return err
393
+ }
394
+
395
+ publicKey := string (publicKeyByte )
396
+
397
+ // Take username and prepend it to the public key
398
+ tokens := strings .Split (publicKey , " " )
399
+ if len (tokens ) != 3 {
400
+ return fmt .Errorf ("Public key not comprised of 3 parts, instead was: %v" , publicKey )
401
+ }
402
+ publicKey = strings .TrimSpace (tokens [2 ]) + ":" + publicKey
403
+
404
+ newKeys = newKeys + publicKey
405
+ glog .V (4 ).Infof ("New ssh-keys for instance %v: %v" , name , newKeys )
406
+ newMeta := & compute.Metadata {
407
+ Fingerprint : fingerprint ,
408
+ Items : []* compute.MetadataItems {
409
+ & compute.MetadataItems {
410
+ Key : "ssh-keys" ,
411
+ Value : & newKeys ,
412
+ },
413
+ },
414
+ }
415
+ _ , err = computeService .Instances .SetMetadata (project , zone , name , newMeta ).Do ()
416
+ if err != nil {
417
+ return err
418
+ }
419
+ return nil
420
+
421
+ }
422
+
358
423
func getexternalIP (instance * compute.Instance ) string {
359
424
for i := range instance .NetworkInterfaces {
360
425
ni := instance .NetworkInterfaces [i ]
@@ -400,6 +465,9 @@ func deleteInstance(host string) {
400
465
glog .Infof ("Deleting instance %q" , host )
401
466
_ , err := computeService .Instances .Delete (* project , * zone , host ).Do ()
402
467
if err != nil {
468
+ if gce .IsGCEError (err , "notFound" ) {
469
+ return
470
+ }
403
471
glog .Errorf ("Error deleting instance %q: %v" , host , err )
404
472
}
405
473
}
0 commit comments