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()
diff --git a/cmd/gomote/destroy.go b/cmd/gomote/destroy.go
index 53cf5d2..4a6c74d 100644
--- a/cmd/gomote/destroy.go
+++ b/cmd/gomote/destroy.go
@@ -5,14 +5,9 @@
package main
import (
- "errors"
"flag"
"fmt"
- "log"
"os"
- "time"
-
- "golang.org/x/build/buildlet"
)
func destroy(args []string) error {
@@ -33,47 +28,5 @@
return err
}
- // Ask it to kill itself, and tell GCE to kill it too:
- gceErrc := make(chan error, 1)
- buildletErrc := make(chan error, 1)
- go func() {
- gceErrc <- buildlet.DestroyVM(projTokenSource(), *proj, *zone, fmt.Sprintf("mote-%s-%s", username(), name))
- }()
- go func() {
- buildletErrc <- bc.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 {
- log.Printf("GCE: %v", err)
- retErr = err
- } else {
- log.Printf("Requested GCE delete.")
- }
- gceDone = true
- case err := <-buildletErrc:
- if err != nil {
- log.Printf("Buildlet: %v", err)
- retErr = err
- } else {
- log.Printf("Requested buildlet to shut down.")
- }
- buildletDone = true
- case <-timeout.C:
- if !buildletDone {
- log.Printf("timeout asking buildlet to shut down")
- }
- if !gceDone {
- log.Printf("timeout asking GCE to delete builder VM")
- }
- return errors.New("timeout")
- }
- }
- return retErr
+ return bc.DestroyVM(projTokenSource(), *proj, *zone, fmt.Sprintf("mote-%s-%s", username(), name))
}
diff --git a/cmd/release/release.go b/cmd/release/release.go
index 82599f2..6a5aad1 100644
--- a/cmd/release/release.go
+++ b/cmd/release/release.go
@@ -108,7 +108,10 @@
defer func() {
log.Printf("%v: Destroying VM.", instance)
- haltAndDestroy(client, instance)
+ err := client.DestroyVM(projTokenSource(), *project, *zone, instance)
+ if err != nil {
+ log.Printf("%v: Destroying VM: %v", instance, err)
+ }
}()
// Push source to VM
@@ -175,49 +178,6 @@
return nil
}
-func haltAndDestroy(bc *buildlet.Client, instance string) {
- // TODO(adg): move this to buildlet library.
-
- // Ask buildlet to kill itself, and tell GCE to kill it too.
- gceErrc := make(chan error, 1)
- buildletErrc := make(chan error, 1)
- go func() {
- gceErrc <- buildlet.DestroyVM(projTokenSource(), *project, *zone, instance)
- }()
- go func() {
- buildletErrc <- bc.Destroy()
- }()
- timeout := time.NewTimer(5 * time.Second)
- defer timeout.Stop()
-
- var gceDone, buildletDone bool
- for !gceDone || !buildletDone {
- select {
- case err := <-gceErrc:
- if err != nil {
- log.Printf("%v: GCE: %v", instance, err)
- } else {
- log.Printf("%v: Requested GCE delete.", instance)
- }
- gceDone = true
- case err := <-buildletErrc:
- if err != nil {
- log.Printf("%v: Buildlet: %v", instance, err)
- } else {
- log.Printf("%v: Requested buildlet to shut down.", instance)
- }
- buildletDone = true
- case <-timeout.C:
- if !buildletDone {
- log.Printf("%v: timeout asking buildlet to shut down", instance)
- }
- if !gceDone {
- log.Printf("%v: timeout asking GCE to delete builder VM", instance)
- }
- }
- }
-}
-
func projTokenSource() oauth2.TokenSource {
ts, err := auth.ProjectTokenSource(*project, compute.ComputeScope)
if err != nil {