feat: add vmid allocator schema
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
- VMID-Allokator-Migration mit transaktionssicherer Reservation pro Cluster angelegt.
|
||||||
- VMs-und-SSH-Keys-Migration mit Ressourcen-Mapping und eindeutigem Proxmox-VMID-Index angelegt.
|
- VMs-und-SSH-Keys-Migration mit Ressourcen-Mapping und eindeutigem Proxmox-VMID-Index angelegt.
|
||||||
- Cluster-Migration fuer Proxmox-Verbindungen mit `encrypted_token bytea` angelegt.
|
- Cluster-Migration fuer Proxmox-Verbindungen mit `encrypted_token bytea` angelegt.
|
||||||
- Projekte-und-Quotas-Migration mit Defaults und Constraints angelegt.
|
- Projekte-und-Quotas-Migration mit Defaults und Constraints angelegt.
|
||||||
|
|||||||
@@ -54,6 +54,11 @@ Arbeitsliste auf Basis von `proxmox-console-entwicklungsplan.md`. Die Entwurfsda
|
|||||||
- [x] VMs referenzieren eindeutig Projekt und Cluster
|
- [x] VMs referenzieren eindeutig Projekt und Cluster
|
||||||
- [x] Unique-Index auf `(cluster_id, proxmox_vmid)` gesetzt
|
- [x] Unique-Index auf `(cluster_id, proxmox_vmid)` gesetzt
|
||||||
- [x] Ressourcen- und Pflichtfeld-Checks gesetzt
|
- [x] Ressourcen- und Pflichtfeld-Checks gesetzt
|
||||||
|
- [x] E2-T06: VMID-Allokator
|
||||||
|
- [x] Clusterweite Allocator-Tabelle angelegt
|
||||||
|
- [x] VMID-Reservationen vor Proxmox-Calls modelliert
|
||||||
|
- [x] Transaktionssichere Funktion `reserve_next_vmid(cluster_id)` mit `SELECT ... FOR UPDATE` angelegt
|
||||||
|
- [x] Concurrency-Test mit 50 parallelen Reservierungen lokal verifiziert
|
||||||
|
|
||||||
## MVP-Backlog
|
## MVP-Backlog
|
||||||
|
|
||||||
@@ -97,3 +102,4 @@ Arbeitsliste auf Basis von `proxmox-console-entwicklungsplan.md`. Die Entwurfsda
|
|||||||
- 2026-06-10: Projekte-und-Quotas-Migration `0003_projects_and_quotas` angelegt und lokal gegen Supabase verifiziert.
|
- 2026-06-10: Projekte-und-Quotas-Migration `0003_projects_and_quotas` angelegt und lokal gegen Supabase verifiziert.
|
||||||
- 2026-06-10: Cluster-Migration `0004_clusters` angelegt und lokal gegen Supabase verifiziert.
|
- 2026-06-10: Cluster-Migration `0004_clusters` angelegt und lokal gegen Supabase verifiziert.
|
||||||
- 2026-06-10: VMs-und-SSH-Keys-Migration `0005_vms_and_ssh_keys` angelegt und lokal gegen Supabase verifiziert.
|
- 2026-06-10: VMs-und-SSH-Keys-Migration `0005_vms_and_ssh_keys` angelegt und lokal gegen Supabase verifiziert.
|
||||||
|
- 2026-06-10: VMID-Allokator-Migration `0006_vmid_allocator` angelegt und mit 50 parallelen Reservierungen lokal gegen Supabase verifiziert.
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
DROP FUNCTION IF EXISTS public.reserve_next_vmid(uuid);
|
||||||
|
DROP INDEX IF EXISTS public.vmid_reservations_cluster_id_idx;
|
||||||
|
DROP INDEX IF EXISTS public.vmid_reservations_reserved_key;
|
||||||
|
DROP TABLE IF EXISTS public.vmid_reservations;
|
||||||
|
DROP TABLE IF EXISTS public.cluster_vmid_allocators;
|
||||||
|
DROP TYPE IF EXISTS public.vmid_reservation_status;
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
CREATE TYPE public.vmid_reservation_status AS ENUM ('reserved', 'released');
|
||||||
|
|
||||||
|
CREATE TABLE public.cluster_vmid_allocators (
|
||||||
|
cluster_id uuid PRIMARY KEY REFERENCES public.clusters(id) ON DELETE CASCADE,
|
||||||
|
next_vmid integer NOT NULL DEFAULT 100,
|
||||||
|
created_at timestamptz NOT NULL DEFAULT now(),
|
||||||
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||||
|
CONSTRAINT cluster_vmid_allocators_next_vmid_check CHECK (next_vmid > 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE public.vmid_reservations (
|
||||||
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
cluster_id uuid NOT NULL REFERENCES public.clusters(id) ON DELETE CASCADE,
|
||||||
|
proxmox_vmid integer NOT NULL,
|
||||||
|
status public.vmid_reservation_status NOT NULL DEFAULT 'reserved',
|
||||||
|
created_at timestamptz NOT NULL DEFAULT now(),
|
||||||
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||||
|
CONSTRAINT vmid_reservations_proxmox_vmid_check CHECK (proxmox_vmid > 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX vmid_reservations_reserved_key
|
||||||
|
ON public.vmid_reservations (cluster_id, proxmox_vmid)
|
||||||
|
WHERE status = 'reserved';
|
||||||
|
|
||||||
|
CREATE INDEX vmid_reservations_cluster_id_idx ON public.vmid_reservations (cluster_id);
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION public.reserve_next_vmid(p_cluster_id uuid)
|
||||||
|
RETURNS integer
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
candidate integer;
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO public.cluster_vmid_allocators (cluster_id)
|
||||||
|
VALUES (p_cluster_id)
|
||||||
|
ON CONFLICT (cluster_id) DO NOTHING;
|
||||||
|
|
||||||
|
SELECT next_vmid
|
||||||
|
INTO candidate
|
||||||
|
FROM public.cluster_vmid_allocators
|
||||||
|
WHERE cluster_id = p_cluster_id
|
||||||
|
FOR UPDATE;
|
||||||
|
|
||||||
|
LOOP
|
||||||
|
EXIT WHEN NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM public.vms
|
||||||
|
WHERE cluster_id = p_cluster_id
|
||||||
|
AND proxmox_vmid = candidate
|
||||||
|
) AND NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM public.vmid_reservations
|
||||||
|
WHERE cluster_id = p_cluster_id
|
||||||
|
AND proxmox_vmid = candidate
|
||||||
|
AND status = 'reserved'
|
||||||
|
);
|
||||||
|
|
||||||
|
candidate := candidate + 1;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
INSERT INTO public.vmid_reservations (cluster_id, proxmox_vmid)
|
||||||
|
VALUES (p_cluster_id, candidate);
|
||||||
|
|
||||||
|
UPDATE public.cluster_vmid_allocators
|
||||||
|
SET next_vmid = candidate + 1,
|
||||||
|
updated_at = now()
|
||||||
|
WHERE cluster_id = p_cluster_id;
|
||||||
|
|
||||||
|
RETURN candidate;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
Reference in New Issue
Block a user