aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2015-01-03 20:12:38 -0800
committerBrad Fitzpatrick <bradfitz@golang.org>2015-01-05 01:32:49 +0000
commitdd517c42bc0960248584a19b23447581cfb4d6d9 (patch)
tree1c8a4dbac6c2e0f2c13c91f79227d7122a395ff2
parente1019ed0e116fe29c324159562694d8c8d438a47 (diff)
downloadtools-dd517c42bc0960248584a19b23447581cfb4d6d9.tar.gz
dashboard/buildlet: add Makefiles, and add Windows stage0 bootstrap binary
Change-Id: I69938af38fb5c45c01598e9171e851a1c29790bc Reviewed-on: https://go-review.googlesource.com/2268 Reviewed-by: Andrew Gerrand <adg@golang.org>
-rw-r--r--dashboard/buildlet/.gitignore3
-rw-r--r--dashboard/buildlet/Makefile14
-rw-r--r--dashboard/buildlet/buildlet.go44
-rw-r--r--dashboard/buildlet/stage0/Makefile3
-rw-r--r--dashboard/buildlet/stage0/stage0.go78
5 files changed, 104 insertions, 38 deletions
diff --git a/dashboard/buildlet/.gitignore b/dashboard/buildlet/.gitignore
new file mode 100644
index 0000000..3775742
--- /dev/null
+++ b/dashboard/buildlet/.gitignore
@@ -0,0 +1,3 @@
+buildlet
+buildlet.*-*
+stage0/buildlet-stage0.*
diff --git a/dashboard/buildlet/Makefile b/dashboard/buildlet/Makefile
new file mode 100644
index 0000000..6897910
--- /dev/null
+++ b/dashboard/buildlet/Makefile
@@ -0,0 +1,14 @@
+buildlet: buildlet.go
+ go build --tags=buildlet
+
+buildlet.openbsd-amd64: buildlet.go
+ GOOS=openbsd GOARCH=amd64 go build -o $@ --tags=buildlet
+ cat $@ | (cd ../coordinator/buildongce && go run create.go --write_object=go-builder-data/$@)
+
+buildlet.plan9-386: buildlet.go
+ GOOS=plan9 GOARCH=386 go build -o $@ --tags=buildlet
+ cat $@ | (cd ../coordinator/buildongce && go run create.go --write_object=go-builder-data/$@)
+
+buildlet.windows-amd64: buildlet.go
+ GOOS=windows GOARCH=amd64 go build -o $@ --tags=buildlet
+ cat $@ | (cd ../coordinator/buildongce && go run create.go --write_object=go-builder-data/$@)
diff --git a/dashboard/buildlet/buildlet.go b/dashboard/buildlet/buildlet.go
index bc35604..3991c48 100644
--- a/dashboard/buildlet/buildlet.go
+++ b/dashboard/buildlet/buildlet.go
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+// +build buildlet
+
// The buildlet is an HTTP server that untars content to disk and runs
// commands it has untarred, streaming their output back over HTTP.
// It is part of Go's continuous build system.
@@ -29,7 +31,6 @@ import (
"io"
"io/ioutil"
"log"
- "net"
"net/http"
"os"
"os/exec"
@@ -37,7 +38,8 @@ import (
"runtime"
"strings"
"sync"
- "time"
+
+ "google.golang.org/cloud/compute/metadata"
)
var (
@@ -46,7 +48,7 @@ var (
)
func defaultListenAddr() string {
- if OnGCE() {
+ if metadata.OnGCE() {
// In production, default to
return ":80"
}
@@ -55,7 +57,7 @@ func defaultListenAddr() string {
func main() {
flag.Parse()
- if !OnGCE() && !strings.HasPrefix(*listenAddr, "localhost:") {
+ if !metadata.OnGCE() && !strings.HasPrefix(*listenAddr, "localhost:") {
log.Printf("** WARNING *** This server is unsafe and offers no security. Be careful.")
}
if *scratchDir == "" {
@@ -239,37 +241,3 @@ func (he httpError) httpStatus() int { return he.statusCode }
func badRequest(msg string) error {
return httpError{http.StatusBadRequest, msg}
}
-
-// metaClient to fetch GCE metadata values.
-var metaClient = &http.Client{
- Transport: &http.Transport{
- Dial: (&net.Dialer{
- Timeout: 750 * time.Millisecond,
- KeepAlive: 30 * time.Second,
- }).Dial,
- ResponseHeaderTimeout: 750 * time.Millisecond,
- },
-}
-
-var onGCE struct {
- sync.Mutex
- set bool
- v bool
-}
-
-// OnGCE reports whether this process is running on Google Compute Engine.
-func OnGCE() bool {
- defer onGCE.Unlock()
- onGCE.Lock()
- if onGCE.set {
- return onGCE.v
- }
- onGCE.set = true
-
- res, err := metaClient.Get("http://metadata.google.internal")
- if err != nil {
- return false
- }
- onGCE.v = res.Header.Get("Metadata-Flavor") == "Google"
- return onGCE.v
-}
diff --git a/dashboard/buildlet/stage0/Makefile b/dashboard/buildlet/stage0/Makefile
new file mode 100644
index 0000000..99abc63
--- /dev/null
+++ b/dashboard/buildlet/stage0/Makefile
@@ -0,0 +1,3 @@
+buildlet-stage0.windows-amd64: stage0.go
+ GOOS=windows GOARCH=amd64 go build -o $@ --tags=stage0
+ cat $@ | (cd ../../coordinator/buildongce && go run create.go --write_object=go-builder-data/$@)
diff --git a/dashboard/buildlet/stage0/stage0.go b/dashboard/buildlet/stage0/stage0.go
new file mode 100644
index 0000000..609c5c8
--- /dev/null
+++ b/dashboard/buildlet/stage0/stage0.go
@@ -0,0 +1,78 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build stage0
+
+// The stage0 command looks up the buildlet's URL from the GCE metadata
+// service, downloads it, and runs it. It's used primarily by Windows,
+// since it can be written in a couple lines of shell elsewhere.
+package main
+
+import (
+ "fmt"
+ "io"
+ "log"
+ "net/http"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "time"
+
+ "google.golang.org/cloud/compute/metadata"
+)
+
+const attr = "buildlet-binary-url"
+
+func main() {
+ buildletURL, err := metadata.InstanceAttributeValue(attr)
+ if err != nil {
+ sleepFatalf("Failed to look up %q attribute value: %v", attr, err)
+ }
+ target := filepath.FromSlash("./buildlet.exe")
+ if err := download(target, buildletURL); err != nil {
+ sleepFatalf("Downloading %s: %v", buildletURL, err)
+ }
+ cmd := exec.Command(target)
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ if err := cmd.Run(); err != nil {
+ sleepFatalf("Error running buildlet: %v", err)
+ }
+}
+
+func sleepFatalf(format string, args ...interface{}) {
+ log.Printf(format, args...)
+ time.Sleep(time.Minute) // so user has time to see it in cmd.exe, maybe
+ os.Exit(1)
+}
+
+func download(file, url string) error {
+ log.Printf("Downloading %s to %s ...\n", url, file)
+ res, err := http.Get(url)
+ if err != nil {
+ return fmt.Errorf("Error fetching %v: %v", url, err)
+ }
+ if res.StatusCode != 200 {
+ return fmt.Errorf("HTTP status code of %s was %v", url, res.Status)
+ }
+ tmp := file + ".tmp"
+ os.Remove(tmp)
+ os.Remove(file)
+ f, err := os.Create(tmp)
+ if err != nil {
+ return err
+ }
+ n, err := io.Copy(f, res.Body)
+ res.Body.Close()
+ if err != nil {
+ return fmt.Errorf("Error reading %v: %v", url, err)
+ }
+ f.Close()
+ err = os.Rename(tmp, file)
+ if err != nil {
+ return err
+ }
+ log.Printf("Downloaded %s (%d bytes)", file, n)
+ return nil
+}