diff --git a/README.md b/README.md index acd8ce4..6496e64 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,8 @@ Custom backup script The custom script : - copy & compress the entire system - extract informations from your system (packages list, crontab, partition table, etc) - - can dump MySQL database(s) - - can dump MariaDB database(s) + - can dump MySQL database(s), including routines/events/triggers + - can dump MariaDB database(s), including routines/events/triggers - can dump PostgreSQL database(s) All files are then send it to a custom Proxmox Backup Server. @@ -39,9 +39,24 @@ Role variables | backup_local_retention | string | | | mandatory | | backup_path_include | list | | | | | backup_path_exclude | list | | | | -| backup_mysql_enabled | boolean | | | uses mysqldump | -| backup_mariadb_enabled | boolean | | | uses mariadb-dump | +| backup_mysql_enabled | boolean | | | uses mysqldump with routines/events/triggers | +| backup_mysql_host | string | | | optional | +| backup_mysql_user | string | | | optional | +| backup_mysql_password | string | | | optional | +| backup_mysql_docker_enabled | boolean | | false | run mysql in docker | +| backup_mysql_docker_container | string | | | required if docker enabled | +| backup_mariadb_enabled | boolean | | | uses mariadb-dump with routines/events/triggers | +| backup_mariadb_host | string | | | optional | +| backup_mariadb_user | string | | | optional | +| backup_mariadb_password | string | | | optional | +| backup_mariadb_docker_enabled | boolean | | false | run mariadb in docker | +| backup_mariadb_docker_container | string | | | required if docker enabled | | backup_pgsql_enabled | boolean | | | | +| backup_pg_host | string | | | optional | +| backup_pg_user | string | | | optional | +| backup_pg_password | string | | | optional | +| backup_pg_docker_enabled | boolean | | false | run postgresql in docker | +| backup_pg_docker_container| string | | | required if docker enabled | | backup_cron_minute | int | | | | | backup_cron_hour | int | | | | @@ -85,8 +100,25 @@ backup_path_exclude: - cache/ backup_mysql_enabled: true +backup_mysql_host: '' +backup_mysql_user: '' +backup_mysql_password: '' +backup_mysql_docker_enabled: false +backup_mysql_docker_container: '' + backup_mariadb_enabled: true +backup_mariadb_host: '' +backup_mariadb_user: '' +backup_mariadb_password: '' +backup_mariadb_docker_enabled: true +backup_mariadb_docker_container: 'mariadb' + backup_pgsql_enabled: true +backup_pg_host: '' +backup_pg_user: '' +backup_pg_password: '' +backup_pg_docker_enabled: false +backup_pg_docker_container: '' backup_cron_minute: 30 backup_cron_hour: 5 diff --git a/defaults/main.yml b/defaults/main.yml index d107f74..138628f 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,3 +1,21 @@ --- pbs_repo_key: "https://enterprise.proxmox.com/debian/proxmox-release-{{ ansible_distribution_release }}.gpg" pbs_repo_no_subscription: "deb [signed-by=/etc/apt/trusted.gpg.d/proxmox-release-{{ ansible_distribution_release }}.gpg] http://download.proxmox.com/debian/pbs-client {{ ansible_distribution_release }} main" + +backup_mysql_host: "" +backup_mysql_user: "" +backup_mysql_password: "" +backup_mysql_docker_enabled: false +backup_mysql_docker_container: "" + +backup_mariadb_host: "" +backup_mariadb_user: "" +backup_mariadb_password: "" +backup_mariadb_docker_enabled: false +backup_mariadb_docker_container: "" + +backup_pg_host: "" +backup_pg_user: "" +backup_pg_password: "" +backup_pg_docker_enabled: false +backup_pg_docker_container: "" diff --git a/templates/brain_backup.j2 b/templates/brain_backup.j2 index 6064f03..f2889f1 100644 --- a/templates/brain_backup.j2 +++ b/templates/brain_backup.j2 @@ -58,24 +58,70 @@ done {% if backup_mysql_enabled is sameas true %} ## mysql ## -mysql_databases=`/usr/bin/mysql -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema)"` +backup_mysql_host="{{ backup_mysql_host | default('') }}" +backup_mysql_user="{{ backup_mysql_user | default('') }}" +backup_mysql_password="{{ backup_mysql_password | default('') }}" +backup_mysql_docker_enabled="{{ (backup_mysql_docker_enabled | default(false)) | ternary('true', 'false') }}" +backup_mysql_docker_container="{{ backup_mysql_docker_container | default('') }}" + +mysql_cmd=(/usr/bin/mysql) +mysqldump_cmd=(/usr/bin/mysqldump) + +if [ "$backup_mysql_docker_enabled" = "true" ]; then + if [ -z "$backup_mysql_docker_container" ]; then + echo "MySQL Docker mode enabled but container name is empty: exiting." + exit 1 + fi + mysql_cmd=(/usr/bin/docker exec -i "$backup_mysql_docker_container" mysql) + mysqldump_cmd=(/usr/bin/docker exec -i "$backup_mysql_docker_container" mysqldump) +fi + +mysql_connection_args=() +[ -n "$backup_mysql_host" ] && mysql_connection_args+=("--host=$backup_mysql_host") +[ -n "$backup_mysql_user" ] && mysql_connection_args+=("--user=$backup_mysql_user") +[ -n "$backup_mysql_password" ] && mysql_connection_args+=("--password=$backup_mysql_password") + +mysql_databases=$("${mysql_cmd[@]}" "${mysql_connection_args[@]}" -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema)") mkdir -p $backup_dir/$today/mysql for db in $mysql_databases; - do mysqldump -e -q -Q --single-transaction $db | gzip -c > $backup_dir/$today/mysql/dump_$db.sql.gz; + do "${mysqldump_cmd[@]}" "${mysql_connection_args[@]}" -e -q -Q --single-transaction --routines --events --triggers "$db" | gzip -c > $backup_dir/$today/mysql/dump_$db.sql.gz; done ## end of mysql ## {% endif %} {% if backup_mariadb_enabled is sameas true %} ## mariadb ## -mariadb_databases=`/usr/bin/mariadb -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema)"` +backup_mariadb_host="{{ backup_mariadb_host | default('') }}" +backup_mariadb_user="{{ backup_mariadb_user | default('') }}" +backup_mariadb_password="{{ backup_mariadb_password | default('') }}" +backup_mariadb_docker_enabled="{{ (backup_mariadb_docker_enabled | default(false)) | ternary('true', 'false') }}" +backup_mariadb_docker_container="{{ backup_mariadb_docker_container | default('') }}" + +mariadb_cmd=(/usr/bin/mariadb) +mariadbdump_cmd=(/usr/bin/mariadb-dump) + +if [ "$backup_mariadb_docker_enabled" = "true" ]; then + if [ -z "$backup_mariadb_docker_container" ]; then + echo "MariaDB Docker mode enabled but container name is empty: exiting." + exit 1 + fi + mariadb_cmd=(/usr/bin/docker exec -i "$backup_mariadb_docker_container" mariadb) + mariadbdump_cmd=(/usr/bin/docker exec -i "$backup_mariadb_docker_container" mariadb-dump) +fi + +mariadb_connection_args=() +[ -n "$backup_mariadb_host" ] && mariadb_connection_args+=("--host=$backup_mariadb_host") +[ -n "$backup_mariadb_user" ] && mariadb_connection_args+=("--user=$backup_mariadb_user") +[ -n "$backup_mariadb_password" ] && mariadb_connection_args+=("--password=$backup_mariadb_password") + +mariadb_databases=$("${mariadb_cmd[@]}" "${mariadb_connection_args[@]}" -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema)") mkdir -p $backup_dir/$today/mariadb for db in $mariadb_databases; - do mariadb-dump -e -q -Q --single-transaction $db | gzip -c > $backup_dir/$today/mariadb/dump_$db.sql.gz; + do "${mariadbdump_cmd[@]}" "${mariadb_connection_args[@]}" -e -q -Q --single-transaction --routines --events --triggers "$db" | gzip -c > $backup_dir/$today/mariadb/dump_$db.sql.gz; done ## end of mariadb ## {% endif %} @@ -83,16 +129,73 @@ done {% if backup_pgsql_enabled is sameas true %} ## postgresql ## pg_port={{ backup_pg_port | default('5432') }} -pg_databases=`sudo su - postgres -c "/usr/bin/psql -p $pg_port -t -c 'SELECT datname FROM pg_database'"|grep -v "template0"` - mkdir -p $backup_dir/$today/postgresql -chown -R postgres: $backup_dir/$today/postgresql +backup_pg_host="{{ backup_pg_host | default('') }}" +backup_pg_user="{{ backup_pg_user | default('') }}" +backup_pg_password="{{ backup_pg_password | default('') }}" +backup_pg_docker_enabled="{{ (backup_pg_docker_enabled | default(false)) | ternary('true', 'false') }}" +backup_pg_docker_container="{{ backup_pg_docker_container | default('') }}" -for db in $pg_databases; - do sudo su - postgres -c "/usr/bin/pg_dump -p $pg_port -Z9 -Fc -b -f $backup_dir/$today/postgresql/dump_$db.sql $db"; -done +if [ "$backup_pg_docker_enabled" = "true" ]; then + if [ -z "$backup_pg_docker_container" ]; then + echo "PostgreSQL Docker mode enabled but container name is empty: exiting." + exit 1 + fi -sudo su - postgres -c "/usr/bin/pg_dumpall --roles-only > $backup_dir/$today/postgresql/role.sql" + pg_connection_args=("-p" "$pg_port") + [ -n "$backup_pg_host" ] && pg_connection_args+=("-h" "$backup_pg_host") + [ -n "$backup_pg_user" ] && pg_connection_args+=("-U" "$backup_pg_user") + + if [ -n "$backup_pg_password" ]; then + pg_databases=$(/usr/bin/docker exec -e PGPASSWORD="$backup_pg_password" -i "$backup_pg_docker_container" psql "${pg_connection_args[@]}" -At -c "SELECT datname FROM pg_database WHERE datistemplate = false;") + else + pg_databases=$(/usr/bin/docker exec -i "$backup_pg_docker_container" psql "${pg_connection_args[@]}" -At -c "SELECT datname FROM pg_database WHERE datistemplate = false;") + fi + + for db in $pg_databases; do + if [ -n "$backup_pg_password" ]; then + /usr/bin/docker exec -e PGPASSWORD="$backup_pg_password" -i "$backup_pg_docker_container" pg_dump "${pg_connection_args[@]}" -Z9 -Fc -b "$db" > "$backup_dir/$today/postgresql/dump_$db.sql" + else + /usr/bin/docker exec -i "$backup_pg_docker_container" pg_dump "${pg_connection_args[@]}" -Z9 -Fc -b "$db" > "$backup_dir/$today/postgresql/dump_$db.sql" + fi + done + + if [ -n "$backup_pg_password" ]; then + /usr/bin/docker exec -e PGPASSWORD="$backup_pg_password" -i "$backup_pg_docker_container" pg_dumpall "${pg_connection_args[@]}" --roles-only > "$backup_dir/$today/postgresql/role.sql" + else + /usr/bin/docker exec -i "$backup_pg_docker_container" pg_dumpall "${pg_connection_args[@]}" --roles-only > "$backup_dir/$today/postgresql/role.sql" + fi +elif [ -n "$backup_pg_host" ] || [ -n "$backup_pg_user" ] || [ -n "$backup_pg_password" ]; then + pg_connection_args=("-p" "$pg_port") + [ -n "$backup_pg_host" ] && pg_connection_args+=("-h" "$backup_pg_host") + [ -n "$backup_pg_user" ] && pg_connection_args+=("-U" "$backup_pg_user") + + if [ -n "$backup_pg_password" ]; then + export PGPASSWORD="$backup_pg_password" + fi + + pg_databases=$(/usr/bin/psql "${pg_connection_args[@]}" -At -c "SELECT datname FROM pg_database WHERE datistemplate = false;") + + for db in $pg_databases; do + /usr/bin/pg_dump "${pg_connection_args[@]}" -Z9 -Fc -b -f "$backup_dir/$today/postgresql/dump_$db.sql" "$db" + done + + /usr/bin/pg_dumpall "${pg_connection_args[@]}" --roles-only > "$backup_dir/$today/postgresql/role.sql" + + if [ -n "$backup_pg_password" ]; then + unset PGPASSWORD + fi +else + chown -R postgres: $backup_dir/$today/postgresql + + pg_databases=`sudo su - postgres -c "/usr/bin/psql -p $pg_port -t -c 'SELECT datname FROM pg_database'"|grep -v "template0"` + + for db in $pg_databases; + do sudo su - postgres -c "/usr/bin/pg_dump -p $pg_port -Z9 -Fc -b -f $backup_dir/$today/postgresql/dump_$db.sql $db"; + done + + sudo su - postgres -c "/usr/bin/pg_dumpall --roles-only > $backup_dir/$today/postgresql/role.sql" +fi ## end of postresql ## {% endif %}