feat: add vmid allocator schema
This commit is contained in:
@@ -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