[machine] Display kubernetes image name.

Change-Id: I2b19f481a680c8e45fe6b45a1673f3a3c3c4f1ff
Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/289787
Reviewed-by: Kevin Lubick <kjlubick@google.com>
Commit-Queue: Joe Gregorio <jcgregorio@google.com>
diff --git a/machine/go/machine/processor/impl.go b/machine/go/machine/processor/impl.go
index e19c0e8..a14ca80 100644
--- a/machine/go/machine/processor/impl.go
+++ b/machine/go/machine/processor/impl.go
@@ -99,6 +99,15 @@
 	}
 }
 
+// sanitizeKubernetesImageName strip off any whitespace and the image: prefix if
+// present.
+func sanitizeKubernetesImageName(in string) string {
+	if strings.HasPrefix(in, "image:") {
+		in = in[6:]
+	}
+	return strings.TrimSpace(in)
+}
+
 // Process implements the Processor interface.
 func (p *ProcessorImpl) Process(ctx context.Context, previous machine.Description, event machine.Event) machine.Description {
 	p.eventsProcessedCount.Inc(1)
@@ -155,7 +164,8 @@
 	ret.RunningSwarmingTask = event.RunningSwarmingTask
 	ret.PodName = event.Host.PodName
 	ret.LastUpdated = time.Now()
-	ret.KubernetesImage = event.Host.KubernetesImage
+
+	ret.KubernetesImage = sanitizeKubernetesImageName(event.Host.KubernetesImage)
 	for k, values := range dimensions {
 		ret.Dimensions[k] = values
 	}
diff --git a/machine/go/machine/processor/impl_test.go b/machine/go/machine/processor/impl_test.go
index c8b18dd..3156367 100644
--- a/machine/go/machine/processor/impl_test.go
+++ b/machine/go/machine/processor/impl_test.go
@@ -675,3 +675,22 @@
 	assert.True(t, ok)
 	assert.Equal(t, map[string]float64{batteryTemperatureKey: 28.1}, temp)
 }
+
+func TestSanitizeKubernetesImageName_SuccessForExpectedValue(t *testing.T) {
+	unittest.SmallTest(t)
+	assert.Equal(t,
+		"gcr.io/skia-public/rpi-swarming-client:2020-05-09T19_28_20Z-jcgregorio-4fef3ca-clean",
+		sanitizeKubernetesImageName("image: gcr.io/skia-public/rpi-swarming-client:2020-05-09T19_28_20Z-jcgregorio-4fef3ca-clean\n"),
+	)
+}
+
+func TestSanitizeKubernetesImageName_PassesEmptyStringThrough(t *testing.T) {
+	unittest.SmallTest(t)
+	assert.Equal(t, "", sanitizeKubernetesImageName(""))
+}
+
+func TestSanitizeKubernetesImageName_PassesStringWithoutImagePrefix(t *testing.T) {
+	unittest.SmallTest(t)
+	const imageName = "gcr.io/skia-public/rpi-swarming-client:2020-05-09T19_28_20Z-jcgregorio-4fef3ca-clean"
+	assert.Equal(t, imageName, sanitizeKubernetesImageName(imageName))
+}
diff --git a/machine/modules/machine-server-sk/machine-server-sk.js b/machine/modules/machine-server-sk/machine-server-sk.js
index ba244db..d73546c 100644
--- a/machine/modules/machine-server-sk/machine-server-sk.js
+++ b/machine/modules/machine-server-sk/machine-server-sk.js
@@ -78,6 +78,17 @@
   return 'Update';
 };
 
+const imageName = (machine) => {
+  // KubernetesImage looks like:
+  // "gcr.io/skia-public/rpi-swarming-client:2020-05-09T19_28_20Z-jcgregorio-4fef3ca-clean".
+  // We just need to display everything after the ":".
+  const parts = machine.KubernetesImage.split(':');
+  if (parts.length < 2) {
+    return '(missing)';
+  }
+  return parts[1];
+};
+
 const rows = (ele) => ele._machines.map((machine) => html`
 <tr id=${machine.Dimensions.id}>
   <td><a href="https://chromium-swarm.appspot.com/bot?id=${machine.Dimensions.id}">${machine.Dimensions.id}</a></td>
@@ -94,6 +105,7 @@
   <td>${diffDate(machine.LastUpdated)}</td>
   <td>${dimensions(machine)}</td>
   <td>${annotation(machine)}</td>
+  <td>${imageName(machine)}</td>
 </tr>
 `);
 
@@ -130,6 +142,7 @@
     <th>Last Seen</th>
     <th>Dimensions</th>
     <th>Annotation</th>
+    <th>Image</th>
   </tr>
   ${rows(ele)}
   </table>