Created
September 5, 2024 16:23
-
-
Save mokshchadha/6c5590e339959a91dc6985b96dee25cb to your computer and use it in GitHub Desktop.
pg_freebsd.sh - install custom pg16 on freebsd
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# Configuration variables | |
POSTGRES_VERSION="16.3" | |
POSTGRES_PREFIX="/usr/local/pgsql" | |
DATA_DIR="$POSTGRES_PREFIX/data" | |
LOGFILE="$POSTGRES_PREFIX/logfile" | |
BUILD_DIR="/tmp/postgresql-build" | |
PYTHON3_PATH=$(which python3) | |
# Helper functions | |
error_exit() { | |
echo "Error: $1" >&2 | |
cleanup | |
exit 1 | |
} | |
warning_message() { | |
echo "Warning: $1" >&2 | |
} | |
cleanup() { | |
echo "Cleaning up..." | |
[ -d "$BUILD_DIR" ] && rm -rf "$BUILD_DIR" || warning_message "Failed to remove build directory." | |
} | |
check_prerequisites() { | |
# Check for GCC 13 | |
if ! command -v gcc13 >/dev/null 2>&1; then | |
echo "GCC 13 is not installed. Installing GCC 13..." | |
pkg install -y gcc13 || error_exit "Failed to install GCC 13. Please install it manually using 'pkg install gcc13'." | |
else | |
echo "GCC 13 is installed. Checking version and configuration..." | |
gcc13 --version | |
gcc13 -v 2>&1 | grep "Configured with" | |
# Check for specs file issue | |
GCC_LIBDIR="/usr/local/lib/gcc13" | |
SPECS_FILE="$GCC_LIBDIR/specs" | |
if [ ! -f "$SPECS_FILE" ]; then | |
echo "specs file not found. Attempting to create..." | |
if ! gcc13 -dumpspecs > "$SPECS_FILE" 2>/dev/null; then | |
error_exit "Failed to create specs file. Please check GCC 13 installation." | |
fi | |
fi | |
# Verify GCC functionality | |
if ! gcc13 -v >/dev/null 2>&1; then | |
error_exit "GCC 13 is not functioning correctly. Please check your GCC installation." | |
fi | |
fi | |
# Check for GNU Make | |
if ! command -v gmake >/dev/null 2>&1; then | |
echo "GNU Make is not installed. Installing GNU Make..." | |
pkg install -y gmake || error_exit "Failed to install GNU Make. Please install it manually using 'pkg install gmake'." | |
fi | |
command -v fetch >/dev/null 2>&1 || error_exit "fetch is required but not installed. Please install it using 'pkg install fetch'." | |
command -v python3 >/dev/null 2>&1 || error_exit "Python3 is required but not installed. Please install it using 'pkg install python3'." | |
command -v openssl >/dev/null 2>&1 || error_exit "OpenSSL is required but not installed. Please install it using 'pkg install openssl'." | |
# Check for pkg-config | |
if ! command -v pkg-config >/dev/null 2>&1; then | |
echo "pkg-config is not installed. Installing pkg-config..." | |
pkg install -y pkgconf || error_exit "Failed to install pkg-config. Please install it manually using 'pkg install pkgconf'." | |
fi | |
# Check for LZ4 | |
if ! pkg info -e liblz4 >/dev/null 2>&1; then | |
echo "LZ4 is not installed. Installing LZ4..." | |
pkg install -y liblz4 || error_exit "Failed to install LZ4. Please install it manually using 'pkg install liblz4'." | |
fi | |
# Verify LZ4 installation | |
if ! pkg-config --exists liblz4; then | |
error_exit "LZ4 library not found by pkg-config. Please check your LZ4 installation." | |
fi | |
# Check for ICU | |
if ! pkg info -e icu >/dev/null 2>&1; then | |
echo "ICU is not installed. Installing ICU..." | |
pkg install -y icu || error_exit "Failed to install ICU. Please install it manually using 'pkg install icu'." | |
fi | |
# Verify ICU installation | |
if [ -f /usr/local/lib/libicuuc.so ]; then | |
echo "ICU library found at /usr/local/lib/libicuuc.so" | |
else | |
error_exit "ICU library not found at expected location. Please check your ICU installation." | |
fi | |
# Print ICU version | |
echo "ICU version:" | |
pkg info icu | grep Version | |
# Print LZ4 version | |
echo "LZ4 version:" | |
pkg info liblz4 | grep Version | |
} | |
ensure_install_directory() { | |
if [ ! -d "$POSTGRES_PREFIX" ]; then | |
mkdir -p "$POSTGRES_PREFIX" || error_exit "Failed to create installation directory." | |
elif [ ! -w "$POSTGRES_PREFIX" ]; then | |
chmod u+w "$POSTGRES_PREFIX" || error_exit "Failed to set permissions on installation directory." | |
fi | |
} | |
create_postgres_user() { | |
if ! pw groupshow postgres >/dev/null 2>&1; then | |
echo "Creating 'postgres' group..." | |
pw groupadd postgres || error_exit "Failed to create 'postgres' group." | |
fi | |
if ! pw usershow postgres >/dev/null 2>&1; then | |
echo "Creating 'postgres' user..." | |
pw useradd postgres -g postgres -m -s /usr/local/bin/bash || error_exit "Failed to create 'postgres' user." | |
else | |
echo "'postgres' user already exists." | |
fi | |
} | |
download_postgresql() { | |
echo "Downloading PostgreSQL $POSTGRES_VERSION..." | |
mkdir -p "$BUILD_DIR" || error_exit "Failed to create build directory." | |
cd "$BUILD_DIR" || error_exit "Failed to enter build directory." | |
if [ ! -f "postgresql-$POSTGRES_VERSION.tar.bz2" ]; then | |
fetch "https://ftp.postgresql.org/pub/source/v$POSTGRES_VERSION/postgresql-$POSTGRES_VERSION.tar.bz2" || error_exit "Failed to download PostgreSQL source." | |
else | |
echo "Source tarball already exists, skipping download." | |
fi | |
if [ ! -d "postgresql-$POSTGRES_VERSION" ]; then | |
tar -xvf "postgresql-$POSTGRES_VERSION.tar.bz2" || error_exit "Failed to extract PostgreSQL source." | |
else | |
echo "Source directory already exists, skipping extraction." | |
fi | |
cd "postgresql-$POSTGRES_VERSION" || error_exit "Failed to enter PostgreSQL source directory." | |
} | |
configure_postgresql() { | |
echo "Configuring PostgreSQL with custom options..." | |
PYTHON_INCLUDE_DIR=$($PYTHON3_PATH -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())") | |
PYTHON_LIB_DIR=$($PYTHON3_PATH -c "from distutils.sysconfig import get_config_var; print(get_config_var('LIBDIR'))") | |
# Add ICU library and include paths | |
ICU_LIBS="-L/usr/local/lib -licui18n -licuuc -licudata" | |
ICU_CFLAGS="-I/usr/local/include" | |
# Add LZ4 library and include paths | |
LZ4_LIBS=$(pkg-config --libs liblz4) | |
LZ4_CFLAGS=$(pkg-config --cflags liblz4) | |
export CC=gcc13 | |
export LDFLAGS="-L/usr/local/lib -L$PYTHON_LIB_DIR $ICU_LIBS $LZ4_LIBS" | |
export CPPFLAGS="-I/usr/local/include -I$PYTHON_INCLUDE_DIR $ICU_CFLAGS $LZ4_CFLAGS" | |
export ICU_LIBS | |
export ICU_CFLAGS | |
export LZ4_LIBS | |
export LZ4_CFLAGS | |
export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH" | |
export LIBRARY_PATH="/usr/local/lib:$LIBRARY_PATH" | |
export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH" | |
config_command="./configure \ | |
CC=gcc13 \ | |
--prefix=\"$POSTGRES_PREFIX\" \ | |
--with-blocksize=32 \ | |
--with-segsize=8 \ | |
--with-openssl \ | |
--with-ssl=openssl \ | |
--with-lz4 \ | |
--with-python \ | |
--with-icu \ | |
--with-includes=\"/usr/local/include $PYTHON_INCLUDE_DIR\" \ | |
--with-libraries=\"/usr/local/lib $PYTHON_LIB_DIR\"" | |
echo "Configuration command: $config_command" | |
echo "LDFLAGS: $LDFLAGS" | |
echo "CPPFLAGS: $CPPFLAGS" | |
echo "ICU_LIBS: $ICU_LIBS" | |
echo "ICU_CFLAGS: $ICU_CFLAGS" | |
echo "LZ4_LIBS: $LZ4_LIBS" | |
echo "LZ4_CFLAGS: $LZ4_CFLAGS" | |
echo "LD_LIBRARY_PATH: $LD_LIBRARY_PATH" | |
echo "LIBRARY_PATH: $LIBRARY_PATH" | |
echo "PKG_CONFIG_PATH: $PKG_CONFIG_PATH" | |
# Run configure and capture output | |
if ! eval $config_command > configure_output.log 2>&1; then | |
echo "Configuration failed. Last 50 lines of output:" | |
tail -n 50 configure_output.log | |
error_exit "Configuration failed. See configure_output.log for details." | |
fi | |
} | |
verify_compilation_options() { | |
echo "Verifying compilation options..." | |
grep -E "BLCKSZ|RELSEG_SIZE" src/include/pg_config.h | |
} | |
compile_postgresql() { | |
echo "Compiling PostgreSQL..." | |
gmake || error_exit "Compilation failed." | |
echo "Compiling contrib modules (including pg_trgm)..." | |
cd contrib || error_exit "Failed to enter contrib directory." | |
gmake || error_exit "Compilation of contrib modules failed." | |
cd .. || error_exit "Failed to return to main PostgreSQL directory." | |
verify_compilation_options | |
} | |
install_postgresql() { | |
echo "Installing PostgreSQL..." | |
gmake install || error_exit "Installation failed." | |
echo "Installing contrib modules (including pg_trgm)..." | |
cd contrib || error_exit "Failed to enter contrib directory." | |
gmake install || error_exit "Installation of contrib modules failed." | |
cd .. || error_exit "Failed to return to main PostgreSQL directory." | |
} | |
setup_environment() { | |
echo "Setting up environment variables..." | |
if ! grep -q "$POSTGRES_PREFIX/bin" /etc/profile; then | |
echo "export PATH=\"$POSTGRES_PREFIX/bin:\$PATH\"" >> /etc/profile || warning_message "Failed to update /etc/profile." | |
. /etc/profile || warning_message "Failed to source /etc/profile." | |
else | |
echo "PATH already includes $POSTGRES_PREFIX/bin." | |
fi | |
} | |
initialize_database() { | |
echo "Initializing the PostgreSQL database..." | |
mkdir -p "$DATA_DIR" || error_exit "Failed to create data directory." | |
chown postgres:postgres "$DATA_DIR" | |
su -m postgres -c "$POSTGRES_PREFIX/bin/initdb -D $DATA_DIR" || error_exit "Database initialization failed." | |
} | |
create_extension_pg_trgm() { | |
echo "Creating pg_trgm extension..." | |
su -m postgres -c "$POSTGRES_PREFIX/bin/psql -d postgres -c 'CREATE EXTENSION IF NOT EXISTS pg_trgm;'" || warning_message "Failed to create pg_trgm extension. You may need to create it manually in your databases." | |
} | |
start_postgresql() { | |
echo "Starting PostgreSQL..." | |
su -m postgres -c "$POSTGRES_PREFIX/bin/pg_ctl -D $DATA_DIR -l $LOGFILE -w start" | |
sleep 5 # Give the server a moment to start up | |
if ! su -m postgres -c "$POSTGRES_PREFIX/bin/pg_isready -q"; then | |
check_log_file | |
error_exit "Failed to start PostgreSQL." | |
fi | |
echo "PostgreSQL started successfully." | |
} | |
check_log_file() { | |
echo "Checking PostgreSQL log file for errors..." | |
if [ -f "$LOGFILE" ]; then | |
tail -n 50 "$LOGFILE" | |
else | |
echo "Log file not found at $LOGFILE" | |
fi | |
} | |
verify_custom_options() { | |
echo "Verifying custom build options..." | |
su -m postgres -c "$POSTGRES_PREFIX/bin/psql -d postgres -c \"SHOW block_size;\"" || warning_message "Failed to verify block size." | |
su -m postgres -c "$POSTGRES_PREFIX/bin/psql -d postgres -c \"SHOW segment_size;\"" || warning_message "Failed to verify segment size." | |
echo "Checking PostgreSQL version and compile-time options:" | |
su -m postgres -c "$POSTGRES_PREFIX/bin/postgres -V" | |
su -m postgres -c "$POSTGRES_PREFIX/bin/pg_config --configure" | |
echo "Verifying pg_trgm extension installation:" | |
su -m postgres -c "$POSTGRES_PREFIX/bin/psql -d postgres -c \"SELECT * FROM pg_extension WHERE extname = 'pg_trgm';\"" || warning_message "Failed to verify pg_trgm extension." | |
} | |
stop_postgresql() { | |
echo "Stopping PostgreSQL..." | |
if command -v "$POSTGRES_PREFIX/bin/pg_ctl" > /dev/null 2>&1; then | |
su -m postgres -c "$POSTGRES_PREFIX/bin/pg_ctl -D $DATA_DIR stop -m fast" || warning_message "Failed to stop PostgreSQL." | |
else | |
echo "pg_ctl command not found; assuming PostgreSQL is not running." | |
fi | |
} | |
uninstall_postgresql() { | |
echo "Uninstalling PostgreSQL..." | |
stop_postgresql | |
if [ -d "$POSTGRES_PREFIX" ]; then | |
rm -rf "$POSTGRES_PREFIX" || warning_message "Failed to remove PostgreSQL directories." | |
echo "PostgreSQL uninstalled successfully." | |
else | |
echo "No PostgreSQL installation detected." | |
fi | |
} | |
perform_installation() { | |
check_prerequisites | |
create_postgres_user | |
ensure_install_directory | |
download_postgresql | |
configure_postgresql | |
compile_postgresql | |
install_postgresql | |
setup_environment | |
initialize_database | |
start_postgresql | |
create_extension_pg_trgm | |
check_log_file | |
verify_custom_options | |
echo "PostgreSQL installed and configured successfully with pg_trgm extension!" | |
} | |
# Ensure cleanup happens on script exit | |
trap cleanup EXIT | |
# Main function | |
case "$1" in | |
stop) | |
stop_postgresql | |
;; | |
uninstall) | |
uninstall_postgresql | |
;; | |
install) | |
perform_installation | |
;; | |
*) | |
echo "Usage: $0 {install|stop|uninstall}" | |
exit 1 | |
;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment