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 (