summaryrefslogblamecommitdiffstats
path: root/dev-tools/xmount_container2raw.sh
blob: 637daff7bb31a2ebd4d3b4ced267ada9874a725b (plain) (tree)





























































































































































                                                                               

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