#!/bin/bash set -e #set -x [ -n "$TERM" ] && clear ### # # Author: Stéphane HUC # mail: devs@stephane-huc.net # gpg:fingerprint: CE2C CF7C AB68 0329 0D20 5F49 6135 D440 4D44 BD58 # # License: BSD Simplified # # Github: # # Date: 2021/09/16 13:40 # ### # # USE: ./deploy.bash # ### # # Need software: # - brotli : compression format .br # - git : # - sshfs + rsync # - lftp (solution de repli) # - java : pour le script minify # - webp : pour la compression format webp # ### ROOT="$(dirname "$(readlink -f -- "$0")")" id='obsd4a' host='djebeltoubkal.linuxmario.net' #passwd='TfpLLyC22fbcA3Sm' port=22 ### the directory where your web site files should go ## dir_dist: relative to chroot SSH dir_dist="/var/www/htdocs/www.openbsd.fr.eu.org/" dir_local="$ROOT/public/" dir_mount="$HOME/servers/${host}/" dir_tools="$ROOT/scripts_nohugo/outils/" email="red+bckp-obsd4a@huc.fr.eu.org" rsync_xclud="--exclude=gopher --exclude=gemini" rsync_opts="--human-readable --progress --stats " ################################################################################ ### ## # Fonctions ## ### ################################################################################ # process to confirm action confirm () { printf '%s\n' "${1}[y|n] " read -r response case "${response}" in # 'o', 'O': Oui and not 0! y|Y|o|O|1) true ;; *) false ;; esac } # delete all compress files (br, gz) _del_gz() { cd "${dir_local}" || exit 1 find . -type f -a \( -name "*.br" -o -name "*.gz" \) -delete cd "$ROOT" || exit 1 } # get rsync status and send mail get_status() { case "$status" in 0) mssg="Succès" ;; 1) mssg="Erreur de syntaxe ou d'utilisation" ;; 2) mssg="Incompatibilité de protocole" ;; 3) mssg="Erreurs de sélection d'entrée ou de sortie des fichiers ou des répertoires" ;; 4) mssg="Action demandée non prise en charge : une tentative de manipulation de fichiers 64 bits a été effectuée sur une plate-forme qui ne peut pas les prendre en charge ; ou une option a été spécifiée qui est pris en charge par le client et non par le serveur." ;; 5) mssg="Erreur de démarrage du protocole client-serveur" ;; 6) mssg="Le service est incapable d'ajouter au fichier journal" ;; 10) mssg="Erreur dans le socket I/O" ;; 11) mssg="Erreur dans le fichier I/O" ;; 12) mssg="Erreur dans le flux de données du protocole rsync" ;; 13) mssg="Erreurs de diagnostic du programme" ;; 14) mssg="Erreur dans le code IPC" ;; 20) mssg="SIGUSR1 ou SIGINT reçus" ;; 21) mssg="Une erreur est retournée par waitpid()" ;; 22) mssg="Erreur lors de l'allocation des mémoires tampons principales" ;; 23) mssg="Transfert partiel dû à une erreur";; 24) mssg="Transfert partiel dû à la disparition des fichiers source" ;; 25) mssg="La limite --max-delete a arrêté les suppressions" ;; 30) mssg="Délai d'attente pour l'envoi ou la réception de données" ;; 35) mssg="Délai d'attente pour la connexion du démon" ;; *) mssg="Code inconnu !" ;; esac #[ -z "$IS_CRON" ] && zenotify "Rsync: $choice!" "Rsync: $choice ; status: $mssg!" if [ "${status}" -eq 0 ]; then mssg="$0::Rsync for ${dir_local}, ended with success!" else mssg="$0::Rsync Error ${status} on execution for ${dir}, with message: ${mssg}!" fi logger "$mssg" printf '%s\n' "$mssg" | mail -s "$(hostname): Backup Review" $email unset mssg status } # git process _git() { git add . git status printf '%s\n' "⇒ Tape a message for the commit : " read -r mssg printf '%s\n' "When you are ready to submit your GPG key…" if _press; then echo " " ##printf '\n%s\n' "See the message : ${mssg}" ##exit # commit signed message git commit -a -S -m "${mssg}" # push commit git push origin HEAD fi unset mssg } # Compress all thoses datas files. _gz() { cd "${dir_local}" || exit 1 find . -not \( -path "./gopher/*" -o -path "./gemini/*" -prune \) \ -type f -size +1024c -a \( \ -name "*.css" -o -name "*.html" -o -name "*.js" -o -name "*.json" \ -o -name "*.svg" -o -name "*.txt" -o -name "*.xml" \ \) | while read -r line; do echo "Compress ${line}"; brotli -Z "${line}"; gzip -9 -f < "${line}" > "${line}.gz"; done #| while read -r file; do gzip -9 -f -v "${file}"; done cd "$ROOT" || exit 1 } # use lftp _lftp() { #/usr/local/bin/lftp -e "mirror -e -R ${dir_local} ${dir_dist}; quit" -p $port sftp://${id}@${host} lftp -e "set ftp:ssl-allow no; mirror -e -R ${dir_local} ${dir_dist}; quit;" ftp://${id}:${passwd}@${host} } main() { if confirm "Do you want to publish a git commit? "; then _git fi if confirm "Do you want to minify CC, JS files? "; then _minify sleep 1 fi if confirm "Do you want to convert images to Avif, Webp formats? "; then _webp sleep 1 fi if confirm "Do you want to build articles and publish them? "; then hugo --gc status="$?" if [ "${status}" -eq 0 ]; then _del_gz sleep 1 _gz sleep 1 if _mount; then _rsync _umount elif confirm "Do you want to try lftp to publish?"; then _lftp fi fi fi } # call minify script _minify() { "${dir_tools}"/minify.bash "$ROOT/static" } # mount remoted fs with sshfs _mount() { [ ! -d "${dir_mount}" ] && mkdir -p "${dir_mount}" #[ -d "${dir_mount}" ] && sshfs -C -p $port -o allow_other -o uid=$(id -u $USER) -o gid=$(id -g $USER) ${id}@${host}:${dir_dist} "${dir_mount}" [ -d "${dir_mount}" ] && sshfs -C -p $port -o uid=$(id -u $USER) -o gid=$(id -g $USER) ${id}@${host}:${dir_dist} "${dir_mount}" } # process press any key _press() { read -n 1 -s -r -p "Press any key to continue" } # call rsync _rsync() { cd "${dir_local}" || exit rsync -av --delete $rsync_xclud $rsync_opts "." "${dir_mount}" status="$?" get_status cd "$ROOT" || exit 1 } # unmount FS _umount() { fusermount -u "${dir_mount}" } # compress image to webp format _webp() { cd "${ROOT}/static" || exit 1 find . -type f -a \( \ -name "*.gif" -o -name '*.jpg' -o -name '*.jpeg' -o -name '*.png' \ \) | while read -r file; do if [ ! -f "${file}.webp" ]; then cwebp "${file}" -exact -lossless -o "${file}.webp"; fi; done cd "$ROOT" || exit 1 } ################################################################################ ### ## # Execution ## ### ################################################################################ main