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