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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
xmount_binary="xmount"
dnbd3_binary="dnbd3-server"
image_file_or_directory=""
do_cleanup=false
container_formats="vmdk,vdi,vhd,qcow2"
print_usage() {
cat << EOF
Converts container images (vmdk,vdi,vhd,qcow2) to raw images (on the fly
via xmount).
Usage:
$0 [options] image_file_or_directory
Options:
-h --help Shows this help message.
-x --xmount Path to xmount. (default: "$xmount_binary").
-d --dnbd3 Path to dnbd3-server. (default: "$dnbd3_binary").
-c --cleanup Cleans up the image directory. Unmounts the images and
removes symlinks.
EOF
}
parse_command_line() {
while true; do
case "$1" in
-h|--help)
print_usage "$0"
exit 0
;;
-x|--xmount)
shift
xmount_binary="$1"
shift
;;
-d|--dnbd3)
shift
dnbd3_binary="$1"
shift
;;
-c|--cleanup)
do_cleanup=true
shift
;;
'') # no more parameters
break
;;
*)
if [ -z "$image_file_or_directory" ]; then
if [ -d "$1" ] || [ -f "$1" ]; then
image_file_or_directory="$(realpath "$1")"
else
echo "ERROR: \"$1\" is not a file or a directory."
exit 1
fi
shift
else
echo "ERROR: unsupported argument: \"$1\""
print_usage "$0"
return 1
fi
esac
done
}
cleanup_image() {
local image="$1"
local mountpoint="$(image_to_mountpoint "$image")"
echo "umounting $mountpoint"
if ! umount "$mountpoint";then
echo "WARNING: umount failed, try with sudo"
return 1
fi
rmdir "$mountpoint"
local link_name="$(image_to_link_name "$image")"
[ -L "$link_name" ] && unlink "$link_name"
}
cleanup() {
if [ -d "$image_file_or_directory" ]; then
local image
shopt -s nullglob # skip unmatched container formats
for image in "${image_file_or_directory}"/*.{$container_formats}.r*; do
cleanup_image "$image"
done
else
cleanup_image "$image_file_or_directory"
fi
}
check_binaries() {
echo $xmount_binary
if ! hash "$xmount_binary" 2>/dev/null; then
echo "xmount not found, " \
"install it or try to set the --xmount option"
exit 1
fi
if ! hash "$dnbd3_binary" 2>/dev/null; then
echo "dnbd3-server not found," \
" install it or try to set the --dnbd3 option"
exit 1
fi
}
image_to_mountpoint() {
# convert [imagename].[container_type].[revision] to
# [imagename].[container_type].[revision].xmount
local image="$1"
extension="${image#*.}"
basepath="${image%.$extension}"
echo "${basepath}.${extension}.xmount"
}
image_to_link_name() {
# convert [imagename].[container_type].[revision] to
# [imagename].[container_type].xmount.[revision]
local image="$1"
extension="${image#*.}"
basepath="${image%.$extension}"
revision="${extension#*.}"
container_type="${extension%.*}"
echo "${basepath}.${container_type}.xmount.${revision}"
}
convert_image() {
local image="$1"
[ -d "$image" ] && return 0
local mountpoint="$(image_to_mountpoint "$image")"
local link_name="$(image_to_link_name "$image")"
echo "creating mountpoint: \"$mountpoint\""
mkdir "$mountpoint" || return 1
${xmount_binary} -o nonempty --in qemu "$image" \
--out raw "${mountpoint}"
echo "creating link: \"$link_name\""
ln -s --relative "${mountpoint}"/*.dd "$link_name"
}
convert() {
if [ -d "$image_file_or_directory" ]; then
local image
shopt -s nullglob # skip unmatched container formats
for image in "${image_file_or_directory}"/*.{vmdk,vdi,vhd,qcow2}.r*; do
convert_image "$image"
done
else
convert_image "$image_file_or_directory"
fi
}
parse_command_line "$@"
if $do_cleanup; then
cleanup
else
check_binaries
convert
fi
|