#!/bin/bash set -Eeuo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PLUGIN_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" COMMON_FILE="$SCRIPT_DIR/mysql_common.sh" NATIVE_MY_CNF="${NATIVE_MY_CNF:-/etc/my.cnf}" NATIVE_MY_CNF_D="${NATIVE_MY_CNF_D:-/etc/my.cnf.d}" NATIVE_MYSQL_CONF="${NATIVE_MYSQL_CONF:-/usr/local/directadmin/conf/mysql.conf}" CUSTOMBUILD_OPTIONS_CONF="${CUSTOMBUILD_OPTIONS_CONF:-/usr/local/directadmin/custombuild/options.conf}" NEW_NATIVE_PORT="${NEW_NATIVE_PORT:-3307}" DA_CLI_BIN="${DA_CLI_BIN:-da}" OS_RELEASE_FILE="${OS_RELEASE_FILE:-/etc/os-release}" LOG_FILE="${NATIVE_TAKEOVER_LOG:-$PLUGIN_DIR/data/logs/native-port-takeover.log}" mkdir -p "$(dirname "$LOG_FILE")" 2>/dev/null || true log() { printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >> "$LOG_FILE" printf '[INFO] %s\n' "$*" } die() { log "ERROR: $*" printf '[BŁĄD] %s\n' "$*" >&2 exit 1 } # --- state populated by the detection functions, consumed by later steps --- NATIVE_CURRENT_PORT="" NATIVE_CURRENT_SOCKET="" NATIVE_CURRENT_HOST="" NATIVE_CURRENT_USER="" NATIVE_CURRENT_PASS="" NATIVE_CURRENT_MYSQL_INST="" require_root() { [ "$(id -u)" -eq 0 ] || die "Ten skrypt musi zostać uruchomiony jako root." } check_os_guard() { [ -r "$OS_RELEASE_FILE" ] || die "Nie można odczytać $OS_RELEASE_FILE." local os_id="" os_version="" os_id="$(awk -F= '$1=="ID"{gsub(/"/,"",$2); print $2}' "$OS_RELEASE_FILE")" os_version="$(awk -F= '$1=="VERSION_ID"{gsub(/"/,"",$2); print $2}' "$OS_RELEASE_FILE")" [ "$os_id" = "almalinux" ] || die "Ten skrypt obsługuje wyłącznie AlmaLinux 8/9 (wykryto: ${os_id:-nieznany})." case "$os_version" in 8*|9*) ;; *) die "Ten skrypt obsługuje wyłącznie AlmaLinux 8/9 (wykryto wersję: ${os_version:-nieznana})." ;; esac log "Wykryto obsługiwany system: AlmaLinux $os_version." } read_native_mysql_conf() { [ -r "$NATIVE_MYSQL_CONF" ] || die "Nie znaleziono pliku $NATIVE_MYSQL_CONF." NATIVE_CURRENT_USER="$(mysql_read_key_value "$NATIVE_MYSQL_CONF" user || true)" NATIVE_CURRENT_PASS="$(mysql_read_key_value "$NATIVE_MYSQL_CONF" passwd || true)" NATIVE_CURRENT_PORT="$(mysql_read_key_value "$NATIVE_MYSQL_CONF" port || true)" NATIVE_CURRENT_SOCKET="$(mysql_read_key_value "$NATIVE_MYSQL_CONF" socket || true)" NATIVE_CURRENT_HOST="$(mysql_read_key_value "$NATIVE_MYSQL_CONF" host || true)" [ -n "$NATIVE_CURRENT_USER" ] || die "Nie udało się odczytać pola user z $NATIVE_MYSQL_CONF." [ -n "$NATIVE_CURRENT_PORT" ] || die "Nie udało się odczytać pola port z $NATIVE_MYSQL_CONF." } read_current_mysql_inst() { [ -r "$CUSTOMBUILD_OPTIONS_CONF" ] || die "Nie znaleziono pliku $CUSTOMBUILD_OPTIONS_CONF." NATIVE_CURRENT_MYSQL_INST="$(mysql_read_key_value "$CUSTOMBUILD_OPTIONS_CONF" mysql_inst || true)" [ -n "$NATIVE_CURRENT_MYSQL_INST" ] || die "Nie udało się odczytać mysql_inst z $CUSTOMBUILD_OPTIONS_CONF." log "Bieżąca wartość mysql_inst: $NATIVE_CURRENT_MYSQL_INST." } already_migrated() { [ "$NATIVE_CURRENT_PORT" != "3306" ] } check_native_reachable() { local bin bin="$(mysql_detect_binary mysql)" || die "Nie znaleziono klienta mysql/mariadb do sprawdzenia natywnej instancji." MYSQL_PWD="$NATIVE_CURRENT_PASS" "$bin" \ --user="$NATIVE_CURRENT_USER" \ --protocol=TCP --host=127.0.0.1 --port="$NATIVE_CURRENT_PORT" \ -e "SELECT 1" >/dev/null 2>>"$LOG_FILE" \ || die "Natywna instancja MariaDB nie odpowiada na porcie $NATIVE_CURRENT_PORT z bieżącymi poświadczeniami." log "Natywna instancja MariaDB odpowiada na porcie $NATIVE_CURRENT_PORT." } port_is_listening() { local port="$1" if command -v ss >/dev/null 2>&1; then ss -ltn "( sport = :$port )" 2>/dev/null | awk 'NR > 1 { found=1 } END { exit !found }' return $? fi if command -v lsof >/dev/null 2>&1; then lsof -nP -iTCP:"$port" -sTCP:LISTEN >/dev/null 2>&1 return $? fi log "Nie znaleziono ss ani lsof - zakładam, że port $port jest wolny." return 1 } preflight_new_port_free() { if port_is_listening "$NEW_NATIVE_PORT"; then die "Port $NEW_NATIVE_PORT jest już zajęty. Zmień NEW_NATIVE_PORT i spróbuj ponownie." fi log "Port docelowy $NEW_NATIVE_PORT jest wolny." } [ -r "$COMMON_FILE" ] || die "missing helper: $COMMON_FILE" # shellcheck source=./mysql_common.sh source "$COMMON_FILE" if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then : # main() is added in Task 4. fi