diff --git a/evobackup-client/defaults/main.yml b/evobackup-client/defaults/main.yml index e48dc739..24c9402c 100644 --- a/evobackup-client/defaults/main.yml +++ b/evobackup-client/defaults/main.yml @@ -3,6 +3,7 @@ evobackup_client__root_key_path: "/root/.ssh/evobackup_id" evobackup_client__cron_path: "/etc/cron.daily/zzz_evobackup" evobackup_client__cron_template_name: "zzz_evobackup" evobackup_client__mail: null +evobackup_client__servers_fallback: -1 evobackup_client__pid_path: "/var/run/evobackup.pid" evobackup_client__log_path: "/var/log/evobackup.log" evobackup_client__backup_path: "/home/backup" diff --git a/evobackup-client/tasks/jail.yml b/evobackup-client/tasks/jail.yml index 82607705..51080d67 100644 --- a/evobackup-client/tasks/jail.yml +++ b/evobackup-client/tasks/jail.yml @@ -1,17 +1,5 @@ --- -- name: 'create jail' - command: "bkctld init {{ evolinux_hostname }}" - args: - creates: "/backup/jails/{{ evolinux_hostname }}/" - become: true - delegate_to: "{{ evobackup_client__hosts[0].ip }}" - notify: - - 'created new jail' - tags: - - evobackup_client - - evobackup_client_jail - - name: 'create jail' command: "bkctld init {{ evolinux_hostname }}" args: diff --git a/evobackup-client/templates/zzz_evobackup.default.sh.j2 b/evobackup-client/templates/zzz_evobackup.default.sh.j2 index b120d211..5d1c315a 100644 --- a/evobackup-client/templates/zzz_evobackup.default.sh.j2 +++ b/evobackup-client/templates/zzz_evobackup.default.sh.j2 @@ -1,5 +1,4 @@ -#!/bin/sh -# +# Careful, the zzz_evobackup template was last updated on 2020/03/23 # Script Evobackup client # See https://gitea.evolix.org/evolix/evobackup # @@ -15,6 +14,10 @@ # # /!\ DON'T FORGET TO SET "MAIL" and "SERVERS" VARIABLES +# Fail on unassigned variables +set -u + + ##### Configuration ################################################### # email adress for notifications @@ -23,8 +26,11 @@ MAIL={{ evobackup_client__mail }} # list of hosts (hostname or IP) and SSH port for Rsync SERVERS="{% for host in evobackup_client__hosts %}{{ host.name }}:{{ host.port }}{% if loop.index != loop.length %} {% endif %}{% endfor %}" +# Should we fallback on servers when the first is unreachable ? +SERVERS_FALLBACK={{ evobackup_client__servers_fallback }} + # timeout (in seconds) for SSH connections -SSH_CONNECT_TIMEOUT=30 +SSH_CONNECT_TIMEOUT=${SSH_CONNECT_TIMEOUT:-30} ## We use /home/backup : feel free to use your own dir LOCAL_BACKUP_DIR="{{ evobackup_client__backup_path }}" @@ -69,7 +75,7 @@ test_server() { port=$(echo "${item}" | cut -d':' -f2) # Test if the server is accepting connections - ssh -q -o "ConnectTimeout ${SSH_CONNECT_TIMEOUT}" -i /root/.ssh/evobackup_id "${host}" -p "${port}" -t "exit" + ssh -q -o "ConnectTimeout ${SSH_CONNECT_TIMEOUT}" "${host}" -p "${port}" -t "exit" # shellcheck disable=SC2181 if [ $? = 0 ]; then # SSH connection is OK @@ -92,7 +98,10 @@ pick_server() { new_error="No more server available" SERVERS_SSH_ERRORS=$(printf "%s\n%s" "${SERVERS_SSH_ERRORS}" "${new_error}" | sed -e '/^$/d') + # Log errors to stderr printf "%s\n" "${SERVERS_SSH_ERRORS}" >&2 + # Log errors to logfile + printf "%s\n" "${SERVERS_SSH_ERRORS}" >> $LOGFILE return 1 fi @@ -113,123 +122,27 @@ pick_server() { ## Verify other evobackup process and kill if needed if [ -e "${PIDFILE}" ]; then pid=$(cat "${PIDFILE}") - # Killing the childs of evobackup. - for ppid in $(ps h --ppid "${pid}" -o pid | tr -s '\n' ' '); do - kill -9 "${ppid}"; - done - # Then kill the main PID. - kill -9 "${pid}" - printf "%s is still running (PID %s). Process has been killed" "$0" "${pid}\n" >&2 + # Does process still exist ? + if kill -0 ${pid} 2> /dev/null; then + # Killing the childs of evobackup. + for ppid in $(pgrep -P "${pid}"); do + kill -9 "${ppid}"; + done + # Then kill the main PID. + kill -9 "${pid}" + printf "%s is still running (PID %s). Process has been killed" "$0" "${pid}\n" >&2 + else + rm -f ${PIDFILE} + fi fi echo "$$" > ${PIDFILE} # shellcheck disable=SC2064 trap "rm -f ${PIDFILE}" EXIT + ##### LOCAL BACKUP #################################################### if [ "${LOCAL_TASKS}" = "1" ]; then - # You can comment or uncomment sections below to customize the backup - - ## OpenLDAP : example with slapcat - # slapcat -l ${LOCAL_BACKUP_DIR}/ldap.bak - - ### MySQL - - ## example with global and compressed mysqldump - # mysqldump --defaults-extra-file=/etc/mysql/debian.cnf -P 3306 \ - # --opt --all-databases --force --events --hex-blob | gzip --best > ${LOCAL_BACKUP_DIR}/mysql.bak.gz - - ## example with two dumps for each table (.sql/.txt) for all databases - # for i in $(echo SHOW DATABASES | mysql --defaults-extra-file=/etc/mysql/debian.cnf -P 3306 \ - # | egrep -v "^(Database|information_schema|performance_schema|sys)" ); \ - # do mkdir -p -m 700 /home/mysqldump/$i ; chown -RL mysql /home/mysqldump ; \ - # mysqldump --defaults-extra-file=/etc/mysql/debian.cnf --force -P 3306 -Q --opt --events --hex-blob --skip-comments \ - # --fields-enclosed-by='\"' --fields-terminated-by=',' -T /home/mysqldump/$i $i; done - - ## example with compressed SQL dump for each databases - # mkdir -p -m 700 /home/mysqldump/ - # for i in $(mysql --defaults-extra-file=/etc/mysql/debian.cnf -P 3306 -e 'show databases' -s --skip-column-names \ - # | egrep -v "^(Database|information_schema|performance_schema|sys)"); do - # mysqldump --defaults-extra-file=/etc/mysql/debian.cnf --force -P 3306 --events --hex-blob $i | gzip --best > /home/mysqldump/${i}.sql.gz - # done - - ## example with *one* uncompressed SQL dump for *one* database (MYBASE) - # mkdir -p -m 700 /home/mysqldump/MYBASE - # chown -RL mysql /home/mysqldump/ - # mysqldump --defaults-extra-file=/etc/mysql/debian.cnf --force -Q \ - # --opt --events --hex-blob --skip-comments -T /home/mysqldump/MYBASE MYBASE - - ## example with mysqlhotcopy - # mkdir -p -m 700 /home/mysqlhotcopy/ - # mysqlhotcopy BASE /home/mysqlhotcopy/ - - ## example for multiples MySQL instances - # mysqladminpasswd=$(grep -m1 'password = .*' /root/.my.cnf|cut -d" " -f3) - # grep -E "^port\s*=\s*\d*" /etc/mysql/my.cnf |while read instance; do - # instance=$(echo "$instance"|awk '{ print $3 }') - # if [ "$instance" != "3306" ] - # then - # mysqldump -P $instance --opt --all-databases --hex-blob -u mysqladmin -p$mysqladminpasswd > ${LOCAL_BACKUP_DIR}/mysql.$instance.bak - # fi - # done - - ### PostgreSQL - - ## example with pg_dumpall (warning: you need space in ~postgres) - # su - postgres -c "pg_dumpall > ~/pg.dump.bak" - # mv ~postgres/pg.dump.bak ${LOCAL_BACKUP_DIR}/ - ## another method with gzip directly piped - # cd /var/lib/postgresql - # sudo -u postgres pg_dumpall | gzip > ${LOCAL_BACKUP_DIR}/pg.dump.bak.gz - # cd - > /dev/null - - ## example with all tables from MYBASE excepts TABLE1 and TABLE2 - # pg_dump -p 5432 -h 127.0.0.1 -U USER --clean -F t --inserts -f ${LOCAL_BACKUP_DIR}/pg-backup.tar -t 'TABLE1' -t 'TABLE2' MYBASE - - ## example with only TABLE1 and TABLE2 from MYBASE - # pg_dump -p 5432 -h 127.0.0.1 -U USER --clean -F t --inserts -f ${LOCAL_BACKUP_DIR}/pg-backup.tar -T 'TABLE1' -T 'TABLE2' MYBASE - - ## MongoDB : example with mongodump - ## don't forget to create use with read-only access - ## > use admin - ## > db.createUser( { user: "mongobackup", pwd: "PASS", roles: [ "backup", ] } ) - # test -d ${LOCAL_BACKUP_DIR}/mongodump/ && rm -rf ${LOCAL_BACKUP_DIR}/mongodump/ - # mkdir -p -m 700 ${LOCAL_BACKUP_DIR}/mongodump/ - # mongodump --quiet -u mongobackup -pPASS -o ${LOCAL_BACKUP_DIR}/mongodump/ - # if [ $? -ne 0 ]; then - # echo "Error with mongodump!" - # fi - - ## Redis : example with copy .rdb file - # cp /var/lib/redis/dump.rdb ${LOCAL_BACKUP_DIR}/ - - ## ElasticSearch, take a snapshot as a backup. - ## Warning: You need to have a path.repo configured. - ## See: https://wiki.evolix.org/HowtoElasticsearch#snapshots-et-sauvegardes - # curl -s -XDELETE "localhost:9200/_snapshot/snaprepo/snapshot.daily" -o /tmp/es_delete_snapshot.daily.log - # curl -s -XPUT "localhost:9200/_snapshot/snaprepo/snapshot.daily?wait_for_completion=true" -o /tmp/es_snapshot.daily.log - ## Clustered version here - ## It basically the same thing except that you need to check that NFS is mounted - # if ss | grep ':nfs' | grep -q 'ip\.add\.res\.s1' && ss | grep ':nfs' | grep -q 'ip\.add\.res\.s2' - # then - # curl -s -XDELETE "localhost:9200/_snapshot/snaprepo/snapshot.daily" -o /tmp/es_delete_snapshot.daily.log - # curl -s -XPUT "localhost:9200/_snapshot/snaprepo/snapshot.daily?wait_for_completion=true" -o /tmp/es_snapshot.daily.log - # else - # echo 'Cannot make a snapshot of elasticsearch, at least one node is not mounting the repository.' - # fi - ## If you need to keep older snapshot, for example the last 10 daily snapshots, replace the XDELETE and XPUT lines by : - # for snapshot in $(curl -s -XGET "localhost:9200/_snapshot/snaprepo/_all?pretty=true" | grep -Eo 'snapshot_[0-9]{4}-[0-9]{2}-[0-9]{2}' | head -n -10); do - # curl -s -XDELETE "localhost:9200/_snapshot/snaprepo/${snapshot}" | grep -v -Fx '{"acknowledged":true}' - # done - # date=$(date +%F) - # curl -s -XPUT "localhost:9200/_snapshot/snaprepo/snapshot_${date}?wait_for_completion=true" -o /tmp/es_snapshot_${date}.log - - ## RabbitMQ : export config - #rabbitmqadmin export ${LOCAL_BACKUP_DIR}/rabbitmq.config >> $LOGFILE - - # backup MegaCli config - #megacli -CfgSave -f ${LOCAL_BACKUP_DIR}/megacli_conf.dump -a0 >/dev/null - ## Dump system and kernel versions uname -a > ${LOCAL_BACKUP_DIR}/uname @@ -242,51 +155,55 @@ if [ "${LOCAL_TASKS}" = "1" ]; then ## Dump process with ps ps auwwx >${LOCAL_BACKUP_DIR}/ps.out - if [ "${SYSTEM}" = "linux" ]; then - ## Dump network connections with ss - ss -taupen > ${LOCAL_BACKUP_DIR}/netstat.out + ## Dump network connections with ss + ss -taupen > ${LOCAL_BACKUP_DIR}/netstat.out - ## List Debian packages - dpkg -l > ${LOCAL_BACKUP_DIR}/packages - dpkg --get-selections > ${LOCAL_BACKUP_DIR}/packages.getselections - apt-cache dumpavail > ${LOCAL_BACKUP_DIR}/packages.available + ## List Debian packages + dpkg -l > ${LOCAL_BACKUP_DIR}/packages + dpkg --get-selections > ${LOCAL_BACKUP_DIR}/packages.getselections + apt-cache dumpavail > ${LOCAL_BACKUP_DIR}/packages.available - ## Dump MBR / table partitions - disks=$(find /dev/ -regex '/dev/\([sv]d[a-z]\|nvme[0-9]+n[0-9]+\)') - for disk in ${disks}; do - name=$(basename "${disk}") - dd if="${disk}" of="${LOCAL_BACKUP_DIR}/MBR-${name}" bs=512 count=1 2>&1 | egrep -v "(records in|records out|512 bytes)" - fdisk -l "${disk}" > "${LOCAL_BACKUP_DIR}/partitions-${name}" - done - cat ${LOCAL_BACKUP_DIR}/partitions-* > ${LOCAL_BACKUP_DIR}/partitions - else - ## Dump network connections with netstat - netstat -finet -atn > ${LOCAL_BACKUP_DIR}/netstat.out + ## Dump MBR / table partitions + disks=$(lsblk -l | grep disk | grep -v -E '(drbd|fd[0-9]+)' | awk '{print $1}') + for disk in ${disks}; do + dd if="/dev/${disk}" of="${LOCAL_BACKUP_DIR}/MBR-${disk}" bs=512 count=1 2>&1 | grep -Ev "(records in|records out|512 bytes)" + fdisk -l "/dev/${disk}" > "${LOCAL_BACKUP_DIR}/partitions-${disk}" 2>&1 + done + cat ${LOCAL_BACKUP_DIR}/partitions-* > ${LOCAL_BACKUP_DIR}/partitions - ## List OpenBSD packages - pkg_info -m > ${LOCAL_BACKUP_DIR}/packages - - ## Dump MBR / table partitions - ##disklabel sd0 > ${LOCAL_BACKUP_DIR}/partitions + ## Dump iptables + if [ -x /sbin/iptables ]; then + { /sbin/iptables -L -n -v; /sbin/iptables -t filter -L -n -v; } > ${LOCAL_BACKUP_DIR}/iptables.txt fi + ## Dump findmnt(8) output + FINDMNT_BIN=$(command -v findmnt) + if [ -x ${FINDMNT_BIN} ]; then + ${FINDMNT_BIN} > ${LOCAL_BACKUP_DIR}/findmnt.txt + fi fi ##### REMOTE BACKUP ################################################### n=0 server="" -while :; do - server=$(pick_server "${n}") - test $? = 0 || exit 2 +if [ "${SERVERS_FALLBACK}" = "1" ]; then + # We try to find a suitable server + while :; do + server=$(pick_server "${n}") + test $? = 0 || exit 2 - if test_server "${server}"; then - break - else - server="" - n=$(( n + 1 )) - fi -done + if test_server "${server}"; then + break + else + server="" + n=$(( n + 1 )) + fi + done +else + # we force the server + server=$(pick_server "${n}") +fi SSH_SERVER=$(echo "${server}" | cut -d':' -f1) SSH_PORT=$(echo "${server}" | cut -d':' -f2) @@ -341,8 +258,6 @@ if [ "${SYNC_TASKS}" = "1" ]; then /etc \ /root \ /var \ - /home \ - /srv \ -e "${RSH_COMMAND}" \ "root@${SSH_SERVER}:/var/backup/" \ | tail -30 >> $LOGFILE @@ -362,4 +277,4 @@ printf "EvoBackup - %s - STOP %s ON %s (LOCAL_TASKS=%s SYNC_TASKS=%s)\n" \ tail -10 $LOGFILE | \ mail -s "[info] EvoBackup - Client ${HOSTNAME}" \ - ${MAIL} + ${MAIL} \ No newline at end of file