migrate2psql.sh 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. #!/bin/bash
  2. # Eye Migration Script for ALT Linux/Debian/Ubuntu with PostgreSQL support
  3. # Version: 1.0
  4. # set -e
  5. # Colors for output
  6. RED='\033[0;31m'
  7. GREEN='\033[0;32m'
  8. YELLOW='\033[1;33m'
  9. BLUE='\033[0;34m'
  10. NC='\033[0m' # No Color
  11. # Output functions
  12. print_info() {
  13. echo -e "${GREEN}[INFO]${NC} $1"
  14. }
  15. print_warn() {
  16. echo -e "${YELLOW}[WARN]${NC} $1"
  17. }
  18. print_error() {
  19. echo -e "${RED}[ERROR]${NC} $1"
  20. }
  21. print_step() {
  22. echo -e "${BLUE}=== $1 ===${NC}"
  23. }
  24. # Check for root privileges
  25. check_root() {
  26. if [[ $EUID -ne 0 ]]; then
  27. print_error "This script must be run as root"
  28. print_error "Use: sudo $0"
  29. exit 1
  30. fi
  31. }
  32. service_exists() {
  33. systemctl cat "$1.service" >/dev/null 2>&1
  34. }
  35. safe_start_service() {
  36. local svc="$1"
  37. if service_exists "$svc"; then
  38. if systemctl start "$svc"; then
  39. print_info "Service ${svc} has been successfully started"
  40. else
  41. print_error "Failed to start ${svc}"
  42. fi
  43. fi
  44. }
  45. safe_stop_service() {
  46. local svc="$1"
  47. if service_exists "$svc"; then
  48. if systemctl stop "$svc"; then
  49. print_info "Service ${svc} has been successfully stopped"
  50. else
  51. print_error "Failed to stop ${svc}"
  52. fi
  53. fi
  54. }
  55. stop_eye() {
  56. print_step "Stopping services"
  57. local PHP_VERSION
  58. PHP_VERSION=$(php -v 2>/dev/null | head -n1 | grep -oP '\d+\.\d+' || echo "")
  59. if [ -n "${PHP_VERSION}" ]; then
  60. safe_stop_service "php${PHP_VERSION}-fpm"
  61. fi
  62. for svc in cron eye-statd dhcp-log stat-sync syslog-stat; do
  63. safe_stop_service "$svc"
  64. done
  65. }
  66. start_eye() {
  67. local PHP_VERSION
  68. PHP_VERSION=$(php -v 2>/dev/null | head -n1 | grep -oP '\d+\.\d+' || echo "")
  69. if [ -n "${PHP_VERSION}" ]; then
  70. safe_start_service "php${PHP_VERSION}-fpm"
  71. fi
  72. for svc in cron eye-statd dhcp-log stat-sync syslog-stat; do
  73. safe_start_service "$svc"
  74. done
  75. }
  76. # Detect distribution and package manager
  77. detect_distro() {
  78. if [[ -f /etc/os-release ]]; then
  79. . /etc/os-release
  80. OS_ID=$ID
  81. OS_VERSION=$VERSION_ID
  82. OS_NAME=$NAME
  83. case $OS_ID in
  84. altlinux)
  85. PACKAGE_MANAGER="apt-get"
  86. SERVICE_MANAGER="systemctl"
  87. OS_FAMILY="alt"
  88. print_info "Detected ALT Linux $OS_VERSION"
  89. ;;
  90. debian)
  91. PACKAGE_MANAGER="apt"
  92. SERVICE_MANAGER="systemctl"
  93. OS_FAMILY="debian"
  94. print_info "Detected Debian $OS_VERSION"
  95. ;;
  96. ubuntu)
  97. PACKAGE_MANAGER="apt"
  98. SERVICE_MANAGER="systemctl"
  99. OS_FAMILY="debian"
  100. print_info "Detected Ubuntu $OS_VERSION"
  101. ;;
  102. *)
  103. print_error "Unsupported distribution: $OS_ID"
  104. print_error "Supported: ALT Linux, Debian, Ubuntu"
  105. exit 1
  106. ;;
  107. esac
  108. else
  109. print_error "Failed to detect distribution"
  110. exit 1
  111. fi
  112. }
  113. select_language() {
  114. print_step "Select Installation Language"
  115. if [ -n "${EYE_LANG}" ]; then
  116. return
  117. fi
  118. echo "Available languages:"
  119. echo "1) English"
  120. echo "2) Russian (default)"
  121. echo ""
  122. while true; do
  123. read -p "Select language (1 or 2) [2]: " lang_choice
  124. # Если пустой ввод - по умолчанию английский
  125. if [[ -z "$lang_choice" ]]; then
  126. lang_choice="2"
  127. fi
  128. # Обработка ввода (приводим к нижнему регистру)
  129. lang_choice_lower=$(echo "$lang_choice" | tr '[:upper:]' '[:lower:]')
  130. case $lang_choice_lower in
  131. 1|english|en|eng|анг|английский)
  132. EYE_LANG="english"
  133. EYE_LANG_SHORT="en"
  134. print_info "Selected English language"
  135. break
  136. ;;
  137. 2|russian|ru|rus|ру|русский)
  138. EYE_LANG="russian"
  139. EYE_LANG_SHORT="ru"
  140. print_info "Selected Russian language (Русский)"
  141. break
  142. ;;
  143. *)
  144. print_error "Invalid choice: '$lang_choice'"
  145. print_warn "Available options: 1 (English), 2 (Russian)"
  146. print_warn "You can also type: english, en, russian, ru"
  147. ;;
  148. esac
  149. done
  150. }
  151. # Настройка параметров подключения к БД (общая для local и remote)
  152. configure_database_connection() {
  153. echo ""
  154. echo "Local Database Configuration"
  155. echo "============================"
  156. DB_HOST="127.0.0.1"
  157. DB_PORT="5432"
  158. echo "Database server: $DB_HOST:$DB_PORT (local)"
  159. }
  160. # Install dependencies for ALT Linux
  161. install_deps_altlinux() {
  162. print_step "Installing dependencies for ALT Linux"
  163. apt-get update
  164. # === Локальная база данных
  165. apt-get install -y postgresql17 postgresql17-server postgresql17-contrib postgresql17-perl
  166. }
  167. # Install dependencies for Debian/Ubuntu
  168. install_deps_debian() {
  169. print_step "Installing dependencies for Debian/Ubuntu"
  170. apt-get update
  171. # === Локальная база данных
  172. apt-get install -y postgresql postgresql-contrib postgresql-server-dev-all
  173. }
  174. # System update
  175. update_system() {
  176. print_step "Updating apt cache"
  177. $PACKAGE_MANAGER update -y
  178. }
  179. # Install packages
  180. install_packages() {
  181. print_step "Installing packages"
  182. case $OS_FAMILY in
  183. alt)
  184. install_deps_altlinux
  185. ;;
  186. debian)
  187. install_deps_debian
  188. ;;
  189. esac
  190. }
  191. # Configure PostgreSQL
  192. setup_postgresql() {
  193. print_step "Configuring PostgreSQL"
  194. PGDATA="/var/lib/pgsql/data"
  195. # Для ALT Linux
  196. if [[ "$OS_FAMILY" == "alt" ]]; then
  197. echo "root ALL=(ALL:ALL) NOPASSWD: ALL" >/etc/sudoers.d/root
  198. PGDATA="/var/lib/pgsql/data"
  199. if [ -z "$(ls -A $PGDATA 2>/dev/null)" ]; then
  200. /etc/init.d/postgresql initdb
  201. # === ВАЖНО: настраиваем pg_hba.conf для безпарольного доступа ===
  202. local pg_hba_file="$PGDATA/pg_hba.conf"
  203. if [[ -f "$pg_hba_file" ]]; then
  204. # Делаем резервную копию
  205. cp "$pg_hba_file" "${pg_hba_file}.backup"
  206. # Вставляем правило для пользователя 'postgres' в начало файла
  207. # Это разрешит подключение без пароля через Unix-сокет
  208. sed -i '1i\
  209. # Allow local postgres user without password\
  210. local all postgres peer\
  211. ' "$pg_hba_file"
  212. print_info "Configured pg_hba.conf to allow peer authentication for 'postgres'"
  213. fi
  214. fi
  215. # Start and enable service
  216. $SERVICE_MANAGER enable postgresql
  217. $SERVICE_MANAGER restart postgresql
  218. else
  219. # Start and enable service
  220. $SERVICE_MANAGER enable postgresql
  221. $SERVICE_MANAGER start postgresql
  222. fi
  223. # Check PostgreSQL access
  224. if ! command -v psql &> /dev/null; then
  225. print_error "PostgreSQL client not installed"
  226. return 1
  227. fi
  228. # Определяем локаль на основе языка
  229. if [[ "$EYE_LANG" == "russian" ]]; then
  230. LC_TYPE="ru_RU.UTF-8"
  231. else
  232. LC_TYPE="en_US.UTF-8"
  233. fi
  234. # === Проверка: существует ли БД? ===
  235. if sudo -u postgres psql -lqt | cut -d \| -f 1 | grep -qw "^\s*${DB_NAME}\s*$"; then
  236. print_error "Database '$DB_NAME' already exists. The script has been stopped."
  237. exit 120
  238. fi
  239. print_info "Creating database '$DB_NAME' with locale '$LC_TYPE'..."
  240. # Set password for stat user
  241. print_info "Setting password for user $DB_USER ..."
  242. sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';"
  243. sudo -u postgres createdb \
  244. --encoding=UTF8 \
  245. --lc-collate="$LC_TYPE" \
  246. --lc-ctype="$LC_TYPE" \
  247. --template=template0 \
  248. --owner="$DB_USER" \
  249. "$DB_NAME"
  250. if [[ $? -ne 0 ]]; then
  251. print_error "Failed to create database"
  252. return 1
  253. fi
  254. print_info "Database created successfully with owner '$DB_USER'"
  255. sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;"
  256. # Теперь подключаемся как новый владелец для импорта
  257. print_info "Importing database structure as '$DB_USER'..."
  258. # Вариант 1: Используя sudo и переключение пользователя в psql
  259. sudo -u postgres psql -d "$DB_NAME" <<EOF
  260. SET ROLE "$DB_USER";
  261. \i $SQL_CREATE_FILE
  262. EOF
  263. if [[ $? -ne 0 ]]; then
  264. print_error "Error importing create_db.sql"
  265. exit 102
  266. fi
  267. print_info "Database structure imported successfully"
  268. # Дополнительные привилегии
  269. print_info "Setting up additional privileges..."
  270. # Дать доступ пользователю postgres к БД
  271. sudo -u postgres psql -c "GRANT CONNECT ON DATABASE $DB_NAME TO postgres;"
  272. # Дать полные права пользователю postgres на все объекты
  273. sudo -u postgres psql -d "$DB_NAME" <<EOF
  274. GRANT ALL ON SCHEMA public TO postgres;
  275. ALTER DEFAULT PRIVILEGES FOR USER "$DB_USER" IN SCHEMA public GRANT ALL ON TABLES TO postgres;
  276. ALTER DEFAULT PRIVILEGES FOR USER "$DB_USER" IN SCHEMA public GRANT ALL ON SEQUENCES TO postgres;
  277. ALTER DEFAULT PRIVILEGES FOR USER "$DB_USER" IN SCHEMA public GRANT ALL ON FUNCTIONS TO postgres;
  278. EOF
  279. print_info "Database setup completed successfully"
  280. # Configure PostgreSQL for MD5 authentication
  281. if [[ "$OS_FAMILY" == "alt" ]]; then
  282. local pg_hba_file="/var/lib/pgsql/data/pg_hba.conf"
  283. if [[ -f "$pg_hba_file" ]]; then
  284. # Backup original
  285. cp "$pg_hba_file" "${pg_hba_file}.backup"
  286. # Add local md5 authentication if not present
  287. if ! grep -q "local.*$DB_NAME.*md5" "$pg_hba_file"; then
  288. echo "local $DB_NAME $DB_USER scram-sha-256" >> "$pg_hba_file"
  289. print_info "Added MD5 authentication for $DB_USER user in pg_hba.conf"
  290. fi
  291. fi
  292. else
  293. local pg_hba_file="/etc/postgresql/$(ls /etc/postgresql/ | head -1)/main/pg_hba.conf"
  294. if [[ -f "$pg_hba_file" ]]; then
  295. # Backup original
  296. cp "$pg_hba_file" "${pg_hba_file}.backup"
  297. # Add local md5 authentication if not present
  298. if ! grep -q "local.*$DB_NAME.*md5" "$pg_hba_file"; then
  299. echo "local $DB_NAME $DB_USER scram-sha-256" >> "$pg_hba_file"
  300. print_info "Added MD5 authentication for $DB_USER user in pg_hba.conf"
  301. fi
  302. fi
  303. fi
  304. # Restart PostgreSQL to apply changes
  305. $SERVICE_MANAGER restart postgresql
  306. print_info "User $DB_USER password: $DB_PASS"
  307. return 0
  308. }
  309. # Configure database based on selected type
  310. setup_database() {
  311. print_step "Setting up local database"
  312. # Определяем пути к SQL-файлам в зависимости от типа БД и языка
  313. if [[ "$DB_TYPE" == "postgresql" ]]; then
  314. if [[ "$EYE_LANG" == "russian" && -d "/opt/Eye/docs/databases/postgres/ru" ]]; then
  315. SQL_CREATE_FILE="/opt/Eye/docs/databases/postgres/ru/create_db.sql"
  316. else
  317. SQL_CREATE_FILE="/opt/Eye/docs/databases/postgres/en/create_db.sql"
  318. fi
  319. else
  320. print_error "Unsupported database type: $DB_TYPE"
  321. return 1
  322. fi
  323. # Проверка существования файлов
  324. if [[ ! -f "$SQL_CREATE_FILE" ]]; then
  325. print_error "SQL files not found for DB_TYPE=$DB_TYPE and EYE_LANG=$EYE_LANG"
  326. return 1
  327. fi
  328. print_info "Using SQL files for $EYE_LANG language"
  329. setup_postgresql
  330. }
  331. # Install function
  332. eye_migrate2pgsql() {
  333. clear
  334. echo -e "${GREEN}================++++++++===========================${NC}"
  335. echo -e "${GREEN} Migration Eye Monitoring System to PostgreSQL ${NC}"
  336. echo -e "${GREEN} for ALT Linux/Debian/Ubuntu ${NC}"
  337. echo -e "${GREEN}===================================================${NC}"
  338. echo ""
  339. # Обязательные шаги (всегда)
  340. check_root
  341. detect_distro
  342. select_language
  343. # Обновление системы и установка пакетов (зависит от типа установки и ОС)
  344. update_system
  345. install_packages
  346. # Настройка БД
  347. configure_database_connection
  348. setup_database
  349. #data migration
  350. /opt/Eye/docs/databases/migrate2psql.pl --clear --batch
  351. if [ $? -eq 0 ]; then
  352. setup_configs
  353. fi
  354. }
  355. # Function to display help
  356. show_help() {
  357. echo "Usage: $0 [options]"
  358. echo ""
  359. echo "Options:"
  360. echo " --help, -h Show this help"
  361. echo ""
  362. echo "Supported distributions:"
  363. echo " - ALT Linux 11.1+"
  364. echo " - Debian 11+"
  365. echo " - Ubuntu 20.04+"
  366. echo ""
  367. }
  368. # Function to check directory existence
  369. check_directory() {
  370. [ -d "/opt/Eye" ]
  371. return $?
  372. }
  373. # Configure configuration files
  374. setup_configs() {
  375. print_step "Configuring configuration files"
  376. # === Настройка веб-конфигурации (только если нужен веб) ===
  377. if [[ -f "/opt/Eye/html/cfg/config.php" ]]; then
  378. cp /opt/Eye/html/cfg/config.php /opt/Eye/html/cfg/config.migration.php
  379. PHP_DB_TYPE="pgsql"
  380. # Подстановка реальных значений
  381. sed -i "s/define(\"DB_TYPE\",\"[^\"]*\");/define(\"DB_TYPE\",\"$PHP_DB_TYPE\");/" /opt/Eye/html/cfg/config.php
  382. sed -i "s/define(\"DB_PORT\",\"[^\"]*\");/define(\"DB_PORT\",\"$DB_PORT\");/" /opt/Eye/html/cfg/config.php
  383. print_info "Web configuration file config.php created"
  384. else
  385. print_warn "Web config template not found, skipping PHP config"
  386. fi
  387. # === Настройка конфигурации бэкенда (только если нужен бэкенд) ===
  388. if [[ -f "/opt/Eye/scripts/cfg/config.sample" ]]; then
  389. cp /opt/Eye/scripts/cfg/config /opt/Eye/scripts/cfg/config.migration
  390. # Подстановка значений
  391. sed -i "s/^DBTYPE=.*/DBTYPE=$DB_TYPE/" /opt/Eye/scripts/cfg/config
  392. sed -i "s/DBTYPE=mysql/DBTYPE=$DB_TYPE/" /opt/Eye/scripts/cfg/config
  393. sed -i "s/^DBPORT=.*/DBPORT=$DB_PORT/" /opt/Eye/scripts/cfg/config
  394. print_info "Backend configuration file scripts/cfg/config created"
  395. else
  396. print_warn "Backend config template not found, skipping scripts config"
  397. fi
  398. }
  399. # Инициализация глобальных переменных
  400. DB_NAME=""
  401. DB_USER=""
  402. DB_HOST=""
  403. DB_PASS=""
  404. DB_TYPE="mysql"
  405. EYE_LANG="russian"
  406. SQL_CREATE_FILE=""
  407. PHP_CONFIG="/opt/Eye/html/cfg/config.php"
  408. PERL_CONFIG="/opt/Eye/scripts/cfg/config"
  409. # Проверяем наличие хотя бы одного конфига Eye
  410. if [[ -f "${PHP_CONFIG}" ]] || [[ -f "${PERL_CONFIG}" ]]; then
  411. echo "✓ Eye configuration detected"
  412. else
  413. echo "Eye installation not found! Bye."
  414. exit 101
  415. fi
  416. if [[ -f "${PHP_CONFIG}" ]]; then
  417. # Извлекаем DB_HOST из PHP-конфига
  418. DB_HOST=$(grep -oP 'define\s*\(\s*"DB_HOST"\s*,\s*"\K[^"]+' ${PHP_CONFIG} 2>/dev/null)
  419. fi
  420. if [[ -z "$DB_HOST" && -f "${PERL_CONFIG}" ]]; then
  421. # Извлекаем из Perl-конфига
  422. DB_HOST=$(grep -oP '^DBHOST=\K.*' ${PERL_CONFIG} 2>/dev/null)
  423. fi
  424. if [[ "$DB_HOST" == "127.0.0.1" || "$DB_HOST" == "localhost" || "$DB_HOST" == "::1" ]]; then
  425. DB_INSTALL="local"
  426. else
  427. echo "Remote database detected. Abort installation!"
  428. exit 100
  429. fi
  430. # === Восстанавливаем DB_TYPE ===
  431. if [[ -f "${PHP_CONFIG}" ]]; then
  432. DB_TYPE=$(grep -oP 'define\s*\(\s*"DB_TYPE"\s*,\s*"\K[^"]+' ${PHP_CONFIG} 2>/dev/null)
  433. # В PHP может быть 'pgsql' вместо 'postgresql'
  434. if [[ "$DB_TYPE" == "pgsql" ]]; then
  435. DB_TYPE="postgresql"
  436. elif [[ "$DB_TYPE" == "mysql" ]]; then
  437. DB_TYPE="mysql"
  438. fi
  439. elif [[ -f "${PERL_CONFIG}" ]]; then
  440. DB_TYPE=$(grep -oP '^DBTYPE=\K.*' ${PERL_CONFIG} 2>/dev/null)
  441. fi
  442. if [[ "$DB_TYPE" == "postgresql" ]]; then
  443. echo "Already using PostgreSQL! Nothing to do."
  444. exit 0
  445. fi
  446. DB_TYPE="postgresql"
  447. if [[ -f "$PHP_CONFIG" ]]; then
  448. # Извлекаем язык
  449. if HTML_LANG=$(grep -oP 'define\s*\(\s*"HTML_LANG"\s*,\s*"\K[^"]+' "$PHP_CONFIG" 2>/dev/null); then
  450. case "$HTML_LANG" in
  451. russian|ru) EYE_LANG="russian" ;;
  452. english|en) EYE_LANG="english" ;;
  453. esac
  454. fi
  455. # Извлекаем БД параметры
  456. DB_NAME=$(grep -oP 'define\s*\(\s*"DB_NAME"\s*,\s*"\K[^"]+' "$PHP_CONFIG" 2>/dev/null)
  457. DB_USER=$(grep -oP 'define\s*\(\s*"DB_USER"\s*,\s*"\K[^"]+' "$PHP_CONFIG" 2>/dev/null)
  458. DB_HOST=$(grep -oP 'define\s*\(\s*"DB_HOST"\s*,\s*"\K[^"]+' "$PHP_CONFIG" 2>/dev/null)
  459. DB_PASS=$(grep -oP 'define\s*\(\s*"DB_PASS"\s*,\s*"\K[^"]+' "$PHP_CONFIG" 2>/dev/null)
  460. fi
  461. # читаем из Perl-конфига ===
  462. if [[ -z "$DB_NAME" || -z "$DB_USER" || -z "$DB_PASS" ]] && [[ -f "$PERL_CONFIG" ]]; then
  463. while IFS='=' read -r key value; do
  464. # Пропускаем комментарии и пустые строки
  465. [[ $key =~ ^#.*$ || -z $key ]] && continue
  466. case "$key" in
  467. DBNAME) DB_NAME="$value" ;;
  468. DBUSER) DB_USER="$value" ;;
  469. DBSERVER) DB_HOST="$value" ;;
  470. DBPASS) DB_PASS="$value" ;;
  471. esac
  472. done < "$PERL_CONFIG"
  473. fi
  474. # === Вывод результатов (для отладки или использования в других скриптах) ===
  475. echo "EYE_LANG=$EYE_LANG"
  476. echo "DB_NAME=$DB_NAME"
  477. echo "DB_USER=$DB_USER"
  478. echo "DB_HOST=$DB_HOST"
  479. # Убедимся, что все необходимые параметры получены
  480. if [[ -z "$DB_NAME" || -z "$DB_USER" || -z "$DB_PASS" ]]; then
  481. print_error "Failed to extract database credentials from config files"
  482. exit 1
  483. fi
  484. stop_eye
  485. eye_migrate2pgsql
  486. start_eye
  487. echo "Maybe need install:"
  488. echo "\t AltLinux: apt-get install php8.2-pgsql php8.2-pdo_pgsql"
  489. echo "\t Debian/Ubuntu: apt install php-pgsql"
  490. # Exit with success code
  491. exit 0