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/bmdb/model/queries.sql b/cloud/bmaas/bmdb/model/queries.sql
index 4e32cff..8f40aac 100644
--- a/cloud/bmaas/bmdb/model/queries.sql
+++ b/cloud/bmaas/bmdb/model/queries.sql
@@ -42,8 +42,6 @@
AND session_id = $2
AND process = $3;
--- Example tag processing queries follow.
-
-- name: MachineAddProvided :exec
INSERT INTO machine_provided (
machine_id, provider, provider_id
@@ -79,6 +77,25 @@
hardware_report_raw = $2
;
+-- name: MachineSetOSInstallationRequest :exec
+INSERT INTO machine_os_installation_request (
+ machine_id, generation, os_installation_request_raw
+) VALUES (
+ $1, $2, $3
+) ON CONFLICT (machine_id) DO UPDATE SET
+ generation = $2,
+ os_installation_request_raw = $3
+;
+
+-- name: MachineSetOSInstallationReport :exec
+INSERT INTO machine_os_installation_report (
+ machine_id, generation
+) VALUES (
+ $1, $2
+) ON CONFLICT (machine_id) DO UPDATE SET
+ generation = $2
+;
+
-- name: GetMachinesForAgentStart :many
-- Get machines that need agent installed for the first time. Machine can be
-- assumed to be 'new', with no previous attempts or failures.
@@ -126,6 +143,25 @@
AND work.machine_id IS NULL
LIMIT $1;
+-- name: GetExactMachineForOSInstallation :many
+SELECT
+ machine_os_installation_request.*
+FROM machines
+LEFT JOIN machine_os_installation_request ON machines.machine_id = machine_os_installation_request.machine_id
+LEFT JOIN machine_os_installation_report ON machines.machine_id = machine_os_installation_report.machine_id
+WHERE
+ -- We are only interested in one concrete machine.
+ machines.machine_id = $1
+ -- We must have an installation request.
+ AND machine_os_installation_request.machine_id IS NOT NULL
+ -- And we either must have no installation report, or the installation
+ -- report's generation must not match the installation request's generation.
+ AND (
+ machine_os_installation_report.machine_id IS NULL
+ OR machine_os_installation_report.generation != machine_os_installation_request.generation
+ )
+LIMIT $2;
+
-- name: AuthenticateAgentConnection :many
SELECT
machine_agent_started.*
@@ -133,4 +169,4 @@
INNER JOIN machine_agent_started ON machines.machine_id = machine_agent_started.machine_id
WHERE
machines.machine_id = $1
- AND machine_agent_started.agent_public_key = $2;
\ No newline at end of file
+ AND machine_agent_started.agent_public_key = $2;