@@ -19,14 +19,17 @@ check_needs() {
1919 PKG_MANAGER=" apt-get"
2020 PKG_UPDATE=" $PKG_MANAGER update -y"
2121 PKG_INSTALL=" $PKG_MANAGER install -y"
22+ MYSQL_CLIENT_PKG=" mysql-client"
2223 elif command -v dnf & > /dev/null; then
2324 PKG_MANAGER=" dnf"
2425 PKG_UPDATE=" $PKG_MANAGER check-update"
2526 PKG_INSTALL=" $PKG_MANAGER install -y"
27+ MYSQL_CLIENT_PKG=" mysql"
2628 elif command -v yum & > /dev/null; then
2729 PKG_MANAGER=" yum"
2830 PKG_UPDATE=" $PKG_MANAGER check-update"
2931 PKG_INSTALL=" $PKG_MANAGER install -y"
32+ MYSQL_CLIENT_PKG=" mysql"
3033 else
3134 error " No supported package manager found. Please install packages manually."
3235 exit 1
@@ -36,7 +39,7 @@ check_needs() {
3639 $PKG_UPDATE || true
3740
3841 packages_to_install=()
39- for pkg in curl wget zip cron; do
42+ for pkg in curl wget zip cron $MYSQL_CLIENT_PKG ; do
4043 if ! command -v $pkg & > /dev/null; then
4144 log " Need to install $pkg "
4245 packages_to_install+=($pkg )
@@ -94,14 +97,20 @@ check_needs() {
9497 systemctl enable cron || { error " Failed to enable cron service." ; exit 1; }
9598 fi
9699
100+ # Verify mysqldump installation
101+ if ! command -v mysqldump & > /dev/null; then
102+ error " mysqldump is not installed. Please check your MySQL client installation."
103+ exit 1
104+ fi
105+
97106 success " All necessary packages are installed and cron service is running."
98107 sleep 1
99108}
100109
101110menu () {
102111 while true ; do
103112 print " \n\t Welcome to Backuper!"
104- print " \t\t version 0.2.0 by @ErfJab"
113+ print " \t\t version 0.2.1 by @ErfJab"
105114 print " —————————————————————————————————————————————————————————————————————————"
106115 print " 1) Install"
107116 print " 2) Manage"
@@ -180,7 +189,8 @@ backup_template() {
180189 print " 2) Marzban Logs"
181190 print " 3) All X-ui's"
182191 print " 4) Hiddify Manager"
183- print " 5) Mirza Bot"
192+ print " 5) Marzneshin"
193+ print " 6) Mirza Bot"
184194 print " 0) Custom"
185195 print " "
186196
@@ -205,6 +215,10 @@ backup_template() {
205215 break
206216 ;;
207217 5)
218+ marzneshin_template
219+ break
220+ ;;
221+ 6)
208222 mirzabot_template
209223 break
210224 ;;
@@ -219,6 +233,87 @@ backup_template() {
219233 done
220234}
221235
236+ marzneshin_template () {
237+ log " Checking Marzneshin configuration..."
238+ local docker_compose_file=" /etc/opt/marzneshin/docker-compose.yml"
239+
240+ if [ ! -f " $docker_compose_file " ]; then
241+ error " Docker compose file not found: $docker_compose_file "
242+ exit 1
243+ else
244+ success " Docker compose file found: $docker_compose_file "
245+ fi
246+
247+ log " Analyzing Marzneshin database configuration..."
248+ local db_type=$( yq eval ' .services.db.image' " $docker_compose_file " )
249+ local db_name=$( yq eval ' .services.db.environment.MARIADB_DATABASE // .services.db.environment.MYSQL_DATABASE' " $docker_compose_file " )
250+ local db_password=$( yq eval ' .services.db.environment.MARIADB_ROOT_PASSWORD // .services.db.environment.MYSQL_ROOT_PASSWORD' " $docker_compose_file " )
251+ local db_port=$( yq eval ' .services.db.ports[0]' " $docker_compose_file " | cut -d' :' -f2)
252+
253+ if [[ " $db_type " == * " mariadb" * ]]; then
254+ success " Database type: MariaDB"
255+ elif [[ " $db_type " == * " mysql" * ]]; then
256+ success " Database type: MySQL"
257+ else
258+ error " Unsupported database type: $db_type "
259+ exit 1
260+ fi
261+
262+ success " Database name: $db_name "
263+ success " Database port: $db_port "
264+
265+ if [ -z " $db_password " ]; then
266+ error " Database password not found in docker-compose.yml"
267+ exit 1
268+ else
269+ success " Database password found"
270+ fi
271+
272+ log " Setting up backup for Marzneshin database..."
273+ local db_backup_path=" /root/${name} _marzneshin_db_backup.sql"
274+ mysql_database[" marzneshin" ]=" marzneshin:${db_name} :${db_password} :${db_port} "
275+
276+ log " Adding Marzneshin directories to backup list..."
277+ directories=()
278+
279+ add_directories () {
280+ local base_dir=" $1 "
281+ while IFS= read -r -d ' ' item; do
282+ if [[ ! " $item " =~ /mysql ]]; then
283+ success " $item "
284+ directories+=(" $item " )
285+ fi
286+ done < <( find " $base_dir " -mindepth 1 -print0)
287+ }
288+
289+ log " Scanning volume: /var/lib/marzneshin"
290+ add_directories " /var/lib/marzneshin"
291+
292+ log " Scanning volume: /etc/opt/marzneshin"
293+ add_directories " /etc/opt/marzneshin"
294+
295+ log " Listing volumes from docker-compose..."
296+ services=$( yq eval ' .services | keys | .[]' " $docker_compose_file " )
297+ for service in $services ; do
298+ volumes=$( yq eval " .services.$service .volumes | .[]" " $docker_compose_file " 2> /dev/null | awk -F ' :' ' {print $1}' )
299+ if [ -n " $volumes " ]; then
300+ for volume in $volumes ; do
301+ if [[ -d " $volume " && ! " $volume " =~ /mysql && ! " $volume " =~ /mariadb ]]; then
302+ log " Scanning volume: $volume for service: $service "
303+ add_directories " $volume "
304+ elif [[ -d " $volume " ]]; then
305+ log " Skipping database volume: $volume for service: $service "
306+ else
307+ error " Volume $volume for service $service does not exist or is not a directory."
308+ fi
309+ done
310+ fi
311+ done
312+
313+ success " Marzneshin backup configuration complete"
314+ sleep 2
315+ }
316+
222317mirzabot_template () {
223318 log " Checking mirzabot backup..."
224319 local mirzabot_file=' /var/www/html/mirzabotconfig/config.php'
@@ -251,7 +346,6 @@ mirzabot_template() {
251346 fi
252347}
253348
254-
255349hiddify_template () {
256350 log " Checking hiddify backup..."
257351 local hiddify_file=" /opt/hiddify-manager/hiddify-panel/backup.sh"
@@ -695,13 +789,22 @@ backup_generate() {
695789 local DB=" "
696790 if [ ${# mysql_database[@]} -gt 0 ]; then
697791 for database in " ${mysql_database[@]} " ; do
698- IFS=' :' read -r service_name db_name db_password <<< " $database"
792+ IFS=' :' read -r service_name db_name db_password db_port <<< " $database"
699793 local db_address=" /root/${name} _${db_name} _backuper.sql"
700- local dump_command=" if ! docker exec marzban-mysql-1 mysqldump -u root -p'${db_password} ' '${db_name} ' > '${db_address} '; then
794+ local dump_command
795+ if [ " $service_name " == " marzneshin" ]; then
796+ dump_command=" if ! mysqldump -h 127.0.0.1 -P ${db_port} -u root -p'${db_password} ' --column-statistics=0 '${db_name} ' > '${db_address} '; then
797+ message=\" Failed to backup Marzneshin database ${db_name} . Please check the server.\"
798+ $send_notification_command
799+ exit 1
800+ fi"
801+ else
802+ dump_command=" if ! docker exec marzban-mysql-1 mysqldump -u root -p'${db_password} ' '${db_name} ' > '${db_address} '; then
701803 message=\" Failed to backup database ${db_name} . Please check the server.\"
702804 $send_notification_command
703805 exit 1
704806fi"
807+ fi
705808 DB+=" ${dump_command} \n"
706809 directories+=(" $db_address " )
707810 done
0 commit comments