cloud/bmaas: implement webug

Webug (pronounced: /wɛbʌɡ/, not /wiːbʌɡ/) is a web debug interface for
BMDB, inspired by the great web debug interfaces of old.

It uses the new BMDB reflection API to access most
machine/tag/work/backoff information, plus sqlc queries to access
session information.

Change-Id: If0e65b6fc33ad92baef9c6d98333f90a02efa1b3
Reviewed-on: https://review.monogon.dev/c/monogon/+/1132
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
Tested-by: Jenkins CI
diff --git a/cloud/bmaas/bmdb/webug/functions.go b/cloud/bmaas/bmdb/webug/functions.go
new file mode 100644
index 0000000..4c5c625
--- /dev/null
+++ b/cloud/bmaas/bmdb/webug/functions.go
@@ -0,0 +1,36 @@
+package webug
+
+import (
+	"strings"
+)
+
+var (
+	// templateFuncs are helper functions accessible to the rendered templates.
+	templateFuncs = map[string]any{
+		// summarizeError attempts to make a Go-style "foo: bar: baz" error short by
+		// using some ugly heuristics. This is currently used to show a shorter error
+		// message in the backoff column of the machine list.
+		//
+		// TODO(q3k): fix backoff causes to be less verbose and nuke this.
+		"summarizeError": func(in string) string {
+			parts := strings.Split(in, ": ")
+			for i, p := range parts {
+				// Attempt to strip some common error prefixes.
+				if strings.HasPrefix(p, "failed to ") {
+					continue
+				}
+				if strings.HasPrefix(p, "when ") {
+					continue
+				}
+				if strings.HasPrefix(p, "while ") {
+					continue
+				}
+				// If we had some prefixes stripped but suddenly reached a part that is not
+				// prefixed
+				return "[...] " + strings.Join(parts[i:], ": ")
+			}
+			// If we stripped every single segment then just return the whole thing.
+			return in
+		},
+	}
+)