@@ -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"
@@ -320,8 +321,20 @@ func createInstance(serviceAccount string) (string, error) {
320
321
glog .Infof ("Compute service GOT instance %v: %#v" , i .Name , gotInstance )
321
322
}
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 ServiceAccount 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 .Infof ("JENKINS_GCE_SSH_PUBLIC_KEY_FILE not set, not adding SSH Public Key to Instance" )
334
+ }
335
+
323
336
then := time .Now ()
324
- 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 ) {
325
338
glog .V (2 ).Infof ("Waiting for instance %v to come up. %v elapsed" , name , time .Since (then ))
326
339
var instance * compute.Instance
327
340
instance , err = computeService .Instances .Get (* project , * zone , name ).Do ()
@@ -341,9 +354,10 @@ func createInstance(serviceAccount string) (string, error) {
341
354
remote .AddHostnameIP (name , externalIP )
342
355
}
343
356
344
- if _ , err = remote .SSHNoSudo (name , "echo" ); err != nil {
357
+ if sshOut , err : = remote .SSHNoSudo (name , "echo" ); err != nil {
345
358
err = fmt .Errorf ("Instance %v in state RUNNING but not available by SSH: %v" , name , err )
346
359
glog .Error (err )
360
+ glog .Errorf ("SSH output: %v" , sshOut )
347
361
return false , nil
348
362
}
349
363
@@ -359,6 +373,58 @@ func createInstance(serviceAccount string) (string, error) {
359
373
return name , nil
360
374
}
361
375
376
+ func addPubKeyToInstance (project , zone , name , pubKeyFile string ) error {
377
+ found := false
378
+ i , err := computeService .Instances .Get (project , zone , name ).Do ()
379
+ if err != nil {
380
+ return err
381
+ }
382
+ fingerprint := i .Metadata .Fingerprint
383
+ items := i .Metadata .Items
384
+ for _ , item := range items {
385
+ if item .Key == "ssh-keys" {
386
+ found = true
387
+ }
388
+ }
389
+ newKeys := ""
390
+ if found {
391
+ // Append these to newKeys first
392
+ glog .Infof ("Found existing public keys on instance %v" , name )
393
+ }
394
+ glog .Infof ("Public key file: %v" , pubKeyFile )
395
+ publicKeyByte , err := ioutil .ReadFile (pubKeyFile )
396
+ if err != nil {
397
+ return err
398
+ }
399
+
400
+ publicKey := string (publicKeyByte )
401
+
402
+ // Take username and prepend it to the public key
403
+ tokens := strings .Split (publicKey , " " )
404
+ if len (tokens ) != 3 {
405
+ return fmt .Errorf ("Public key not comprised of 3 parts, instead was: %v" , publicKey )
406
+ }
407
+ publicKey = strings .TrimSpace (tokens [2 ]) + ":" + publicKey
408
+
409
+ newKeys = newKeys + publicKey
410
+ glog .Infof ("New Keys: %v" , newKeys )
411
+ newMeta := & compute.Metadata {
412
+ Fingerprint : fingerprint ,
413
+ Items : []* compute.MetadataItems {
414
+ & compute.MetadataItems {
415
+ Key : "ssh-keys" ,
416
+ Value : & newKeys ,
417
+ },
418
+ },
419
+ }
420
+ _ , err = computeService .Instances .SetMetadata (project , zone , name , newMeta ).Do ()
421
+ if err != nil {
422
+ return err
423
+ }
424
+ return nil
425
+
426
+ }
427
+
362
428
func getexternalIP (instance * compute.Instance ) string {
363
429
for i := range instance .NetworkInterfaces {
364
430
ni := instance .NetworkInterfaces [i ]
0 commit comments