From d343524e05dff876950512d1a8aae327f0d630fb Mon Sep 17 00:00:00 2001 From: Marc Villain Date: Sun, 22 Feb 2026 20:50:26 +0100 Subject: [PATCH] feat(tools): add docker scripts --- Makefile | 62 ++++++++++++++++++++++++++++++++++----- tools/clean_docker.sh | 21 +++++++++++++ tools/install_docker.sh | 52 ++++++++++++++++++++++++++++++++ tools/start_docker.sh | 43 +++++++++++++++++++++++++++ tools/stop_docker.sh | 16 ++++++++++ tools/test_docker.sh | 41 ++++++++++++++++++++++++++ tools/uninstall_docker.sh | 22 ++++++++++++++ 7 files changed, 249 insertions(+), 8 deletions(-) create mode 100644 tools/clean_docker.sh create mode 100755 tools/install_docker.sh create mode 100755 tools/start_docker.sh create mode 100644 tools/stop_docker.sh create mode 100755 tools/test_docker.sh create mode 100644 tools/uninstall_docker.sh diff --git a/Makefile b/Makefile index b4a177d..ec12ef3 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,10 @@ PROJECT_FILENAME = pg_morbac # Read version from control file using centralized script PROJECT_VERSION = $(shell ./tools/get_version.sh $(PROJECT_FILENAME).control) +# Docker configuration +DOCKER_CONTAINER ?= postgres +DOCKER_PORT ?= 5432 + # For development, work on source files in src/ SRC_DIR = src OUTPUT_DEV_FILENAME = $(PROJECT_FILENAME).sql @@ -18,6 +22,7 @@ include $(PGXS) # Custom targets +# Build the extension SQL file from source components .PHONY: build build: @./tools/build.sh $(SRC_DIR) $(OUTPUT_DEV_FILENAME) @@ -38,6 +43,32 @@ install: build @cp $(OUTPUT_DEV_FILENAME) $(OUTPUT_RELEASE_FILENAME) @./tools/install.sh $(PROJECT_FILENAME) $(PROJECT_VERSION) +# Start PostgreSQL Docker container +.PHONY: docker-start +docker-start: + @./tools/start_docker.sh $(DOCKER_CONTAINER) $(DOCKER_PORT) + +# Stop PostgreSQL Docker container +.PHONY: docker-stop +docker-stop: + @./tools/stop_docker.sh $(DOCKER_CONTAINER) + +# Remove PostgreSQL Docker container +.PHONY: docker-clean +docker-clean: + @./tools/clean_docker.sh $(DOCKER_CONTAINER) + +# Build and install extension in Docker container +.PHONY: docker-install +docker-install: build docker-start + @cp $(OUTPUT_DEV_FILENAME) $(OUTPUT_RELEASE_FILENAME) + @./tools/install_docker.sh $(DOCKER_CONTAINER) $(PROJECT_FILENAME) $(PROJECT_VERSION) + +# Uninstall extension from Docker container +.PHONY: docker-uninstall +docker-uninstall: + @./tools/uninstall_docker.sh $(DOCKER_CONTAINER) $(PROJECT_FILENAME) + .PHONY: test test: build @dropdb morbac_test 2>/dev/null || true @@ -45,6 +76,11 @@ test: build @./tools/test.sh morbac_test $(OUTPUT_DEV_FILENAME) @dropdb morbac_test +# Build and run tests in Docker container +.PHONY: docker-test +docker-test: build docker-start + @./tools/test_docker.sh $(DOCKER_CONTAINER) morbac_test $(OUTPUT_DEV_FILENAME) + # Uninstall extension from PostgreSQL .PHONY: uninstall uninstall: @@ -59,12 +95,22 @@ clean: # Show help .PHONY: help help: - @echo "pg_morbac Makefile targets:" - @echo " make build - Build $(OUTPUT_DEV_FILENAME) from src/" - @echo " make release - Build versioned $(PROJECT_FILENAME)--X.Y.Z.sql from src/" - @echo " make test - Build and run test suite" - @echo " make install - Build and install $(PROJECT_FILENAME) to PostgreSQL" - @echo " make uninstall - Uninstall $(PROJECT_FILENAME) from PostgreSQL" - @echo " make clean - Clean up generated files" - @echo " make help - Show this help" + @echo "pg_morbac Makefile - Build and manage the PostgreSQL extension" + @echo "" + @echo "Makefile targets:" + @echo " make build - Build $(OUTPUT_DEV_FILENAME) from src/" + @echo " make release - Build versioned $(PROJECT_FILENAME)--X.Y.Z.sql from src/" + @echo " make test - Build and run test suite" + @echo " make install - Build and install $(PROJECT_FILENAME) to PostgreSQL" + @echo " make uninstall - Uninstall $(PROJECT_FILENAME) from PostgreSQL" + @echo " make clean - Clean up generated files" + @echo " make help - Show this help" + @echo "" + @echo "Docker targets:" + @echo " make docker-start - Start PostgreSQL Docker container" + @echo " make docker-stop - Stop PostgreSQL Docker container" + @echo " make docker-clean - Remove PostgreSQL Docker container" + @echo " make docker-install - Build and install extension in Docker container" + @echo " make docker-uninstall - Uninstall extension from Docker container" + @echo " make docker-test - Build and run test suite in Docker container" @echo "" diff --git a/tools/clean_docker.sh b/tools/clean_docker.sh new file mode 100644 index 0000000..2e7299b --- /dev/null +++ b/tools/clean_docker.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# clean_docker.sh - Remove a PostgreSQL Docker container +# Usage: ./clean_docker.sh [container_name] + +set -e # Exit immediately if a command exits with a non-zero status + +CONTAINER="${1:-postgres}" + +if ! docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER}$"; then + echo "Container $CONTAINER does not exist" + exit 0 +fi + +if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER}$"; then + echo "Stopping container $CONTAINER" + docker stop "$CONTAINER" +fi + +echo "Removing container $CONTAINER" +docker rm "$CONTAINER" diff --git a/tools/install_docker.sh b/tools/install_docker.sh new file mode 100755 index 0000000..cb813c2 --- /dev/null +++ b/tools/install_docker.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# install_docker.sh - Install the PostgreSQL extension to a Docker container +# Usage: ./install_docker.sh [container_name] [project_name] [version] + +set -e # Exit immediately if a command exits with a non-zero status + +CONTAINER="${1:-postgres}" +PROJECT_FILENAME="${2:-pg_morbac}" +PROJECT_VERSION="${3}" + +if [ -z "$PROJECT_VERSION" ]; then + SCRIPT_DIR=$(dirname "$0") + CONTROL_FILE="${PROJECT_FILENAME}.control" + PROJECT_VERSION=$("$SCRIPT_DIR/get_version.sh" "$CONTROL_FILE") +fi + +if [ -z "$PROJECT_VERSION" ]; then + echo "Error: could not detect version" >&2 + exit 1 +fi + +SQL_FILE="${PROJECT_FILENAME}--${PROJECT_VERSION}.sql" +CONTROL_FILE="${PROJECT_FILENAME}.control" + +if [ ! -f "$SQL_FILE" ]; then + echo "Error: versioned SQL file not found: $SQL_FILE" >&2 + exit 1 +fi + +if [ ! -f "$CONTROL_FILE" ]; then + echo "Error: control file not found: $CONTROL_FILE" >&2 + exit 1 +fi + +if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER}$"; then + echo "Error: Docker container not running: $CONTAINER" >&2 + exit 1 +fi + +docker exec "$CONTAINER" mkdir -p /tmp/pg_morbac +docker cp "$CONTROL_FILE" "$CONTAINER:/tmp/pg_morbac/" +docker cp "$SQL_FILE" "$CONTAINER:/tmp/pg_morbac/" + +docker exec "$CONTAINER" sh -c " + EXTDIR=\$(pg_config --sharedir)/extension + cp /tmp/pg_morbac/${CONTROL_FILE} \$EXTDIR/ + cp /tmp/pg_morbac/${SQL_FILE} \$EXTDIR/ + rm -rf /tmp/pg_morbac +" + +echo "Installed ${PROJECT_FILENAME} v${PROJECT_VERSION} to container ${CONTAINER}" diff --git a/tools/start_docker.sh b/tools/start_docker.sh new file mode 100755 index 0000000..7812b96 --- /dev/null +++ b/tools/start_docker.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +# start_docker.sh - Start a PostgreSQL Docker container +# Usage: ./start_docker.sh [container_name] [port] + +set -e # Exit immediately if a command exits with a non-zero status + +CONTAINER="${1:-postgres}" +PORT="${2:-5432}" +POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-postgres}" +POSTGRES_USER="${POSTGRES_USER:-postgres}" + +if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER}$"; then + if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER}$"; then + echo "Container $CONTAINER is already running" + exit 0 + else + echo "Starting existing container $CONTAINER" + docker start "$CONTAINER" + sleep 2 + fi +else + echo "Creating and starting container $CONTAINER" + docker run -d \ + --name "$CONTAINER" \ + -e POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ + -e POSTGRES_USER="$POSTGRES_USER" \ + -p "${PORT}:5432" \ + postgres:latest + sleep 3 +fi + +echo "Waiting for PostgreSQL to be ready..." +for i in {1..30}; do + if docker exec "$CONTAINER" psql -U "$POSTGRES_USER" -c '\q' 2>/dev/null; then + echo "PostgreSQL is ready in container $CONTAINER" + exit 0 + fi + sleep 1 +done + +echo "Error: PostgreSQL did not become ready in time" >&2 +exit 1 diff --git a/tools/stop_docker.sh b/tools/stop_docker.sh new file mode 100644 index 0000000..ca43484 --- /dev/null +++ b/tools/stop_docker.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# stop_docker.sh - Stop a PostgreSQL Docker container +# Usage: ./stop_docker.sh [container_name] + +set -e # Exit immediately if a command exits with a non-zero status + +CONTAINER="${1:-postgres}" + +if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER}$"; then + echo "Container $CONTAINER is not running" + exit 0 +fi + +echo "Stopping container $CONTAINER" +docker stop "$CONTAINER" diff --git a/tools/test_docker.sh b/tools/test_docker.sh new file mode 100755 index 0000000..68e021d --- /dev/null +++ b/tools/test_docker.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# test_docker.sh - Run tests in a Docker container +# Usage: ./test_docker.sh [container_name] [database_name] [sql_file] + +set -e # Exit immediately if a command exits with a non-zero status + +CONTAINER="${1:-postgres}" +DB="${2:-morbac_test}" +SQL_FILE="${3:-pg_morbac.sql}" + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" + +if [ ! -f "$PROJECT_DIR/$SQL_FILE" ]; then + echo "Error: SQL file not found: $SQL_FILE" >&2 + exit 1 +fi + +if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER}$"; then + echo "Error: Docker container not running: $CONTAINER" >&2 + exit 1 +fi + +if ! docker exec "$CONTAINER" psql -U postgres -c '\q' 2>/dev/null; then + echo "Error: PostgreSQL not accessible in container: $CONTAINER" >&2 + exit 1 +fi + +docker exec "$CONTAINER" psql -U postgres -c "DROP DATABASE IF EXISTS $DB" -q +docker exec "$CONTAINER" psql -U postgres -c "CREATE DATABASE $DB" -q + +docker exec "$CONTAINER" mkdir -p /tmp/pg_morbac_test/tools +docker cp "$PROJECT_DIR/$SQL_FILE" "$CONTAINER:/tmp/pg_morbac_test/" +docker cp "$PROJECT_DIR/tests" "$CONTAINER:/tmp/pg_morbac_test/" +docker cp "$SCRIPT_DIR/test.sh" "$CONTAINER:/tmp/pg_morbac_test/tools/" + +docker exec -w /tmp/pg_morbac_test "$CONTAINER" bash tools/test.sh "$DB" "$SQL_FILE" + +docker exec "$CONTAINER" psql -U postgres -c "DROP DATABASE $DB" -q +docker exec "$CONTAINER" rm -rf /tmp/pg_morbac_test diff --git a/tools/uninstall_docker.sh b/tools/uninstall_docker.sh new file mode 100644 index 0000000..f7462da --- /dev/null +++ b/tools/uninstall_docker.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# uninstall_docker.sh - Uninstall the PostgreSQL extension from a Docker container +# Usage: ./uninstall_docker.sh [container_name] [project_name] + +set -e # Exit immediately if a command exits with a non-zero status + +CONTAINER="${1:-postgres}" +PROJECT_FILENAME="${2:-pg_morbac}" + +if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER}$"; then + echo "Error: Docker container not running: $CONTAINER" >&2 + exit 1 +fi + +docker exec "$CONTAINER" sh -c " + EXTDIR=\$(pg_config --sharedir)/extension + rm -f \$EXTDIR/${PROJECT_FILENAME}.control + rm -f \$EXTDIR/${PROJECT_FILENAME}--*.sql +" + +echo "Uninstalled ${PROJECT_FILENAME} from container ${CONTAINER}"