ansible/roles/vm/templates/script_stacks.j2
2023-12-05 18:12:35 +01:00

460 lines
11 KiB
Django/Jinja

#!/bin/bash
{# Updated: 2023-12-05 #}
# master: {{ common_mastering }}
# updated: {{ ansible_date_time.date }}
doBuildSystem() {
echo "v{{ vm_mastering }}"
}
# Display introduction
doIntro() {
echo
echo "Docker Stacks Managment: $HOSTNAME {$OPTION}"
doBuildSystem
echo
}
# Show date/time header
doHeader() {
NOW=`date +"%Y/%m/%d %H:%M:%S"`
echo "- $NOW"
echo ""
}
if [ "$(id -u)" != "0" ]; then
doIntro
doHeader
echo
echo "This script must be run as root" 1>&2
echo
exit 1
fi
WORK={{ vm_docker_work }}
BACKUPS={{ vm_docker_backups }}
LOGNAME={{ vm_stack_logfilename }}
LOGEXT={{ vm_stack_logfileext }}
HOSTNAME=$(hostname)
SELF=$(realpath $0)
SCRIPT=$(basename $SELF)
CWD=$(dirname $SELF)
STACKS=$CWD
SETUP=$STACKS/_vm
LOGFOLDER={{ vm_stack_logpath }}
LOGFILE=$LOGFOLDER/$LOGNAME.$LOGEXT
MASK="{{ vm_stack_backup_header}}${HOSTNAME}{{ vm_stack_backup_common }}NAME_DATE"
OPTION=$1
OPTION="${OPTION:=help}"
STACKNAME=$2
PROFILE=$3
cd $STACKS
# Send notification (0=no, 1=yes)
NOTIFY=1
# Rotate logfile
doRotateLogfile() {
if [ -f ${LOGFILE} ]; then
NOW=`date +"%Y%m%d-%H%M%S"`
mv ${LOGFILE} ${LOGFOLDER}/${LOGNAME}_${NOW}.${LOGEXT}
fi
touch ${LOGFILE}
}
# Force sync & flush
doSync() {
sync
echo 3 > /proc/sys/vm/drop_caches
}
doHead() {
doIntro
doHeader
}
# Display help
doHelp() {
doIntro
doHeader
if [ $OPTION != "help" ]; then
echo ">>> Unspecified, unknown or invalid option specified !"
echo
fi
echo "Usage: $SCRIPT OPTION [STACK] [PROFILE]"
echo
echo "OPTION:"
echo " help - Show this help"
echo " up - Up the stacks"
echo " down - Down the stacks"
echo " recycle - Up/Down 1 stacks"
echo " start - Start stacks"
echo " stop - Stop the stacks"
echo " pause - Pause stacks"
echo " unpause - Unpause the stacks"
echo " restart - Restart the stacks"
echo " update - Update the stacks"
echo " backup - Backup the stacks"
echo " self - Backup self system"
echo " autostop - Auto-Stop specified stacks"
echo " buildup - Build & Up the stack"
echo
echo "STACK: (optional)"
echo " name of a stack to process"
echo
}
# Send notification
doNotify() {
if [ $NOTIFY == 1 ]; then
curl \
-H "Title: Docker Stacks: $HOSTNAME" \
-T $LOGFILE \
-H "Filename: $LOGNAME" \
-H "Tags: heavy_check_mark" \
{{ vm_network_range }}.{{ vm_ip_master }}:6000/zogg \
>/dev/null 2>&1
fi
}
dockerCompose() {
ACTION=$1
NAME=$2
FLAGS=$3
NOW=`date +"%Y/%m/%d %H:%M:%S"`
echo "* { $ACTION: $1 }"
echo "> $NOW"
case $ACTION in
BUILDUP)
if [[ ! (-L .env && -e .env) ]]; then
echo "> Recreate .env"
rm -rf .env
ln -s ../_vm/.env .env
chown {{ vm_puid }}:{{ vm_pgid }} .env
fi
docker compose --profile $PROFILE up --build -d
;;
UP)
if [[ ! (-L .env && -e .env) ]]; then
echo "> Recreate .env"
rm -rf .env
ln -s ../_vm/.env .env
chown {{ vm_puid }}:{{ vm_pgid }} .env
fi
docker compose up --remove-orphans --quiet-pull --pull missing $2 -d
;;
PULL)
docker compose pull --include-deps $2
;;
DOWN)
docker compose down
;;
START)
docker compose start
;;
STOP)
docker compose stop -t 10
;;
PAUSE)
docker compose pause
;;
UNPAUSE)
docker compose unpause
;;
RESTART)
docker compose restart
;;
*)
doHelp
doNotify
exit 1
;;
esac
NOW=`date +"%Y/%m/%d %H:%M:%S"`
echo "> $NOW"
echo
}
# BACKUP
backupStack() {
FLDR=$(realpath $(pwd))
DATE=$(date +"%Y%m%d%H%M")
NAME=$1
FNAME=${MASK/NAME/$NAME}
FNAME=${FNAME/DATE/$DATE}
TOTAL=$(du -hs -B 1 $FLDR | cut -f1 | tail -n 1)
TOTALH=$(echo $TOTAL | awk ' BEGIN { split("bytes,KB,MB,GB,TB,PB,EB,ZB,YB",SZ,",") } { p=1;for(i=0;$1/p>1024;i++) p*=1024; printf "%4.2f %s\n", $1/p, SZ[i+1]}')
WRK=$WORK/$FNAME
MAXSIZE=1073741824 # 1 Go
echo " > Flush"
doSync
echo " > TAR"
tar --create --dereference --file=$WRK.tar -X $SETUP/excluded.txt $FLDR/ 2>/dev/null
TARSIZE=$(stat -c%s "$WRK.tar")
if (( TARSIZE < MAXSIZE)); then
echo " > Compress"
pigz --fast $WRK.tar
echo " > Move"
mv $WRK.tar.gz $BACKUPS/
else
echo " > Move"
mv $WRK.tar $BACKUPS/
fi
echo " > Flush"
doSync
echo " > Done!"
}
# Do: backup a stack
dockerBackupStack() {
NOW=`date +"%Y/%m/%d %H:%M:%S"`
echo "* { BACKUP: $1 }"
echo "> $NOW"
backupStack $1
NOW=`date +"%Y/%m/%d %H:%M:%S"`
echo "> $NOW"
echo
}
# Do: backup self system
backupSelf() {
FLDR=$(realpath $(pwd))
DATE=$(date +"%Y%m%d%H%M")
NAME="self-system"
FNAME=${MASK/NAME/$NAME}
FNAME=${FNAME/DATE/$DATE}
WRK=$WORK/$FNAME
MAXSIZE=524288000 # 500 Mo
echo " > Flush"
doSync
echo " > TAR"
tar --create --dereference --file=$WRK.tar -X $SETUP/excluded.txt $(realpath $SELF) $SETUP/ 2>/dev/null
TARSIZE=$(stat -c%s "$WRK.tar")
if (( TARSIZE < MAXSIZE)); then
echo " > Compress"
pigz --fast $WRK.tar
echo " > Move"
mv $WRK.tar.gz $BACKUPS/
else
echo " > Move"
mv $WRK.tar $BACKUPS/
fi
echo " > Flush"
doSync
echo " > Done!"
}
# Iterate stacks from file
doIterateFile() {
OPTION=$1
FILENAME=$2
FLAGS=$3
case $OPTION in
up | start | pause | restart | backup | autostop | update):
stacks=`cat -v $FILENAME`
;;
down | stop | unpause):
stacks=`cat -v $FILENAME | tac`
;;
*)
doHelp
doNotify
exit 1
;;
esac
for stack in $stacks; do
if [[
(-n $stack) # if not null
&& (${stack:0:1} != ';') # skip when starting with ';' (comment)
&& ( (${stack:0:1} == '+') || "$1" == "backup" ) # use when start with '+' or when asked to backup
]]; then
name=${stack:1}
cd $STACKS/$name
case $OPTION in
buildup):
dockerCompose "BUILDUP" "$name" "$FLAGS" "$PROFILE"
;;
up):
dockerCompose "UP" $name $FLAGS
;;
down):
dockerCompose "DOWN" $name $FLAGS
;;
start):
dockerCompose "START" $name $FLAGS
;;
stop):
dockerCompose "STOP" $name $FLAGS
;;
pause):
dockerCompose "PAUSE" $name $FLAGS
;;
unpause):
dockerCompose "UNPAUSE" $name $FLAGS
;;
restart):
dockerCompose "RESTART" $name $FLAGS
;;
backup):
dockerCompose "STOP" $name $FLAGS
dockerBackupStack $name $FLAGS
dockerCompose "START" $name $FLAGS
;;
autostop):
dockerCompose "STOP" $name $FLAGS
;;
update):
dockerCompose "DOWN" $name $FLAGS
dockerCompose "PULL" $name $FLAGS
dockerCompose "UP" $name $FLAGS
;;
*)
doHelp
doNotify
exit 1
;;
esac
cd $CWD
fi
done
cd $CWD
}
# Proceedd operations on stacks
doIterate() {
OPTION=$1
STACKNAME=$2
if [ ! -z $STACKNAME ]; then
echo "+$STACKNAME" > "$SETUP/{{ vm_stack_unitary }}"
else
rm -rf "$SETUP/{{ vm_stack_unitary }}"
fi
if [ -f "$SETUP/{{ vm_stack_unitary }}" ]; then
doHead
case $OPTION in
recycle):
doIterateFile down "$SETUP/{{ vm_stack_unitary }}" ""
doIterateFile up "$SETUP/{{ vm_stack_unitary }}" ""
;;
*)
doIterateFile $OPTION "$SETUP/{{ vm_stack_unitary }}" ""
;;
esac
rm -rf "$SETUP/{{ vm_stack_unitary }}"
else
case $OPTION in
start):
doHead
doIterateFile $OPTION "$SETUP/{{ vm_stack_before }}" ""
doIterateFile $OPTION "$SETUP/{{ vm_stack_current }}" ""
doIterateFile $OPTION "$SETUP/{{ vm_stack_after }}" ""
;;
stop):
doHead
doIterateFile $OPTION "$SETUP/{{ vm_stack_after }}" ""
doIterateFile $OPTION "$SETUP/{{ vm_stack_current }}" ""
doIterateFile $OPTION "$SETUP/{{ vm_stack_before }}" ""
;;
up):
doHead
doIterateFile $OPTION "$SETUP/{{ vm_stack_before }}" "--wait"
doIterateFile $OPTION "$SETUP/{{ vm_stack_current }}" ""
doIterateFile $OPTION "$SETUP/{{ vm_stack_after }}" ""
doIterateFile autostop "$SETUP/{{ vm_stack_stop }}" ""
;;
down):
doHead
doIterateFile $OPTION "$SETUP/{{ vm_stack_after }}" ""
doIterateFile $OPTION "$SETUP/{{ vm_stack_current }}" ""
doIterateFile $OPTION "$SETUP/{{ vm_stack_before }}" ""
;;
restart):
doHead
doIterateFile $OPTION "$SETUP/{{ vm_stack_after }}" ""
doIterateFile $OPTION "$SETUP/{{ vm_stack_current }}" ""
doIterateFile $OPTION "$SETUP/{{ vm_stack_before }}" ""
doIterateFile autostop "$SETUP/{{ vm_stack_stop }}" ""
;;
pause):
doHead
doIterateFile $OPTION "$SETUP/{{ vm_stack_after }}" ""
doIterateFile $OPTION "$SETUP/{{ vm_stack_current }}" ""
doIterateFile $OPTION "$SETUP/{{ vm_stack_before }}" ""
;;
unpause):
doHead
doIterateFile $OPTION "$SETUP/{{ vm_stack_before }}" ""
doIterateFile $OPTION "$SETUP/{{ vm_stack_current }}" ""
doIterateFile $OPTION "$SETUP/{{ vm_stack_after }}" ""
;;
update):
doHead
doIterateFile $OPTION "$SETUP/{{ vm_stack_after }}" ""
doIterateFile $OPTION "$SETUP/{{ vm_stack_current }}" ""
doIterateFile $OPTION "$SETUP/{{ vm_stack_before }}" ""
doIterateFile autostop "$SETUP/{{ vm_stack_stop }}" ""
;;
backup):
doHead
doIterateFile $OPTION "$SETUP/{{ vm_stack_after }}" ""
doIterateFile $OPTION "$SETUP/{{ vm_stack_current }}" ""
doIterateFile $OPTION "$SETUP/{{ vm_stack_before }}" ""
doIterateFile autostop "$SETUP/{{ vm_stack_stop }}" ""
$SELF self
;;
self):
doHead
backupSelf
;;
autostop):
doHead
doIterateFile $OPTION "$SETUP/{{ vm_stack_stop }}" ""
;;
esac
fi
}
# Entrypoint of operations
case $OPTION in
buildup|up|start|pause | down|stop|unpause | update | restart|recycle | backup|self | autostop):
doRotateLogfile
doSync
doIterate $OPTION $STACKNAME > >(tee -a $LOGFILE) 2>&1
doNotify
doSync
;;
help | *)
doHelp
doNotify
exit 1
;;
esac
exit 0