From 61e84836731048d7e8b8158a901c96cbdc6d9766 Mon Sep 17 00:00:00 2001 From: Valentin Lab Date: Thu, 8 Apr 2021 05:57:43 +0200 Subject: [PATCH] new: [vps] common backup process between ``mailcow`` and ``compose`` installs Signed-off-by: Valentin Lab --- README.org | 85 +++++++++++----------- bin/myc-check-and-launch-backup | 30 -------- bin/vps | 125 +++++++++++++++++++++++++++++++- 3 files changed, 163 insertions(+), 77 deletions(-) delete mode 100755 bin/myc-check-and-launch-backup diff --git a/README.org b/README.org index a3a9519..a7e4be4 100644 --- a/README.org +++ b/README.org @@ -719,55 +719,52 @@ export MYSQL_CONTAINER=mailcowdockerized_mysql-mailcow_1 *** rsync-backup -**** Installation du backup via compose +**** Installation du backup via compose / mailcow -A faire depuis le serveur ayant des services géré par =compose= à +- un serveur =compose= est un serveur ayant des services géré par =compose= à backupper. +- un serveur =mailcow= est un serveur faisant tourner l'installation =mailcow=. -#+begin_src sh -DOMAIN=xxx.fr +A faire depuis le serveur compose ou mailcow: -## CODE -BACKUP_SERVER=core-06.0k.io:10023 +#+begin_src sh +vps install backup core-06.0k.io:10023 +#+end_src -ssh-keygen -t rsa -N "" -f /root/.ssh/rsync_rsa -C "rsync@$DOMAIN" -cat <> /opt/apps/myc-deploy/compose.yml +Ici =core-06.0k.io:10023= est le serveur cible d'archivage (à modifier +si nécessaire). -rsync-backup: - options: - ident: $DOMAIN - target: $BACKUP_SERVER - private-key: | -$(cat /root/.ssh/rsync_rsa | sed -r 's/^/ /g') -EOF +A la fin de l'opération, une commande est proposée pour ajouter +facilement la nouvelle clé à l'hôte s'occupant de l'archivage. -dest="$BACKUP_SERVER" -dest="${dest%/*}" -dest="${dest%%:*}" -echo "Contacting '$dest' host, to add key in authorized key:" -ssh -o "StrictHostKeyChecking=no" "root@${dest}" -- compose-add-rsync-key -R "\"$DOMAIN\"" "\"$(cat /root/.ssh/rsync_rsa.pub)\"" +Cette commande doit être executée sur le serveur d'archivage et suivie +d'un =compose up=. Plusieurs clés peuvent être ajoutée avant de +redémarrer le service d'archivage du coté du serveur. +Dans le cas d'un VPS sur installation compose, il s'agira également de +relancer sur le =vps= lui-même, un =compose up= pour intégrer et +lancer le nouveau container de backup. -#+end_src +Une fois la clé enregistrée du coté du serveur d'archivage, un premier +archivage peut être déclenché via: -**** Installation du backup sur une installe mailcow +#+begin_quote +vps backup +#+end_quote -Le script suivant va s'occuper de tout, il doit être lancé -depuis l'hôte faisant tourner l'installation =mailcow=. +Ceci permet de lancer le premier backup et de valider que tout fonctionne -#+begin_src sh -mailcow-backup-install -#+end_src **** Installation du backup sur un host debian Cela fonctionnera sur tout host ayant une base debian. #+begin_src sh -export DOMAIN=mail.myceliandre.fr -export BACKUP_SERVER=core-06.0k.io:10023 +DOMAIN=mail.xxxx.fr +BACKUP_SERVER=core-06.0k.io:10023 -/srv/charm-store/rsync-backup/hooks/install.d/60-install.sh +cd /srv/charm-store/rsync-backup/ +./hooks/install.d/60-install.sh #+end_src @@ -775,22 +772,22 @@ Note, il est possible de spécifier des exclusions pour chaque répértoire mirroré de telle façon: #+begin_src sh -cat < /etc/mirror-dir/config.yml +cat <> /etc/mirror-dir/config.yml /home: - exclude: - - /*/.cache/ - - /*/.gvfs/ - - /*/.local/share/Trash/files/ - - /*/.Trash/ - - /*/.mozilla/firefox/*/Cache/ - - /*/.mozilla/firefox/*/storage/default/*/cache/ + exclude: + - /*/.cache/ + - /*/.gvfs/ + - /*/.local/share/Trash/files/ + - /*/.Trash/ + - /*/.mozilla/firefox/*/Cache/ + - /*/.mozilla/firefox/*/storage/default/*/cache/ /media/data: - exclude: - - /binary/games/_steam - - /incoming - - /.Trash* - - /lost+found - - /backup/device + exclude: + - /binary/games/_steam + - /incoming + - /.Trash* + - /lost+found + - /backup/device EOF #+end_src diff --git a/bin/myc-check-and-launch-backup b/bin/myc-check-and-launch-backup deleted file mode 100755 index 3edac4c..0000000 --- a/bin/myc-check-and-launch-backup +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -## -## Quick and dirty check launching backup -## - -if ! cron_line=$(docker exec myc_cron_1 cat /etc/cron.d/rsync-backup | grep "\* \* \*"); then - echo "can't find cron_line in cron container." >&2 - exit 1 -fi - -cron_line=${cron_line%|*} -cron_line=${cron_line%"2>&1"*} - -cmd_line="${cron_line#*root}" - -eval "args=($cmd_line)" - -## should be last argument - -docker_cmd=$(echo ${args[@]: -1}) - -if ! [[ "$docker_cmd" == "docker run --rm -e "* ]]; then - echo "docker command found should start with 'docker run'." >&2 - echo "Here's command:" >&2 - echo " $docker_cmd" >&2 - exit 1 -fi - -eval "docker exec -i myc_cron_1 $docker_cmd" diff --git a/bin/vps b/bin/vps index ffcc8c2..fcc3338 100755 --- a/bin/vps +++ b/bin/vps @@ -303,7 +303,7 @@ EOF fi info "You can run this following command on $BACKUP_SERVER:" - public_key=$(ssh-keygen -y -f <(e "$private_key")) + public_key=$(ssh-keygen -y -f <(e "$private_key"$'\n')) echo "compose-add-rsync-key -R '$host' '$public_key ${service_name}@$host'" } @@ -320,11 +320,9 @@ cmdline.spec.gnu cmdline.spec.reporting cmdline.spec.gnu install -cmdline.spec.gnu backup cmdline.spec::cmd:install:run() { - : } @@ -394,4 +392,125 @@ cmdline.spec:install:cmd:mailcow-backup:run() { } + +cmdline.spec.gnu backup +cmdline.spec::cmd:backup:run() { + + local vps_type + vps_type=$(vps:get-type) || { + err "Failed to get type of installation." + return 1 + } + if ! fn.exists "cmdline.spec:backup:cmd:${vps_type}:run"; then + err "type '${vps_type}' has no backup process implemented yet." + return 1 + fi + + "cmdline.spec:backup:cmd:${vps_type}:run" +} + + +cmdline.spec:backup:cmd:mailcow:run() { + + local cmd_line cron_line cmd + + for f in mysql-backup mirror-dir; do + [ -e "/etc/cron.d/$f" ] || { + err "Can't find '/etc/cron.d/$f'." \ + "Have you forgotten to run 'vps install backup BACKUP_HOST' ?" + return 1 + } + + if ! cron_line=$(cat "/etc/cron.d/$f" | + grep -v "^#" | grep "\* \* \*"); then + err "Can't find cron_line in '/etc/cron.d/$f'." \ + "Have you modified it ?" + return 1 + fi + + cron_line=${cron_line%|*} + cmd_line=(${cron_line#*root}) + + if [ "$f" == "mirror-dir" ]; then + cmd=() + for arg in "${cmd_line[@]}"; do + [ "$arg" != "-q" ] && cmd+=("$arg") + done + else + cmd=("${cmd_line[@]}") + fi + + code="${cmd[*]}" + echo "${WHITE}Launching:${NORMAL} ${code}" + { + { + ( + ## Some commands are using colors that are already + ## set by this current program and will trickle + ## down unwantedly + ansi_color no + eval "${code}" + ) | sed -r "s/^/ ${GRAY}|${NORMAL} /g" + set_errlvl "${PIPESTATUS[0]}" + } 3>&1 1>&2 2>&3 | sed -r "s/^/ $DARKRED\!$NORMAL /g" + set_errlvl "${PIPESTATUS[0]}" + } 3>&1 1>&2 2>&3 + + if [ "$?" != "0" ]; then + err "Failed." + return 1 + fi + done + info "Mysql backup and subsequent mirror-dir ${DARKGREEN}succeeded${NORMAL}." +} + + +set_errlvl() { return "${1:-1}"; } + + +cmdline.spec:backup:cmd:compose:run() { + + local cron_line args + if ! cron_line=$(docker exec myc_cron_1 cat /etc/cron.d/rsync-backup | grep "\* \* \*"); then + err "Can't find cron_line in cron container." \ + "Have you forgotten to run 'compose up' ?" + exit 1 + fi + + cron_line=${cron_line%|*} + cron_line=${cron_line%"2>&1"*} + + cmd_line="${cron_line#*root}" + + eval "args=($cmd_line)" + + ## should be last argument + + docker_cmd=$(echo ${args[@]: -1}) + + if ! [[ "$docker_cmd" == "docker run --rm -e "* ]]; then + echo "docker command found should start with 'docker run'." >&2 + echo "Here's command:" >&2 + echo " $docker_cmd" >&2 + exit 1 + fi + + echo "${WHITE}Launching:${NORMAL} docker exec -i myc_cron_1 $docker_cmd" + + { + { + eval "docker exec -i myc_cron_1 $docker_cmd" | sed -r "s/^/ ${GRAY}|${NORMAL} /g" + set_errlvl "${PIPESTATUS[0]}" + } 3>&1 1>&2 2>&3 | sed -r "s/^/ $DARKRED\!$NORMAL /g" + set_errlvl "${PIPESTATUS[0]}" + } 3>&1 1>&2 2>&3 + + if [ "$?" != "0" ]; then + err "Failed." + return 1 + fi + info "mirror-dir ${DARKGREEN}succeeded${NORMAL}." + +} + cmdline::parse "$@"