468 lines
12 KiB
Plaintext
468 lines
12 KiB
Plaintext
|
#!/bin/bash
|
||
|
# master: {{ vm_mastering }}
|
||
|
# edited: 2023-09-25
|
||
|
# 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_logfile }}
|
||
|
|
||
|
HOSTNAME=$(hostname)
|
||
|
SELF=$(realpath $0)
|
||
|
SCRIPT=$(basename $SELF)
|
||
|
CWD=$(dirname $SELF)
|
||
|
STACKS=$CWD
|
||
|
|
||
|
SETUP=$STACKS/_vm
|
||
|
LOGFILE={{ vm_stack_logpath }}/$LOGNAME
|
||
|
MASK="{{ vm_stack_backup_header}}${HOSTNAME}{{ vm_stack_backup_common }}NAME_DATE"
|
||
|
|
||
|
OPTION=$1
|
||
|
OPTION="${OPTION:=help}"
|
||
|
STACKNAME=$2
|
||
|
|
||
|
cd $STACKS
|
||
|
|
||
|
# Send notification (0=no, 1=yes)
|
||
|
NOTIFY=1
|
||
|
|
||
|
# 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]"
|
||
|
echo
|
||
|
echo "OPTION:"
|
||
|
echo " help - Show this help"
|
||
|
echo " up - Up the stacks"
|
||
|
echo " down - Down the 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
|
||
|
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 }}:8050/zogg \
|
||
|
>/dev/null 2>&1
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
# UP
|
||
|
dockerComposeUp() {
|
||
|
NOW=`date +"%Y/%m/%d %H:%M:%S"`
|
||
|
echo "* { UP: $1 }"
|
||
|
echo "> $NOW"
|
||
|
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
|
||
|
NOW=`date +"%Y/%m/%d %H:%M:%S"`
|
||
|
echo "> $NOW"
|
||
|
echo
|
||
|
}
|
||
|
|
||
|
# PULL
|
||
|
dockerComposePull() {
|
||
|
NOW=`date +"%Y/%m/%d %H:%M:%S"`
|
||
|
echo "* { PULL: $1 }"
|
||
|
echo "> $NOW"
|
||
|
echo " Pulling"
|
||
|
docker compose pull --include-deps $2
|
||
|
NOW=`date +"%Y/%m/%d %H:%M:%S"`
|
||
|
echo "> $NOW"
|
||
|
echo
|
||
|
}
|
||
|
|
||
|
# DOWN
|
||
|
dockerComposeDown() {
|
||
|
NOW=`date +"%Y/%m/%d %H:%M:%S"`
|
||
|
echo "* { DOWN: $1 }"
|
||
|
echo "> $NOW"
|
||
|
docker compose down
|
||
|
NOW=`date +"%Y/%m/%d %H:%M:%S"`
|
||
|
echo "> $NOW"
|
||
|
echo
|
||
|
}
|
||
|
|
||
|
# START
|
||
|
dockerComposeStart() {
|
||
|
NOW=`date +"%Y/%m/%d %H:%M:%S"`
|
||
|
echo "* { START: $1 }"
|
||
|
echo "> $NOW"
|
||
|
echo ">> start"
|
||
|
docker compose start
|
||
|
NOW=`date +"%Y/%m/%d %H:%M:%S"`
|
||
|
echo "> $NOW"
|
||
|
echo
|
||
|
}
|
||
|
|
||
|
# STOP
|
||
|
dockerComposeStop() {
|
||
|
NOW=`date +"%Y/%m/%d %H:%M:%S"`
|
||
|
echo "* { STOP: $1 }"
|
||
|
echo "> $NOW"
|
||
|
docker compose stop -t 10
|
||
|
NOW=`date +"%Y/%m/%d %H:%M:%S"`
|
||
|
echo "> $NOW"
|
||
|
echo
|
||
|
}
|
||
|
|
||
|
# PAUSE
|
||
|
dockerComposePause() {
|
||
|
NOW=`date +"%Y/%m/%d %H:%M:%S"`
|
||
|
echo "* { PAUSE: $1 }"
|
||
|
echo "> $NOW"
|
||
|
docker compose pause
|
||
|
NOW=`date +"%Y/%m/%d %H:%M:%S"`
|
||
|
echo "> $NOW"
|
||
|
echo
|
||
|
}
|
||
|
|
||
|
# UNPAUSE
|
||
|
dockerComposeUnpause() {
|
||
|
NOW=`date +"%Y/%m/%d %H:%M:%S"`
|
||
|
echo "* { UNPAUSE: $1 }"
|
||
|
echo "> $NOW"
|
||
|
docker compose unpause
|
||
|
NOW=`date +"%Y/%m/%d %H:%M:%S"`
|
||
|
echo "> $NOW"
|
||
|
echo
|
||
|
}
|
||
|
|
||
|
# RESTART
|
||
|
dockerComposeRestart() {
|
||
|
NOW=`date +"%Y/%m/%d %H:%M:%S"`
|
||
|
echo "* { RESTART: $1 }"
|
||
|
echo "> $NOW"
|
||
|
docker compose restart
|
||
|
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
|
||
|
up):
|
||
|
dockerComposeUp $name $FLAGS
|
||
|
;;
|
||
|
down):
|
||
|
dockerComposeDown $name $FLAGS
|
||
|
;;
|
||
|
start):
|
||
|
dockerComposeStart $name $FLAGS
|
||
|
;;
|
||
|
stop):
|
||
|
dockerComposeStop $name $FLAGS
|
||
|
;;
|
||
|
pause):
|
||
|
dockerComposePause $name $FLAGS
|
||
|
;;
|
||
|
unpause):
|
||
|
dockerComposeUnpause $name $FLAGS
|
||
|
;;
|
||
|
restart):
|
||
|
dockerComposeRestart $name $FLAGS
|
||
|
;;
|
||
|
backup):
|
||
|
dockerComposeStop $name $FLAGS
|
||
|
dockerBackupStack $name $FLAGS
|
||
|
dockerComposeStart $name $FLAGS
|
||
|
;;
|
||
|
autostop):
|
||
|
dockerComposeStop $name $FLAGS
|
||
|
;;
|
||
|
update):
|
||
|
dockerComposeDown $name $FLAGS
|
||
|
dockerComposePull $name $FLAGS
|
||
|
dockerComposeUp $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
|
||
|
doIterateFile $OPTION "$SETUP/{{ vm_stack_unitary }}" ""
|
||
|
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
|
||
|
up|start|pause | down|stop|unpause | update | restart | backup|self | autostop):
|
||
|
doIterate $OPTION $STACKNAME > >(tee -a $LOGFILE) 2>&1
|
||
|
doNotify
|
||
|
doSync
|
||
|
;;
|
||
|
help | *)
|
||
|
doHelp
|
||
|
doNotify
|
||
|
exit 1
|
||
|
;;
|
||
|
esac
|
||
|
|
||
|
exit 0
|