c/bmaas/bmdb: implement OS installation flow

This adds two new tags: OSInstallationRequest and
OSInstallationResponse. It also implements interacting with these tags
from the agent side.

This doesn't yet implement any admin/user-facing API to actually request
OS installation, for now we just exercise this in tests.

Change-Id: I2e31a8369a3a8670bb92bcacfb8231a0d5e1b9fd
Reviewed-on: https://review.monogon.dev/c/monogon/+/1011
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
Tested-by: Jenkins CI
diff --git a/cloud/bmaas/server/api/agent.proto b/cloud/bmaas/server/api/agent.proto
index c08c767..0ed29c3 100644
--- a/cloud/bmaas/server/api/agent.proto
+++ b/cloud/bmaas/server/api/agent.proto
@@ -21,6 +21,14 @@
   // TODO(lorenz): implement
 }
 
+// OSInstallationReport is submitted from the agent to the BMDB server after
+// successful OS installation.
+message OSInstallationReport {
+  // generation must be set to the same value as 'generation' in the
+  // OSInstallation request which triggered the OS installation
+  int64 generation = 1;
+}
+
 message AgentHeartbeatRequest {
   // MachineID that this agent represents. Technically not necessary since
   // keypairs between agents should be unique, but this provides an extra layer
@@ -29,8 +37,26 @@
   // Optional hardware report to be upserted for this machine. An agent should
   // submit one at least once after it's started, as early as it can.
   AgentHardwareReport hardware_report = 2;
+  // Optional installation report sent to be upserted to this machine. An agent
+  // should submit one after it successfully installed an operating system for
+  // a given OSInstallationRequest.
+  OSInstallationReport installation_report = 3;
+}
+
+// OSInstallationRequest is provided to the agent by the BMDB server, from
+// a responding BMDB tag, when an OS installation request is pending.
+message OSInstallationRequest {
+  // generation is the 'version' of the OS installation request, and will always
+  // be incremented within the BMDB when a new OS installation request is
+  // submitted. The agent must pipe this through to the OSInstallationReport to
+  // let the rest of the system know which OS installation request it actually
+  // fulfilled.
+  int64 generation = 1;
+  // TODO(lorenz): implement
 }
 
 message AgentHeartbeatResponse {
-  // Agent actions (like install, reboot, etc) go here.
+  // If set, the control plane is requesting the installation of an operating
+  // system.
+  OSInstallationRequest installation_request = 1;
 }
\ No newline at end of file