forked from ricardobranco777/docker-volumes.sh
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-volumes.sh
More file actions
105 lines (91 loc) · 2.71 KB
/
docker-volumes.sh
File metadata and controls
105 lines (91 loc) · 2.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/bin/bash
#
# The docker-export and docker-commit/docker-save commands do not save the container volumes.
# Use this script to save and load the container volumes.
#
# NOTES:
# + This script could have been written in Python or Go, but the tarfile module and the tar package
# lack support for writing sparse files.
# + We use the Ubuntu docker image with tar v1.29+ that uses SEEK_DATA/SEEK_HOLE to manage sparse files.
#
VERSION="2.0.1"
# Set DOCKER=podman if you want to use podman instead of docker
DOCKER="${DOCKER:-docker}"
IMAGE="${IMAGE:-ubuntu:24.04}"
# We use .Destination since we're using --volumes-from
FILTER_BOTH='{{ range .Mounts }}{{ printf "%v\x00" .Destination }}{{ end }}'
FILTER_BIND='{{ range .Mounts }}{{ if eq .Type "bind" }}{{ printf "%v\x00" .Destination }}{{ end }}{{ end }}'
FILTER_VOLUME='{{ range .Mounts }}{{ if eq .Type "volume" }}{{ printf "%v\x00" .Destination }}{{ end }}{ end }}'
FILTER="$FILTER_BOTH"
show_usage() {
cat <<-EOF
Usage: $0 [-b|--bind] [-V|--volume] [-v|--verbose] CONTAINER save|load TARBALL
Options:
-b, --bind Use only bind-mounts
-V, --volume Use only internal volumes
-v, --verbose Be verbose
--version Print version and exit
-h, --help Show this help
EOF
}
verbose=""
while [[ $# -gt 0 ]]; do
case "$1" in
-b|--bind)
FILTER="$FILTER_BIND"
shift ;;
-V|--volume)
FILTER="$FILTER_VOLUME"
shift ;;
-v|--verbose)
verbose="-v"
shift ;;
-h|--help)
show_usage
exit 0 ;;
--version)
echo "$VERSION"
exit 0 ;;
-*)
echo "Invalid option: $1" >&2
show_usage >&2
exit 1 ;;
*)
break ;;
esac
done
if [[ $# -ne 3 || ! $2 =~ ^(save|load)$ ]] ; then
echo "Usage: $0 [-v|--verbose] CONTAINER [save|load] TARBALL" >&2
exit 1
fi
get_volumes () {
$DOCKER inspect --type container -f "$FILTER" "$CONTAINER" | head -c -1 | sort -uz
}
save_volumes () {
if [ -f "$TAR_FILE" ] ; then
echo "ERROR: $TAR_FILE already exists" >&2
exit 1
fi
umask 077
# Create a void tar file to avoid mounting its directory as a volume
touch -- "$TAR_FILE"
tmp_dir=$(mktemp -du -p /)
get_volumes | $DOCKER run --rm -i --volumes-from "$CONTAINER" -e LC_ALL=C.UTF-8 -v "$TAR_FILE:/${tmp_dir}/${TAR_FILE##*/}" "$IMAGE" tar -c -a $verbose --null -T- -f "/${tmp_dir}/${TAR_FILE##*/}"
}
load_volumes () {
if [ ! -f "$TAR_FILE" ] ; then
echo "ERROR: $TAR_FILE doesn't exist in the current directory" >&2
exit 1
fi
tmp_dir=$(mktemp -du -p /)
$DOCKER run --rm --volumes-from "$CONTAINER" -e LC_ALL=C.UTF-8 -v "$TAR_FILE:/${tmp_dir}/${TAR_FILE##*/}":ro "$IMAGE" tar -xp $verbose -S -f "/${tmp_dir}/${TAR_FILE##*/}" -C / --overwrite
}
CONTAINER="$1"
TAR_FILE=$(readlink -f "$3")
set -e
case "$2" in
save)
save_volumes ;;
load)
load_volumes ;;
esac