diff options
Diffstat (limited to 'dev-tools')
-rwxr-xr-x | dev-tools/xmount_container2raw.sh | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/dev-tools/xmount_container2raw.sh b/dev-tools/xmount_container2raw.sh new file mode 100755 index 00000000..637daff7 --- /dev/null +++ b/dev-tools/xmount_container2raw.sh @@ -0,0 +1,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 |