save progress

This commit is contained in:
StellaOps Bot
2026-01-06 09:42:02 +02:00
parent 94d68bee8b
commit 37e11918e0
443 changed files with 85863 additions and 897 deletions

View File

@@ -0,0 +1,49 @@
# devops/docker/schema-versions/Dockerfile
# Versioned PostgreSQL container for schema evolution testing
# Sprint: SPRINT_20260105_002_005_TEST_cross_cutting
# Task: CCUT-008
#
# USAGE:
# ======
# Build for specific module and version:
# docker build --build-arg MODULE=scanner --build-arg SCHEMA_VERSION=v1.2.0 \
# -t stellaops/schema-test:scanner-v1.2.0 .
#
# Run for testing:
# docker run -d -p 5432:5432 stellaops/schema-test:scanner-v1.2.0
ARG POSTGRES_VERSION=16
FROM postgres:${POSTGRES_VERSION}-alpine
# Build arguments
ARG MODULE=scanner
ARG SCHEMA_VERSION=latest
ARG SCHEMA_DATE=""
# Labels for identification
LABEL org.opencontainers.image.title="StellaOps Schema Test - ${MODULE}"
LABEL org.opencontainers.image.description="PostgreSQL with ${MODULE} schema version ${SCHEMA_VERSION}"
LABEL org.opencontainers.image.version="${SCHEMA_VERSION}"
LABEL org.stellaops.module="${MODULE}"
LABEL org.stellaops.schema.version="${SCHEMA_VERSION}"
LABEL org.stellaops.schema.date="${SCHEMA_DATE}"
# Environment variables
ENV POSTGRES_USER=stellaops_test
ENV POSTGRES_PASSWORD=test_password
ENV POSTGRES_DB=stellaops_schema_test
ENV STELLAOPS_MODULE=${MODULE}
ENV STELLAOPS_SCHEMA_VERSION=${SCHEMA_VERSION}
# Copy initialization scripts
COPY docker-entrypoint-initdb.d/ /docker-entrypoint-initdb.d/
# Copy module-specific schema
COPY schemas/${MODULE}/ /schemas/${MODULE}/
# Health check
HEALTHCHECK --interval=10s --timeout=5s --start-period=30s --retries=3 \
CMD pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB} || exit 1
# Expose PostgreSQL port
EXPOSE 5432

View File

@@ -0,0 +1,179 @@
#!/bin/bash
# build-schema-images.sh
# Build versioned PostgreSQL images for schema evolution testing
# Sprint: SPRINT_20260105_002_005_TEST_cross_cutting
# Task: CCUT-008
#
# USAGE:
# ======
# Build all versions for a module:
# ./build-schema-images.sh scanner
#
# Build specific version:
# ./build-schema-images.sh scanner v1.2.0
#
# Build all modules:
# ./build-schema-images.sh --all
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
REGISTRY="${SCHEMA_REGISTRY:-ghcr.io/stellaops}"
POSTGRES_VERSION="${POSTGRES_VERSION:-16}"
# Modules with schema evolution support
MODULES=("scanner" "concelier" "evidencelocker" "authority" "sbomservice" "policy")
usage() {
echo "Usage: $0 <module|--all> [version]"
echo ""
echo "Arguments:"
echo " module Module name (scanner, concelier, evidencelocker, authority, sbomservice, policy)"
echo " --all Build all modules"
echo " version Optional specific version to build (default: all versions)"
echo ""
echo "Environment variables:"
echo " SCHEMA_REGISTRY Container registry (default: ghcr.io/stellaops)"
echo " POSTGRES_VERSION PostgreSQL version (default: 16)"
echo " PUSH_IMAGES Set to 'true' to push images after build"
exit 1
}
# Get schema versions from git tags or migration files
get_schema_versions() {
local module=$1
local versions=()
# Check for version tags
local tags=$(git tag -l "${module}-schema-v*" 2>/dev/null | sed "s/${module}-schema-//" | sort -V)
if [ -n "$tags" ]; then
versions=($tags)
else
# Fall back to migration file count
local migration_dir="$REPO_ROOT/docs/db/migrations/${module}"
if [ -d "$migration_dir" ]; then
local count=$(ls -1 "$migration_dir"/*.sql 2>/dev/null | wc -l)
for i in $(seq 1 $count); do
versions+=("v1.0.$i")
done
fi
fi
# Always include 'latest'
versions+=("latest")
echo "${versions[@]}"
}
# Copy schema files to build context
prepare_schema_context() {
local module=$1
local version=$2
local build_dir="$SCRIPT_DIR/.build/${module}/${version}"
mkdir -p "$build_dir/schemas/${module}"
mkdir -p "$build_dir/docker-entrypoint-initdb.d"
# Copy entrypoint scripts
cp "$SCRIPT_DIR/docker-entrypoint-initdb.d/"*.sh "$build_dir/docker-entrypoint-initdb.d/"
# Copy base schema
local base_schema="$REPO_ROOT/docs/db/schemas/${module}.sql"
if [ -f "$base_schema" ]; then
cp "$base_schema" "$build_dir/schemas/${module}/base.sql"
fi
# Copy migrations directory
local migrations_dir="$REPO_ROOT/docs/db/migrations/${module}"
if [ -d "$migrations_dir" ]; then
mkdir -p "$build_dir/schemas/${module}/migrations"
cp "$migrations_dir"/*.sql "$build_dir/schemas/${module}/migrations/" 2>/dev/null || true
fi
echo "$build_dir"
}
# Build image for module and version
build_image() {
local module=$1
local version=$2
echo "Building ${module} schema version ${version}..."
local build_dir=$(prepare_schema_context "$module" "$version")
local image_tag="${REGISTRY}/schema-test:${module}-${version}"
local schema_date=$(date -u +%Y-%m-%dT%H:%M:%SZ)
# Copy Dockerfile to build context
cp "$SCRIPT_DIR/Dockerfile" "$build_dir/"
# Build the image
docker build \
--build-arg MODULE="$module" \
--build-arg SCHEMA_VERSION="$version" \
--build-arg SCHEMA_DATE="$schema_date" \
--build-arg POSTGRES_VERSION="$POSTGRES_VERSION" \
-t "$image_tag" \
"$build_dir"
echo "Built: $image_tag"
# Push if requested
if [ "$PUSH_IMAGES" = "true" ]; then
echo "Pushing: $image_tag"
docker push "$image_tag"
fi
# Cleanup build directory
rm -rf "$build_dir"
}
# Build all versions for a module
build_module() {
local module=$1
local target_version=$2
echo "========================================"
echo "Building schema images for: $module"
echo "========================================"
if [ -n "$target_version" ]; then
build_image "$module" "$target_version"
else
local versions=$(get_schema_versions "$module")
for version in $versions; do
build_image "$module" "$version"
done
fi
}
# Main
if [ $# -lt 1 ]; then
usage
fi
case "$1" in
--all)
for module in "${MODULES[@]}"; do
build_module "$module" "$2"
done
;;
--help|-h)
usage
;;
*)
if [[ " ${MODULES[*]} " =~ " $1 " ]]; then
build_module "$1" "$2"
else
echo "Error: Unknown module '$1'"
echo "Valid modules: ${MODULES[*]}"
exit 1
fi
;;
esac
echo ""
echo "Build complete!"
echo "To push images, run with PUSH_IMAGES=true"

View File

@@ -0,0 +1,70 @@
#!/bin/bash
# 00-init-schema.sh
# Initialize PostgreSQL with module schema for testing
# Sprint: SPRINT_20260105_002_005_TEST_cross_cutting
# Task: CCUT-008
set -e
echo "Initializing schema for module: ${STELLAOPS_MODULE}"
echo "Schema version: ${STELLAOPS_SCHEMA_VERSION}"
# Create extensions
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
CREATE EXTENSION IF NOT EXISTS "btree_gist";
EOSQL
# Apply base schema if exists
BASE_SCHEMA="/schemas/${STELLAOPS_MODULE}/base.sql"
if [ -f "$BASE_SCHEMA" ]; then
echo "Applying base schema: $BASE_SCHEMA"
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -f "$BASE_SCHEMA"
fi
# Apply versioned schema if exists
VERSION_SCHEMA="/schemas/${STELLAOPS_MODULE}/${STELLAOPS_SCHEMA_VERSION}.sql"
if [ -f "$VERSION_SCHEMA" ]; then
echo "Applying version schema: $VERSION_SCHEMA"
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -f "$VERSION_SCHEMA"
fi
# Apply all migrations up to version
MIGRATIONS_DIR="/schemas/${STELLAOPS_MODULE}/migrations"
if [ -d "$MIGRATIONS_DIR" ]; then
echo "Applying migrations from: $MIGRATIONS_DIR"
# Get version number for comparison
VERSION_NUM=$(echo "$STELLAOPS_SCHEMA_VERSION" | sed 's/v//' | sed 's/\.//g')
for migration in $(ls -1 "$MIGRATIONS_DIR"/*.sql 2>/dev/null | sort -V); do
MIGRATION_VERSION=$(basename "$migration" .sql | sed 's/[^0-9]//g')
if [ -n "$VERSION_NUM" ] && [ "$MIGRATION_VERSION" -gt "$VERSION_NUM" ]; then
echo "Skipping migration $migration (version $MIGRATION_VERSION > $VERSION_NUM)"
continue
fi
echo "Applying migration: $migration"
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -f "$migration"
done
fi
# Record schema version in metadata table
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE TABLE IF NOT EXISTS _schema_metadata (
key TEXT PRIMARY KEY,
value TEXT NOT NULL,
updated_at TIMESTAMPTZ DEFAULT NOW()
);
INSERT INTO _schema_metadata (key, value)
VALUES
('module', '${STELLAOPS_MODULE}'),
('schema_version', '${STELLAOPS_SCHEMA_VERSION}'),
('initialized_at', NOW()::TEXT)
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW();
EOSQL
echo "Schema initialization complete for ${STELLAOPS_MODULE} version ${STELLAOPS_SCHEMA_VERSION}"