Add docker-volume-backup and docker-volume-restore binaries

This commit is contained in:
2018-03-16 16:22:28 +00:00
parent 7c6427d952
commit e1d20e237a
2 changed files with 203 additions and 0 deletions

97
bin/docker-volume-backup Executable file
View File

@@ -0,0 +1,97 @@
#! /usr/bin/env bash
set -e
abs_dirname () {
local path="$1"
local cwd
cwd="$(pwd)"
while [ -n "$path" ]; do
cd "${path%/*}" 2>/dev/null
local name="${path##*/}"
path="$(resolve_link "$name" || true)"
done
pwd
cd "$cwd"
}
abs_path () {
local path="$1"
echo "$(cd "$(abs_dirname "$path")" && pwd)/$(basename "$path")"
}
resolve_link () {
$(type -p greadlink readlink | head -1) "$1"
}
resolve_dest () {
local dest="$1"
if [ -z "$dest" ]; then
dest="$(pwd)/${volname}_$(date '+%Y-%m-%d_%H-%M-%S').tar.gz"
fi
dest="$(abs_path "$dest")"
if [ -f "$dest" ]; then
echo "ERROR: \"${dest}\" already exists." 1>&2
exit 1
fi
echo "$dest"
}
resolve_dest_dir () {
local dest="$1"
local dir
dir="$(dirname "$dest")"
if [ ! -d "$dir" ]; then
echo "ERROR: \"$dir\" is not a directory."
fi
echo "$dest_dir"
}
help () {
echo "usage: docker-volume-backup <vol-name> [<output-filename>]"
echo ""
echo "Backs up contents of <vol-name> to a gzipped tar archive."
echo ""
echo "If optional <output-filename> argument is given, it should"
echo "end with \".tar.gz\". If <output-filename> is not given,"
echo "resulting file with be named: <vol-name>_<datetime>.tar.gz"
}
main () {
local volname="$1"
local dest="$2"
local dest_dir
if [ -z "$volname" ]; then
help 1>&2
exit 1
fi
if ! docker volume inspect "$volname" &>/dev/null; then
echo "ERROR: Volume \"${volname}\" does not exist." 1>&2
exit 1
fi
dest="$(resolve_dest "$dest")"
dest_dir="$(resolve_dest_dir "$dest")"
dest_file="$(basename "$dest")"
echo "Starting volume backup to: ${dest}"
docker run --rm \
--volume "${volname}:/source/${volname}" \
--volume "${dest_dir}:/target" \
alpine:latest \
sh -c "cd /source && tar -cvzf \"/target/${dest_file}\" \"${volname}\""
echo "Volume \"${volname}\" was backed up to: ${dest}"
}
main "$@"

106
bin/docker-volume-restore Executable file
View File

@@ -0,0 +1,106 @@
#! /usr/bin/env bash
set -e
abs_dirname () {
local path="$1"
local cwd
cwd="$(pwd)"
while [ -n "$path" ]; do
cd "${path%/*}" 2>/dev/null
local name="${path##*/}"
path="$(resolve_link "$name" || true)"
done
pwd
cd "$cwd"
}
abs_path () {
local path="$1"
echo "$(cd "$(abs_dirname "$path")" && pwd)/$(basename "$path")"
}
resolve_link () {
$(type -p greadlink readlink | head -1) "$1"
}
resolve_archive() {
local archive="$1"
archive="$(abs_path "$archive")"
if [ ! -f "$archive" ]; then
echo "ERROR: \"${archive}\" is not a file." 1>&2
exit 1
fi
echo "$archive"
}
resolve_volname () {
local archive="$1"
local file
local dir
file="$(basename "$archive")"
dir="$(dirname "$archive")"
docker run --rm \
--volume "${dir}:/source" \
alpine:latest \
sh -c "tar --exclude=\"*/*/*\" -tzf \"/source/${file}\" \
| grep -v '^[^/]\+/[^/]\+$' | sed s'/.$//'" 2>/dev/null
}
help () {
echo "usage: docker-volume-restore <archive> [<volume-name>]"
echo ""
echo "Input <archive> should be a *.tar.gz producded by the"
echo "docker-volume-backup command."
}
main () {
local archive="$1"
local volname="$2"
local archive_volname
local archive_file
local archive_dir
if [ -z "$archive" ]; then
help 1>&2
exit 1
fi
archive="$(resolve_archive "$archive")"
archive_file="$(basename "$archive")"
archive_dir="$(dirname "$archive")"
archive_volname="$(resolve_volname "$archive")"
if [ "$(echo "$archive_volname" | wc -l)" -gt 1 ]; then
echo "ERROR: \"$archive_file\" has more than one root directory." 1>&2
exit 1
fi
if [ -z "$volname" ]; then
volname="$archive_volname"
fi
if docker volume inspect "$volname" &>/dev/null; then
echo "ERROR: Volume \"${volname}\" already exists." 1>&2
exit 1
fi
echo "Restoring volume ${volume} from: ${archive_file}"
docker volume create "$volname"
docker run --rm \
--volume "${volname}:/target" \
--volume "${archive_dir}:/source" \
alpine:latest \
sh -c "cd /target && tar --strip-components=1 \
-xvzf \"/source/${archive_file}\""
echo "Volume \"${volname}\" was restored from: ${archive_file}"
}
main "$@"