Import postgresql plugin

This commit is contained in:
Marek Miklewicz
2026-07-04 16:00:04 +02:00
commit ddc971567f
74 changed files with 18735 additions and 0 deletions
+520
View File
@@ -0,0 +1,520 @@
#!/bin/bash
# =============================================================================
# recompile_php.sh
# Weryfikacja i rekompilacja wersji PHP w DirectAdmin CustomBuild
# tak, aby każda aktywna wersja miała rozszerzenia pgsql i pdo_pgsql.
# =============================================================================
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
sekcja() { echo -e "\n${BOLD}${CYAN}=== $* ===${NC}\n"; }
die() { echo -e "${RED}[BŁĄD]${NC} $*" >&2; exit 1; }
CB_PHP_WEBSERVER=""
CB_PHP_OPTIONS_CONF=""
CB_PG_PREFIX=""
CB_PG_VERSION=""
CB_PG_CONFIG=""
DA_PG_RUNTIME_LIBDIR=""
DA_PG_RUNTIME_LIBPQ=""
declare -ag CB_PHP_VERSIONS=()
declare -ag CB_PHP_CODES=()
declare -ag CB_PHP_MODES=()
cb_pgsql_reset_php_targets() {
CB_PHP_VERSIONS=()
CB_PHP_CODES=()
CB_PHP_MODES=()
}
cb_pgsql_get_cb_option() {
local options_conf="$1"
local key="$2"
local value=""
[[ -f "$options_conf" ]] || return 1
value="$(awk -F= -v key="$key" '
$1 == key {
sub(/^[[:space:]]+/, "", $2)
sub(/[[:space:]]+$/, "", $2)
print $2
exit
}
' "$options_conf")"
[[ -n "$value" ]] || return 1
printf '%s\n' "$value"
}
cb_pgsql_php_code_from_version() {
printf '%s\n' "${1//./}"
}
cb_pgsql_php_version_from_code() {
local code="$1"
if [[ "$code" == *.* ]]; then
printf '%s\n' "$code"
elif [[ "$code" =~ ^[0-9]{2,3}$ ]]; then
printf '%s.%s\n' "${code:0:1}" "${code:1}"
else
printf '%s\n' "$code"
fi
}
cb_pgsql_add_php_target() {
local version="$1"
local mode="$2"
local code=""
local idx=""
[[ -n "$version" ]] || return 0
code="$(cb_pgsql_php_code_from_version "$version")"
for idx in "${!CB_PHP_CODES[@]}"; do
if [[ "${CB_PHP_CODES[$idx]}" == "$code" ]]; then
return 0
fi
done
CB_PHP_VERSIONS+=("$version")
CB_PHP_CODES+=("$code")
CB_PHP_MODES+=("${mode:-php-fpm}")
}
cb_pgsql_detect_webserver() {
local cb_dir="$1"
CB_PHP_OPTIONS_CONF="${cb_dir}/options.conf"
CB_PHP_WEBSERVER="apache"
if [[ -f "$CB_PHP_OPTIONS_CONF" ]]; then
CB_PHP_WEBSERVER="$(cb_pgsql_get_cb_option "$CB_PHP_OPTIONS_CONF" "webserver" || true)"
[[ -n "$CB_PHP_WEBSERVER" ]] || CB_PHP_WEBSERVER="apache"
fi
}
cb_pgsql_collect_php_targets() {
local cb_dir="$1"
local slot=""
local release=""
local mode=""
local default_mode=""
cb_pgsql_reset_php_targets
cb_pgsql_detect_webserver "$cb_dir"
# CloudLinux może używać lsphp także przy webserver=apache.
# Dlatego najpierw honorujemy phpN_mode/php1_mode z options.conf,
# a dopiero przy ich braku stosujemy domyślny tryb wynikający z webserwera.
case "$CB_PHP_WEBSERVER" in
litespeed|openlitespeed) default_mode="lsphp" ;;
*) default_mode="php-fpm" ;;
esac
for slot in 1 2 3 4 5 6 7 8 9; do
release="$(cb_pgsql_get_cb_option "$CB_PHP_OPTIONS_CONF" "php${slot}_release" || true)"
mode="$(cb_pgsql_get_cb_option "$CB_PHP_OPTIONS_CONF" "php${slot}_mode" || true)"
[[ -n "$mode" ]] || mode="$(cb_pgsql_get_cb_option "$CB_PHP_OPTIONS_CONF" "php1_mode" || true)"
[[ -n "$mode" ]] || mode="$default_mode"
case "${release,,}" in
""|no|off) continue ;;
esac
case "${mode,,}" in
no|off) continue ;;
esac
cb_pgsql_add_php_target "$release" "$mode"
done
}
cb_pgsql_build_file_candidates() {
local cb_dir="$1"
local mode="$2"
local code="$3"
local -n out_ref="$4"
out_ref=()
if [[ "$mode" == "lsphp" ]]; then
case "$CB_PHP_WEBSERVER" in
litespeed)
out_ref+=("${cb_dir}/configure/litespeed/configure.php${code}")
;;
openlitespeed)
out_ref+=("${cb_dir}/configure/openlitespeed/configure.php${code}")
;;
esac
out_ref+=("${cb_dir}/configure/lsphp/configure.lsphp${code}")
out_ref+=("${cb_dir}/configure/lsphp/configure.php${code}")
fi
out_ref+=("${cb_dir}/configure/php/configure.php${code}")
}
cb_pgsql_resolve_config_paths() {
local cb_dir="$1"
local version="$2"
local mode="$3"
local source_ref_name="$4"
local custom_ref_name="$5"
local code=""
local -a candidates=()
local candidate=""
code="$(cb_pgsql_php_code_from_version "$version")"
printf -v "$source_ref_name" '%s' ""
printf -v "$custom_ref_name" '%s' ""
cb_pgsql_build_file_candidates "$cb_dir" "$mode" "$code" candidates
for candidate in "${candidates[@]}"; do
if [[ -f "$candidate" ]]; then
printf -v "$source_ref_name" '%s' "$candidate"
printf -v "$custom_ref_name" '%s' "$(printf '%s\n' "$candidate" | sed "s#^${cb_dir}/configure/#${cb_dir}/custom/#")"
return 0
fi
done
for candidate in "${candidates[@]}"; do
candidate="$(printf '%s\n' "$candidate" | sed "s#^${cb_dir}/configure/#${cb_dir}/custom/#")"
if [[ -f "$candidate" ]]; then
printf -v "$source_ref_name" '%s' "$candidate"
printf -v "$custom_ref_name" '%s' "$candidate"
return 0
fi
done
return 1
}
cb_pgsql_insert_flags() {
local config_file="$1"
local pg_prefix="$2"
local tmp_file="${config_file}.tmp"
sed -i '/--with-pgsql=/d; /--with-pdo-pgsql=/d' "$config_file"
if grep -q -- '--with-pdo-mysql' "$config_file"; then
awk -v prefix="$pg_prefix" '
/--with-pdo-mysql/ {
print
print "\t--with-pgsql=" prefix " \\"
print "\t--with-pdo-pgsql=" prefix " \\"
next
}
{ print }
' "$config_file" > "$tmp_file"
else
awk -v prefix="$pg_prefix" '
/^[[:space:]]*--with/ { last = NR }
{ lines[NR] = $0 }
END {
if (last == 0) {
for (i = 1; i <= NR; i++) print lines[i]
exit
}
for (i = 1; i <= NR; i++) {
print lines[i]
if (i == last) {
print "\t--with-pgsql=" prefix " \\"
print "\t--with-pdo-pgsql=" prefix " \\"
}
}
}
' "$config_file" > "$tmp_file"
fi
mv "$tmp_file" "$config_file"
}
cb_pgsql_prepare_custom_config() {
local cb_dir="$1"
local version="$2"
local mode="$3"
local pg_prefix="$4"
local source_conf=""
local custom_conf=""
local ts=""
if ! cb_pgsql_resolve_config_paths "$cb_dir" "$version" "$mode" source_conf custom_conf; then
warn "Nie znaleziono configure dla PHP ${version} (tryb ${mode}, webserver ${CB_PHP_WEBSERVER})."
return 1
fi
mkdir -p "$(dirname "$custom_conf")"
ts="$(date +%s)"
if [[ "$source_conf" != "$custom_conf" && ! -f "$custom_conf" ]]; then
cp -p "$source_conf" "$custom_conf"
elif [[ -f "$custom_conf" ]]; then
cp -p "$custom_conf" "${custom_conf}.bak.${ts}"
fi
cb_pgsql_insert_flags "$custom_conf" "$pg_prefix"
chmod +x "$custom_conf" || true
info "Przygotowano configure dla PHP ${version}: ${custom_conf}"
return 0
}
cb_pgsql_configure_runtime_libpq() {
local pg_prefix="$1"
local pg_libdir="${pg_prefix}/lib"
local libpq_so="${pg_libdir}/libpq.so.5"
local ld_conf="/etc/ld.so.conf.d/00-da-postgresql-libpq.conf"
local old_ld_conf="/etc/ld.so.conf.d/da-postgresql-libpq.conf"
local preferred=""
[[ -d "$pg_libdir" ]] || die "Nie znaleziono katalogu bibliotek PostgreSQL: ${pg_libdir}"
[[ -r "$libpq_so" ]] || die "Nie znaleziono biblioteki libpq: ${libpq_so}"
printf '%s\n' "$pg_libdir" > "$ld_conf"
chmod 644 "$ld_conf"
[[ "$old_ld_conf" == "$ld_conf" ]] || rm -f "$old_ld_conf"
if command -v ldconfig >/dev/null 2>&1; then
ldconfig || die "Nie udało się odświeżyć cache bibliotek przez ldconfig."
preferred="$(ldconfig -p 2>/dev/null | awk '/libpq\.so\.5/{print $NF; exit}')"
if [[ -n "$preferred" && "$preferred" != "$libpq_so" ]]; then
warn "Domyślna libpq to ${preferred}; wymuszę właściwą bibliotekę przez LD_PRELOAD podczas kompilacji PHP."
fi
else
warn "Brak ldconfig. Kontynuuję z LD_LIBRARY_PATH."
fi
DA_PG_RUNTIME_LIBDIR="$pg_libdir"
DA_PG_RUNTIME_LIBPQ="$libpq_so"
info "Skonfigurowano bibliotekę runtime PostgreSQL: ${pg_libdir}"
}
cb_pgsql_detect_pg_prefix() {
local candidate=""
CB_PG_PREFIX=""
CB_PG_VERSION=""
CB_PG_CONFIG=""
if [[ -x /usr/local/bin/pg_config ]]; then
candidate="$(readlink -f /usr/local/bin/pg_config 2>/dev/null || true)"
if [[ -x "$candidate" ]]; then
CB_PG_CONFIG="$candidate"
fi
fi
if [[ -z "$CB_PG_CONFIG" ]]; then
candidate="$(ls -1 /usr/pgsql-*/bin/pg_config 2>/dev/null | sort -V | tail -n1 || true)"
if [[ -n "$candidate" && -x "$candidate" ]]; then
CB_PG_CONFIG="$candidate"
fi
fi
[[ -n "$CB_PG_CONFIG" ]] || return 1
CB_PG_PREFIX="$(cd "$(dirname "$CB_PG_CONFIG")/.." && pwd)"
if [[ "$CB_PG_PREFIX" =~ /usr/pgsql-([0-9]+)$ ]]; then
CB_PG_VERSION="${BASH_REMATCH[1]}"
fi
[[ -n "$CB_PG_PREFIX" ]] || return 1
return 0
}
cb_pgsql_find_php_bin_for_version() {
local version="$1"
local code=""
local candidate=""
code="$(cb_pgsql_php_code_from_version "$version")"
for candidate in \
"/usr/local/php${code}/bin/php" \
"/usr/local/php${code}/bin/lsphp" \
"/usr/local/lsphp${code}/bin/lsphp" \
"/usr/local/php${code}/bin/php-cgi"; do
if [[ -x "$candidate" ]]; then
printf '%s\n' "$candidate"
return 0
fi
done
return 1
}
cb_pgsql_probe_php_extensions() {
local php_bin="$1"
local pgsql_ref_name="$2"
local pdo_ref_name="$3"
local modules=""
local modules_lc=""
local probe_pgsql_status="NIE"
local probe_pdo_status="NIE"
modules="$("$php_bin" -m 2>/dev/null || true)"
if [[ -z "$modules" ]]; then
probe_pgsql_status="BŁĄD"
probe_pdo_status="BŁĄD"
printf -v "$pgsql_ref_name" '%s' "$probe_pgsql_status"
printf -v "$pdo_ref_name" '%s' "$probe_pdo_status"
return 1
fi
modules_lc="$(printf '%s\n' "$modules" | tr '[:upper:]' '[:lower:]')"
if printf '%s\n' "$modules_lc" | grep -qx 'pgsql'; then
probe_pgsql_status="OK"
fi
if printf '%s\n' "$modules_lc" | grep -qx 'pdo_pgsql'; then
probe_pdo_status="OK"
fi
printf -v "$pgsql_ref_name" '%s' "$probe_pgsql_status"
printf -v "$pdo_ref_name" '%s' "$probe_pdo_status"
return 0
}
cb_pgsql_render_extensions_table() {
local found=0
local idx=""
local version=""
local php_bin=""
local pgsql_status=""
local pdo_pgsql_status=""
echo "+------------+-------+-----------+"
printf "| %-10s | %-5s | %-9s |\n" "Wersja PHP" "PGSQL" "PDO_PGSQL"
echo "+------------+-------+-----------+"
for idx in "${!CB_PHP_VERSIONS[@]}"; do
version="${CB_PHP_VERSIONS[$idx]}"
php_bin="$(cb_pgsql_find_php_bin_for_version "$version" || true)"
if [[ -z "$php_bin" ]]; then
printf "| %-10s | %-5s | %-9s |\n" "PHP ${version}" "BRAK" "BRAK"
found=1
continue
fi
cb_pgsql_probe_php_extensions "$php_bin" pgsql_status pdo_pgsql_status >/dev/null 2>&1 || true
printf "| %-10s | %-5s | %-9s |\n" "PHP ${version}" "$pgsql_status" "$pdo_pgsql_status"
found=1
done
if [[ $found -eq 1 ]]; then
echo "+------------+-------+-----------+"
else
warn "Nie znaleziono wersji PHP do raportu."
fi
}
[[ $EUID -eq 0 ]] || die "Skrypt musi być uruchomiony jako root."
LOGFILE="/var/log/recompile_php_$(date +%Y%m%d_%H%M%S).log"
exec 1> >(tee >(sed 's/\x1b\[[0-9;]*[a-zA-Z]//g' >> "$LOGFILE")) 2>&1
info "Pełny log zapisany w: $LOGFILE"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
CB_DIR="/usr/local/directadmin/custombuild"
[[ -x "${CB_DIR}/build" ]] || die "Nie znaleziono DirectAdmin CustomBuild: ${CB_DIR}/build"
sekcja "Wykrywanie środowiska DirectAdmin"
cb_pgsql_collect_php_targets "$CB_DIR"
[[ ${#CB_PHP_VERSIONS[@]} -gt 0 ]] || die "Nie wykryto aktywnych wersji PHP w DirectAdmin CustomBuild."
info "Web serwer: ${CB_PHP_WEBSERVER}"
info "Wykryte wersje PHP: $(IFS=', '; echo "${CB_PHP_VERSIONS[*]}")"
sekcja "Wykrywanie PostgreSQL dla kompilacji PHP"
cb_pgsql_detect_pg_prefix || die "Nie znaleziono pg_config. Zainstaluj PostgreSQL lub ustaw /usr/local/bin/pg_config."
[[ -n "$CB_PG_VERSION" ]] || die "Nie udało się ustalić wersji PostgreSQL z ${CB_PG_CONFIG}."
info "Wykryty prefix PostgreSQL: ${CB_PG_PREFIX}"
info "Wykryta wersja PostgreSQL: ${CB_PG_VERSION}"
dnf install -y "postgresql${CB_PG_VERSION}-devel" \
"postgresql${CB_PG_VERSION}-libs" \
|| die "Nie udało się zainstalować postgresql${CB_PG_VERSION}-devel/libs."
if [[ -x "$CB_PG_CONFIG" ]]; then
if [[ -e /usr/local/bin/pg_config && ! -L /usr/local/bin/pg_config ]]; then
warn "/usr/local/bin/pg_config istnieje i nie jest dowiązaniem pomijam aktualizację symlinku."
else
ln -sf "$CB_PG_CONFIG" /usr/local/bin/pg_config
info "Zaktualizowano symlink: /usr/local/bin/pg_config -> ${CB_PG_CONFIG}"
fi
fi
cb_pgsql_configure_runtime_libpq "$CB_PG_PREFIX"
sekcja "Analiza rozszerzeń PHP"
declare -a REBUILD_VERSIONS=()
declare -a REBUILD_MODES=()
for idx in "${!CB_PHP_VERSIONS[@]}"; do
php_version="${CB_PHP_VERSIONS[$idx]}"
php_mode="${CB_PHP_MODES[$idx]}"
php_bin="$(cb_pgsql_find_php_bin_for_version "$php_version" || true)"
pgsql_status="BRAK"
pdo_pgsql_status="BRAK"
if [[ -z "$php_bin" ]]; then
warn "Nie znaleziono binarki PHP dla wersji ${php_version}. Dodaję do rekompilacji."
REBUILD_VERSIONS+=("$php_version")
REBUILD_MODES+=("$php_mode")
continue
fi
cb_pgsql_probe_php_extensions "$php_bin" pgsql_status pdo_pgsql_status >/dev/null 2>&1 || true
if [[ "$pgsql_status" != "OK" || "$pdo_pgsql_status" != "OK" ]]; then
info "PHP ${php_version}: brakujące rozszerzenia (PGSQL=${pgsql_status}, PDO_PGSQL=${pdo_pgsql_status})"
REBUILD_VERSIONS+=("$php_version")
REBUILD_MODES+=("$php_mode")
else
info "PHP ${php_version}: rozszerzenia pgsql i pdo_pgsql są już dostępne."
fi
done
if [[ ${#REBUILD_VERSIONS[@]} -eq 0 ]]; then
sekcja "Tabela rozszerzeń PHP"
cb_pgsql_render_extensions_table
info "Pełny log: ${LOGFILE}"
exit 0
fi
sekcja "Przygotowanie configure.phpXX"
prepared_any=0
for idx in "${!REBUILD_VERSIONS[@]}"; do
if cb_pgsql_prepare_custom_config "$CB_DIR" "${REBUILD_VERSIONS[$idx]}" "${REBUILD_MODES[$idx]}" "$CB_PG_PREFIX"; then
prepared_any=1
fi
done
[[ "$prepared_any" -eq 1 ]] || die "Nie udało się przygotować żadnego pliku configure dla rekompilacji PHP."
sekcja "Rekompilacja PHP"
cd "$CB_DIR"
for php_version in "${REBUILD_VERSIONS[@]}"; do
info "Uruchamiam: ./build php ${php_version}"
LD_LIBRARY_PATH="${DA_PG_RUNTIME_LIBDIR}${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" \
LD_PRELOAD="${DA_PG_RUNTIME_LIBPQ}${LD_PRELOAD:+:${LD_PRELOAD}}" \
LIBRARY_PATH="${DA_PG_RUNTIME_LIBDIR}${LIBRARY_PATH:+:${LIBRARY_PATH}}" \
PKG_CONFIG_PATH="${DA_PG_RUNTIME_LIBDIR}/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}" \
LDFLAGS="-L${DA_PG_RUNTIME_LIBDIR} ${LDFLAGS:-}" \
CPPFLAGS="-I${CB_PG_PREFIX}/include ${CPPFLAGS:-}" \
./build php "$php_version" \
|| die "Rekompilacja PHP ${php_version} nie powiodła się."
done
./build rewrite_confs \
|| warn "rewrite_confs zakończył się błędem sprawdź konfigurację ręcznie."
cd - >/dev/null
sekcja "Tabela rozszerzeń PHP po rekompilacji"
cb_pgsql_collect_php_targets "$CB_DIR"
cb_pgsql_render_extensions_table
info "Pełny log: ${LOGFILE}"
exit 0