1
0
mirror of https://github.com/golang/go synced 2024-11-18 16:14:46 -07:00

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>
This commit is contained in:
Brad Fitzpatrick 2015-01-03 20:12:38 -08:00
parent e1019ed0e1
commit dd517c42bc
5 changed files with 104 additions and 38 deletions

3
dashboard/buildlet/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
buildlet
buildlet.*-*
stage0/buildlet-stage0.*

View File

@ -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/$@)

View File

@ -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
}

View File

@ -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/$@)

View File

@ -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
}