First Commit

This commit is contained in:
Andrew Hurley 2022-10-26 20:31:43 +11:00
commit 4a2eb7588d
8 changed files with 445 additions and 0 deletions

0
README.md Normal file
View File

39
b2v.sh Executable file
View File

@ -0,0 +1,39 @@
#!/bin/bash
#set -o xtrace
PREFIX=""
if [[ -v 1 ]]; then
PREFIX="${1}_"
fi
cprompt () {
read -r -s -N 1 -p "Continue [Enter]?"
if [[ $REPLY == $'\n' ]]; then
printf "\n"
else
printf "\n"
printf " Script stopped!\n"
exit
fi
}
#pushd vtb || exit 1
for TAR in *.tar.bz2; do
if [[ $TAR =~ .tar.bz2 ]]; then
VOL=${TAR%.tar.bz2}
if [[ -n $PREFIX ]]; then
VOL="${PREFIX}${VOL#*_}"
fi
if sudo docker volume ls -q |grep -qw "${VOL}"; then
printf "Operation: ${TAR} -> ${VOL}\n"
cprompt
sudo cat "${TAR}" \
|sudo docker run -i -v "${VOL}:/volume" --rm \
loomchild/volume-backup restore -v -f - || exit 3
fi
fi
done
#popd || exit 1
set +o xtrace

1
backup.cron Normal file
View File

@ -0,0 +1 @@
14 4 * * * root /srv/backup/backup.sh 2>&1 |tee /root/cron-backup.log

3
backup.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
pushd /srv/backup && ./vvv.sh docker local mailu && nice ./v2b.sh -u backup_docker && popd

49
m2v.sh Executable file
View File

@ -0,0 +1,49 @@
#!/bin/bash
set -o xtrace
if [[ $# < 2 ]]; then
echo "First argument is compose prefix. File with list of 'volumes binddir' needed as second argument"
exit 1
fi
if [[ ! -f "${2}" ]]; then
echo "File with list of 'volumes binddir' missing (${2})."
exit 1
fi
if [[ ! -d "../@${1}" ]]; then
echo "Compose directory not valid (${1})"
exit 1
fi
sudo docker rm -f helper
if [[ -f log.txt ]]; then
mv log.txt "log-$(date +%N).txt"
else
touch log.txt
fi
VOLUMES="$(sudo docker volume ls -q |grep ${1}_)a"
touch log.txt
sleep 2
while read -r F1 F2; do
VOLUME="${1}_${F1}"
if grep -wq "${VOLUME}" - <<< $VOLUMES; then
COMMAND="rm -rvf /volume/{*,.*} && cp -a ../bindmnt/. /volume"
BINDMNT=$(realpath "../cndata/${F2}")
sudo docker run --name helper \
-v "${VOLUME}:/volume" \
-v "${BINDMNT}:/bindmnt" \
busybox \
sh -c "${COMMAND}"
sudo docker logs helper >> log.txt
sudo docker rm -f helper
sleep 2
else
echo "$VOLUME is not available for restoration"
exit 1
fi
done < "${2}"
set +o xtrace

103
rem.sh Executable file
View File

@ -0,0 +1,103 @@
#!/bin/bash
set -o xtrace
set -u
set -o pipefail
usage () {
printf " Usage: rem.sh <url>\n"
printf " option: f <folder> (local folder contents to send to remote)\n"
printf " option: b (send backup scripts located in ../backup to remote)\n"
printf " option: d (send server docker spec located in ../docker to remote)\n"
printf " option: s (send server certificates located in ../srvtls to remote)\n"
printf " option: c (send server config located in ../config to remote)\n"
printf " option: a (options d,s,c combined - complete server, excluding scripts)\n"
}
FOLDER="_vols_"
SCRIPTS="false"
CERTS="false"
DOCKER="false"
CONFIG="false"
OUTPUT=""
while getopts ':f:bdsca' OPT; do
case $OPT in
b)
SCRIPTS="true"
OUTPUT="${OUTPUT} Option: SEND BACKUP SCRIPTS\n";;
f)
FOLDER="${OPTARGS}"
OUTPUT="${OUTPUT} Option: SPECIFY SOURCE FOLDER\n";;
s)
CERTS="true"
OUTPUT="${OUTPUT} Option: SEND CERTIFICATES\n";;
d)
DOCKER="true"
OUTPUT="${OUTPUT} Option: SEND DOCKER SPEC\n";;
c)
CONFIG="true"
OUTPUT="${OUTPUT} Option: SEND CONFIG SPEC\n";;
a)
CONFIG="true"; DOCKER="true"; CERTS="true";
OUTPUT="${OUTPUT} Option: SEND ALL (BACKUP,CERTS,DOCKER,CONFIG\n";;
\?)
usage;
exit;;
esac
done
shift $((OPTIND -1))
REMOTEURL=""
if [[ -v 1 ]]; then
REMOTEURL="${1}"
else
echo "Missing remote address: user@url"
exit 1
fi
REMOTEDIR="_vols_"
sudo ssh "${REMOTEURL}" << EOT || exit 1
echo "Local user: $USER"
echo "Remote user: \$USER"
pushd /srv/backup || exit 1
if [[ -d _vols_ ]]; then
if [[ -n "$(ls -A _vols_)" ]]; then
TF="$(stat -c "%W" "${REMOTEDIR}")"
mv "${REMOTEDIR}" "${REMOTEDIR}\${TF}" || exit 1
fi
fi
mkdir -p "${REMOTEDIR}" || exit 1
popd || exit 1
EOT
pushd "${FOLDER}" || exit 1
sudo scp *.tar.bz2 "${REMOTEURL}:/srv/backup/_vols_" || exit 1
popd || exit 1
if [[ $SCRIPTS == "true" ]]; then
pushd "../backup" || exit 1
sudo scp *.sh "${REMOTEURL}:/srv/backup" || exit 1
popd || exit 1
fi
if [[ $CERTS == "true" ]]; then
pushd "../srvtls" || exit 1
sudo scp * "${REMOTEURL}:/srv/srvtls" || exit 1
popd || exit 1
fi
if [[ $DOCKER == "true" ]]; then
pushd "../docker" || exit 1
sudo scp * .env "${REMOTEURL}:/srv/docker" || exit 1
popd || exit 1
fi
if [[ $CONFIG == "true" ]]; then
pushd "../config" || exit 1
sudo scp * .env "${REMOTEURL}:/srv/config" || exit 1
popd || exit 1
fi
set +o xtrace

135
v2b.sh Executable file
View File

@ -0,0 +1,135 @@
#!/bin/bash
#set -o xtrace
set -u
set -o pipefail
UMASK="$(umask)"
final-local () {
if [[ -z "$(ls -A ${TEMPF})" ]]; then
rmdir "${TEMPF}"
else
if [[ $KEEP == "true" ]]; then
mv "${FOLDER}" "${NEWFL}"
else
rm -rf "${FOLDER}"
fi
mv "${TEMPF}" "${FOLDER}"
fi
}
final-remote () {
if [[ -z "$(ls ${TEMPF})" ]]; then
rmdir "${TEMPF}"
else
sudo scp -r "${TEMPF}" "${ADDR}:/srv/backup/${TEMPF}" || exit 1
if [[ $KEEP == "true" ]]; then
sudo ssh "${ADDR}" "cd /srv/backup; mv \"${FOLDER}\" \"${NEWFL}\""
else
sudo ssh "${ADDR}" "cd /srv/backup; rm -rf \"${FOLDER}\""
fi
sudo scp -r "${TEMPF}" "${ADDR}:/srv/backup" && rm -rf "${TEMPF}"
sudo ssh "${ADDR}" "cd /srv/backup; mv \"${TEMPF}\" \"${FOLDER}\""
fi
}
cprompt () {
if [[ $UNATTENDED == "true" ]]; then return; fi
read -r -s -N 1 -p "Continue [Enter]?"
if [[ $REPLY != $'\n' ]]; then
printf "\n"
printf " Script stopped!\n"
if [[ $SEND == "true" ]]; then
final-remote
else
final-local
fi
exit
fi
}
usage () {
printf "v2b.sh <option> [ <prefix> ]\n"
printf " <prefix> only backup volumes with this prefix\n"
printf " option: k (keep existing backups)\n"
printf " option: p (remove prefix from tar archive file name\n"
printf " option: u (unattended backup)\n"
printf " option: s <address> (send backup directly to remote address via ssh)\n"
}
SEND="false"
ADDR=""
REMOVE="false"
KEEP="false"
UNATTENDED="false"
OUTPUT=""
while getopts ':s:pku' OPT; do
case $OPT in
s) SEND="true"; ADDR="${OPTARG}"; OUTPUT="${OUTPUT} Option: SEND BACKUPS\n";;
p) REMOVE="true"; OUTPUT="${OUTPUT} Option: RESTART AFTER\n";;
r) KEEP="true"; OUTPUT="${OUTPUT} Option: KEEP EXISTING BACKUPS\n";;
u) UNATTENDED="true"; OUTPUT="${OUTPUT} Option: UNATTENDED BACKUP\n";;
\?) usage; exit;;
esac
done
shift $((OPTIND -1))
if [[ $SEND == "true" ]]; then
FOLDER="_$(hostname -f)_"
else
FOLDER="_vols_"
fi
if [[ $# > 0 ]]; then
VOLUMES="$(sudo docker volume ls -q |grep "${1}")"
else
VOLUMES="$(sudo docker volume ls -q)"
fi
if [[ -z $VOLUMES ]]; then
printf "Cannot find volumes spec: ${1}_\n"
exit 1
fi
if [[ $SEND == "true" ]]; then
if sudo ssh "${ADDR}" test -d "/srv/backup/${FOLDER}"; then
LASTF="$(sudo ssh "${ADDR}" ls -d --format=single-column ${FOLDER}* |tail -n1)"
else
LASTF="${FOLDER}"
fi
else
if [[ -d ${FOLDER} ]]; then
LASTF="$(ls -d --format=single-column ${FOLDER}* |tail -n1)"
else
LASTF="${FOLDER}"
fi
fi
INDEX="$((( ${LASTF#${FOLDER}} + 0 )))"
NEWFL="${FOLDER}$(printf "%05d" $((( ${INDEX} + 1 ))))"
TEMPF="$(mktemp -dt -p $PWD XXXXXXXXXXXXXXX)"
for VOL in ${VOLUMES}; do
if [[ $REMOVE == "true" ]]; then
TAR="${VOL#${1}_}.tar.bz2"
else
TAR="${VOL}.tar.bz2"
fi
printf "${VOL} --> ${TEMPF}/${TAR}\n"
cprompt
sudo docker run --rm --log-driver none \
-v "${VOL}:/volume" \
-v "${TEMPF}:/backup" \
loomchild/volume-backup backup -v "${TAR}"
sudo chmod 400 "${TEMPF}/${TAR}"
done
if [[ $SEND == "true" ]]; then
final-remote
else
final-local
fi
set +o xtrace

115
vvv.sh Executable file
View File

@ -0,0 +1,115 @@
#!/bin/bash
#set -o xtrace
set -u
set -o pipefail
RESTORE="false"
OUTPUT=""
while getopts ':r' OPT; do
case $OPT in
r) RESTORE="true"; OUTPUT="${OUTPUT} Option: RESTORE OPERATION";;
\?) usage; exit;;
esac
done
shift $((OPTIND -1))
if [[ $RESTORE == "true" ]] && [[ ! -f docker-restore.sh ]]; then
echo "Problem: docker-restore.sh missing!"
exit 1
fi
usage () {
printf "Usage: vvv.sh <project> <profile> [ <profile> ... ]\n"
printf " Project = Compose project folder.\n"
printf " Profile(s) = profiles to stop and then restart after.\n"
}
scripts () {
for MODE in backup restore; do
FILE="docker-${MODE}.sh"
SCRIPT="#!/bin/bash"$'\n'
SCRIPT="${SCRIPT}sudo docker run --rm \\"$'\n'
SCRIPT="${SCRIPT} --name volumerize \\"$'\n'
SCRIPT="${SCRIPT} -e TZ=Australia/Perth \\"$'\n'
SCRIPT="${SCRIPT} -e VOLUMERIZE_SOURCE=/source \\"$'\n'
SCRIPT="${SCRIPT} -e VOLUMERIZE_TARGET=file:///backup \\"$'\n'
SCRIPT="${SCRIPT} -v backup_${PROJECT}-cache:/volumerize-cache \\"$'\n'
if [[ $MODE == "restore" ]]; then
SCRIPT="${SCRIPT} -v backup_${PROJECT}-volume:/backup:ro \\"$'\n'
for VOL in $VOLUMES; do
SCRIPT="${SCRIPT} -v ${VOL}:/source/${VOL} \\"$'\n'
done
SCRIPT="${SCRIPT} blacklabelops/volumerize:1.7.1 restore"$'\n'$'\n'
elif [[ $MODE == "backup" ]]; then
SCRIPT="${SCRIPT} -v backup_${PROJECT}-volume:/backup \\"$'\n'
for VOL in $VOLUMES; do
SCRIPT="${SCRIPT} -v ${VOL}:/source/${VOL}:ro \\"$'\n'
done
SCRIPT="${SCRIPT} blacklabelops/volumerize:1.7.1 backup"$'\n'$'\n'
else
printf "Fatal error 1.\n"
exit 1
fi
printf "${SCRIPT}" > "${FILE}"
chmod +x "${FILE}"
done
}
if [[ $# -lt 2 ]]; then
usage
exit 1
fi
PROJECT="$1"
if [[ ! -d "../${PROJECT}" ]]; then
printf "Folder ${1} does not exist!\n"
exit 1
fi
VOLUMES="$(sudo ls /var/lib/docker/volumes |grep "${PROJECT}_")"
if [[ -z "$VOLUMES" ]]; then
printf "There are no volumes found to backup/restore!\n"
exit 1
fi
pushd "../${PROJECT}" > /dev/null || exit 1
if [[ ! $RESTORE == "true" ]]; then
scripts
fi
shift
for PRO in $@; do
COMMAND="sudo docker compose --profile=${PRO} stop"
printf "${COMMAND}\n"
${COMMAND}
if ! ${COMMAND}; then
printf "Services 'docker compose stop' error."
exit 1
fi
COMMAND="sudo docker compose --profile=${PRO} rm -f"
printf "${COMMAND}\n"
${COMMAND}
if ! ${COMMAND}; then
printf "Services 'docker compose rm' error."
exit 1
fi
done
if [[ $RESTORE == "true" ]]; then
"./docker-restore.sh"
else
"./docker-backup.sh"
fi
for PRO in $@; do
COMMAND="sudo docker compose --profile=${PRO} up -d"
printf "${COMMAND}\n"
if ! ${COMMAND}; then
printf "Services 'up' error."
exit 1
fi
done
popd > /dev/null || exit 1