buildlet: add DestroyVM method to Client

And use it in gomote and release tools.

Change-Id: I87fa013d6d6729e7305dacd137be1b3d3b02f5f4
Reviewed-on: https://go-review.googlesource.com/3771
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/buildlet/buildletclient.go b/buildlet/buildletclient.go
index f341224..9d0e4d8 100644
--- a/buildlet/buildletclient.go
+++ b/buildlet/buildletclient.go
@@ -15,6 +15,9 @@
 	"net/http"
 	"net/url"
 	"strings"
+	"time"
+
+	"golang.org/x/oauth2"
 )
 
 // NewClient returns a *Client that will manipulate ipPort,
@@ -232,6 +235,50 @@
 	return c.doOK(req)
 }
 
+// DestroyVM shuts down the buildlet and destroys the VM instance.
+func (c *Client) DestroyVM(ts oauth2.TokenSource, proj, zone, instance string) error {
+	gceErrc := make(chan error, 1)
+	buildletErrc := make(chan error, 1)
+	go func() {
+		gceErrc <- DestroyVM(ts, proj, zone, instance)
+	}()
+	go func() {
+		buildletErrc <- c.Destroy()
+	}()
+	timeout := time.NewTimer(5 * time.Second)
+	defer timeout.Stop()
+
+	var retErr error
+	var gceDone, buildletDone bool
+	for !gceDone || !buildletDone {
+		select {
+		case err := <-gceErrc:
+			if err != nil {
+				retErr = err
+			}
+			gceDone = true
+		case err := <-buildletErrc:
+			if err != nil {
+				retErr = err
+			}
+			buildletDone = true
+		case <-timeout.C:
+			e := ""
+			if !buildletDone {
+				e = "timeout asking buildlet to shut down"
+			}
+			if !gceDone {
+				if e != "" {
+					e += " and "
+				}
+				e += "timeout asking GCE to delete builder VM"
+			}
+			return errors.New(e)
+		}
+	}
+	return retErr
+}
+
 func condRun(fn func()) {
 	if fn != nil {
 		fn()