#!/bin/sh -e

. /lib/partman/lib/base.sh

db_get netcfg/get_hostname

# LVM uses '-' itself for separating VG and LV names
VG=$(echo $RET | tr -d -)
HOST=$RET

ask_again () {
    template=partman-lvmraid/$2
    db_fset $template seen false
    db_input $1 $template
    shift 2
    while [ -n "$1" ]; do
	db_subst $template $1 $2
	shift 2
    done
    if db_go; then
	ret=0
	db_get $template
    else ret=$?
    fi
}

partition_disks () {
    db_get partman-lvmraid/bootsize
    type=$1
    shift
    disable_swap
    vgchange --available n # free the MD devices
    if ! mdadm --stop --scan; then
        ask_again critical stop-raid
        exit
    fi
    for dev in $*; do
        # DOS compatibility is needed because of an MD bug (according to hpa)
	sfdisk -D -uM $dev <<EOF
,$RET,$type,*
,,$type
EOF
    done
}

case $1 in
    lvmraid)
        SELTEMPLATE=select-disks;;
    lvmpv)
        SELTEMPLATE=select-disk;;
    *)
        ask_again critical unknown-schema SCHEMA "$1"; exit;;
esac

if ! modprobe dm-mod; then
    ask_again critical no-dm-mod
    exit
fi

if vgck $VG; then
    db_set partman-lvmraid/volume-group-exists $VG
    ask_again critical volume-group-exists VG $VG
    [ $ret = 0 ] || exit
    VG=$RET
    lvremove -f $VG || true
    vgremove $VG || true
fi

pattern="s/, / /g"
for dev in $DEVICES/*=disc $DEVICES/*=xvda; do
    [ -d $dev ] || continue
    device=$(cat $dev/device)
    name=$(device_name $dev | tr , :)
    pattern="s|$name|$device|;$pattern"
    names="$names, $name"
done

ask_again critical $SELTEMPLATE CHOICES "${names#, }"
devices=$(echo $RET | sed -e "$pattern")

# FIXME: We're using Syslinux instead, leaving this here
#        for backward compatibility only.
# Install GRUB automatically in the MBR of each disk
for devfs in $devices; do
    # Convert from devfs to standard naming
    match=$(find /dev -type l -exec echo -n "{}:" \&\& readlink "{}" \; | sed -n -e "s|:${devfs#/dev/}$||;T;p")
    devnames="$devnames $match"
done
db_set grub-installer/bootdev $devnames

if [ $1 = lvmraid ]; then
    numdevs=$(echo $devices | wc -w | sed -e "s/^ *//")
    boots=$(echo $devices | sed -e "s|disc|part1|g")
    parts=$(echo $devices | sed -e "s|disc|part2|g")

    if [ $numdevs -eq 0 ]; then
        ask_again critical no-disks
        exit
    fi

    ask_again medium bootsize || true
    if [ $numdevs -eq 1 ]; then
        partition_disks 8e $devices
        boot=$devices
        pv=$parts
    else
        partition_disks fd $devices
        boot=/dev/md/0
        pv=/dev/md/1
        modprobe raid1
# Version 1 superblocks are not supported by Etch's initrd hooks
        mdadm --create $boot --auto=yes --homehost=$HOST --level=1      --raid-devices=$numdevs $boots --run
        if [ $numdevs = 2 ]; then level=1; else level=5; modprobe raid456; fi
        mdadm --create $pv   --auto=yes --homehost=$HOST --level=$level --raid-devices=$numdevs $parts --run
    fi
    logger partitioning done
else
    pv=$devices
fi

pvcreate -ff -y $pv
logger pvcreate done

vgcreate $VG $pv
logger vgcreate done

ask_again medium logical-volumes || true
# Ease parsing
VOLUMES=$(echo $RET | sed -e 's/ *//g;y/:,/ \n/')
echo "$VOLUMES" | while read name point size type options; do
    logger "LV name=($name) point=($point) size=($size) type=($type) options=($options)"
    lvcreate -L$size -n$name $VG
done
logger lvcreates done

stop_parted_server
rm -rf $DEVICES
restart_partman

if [ $1 = lvmraid ]; then
# Prepare the boot partition
    dev=$DEVICES/$(echo $boot | tr / =)
    cd $dev
# The ID (directory name) is of the form start-end; get the first partition.
# In a multi-disk setup there is only a single "partition": the raid device.
    id=$(ls -d *-* | sort -n | head -1)
    cd $id
    echo format >method
    touch format
    touch use_filesystem
    echo ext2 >filesystem
    echo /boot >mountpoint
    mkdir options
    cd options
    touch nodev noexec sync
    update_partition $dev $id
    logger ${dev##*/}/$id set up as /boot
fi

# Backup STDIN for update_partition (only single digit descriptor
# numbers are allowed in ash)
exec 9<&0

echo "$VOLUMES" | while read name point size type options; do
    dev=$DEVICES/=dev=mapper=$VG-$name
    cd $dev
    id=$(ls -d 0-*) # these devices are partitions, so they start at offset 0
    cd $id
    touch format
    if [ "$type" = swap ]; then
        echo swap >method
    else
        echo format >method
        touch use_filesystem
        echo $type >filesystem
        echo $point >mountpoint
        if [ -n "$options" ]; then
            mkdir options
            cd options
            for i in $options; do touch $i; done
            options=", options: $options" # for nicer logging
        fi
    fi
    update_partition $dev $id <&9 # with original STDIN
    logger ${dev##*/}/$id under $point set up as $type, options $options
done

# Finish partitioning
exit 100
