treewide: dynamically generate copyright line

A copyright line with hardcoded year was shown in various places of the
UI. Instead, take the year from the commit date.

Change-Id: I424d6c5b3aff34fe4479c37f30f9ea280b7eb4af
Reviewed-on: https://review.monogon.dev/c/monogon/+/4168
Tested-by: Jenkins CI
Reviewed-by: Tim Windelschmidt <tim@monogon.tech>
diff --git a/metropolis/installer/BUILD.bazel b/metropolis/installer/BUILD.bazel
index 27eb5a5..7e62727 100644
--- a/metropolis/installer/BUILD.bazel
+++ b/metropolis/installer/BUILD.bazel
@@ -10,7 +10,11 @@
         "//metropolis/node/core/abloader",  #keep
     ],
     importpath = "source.monogon.dev/metropolis/installer",
+    stampsrcs = ["//build:stabler_status"],
     visibility = ["//visibility:private"],
+    x_defs = {
+        "copyrightLine": "{STABLER_MONOGON_copyright}",
+    },
     deps = [
         "//osbase/blockdev",
         "//osbase/bringup",
diff --git a/metropolis/installer/main.go b/metropolis/installer/main.go
index ad0fa30..c79bf9e 100644
--- a/metropolis/installer/main.go
+++ b/metropolis/installer/main.go
@@ -32,6 +32,9 @@
 //go:embed metropolis/node/core/abloader/abloader_bin.efi
 var abloader []byte
 
+// Filled at linking time.
+var copyrightLine string
+
 const mib = 1024 * 1024
 
 // mountInstallerESP mounts the filesystem the installer was loaded from based
@@ -112,7 +115,7 @@
 	l := supervisor.Logger(ctx)
 
 	l.Info("Metropolis Installer")
-	l.Info("Copyright (c) 2024 The Monogon Project Authors")
+	l.Info(copyrightLine)
 	l.Info("")
 
 	// Validate we are running via EFI.
diff --git a/metropolis/node/core/minit/BUILD.bazel b/metropolis/node/core/minit/BUILD.bazel
index 70419d5..bff1f69 100644
--- a/metropolis/node/core/minit/BUILD.bazel
+++ b/metropolis/node/core/minit/BUILD.bazel
@@ -1,9 +1,19 @@
+load("@aspect_bazel_lib//lib:expand_template.bzl", "expand_template")
 load("@rules_cc//cc:defs.bzl", "cc_binary")
 
+expand_template(
+    name = "stamp",
+    out = "stamp.h",
+    stamp = 1,
+    stamp_substitutions = {"copyright": "{{STABLE_MONOGON_copyright}}"},
+    template = ["#define COPYRIGHT_LINE \"copyright\""],
+)
+
 cc_binary(
     name = "minit",
     srcs = [
         "main.c",
+        ":stamp",
     ],
     visibility = [
         "//metropolis/node:__pkg__",
diff --git a/metropolis/node/core/minit/main.c b/metropolis/node/core/minit/main.c
index 7b3e606..834b023 100644
--- a/metropolis/node/core/minit/main.c
+++ b/metropolis/node/core/minit/main.c
@@ -27,6 +27,8 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
+#include "metropolis/node/core/minit/stamp.h"
+
 void handle_signal(pid_t child_pid, int signum);
 
 #define NUM_CONSOLES 3
@@ -81,7 +83,7 @@
     cprintf(
         "\n"
         "  Metropolis Cluster Operating System\n"
-        "  Copyright 2020-2024 The Monogon Project Authors\n"
+        "  " COPYRIGHT_LINE "\n"
         "\n"
     );
 
diff --git a/metropolis/node/core/tconsole/BUILD.bazel b/metropolis/node/core/tconsole/BUILD.bazel
index e16eb41..2cae5df 100644
--- a/metropolis/node/core/tconsole/BUILD.bazel
+++ b/metropolis/node/core/tconsole/BUILD.bazel
@@ -11,7 +11,11 @@
         "tconsole.go",
     ],
     importpath = "source.monogon.dev/metropolis/node/core/tconsole",
+    stampsrcs = ["//build:stabler_status"],
     visibility = ["//visibility:public"],
+    x_defs = {
+        "copyrightLine": "{STABLER_MONOGON_copyright}",
+    },
     deps = [
         "//metropolis/node/core/network",
         "//metropolis/node/core/roleserve",
diff --git a/metropolis/node/core/tconsole/page_status.go b/metropolis/node/core/tconsole/page_status.go
index 2843ddf..8b08b23 100644
--- a/metropolis/node/core/tconsole/page_status.go
+++ b/metropolis/node/core/tconsole/page_status.go
@@ -13,6 +13,9 @@
 	"source.monogon.dev/version"
 )
 
+// Filled at linking time.
+var copyrightLine string
+
 // pageStatusData encompasses all data to be shown within the status page.
 type pageStatusData struct {
 	netAddr     string
@@ -39,7 +42,7 @@
 
 	// Draw the top part.
 	c.drawTextCentered(c.width/2, splitV/2, "Monogon Cluster Operating System", sty1)
-	c.drawTextCentered(c.width/2, splitV/2+1, "Copyright 2022-2024 The Monogon Project Authors", sty1)
+	c.drawTextCentered(c.width/2, splitV/2+1, copyrightLine, sty1)
 
 	// Horizontal split between left logo and right status lines, a la 'fetch'.
 	splitH := split(c.width, logoWidth, 60)