checkDBschema.sh 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. #!/bin/bash
  2. # Eye Script validating current DB schema 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. # Detect distribution and package manager
  33. detect_distro() {
  34. if [[ -f /etc/os-release ]]; then
  35. . /etc/os-release
  36. OS_ID=$ID
  37. OS_VERSION=$VERSION_ID
  38. OS_NAME=$NAME
  39. case $OS_ID in
  40. altlinux)
  41. PACKAGE_MANAGER="apt-get"
  42. SERVICE_MANAGER="systemctl"
  43. OS_FAMILY="alt"
  44. print_info "Detected ALT Linux $OS_VERSION"
  45. ;;
  46. debian)
  47. PACKAGE_MANAGER="apt"
  48. SERVICE_MANAGER="systemctl"
  49. OS_FAMILY="debian"
  50. print_info "Detected Debian $OS_VERSION"
  51. ;;
  52. ubuntu)
  53. PACKAGE_MANAGER="apt"
  54. SERVICE_MANAGER="systemctl"
  55. OS_FAMILY="debian"
  56. print_info "Detected Ubuntu $OS_VERSION"
  57. ;;
  58. *)
  59. print_error "Unsupported distribution: $OS_ID"
  60. print_error "Supported: ALT Linux, Debian, Ubuntu"
  61. exit 1
  62. ;;
  63. esac
  64. else
  65. print_error "Failed to detect distribution"
  66. exit 1
  67. fi
  68. }
  69. select_language() {
  70. print_step "Select Installation Language"
  71. if [ -n "${EYE_LANG}" ]; then
  72. return
  73. fi
  74. echo "Available languages:"
  75. echo "1) English"
  76. echo "2) Russian (default)"
  77. echo ""
  78. while true; do
  79. read -p "Select language (1 or 2) [2]: " lang_choice
  80. # Если пустой ввод - по умолчанию английский
  81. if [[ -z "$lang_choice" ]]; then
  82. lang_choice="2"
  83. fi
  84. # Обработка ввода (приводим к нижнему регистру)
  85. lang_choice_lower=$(echo "$lang_choice" | tr '[:upper:]' '[:lower:]')
  86. case $lang_choice_lower in
  87. 1|english|en|eng|анг|английский)
  88. EYE_LANG="english"
  89. EYE_LANG_SHORT="en"
  90. print_info "Selected English language"
  91. break
  92. ;;
  93. 2|russian|ru|rus|ру|русский)
  94. EYE_LANG="russian"
  95. EYE_LANG_SHORT="ru"
  96. print_info "Selected Russian language (Русский)"
  97. break
  98. ;;
  99. *)
  100. print_error "Invalid choice: '$lang_choice'"
  101. print_warn "Available options: 1 (English), 2 (Russian)"
  102. print_warn "You can also type: english, en, russian, ru"
  103. ;;
  104. esac
  105. done
  106. }
  107. # Настройка параметров подключения к БД (общая для local и remote)
  108. configure_database_connection() {
  109. echo ""
  110. echo "Local Database Configuration"
  111. echo "============================"
  112. if [[ "$DB_TYPE" == "postgresql" ]]; then
  113. DB_PORT="5432"
  114. else
  115. DB_PORT="3306"
  116. fi
  117. }
  118. # Configure MySQL
  119. setup_mysql() {
  120. print_step "Configuring MySQL"
  121. # Check MySQL access
  122. if ! command -v mysql &> /dev/null; then
  123. print_error "MySQL client not installed"
  124. return 1
  125. fi
  126. MYSQL_OPT="-u root"
  127. # Check access without password
  128. if mysql -u root -e "SELECT 1;" 2>/dev/null; then
  129. print_info "MySQL accessible with empty password"
  130. echo ""
  131. print_warn "IMPORTANT: Need to set root password for MySQL!"
  132. print_warn "After installation run: mysql_secure_installation"
  133. echo ""
  134. else
  135. # Ask for password and create config file
  136. read -p "Enter MySQL root user password: " DB_ROOT_PASSWORD
  137. echo ""
  138. # Create temporary config file
  139. MYSQL_CNF_FILE="/tmp/mysql_root_eye.cnf"
  140. echo "[client]" > "$MYSQL_CNF_FILE"
  141. echo "user=root" >> "$MYSQL_CNF_FILE"
  142. echo "password=$DB_ROOT_PASSWORD" >> "$MYSQL_CNF_FILE"
  143. chmod 600 "$MYSQL_CNF_FILE"
  144. # Check connection
  145. if mysql --defaults-extra-file="$MYSQL_CNF_FILE" -e "SELECT 1;" &>/dev/null; then
  146. print_info "Successfully connected to MySQL"
  147. MYSQL_OPT="--defaults-extra-file=$MYSQL_CNF_FILE"
  148. else
  149. print_error "Incorrect MySQL root password"
  150. rm -f "$MYSQL_CNF_FILE"
  151. return 1
  152. fi
  153. fi
  154. # === Проверка: существует ли база данных? ===
  155. if mysql $MYSQL_OPT -sN -e "SHOW DATABASES;" | grep -q "^${DB_TEST}$"; then
  156. print_error "Database '$DB_TEST' already exists. The script has been stopped."
  157. exit 120
  158. fi
  159. print_info "Creating database..."
  160. # Import main SQL file
  161. mysql $MYSQL_OPT <<EOF
  162. CREATE DATABASE IF NOT EXISTS ${DB_TEST} DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  163. EOF
  164. print_info "Importing database structure..."
  165. mysql $MYSQL_OPT ${DB_TEST} < ${SQL_CREATE_FILE}
  166. if [[ $? -ne 0 ]]; then
  167. print_error "Error importing create_db.sql"
  168. if [[ -f "$MYSQL_CNF_FILE" ]]; then
  169. rm -f "$MYSQL_CNF_FILE"
  170. fi
  171. return 1
  172. fi
  173. print_info "Database structure imported"
  174. # Create db user
  175. print_info "Creating user ${DB_USER}.."
  176. mysql $MYSQL_OPT <<EOF
  177. GRANT ALL PRIVILEGES ON $DB_TEST.* TO '$DB_USER'@'localhost';
  178. FLUSH PRIVILEGES;
  179. EOF
  180. if [[ $? -ne 0 ]]; then
  181. print_error "Error update user $DB_USER"
  182. if [[ -f "$MYSQL_CNF_FILE" ]]; then
  183. rm -f "$MYSQL_CNF_FILE"
  184. fi
  185. return 1
  186. fi
  187. # Clean up temporary file if created
  188. if [[ -f "$MYSQL_CNF_FILE" ]]; then
  189. rm -f "$MYSQL_CNF_FILE"
  190. fi
  191. return 0
  192. }
  193. # Configure PostgreSQL
  194. setup_postgresql() {
  195. print_step "Configuring PostgreSQL"
  196. # Определяем локаль на основе языка
  197. if [[ "$EYE_LANG" == "russian" ]]; then
  198. LC_TYPE="ru_RU.UTF-8"
  199. else
  200. LC_TYPE="en_US.UTF-8"
  201. fi
  202. # === Проверка: существует ли БД? ===
  203. if sudo -u postgres psql -lqt | cut -d \| -f 1 | grep -qw "^\s*${DB_TEST}\s*$"; then
  204. print_error "Database '$DB_TEST' already exists. The script has been stopped."
  205. exit 120
  206. fi
  207. print_info "Creating database '$DB_TEST' with locale '$LC_TYPE'..."
  208. sudo -u postgres createdb \
  209. --encoding=UTF8 \
  210. --lc-collate="$LC_TYPE" \
  211. --lc-ctype="$LC_TYPE" \
  212. --template=template0 \
  213. --owner="$DB_USER" \
  214. "$DB_TEST"
  215. if [[ $? -ne 0 ]]; then
  216. print_error "Failed to create database"
  217. return 1
  218. fi
  219. print_info "Database created successfully with owner '$DB_USER'"
  220. sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_TEST TO $DB_USER;"
  221. # Теперь подключаемся как новый владелец для импорта
  222. print_info "Importing database structure as '$DB_USER'..."
  223. # Вариант 1: Используя sudo и переключение пользователя в psql
  224. sudo -u postgres psql -d "$DB_TEST" <<EOF
  225. SET ROLE "$DB_USER";
  226. \i $SQL_CREATE_FILE
  227. EOF
  228. if [[ $? -ne 0 ]]; then
  229. print_error "Error importing create_db.sql"
  230. exit 102
  231. fi
  232. print_info "Database structure imported successfully"
  233. # Дополнительные привилегии
  234. print_info "Setting up additional privileges..."
  235. # Дать доступ пользователю postgres к БД
  236. sudo -u postgres psql -c "GRANT CONNECT ON DATABASE $DB_TEST TO postgres;"
  237. # Дать полные права пользователю postgres на все объекты
  238. sudo -u postgres psql -d "$DB_TEST" <<EOF
  239. GRANT ALL ON SCHEMA public TO postgres;
  240. ALTER DEFAULT PRIVILEGES FOR USER "$DB_USER" IN SCHEMA public GRANT ALL ON TABLES TO postgres;
  241. ALTER DEFAULT PRIVILEGES FOR USER "$DB_USER" IN SCHEMA public GRANT ALL ON SEQUENCES TO postgres;
  242. ALTER DEFAULT PRIVILEGES FOR USER "$DB_USER" IN SCHEMA public GRANT ALL ON FUNCTIONS TO postgres;
  243. EOF
  244. print_info "Database setup completed successfully"
  245. return 0
  246. }
  247. # Configure database based on selected type
  248. setup_database() {
  249. # Пропускаем настройку, если БД — удалённая
  250. if [[ "$DB_INSTALL" != "local" ]]; then
  251. print_info "Database is configured remotely — skipping local setup"
  252. return 0
  253. fi
  254. print_step "Setting up local database"
  255. # Определяем пути к SQL-файлам в зависимости от типа БД и языка
  256. if [[ "$DB_TYPE" == "mysql" ]]; then
  257. if [[ "$EYE_LANG" == "russian" && -d "/opt/Eye/docs/databases/mysql/ru" ]]; then
  258. SQL_CREATE_FILE="/opt/Eye/docs/databases/mysql/ru/create_db.sql"
  259. else
  260. SQL_CREATE_FILE="/opt/Eye/docs/databases/mysql/en/create_db.sql"
  261. fi
  262. elif [[ "$DB_TYPE" == "postgresql" ]]; then
  263. if [[ "$EYE_LANG" == "russian" && -d "/opt/Eye/docs/databases/postgres/ru" ]]; then
  264. SQL_CREATE_FILE="/opt/Eye/docs/databases/postgres/ru/create_db.sql"
  265. else
  266. SQL_CREATE_FILE="/opt/Eye/docs/databases/postgres/en/create_db.sql"
  267. fi
  268. else
  269. print_error "Unsupported database type: $DB_TYPE"
  270. return 1
  271. fi
  272. # Проверка существования файлов
  273. if [[ ! -f "$SQL_CREATE_FILE" ]]; then
  274. print_error "SQL files not found for DB_TYPE=$DB_TYPE and EYE_LANG=$EYE_LANG"
  275. return 1
  276. fi
  277. print_info "Using SQL files for $EYE_LANG language"
  278. # Выполняем настройку в зависимости от СУБД
  279. if [[ "$DB_TYPE" == "postgresql" ]]; then
  280. setup_postgresql
  281. else
  282. setup_mysql
  283. fi
  284. }
  285. # Install function
  286. install_clear_db() {
  287. clear
  288. echo -e "${GREEN}================++++++++===========================${NC}"
  289. echo -e "${GREEN} CheckDB Schema for Eye Monitoring System ${NC}"
  290. echo -e "${GREEN} for ALT Linux/Debian/Ubuntu ${NC}"
  291. echo -e "${GREEN}===================================================${NC}"
  292. echo ""
  293. # Обязательные шаги (всегда)
  294. check_root
  295. detect_distro
  296. select_language
  297. # Настройка БД
  298. configure_database_connection
  299. setup_database
  300. #data migration
  301. /opt/Eye/docs/databases/checkDBschema.pl
  302. echo "The $DB_TEST database can be deleted"
  303. }
  304. # Function to display help
  305. show_help() {
  306. echo "Usage: $0"
  307. echo "\tThe script checks the correctness of the working database structure."
  308. echo "\tTo do this, it creates a new empty database with a reference structure,"
  309. echo "\tand then compares the two databases. "
  310. echo "\tThe name of the test database is formed from the name of the working database with _test appended to it."
  311. echo ""
  312. echo "Options:"
  313. echo " --help, -h Show this help"
  314. echo ""
  315. echo "Supported distributions:"
  316. echo " - ALT Linux 11.1+"
  317. echo " - Debian 11+"
  318. echo " - Ubuntu 20.04+"
  319. echo ""
  320. }
  321. # Function to check directory existence
  322. check_directory() {
  323. [ -d "/opt/Eye" ]
  324. return $?
  325. }
  326. # Инициализация глобальных переменных
  327. DB_NAME=""
  328. DB_USER=""
  329. DB_HOST=""
  330. DB_PASS=""
  331. DB_TYPE="mysql"
  332. EYE_LANG="russian"
  333. SQL_CREATE_FILE=""
  334. PHP_CONFIG="/opt/Eye/html/cfg/config.php"
  335. PERL_CONFIG="/opt/Eye/scripts/cfg/config"
  336. # Проверяем наличие хотя бы одного конфига Eye
  337. if [[ -f "${PHP_CONFIG}" ]] || [[ -f "${PERL_CONFIG}" ]]; then
  338. echo "✓ Eye configuration detected"
  339. else
  340. echo "Eye installation not found! Bye."
  341. exit 101
  342. fi
  343. if [[ -f "${PHP_CONFIG}" ]]; then
  344. # Извлекаем DB_HOST из PHP-конфига
  345. DB_HOST=$(grep -oP 'define\s*\(\s*"DB_HOST"\s*,\s*"\K[^"]+' ${PHP_CONFIG} 2>/dev/null)
  346. fi
  347. if [[ -z "$DB_HOST" && -f "${PERL_CONFIG}" ]]; then
  348. # Извлекаем из Perl-конфига
  349. DB_HOST=$(grep -oP '^DBHOST=\K.*' ${PERL_CONFIG} 2>/dev/null)
  350. fi
  351. if [[ "$DB_HOST" == "127.0.0.1" || "$DB_HOST" == "localhost" || "$DB_HOST" == "::1" ]]; then
  352. DB_INSTALL="local"
  353. else
  354. echo "Remote database detected. Abort installation!"
  355. exit 100
  356. fi
  357. # === Восстанавливаем DB_TYPE ===
  358. if [[ -f "${PHP_CONFIG}" ]]; then
  359. DB_TYPE=$(grep -oP 'define\s*\(\s*"DB_TYPE"\s*,\s*"\K[^"]+' ${PHP_CONFIG} 2>/dev/null)
  360. # В PHP может быть 'pgsql' вместо 'postgresql'
  361. if [[ "$DB_TYPE" == "pgsql" ]]; then
  362. DB_TYPE="postgresql"
  363. elif [[ "$DB_TYPE" == "mysql" ]]; then
  364. DB_TYPE="mysql"
  365. fi
  366. elif [[ -f "${PERL_CONFIG}" ]]; then
  367. DB_TYPE=$(grep -oP '^DBTYPE=\K.*' ${PERL_CONFIG} 2>/dev/null)
  368. fi
  369. if [[ -f "$PHP_CONFIG" ]]; then
  370. # Извлекаем язык
  371. if HTML_LANG=$(grep -oP 'define\s*\(\s*"HTML_LANG"\s*,\s*"\K[^"]+' "$PHP_CONFIG" 2>/dev/null); then
  372. case "$HTML_LANG" in
  373. russian|ru) EYE_LANG="russian" ;;
  374. english|en) EYE_LANG="english" ;;
  375. esac
  376. fi
  377. # Извлекаем БД параметры
  378. DB_NAME=$(grep -oP 'define\s*\(\s*"DB_NAME"\s*,\s*"\K[^"]+' "$PHP_CONFIG" 2>/dev/null)
  379. DB_USER=$(grep -oP 'define\s*\(\s*"DB_USER"\s*,\s*"\K[^"]+' "$PHP_CONFIG" 2>/dev/null)
  380. DB_HOST=$(grep -oP 'define\s*\(\s*"DB_HOST"\s*,\s*"\K[^"]+' "$PHP_CONFIG" 2>/dev/null)
  381. DB_PASS=$(grep -oP 'define\s*\(\s*"DB_PASS"\s*,\s*"\K[^"]+' "$PHP_CONFIG" 2>/dev/null)
  382. fi
  383. # читаем из Perl-конфига ===
  384. if [[ -z "$DB_NAME" || -z "$DB_USER" || -z "$DB_PASS" ]] && [[ -f "$PERL_CONFIG" ]]; then
  385. while IFS='=' read -r key value; do
  386. # Пропускаем комментарии и пустые строки
  387. [[ $key =~ ^#.*$ || -z $key ]] && continue
  388. case "$key" in
  389. DBNAME) DB_NAME="$value" ;;
  390. DBUSER) DB_USER="$value" ;;
  391. DBSERVER) DB_HOST="$value" ;;
  392. DBPASS) DB_PASS="$value" ;;
  393. esac
  394. done < "$PERL_CONFIG"
  395. fi
  396. if [ -z "${DB_TYPE}" ]; then
  397. DB_TYPE='mysql'
  398. fi
  399. # === Вывод результатов (для отладки или использования в других скриптах) ===
  400. echo "EYE_LANG=$EYE_LANG"
  401. echo "DB_NAME=$DB_NAME"
  402. echo "DB_USER=$DB_USER"
  403. echo "DB_HOST=$DB_HOST"
  404. echo "DB_TYPE=$DB_TYPE"
  405. DB_TEST="${DB_NAME}_test"
  406. # Убедимся, что все необходимые параметры получены
  407. if [[ -z "$DB_NAME" || -z "$DB_USER" || -z "$DB_PASS" ]]; then
  408. print_error "Failed to extract database credentials from config files"
  409. exit 1
  410. fi
  411. install_clear_db
  412. # Exit with success code
  413. exit 0