cmd/release: use remote buildlets
Change-Id: Id5dfde505c0485bb4cb0ec98c328fd087e96411b
Reviewed-on: https://go-review.googlesource.com/11942
Reviewed-by: Andrew Gerrand <adg@golang.org>
diff --git a/cmd/release/release.go b/cmd/release/release.go
index a3fa773..fc35d4a 100644
--- a/cmd/release/release.go
+++ b/cmd/release/release.go
@@ -7,23 +7,21 @@
import (
"bytes"
- "crypto/rand"
"flag"
"fmt"
"io"
+ "io/ioutil"
"log"
"os"
"path"
"path/filepath"
+ "runtime"
"strings"
"sync"
- "time"
- "golang.org/x/build/auth"
+ "golang.org/x/build"
"golang.org/x/build/buildlet"
"golang.org/x/build/dashboard"
- "golang.org/x/oauth2"
- "google.golang.org/api/compute/v1"
)
var (
@@ -35,10 +33,11 @@
blogRev = flag.String("blog", "master", "Blog revision to include")
netRev = flag.String("net", "master", "Net revision to include")
- project = flag.String("project", "symbolic-datum-552", "Google Cloud Project")
- zone = flag.String("zone", "us-central1-a", "Compute Engine zone")
+ user = flag.String("user", username(), "coordinator username, appended to 'user-'")
)
+var coordClient *buildlet.CoordinatorClient
+
type Build struct {
OS, Arch string
@@ -113,6 +112,8 @@
log.Fatal("must specify -tools flag")
}
+ coordClient = coordinatorClient()
+
var wg sync.WaitGroup
for _, b := range builds {
b := b
@@ -129,59 +130,15 @@
wg.Wait()
}
-func (b *Build) shouldStartNewVM() bool {
- if strings.HasPrefix(b.Builder, "darwin-") {
- return false
- }
- return true
-}
-
func (b *Build) buildlet() (*buildlet.Client, error) {
- if b.shouldStartNewVM() {
- return b.buildletFromVM()
- }
- panic("TODO: obtain a buildlet via the coordiantor, where the OS X machines are dialed into via the reverse pool")
-}
-
-func (b *Build) buildletFromVM() (*buildlet.Client, error) {
- bc, ok := dashboard.Builders[b.Builder]
- if !ok {
- return nil, fmt.Errorf("unknown builder: %v", bc)
- }
- // Start VM
- log.Printf("%v: Starting VM.", b)
- keypair, err := buildlet.NewKeyPair()
+ bc, err := coordClient.CreateBuildlet(b.Builder)
if err != nil {
return nil, err
}
- instance := fmt.Sprintf("release-%v-%v-rn%v", os.Getenv("USER"), bc.Name, randHex(6))
- client, err := buildlet.StartNewVM(projTokenSource(), instance, bc.Name, buildlet.VMOpts{
- Zone: *zone,
- ProjectID: *project,
- TLS: keypair,
- Description: fmt.Sprintf("release buildlet for %s", os.Getenv("USER")),
- DeleteIn: 1 * time.Hour, // If we don't shut it down, it should kill itself.
- OnInstanceRequested: func() {
- log.Printf("%v: Sent create request. Waiting for operation.", b)
- },
- OnInstanceCreated: func() {
- log.Printf("%v: Instance created.", b)
- },
+ bc.SetCloseFunc(func() error {
+ return bc.Destroy()
})
- if err != nil {
- return nil, err
- }
- log.Printf("%v: Instance %v up.", b, instance)
-
- client.SetCloseFunc(func() error {
- log.Printf("%v: Destroying VM.", b)
- err := client.DestroyVM(projTokenSource(), *project, *zone, instance)
- if err != nil {
- log.Printf("%v: Destroying VM: %v", b, err)
- }
- return nil
- })
- return client, nil
+ return bc, nil
}
func (b *Build) make() (err error) {
@@ -376,23 +333,6 @@
return nil
}
-func projTokenSource() oauth2.TokenSource {
- ts, err := auth.ProjectTokenSource(*project, compute.ComputeScope)
- if err != nil {
- log.Fatalf("Failed to get OAuth2 token source for project %s: %v", *project, err)
- }
- return ts
-}
-
-func randHex(n int) string {
- buf := make([]byte, n/2)
- _, err := rand.Read(buf)
- if err != nil {
- panic("Failed to get randomness: " + err.Error())
- }
- return fmt.Sprintf("%x", buf)
-}
-
func addPrefix(prefix string, in []string) []string {
var out []string
for _, s := range in {
@@ -400,3 +340,55 @@
}
return out
}
+
+func coordinatorClient() *buildlet.CoordinatorClient {
+ return &buildlet.CoordinatorClient{
+ Auth: buildlet.UserPass{
+ Username: "user-" + *user,
+ Password: userToken(),
+ },
+ Instance: build.ProdCoordinator,
+ }
+}
+
+func homeDir() string {
+ if runtime.GOOS == "windows" {
+ return os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
+ }
+ return os.Getenv("HOME")
+}
+
+func configDir() string {
+ if runtime.GOOS == "windows" {
+ return filepath.Join(os.Getenv("APPDATA"), "Gomote")
+ }
+ if xdg := os.Getenv("XDG_CONFIG_HOME"); xdg != "" {
+ return filepath.Join(xdg, "gomote")
+ }
+ return filepath.Join(homeDir(), ".config", "gomote")
+}
+
+func username() string {
+ if runtime.GOOS == "windows" {
+ return os.Getenv("USERNAME")
+ }
+ return os.Getenv("USER")
+}
+
+func userToken() string {
+ if *user == "" {
+ panic("userToken called with user flag empty")
+ }
+ keyDir := configDir()
+ baseFile := "user-" + *user + ".token"
+ tokenFile := filepath.Join(keyDir, baseFile)
+ slurp, err := ioutil.ReadFile(tokenFile)
+ if os.IsNotExist(err) {
+ log.Printf("Missing file %s for user %q. Change --user or obtain a token and place it there.",
+ tokenFile, *user)
+ }
+ if err != nil {
+ log.Fatal(err)
+ }
+ return strings.TrimSpace(string(slurp))
+}