Compare commits
14 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
3fefde417a | |
|
|
21e339a255 | |
|
|
bde62426ae | |
|
|
a746f94e41 | |
|
|
dc6857fcdd | |
|
|
4367f4b69b | |
|
|
92570c796e | |
|
|
cdfb0697c1 | |
|
|
46ec2d2a95 | |
|
|
ad2898c5e5 | |
|
|
8a551dac84 | |
|
|
426cfd9ec6 | |
|
|
c81246bd90 | |
|
|
b145b1654f |
|
|
@ -0,0 +1 @@
|
||||||
|
_**
|
||||||
1
b2v.sh
1
b2v.sh
|
|
@ -5,6 +5,7 @@
|
||||||
PREFIX=""
|
PREFIX=""
|
||||||
if [[ -v 1 ]]; then
|
if [[ -v 1 ]]; then
|
||||||
PREFIX="${1}_"
|
PREFIX="${1}_"
|
||||||
|
printf "Add prefix $PREFIX\n"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cprompt () {
|
cprompt () {
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
14 4 * * * root /srv/backup/backup.sh 2>&1 |tee /root/cron-backup.log
|
14 4 * * * root /srv/backup/backup.sh -r "/srv/fsback" docker 2>&1 |tee /srv/fsback/$(date +%^a).log
|
||||||
|
|
|
||||||
49
backup.sh
49
backup.sh
|
|
@ -1,3 +1,50 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
pushd /srv/backup && ./vvv.sh docker && nice ./v2b.sh -u backup_docker && popd
|
usage () {
|
||||||
|
printf "Usage: backup.sh <options> <project> [<project>]\n"
|
||||||
|
printf " project = Compose project folder(s).\n"
|
||||||
|
printf " Option r <location>: rsync to another location - will make path (rsync mkpath option used)\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
pexit () {
|
||||||
|
printf "${1}\n"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
RSYNC=""
|
||||||
|
while getopts ':r:' OPT; do
|
||||||
|
case $OPT in
|
||||||
|
r) RSYNC="${OPTARG}";;
|
||||||
|
\?) usage; exit;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $((OPTIND -1))
|
||||||
|
|
||||||
|
if [[ $# -lt 1 ]]; then
|
||||||
|
pexit "Error: missing project(s)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n $RSYNC ]]; then
|
||||||
|
HN=$(hostname -f)
|
||||||
|
if [[ ! $HN =~ "." ]]; then
|
||||||
|
pexit "Error: fully quaififed hostname required (add to /etc/hosts - 127.0.0.11)"
|
||||||
|
fi
|
||||||
|
printf "Hostname: ${HN}\n"
|
||||||
|
fi
|
||||||
|
|
||||||
|
pushd /srv/backup || pexit "Error: changing to backup directory"
|
||||||
|
printf "Backup start: $(date)\n"
|
||||||
|
for PROJECT in $@; do
|
||||||
|
./vvv.sh "${PROJECT}" || pexit "Error: using vvv.sh ${PROJECT}"
|
||||||
|
done
|
||||||
|
nice ./v2b.sh -u backup || pexit "Error: using v2b.sh -u backup"
|
||||||
|
if [[ -n $RSYNC ]]; then
|
||||||
|
RSYNC="${RSYNC}/${HN}/$(date +%^a)"
|
||||||
|
rsync -av --mkpath ./_vols_/ "${RSYNC}/" || pexit "Error: using rsync -av --mkpath ./_vols_/ ${RSYNC}/"
|
||||||
|
fi
|
||||||
|
printf "Backup end: $(date)\n" && \
|
||||||
|
popd || pexit "Error: using popd"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# e.g. rsync -av --mkpath ./_vols_/ "/srv/fsback/${HN}/$(date +%^a)/"
|
||||||
|
|
|
||||||
43
v2b.sh
43
v2b.sh
|
|
@ -4,25 +4,29 @@
|
||||||
set -u
|
set -u
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
|
if [[ $(id -u) -ne "0" ]]; then
|
||||||
|
printf "Elevated privileges required\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
UMASK="$(umask)"
|
UMASK="$(umask)"
|
||||||
|
|
||||||
cprompt () {
|
cprompt () {
|
||||||
if [[ $UNATTENDED == "true" ]]; then
|
if [[ $UNATTENDED == "true" ]]; then
|
||||||
return;
|
return;
|
||||||
fi
|
fi
|
||||||
read -r -s -N 1 -p "Press 'Enter' to continue "
|
read -r -s -N 1 -p "Press 'Enter' to backup, 'Escape' to skip..."
|
||||||
if [[ $REPLY != $'\n' ]]; then
|
if [[ $REPLY != $'\n' ]]; then
|
||||||
printf "\n"
|
printf "backup skipped!\n"
|
||||||
printf " Backup stopped!\n"
|
|
||||||
return 1
|
return 1
|
||||||
else
|
else
|
||||||
printf "\n"
|
printf "backup starting.\n"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
usage () {
|
usage () {
|
||||||
printf "v2b.sh <option> [ <prefix> ]\n"
|
printf "v2b.sh <option> [ <prefix> ]\n"
|
||||||
printf " <prefix> only backup volumes with this prefix\n"
|
printf " <prefix> only backup volumes with this prefix (underscore not required)\n"
|
||||||
printf " option: k (keep existing backups)\n"
|
printf " option: k (keep existing backups)\n"
|
||||||
printf " option: p (remove prefix from tar archive file name\n"
|
printf " option: p (remove prefix from tar archive file name\n"
|
||||||
printf " option: u (unattended backup)\n"
|
printf " option: u (unattended backup)\n"
|
||||||
|
|
@ -40,7 +44,7 @@ while getopts ':s:pku' OPT; do
|
||||||
case $OPT in
|
case $OPT in
|
||||||
s) SEND="true"; ADDR="${OPTARG}"; OUTPUT="${OUTPUT} Option: SEND BACKUPS\n";;
|
s) SEND="true"; ADDR="${OPTARG}"; OUTPUT="${OUTPUT} Option: SEND BACKUPS\n";;
|
||||||
p) REMOVE="true"; OUTPUT="${OUTPUT} Option: PREFIXES REMOVED\n";;
|
p) REMOVE="true"; OUTPUT="${OUTPUT} Option: PREFIXES REMOVED\n";;
|
||||||
r) KEEP="true"; OUTPUT="${OUTPUT} Option: KEEP EXISTING BACKUPS\n";;
|
k) KEEP="true"; OUTPUT="${OUTPUT} Option: KEEP EXISTING BACKUPS\n";;
|
||||||
u) UNATTENDED="true"; OUTPUT="${OUTPUT} Option: UNATTENDED BACKUP\n";;
|
u) UNATTENDED="true"; OUTPUT="${OUTPUT} Option: UNATTENDED BACKUP\n";;
|
||||||
\?) usage; exit;;
|
\?) usage; exit;;
|
||||||
esac
|
esac
|
||||||
|
|
@ -50,9 +54,9 @@ shift $((OPTIND -1))
|
||||||
FOLDER="_vols_"
|
FOLDER="_vols_"
|
||||||
|
|
||||||
if [[ $# > 0 ]]; then
|
if [[ $# > 0 ]]; then
|
||||||
VOLUMES="$(sudo docker volume ls -q |grep "${1}")"
|
VOLUMES="$(docker volume ls -q |grep "${1}_")"
|
||||||
else
|
else
|
||||||
VOLUMES="$(sudo docker volume ls -q)"
|
VOLUMES="$(docker volume ls -q)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z $VOLUMES ]]; then
|
if [[ -z $VOLUMES ]]; then
|
||||||
|
|
@ -66,13 +70,14 @@ else
|
||||||
LASTF="${FOLDER}"
|
LASTF="${FOLDER}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
USER="$(stat -c '%u' $BASH_SOURCE)"
|
||||||
INDEX="$((( ${LASTF#${FOLDER}} + 0 )))"
|
INDEX="$((( ${LASTF#${FOLDER}} + 0 )))"
|
||||||
NEWFL="${FOLDER}$(printf "%05d" $((( ${INDEX} + 1 ))))"
|
NEWFL="${FOLDER}$(printf "%05d" $((( ${INDEX} + 1 ))))"
|
||||||
TEMPF="$(mktemp -dt -p $PWD _XXXXXXXXXXXXXXX_)"
|
TEMPF="$(sudo -u \#${USER?err} mktemp -dt -p $PWD _XXXXXXXXXXXXXXX_)"
|
||||||
|
|
||||||
for VOL in ${VOLUMES}; do
|
for VOL in ${VOLUMES}; do
|
||||||
if [[ $REMOVE == "true" ]]; then
|
if [[ $REMOVE == "true" ]]; then
|
||||||
if [[ -v 1 ]]; then
|
if [[ $# > 0 ]]; then
|
||||||
TAR="${VOL#${1}_}.tar.bz2"
|
TAR="${VOL#${1}_}.tar.bz2"
|
||||||
else
|
else
|
||||||
TAR="${VOL#*_}.tar.bz2"
|
TAR="${VOL#*_}.tar.bz2"
|
||||||
|
|
@ -80,13 +85,15 @@ for VOL in ${VOLUMES}; do
|
||||||
else
|
else
|
||||||
TAR="${VOL}.tar.bz2"
|
TAR="${VOL}.tar.bz2"
|
||||||
fi
|
fi
|
||||||
printf "${VOL} --> ${TEMPF}/${TAR}\n"
|
printf "\n${VOL} --> ${TEMPF}/${TAR}\n"
|
||||||
cprompt || break
|
cprompt || continue
|
||||||
sudo docker run --rm --log-driver none \
|
docker run --rm --log-driver none \
|
||||||
-v "${VOL}:/volume" \
|
-v "${VOL}:/volume" \
|
||||||
-v "${TEMPF}:/backup" \
|
-v "${TEMPF}:/backup" \
|
||||||
loomchild/volume-backup backup -v "${TAR}"
|
loomchild/volume-backup backup -v "${TAR}"
|
||||||
sudo chmod 600 "${TEMPF}/${TAR}"
|
if [[ -f "${TEMPF}/${TAR}" ]]; then
|
||||||
|
chmod 600 "${TEMPF}/${TAR}"
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ -z "$(ls -A ${TEMPF})" ]]; then
|
if [[ -z "$(ls -A ${TEMPF})" ]]; then
|
||||||
|
|
@ -100,12 +107,12 @@ else
|
||||||
if mv "${TEMPF}" "${FOLDER}"; then
|
if mv "${TEMPF}" "${FOLDER}"; then
|
||||||
if [[ $SEND == "true" ]]; then
|
if [[ $SEND == "true" ]]; then
|
||||||
if [[ $ADDR =~ ":" ]]; then
|
if [[ $ADDR =~ ":" ]]; then
|
||||||
if sudo ssh "${ADDR%:*}" "mkdir -p ${ADDR#*:}"; then
|
if ssh "${ADDR%:*}" "mkdir -p ${ADDR#*:}"; then
|
||||||
sudo scp "${FOLDER}"/* "${ADDR}"
|
scp "${FOLDER}"/* "${ADDR}"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if sudo ssh "${ADDR}" "mkdir -p ${PWD}/_$(hostname -f)_"; then
|
if ssh "${ADDR}" "mkdir -p ${PWD}/_$(hostname -f)_"; then
|
||||||
sudo scp "${FOLDER}"/* "${ADDR}:${PWD}/_$(hostname -f)_"
|
scp "${FOLDER}"/* "${ADDR}:${PWD}/_$(hostname -f)_"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
109
vvv.sh
109
vvv.sh
|
|
@ -4,8 +4,13 @@
|
||||||
set -u
|
set -u
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
|
if [[ $(id -u) -ne "0" ]]; then
|
||||||
|
printf "Elevated privileges required\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
usage () {
|
usage () {
|
||||||
printf "Usage: vvv.sh <project>\n"
|
printf "Usage: vvv.sh <options> <project>\n"
|
||||||
printf " project = Compose project folder.\n"
|
printf " project = Compose project folder.\n"
|
||||||
printf " Option r: restore operation\n"
|
printf " Option r: restore operation\n"
|
||||||
printf " Option d: keep containers down - don't bring back up\n"
|
printf " Option d: keep containers down - don't bring back up\n"
|
||||||
|
|
@ -13,26 +18,21 @@ usage () {
|
||||||
|
|
||||||
RESTORE="false"
|
RESTORE="false"
|
||||||
DOWN="false"
|
DOWN="false"
|
||||||
OUTPUT=""
|
OUTPUT=" Option: BACKUP OPERATION"
|
||||||
while getopts ':rd' OPT; do
|
while getopts ':rd' OPT; do
|
||||||
case $OPT in
|
case $OPT in
|
||||||
r) RESTORE="true"; OUTPUT="${OUTPUT} Option: RESTORE OPERATION";;
|
r) RESTORE="true"; OUTPUT=" Option: RESTORE OPERATION";;
|
||||||
d) DOWN="true"; OUTPUT="${OUTPUT} Option: KEEP DOWN";;
|
d) DOWN="true"; OUTPUT="${OUTPUT} Option: KEEP DOWN";;
|
||||||
\?) usage; exit;;
|
\?) usage; exit;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
shift $((OPTIND -1))
|
shift $((OPTIND -1))
|
||||||
|
|
||||||
if [[ $RESTORE == "true" ]] && [[ ! -f docker-restore.sh ]]; then
|
|
||||||
echo "Problem: docker-restore.sh missing!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
scripts () {
|
scripts () {
|
||||||
for MODE in backup restore; do
|
for MODE in backup restore; do
|
||||||
FILE="docker-${MODE}.sh"
|
FILE="docker-${MODE}.sh"
|
||||||
SCRIPT="#!/bin/bash"$'\n'
|
SCRIPT="#!/bin/bash"$'\n'
|
||||||
SCRIPT="${SCRIPT}sudo docker run --rm \\"$'\n'
|
SCRIPT="${SCRIPT}docker run --rm \\"$'\n'
|
||||||
SCRIPT="${SCRIPT} --name volumerize \\"$'\n'
|
SCRIPT="${SCRIPT} --name volumerize \\"$'\n'
|
||||||
SCRIPT="${SCRIPT} -e TZ=Australia/Perth \\"$'\n'
|
SCRIPT="${SCRIPT} -e TZ=Australia/Perth \\"$'\n'
|
||||||
SCRIPT="${SCRIPT} -e VOLUMERIZE_SOURCE=/source \\"$'\n'
|
SCRIPT="${SCRIPT} -e VOLUMERIZE_SOURCE=/source \\"$'\n'
|
||||||
|
|
@ -54,12 +54,11 @@ scripts () {
|
||||||
printf "Fatal error 1.\n"
|
printf "Fatal error 1.\n"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
printf "${SCRIPT}" > "${FILE}"
|
printf "${SCRIPT}" |sudo -u "#${USER?err}" tee "${FILE}"
|
||||||
chmod +x "${FILE}"
|
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ $# -lt 1 ]]; then
|
if [[ ! $# -eq 1 ]]; then
|
||||||
usage
|
usage
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
@ -70,52 +69,78 @@ if [[ ! -d "../${PROJECT}" ]]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
VOLUMES="$(sudo ls /var/lib/docker/volumes |grep "${PROJECT}_")"
|
VOLUMES="$(ls /var/lib/docker/volumes |grep "${PROJECT}_")"
|
||||||
if [[ -z "$VOLUMES" ]]; then
|
if [[ -z "$VOLUMES" ]]; then
|
||||||
printf "There are no volumes found to backup/restore!\n"
|
printf "There are no volumes found to backup/restore!\n"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
printf "${OUTPUT}\n"
|
||||||
|
if timeout --preserve-status --foreground 10 bash -c 'read -r -s -N 1 -p "Starting delay of 10 seconds. Press a key to cancel... "'; then
|
||||||
|
printf "cancelled\n"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
printf "starting\n"
|
||||||
|
fi
|
||||||
|
|
||||||
|
USER=$(stat -c '%u' $BASH_SOURCE)
|
||||||
|
|
||||||
pushd "../${PROJECT}" > /dev/null || exit 1
|
pushd "../${PROJECT}" > /dev/null || exit 1
|
||||||
|
|
||||||
|
if [[ $RESTORE == "true" ]] && [[ ! -f docker-restore.sh ]]; then
|
||||||
|
echo "Problem: docker-restore.sh missing!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ ! $RESTORE == "true" ]]; then
|
if [[ ! $RESTORE == "true" ]]; then
|
||||||
scripts
|
scripts
|
||||||
fi
|
fi
|
||||||
|
|
||||||
COMMAND="sudo docker compose stop"
|
for COMP in docker-compose*.yml; do
|
||||||
printf "${COMMAND}\n"
|
if command -v docker-compose; then
|
||||||
${COMMAND}
|
COMMAND="docker-compose -f $COMP stop"
|
||||||
if ! ${COMMAND}; then
|
else
|
||||||
printf "Services 'docker compose stop' error."
|
COMMAND="docker compose -f $COMP stop"
|
||||||
exit 1
|
fi
|
||||||
fi
|
printf "${COMMAND}\n"
|
||||||
COMMAND="sudo docker compose rm -f"
|
if ! bash -c "${COMMAND}"; then
|
||||||
printf "${COMMAND}\n"
|
printf "Services 'docker compose stop' error."
|
||||||
${COMMAND}
|
exit 1
|
||||||
if ! ${COMMAND}; then
|
fi
|
||||||
printf "Services 'docker compose rm' error."
|
done
|
||||||
exit 1
|
|
||||||
fi
|
for COMP in docker-compose*.yml; do
|
||||||
|
if command -v docker-compose; then
|
||||||
|
COMMAND="docker-compose -f $COMP rm -f"
|
||||||
|
else
|
||||||
|
COMMAND="docker compose -f $COMP rm -f"
|
||||||
|
fi
|
||||||
|
printf "${COMMAND}\n"
|
||||||
|
if ! bash -c "${COMMAND}"; then
|
||||||
|
printf "Services 'docker compose rm' error."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
if [[ $RESTORE == "true" ]]; then
|
if [[ $RESTORE == "true" ]]; then
|
||||||
"./docker-restore.sh"
|
bash "./docker-restore.sh"
|
||||||
else
|
else
|
||||||
"./docker-backup.sh"
|
bash "./docker-backup.sh"
|
||||||
if [[ $DOWN = "false" ]]; then
|
if [[ $DOWN = "false" ]]; then
|
||||||
COMMAND="sudo docker compose up -d"
|
for COMP in docker-compose*.yml; do
|
||||||
printf "${COMMAND}\n"
|
if command -v docker-compose; then
|
||||||
if ! ${COMMAND}; then
|
COMMAND="docker-compose -f $COMP up -d"
|
||||||
printf "Services 'up' error."
|
else
|
||||||
exit 1
|
COMMAND="docker compose -f $COMP up -d"
|
||||||
fi
|
fi
|
||||||
|
printf "${COMMAND}\n"
|
||||||
|
if ! bash -c "${COMMAND}"; then
|
||||||
|
printf "Services 'up' error."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
COMMAND="sudo docker compose up -d"
|
|
||||||
printf "${COMMAND}\n"
|
|
||||||
if ! ${COMMAND}; then
|
|
||||||
printf "Services 'up' error."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
popd > /dev/null || exit 1
|
popd > /dev/null || exit 1
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue