#!/bin/bash

#set -x

ME=$(basename $0);


source //etc/common-utils.rc
source //etc/ec2.rc


function _init ()
{
    return;
}

function wait_release ()
{
    num=$#;
    timeout=600;
    release_volumes="$@";

    for ((i=0; $i < $timeout; i++)); do
        echo -n "Waiting to detach $release_volumes ... ($(($timeout - $i)) secs)"

        for device in $release_volumes; do
            if [ ! -e $device ]; then
                release_volumes=$(echo ${release_volumes/$device/});
            fi
        done

        if [ -z "$release_volumes" ]; then
            echo " done."
            return;
        else
            echo " waiting."
        fi

        i=$(($i + 4));
        sleep 5;
    done

    echo " TIMEOUT.";
    false;
}

function wait_delete ()
{
    num=$#;
    timeout=600;
    delete_volumes="$@";

    for ((i=0; $i < $timeout; i++)); do
        echo -n "Waiting to delete $delete_volumes ... ($(($timeout - $i)) secs)"

        for volume in $delete_volumes; do
            string=$(ec2-describe-volumes --region $ec2_placement_region $volume 2>/dev/null);
            if [ -z "$string" ]; then
                delete_volumes=$(echo ${delete_volumes/$volume/});
            fi
        done

        if [ -z "$delete_volumes" ]; then
            echo " done."
            return;
        else
            echo " waiting."
        fi

        i=$(($i + 9));
        sleep 10;
    done

    echo " TIMEOUT.";
    false;
}

function release_ebs ()
{
    for volume in $@; do
        str=$(ec2-detach-volume --region $ec2_placement_region $volume);
    done
}

function delete_ebs ()
{
    for volume in $@; do
        echo "Deleting $volume ...";
        ec2-delete-tags --region $ec2_placement_region $volume \
            --tag Domain \
            --tag Brick \
            --tag Array \
            --tag Instance \
            --tag Name \
            --tag Device;
        ec2-delete-volume --region $ec2_placement_region  $volume;
    done
}

function umount_md_arrays ()
{
    for mdev in $@; do
        umount $mdev || true;
    done
}

function stop_md_arrays ()
{
    for mdev in $@; do
        mdadm --stop --scan $mdev
    done
}

function remove_entry_from_fstab ()
{
    for device in $@; do
        sed -i /$(basename $device)/d /etc/fstab
    done;
}


function show_help ()
{
    usage_banner;
    cat <<EOF

Usage:  $ME [-h] [-d] [MD-DEVICE]

Release attached EBS volumes.  If MD-DEVICE is given, EBS volumes
associated to that MD-DEVICE are released, otherwise all EBS volumes
are released.  MD-DEVICE is a RAID device created by
gluster-provision-storage tool.

Miscellaneous:
  -d                        delete/destroy EBS volumes after release
  -h                        display this help and exit

Example:
  $ME
  $ME -d /dev/md1
EOF
}


function main ()
{
    delete_option="no";
    # Parse command line arguments.
    while getopts :hd OPT; do
	case "$OPT" in
	    h)
		show_help
		exit 0
		;;
	    d)
		delete_option="yes"
		;;
	    \?)
                # getopts issues an error message
		echo "Invalid option: -$OPTARG"
		show_help
		exit 1
		;;
	esac
    done

    # Remove the switches we parsed above.
    shift `expr $OPTIND - 1`

    # We want only one non-option argument optionally.
    if [ $# -gt 1 ]; then
	show_help
	exit 1
    fi

    set -e

    if [ -n "$1" ]; then
	if [ ! -e "$1" ]; then
            echo "$1 doesn't exist"
            exit 1
        fi
        md_device_list="$1";
    else
	md_device_list=$(awk '$1 ~ "^md[0-9]+" { print "/dev/"$1 }' /proc/mdstat);
    fi

    if [ -z "$md_device_list" ]; then
	echo "No MD device found.  Nothing to do"
	exit 0
    fi

    device_list="";
    for mdev in $md_device_list; do
	if grep -wq "^$mdev" /proc/mounts; then
	    echo "ERROR: $mdev is mounted.  Please unmount first"
	    exit 1
	fi
        tmp_device_list=$(mdadm --detail $mdev  | grep /dev/sd | awk '{print $7 }');
        device_list=$(echo $device_list $tmp_device_list);
    done
    if [ -z "$device_list" ]; then
        echo "No EBS volumes attached.";
        exit 1;
    fi

    echo "Getting list of volumes attached ... ";
    volumes_list="";
    volumes_in_this_instance=$(ec2-describe-tags --region $ec2_placement_region | grep $ec2_instance_id | grep volume | cut -f3)
    voldump=$(ec2-describe-volumes --region $ec2_placement_region $volumes_in_this_instance);
    for device in $device_list; do
        volume=$(echo "$voldump" | grep attached | grep $device | cut -f2);
        volumes_list=$(echo $volumes_list $volume)
        echo "$volume - $device";
    done
    echo;

    echo Umounting $md_device_list ... ;
    umount_md_arrays $md_device_list;

    echo Stopping $md_device_list ... ;
    stop_md_arrays $md_device_list;

    echo Removing fstab entries ... ;
    remove_entry_from_fstab $md_device_list;

    echo "Detaching volumes from instance ..."
    release_ebs $volumes_list &

    wait_release $device_list;

    if [ "$delete_option" == "yes" ] ; then
        echo "Deleting EBS volumes ... ";
        delete_ebs $volumes_list
        wait_delete $volumes_list
    fi

    echo "Removing $md_device_list ... "
    rm -vf $md_device_list;
    echo "DONE."

    mdadm --detail --scan > /etc/mdadm.conf;
}


_init "$@" && main "$@"
