go/{mirko,statusz}: better status, kubernetes client

Change-Id: I66753a79eaf36529aee508d2b7782aab00de1498
diff --git a/go/statusz/BUILD.bazel b/go/statusz/BUILD.bazel
index f051d72..4434b95 100644
--- a/go/statusz/BUILD.bazel
+++ b/go/statusz/BUILD.bazel
@@ -12,4 +12,10 @@
         "@com_github_golang_glog//:go_default_library",
         "@com_github_shirou_gopsutil//load:go_default_library",
     ],
+    x_defs = {
+        "code.hackerspace.pl/hscloud/go/statusz.GitCommit": "{STABLE_GIT_COMMIT}",
+        "code.hackerspace.pl/hscloud/go/statusz.GitVersion": "{STABLE_GIT_VERSION}",
+        "code.hackerspace.pl/hscloud/go/statusz.Builder": "{STABLE_BUILDER}",
+        "code.hackerspace.pl/hscloud/go/statusz.BuildTimestamp": "{BUILD_TIMESTAMP}",
+    },
 )
diff --git a/go/statusz/statusz.go b/go/statusz/statusz.go
index 2aa76e4..20d5151 100644
--- a/go/statusz/statusz.go
+++ b/go/statusz/statusz.go
@@ -42,6 +42,7 @@
 	"os"
 	"os/user"
 	"path/filepath"
+	"strconv"
 	"sync"
 	"time"
 
@@ -60,6 +61,13 @@
 	tmpl     = template.Must(reparse(nil))
 	funcs    = make(template.FuncMap)
 
+	GitCommit      = "unknown"
+	GitVersion     = "unknown"
+	Builder        = "unknown"
+	BuildTimestamp = "0"
+	// mirko populates this
+	PublicAddress = "#"
+
 	DefaultMux = true
 )
 
@@ -75,15 +83,18 @@
 <title>Status for {{.BinaryName}}</title>
 <style>
 body {
-font-family: sans-serif;
 background: #fff;
 }
 h1 {
+font-family: sans-serif;
 clear: both;
 width: 100%;
 text-align: center;
 font-size: 120%;
+padding-top: 0.3em;
+padding-bottom: 0.3em;
 background: #eeeeff;
+margin-top: 1em;
 }
 .lefthand {
 float: left;
@@ -97,16 +108,19 @@
 <h1>Status for {{.BinaryName}}</h1>
 <div>
 <div class=lefthand>
-Started at {{.StartTime}}<br>
-Current time {{.CurrentTime}}<br>
+Started: {{.StartTime}} -- up {{.Up}}<br>
+Built on {{.BuildTime}}<br>
+Built at {{.Builder}}<br>
+Built from git checkout <a href="https://gerrit.hackerspace.pl/plugins/gitiles/hscloud/+/{{.GitCommit}}">{{.GitVersion}}</a><br>
 SHA256 {{.BinaryHash}}<br>
 </div>
 <div class=righthand>
-Running as {{.Username}} on {{.Hostname}}<br>
+Running as {{.Username}} on <a href="{{.PublicAddress}}">{{.Hostname}}</a><br>
 Load {{.LoadAvg}}<br>
 View <a href=/debug/status>status</a>,
 	<a href=/debug/requests>requests</a>
 </div>
+<div style="clear: both;"> </div>
 </div>`
 
 func reparse(sections []section) (*template.Template, error) {
@@ -133,24 +147,39 @@
 	lock.Lock()
 	defer lock.Unlock()
 
+	buildTime := time.Unix(0, 0)
+	if buildTimeNum, err := strconv.Atoi(BuildTimestamp); err == nil {
+		buildTime = time.Unix(int64(buildTimeNum), 0)
+	}
+
 	data := struct {
-		Sections    []section
-		BinaryName  string
-		BinaryHash  string
-		Hostname    string
-		Username    string
-		StartTime   string
-		CurrentTime string
-		LoadAvg     string
+		Sections      []section
+		BinaryName    string
+		BinaryHash    string
+		GitVersion    string
+		GitCommit     string
+		Builder       string
+		BuildTime     string
+		Hostname      string
+		Username      string
+		StartTime     string
+		Up            string
+		LoadAvg       string
+		PublicAddress string
 	}{
-		Sections:    sections,
-		BinaryName:  binaryName,
-		BinaryHash:  binaryHash,
-		Hostname:    hostname,
-		Username:    username,
-		StartTime:   serverStart.Format(time.RFC1123),
-		CurrentTime: time.Now().Format(time.RFC1123),
-		LoadAvg:     loadAverage(),
+		Sections:      sections,
+		BinaryName:    binaryName,
+		BinaryHash:    binaryHash,
+		GitVersion:    GitVersion,
+		GitCommit:     GitCommit,
+		Builder:       Builder,
+		BuildTime:     fmt.Sprintf("%s (%d)", buildTime.Format(time.RFC1123), buildTime.Unix()),
+		Hostname:      hostname,
+		Username:      username,
+		StartTime:     serverStart.Format(time.RFC1123),
+		Up:            time.Since(serverStart).String(),
+		LoadAvg:       loadAverage(),
+		PublicAddress: PublicAddress,
 	}
 
 	if err := tmpl.ExecuteTemplate(w, "status", data); err != nil {