build: convert most Linux builders to be VM-based

We still use Dockerfiles to describe them, but then a new tool
(docker2boot) converts them into VM images suitable for booting on
GCE, running the buildlet like all the other operating systems. Things
are easier if everything acts the same way.

Note that since we're no longer moving around Docker images, the image
size and the layer accumulation cruft no longer matters. We can now
have Dockerfile lines like "RUN rm -rf /usr/share/doc" and it actually
results in a smaller VM image, since we just "docker export" the files
out of it to create the VM image.

This doesn't yet convert the clang, sid, or nacl builders. The
coordinator still runs those under Docker directly. A future change
will convert those to VM images as well.

Change-Id: Iedb136ae3daf888c955eb843bdcc9a638d08f5e9
Reviewed-on: https://go-review.googlesource.com/3341
Reviewed-by: Andrew Gerrand <adg@golang.org>
This commit is contained in:
Brad Fitzpatrick 2015-01-27 14:22:21 -08:00
Родитель 01edbde622
Коммит 50ba0cb8f6
15 изменённых файлов: 457 добавлений и 115 удалений

Просмотреть файл

@ -124,8 +124,7 @@ func StartNewVM(ts oauth2.TokenSource, instName, builderType string, opts VMOpts
// which the VMs are configured to download at boot and run.
// This lets us/ update the buildlet more easily than
// rebuilding the whole VM image.
addMeta("buildlet-binary-url",
"http://storage.googleapis.com/go-builder-data/buildlet."+conf.GOOS()+"-"+conf.GOARCH())
addMeta("buildlet-binary-url", conf.BuildletBinaryURL())
addMeta("builder-type", builderType)
if !opts.TLS.IsZero() {
addMeta("tls-cert", opts.TLS.CertPEM)
@ -232,7 +231,7 @@ OpLoop:
break
}
if !alive {
return nil, fmt.Errorf("buildlet didn't come up in %v", timeout)
return nil, fmt.Errorf("buildlet didn't come up at %s in %v", buildletURL, timeout)
}
return NewClient(ipPort, opts.TLS), nil

Просмотреть файл

@ -7,12 +7,7 @@ buildlet.darwin-amd64: buildlet.go
buildlet.freebsd-amd64: buildlet.go
GOOS=freebsd GOARCH=amd64 go build -o $@
# We use the same binary for freebsd-386 as freebsd-amd64:
.PHONY: freebsd
freebsd: buildlet.freebsd-amd64
cat buildlet.freebsd-amd64 | (cd ../upload && go run upload.go --public go-builder-data/buildlet.freebsd-amd64)
cat buildlet.freebsd-amd64 | (cd ../upload && go run upload.go --public go-builder-data/buildlet.freebsd-386)
cat $@ | (cd ../upload && go run upload.go --public go-builder-data/$@)
buildlet.linux-amd64: buildlet.go
GOOS=linux GOARCH=amd64 go build -o $@

Просмотреть файл

@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// 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.
// The stage0 command looks up the buildlet's URL from the GCE
// metadata service, downloads it, and runs it. If not on GCE, such as
// when in a Linux Docker container being developed and tested
// locally, the stage0 instead looks for the META_BUILDLET_BINARY_URL
// environment to have a URL to the buildlet binary.
package main
import (
"flag"
"fmt"
"io"
"log"
@ -15,22 +18,34 @@ import (
"os"
"os/exec"
"path/filepath"
"runtime"
"time"
"google.golang.org/cloud/compute/metadata"
)
// This lets us be lazy and put the stage0 start-up in rc.local where
// it might race with the network coming up, rather than write proper
// upstart+systemd+init scripts:
var networkWait = flag.Duration("network-wait", 0, "if non-zero, the time to wait for the network to come up.")
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)
}
flag.Parse()
// Note: we name it ".exe" for Windows, but the name also
// works fine on Linux, etc.
target := filepath.FromSlash("./buildlet.exe")
if err := download(target, buildletURL); err != nil {
if err := download(target, buildletURL()); err != nil {
sleepFatalf("Downloading %s: %v", buildletURL, err)
}
if runtime.GOOS != "windows" {
if err := os.Chmod(target, 0755); err != nil {
log.Fatal(err)
}
}
cmd := exec.Command(target)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
@ -39,17 +54,45 @@ func main() {
}
}
func buildletURL() string {
if !metadata.OnGCE() {
if v := os.Getenv("META_BUILDLET_BINARY_URL"); v != "" {
return v
}
sleepFatalf("Not on GCE, and no META_BUILDLET_BINARY_URL specified.")
}
v, err := metadata.InstanceAttributeValue(attr)
if err != nil {
sleepFatalf("Failed to look up %q attribute value: %v", attr, err)
}
return v
}
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
if runtime.GOOS == "windows" {
log.Printf("(sleeping for 1 minute before failing)")
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)
var res *http.Response
var err error
deadline := time.Now().Add(*networkWait)
for {
res, err = http.Get(url)
if err != nil {
if time.Now().Before(deadline) {
time.Sleep(1 * time.Second)
continue
}
return fmt.Errorf("Error fetching %v: %v", url, err)
}
break
}
if res.StatusCode != 200 {
return fmt.Errorf("HTTP status code of %s was %v", url, res.Status)

Просмотреть файл

@ -477,6 +477,11 @@ func findWork(work chan<- builderRev) error {
return errors.New("bogus JSON response from dashboard: results is too long.")
}
for i, res := range br.Results {
if res == "https://build.golang.org/log/" {
// Work around golang.org/issue/9701
// TODO(bradfitz): remove this hack, once #9701 is fixed.
res = ""
}
if res != "" {
// It's either "ok" or a failure URL.
continue

2
cmd/docker2boot/.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,2 @@
disk.raw
docker2boot

Просмотреть файл

@ -0,0 +1,262 @@
// 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.
// The docker2boot command converts a Docker image into a bootable GCE
// VM image.
package main
import (
"flag"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strconv"
"strings"
"time"
)
var (
numGB = flag.Int("gb", 2, "size of raw disk, in gigabytes")
rawFile = flag.String("disk", "disk.raw", "temporary raw disk file to create and delete")
img = flag.String("image", "", "Docker image to convert. Required.")
outFile = flag.String("out", "image.tar.gz", "GCE output .tar.gz image file to create")
justRaw = flag.Bool("justraw", false, "If true, stop after preparing the raw file, but before creating the tar.gz")
)
// This is a Linux kernel and initrd that boots on GCE. It's the
// standard one that comes with the GCE Debian image.
const (
bootTarURL = "https://storage.googleapis.com/go-builder-data/boot-linux-3.16-0.bpo.3-amd64.tar.gz"
// bootUUID is the filesystem UUID in the bootTarURL snapshot.
// TODO(bradfitz): parse this out of boot/grub/grub.cfg
// instead, or write that file completely, so this doesn't
// need to exist and stay in sync with the kernel snapshot.
bootUUID = "906181f7-4e10-4a4e-8fd8-43b20ec980ff"
)
func main() {
flag.Parse()
defer os.Exit(1) // otherwise we call os.Exit(0) at the bottom
if runtime.GOOS != "linux" {
failf("docker2boot only runs on Linux")
}
if *img == "" {
failf("Missing required --image Docker image flag.")
}
if *outFile == "" {
failf("Missing required --out flag")
}
if strings.Contains(slurpFile("/proc/mounts"), "nbd0p1") {
failf("/proc/mounts shows nbd0p1 already mounted. Unmount that first.")
}
checkDeps()
mntDir, err := ioutil.TempDir("", "docker2boot")
if err != nil {
failf("Failed to create mount temp dir: %v", err)
}
defer os.RemoveAll(mntDir)
out, err := exec.Command("docker", "run", "-d", *img, "/bin/true").CombinedOutput()
if err != nil {
failf("Error creating container to snapshot: %v, %s", err, out)
}
container := strings.TrimSpace(string(out))
if os.Getenv("USER") != "root" {
failf("this tool requires root. Re-run with sudo.")
}
// Install the kernel's network block device driver, if it's not already.
// The qemu-nbd command would probably do this too, but this is a good place
// to fail early if it's not available.
run("modprobe", "nbd")
if strings.Contains(slurpFile("/proc/partitions"), "nbd0") {
// TODO(bradfitz): make the nbd device configurable,
// or auto-select a free one. Hard-coding the first
// one is lazy, but works. Who uses NBD anyway?
failf("Looks like /dev/nbd0 is already in use. Maybe a previous run failed in the middle? Try sudo qemu-nbd -d /dev/nbd0")
}
if _, err := os.Stat(*rawFile); !os.IsNotExist(err) {
failf("File %s already exists. Delete it and try again, or use a different --disk flag value.", *rawFile)
}
defer os.Remove(*rawFile)
// Make a big empty file full of zeros. Using fallocate to make a sparse
// file is much quicker (~immediate) than using dd to write from /dev/zero.
// GCE requires disk images to be sized by the gigabyte.
run("fallocate", "-l", strconv.Itoa(*numGB)+"G", *rawFile)
// Start a NBD server so the kernel's /dev/nbd0 reads/writes
// from our disk image, currently all zeros.
run("qemu-nbd", "-c", "/dev/nbd0", "--format=raw", *rawFile)
defer exec.Command("qemu-nbd", "-d", "/dev/nbd0").Run()
// Put a MS-DOS partition table on it (GCE requirement), with
// the first partition's initial sector far enough in to leave
// room for the grub boot loader.
fdisk := exec.Command("/sbin/fdisk", "/dev/nbd0")
fdisk.Stdin = strings.NewReader("o\nn\np\n1\n2048\n\nw\n")
out, err = fdisk.CombinedOutput()
if err != nil {
failf("fdisk: %v, %s", err, out)
}
// Wait for the kernel to notice the partition. fdisk does an ioctl
// to make the kernel rescan for partitions.
deadline := time.Now().Add(5 * time.Second)
for !strings.Contains(slurpFile("/proc/partitions"), "nbd0p1") {
if time.Now().After(deadline) {
failf("timeout waiting for nbd0p1 to appear")
}
time.Sleep(50 * time.Millisecond)
}
// Now that the partition is available, make a filesystem on it.
run("mkfs.ext4", "/dev/nbd0p1")
run("mount", "/dev/nbd0p1", mntDir)
defer exec.Command("umount", mntDir).Run()
log.Printf("Populating /boot/ partition from %s", bootTarURL)
pipeInto(httpGet(bootTarURL), "tar", "-zx", "-C", mntDir)
log.Printf("Exporting Docker container %s into fs", container)
exp := exec.Command("docker", "export", container)
tarPipe, err := exp.StdoutPipe()
if err != nil {
failf("Pipe: %v", err)
}
if err := exp.Start(); err != nil {
failf("docker export: %v", err)
}
pipeInto(tarPipe, "tar", "-x", "-C", mntDir)
if err := exp.Wait(); err != nil {
failf("docker export: %v", err)
}
// Docker normally provides these etc files, so they're not in
// the export and we have to include them ourselves.
writeFile(filepath.Join(mntDir, "etc", "hosts"), "127.0.0.1\tlocalhost\n")
writeFile(filepath.Join(mntDir, "etc", "resolve.conf"), "nameserver 8.8.8.8\n")
// Install grub. Adjust the grub.cfg to have the correct
// filesystem UUID of the filesystem made above.
grubCfgFile := filepath.Join(mntDir, "boot/grub/grub.cfg")
writeFile(grubCfgFile, strings.Replace(slurpFile(grubCfgFile), bootUUID, filesystemUUID(), -1))
run("rm", filepath.Join(mntDir, "boot/grub/device.map"))
run("grub-install", "--boot-directory="+filepath.Join(mntDir, "boot"), "/dev/nbd0")
// Set some password for testing.
run("chroot", mntDir, "/bin/bash", "-c", "echo root:r | chpasswd")
run("umount", mntDir)
run("qemu-nbd", "-d", "/dev/nbd0")
if *justRaw {
log.Printf("Stopping, and leaving %s alone.\nRun with:\n\n$ qemu-system-x86_64 -machine accel=kvm -nographic -curses -nodefconfig -smp 2 -drive if=virtio,file=%s -net nic,model=virtio -net user -boot once=d\n\n", *rawFile, *rawFile)
os.Exit(0)
}
// Write out a sparse tarball. GCE creates images from sparse
// tarballs on Google Cloud Storage.
run("tar", "-Szcf", *outFile, *rawFile)
os.Remove(*rawFile)
os.Exit(0)
}
func checkDeps() {
var missing []string
for _, cmd := range []string{
"docker",
"dumpe2fs",
"fallocate",
"grub-install",
"mkfs.ext4",
"modprobe",
"mount",
"qemu-nbd",
"rm",
"tar",
"umount",
} {
if _, err := exec.LookPath(cmd); err != nil {
missing = append(missing, cmd)
}
}
if len(missing) > 0 {
failf("Missing dependency programs: %v", missing)
}
}
func filesystemUUID() string {
e2fs, err := exec.Command("dumpe2fs", "/dev/nbd0p1").Output()
if err != nil {
failf("dumpe2fs: %v", err)
}
m := regexp.MustCompile(`Filesystem UUID:\s+(\S+)`).FindStringSubmatch(string(e2fs))
if m == nil || m[1] == "" {
failf("failed to find filesystem UUID")
}
return m[1]
}
// failf is like log.Fatalf, but runs deferred functions.
func failf(msg string, args ...interface{}) {
log.Printf(msg, args...)
runtime.Goexit()
}
func httpGet(u string) io.Reader {
res, err := http.Get(u)
if err != nil {
failf("Get %s: %v", u, err)
}
if res.StatusCode != 200 {
failf("Get %s: %v", u, res.Status)
}
// Yeah, not closing it. This program is short-lived.
return res.Body
}
func slurpFile(file string) string {
v, err := ioutil.ReadFile(file)
if err != nil {
failf("Failed to read %s: %v", file, err)
}
return string(v)
}
func writeFile(file, contents string) {
if err := ioutil.WriteFile(file, []byte(contents), 0644); err != nil {
failf("writeFile %s: %v", file, err)
}
}
func run(cmd string, args ...string) {
log.Printf("Running %s %s", cmd, args)
out, err := exec.Command(cmd, args...).CombinedOutput()
if err != nil {
failf("Error running %s %v: %v, %s", cmd, args, err, out)
}
}
func pipeInto(stdin io.Reader, cmd string, args ...string) {
log.Printf("Running %s %s", cmd, args)
c := exec.Command(cmd, args...)
c.Stdin = stdin
out, err := c.CombinedOutput()
if err != nil {
failf("Error running %s %v: %v, %s", cmd, args, err, out)
}
}

Просмотреть файл

@ -28,6 +28,7 @@ type BuildConfig struct {
VMImage string // e.g. "openbsd-amd64-56"
machineType string // optional GCE instance type
Go14URL string // URL to built Go 1.4 tar.gz
buildletURL string // optional override buildlet URL
// Docker-specific settings: (used if VMImage == "")
Image string // Docker image to use to build
@ -52,6 +53,14 @@ func (c *BuildConfig) GOARCH() string {
return arch[:i]
}
// BuildletBinaryURL returns the public URL of this builder's buildlet.
func (c *BuildConfig) BuildletBinaryURL() string {
if c.buildletURL != "" {
return c.buildletURL
}
return "http://storage.googleapis.com/go-builder-data/buildlet." + c.GOOS() + "-" + c.GOARCH()
}
// AllScript returns the relative path to the operating system's script to
// do the build and run its standard set of tests.
// Example values are "src/all.bash", "src/all.bat", "src/all.rc".
@ -128,14 +137,7 @@ func (conf BuildConfig) DockerRunArgs(rev, builderKey string) ([]string, error)
}
func init() {
addBuilder(BuildConfig{Name: "linux-386"})
addBuilder(BuildConfig{Name: "linux-386-387", env: []string{"GO386=387"}})
addBuilder(BuildConfig{Name: "linux-amd64"})
addBuilder(BuildConfig{Name: "linux-amd64-nocgo", env: []string{"CGO_ENABLED=0", "USER=root"}})
addBuilder(BuildConfig{Name: "linux-amd64-noopt", env: []string{"GO_GCFLAGS=-N -l"}})
addBuilder(BuildConfig{Name: "linux-amd64-race"})
addBuilder(BuildConfig{Name: "nacl-386"})
addBuilder(BuildConfig{Name: "nacl-amd64p32"})
// Docker-based gccgo builders:
addBuilder(BuildConfig{
Name: "linux-amd64-gccgo",
Image: "gobuilders/linux-x86-gccgo",
@ -150,10 +152,14 @@ func init() {
dashURL: "https://build.golang.org/gccgo",
tool: "gccgo",
})
// TODO(bradfitz,adg,jbd): convert these (sid, clang, nacl) to VMs too:
addBuilder(BuildConfig{Name: "linux-386-sid", Image: "gobuilders/linux-x86-sid"})
addBuilder(BuildConfig{Name: "linux-amd64-sid", Image: "gobuilders/linux-x86-sid"})
addBuilder(BuildConfig{Name: "linux-386-clang", Image: "gobuilders/linux-x86-clang"})
addBuilder(BuildConfig{Name: "linux-amd64-clang", Image: "gobuilders/linux-x86-clang"})
addBuilder(BuildConfig{Name: "nacl-386"})
addBuilder(BuildConfig{Name: "nacl-amd64p32"})
// VMs:
addBuilder(BuildConfig{
@ -180,8 +186,55 @@ func init() {
Name: "freebsd-386-gce101",
VMImage: "freebsd-amd64-gce101",
machineType: "n1-highcpu-2",
buildletURL: "http://storage.googleapis.com/go-builder-data/buildlet.freebsd-amd64",
Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-freebsd-amd64.tar.gz",
env: []string{"GOARCH=386", "CC=clang"},
// TODO(bradfitz): setting GOHOSTARCH=386 should work
// to eliminate some unnecessary work (it works on
// Linux), but fails on FreeBSD with:
// ##### ../misc/cgo/testso
// Shared object "libcgosotest.so" not found, required by "main"
// Maybe this is a clang thing? We'll see when we do linux clang too.
env: []string{"GOARCH=386", "CC=clang"},
})
addBuilder(BuildConfig{
Name: "linux-386",
VMImage: "linux-buildlet-std",
buildletURL: "http://storage.googleapis.com/go-builder-data/buildlet.linux-amd64",
env: []string{"GOROOT_BOOTSTRAP=/go1.4", "GOARCH=386", "GOHOSTARCH=386"},
})
addBuilder(BuildConfig{
Name: "linux-386-387",
VMImage: "linux-buildlet-std",
buildletURL: "http://storage.googleapis.com/go-builder-data/buildlet.linux-amd64",
env: []string{"GOROOT_BOOTSTRAP=/go1.4", "GOARCH=386", "GOHOSTARCH=386", "GO386=387"},
})
addBuilder(BuildConfig{
Name: "linux-amd64",
VMImage: "linux-buildlet-std",
env: []string{"GOROOT_BOOTSTRAP=/go1.4"},
})
addBuilder(BuildConfig{
Name: "linux-amd64-nocgo",
VMImage: "linux-buildlet-std",
env: []string{
"GOROOT_BOOTSTRAP=/go1.4",
"CGO_ENABLED=0",
// This USER=root was required for Docker-based builds but probably isn't required
// in the VM anymore, since the buildlet probably already has this in its environment.
// (It was required because without cgo, it couldn't find the username)
"USER=root",
},
})
addBuilder(BuildConfig{
Name: "linux-amd64-noopt",
VMImage: "linux-buildlet-std",
env: []string{"GOROOT_BOOTSTRAP=/go1.4", "GO_GCFLAGS=-N -l"},
})
addBuilder(BuildConfig{
Name: "linux-amd64-race",
VMImage: "linux-buildlet-std",
machineType: "n1-highcpu-4",
env: []string{"GOROOT_BOOTSTRAP=/go1.4"},
})
addBuilder(BuildConfig{
Name: "openbsd-amd64-gce56",
@ -257,7 +310,7 @@ func addBuilder(c BuildConfig) {
c.cmd = "/usr/local/bin/build-command.pl"
}
}
if strings.HasPrefix(c.Name, "linux-") && c.Image == "" {
if strings.HasPrefix(c.Name, "linux-") && c.Image == "" && c.VMImage == "" {
c.Image = "gobuilders/linux-x86-base"
}
if c.Image == "" && c.VMImage == "" {

19
env/linux-x86-base/Dockerfile поставляемый
Просмотреть файл

@ -1,19 +0,0 @@
# Copyright 2014 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.
# Base builder image: gobuilders/linux-x86-base
FROM debian:wheezy
MAINTAINER golang-dev <golang-dev@googlegroups.com>
ENV DEBIAN_FRONTEND noninteractive
ADD /scripts/install-apt-deps.sh /scripts/
RUN /scripts/install-apt-deps.sh
ADD /scripts/build-go-builder.sh /scripts/
RUN GO_REV=go1.4 TOOLS_REV=d79e0375a BUILDER_REV=fa8373a /scripts/build-go-builder.sh && test -f /usr/local/bin/builder
RUN mkdir -p /go1.4-386 && (curl --silent https://storage.googleapis.com/golang/go1.4.linux-386.tar.gz | tar -C /go1.4-386 -zxv)
RUN mkdir -p /go1.4-amd64 && (curl --silent https://storage.googleapis.com/golang/go1.4.linux-amd64.tar.gz | tar -C /go1.4-amd64 -zxv)

15
env/linux-x86-base/Makefile поставляемый
Просмотреть файл

@ -1,15 +0,0 @@
# Copyright 2014 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.
docker: Dockerfile
docker build -t gobuilders/linux-x86-base .
docker-linux.base.tar.gz: docker
docker save gobuilders/linux-x86-base | gzip | (cd ../../cmd/upload && go run upload.go --public go-builder-data/docker-linux.base.tar.gz)
check: docker
docker run -e GOROOT_BOOTSTRAP=/go1.4-amd64/go gobuilders/linux-x86-base /usr/local/bin/builder -rev=20a10e7ddd1 -buildroot=/ -v -report=false linux-amd64-temp
check32: docker
docker run -e GOROOT_BOOTSTRAP=/go1.4-386/go gobuilders/linux-x86-base /usr/local/bin/builder -rev=20a10e7ddd1 -buildroot=/ -v -report=false linux-386-temp

Просмотреть файл

@ -1,30 +0,0 @@
set -ex
export GOPATH=/gopath
export GOROOT=/goroot
PREFIX=/usr/local
: ${GO_REV:?"need to be set to the golang repo revision used to build the builder."}
: ${TOOLS_REV:?"need to be set to the tools repo revision used to build the builder."}
: ${BUILDER_REV:?"need to be set to the build repo revision for the builder."}
mkdir -p $GOROOT
git clone https://go.googlesource.com/go $GOROOT
(cd $GOROOT/src && git checkout $GO_REV && find && ./make.bash)
GO_TOOLS=$GOPATH/src/golang.org/x/tools
mkdir -p $GO_TOOLS
git clone https://go.googlesource.com/tools $GO_TOOLS
(cd $GO_TOOLS && git reset --hard $TOOLS_REV)
GO_BUILD=$GOPATH/src/golang.org/x/build
mkdir -p $GO_BUILD
git clone https://go.googlesource.com/build $GO_BUILD
mkdir -p $PREFIX/bin
(cd $GO_BUILD && git reset --hard $BUILDER_REV && GOBIN=$PREFIX/bin /goroot/bin/go install golang.org/x/build/cmd/builder)
rm -fR $GOROOT/bin $GOROOT/pkg $GOPATH
cd $GOROOT
git clean -f -d -x
git checkout master

Просмотреть файл

@ -1,20 +0,0 @@
set -ex
apt-get update
apt-get install -y --no-install-recommends ca-certificates
# Optionally used by some net/http tests:
apt-get install -y --no-install-recommends strace
# Optionally used by runtime tests for gdb:
apt-get install -y --no-install-recommends gdb
# For building Go's bootstrap 'dist' prog
apt-get install -y --no-install-recommends gcc libc6-dev
# For 32-bit builds:
# TODO(bradfitz): move these into a 386 image that derives from this one.
apt-get install -y --no-install-recommends libc6-dev-i386 gcc-multilib
# For interacting with the Go source & subrepos:
apt-get install -y --no-install-recommends git-core
# For downloading Go 1.4:
apt-get install -y --no-install-recommends curl
apt-get clean
rm -fr /var/lib/apt/lists

48
env/linux-x86-std/Dockerfile поставляемый Normal file
Просмотреть файл

@ -0,0 +1,48 @@
# Copyright 2014 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.
# Base builder image: gobuilders/linux-x86-base
FROM debian:wheezy
MAINTAINER golang-dev <golang-dev@googlegroups.com>
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get install -y --no-install-recommends ca-certificates
# Optionally used by some net/http tests:
RUN apt-get install -y --no-install-recommends strace
# Optionally used by runtime tests for gdb:
RUN apt-get install -y --no-install-recommends gdb
# For building Go's bootstrap 'dist' prog
RUN apt-get install -y --no-install-recommends gcc libc6-dev
# For 32-bit builds:
# TODO(bradfitz): move these into a 386 image that derives from this one.
RUN apt-get install -y --no-install-recommends libc6-dev-i386 gcc-multilib
# For downloading Go 1.4:
RUN apt-get install -y --no-install-recommends curl
RUN apt-get install -y --no-install-recommends net-tools ifupdown isc-dhcp-client dhcp3-client
RUN apt-get install -y --no-install-recommends procps lsof psmisc
RUN apt-get clean
RUN mkdir -p /go1.4-amd64 && (curl --silent https://storage.googleapis.com/golang/go1.4.linux-amd64.tar.gz | tar -C /go1.4-amd64 -zxv)
RUN mv /go1.4-amd64/go /go1.4 && rmdir /go1.4-amd64
RUN curl -o /usr/local/bin/stage0 https://storage.googleapis.com/go-builder-data/stage0.linux-amd64.92ebb4ec
RUN chmod +x /usr/local/bin/stage0
ADD scripts/rc.local /etc/init.d/rc.local
RUN chmod +x /etc/init.d/rc.local
RUN rm -rf /var/lib/apt/lists /usr/share/doc
RUN rm -rf /go1.4/pkg/linux_amd64_race /go1.4/api /go1.4/blog /go1.4/doc /go1.4/misc /go1.4/test
RUN find /go1.4 -type d -name testdata | xargs rm -rf
RUN rm -rf /go1.4/pkg/linux_amd64_race /go1.4/test /go1.4/api
RUN (cd /usr/share/locale/ && ls -1 | grep -v en | xargs rm -rf)
RUN rm -rf /var/cache/debconf/*
RUN rm -rf /usr/share/man
RUN (echo "auto lo"; echo "iface lo inet loopback"; echo "auto eth0"; echo "iface eth0 inet dhcp") > /etc/network/interfaces

15
env/linux-x86-std/Makefile поставляемый Normal file
Просмотреть файл

@ -0,0 +1,15 @@
# Copyright 2014 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.
docker: Dockerfile
docker build -t gobuilders/linux-x86-std .
# TODO(bradfitz): test targets, using cmd/gomote and the buildlet in the container.
# TODO(bradfitz): docs on how to build a new image. In a nutshell,
#
# $ go install golang.org/x/build/cmd/docker2boot
# $ sudo docker2boot --image=gobuilders/linux-x86-std --out=linux-buildlet-std.tar.gz
# $ gsutil cp -a public-read linux-buildlet-std.tar.gz gs://go-builder-data/linux-buildlet-std.tar.gz
# $ gcloud compute --project symbolic-datum-552 images create linux-buildlet-std --source-uri gs://go-builder-data/linux-buildlet-std.tar.gz

Просмотреть файл

4
env/linux-x86-std/scripts/rc.local поставляемый Normal file
Просмотреть файл

@ -0,0 +1,4 @@
#!/bin/sh -e
start-stop-daemon --start --exec=/usr/local/bin/stage0 --background /usr/local/bin/stage0 -- --network-wait=15s
exit 0