First Commit
This commit is contained in:
commit
4a2eb7588d
|
|
@ -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
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
14 4 * * * root /srv/backup/backup.sh 2>&1 |tee /root/cron-backup.log
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
pushd /srv/backup && ./vvv.sh docker local mailu && nice ./v2b.sh -u backup_docker && popd
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
Loading…
Reference in New Issue