Skip to content

Commit 92b7f2c

Browse files
committed
ci: add db support to deploy script
1 parent 7851e23 commit 92b7f2c

File tree

2 files changed

+232
-0
lines changed

2 files changed

+232
-0
lines changed

scripts/deploy.sh

+148
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ declare -A containers=(
1010
["prosper-dev"]="dev,5060,3060"
1111
)
1212

13+
# PostgreSQL configuration
14+
PG_CONTAINER_NAME="agents-db"
15+
PG_PORT="5432"
16+
PG_USER="postgres"
17+
PG_PASSWORD="postgres"
18+
PG_DB="postgres" # Default PostgreSQL database
19+
PG_VOLUME="agents-db-data"
20+
DOCKER_NETWORK="agents-network"
21+
1322
# navigate to the directory containing this script
1423
cd $(dirname $0)
1524

@@ -25,6 +34,124 @@ command -v docker >/dev/null 2>&1 || { log_message "Error: docker is required bu
2534

2635
log_message "All required commands are available"
2736

37+
# Function to ensure the Docker network exists
38+
ensure_network() {
39+
log_message "Checking Docker network..."
40+
if ! docker network ls --format '{{.Name}}' | grep -q "^${DOCKER_NETWORK}$"; then
41+
log_message "Creating Docker network ${DOCKER_NETWORK}..."
42+
docker network create ${DOCKER_NETWORK}
43+
else
44+
log_message "Docker network ${DOCKER_NETWORK} already exists."
45+
fi
46+
}
47+
48+
# Function to setup PostgreSQL container if it doesn't exist
49+
setup_postgres() {
50+
log_message "Checking PostgreSQL container..."
51+
52+
# Check if PostgreSQL container exists and is running
53+
if docker ps --format '{{.Names}}' | grep -q "^${PG_CONTAINER_NAME}$"; then
54+
log_message "PostgreSQL container is already running."
55+
56+
# Ensure the container is in the right network
57+
if ! docker network inspect ${DOCKER_NETWORK} | grep -q "\"${PG_CONTAINER_NAME}\""; then
58+
log_message "Connecting PostgreSQL container to ${DOCKER_NETWORK} network..."
59+
docker network connect ${DOCKER_NETWORK} ${PG_CONTAINER_NAME}
60+
fi
61+
62+
return 0
63+
fi
64+
65+
# Check if container exists but is not running
66+
if docker ps -a --format '{{.Names}}' | grep -q "^${PG_CONTAINER_NAME}$"; then
67+
log_message "PostgreSQL container exists but is not running. Starting it..."
68+
docker start ${PG_CONTAINER_NAME}
69+
70+
# Ensure the container is in the right network
71+
if ! docker network inspect ${DOCKER_NETWORK} | grep -q "\"${PG_CONTAINER_NAME}\""; then
72+
log_message "Connecting PostgreSQL container to ${DOCKER_NETWORK} network..."
73+
docker network connect ${DOCKER_NETWORK} ${PG_CONTAINER_NAME}
74+
fi
75+
76+
return 0
77+
fi
78+
79+
# Check if volume exists, if not create it
80+
if ! docker volume ls --format '{{.Name}}' | grep -q "^${PG_VOLUME}$"; then
81+
log_message "Creating PostgreSQL volume ${PG_VOLUME}..."
82+
docker volume create ${PG_VOLUME}
83+
fi
84+
85+
# Create PostgreSQL container
86+
log_message "Creating and starting PostgreSQL container..."
87+
docker run -d \
88+
--name ${PG_CONTAINER_NAME} \
89+
-e POSTGRES_USER=${PG_USER} \
90+
-e POSTGRES_PASSWORD=${PG_PASSWORD} \
91+
-e POSTGRES_DB=${PG_DB} \
92+
-v ${PG_VOLUME}:/var/lib/postgresql/data \
93+
--network=${DOCKER_NETWORK} \
94+
--restart unless-stopped \
95+
postgres
96+
97+
# Wait for PostgreSQL to be ready
98+
log_message "Waiting for PostgreSQL to be ready..."
99+
sleep 10
100+
101+
# Check if PostgreSQL is running
102+
if ! docker ps --format '{{.Names}}' | grep -q "^${PG_CONTAINER_NAME}$"; then
103+
log_message "Error: Failed to start PostgreSQL container. Aborting." >&2
104+
return 1
105+
fi
106+
107+
log_message "PostgreSQL container is ready."
108+
return 0
109+
}
110+
111+
# Function to ensure database for a container if it doesn't exist
112+
ensure_container_database() {
113+
local container_name=$1
114+
# Replace hyphens with underscores in database name to avoid SQL syntax errors
115+
local container_db="db_${container_name//-/_}"
116+
117+
log_message "Ensuring database exists for ${container_name}..." >&2
118+
119+
# Check if database exists
120+
local db_exists=$(docker exec -i ${PG_CONTAINER_NAME} psql -U ${PG_USER} -t -c "SELECT 1 FROM pg_database WHERE datname='${container_db}'")
121+
122+
# Create database if it doesn't exist
123+
if [ -z "$db_exists" ] || [ "$db_exists" != " 1" ]; then
124+
log_message "Creating database '${container_db}' for ${container_name}..." >&2
125+
docker exec -i ${PG_CONTAINER_NAME} psql -U ${PG_USER} -c "CREATE DATABASE ${container_db}"
126+
else
127+
log_message "Database '${container_db}' already exists for ${container_name}." >&2
128+
fi
129+
130+
echo "${container_db}"
131+
}
132+
133+
# Function to run SQL script for a container
134+
run_sql_for_container() {
135+
local container_name=$1
136+
137+
# Ensure container database exists and get its name
138+
local container_db=$(ensure_container_database "${container_name}")
139+
140+
log_message "Running tracing-schema.sql for ${container_name} in database ${container_db}..."
141+
142+
# Create a temporary file that customizes the SQL for this container
143+
local temp_sql_file=$(mktemp)
144+
cat tracing-schema.sql | sed "s/{{container_name}}/${container_name}/g" > ${temp_sql_file}
145+
146+
# Run the SQL script against the container's database
147+
docker exec -i ${PG_CONTAINER_NAME} psql -U ${PG_USER} -d ${container_db} < ${temp_sql_file}
148+
149+
# Clean up
150+
rm ${temp_sql_file}
151+
152+
log_message "SQL script execution completed for ${container_name} in database ${container_db}."
153+
}
154+
28155
# Function to get the specific version tag from an image
29156
get_version_tag() {
30157
local image_name=$1
@@ -95,6 +222,9 @@ deploy_containers() {
95222
continue
96223
fi
97224

225+
# Ensure container database exists and get its name
226+
local container_db=$(ensure_container_database "${container}")
227+
98228
# Stop and remove existing container if it exists
99229
if docker ps -a --format '{{.Names}}' | grep -q "^${container}$"; then
100230
log_message "Stopping and removing existing ${container} container..."
@@ -110,11 +240,29 @@ deploy_containers() {
110240
-p ${port2}:${port2} \
111241
-v $(pwd)/${container}.env:/app/.env \
112242
-e VERSION="${version_tag}" \
243+
-e POSTGRES_HOST="${PG_CONTAINER_NAME}" \
244+
-e POSTGRES_PORT="${PG_PORT}" \
245+
-e POSTGRES_USER="${PG_USER}" \
246+
-e POSTGRES_PASSWORD="${PG_PASSWORD}" \
247+
-e POSTGRES_DB="${container_db}" \
248+
--network=${DOCKER_NETWORK} \
113249
--restart unless-stopped \
114250
ghcr.io/sifchain/realityspiral:${image_tag}
251+
252+
# Run SQL script for this container
253+
run_sql_for_container "${container}"
115254
done
116255
}
117256

257+
# Ensure Docker network exists
258+
ensure_network
259+
260+
# Setup PostgreSQL container
261+
if ! setup_postgres; then
262+
log_message "Failed to setup PostgreSQL container. Aborting deployment."
263+
exit 1
264+
fi
265+
118266
# Deploy production containers with specific version tag
119267
log_message "Deploying production containers..."
120268
deploy_containers "prod" "latest" # The actual tag will be replaced in the function

scripts/tracing-schema.sql

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
-- Drop tables if they already exist (drop events first since it depends on traces)
2+
DROP TABLE IF EXISTS events;
3+
DROP TABLE IF EXISTS traces;
4+
5+
-- Create the traces table
6+
CREATE TABLE IF NOT EXISTS traces (
7+
trace_id VARCHAR(256) NOT NULL,
8+
span_id VARCHAR(256) NOT NULL,
9+
parent_span_id VARCHAR(256),
10+
trace_state VARCHAR(256),
11+
span_name VARCHAR(256) NOT NULL,
12+
span_kind VARCHAR(64) NOT NULL, -- e.g., "INTERNAL", "SERVER", "CLIENT"
13+
start_time TIMESTAMPTZ NOT NULL,
14+
end_time TIMESTAMPTZ NOT NULL,
15+
duration_ms INTEGER,
16+
status_code VARCHAR(64), -- e.g., "OK", "ERROR"
17+
status_message TEXT,
18+
attributes JSONB,
19+
events JSONB,
20+
links JSONB,
21+
resource JSONB,
22+
agent_id VARCHAR(256),
23+
session_id VARCHAR(256),
24+
environment VARCHAR(64),
25+
room_id VARCHAR(256),
26+
raw_context TEXT NOT NULL DEFAULT '',
27+
raw_response TEXT NOT NULL DEFAULT '',
28+
PRIMARY KEY (trace_id, span_id)
29+
);
30+
31+
-- Create indexes for traces table
32+
CREATE INDEX idx_traces_trace_id ON traces (trace_id);
33+
CREATE INDEX idx_traces_span_name ON traces (span_name);
34+
CREATE INDEX idx_traces_start_time ON traces (start_time);
35+
CREATE INDEX idx_traces_room ON traces (room_id);
36+
37+
-- Create the events table with a composite foreign key referencing traces
38+
CREATE TABLE IF NOT EXISTS events (
39+
event_id UUID DEFAULT gen_random_uuid(),
40+
trace_id VARCHAR(256) NOT NULL,
41+
span_id VARCHAR(256) NOT NULL,
42+
agent_id VARCHAR(256) NOT NULL,
43+
event_type VARCHAR(64) NOT NULL,
44+
event_time TIMESTAMPTZ NOT NULL DEFAULT NOW(),
45+
event_data JSONB NOT NULL,
46+
room_id VARCHAR(256) NOT NULL,
47+
PRIMARY KEY (event_id),
48+
FOREIGN KEY (trace_id, span_id) REFERENCES traces(trace_id, span_id)
49+
);
50+
51+
-- Create indexes for events table
52+
CREATE INDEX idx_events_agent ON events (agent_id);
53+
CREATE INDEX idx_events_type ON events (event_type);
54+
CREATE INDEX idx_events_time ON events (event_time);
55+
CREATE INDEX idx_events_room ON events (room_id);
56+
57+
-- Remove strict constraints temporarily
58+
ALTER TABLE traces
59+
DROP CONSTRAINT IF EXISTS raw_context_not_empty,
60+
DROP CONSTRAINT IF EXISTS raw_response_not_empty;
61+
62+
-- Keep NOT NULL but allow empty strings
63+
ALTER TABLE traces
64+
ALTER COLUMN raw_context DROP DEFAULT,
65+
ALTER COLUMN raw_response DROP DEFAULT;
66+
67+
-- Add smarter constraints that allow placeholders
68+
ALTER TABLE traces
69+
DROP CONSTRAINT valid_raw_context,
70+
DROP CONSTRAINT valid_raw_response;
71+
72+
ALTER TABLE traces
73+
ADD CONSTRAINT valid_raw_context
74+
CHECK (
75+
(span_name = 'llm_context_pre' AND raw_context <> '')
76+
OR (span_name <> 'llm_context_pre')
77+
);
78+
79+
ALTER TABLE traces
80+
ADD CONSTRAINT valid_raw_response
81+
CHECK (
82+
(span_name = 'llm_response_post' AND raw_response <> '')
83+
OR (span_name <> 'llm_response_post')
84+
);

0 commit comments

Comments
 (0)