Files
Containr/app/backend/migrations/003_agent_system.sql
T
2026-04-10 12:02:36 +02:00

192 lines
8.1 KiB
PL/PgSQL

-- Agent system migration for Phase 3: Node Agent System
-- Create node_agents table
CREATE TABLE IF NOT EXISTS node_agents (
id VARCHAR(255) PRIMARY KEY,
name VARCHAR(255) NOT NULL,
hostname VARCHAR(255) NOT NULL,
ip_address VARCHAR(45) NOT NULL,
port INTEGER NOT NULL,
status VARCHAR(50) DEFAULT 'offline',
version VARCHAR(50),
capabilities JSONB,
resources JSONB,
last_heartbeat TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
metadata JSONB
);
-- Create container_instances table
CREATE TABLE IF NOT EXISTS container_instances (
id VARCHAR(255) PRIMARY KEY,
name VARCHAR(255) NOT NULL,
image VARCHAR(255) NOT NULL,
project_id VARCHAR(255) NOT NULL,
service_id VARCHAR(255) NOT NULL,
node_agent_id VARCHAR(255) NOT NULL,
status JSONB,
resources JSONB,
ports JSONB,
environment JSONB,
volumes JSONB,
networks JSONB,
restart_policy JSONB,
health_check JSONB,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
started_at TIMESTAMP WITH TIME ZONE,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
FOREIGN KEY (node_agent_id) REFERENCES node_agents(id) ON DELETE CASCADE
);
-- Create agent_commands table
CREATE TABLE IF NOT EXISTS agent_commands (
id VARCHAR(255) PRIMARY KEY,
type VARCHAR(100) NOT NULL,
node_agent_id VARCHAR(255) NOT NULL,
container_id VARCHAR(255),
payload JSONB,
status VARCHAR(50) DEFAULT 'pending',
result TEXT,
error TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
completed_at TIMESTAMP WITH TIME ZONE,
FOREIGN KEY (node_agent_id) REFERENCES node_agents(id) ON DELETE CASCADE,
FOREIGN KEY (container_id) REFERENCES container_instances(id) ON DELETE CASCADE
);
-- Create node_clusters table
CREATE TABLE IF NOT EXISTS node_clusters (
id VARCHAR(255) PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT,
status VARCHAR(50) DEFAULT 'active',
total_resources JSONB,
used_resources JSONB,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Create cluster_agents table to link clusters and agents
CREATE TABLE IF NOT EXISTS cluster_agents (
cluster_id VARCHAR(255) NOT NULL,
agent_id VARCHAR(255) NOT NULL,
added_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
PRIMARY KEY (cluster_id, agent_id),
FOREIGN KEY (cluster_id) REFERENCES node_clusters(id) ON DELETE CASCADE,
FOREIGN KEY (agent_id) REFERENCES node_agents(id) ON DELETE CASCADE
);
-- Create scheduling_rules table
CREATE TABLE IF NOT EXISTS scheduling_rules (
id VARCHAR(255) PRIMARY KEY,
cluster_id VARCHAR(255) NOT NULL,
name VARCHAR(255) NOT NULL,
type VARCHAR(50) NOT NULL,
selector JSONB,
weight INTEGER DEFAULT 1,
enabled BOOLEAN DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
FOREIGN KEY (cluster_id) REFERENCES node_clusters(id) ON DELETE CASCADE
);
-- Create container_metrics table for monitoring
CREATE TABLE IF NOT EXISTS container_metrics (
id SERIAL PRIMARY KEY,
container_id VARCHAR(255) NOT NULL,
timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
cpu_usage DECIMAL(5,2),
cpu_usage_percent DECIMAL(5,2),
memory_usage BIGINT,
memory_usage_percent DECIMAL(5,2),
memory_limit BIGINT,
network_rx_bytes BIGINT,
network_tx_bytes BIGINT,
network_rx_packets BIGINT,
network_tx_packets BIGINT,
block_read_bytes BIGINT,
block_write_bytes BIGINT,
pids_current INTEGER,
pids_limit INTEGER,
FOREIGN KEY (container_id) REFERENCES container_instances(id) ON DELETE CASCADE
);
-- Create indexes for performance
CREATE INDEX IF NOT EXISTS idx_node_agents_status ON node_agents(status);
CREATE INDEX IF NOT EXISTS idx_node_agents_hostname ON node_agents(hostname);
CREATE INDEX IF NOT EXISTS idx_node_agents_ip_address ON node_agents(ip_address);
CREATE INDEX IF NOT EXISTS idx_node_agents_last_heartbeat ON node_agents(last_heartbeat);
CREATE INDEX IF NOT EXISTS idx_container_instances_project_id ON container_instances(project_id);
CREATE INDEX IF NOT EXISTS idx_container_instances_service_id ON container_instances(service_id);
CREATE INDEX IF NOT EXISTS idx_container_instances_node_agent_id ON container_instances(node_agent_id);
CREATE INDEX IF NOT EXISTS idx_container_instances_status ON container_instances USING GIN(status);
CREATE INDEX IF NOT EXISTS idx_agent_commands_node_agent_id ON agent_commands(node_agent_id);
CREATE INDEX IF NOT EXISTS idx_agent_commands_status ON agent_commands(status);
CREATE INDEX IF NOT EXISTS idx_agent_commands_type ON agent_commands(type);
CREATE INDEX IF NOT EXISTS idx_agent_commands_created_at ON agent_commands(created_at);
CREATE INDEX IF NOT EXISTS idx_container_metrics_container_id ON container_metrics(container_id);
CREATE INDEX IF NOT EXISTS idx_container_metrics_timestamp ON container_metrics(timestamp);
-- Create updated_at trigger function
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ language 'plpgsql';
-- Create triggers for updated_at (only if they don't exist)
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'update_node_agents_updated_at') THEN
CREATE TRIGGER update_node_agents_updated_at BEFORE UPDATE ON node_agents
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'update_container_instances_updated_at') THEN
CREATE TRIGGER update_container_instances_updated_at BEFORE UPDATE ON container_instances
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'update_agent_commands_updated_at') THEN
CREATE TRIGGER update_agent_commands_updated_at BEFORE UPDATE ON agent_commands
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'update_node_clusters_updated_at') THEN
CREATE TRIGGER update_node_clusters_updated_at BEFORE UPDATE ON node_clusters
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'update_scheduling_rules_updated_at') THEN
CREATE TRIGGER update_scheduling_rules_updated_at BEFORE UPDATE ON scheduling_rules
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
END IF;
END $$;
-- Insert default cluster
INSERT INTO node_clusters (id, name, description, status, total_resources, used_resources)
VALUES (
'default-cluster',
'Default Cluster',
'Default cluster for all node agents',
'active',
'{"cpu": {"cores": 0, "allocation": 0, "usage": 0}, "memory": {"total": 0, "allocated": 0, "used": 0, "available": 0}, "storage": {"total": 0, "allocated": 0, "used": 0, "available": 0}, "network": {"interfaces": [], "bandwidth": {"inbound": 0, "outbound": 0}}}',
'{"cpu": {"cores": 0, "allocation": 0, "usage": 0}, "memory": {"total": 0, "allocated": 0, "used": 0, "available": 0}, "storage": {"total": 0, "allocated": 0, "used": 0, "available": 0}, "network": {"interfaces": [], "bandwidth": {"inbound": 0, "outbound": 0}}}'
) ON CONFLICT (id) DO NOTHING;
-- Add comment to tables
COMMENT ON TABLE node_agents IS 'Container orchestration agents that manage containers on nodes';
COMMENT ON TABLE container_instances IS 'Container instances running on node agents';
COMMENT ON TABLE agent_commands IS 'Commands sent to node agents for execution';
COMMENT ON TABLE node_clusters IS 'Clusters of node agents for resource pooling';
COMMENT ON TABLE cluster_agents IS 'Many-to-many relationship between clusters and agents';
COMMENT ON TABLE scheduling_rules IS 'Rules for scheduling containers on agents';
COMMENT ON TABLE container_metrics IS 'Metrics collected from running containers';