aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-11-19 12:29:00 +0100
committerDmitry Vyukov <dvyukov@google.com>2017-11-19 12:29:00 +0100
commit9badd05327bc3a1a96c828de3c32dc8101be77cc (patch)
treed1fe4812d2c3dd4e3d070efee54e832d5a49bc0f
parent2994ea09810a461d7a6334cdc4867179d46a08e2 (diff)
vm/gce: provide VM console output on boot failures
"can't ssh into the instance" is not a very useful error.
-rw-r--r--pkg/gce/gce.go10
-rw-r--r--vm/gce/gce.go4
2 files changed, 14 insertions, 0 deletions
diff --git a/pkg/gce/gce.go b/pkg/gce/gce.go
index e8ad084e6..c08ae5519 100644
--- a/pkg/gce/gce.go
+++ b/pkg/gce/gce.go
@@ -228,6 +228,16 @@ func (ctx *Context) DeleteImage(imageName string) error {
return nil
}
+func (ctx *Context) GetSerialPortOutput(instance string) (string, error) {
+ <-ctx.apiRateGate
+ output, err := ctx.computeService.Instances.GetSerialPortOutput(
+ ctx.ProjectID, ctx.ZoneID, instance).Port(1).Do()
+ if err != nil {
+ return "", fmt.Errorf("failed to get serial port output: %v", err)
+ }
+ return output.Contents, nil
+}
+
type resourcePoolExhaustedError string
func (err resourcePoolExhaustedError) Error() string {
diff --git a/vm/gce/gce.go b/vm/gce/gce.go
index 165ffe4ce..7d973fe2e 100644
--- a/vm/gce/gce.go
+++ b/vm/gce/gce.go
@@ -15,6 +15,7 @@ import (
"archive/tar"
"bytes"
"compress/gzip"
+ "errors"
"fmt"
"io"
"io/ioutil"
@@ -164,6 +165,9 @@ func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) {
}
Logf(0, "wait instance to boot: %v (%v)", name, ip)
if err := pool.waitInstanceBoot(ip, sshKey, sshUser); err != nil {
+ if output, err := pool.GCE.GetSerialPortOutput(name); err == nil {
+ err = errors.New(err.Error() + "\n\n" + output)
+ }
return nil, err
}
ok = true