db.sh 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. # MySQL
  2. mysql_connect() {
  3. host_str=$(grep "HOST='$1'" $VESTA/conf/mysql.conf)
  4. eval $host_str
  5. if [ -z $HOST ] || [ -z $USER ] || [ -z $PASSWORD ]; then
  6. echo "Error: mysql config parsing failed"
  7. log_event "$E_PARSING" "$ARGUMENTS"
  8. exit $E_PARSING
  9. fi
  10. mycnf="$VESTA/conf/.mysql.$HOST"
  11. if [ ! -e "$mycnf" ]; then
  12. echo "[client]">$mycnf
  13. echo "host='$HOST'" >> $mycnf
  14. echo "user='$USER'" >> $mycnf
  15. echo "password='$PASSWORD'" >> $mycnf
  16. chmod 600 $mycnf
  17. else
  18. mypw=$(grep password $mycnf|cut -f 2 -d \')
  19. if [ "$mypw" != "$PASSWORD" ]; then
  20. echo "[client]">$mycnf
  21. echo "host='$HOST'" >> $mycnf
  22. echo "user='$USER'" >> $mycnf
  23. echo "password='$PASSWORD'" >> $mycnf
  24. chmod 660 $mycnf
  25. fi
  26. fi
  27. mysql_out=$(mktemp)
  28. mysql --defaults-file=$mycnf -e 'SELECT VERSION()' > $mysql_out 2>&1
  29. if [ '0' -ne "$?" ]; then
  30. if [ "$notify" != 'no' ]; then
  31. echo -e "Can't connect to MySQL $HOST\n$(cat $mysql_out)" |\
  32. $SENDMAIL -s "$subj" $email
  33. fi
  34. rm -f $mysql_out
  35. echo "Error: Connection to $HOST failed"
  36. log_event "$E_CONNECT" "$ARGUMENTS"
  37. exit $E_CONNECT
  38. fi
  39. mysql_ver=$(cat $mysql_out |tail -n1 |cut -f 1 -d -)
  40. mysql_fork="mysql"
  41. check_mysql_fork=$(grep "MariaDB" $mysql_out)
  42. if [ ! -z "$check_mysql_fork" ]; then
  43. mysql_fork="mariadb"
  44. fi
  45. rm -f $mysql_out
  46. }
  47. mysql_query() {
  48. sql_tmp=$(mktemp)
  49. echo "$1" > $sql_tmp
  50. mysql --defaults-file=$mycnf < "$sql_tmp" 2>/dev/null
  51. rm -f "$sql_tmp"
  52. }
  53. mysql_dump() {
  54. err="/tmp/e.mysql"
  55. mysqldump --defaults-file=$mycnf --single-transaction -r $1 $2 2> $err
  56. if [ '0' -ne "$?" ]; then
  57. rm -rf $tmpdir
  58. if [ "$notify" != 'no' ]; then
  59. echo -e "Can't dump database $database\n$(cat $err)" |\
  60. $SENDMAIL -s "$subj" $email
  61. fi
  62. echo "Error: dump $database failed"
  63. log_event "$E_DB" "$ARGUMENTS"
  64. exit $E_DB
  65. fi
  66. }
  67. # PostgreSQL
  68. psql_connect() {
  69. host_str=$(grep "HOST='$1'" $VESTA/conf/pgsql.conf)
  70. eval $host_str
  71. export PGPASSWORD="$PASSWORD"
  72. if [ -z $HOST ] || [ -z $USER ] || [ -z $PASSWORD ] || [ -z $TPL ]; then
  73. echo "Error: postgresql config parsing failed"
  74. log_event "$E_PARSING" "$ARGUMENTS"
  75. exit $E_PARSING
  76. fi
  77. psql -h $HOST -U $USER -c "SELECT VERSION()" > /dev/null 2>/tmp/e.psql
  78. if [ '0' -ne "$?" ]; then
  79. if [ "$notify" != 'no' ]; then
  80. echo -e "Can't connect to PostgreSQL $HOST\n$(cat /tmp/e.psql)" |\
  81. $SENDMAIL -s "$subj" $email
  82. fi
  83. echo "Error: Connection to $HOST failed"
  84. log_event "$E_CONNECT" "$ARGUMENTS"
  85. exit $E_CONNECT
  86. fi
  87. }
  88. psql_query() {
  89. sql_tmp=$(mktemp)
  90. echo "$1" > $sql_tmp
  91. psql -h $HOST -U $USER -f "$sql_tmp" 2>/dev/null
  92. rm -f $sql_tmp
  93. }
  94. psql_dump() {
  95. pg_dump -h $HOST -U $USER -c --inserts -O -x -f $1 $2 2>/tmp/e.psql
  96. if [ '0' -ne "$?" ]; then
  97. rm -rf $tmpdir
  98. if [ "$notify" != 'no' ]; then
  99. echo -e "Can't dump database $database\n$(cat /tmp/e.psql)" |\
  100. $SENDMAIL -s "$subj" $email
  101. fi
  102. echo "Error: dump $database failed"
  103. log_event "$E_DB" "$ARGUMENTS"
  104. exit $E_DB
  105. fi
  106. }
  107. # Get database host
  108. get_next_dbhost() {
  109. if [ -z "$host" ] || [ "$host" == 'default' ]; then
  110. IFS=$'\n'
  111. host='EMPTY_DB_HOST'
  112. config="$VESTA/conf/$type.conf"
  113. host_str=$(grep "SUSPENDED='no'" $config)
  114. check_row=$(echo "$host_str"|wc -l)
  115. if [ 0 -lt "$check_row" ]; then
  116. if [ 1 -eq "$check_row" ]; then
  117. for db in $host_str; do
  118. eval $db
  119. if [ "$MAX_DB" -gt "$U_DB_BASES" ]; then
  120. host=$HOST
  121. fi
  122. done
  123. else
  124. old_weight='100'
  125. for db in $host_str; do
  126. eval $db
  127. let weight="$U_DB_BASES * 100 / $MAX_DB" >/dev/null 2>&1
  128. if [ "$old_weight" -gt "$weight" ]; then
  129. host="$HOST"
  130. old_weight="$weight"
  131. fi
  132. done
  133. fi
  134. fi
  135. fi
  136. }
  137. # Database charset validation
  138. is_charset_valid() {
  139. host_str=$(grep "HOST='$host'" $VESTA/conf/$type.conf)
  140. eval $host_str
  141. if [ -z "$(echo $CHARSETS | grep -wi $charset )" ]; then
  142. echo "Error: charset $charset not exist"
  143. log_event "$E_NOTEXIST" "$ARGUMENTS"
  144. exit $E_NOTEXIST
  145. fi
  146. }
  147. # Increase database host value
  148. increase_dbhost_values() {
  149. host_str=$(grep "HOST='$host'" $VESTA/conf/$type.conf)
  150. eval $host_str
  151. old_dbbases="U_DB_BASES='$U_DB_BASES'"
  152. new_dbbases="U_DB_BASES='$((U_DB_BASES + 1))'"
  153. if [ -z "$U_SYS_USERS" ]; then
  154. old_users="U_SYS_USERS=''"
  155. new_users="U_SYS_USERS='$user'"
  156. else
  157. old_users="U_SYS_USERS='$U_SYS_USERS'"
  158. new_users="U_SYS_USERS='$U_SYS_USERS'"
  159. if [ -z "$(echo $U_SYS_USERS|sed "s/,/\n/g"|grep -w $user)" ]; then
  160. old_users="U_SYS_USERS='$U_SYS_USERS'"
  161. new_users="U_SYS_USERS='$U_SYS_USERS,$user'"
  162. fi
  163. fi
  164. sed -i "s/$old_dbbases/$new_dbbases/g" $VESTA/conf/$type.conf
  165. sed -i "s/$old_users/$new_users/g" $VESTA/conf/$type.conf
  166. }
  167. # Decrease database host value
  168. decrease_dbhost_values() {
  169. host_str=$(grep "HOST='$HOST'" $VESTA/conf/$TYPE.conf)
  170. eval $host_str
  171. old_dbbases="U_DB_BASES='$U_DB_BASES'"
  172. new_dbbases="U_DB_BASES='$((U_DB_BASES - 1))'"
  173. old_users="U_SYS_USERS='$U_SYS_USERS'"
  174. U_SYS_USERS=$(echo "$U_SYS_USERS" |\
  175. sed "s/,/\n/g"|\
  176. sed "s/^$user$//g"|\
  177. sed "/^$/d"|\
  178. sed ':a;N;$!ba;s/\n/,/g')
  179. new_users="U_SYS_USERS='$U_SYS_USERS'"
  180. sed -i "s/$old_dbbases/$new_dbbases/g" $VESTA/conf/$TYPE.conf
  181. sed -i "s/$old_users/$new_users/g" $VESTA/conf/$TYPE.conf
  182. }
  183. # Create MySQL database
  184. add_mysql_database() {
  185. mysql_connect $host
  186. query="CREATE DATABASE \`$database\` CHARACTER SET $charset"
  187. mysql_query "$query" > /dev/null
  188. # This can be modified for mysql 5.7 for better compatibility
  189. if [ "$(echo $mysql_ver |cut -d '.' -f1)" -eq 8 ]; then
  190. query="CREATE USER IF NOT EXISTS '$dbuser'@'localhost' IDENTIFIED BY '$dbpass';"
  191. mysql_query "$query" > /dev/null
  192. query="CREATE USER IF NOT EXISTS '$dbuser'@'%' IDENTIFIED BY '$dbpass';"
  193. mysql_query "$query" > /dev/null
  194. query="GRANT ALL ON \`$database\`.* TO \`$dbuser\`@\`%\`"
  195. mysql_query "$query" > /dev/null
  196. query="GRANT ALL ON \`$database\`.* TO \`$dbuser\`@localhost"
  197. mysql_query "$query" > /dev/null
  198. else
  199. query="GRANT ALL ON \`$database\`.* TO \`$dbuser\`@\`%\`
  200. IDENTIFIED BY '$dbpass'"
  201. mysql_query "$query" > /dev/null
  202. query="GRANT ALL ON \`$database\`.* TO \`$dbuser\`@localhost
  203. IDENTIFIED BY '$dbpass'"
  204. mysql_query "$query" > /dev/null
  205. fi
  206. # for mysql 8 this will work only if mysql_native_password is enabled
  207. # Not think yet how to add compatibility for new cached SHA-256 password system
  208. if [ "$(echo $mysql_ver |cut -d '.' -f2)" -ge 7 ] || [ "$(echo $mysql_ver |cut -d '.' -f1)" -eq 8 ]; then
  209. md5=$(mysql_query "SHOW CREATE USER \`$dbuser\`" 2>/dev/null)
  210. md5=$(echo "$md5" |grep password |cut -f8 -d \')
  211. else
  212. md5=$(mysql_query "SHOW GRANTS FOR \`$dbuser\`" 2>/dev/null)
  213. md5=$(echo "$md5" |grep PASSW|tr ' ' '\n' |tail -n1 |cut -f 2 -d \')
  214. fi
  215. }
  216. # Create PostgreSQL database
  217. add_pgsql_database() {
  218. psql_connect $host
  219. query="CREATE ROLE $dbuser WITH LOGIN PASSWORD '$dbpass'"
  220. psql_query "$query" > /dev/null
  221. query="CREATE DATABASE $database OWNER $dbuser"
  222. if [ "$TPL" = 'template0' ]; then
  223. query="$query ENCODING '$charset' TEMPLATE $TPL"
  224. else
  225. query="$query TEMPLATE $TPL"
  226. fi
  227. psql_query "$query" > /dev/null
  228. query="GRANT ALL PRIVILEGES ON DATABASE $database TO $dbuser"
  229. psql_query "$query" > /dev/null
  230. query="GRANT CONNECT ON DATABASE template1 to $dbuser"
  231. psql_query "$query" > /dev/null
  232. query="SELECT rolpassword FROM pg_authid WHERE rolname='$dbuser';"
  233. md5=$(psql_query "$query" | grep md5 | cut -f 2 -d \ )
  234. }
  235. # Check if database host do not exist in config
  236. is_dbhost_new() {
  237. if [ -e "$VESTA/conf/$type.conf" ]; then
  238. check_host=$(grep "HOST='$host'" $VESTA/conf/$type.conf)
  239. if [ ! -z "$check_host" ]; then
  240. echo "Error: db host exist"
  241. log_event "$E_EXISTS" "$ARGUMENTS"
  242. exit $E_EXISTS
  243. fi
  244. fi
  245. }
  246. # Get database values
  247. get_database_values() {
  248. eval $(grep "DB='$database'" $USER_DATA/db.conf)
  249. }
  250. # Change MySQL database password
  251. change_mysql_password() {
  252. mysql_connect $HOST
  253. query="GRANT ALL ON \`$database\`.* TO \`$DBUSER\`@\`%\`
  254. IDENTIFIED BY '$dbpass'"
  255. mysql_query "$query" > /dev/null
  256. query="GRANT ALL ON \`$database\`.* TO \`$DBUSER\`@localhost
  257. IDENTIFIED BY '$dbpass'"
  258. mysql_query "$query" > /dev/null
  259. if [ "$(echo $mysql_ver |cut -d '.' -f2)" -ge 7 ]; then
  260. md5=$(mysql_query "SHOW CREATE USER \`$DBUSER\`" 2>/dev/null)
  261. md5=$(echo "$md5" |grep password |cut -f8 -d \')
  262. else
  263. md5=$(mysql_query "SHOW GRANTS FOR \`$DBUSER\`" 2>/dev/null)
  264. md5=$(echo "$md5" |grep PASSW|tr ' ' '\n' |tail -n1 |cut -f 2 -d \')
  265. fi
  266. }
  267. # Change PostgreSQL database password
  268. change_pgsql_password() {
  269. psql_connect $HOST
  270. query="ALTER ROLE $DBUSER WITH LOGIN PASSWORD '$dbpass'"
  271. psql_query "$query" > /dev/null
  272. query="SELECT rolpassword FROM pg_authid WHERE rolname='$DBUSER';"
  273. md5=$(psql_query "$query" | grep md5 |cut -f 2 -d \ )
  274. }
  275. # Delete MySQL database
  276. delete_mysql_database() {
  277. mysql_connect $HOST
  278. query="DROP DATABASE \`$database\`"
  279. mysql_query "$query" > /dev/null
  280. query="REVOKE ALL ON \`$database\`.* FROM \`$DBUSER\`@\`%\`"
  281. mysql_query "$query" > /dev/null
  282. query="REVOKE ALL ON \`$database\`.* FROM \`$DBUSER\`@localhost"
  283. mysql_query "$query" > /dev/null
  284. if [ "$(grep "DBUSER='$DBUSER'" $USER_DATA/db.conf |wc -l)" -lt 2 ]; then
  285. query="DROP USER '$DBUSER'@'%'"
  286. mysql_query "$query" > /dev/null
  287. query="DROP USER '$DBUSER'@'localhost'"
  288. mysql_query "$query" > /dev/null
  289. fi
  290. }
  291. # Delete PostgreSQL database
  292. delete_pgsql_database() {
  293. psql_connect $HOST
  294. query="REVOKE ALL PRIVILEGES ON DATABASE $database FROM $DBUSER"
  295. psql_qyery "$query" > /dev/null
  296. query="DROP DATABASE $database"
  297. psql_query "$query" > /dev/null
  298. if [ "$(grep "DBUSER='$DBUSER'" $USER_DATA/db.conf |wc -l)" -lt 2 ]; then
  299. query="REVOKE CONNECT ON DATABASE template1 FROM $db_user"
  300. psql_query "$query" > /dev/null
  301. query="DROP ROLE $db_user"
  302. psql_query "$query" > /dev/null
  303. fi
  304. }
  305. # Dump MySQL database
  306. dump_mysql_database() {
  307. mysql_connect $HOST
  308. mysql_dump $dump $database
  309. query="SHOW GRANTS FOR '$DBUSER'@'localhost'"
  310. mysql_query "$query" | grep -v "Grants for" > $grants
  311. query="SHOW GRANTS FOR '$DBUSER'@'%'"
  312. mysql_query "$query" | grep -v "Grants for" > $grants
  313. }
  314. # Dump PostgreSQL database
  315. dump_pgsql_database() {
  316. psql_connect $HOST
  317. psql_dump $dump $database
  318. query="SELECT rolpassword FROM pg_authid WHERE rolname='$DBUSER';"
  319. md5=$(psql_query "$query" | head -n1 | cut -f 2 -d \ )
  320. pw_str="UPDATE pg_authid SET rolpassword='$md5' WHERE rolname='$DBUSER';"
  321. gr_str="GRANT ALL PRIVILEGES ON DATABASE $database to '$DBUSER'"
  322. echo -e "$pw_str\n$gr_str" >> $grants
  323. }
  324. # Check if database server is in use
  325. is_dbhost_free() {
  326. host_str=$(grep "HOST='$host'" $VESTA/conf/$type.conf)
  327. eval $host_str
  328. if [ 0 -ne "$U_DB_BASES" ]; then
  329. echo "Error: host $HOST is used"
  330. log_event "$E_INUSE" "$ARGUMENTS"
  331. exit $E_INUSE
  332. fi
  333. }
  334. # Suspend MySQL database
  335. suspend_mysql_database() {
  336. mysql_connect $HOST
  337. query="REVOKE ALL ON \`$database\`.* FROM \`$DBUSER\`@\`%\`"
  338. mysql_query "$query" > /dev/null
  339. query="REVOKE ALL ON \`$database\`.* FROM \`$DBUSER\`@localhost"
  340. mysql_query "$query" > /dev/null
  341. }
  342. # Suspend PostgreSQL database
  343. suspend_pgsql_database() {
  344. psql_connect $HOST
  345. query="REVOKE ALL PRIVILEGES ON $database FROM $DBUSER"
  346. psql_query "$query" > /dev/null
  347. }
  348. # Unsuspend MySQL database
  349. unsuspend_mysql_database() {
  350. mysql_connect $HOST
  351. query="GRANT ALL ON \`$database\`.* FROM \`$DBUSER\`@\`%\`"
  352. mysql_query "$query" > /dev/null
  353. query="GRANT ALL ON \`$database\`.* TO \`$DBUSER\`@localhost"
  354. mysql_query "$query" > /dev/null
  355. }
  356. # Unsuspend PostgreSQL database
  357. unsuspend_pgsql_database() {
  358. psql_connect $HOST
  359. query="GRANT ALL PRIVILEGES ON DATABASE $database TO $DBUSER"
  360. psql_query "$query" > /dev/null
  361. }
  362. # Get MySQL disk usage
  363. get_mysql_disk_usage() {
  364. mysql_connect $HOST
  365. query="SELECT SUM( data_length + index_length ) / 1024 / 1024 'Size'
  366. FROM information_schema.TABLES WHERE table_schema='$database'"
  367. usage=$(mysql_query "$query" |tail -n1)
  368. if [ "$usage" == '' ] || [ "$usage" == 'NULL' ] || [ "${usage:0:1}" -eq '0' ]; then
  369. usage=1
  370. fi
  371. export LC_ALL=C
  372. usage=$(printf "%0.f\n" $usage)
  373. }
  374. # Get PostgreSQL disk usage
  375. get_pgsql_disk_usage() {
  376. psql_connect $HOST
  377. query="SELECT pg_database_size('$database');"
  378. usage=$(psql_query "$query")
  379. usage=$(echo "$usage" | grep -v "-" | grep -v 'row' | sed "/^$/d")
  380. usage=$(echo "$usage" | grep -v "pg_database_size" | awk '{print $1}')
  381. if [ -z "$usage" ]; then
  382. usage=0
  383. fi
  384. usage=$(($usage / 1048576))
  385. if [ "$usage" -eq '0' ]; then
  386. usage=1
  387. fi
  388. }
  389. # Delete MySQL user
  390. delete_mysql_user() {
  391. mysql_connect $HOST
  392. query="REVOKE ALL ON \`$database\`.* FROM \`$old_dbuser\`@\`%\`"
  393. mysql_query "$query" > /dev/null
  394. query="REVOKE ALL ON \`$database\`.* FROM \`$old_dbuser\`@localhost"
  395. mysql_query "$query" > /dev/null
  396. query="DROP USER '$old_dbuser'@'%'"
  397. mysql_query "$query" > /dev/null
  398. query="DROP USER '$old_dbuser'@'localhost'"
  399. mysql_query "$query" > /dev/null
  400. }
  401. # Delete PostgreSQL user
  402. delete_pgsql_user() {
  403. psql_connect $HOST
  404. query="REVOKE ALL PRIVILEGES ON DATABASE $database FROM $old_dbuser"
  405. psql_query "$query" > /dev/null
  406. query="REVOKE CONNECT ON DATABASE template1 FROM $old_dbuser"
  407. psql_query "$query" > /dev/null
  408. query="DROP ROLE $old_dbuser"
  409. psql_query "$query" > /dev/null
  410. }