#!/bin/bash set -e # Function to log errors log_error() { echo "ERROR: $1" >&2 } log_info() { echo "INFO: $1" } # Trap errors and log them trap 'log_error "Script failed at line $LINENO"' ERR log_info "Starting Redis FDW initialization..." log_info "Redis connection details:" log_info " Host: ${REDIS_HOST:-redis}" log_info " Port: 6379" log_info " Password: $(if [ -n "$REDIS_PASSWORD" ]; then echo "[SET]"; else echo "[NOT SET]"; fi)" # Wait for Redis to be ready log_info "Waiting for Redis to be ready..." REDIS_READY=false MAX_ATTEMPTS=30 ATTEMPT=0 while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do if redis-cli -h ${REDIS_HOST:-redis} -a "${REDIS_PASSWORD}" ping 2>/dev/null | grep -q PONG; then REDIS_READY=true log_info "Redis is ready after $ATTEMPT attempts" break fi ATTEMPT=$((ATTEMPT + 1)) log_info "Redis is unavailable - attempt $ATTEMPT/$MAX_ATTEMPTS" sleep 2 done if [ "$REDIS_READY" = false ]; then log_error "Redis failed to become ready after $MAX_ATTEMPTS attempts" log_error "Check if Redis container is running and accessible at ${REDIS_HOST:-redis}:6379" exit 1 fi # Get Redis info log_info "Fetching Redis server information..." REDIS_VERSION=$(redis-cli -h ${REDIS_HOST:-redis} -a "${REDIS_PASSWORD}" INFO server 2>/dev/null | grep "redis_version" | cut -d: -f2 | tr -d '\r' || echo "unknown") REDIS_MODE=$(redis-cli -h ${REDIS_HOST:-redis} -a "${REDIS_PASSWORD}" INFO server 2>/dev/null | grep "redis_mode" | cut -d: -f2 | tr -d '\r' || echo "unknown") REDIS_UPTIME=$(redis-cli -h ${REDIS_HOST:-redis} -a "${REDIS_PASSWORD}" INFO server 2>/dev/null | grep "uptime_in_seconds" | cut -d: -f2 | tr -d '\r' || echo "unknown") TOTAL_KEYS=$(redis-cli -h ${REDIS_HOST:-redis} -a "${REDIS_PASSWORD}" DBSIZE 2>/dev/null | awk '{print $2}' || echo "0") log_info "Redis server info:" log_info " Version: $REDIS_VERSION" log_info " Mode: $REDIS_MODE" log_info " Uptime: $REDIS_UPTIME seconds" log_info " Total keys in DB 0: $TOTAL_KEYS" # Test Redis connectivity with a test key log_info "Testing Redis write/read operations..." if redis-cli -h ${REDIS_HOST:-redis} -a "${REDIS_PASSWORD}" SET fdw_test_key "fdw_init_$(date +%s)" EX 60 >/dev/null 2>&1; then TEST_VALUE=$(redis-cli -h ${REDIS_HOST:-redis} -a "${REDIS_PASSWORD}" GET fdw_test_key 2>/dev/null) log_info "Redis write/read test successful (value: $TEST_VALUE)" else log_error "Redis write/read test failed" exit 1 fi log_info "Setting up redis_fdw extension..." log_info "PostgreSQL connection:" log_info " User: $POSTGRES_USER" log_info " Database: $POSTGRES_DB" # Run SQL setup as postgres user with error handling if psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL; then -- Create redis_fdw extension DO \$\$ BEGIN CREATE EXTENSION IF NOT EXISTS redis_fdw; RAISE NOTICE 'redis_fdw extension created/verified'; EXCEPTION WHEN OTHERS THEN RAISE EXCEPTION 'Failed to create redis_fdw extension: %', SQLERRM; END; \$\$; -- Create foreign server DO \$\$ BEGIN DROP SERVER IF EXISTS redis_server CASCADE; CREATE SERVER redis_server FOREIGN DATA WRAPPER redis_fdw OPTIONS ( address '${REDIS_HOST:-redis}', port '6379' ); RAISE NOTICE 'Foreign server redis_server created (host: ${REDIS_HOST:-redis}, port: 6379)'; EXCEPTION WHEN OTHERS THEN RAISE EXCEPTION 'Failed to create foreign server: %', SQLERRM; END; \$\$; -- Create user mapping DO \$\$ BEGIN CREATE USER MAPPING FOR CURRENT_USER SERVER redis_server OPTIONS (password '${REDIS_PASSWORD}'); RAISE NOTICE 'User mapping created for CURRENT_USER'; EXCEPTION WHEN OTHERS THEN RAISE EXCEPTION 'Failed to create user mapping: %', SQLERRM; END; \$\$; -- Create foreign table for Redis hashes DO \$\$ BEGIN DROP FOREIGN TABLE IF EXISTS redis_hashes; CREATE FOREIGN TABLE redis_hashes ( key TEXT, value TEXT ) SERVER redis_server OPTIONS ( database '0', tabletype 'hash' ); RAISE NOTICE 'Foreign table redis_hashes created (database: 0, tabletype: hash)'; EXCEPTION WHEN OTHERS THEN RAISE EXCEPTION 'Failed to create redis_hashes: %', SQLERRM; END; \$\$; -- Create foreign table for Redis lists DO \$\$ BEGIN DROP FOREIGN TABLE IF EXISTS redis_lists; CREATE FOREIGN TABLE redis_lists ( key TEXT, value TEXT ) SERVER redis_server OPTIONS ( database '0', tabletype 'list' ); RAISE NOTICE 'Foreign table redis_lists created (database: 0, tabletype: list)'; EXCEPTION WHEN OTHERS THEN RAISE EXCEPTION 'Failed to create redis_lists: %', SQLERRM; END; \$\$; -- Create foreign table for Redis sets DO \$\$ BEGIN DROP FOREIGN TABLE IF EXISTS redis_sets; CREATE FOREIGN TABLE redis_sets ( key TEXT, value TEXT ) SERVER redis_server OPTIONS ( database '0', tabletype 'set' ); RAISE NOTICE 'Foreign table redis_sets created (database: 0, tabletype: set)'; EXCEPTION WHEN OTHERS THEN RAISE EXCEPTION 'Failed to create redis_sets: %', SQLERRM; END; \$\$; -- Create foreign table for Redis sorted sets DO \$\$ BEGIN DROP FOREIGN TABLE IF EXISTS redis_zsets; CREATE FOREIGN TABLE redis_zsets ( key TEXT, value TEXT ) SERVER redis_server OPTIONS ( database '0', tabletype 'zset' ); RAISE NOTICE 'Foreign table redis_zsets created (database: 0, tabletype: zset)'; EXCEPTION WHEN OTHERS THEN RAISE EXCEPTION 'Failed to create redis_zsets: %', SQLERRM; END; \$\$; -- Grant permissions DO \$\$ BEGIN GRANT SELECT ON redis_hashes TO PUBLIC; GRANT SELECT ON redis_lists TO PUBLIC; GRANT SELECT ON redis_sets TO PUBLIC; GRANT SELECT ON redis_zsets TO PUBLIC; RAISE NOTICE 'Permissions granted on all Redis foreign tables'; EXCEPTION WHEN OTHERS THEN RAISE EXCEPTION 'Failed to grant permissions: %', SQLERRM; END; \$\$; -- Final verification SELECT 'Redis FDW setup completed successfully!' as status; EOSQL log_info "Redis FDW SQL setup completed successfully" else log_error "Redis FDW SQL setup failed with exit code $?" exit 1 fi log_info "Redis FDW initialization complete"