all: more work on Kubernetes buildlet pool

Updates golang/go#12546

Change-Id: Iac31c237fed7973ec2bebace5248904fe3e3692d
Reviewed-on: https://go-review.googlesource.com/14396
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/cmd/buildlet/buildlet.go b/cmd/buildlet/buildlet.go
index 4213137..2488914 100644
--- a/cmd/buildlet/buildlet.go
+++ b/cmd/buildlet/buildlet.go
@@ -74,7 +74,7 @@
 	if runtime.GOOS == "plan9" {
 		log.SetOutput(&plan9LogWriter{w: os.Stderr})
 	}
-	if runtime.GOOS == "linux" {
+	if runtime.GOOS == "linux" && !inKube {
 		if w, err := os.OpenFile("/dev/console", os.O_WRONLY, 0); err == nil {
 			log.SetOutput(w)
 		}
@@ -177,12 +177,27 @@
 	log.Fatalf("Serve: %v", srv.Serve(ln))
 }
 
+var inKube, _ = strconv.ParseBool(os.Getenv("IN_KUBERNETES"))
+
 // metadataValue returns the GCE metadata instance value for the given key.
 // If the metadata is not defined, the returned string is empty.
 //
 // If not running on GCE, it falls back to using environment variables
 // for local development.
 func metadataValue(key string) string {
+	// On Kubernetes
+	if inKube {
+		v := os.Getenv(key)
+		// Respect curl-style '@' prefix to mean the rest is a filename.
+		if strings.HasPrefix(v, "@") {
+			slurp, err := ioutil.ReadFile(v[1:])
+			if err != nil {
+				log.Fatalf("Error reading file for %v: %v", key, err)
+			}
+			return string(slurp)
+		}
+	}
+
 	// The common case:
 	if metadata.OnGCE() {
 		v, err := metadata.InstanceAttributeValue(key)
diff --git a/cmd/coordinator/kube.go b/cmd/coordinator/kube.go
index 7b5f9e5..df1cd1d 100644
--- a/cmd/coordinator/kube.go
+++ b/cmd/coordinator/kube.go
@@ -11,6 +11,8 @@
 	"sync"
 
 	"golang.org/x/build/buildlet"
+	"golang.org/x/build/dashboard"
+	"golang.org/x/build/kubernetes/api"
 )
 
 /*
@@ -41,3 +43,68 @@
 	p.mu.Unlock()
 	return fmt.Sprintf("Kubernetes pool capacity: %d/%d", inUse, total)
 }
+
+// uid is caller-generated random id for the build
+func buildletPod(cfg dashboard.BuildConfig, uid string) (*api.Pod, error) {
+	pn := fmt.Sprintf("%v-%v", cfg.Name, uid)
+	p := &api.Pod{
+		TypeMeta: api.TypeMeta{
+			APIVersion: "v1",
+			Kind:       "Pod",
+		},
+		ObjectMeta: api.ObjectMeta{
+			Name: pn,
+			Labels: map[string]string{
+				"type": "buildlet",
+				"name": pn,
+			},
+		},
+		Spec: api.PodSpec{
+			Containers: []api.Container{
+				{
+					Name:  pn,
+					Image: cfg.KubeImage,
+					Ports: []api.ContainerPort{
+						{
+							Name:          "buildlet",
+							ContainerPort: 80,
+						},
+					},
+					Env: []api.EnvVar{
+						{
+							Name:  "IN_KUBERNETES",
+							Value: "1",
+						},
+					},
+				},
+			},
+		},
+	}
+	return p, nil
+}
+
+func buildletService(p *api.Pod) (*api.Service, error) {
+	s := &api.Service{
+		TypeMeta: api.TypeMeta{
+			APIVersion: "v1",
+			Kind:       "Service",
+		},
+		ObjectMeta: api.ObjectMeta{
+			Name: p.ObjectMeta.Name,
+			Labels: map[string]string{
+				"type": "buildlet-service",
+				"name": p.ObjectMeta.Name,
+			},
+		},
+		Spec: api.ServiceSpec{
+			Selector: p.ObjectMeta.Labels,
+			Type:     api.ServiceTypeNodePort,
+			Ports: []api.ServicePort{
+				{
+					Protocol: api.ProtocolTCP,
+				},
+			},
+		},
+	}
+	return s, nil
+}
diff --git a/kubernetes/client.go b/kubernetes/client.go
index de7905b..b44b650 100644
--- a/kubernetes/client.go
+++ b/kubernetes/client.go
@@ -15,7 +15,7 @@
 	"strings"
 	"time"
 
-	api "github.com/kubernetes/kubernetes/pkg/api/v1"
+	"golang.org/x/build/kubernetes/api"
 )
 
 const (