#!/bin/bash

#DEBUG#set -x

### Include ymclibnettools
. /usr/lib/lib-fliwi/ymc-networktools.bash


lvm_group_prefix="fliwi_lvm_"
lvm_default_volume_group="platters"

ymc_cluster_action='undefined'
ymc_cluster_noreboot=$1
ymc_cluster_noswraid=$2
ymc_cluster_consoles=''
ymc_cluster_raw_consoles=''
ymc_cluster_serial_console_infos=''
ymc_cluster_clocksource=''
fliwi_rootdelay=''
fliwi_no_kms=0
serial_console_hw_flow_control_switch='-h'
proc_cmdline='/proc/cmdline'

FLIWI_APT_MIRROR="http://apt-cacher:3142/fliwi"
FLIWI_DISTRIBUTION="production"
FLIWI_COMPONENTS="main"

FLIWI_DEBIAN_APT_MIRROR="http://apt-cacher:3142/debian"
FLIWI_DEBIAN_DISTRIBUTION="stable"
FLIWI_DEBIAN_COMPONENTS="main"
FLIWI_DEBIAN_EXTRA_PACKAGES="grub-pc nfs-common lvm2 mdadm postfix reiserfsprogs e2tools atop openssh-server xfsprogs"


### Include some basic configuration
. /etc/fliwi-in-memory-system/base.conf

ymc_cluster_nfs_root_wait_for_partition_to_appear()
{
  local partition_with_dev_to_wait_for=$1
  local loop_protection=30

  if [ -z "$partition_with_dev_to_wait_for" ]; then
    echo -n "WARNING: Can not wait for empty block-device '$partition_with_dev_to_wait_for' to appear...FAILED"
    sleep 5
    return 1
  fi

  echo -n "NOTICE: Waiting for '$partition_with_dev_to_wait_for' to appear..."

  while [ $loop_protection -gt 0 ]
  do
    if [ -b "$partition_with_dev_to_wait_for" ]; then
      echo "OKAY"
      sleep 1
      return 0
    else
      udevadm settle 1>/dev/null 2>/dev/null

      if [ -d "/sys/block/$(basename $partition_with_dev_to_wait_for)" ]; then
        drive_to_read_partition_table_from="/dev/$(basename $partition_with_dev_to_wait_for)"
      else
        drive_to_read_partition_table_from="/dev/$(basename $(dirname $(find /sys/block/*/ -maxdepth 1 -type d | grep -E -e $(basename $partition_with_dev_to_wait_for)'$' | head -n 1)))"
      fi

      if [ -b "$drive_to_read_partition_table_from" ]; then
        blockdev --rereadpt $drive_to_read_partition_table_from  1>/dev/null 2>/dev/null
      fi

      echo -n -e '\r'
      echo -n "NOTICE: Waiting for '$partition_with_dev_to_wait_for' to appear... [$loop_protection]  "
      sleep 1
      echo -n -e '\r'
      echo -n "                                                                               "
      echo -n -e '\r'
      echo -n "NOTICE: Waiting for '$partition_with_dev_to_wait_for' to appear..."

    fi

    loop_protection=$(expr $loop_protection - 1)
  done

  echo "FAILED"

  return 1
}

fliwi_minimal_clean_block_device()
{
  local block_device_with_dev_to_clean=$1

  if [ ! -b "$block_device_with_dev_to_clean" ]; then
    echo "WARNING: Can not clean '$block_device_with_dev_to_clean', since it is not a block-device"
    return 1
  fi

  size_in_512_block=$(blockdev --getsz $block_device_with_dev_to_clean)
  if [ $? -ne 0 ]; then
    echo "WARNING: Can not clean '$block_device_with_dev_to_clean', since its size could not be retrieved"
    return 1
  fi

  size_in_512_block=$(echo $size_in_512_block | sed -r 's/[^0-9]//g')
  if [ -z "$size_in_512_block" ]; then
    echo "WARNING: Can not clean '$block_device_with_dev_to_clean', since its size is invalid"
    return 1
  fi

  if [ $(expr $size_in_512_block / 512) -le 16 ]; then
    echo -n "INFO: Cleaning full device '$block_device_with_dev_to_clean'..."
    dd if=/dev/zero of=$block_device_with_dev_to_clean oflag=direct bs=512 2>/dev/null 1>&2
    echo "DONE"
  else
    echo -n "INFO: Cleaning first 8M of '$block_device_with_dev_to_clean'..."
    dd if=/dev/zero of=$block_device_with_dev_to_clean oflag=direct bs=512 count=16 2>/dev/null 1>&2
    echo "DONE"

    echo -n "INFO: Cleaning last 8M of '$block_device_with_dev_to_clean'..."
    dd if=/dev/zero of=$block_device_with_dev_to_clean oflag=direct bs=512 seek=$(expr $size_in_512_block - 16) 2>/dev/null 1>&2
    echo "DONE"
  fi

  return 0
}

ymc_install_package()
{
  LC_ALL=C DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical \
    apt-get --yes --no-install-recommends install $@
  apt-get clean
}

### Update time using ntpdate
echo "I: Updating system time using ntpdate..." 1>&2
ntpdate-debian

### First install fliwi-apt-config, if it is not present
dpkg -l fliwi-apt-config 2>/dev/null 1>&2
if [ $? -ne 0 ]; then
  apt-get update
  ymc_install_package fliwi-apt-config
fi

### Update our package list
apt-get update

### We will need some additional packages for the installer, but do not
### want them to execute their init-scripts during install...
### Add a policy-flag for that!
echo '#!/bin/sh'> /usr/sbin/policy-rc.d
echo 'exit 101' >> /usr/sbin/policy-rc.d
chmod 755 /usr/sbin/policy-rc.d

### Now install some additional packages we need for this installer
ymc_install_package mdadm
ymc_install_package lvm2

### Now we can safely remove the policy-flag, again...
rm -f /usr/sbin/policy-rc.d

### Now install some more additional packages we need for this installer
ymc_install_package parted
ymc_install_package gdisk
ymc_install_package debootstrap

### Now that we have everything in place, do some cleanup to get more space...
rm -f /var/cache/apt/pkgcache.bin /var/cache/apt/srcpkgcache.bin
rm -f /var/lib/apt/lists/*_Release /var/lib/apt/lists/*_Packages




if [ ! -f "$proc_cmdline" ]; then
  echo "ERROR: '$proc_cmdline' not found..." 1>&2
  exit 1
fi

for x in $(cat $proc_cmdline); do
  case $x in
    console=*)
      ymc_cluster_raw_consoles=$ymc_cluster_raw_consoles${x#console=}' '
    ;;

    FLIWI_NO_HW_FLOW_CONTROL)
      serial_console_hw_flow_control_switch=''
    ;;

    clocksource=*)
      ymc_cluster_clocksource=${x#clocksource=}
    ;;

    rootdelay=*)
      fliwi_rootdelay=${x#rootdelay=}
    ;;

    nomodeset)
      fliwi_no_kms=1
    ;;
  esac
done



ymc_cluster_consoles=$(echo $ymc_cluster_raw_consoles | sed -r 's/^([^,]+),.*/\1/' | sed -r 's/ +$//')
if [ "$ymc_cluster_consoles" == '' ]; then
  ymc_cluster_consoles='tty0'
fi

ymc_cluster_console_string_grub=''
for ymc_cluster_raw_console in $ymc_cluster_raw_consoles
do
  if [ $(echo $ymc_cluster_raw_console | grep -c -E -e '^ttyS') -ne 0 ]; then
    ymc_cluster_console_string_grub=$ymc_cluster_console_string_grub" console=$ymc_cluster_raw_console"
    ymc_cluster_serial_console_infos=$ymc_cluster_serial_console_infos' '$ymc_cluster_raw_console
  else
    ymc_cluster_console_string_grub=$ymc_cluster_console_string_grub" console=$ymc_cluster_raw_console"
  fi
done
ymc_cluster_serial_console_infos=$(echo $ymc_cluster_serial_console_infos | sed -r 's/ +$//')


disk_sizes=''
drives=$(ymc_get_harddrives)

###### Sizes are in GB and NO BASH INTEGERS!

### Stop lvm
/etc/init.d/lvm2 stop

### Stop mdadm-raid
/etc/init.d/mdadm-raid stop

### Find LVM physical volumens
old_lvm_physical_volumes=$(pvscan --short 2>/dev/null | grep -E -e '[ \t]*/dev/')
for old_lvm_physical_volume in $old_lvm_physical_volumes
do
  ## Wipe out...
  if [ -b "$old_lvm_physical_volume" ]; then
    echo "Destroying LVM physical volume $old_lvm_physical_volume..."
    pvremove -ff -y $old_lvm_physical_volume
    if [ $? -eq 0 ]; then
      echo "DONE"
    else
      echo "FAILED"
    fi
  fi
done


### Stop all sw-raids
for raid_device in $(ls /dev/md*)
do
  if [ -b "$raid_device" ]; then
    echo -e "Stopping sw-raid $raid_device..."
    mdadm $raid_device --fail detached --remove detached --stop
    if [ $? -eq 0 ]; then
      echo "DONE"
    else
      echo "FAILED"
    fi
  fi
done

for drive in $drives
do
  disk_size=$(ymc_simple_calc "$(ymc_get_disk_size $drive) / 1024 / 1024 / 1024")
  disk_size_washed=$(echo $disk_size | sed -r 's/\./_/g' )
  if [ $(ymc_contains $disk_size $disk_sizes) -eq 0 ]; then
    disk_sizes=$disk_sizes' '$disk_size
    eval $(echo disks_$disk_size_washed=$drive)
  else
    eval $(echo disks_$disk_size_washed=\"$(ymc_var_value disks_$disk_size_washed) $drive\")
    ### Just a dummy line to fix older jedit-shell-parseres #"
  fi
done

#echo $disk_sizes
lvm_vg_created=""
md_device_number=1
boot_drives_with_dev=''
boot_drives_with_devnum=''
disk_group_controlled_devices=''

### First proceed disk-groups //start
for disk_group_name in $(fliwi-get-my-disk-groups --show-name)
do
  echo "INFO: Processing (host-)disk-group '$disk_group_name'..."
  disk_group_devices=$(fliwi-get-my-disk-groups --show-devices --limit=$disk_group_name) && \
  disk_group_sizes=$(fliwi-get-my-disk-groups --show-sizes --limit=$disk_group_name)  && \
  disk_group_partitions=$(fliwi-get-my-disk-groups --show-partitions --limit=$disk_group_name) || false
  if [ $? -ne 0 ] || \
     [ "$disk_group_devices" == "" ] || \
     [ "$disk_group_sizes" == "" ]; then
    echo "ERROR: Can not get all required disk-group-definitions from cluster-config for (host-)disk-group '$disk_group_name'" 1>&2
    exit 1
  fi

  disk_group_controlled_devices="$disk_group_controlled_devices $disk_group_devices"

  ### Do some basic checks //start
  tmp_disk_counter=0
  for disk_group_device in $disk_group_devices
  do
    tmp_disk_counter=$(expr $tmp_disk_counter + 1)
    disk_group_device_without_dev=$(echo $disk_group_device | sed -r 's|^/dev/||')

    if [ ! -b "$disk_group_device" ]; then
      echo "ERROR: Non-existing block-device '$disk_group_device' configured in (host-)disk-group '$disk_group_name'" 1>&2
      exit 1
    fi

    check_size=$(echo $disk_group_sizes | cut -d ' ' -f $tmp_disk_counter)
    check_size_number=$(echo $check_size | sed -r 's/[^0-9]//g')
    check_size_in_gb=0
    if [ $(echo $check_size | grep -c -E -e 'T$') -eq 1 ]; then
      check_size_in_gb=$(ymc_simple_calc "$check_size_number * 1024")
    elif [ $(echo $check_size | grep -c -E -e 'G$') -eq 1 ]; then
      check_size_in_gb=$check_size_number
    elif [ $(echo $check_size | grep -c -E -e 'M$') -eq 1 ]; then
      check_size_in_gb=$(ymc_simple_calc "$check_size_number / 1024" | sed -r 's/([^.]+)\..*/\1/')
    elif [ $(echo $check_size | grep -c -E -e 'K$') -eq 1 ]; then
      check_size_in_gb=$(ymc_simple_calc "$check_size_number / 1024 / 1024" | sed -r 's/([^.]+)\..*/\1/')
    else
      echo "ERROR: No size-unit given for '$disk_group_device' configured in (host-)disk-group '$disk_group_name'" 1>&2
      exit 1
    fi

    check_size_in_gb=$(echo $check_size_in_gb | sed -r 's/[^0-9]//g')
    if [ -z "$check_size_in_gb" ] || \
       [ $check_size_in_gb -le 0 ]; then
      echo "ERROR: Can not determine checksize for '$disk_group_device' configured in (host-)disk-group '$disk_group_name'" 1>&2
      exit 1
    fi

    existing_disk_size_in_GB_by_1024=$(ymc_simple_calc "$(ymc_get_disk_size $disk_group_device_without_dev) / 1024 / 1024 / 1024" | sed -r 's/([^.]+)\..*/\1/')
    existing_disk_size_in_GB_by_1000=$(ymc_simple_calc "$(ymc_get_disk_size $disk_group_device_without_dev) / 1000 / 1000 / 1000" | sed -r 's/([^.]+)\..*/\1/')
    if [ -z "$existing_disk_size_in_GB_by_1024" ] && \
       [ -z "$existing_disk_size_in_GB_by_1000" ]; then
      echo "ERROR: Can not get size of '$disk_group_device' for (host-)disk-group '$disk_group_name'" 1>&2
      exit 1
    elif [ $existing_disk_size_in_GB_by_1024 -ne $check_size_in_gb ] && \
         [ $existing_disk_size_in_GB_by_1000 -ne $check_size_in_gb ]; then
      echo "ERROR: No match between configured and real size of '$disk_group_device' for (host-)disk-group '$disk_group_name'" 1>&2
      echo "       Configured: "$check_size_in_gb"GB" 1>&2
      echo "             Real: "$existing_disk_size_in_GB_by_1024"GB ("$existing_disk_size_in_GB_by_1000"GB divided by thousands)" 1>&2
      exit 1
    fi
  done
  tmp_disk_counter=""
  ### Do some basic checks //end


  ### Setup partitions //start
  for disk_group_device in $disk_group_devices
  do
    disk_group_device_without_dev=$(echo $disk_group_device | sed -r 's|^/dev/||')

    parted --script --align=opt $disk_group_device "mklabel GPT"
    fliwi_minimal_clean_block_device $disk_group_device

    tmp_partition_counter=2
    partition_start_mib=256

    parted --script --align=opt $disk_group_device "mklabel GPT"
    parted --script --align=opt $disk_group_device "mkpart grub 1MiB 4MiB"
    parted --script --align=opt $disk_group_device "set 1 bios_grub on"
    ymc_cluster_nfs_root_wait_for_partition_to_appear $disk_group_device'1'
    fliwi_minimal_clean_block_device $disk_group_device'1'

    parted --script --align=opt $disk_group_device "mkpart boot 4MiB 256MiB"
    parted --script --align=opt $disk_group_device "set 2 raid on"
    ymc_cluster_nfs_root_wait_for_partition_to_appear $disk_group_device'2'
    fliwi_minimal_clean_block_device $disk_group_device'2'

    for disk_group_partition in $disk_group_partitions
    do
      tmp_partition_counter=$(expr $tmp_partition_counter + 1)

      partition_size=$(echo $disk_group_partition | cut -s -d ':' -f 1)
      if [ $partition_start_mib -le 0 ]; then
        echo "ERROR: Only the last partition configured can use all remain space in (host-)disk-group '$disk_group_name'" 1>&2
        exit 1
      elif [ "$partition_size" = "REMAINING" ]; then
        partition_end_mib="-1"
      else
        partition_size_number=$(echo $partition_size | sed -r 's/[^0-9]//g')
        partition_size_in_mib=0
        if [ $(echo $partition_size | grep -c -E -e 'T$') -eq 1 ]; then
          partition_size_in_mib=$(ymc_simple_calc "$partition_size_number * 1000 * 1000")
        elif [ $(echo $partition_size | grep -c -E -e 'G$') -eq 1 ]; then
          partition_size_in_mib=$(ymc_simple_calc "$partition_size_number * 1000")
        elif [ $(echo $partition_size | grep -c -E -e 'M$') -eq 1 ]; then
          partition_size_in_mib=$partition_size_number
        elif [ $(echo $partition_size | grep -c -E -e 'K$') -eq 1 ]; then
          partition_size_in_mib=$(ymc_simple_calc "$partition_size_number / 1000" | sed -r 's/([^.]+)\..*/\1/')
        else
          echo "ERROR: No size-unit given for partition #$tmp_partition_counter configured in (host-)disk-group '$disk_group_name'" 1>&2
          exit 1
        fi

        partition_size_in_mib=$(echo $partition_size_in_mib | sed -r 's/[^0-9]//g')
        if [ -z "$partition_size_in_mib" ] || \
           [ $partition_size_in_mib -le 0 ]; then
          echo "ERROR: Can not determine size for partition #$tmp_partition_counter configured in (host-)disk-group '$disk_group_name'" 1>&2
          exit 1
        fi
        partition_end_mib=$(ymc_simple_calc "$partition_start_mib + $partition_size_in_mib")
      fi

      partition_type_info=$(echo $disk_group_partition | cut -s -d ':' -f 2)
      partition_type=$(echo $partition_type_info | cut -d '-' -f 1)
      case "$partition_type" in
        RAID)
          partition_type_for_parted="raid"
        ;;

        LVM)
          partition_type_for_parted="lvm"
        ;;

        DATA)
          partition_type_for_parted="data"
        ;;

        *)
          echo "ERROR: Can not handle partition-type '$partition_type' configured for partition #$tmp_partition_counter in (host-)disk-group '$disk_group_name'" 1>&2
          exit 1
        ;;
      esac


      echo "INFO: Will create a partition on '$disk_group_device':"
      echo "      Size: $partition_size"
      echo "      Type: $partition_type"

      partition_start_string_for_parted=$partition_start_mib"MiB"
      partition_end_string_for_parted=$partition_end_mib"MiB"
      parted --script --align=opt $disk_group_device "mkpart $partition_type_for_parted $partition_start_string_for_parted $partition_end_string_for_parted"
      if [ "$partition_type_for_parted" != "data" ]; then
        parted --script --align=opt $disk_group_device "set $tmp_partition_counter $partition_type_for_parted on"
      else
        ### Parted currently does not support linux-data-partion-flag, therefore we use sgdisk
        sgdisk -t $tmp_partition_counter:0FC63DAF-8483-4772-8E79-3D69D8477DE4 $disk_group_device
      fi

      ### Make sure the kernel is aware of the new partitions
      ymc_cluster_nfs_root_wait_for_partition_to_appear $disk_group_device$tmp_partition_counter
      fliwi_minimal_clean_block_device $disk_group_device$tmp_partition_counter

      partition_start_mib="$partition_end_mib"
    done

    boot_drive_to_add='/dev/'$(ymc_get_partition_for_drive_by_num $disk_group_device_without_dev 2)
    if [ $(ymc_contains "$boot_drive_to_add" $boot_drives_with_devnum) -eq 0 ]; then
      boot_drives_with_devnum=$boot_drives_with_devnum' '$boot_drive_to_add
    fi

    if [ $(ymc_contains "$disk_group_device" $boot_drives_with_dev) -eq 0 ]; then
      boot_drives_with_dev=$boot_drives_with_dev' '$disk_group_device
    fi

    partition_start_mib=""
    tmp_partition_counter=""
  done
  ### Setup partitions //end

  ### Make the disk-group usable (create raid-volume, setup LVM or generate filesystems) //start
  tmp_partition_counter=1
  for disk_group_partition in $disk_group_partitions
  do
    tmp_partition_counter=$(expr $tmp_partition_counter + 1)
    local_partition_number=$(expr $tmp_partition_counter + 1)

    partition_type_info=$(echo $disk_group_partition | cut -s -d ':' -f 2)
    partition_type=$(echo $partition_type_info | cut -d '-' -f 1)
    partition_type_extra=$(echo $partition_type_info | cut -s -d '-' -f 2)

    ### Process each drive... //start
    for disk_group_device in $disk_group_devices
    do
      disk_group_device_without_dev=$(echo $disk_group_device | sed -r 's|^/dev/||')
      partition_dev_string='/dev/'$(ymc_get_partition_for_drive_by_num $disk_group_device_without_dev $local_partition_number)

      ymc_cluster_nfs_root_wait_for_partition_to_appear $partition_dev_string
      fliwi_minimal_clean_block_device $partition_dev_string

      case "$partition_type" in
        RAID)
          echo "INFO: Will use '$partition_dev_string' as a drive for the RAID '$partition_type_extra'..."
          ymc_set_var_content "raid_devices_$partition_type_extra" "$(ymc_var_value raid_devices_$partition_type_extra) $partition_dev_string"
        ;;

        LVM)
          echo "INFO: Using '$partition_dev_string' as a LVM-PV..."
          ### Kill a possibly existing LVM physical volume on our freshly setup device (just in case...)
          pvremove -ff -y $partition_dev_string 1>/dev/null 2>&1
          if [ $? -eq 0 ]; then
            echo "Killed an old LVM-PV on '$partition_dev_string'"
          fi

          ### Create the LVM physical volume
          pvcreate -ff $partition_dev_string

          if [ -n "$partition_type_extra" ]; then
            if [ $(ymc_contains $partition_type_extra $lvm_vg_created) -eq 0 ]; then
              # Create
              vgcreate $lvm_group_prefix$partition_type_extra $partition_dev_string
              lvm_vg_created=$lvm_vg_created" $partition_type_extra"
            else
              # Extend
              vgextend $lvm_group_prefix$partition_type_extra $partition_dev_string
            fi
          else
            echo "INFO: Nothing done with LVM-PV '$partition_dev_string'..."
          fi
        ;;

        DATA)
          if [ -n "$partition_type_extra" ]; then
            echo "INFO: Creating a filesystem of type '$partition_type_extra' on '$partition_dev_string'..."
            mkfs.$partition_type_extra $partition_dev_string
            if [ $? -ne 0 ]; then
              mkfs.$partition_type_extra -f $partition_dev_string
              if [ $? -ne 0 ]; then
                echo "ERROR: Failed to create filesystem of type '$partition_type_extra' on '$partition_dev_string'" 1>&2
                exit 1
              fi
            fi
          else
            echo "INFO: Nothing done with data-partition '$partition_dev_string'..."
          fi
        ;;

        *)
          echo "NOTICE: Nothing to do for partition-type '$partition_type' configured for partition #$tmp_partition_counter in (host-)disk-group '$disk_group_name'" 1>&2
        ;;
      esac
    done
    ### Process each drive... //end

  done
  tmp_partition_counter=0
  ### Make the disk-group usable (create raid-volume, setup LVM or generate filesystems) //end

done
### First proceed disk-groups //end

### Second proceed raids //start
for raid_name in $(fliwi-get-my-raids --show-name)
do
  raid_drives_with_devnum=$(ymc_var_value "raid_devices_$raid_name")
  raid_level=$(fliwi-get-my-raids --limit=$raid_name --show-level)

  echo "INFO: setting up RAID '$raid_name' with level '$raid_level', using drives: $raid_drives_with_devnum"

  raid_content=$(fliwi-get-my-raids --limit=$raid_name --show-raid-content)
  raid_content_type=$(echo $raid_content | cut -d '-' -f 1)
  raid_content_extra=$(echo $raid_content | cut -s -d '-' -f 2)

  raid_number_of_devices=$(fliwi-get-my-raids --limit=$raid_name --show-number-of-devices)

  raid_number_of_spare_devices=$(fliwi-get-my-raids --limit=$raid_name --show-number-of-spare-devices)
  raid_size=$(fliwi-get-my-raids --limit=$raid_name --show-size)
  raid_chunk=$(fliwi-get-my-raids --limit=$raid_name --show-chunk)
  raid_layout=$(fliwi-get-my-raids --limit=$raid_name --show-layout)
  raid_metadata_version=$(fliwi-get-my-raids --limit=$raid_name --show-metadata-version)


  ### WE DO NOT SUPPORT THIS, YET ### mdadm_raid_name_string="--name=$raid_name"
  mdadm_raid_name_string=""

  if [ $(echo $raid_drives_with_devnum | wc -w) -eq 1 ] && \
     [ $raid_level -eq 1 ]; then
    mdadm_force_string='--force'
  else
    mdadm_force_string=''
  fi

  if [ $raid_level -gt 0 ] &&\
     [ $raid_number_of_spare_devices -gt 0 ]; then
    mdadm_number_of_spare_devices_string="--spare-devices=$raid_number_of_spare_devices"
  else
    mdadm_number_of_spare_devices_string=""
  fi

  if [ "$raid_size" != "default" ]; then
    mdadm_size_string="--size $raid_size"
  else
    mdadm_size_string=""
  fi

  if [ "$raid_chunk" != "default" ]; then
    mdadm_chunk_string="--chunk $raid_chunk"
  else
    mdadm_chunk_string=""
  fi

  if [ "$raid_layout" != "default" ]; then
    mdadm_layout_string="--layout $raid_layout"
  else
    mdadm_layout_string=""
  fi

  if [ "$raid_metadata_version" != "default" ]; then
    mdadm_metadata_version_string="--metadata $raid_metadata_version"
  else
    mdadm_metadata_version_string=""
  fi


  for raid_drive_with_devnum in $raid_drives_with_devnum
  do
    ymc_cluster_nfs_root_wait_for_partition_to_appear $raid_drive_with_devnum
    fliwi_minimal_clean_block_device $raid_drive_with_devnum
  done

  mdadm --create --run /dev/md$md_device_number \
        $mdadm_raid_name_string \
        --level=$raid_level \
        --raid-devices=$raid_number_of_devices \
        $mdadm_number_of_spare_devices_string \
        $mdadm_force_string \
        $mdadm_size_string \
        $mdadm_chunk_string \
        $mdadm_layout_string \
        $mdadm_metadata_version_string \
        $raid_drives_with_devnum
  ### Slow down the initial sync...
  if [ -e "/sys/block/md$md_device_number/sync_speed_max" ]; then
    echo 10000 > /sys/block/md$md_device_number/sync_speed_max
  elif [ -e "/sys/block/md$md_device_number/md/sync_speed_max" ]; then
    echo 10000 > /sys/block/md$md_device_number/md/sync_speed_max
  fi

  ymc_cluster_nfs_root_wait_for_partition_to_appear /dev/md$md_device_number
  fliwi_minimal_clean_block_device /dev/md$md_device_number



  case "$raid_content_type" in
    LVM)
      echo "INFO: Using '/dev/md$md_device_number' as a LVM-PV..."
      ### Kill a possibly existing LVM physical volume on our freshly setup device (just in case...)
      pvremove -ff -y /dev/md$md_device_number 1>/dev/null 2>&1
      if [ $? -eq 0 ]; then
        echo "Killed an old LVM-PV on '/dev/md$md_device_number'"
      fi

      ### Create the LVM physical volume
      pvcreate -ff /dev/md$md_device_number

      if [ -n "$raid_content_extra" ]; then
        if [ $(ymc_contains $raid_content_extra $lvm_vg_created) -eq 0 ]; then
          # Create
          vgcreate $lvm_group_prefix$raid_content_extra /dev/md$md_device_number
          lvm_vg_created=$lvm_vg_created" $raid_content_extra"
        else
          # Extend
          vgextend $lvm_group_prefix$raid_content_extra /dev/md$md_device_number
        fi
      else
        echo "INFO: Nothing done with LVM-PV '/dev/md$md_device_number'..."
      fi
    ;;

    DATA)
      if [ -n "$raid_content_extra" ]; then
        echo "INFO: Creating a filesystem of type '$raid_content_extra' on '/dev/md$md_device_number'..."
        mkfs.$raid_content_extra /dev/md$md_device_number
        if [ $? -ne 0 ]; then
          mkfs.$raid_content_extra -f /dev/md$md_device_number
          if [ $? -ne 0 ]; then
            echo "ERROR: Failed to create filesystem of type '$raid_content_extra' on '/dev/md$md_device_number'" 1>&2
            exit 1
          fi
        fi
      else
        echo "INFO: Nothing done with data-raid '$raid_content_extra'..."
      fi
    ;;

    *)
      echo "NOTICE: Nothing to do for raid-device /dev/md$md_device_number of type '$raid_content_type'" 1>&2
    ;;
  esac

  ### Increment the raid device number
  md_device_number=$(expr $md_device_number + 1)
done
### Second proceed raids //end

for disk_size in $disk_sizes
do
  disk_size_washed=$(echo $disk_size | sed -r 's/\./_/g' )
  all_same_size_drives=$(ymc_var_value disks_$disk_size_washed)

  for all_same_size_drive in $all_same_size_drives
  do
    if [ $(ymc_contains "/dev/$all_same_size_drive" $disk_group_controlled_devices) -eq 0 ]; then
      same_size_drives=$same_size_drives" "$all_same_size_drive
    fi
  done

  drives_with_devnum=''
  for same_size_drive in $same_size_drives
  do
    boot_drives_with_dev=$boot_drives_with_dev' /dev/'$same_size_drive
  done

  if [ $ymc_cluster_noswraid -eq 1 ]; then
    count_same_size_drives=0
  else
    count_same_size_drives=$(echo $same_size_drives | wc -w)
  fi

  if [ $count_same_size_drives -gt 1 ]; then
    for same_size_drive in $same_size_drives
    do
      ### Drop out existing partitions
      parted --script --align=opt /dev/$same_size_drive "mklabel GPT"
      fliwi_minimal_clean_block_device /dev/$same_size_drive

      echo "Reserving 256 MB on $same_size_drive for the boot partition..."
      echo "Leaving the rest of available space to an sw-raid..."

      parted --script --align=opt /dev/$same_size_drive "mklabel GPT"
      parted --script --align=opt /dev/$same_size_drive "mkpart grub 1MiB 4MiB"
      parted --script --align=opt /dev/$same_size_drive "set 1 bios_grub on"
      ymc_cluster_nfs_root_wait_for_partition_to_appear /dev/$same_size_drive'1'
      fliwi_minimal_clean_block_device /dev/$same_size_drive'1'

      parted --script --align=opt /dev/$same_size_drive "mkpart boot 4MiB 256MiB"
      parted --script --align=opt /dev/$same_size_drive "set 2 raid on"
      ymc_cluster_nfs_root_wait_for_partition_to_appear /dev/$same_size_drive'2'
      fliwi_minimal_clean_block_device /dev/$same_size_drive'2'

      parted --script --align=opt /dev/$same_size_drive "mkpart raid 256MiB -1MiB"
      parted --script --align=opt /dev/$same_size_drive "set 3 raid on"
      ymc_cluster_nfs_root_wait_for_partition_to_appear /dev/$same_size_drive'3'
      fliwi_minimal_clean_block_device /dev/$same_size_drive'3'

      boot_drives_with_devnum=$boot_drives_with_devnum' /dev/'$(ymc_get_partition_for_drive_by_num $same_size_drive 2)
      drives_with_devnum=$drives_with_devnum' /dev/'$(ymc_get_partition_for_drive_by_num $same_size_drive 3)
    done
    echo "The following drives have the same size and will be grouped into a single sw-raid:"
    echo $same_size_drives

    num_spare_disks=0
    if [ $count_same_size_drives -eq 2 ]; then
      raid_level=1
    elif [ $count_same_size_drives -eq 3 ]; then
      raid_level=5
    elif [ $count_same_size_drives -eq 4 ] || \
         [ $count_same_size_drives -eq 8 ] || \
         [ $count_same_size_drives -eq 12 ] || \
         [ $count_same_size_drives -eq 16 ] || \
         [ $count_same_size_drives -eq 20 ] || \
         [ $count_same_size_drives -eq 24 ]; then
      raid_level=10
    elif [ $count_same_size_drives -eq 5 ] || \
         [ $count_same_size_drives -eq 9 ] || \
         [ $count_same_size_drives -eq 13 ] || \
         [ $count_same_size_drives -eq 17 ] || \
         [ $count_same_size_drives -eq 21 ] || \
         [ $count_same_size_drives -eq 25 ]; then
      raid_level=10
      num_spare_disks=1
    elif [ $count_same_size_drives -eq 6 ] || \
         [ $count_same_size_drives -eq 10 ] || \
         [ $count_same_size_drives -eq 14 ] || \
         [ $count_same_size_drives -eq 18 ] || \
         [ $count_same_size_drives -eq 22 ] || \
         [ $count_same_size_drives -eq 26 ]; then
      raid_level=10
      num_spare_disks=2
    elif [ $count_same_size_drives -eq 11 ] || \
         [ $count_same_size_drives -eq 15 ] || \
         [ $count_same_size_drives -eq 19 ] || \
         [ $count_same_size_drives -eq 23 ] || \
         [ $count_same_size_drives -eq 27 ]; then
      raid_level=10
      num_spare_disks=3
    else
      raid_level=6
    fi

    num_raid_disks=$(ymc_simple_calc "$count_same_size_drives - $num_spare_disks")

    if [ $num_spare_disks -gt 0 ]; then
      echo "Generating a RAID $raid_level with $num_raid_disks active and $num_spare_disks spare disks..."
      spare_devices_string="--spare-devices=$num_spare_disks"
    else
      echo "Generating a RAID $raid_level with $num_raid_disks devices..."
      spare_devices_string=""
    fi

    mdadm --create --run /dev/md$md_device_number --level=$raid_level --raid-devices=$num_raid_disks $spare_devices_string $drives_with_devnum
    ### Slow down the initial sync...
    if [ -e "/sys/block/md$md_device_number/sync_speed_max" ]; then
      echo 10000 > /sys/block/md$md_device_number/sync_speed_max
    elif [ -e "/sys/block/md$md_device_number/md/sync_speed_max" ]; then
      echo 10000 > /sys/block/md$md_device_number/md/sync_speed_max
    fi

    ### Kill a possibly existing LVM physical volume on our freshly setup device (just in case...)
    pvremove -ff -y /dev/md$md_device_number 1>/dev/null 2>&1
    if [ $? -eq 0 ]; then
      echo "Killed an old LVM-PV on '/dev/md$md_device_number'"
    fi

    ### Create the LVM physical volume
    pvcreate -ff /dev/md$md_device_number

    ## Create or extend the default-volume-group
    if [ $(ymc_contains $lvm_default_volume_group $lvm_vg_created) -eq 0 ]; then
      # Create
      vgcreate $lvm_group_prefix"$lvm_default_volume_group" /dev/md$md_device_number
      lvm_vg_created=$lvm_vg_created" $lvm_default_volume_group"
    else
      # Extend
      vgextend $lvm_group_prefix"$lvm_default_volume_group" /dev/md$md_device_number
    fi

    ### Increment the raid device number
    md_device_number=$(expr $md_device_number + 1)
  elif [ $count_same_size_drives -eq 1 ]; then
    drives_with_devnum=''
    for same_size_drive in $same_size_drives
    do
      ### Drop out existing partitions
      parted --script --align=opt /dev/$same_size_drive "mklabel GPT"
      fliwi_minimal_clean_block_device /dev/$same_size_drive

      echo "Reserving 256 MB on $same_size_drive for the boot partition..."
      echo "Leaving the rest of available space to LVM..."
      parted --script --align=opt /dev/$same_size_drive "mklabel GPT"
      parted --script --align=opt /dev/$same_size_drive "mkpart grub 1MiB 4MiB"
      parted --script --align=opt /dev/$same_size_drive "set 1 bios_grub on"
      ymc_cluster_nfs_root_wait_for_partition_to_appear /dev/$same_size_drive'1'
      fliwi_minimal_clean_block_device /dev/$same_size_drive'1'

      parted --script --align=opt /dev/$same_size_drive "mkpart boot 4MiB 256MiB"
      parted --script --align=opt /dev/$same_size_drive "set 2 raid on"
      ymc_cluster_nfs_root_wait_for_partition_to_appear /dev/$same_size_drive'2'
      fliwi_minimal_clean_block_device /dev/$same_size_drive'2'

      parted --script --align=opt /dev/$same_size_drive "mkpart lvm 256MiB -1MiB"
      parted --script --align=opt /dev/$same_size_drive "set 3 lvm on"
      ymc_cluster_nfs_root_wait_for_partition_to_appear /dev/$same_size_drive'3'
      fliwi_minimal_clean_block_device /dev/$same_size_drive'3'

      ### Make sure the kernel is aware of the new partitions
      ymc_cluster_nfs_root_wait_for_partition_to_appear /dev/$same_size_drive

      boot_drives_with_devnum=$boot_drives_with_devnum' /dev/'$(ymc_get_partition_for_drive_by_num $same_size_drive 2)
      drives_with_devnum=$drives_with_devnum' /dev/'$(ymc_get_partition_for_drive_by_num $same_size_drive 3)
    done
    echo "The following drive is either a hw-raid or a single drive:"
    echo $same_size_drives
    echo "WARNING: If drive $same_size_drives is not a hw-raid it won't be redundant" 1>&2

    ### Kill a possibly existing LVM physical volume on our freshly setup device (just in case...)
    pvremove -ff -y $drives_with_devnum 1>/dev/null 2>&1
    if [ $? -eq 0 ]; then
      echo "Killed an old LVM-PV on '$drives_with_devnum'"
    fi

    ### Create the LVM physical volume
    pvcreate -ff $drives_with_devnum

    if [ $(ymc_contains $lvm_default_volume_group $lvm_vg_created) -eq 0 ]; then
      # Create
      vgcreate $lvm_group_prefix"$lvm_default_volume_group" $drives_with_devnum
      lvm_vg_created=$lvm_vg_created" $lvm_default_volume_group"
    else
      # Extend
      vgextend $lvm_group_prefix"$lvm_default_volume_group" $drives_with_devnum
    fi
  fi
done

### Create the boot-sw-raid1
force_one_device=''
count_all_drives=$(echo $boot_drives_with_devnum | wc -w)
if [ $count_all_drives -eq 1 ]; then
  force_one_device='--force'
fi
### WE DO NOT SUPPORT THIS, YET ### mdadm_raid_name_string="--name=boot"
mdadm_raid_name_string=""

mdadm --create --run /dev/md0 \
      $mdadm_raid_name_string \
      --level=1 \
      $force_one_device \
      --raid-devices=$count_all_drives \
      --metadata=1.2 \
      $boot_drives_with_devnum
if [ $? -ne 0 ]; then
  echo "ERROR: Failed to create the boot-raid" 1>&2
  exit 1
fi

mkfs.ext2 -q /dev/md0
if [ $? -ne 0 ]; then
  echo "ERROR: Failed to create a filesystem on the boot-partition" 1>&2
  exit 1
fi

### handle logical-volumes 'root' and 'swap'
for volume_config_name in $(fliwi-get-my-logical-volumes --host-based-lookup --show-config-name | grep -E -e '^(root|swap)$')
do
  echo "INFO: Processing volume '$volume_config_name'..."

  volume_name=$(fliwi-get-my-logical-volumes --host-based-lookup --limit=$volume_config_name --show-volume-name)
  if [ $? -ne 0 ] || \
     [ "$volume_name" == "" ]; then
    echo "ERROR: Can not get the volume-name for volume '$volume_config_name'"
    exit 1
  fi

  volume_group_name=$(fliwi-get-my-logical-volumes --host-based-lookup --limit=$volume_config_name --show-volume-group)
  if [ $? -ne 0 ] || \
     [ "$volume_group_name" == "" ]; then
    echo "ERROR: Can not get the volume-group for volume '$volume_config_name'"
    exit 1
  fi

  volume_device_path=$(fliwi-get-my-logical-volumes --host-based-lookup --limit=$volume_config_name --show-device-path)
  if [ $? -ne 0 ] || \
     [ "$volume_device_path" == "" ]; then
    echo "ERROR: Can not get the device-path for volume '$volume_config_name'"
    exit 1
  fi

  if [ -b "$volume_device_path" ]; then
    echo "INFO: Volume '$volume_device_path' already exists..."
    exit 1
  fi

  if [ -e "$volume_device_path" ]; then
    echo "ERROR: Something exists at '$volume_device_path' but it is not a block-device..."
    exit 1
  fi

  volume_size=$(fliwi-get-my-logical-volumes --host-based-lookup --limit=$volume_config_name --show-size)
  if [ $? -ne 0 ] || \
     [ "$volume_size" == "" ]; then
    echo "ERROR: Can not get size for volume '$volume_config_name'"
    exit 1
  fi

  lvcreate -n $volume_name -L $volume_size $volume_group_name
  if [ $? -ne 0 ]; then
    echo "ERROR: Failed to create the logical volume '$volume_config_name'"
    exit 1
  fi

  ### Generate the filesystem
  volume_filesystem=$(fliwi-get-my-logical-volumes --host-based-lookup --limit=$volume_config_name --show-filesystem)
  if [ $? -ne 0 ] || \
     [ "$volume_filesystem" == "" ]; then
    echo "ERROR: Can not get filesystem for volume '$volume_config_name'"
    exit 1
  fi

  if [ "$volume_filesystem" = "swap" ]; then
    echo "INFO: Generating SWAP on '$volume_device_path'"
    mkswap -f $volume_device_path
    if [ $? -ne 0 ]; then
      echo "ERROR: Failed to generate SWAP on volume '$volume_config_name'"
      exit 1
    fi
  else
    echo "INFO: Generating a filesystem of type '$volume_filesystem' on '$volume_device_path'"
    mkfs.$volume_filesystem -q $volume_device_path
    if [ $? -ne 0 ]; then
      echo "ERROR: Failed to create a filesystem of type '$volume_filesystem' on volume '$volume_config_name'"
      exit 1
    fi
  fi

  if [ "$volume_config_name" = "root" ]; then
    root_device_path="$volume_device_path"
    root_filesystem="$volume_filesystem"
  elif [ "$volume_config_name" = "swap" ]; then
    swap_device_path="$volume_device_path"
  fi
done

/etc/init.d/lvm2 start

if [ -z "$root_device_path" ]; then
  echo "ERROR: Missing root device"
  exit 1
elif [ -z "$root_filesystem" ]; then
  echo "ERROR: Missing root-filesystem"
  exit 1
elif [ -z "$swap_device_path" ]; then
  echo "ERROR: Missing swap device"
  exit 1
fi

### TBD: Get root mount options from cluster-configured mounts...
root_mount_options="defaults"
if [ "$root_filesystem" == "ext4" ]; then
  root_mount_options="defaults,nobarrier"
fi

target_dir="/mnt/install/root"
arch=$(dpkg --print-architecture)
if [ -b "$root_device_path" ]; then
  mkdir -p $target_dir
  mount -o $root_mount_options $root_device_path $target_dir
  if [ $? -ne 0 ]; then
    echo "ERROR: Failed to mount the root-partition"
    exit 1
  fi
else
  echo "ERROR: Failed to create the root-partition"
  exit 1
fi

### Install the system...
echo "INFO: Installing the base system..."
echo "INFO: Calling debootstrap - this might take a while..."
debootstrap --verbose --include=$(echo $FLIWI_DEBIAN_EXTRA_PACKAGES | sed -r 's/[[:space:]]+/,/g') --components=$(echo $FLIWI_DEBIAN_COMPONENTS | sed -r 's/[[:space:]]+/,/g') $FLIWI_DEBIAN_DISTRIBUTION $target_dir $FLIWI_DEBIAN_APT_MIRROR
if [ $? -ne 0 ] || [ ! -d "$target_dir/boot" ]; then
  echo "ERROR: Failed to setup the base system - removing it!" 1>&2
  rm -rf $target_dir/*
  exit 1
fi

### In wheezy getty cleans the tty, which we do not want to happen...
if [ "$FLIWI_DEBIAN_DISTRIBUTION" = "wheezy" ]; then
  sed -ri 's|^(1:[0-9]+:respawn:/sbin/getty) (38400 tty1$)|\1 --noclear \2|' $target_dir/etc/inittab
fi

echo "deb $FLIWI_APT_MIRROR $FLIWI_DISTRIBUTION $FLIWI_COMPONENTS" > $target_dir/etc/apt/sources.list.d/fliwi-initial-install.list
echo "deb $FLIWI_APT_MIRROR-indispensable-backports $FLIWI_DISTRIBUTION $FLIWI_COMPONENTS" >> $target_dir/etc/apt/sources.list.d/fliwi-initial-install.list
echo "deb $FLIWI_APT_MIRROR-indispensable-foreports $FLIWI_DISTRIBUTION $FLIWI_COMPONENTS" >> $target_dir/etc/apt/sources.list.d/fliwi-initial-install.list

echo "# /etc/fstab: static file system information." >> $target_dir/etc/fstab
echo "#" >> $target_dir/etc/fstab
echo "# <file system>                                  <mount point>             <type>     <options>            <dump>  <pass>" >> $target_dir/etc/fstab
echo "proc                                             /proc                     proc       defaults             0       0" >> $target_dir/etc/fstab
echo "/dev/md0                                         /boot                     ext2       defaults             0       2" >> $target_dir/etc/fstab
echo "$swap_device_path  none  swap  sw,pri=1  0  0" >> $target_dir/etc/fstab
echo "# Fliwi root mount //start" >> $target_dir/etc/fstab
echo "$root_device_path  /  $root_filesystem  $root_mount_options  0  1" >> $target_dir/etc/fstab
echo "# Fliwi root mount //end" >> $target_dir/etc/fstab


function chroot_exec
{
  LC_ALL=C DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical chroot $target_dir $@
  exit_code=$?
  return $exit_code
}

echo "INFO: Mounting /dev in chroot..."
mount -o bind /dev $target_dir/dev/

echo "INFO: Mounting /proc in chroot..."
chroot $target_dir mount /proc

echo "INFO: Mounting /sys in chroot..."
chroot $target_dir mount /sys

echo "INFO: Mounting /dev/pts in chroot..."
chroot $target_dir mount devpts /dev/pts -t devpts

### Add the chroot-policy-flag
echo '#!/bin/sh'> $target_dir/usr/sbin/policy-rc.d
echo 'exit 101' >> $target_dir/usr/sbin/policy-rc.d
chmod 755 $target_dir/usr/sbin/policy-rc.d

chroot_exec apt-get update
chroot_exec apt-get --yes --allow-unauthenticated install fliwi-apt-keyring
chroot_exec apt-get update
chroot_exec apt-get --yes install fliwi-apt-config
chroot_exec apt-get update
chroot_exec apt-get --yes upgrade
chroot_exec apt-get --yes dist-upgrade

### Generate a valid kernel-img.conf on the nfsroot
echo "# Kernel Image management overrides" > $target_dir/etc/kernel-img.conf
echo "# See kernel-img.conf(5) for details" >> $target_dir/etc/kernel-img.conf
echo "do_symlinks = yes" >> $target_dir/etc/kernel-img.conf
echo "relative_links = yes" >> $target_dir/etc/kernel-img.conf
echo "do_bootloader = no" >> $target_dir/etc/kernel-img.conf
echo "do_bootfloppy = no" >> $target_dir/etc/kernel-img.conf
echo "do_initrd = yes" >> $target_dir/etc/kernel-img.conf
echo "link_in_boot = yes" >> $target_dir/etc/kernel-img.conf
echo "postinst_hook = update-grub" >> $target_dir/etc/kernel-img.conf
echo "postrm_hook   = update-grub" >> $target_dir/etc/kernel-img.conf

echo "INFO: Mounting /boot in chroot..."
chroot_exec mount /boot
if [ $? -ne 0 ]; then
  echo "ERROR: Could not mount /boot in chroot!" 1>&2
  exit 1
fi

### Install grub on all devices
#  grub_can_handle_only_8_drives_counter=0
sorted_boot_drives_with_dev=$(echo $(echo $boot_drives_with_dev | sed -r 's/ /\n/g' | sort))
for boot_drive_with_dev in $sorted_boot_drives_with_dev
do
#    grub_can_handle_only_8_drives_counter=$(ymc_simple_calc "$grub_can_handle_only_8_drives_counter + 1")
#    if [ $grub_can_handle_only_8_drives_counter -gt 8 ]; then
#      echo "WARNING: NOT installing grub on device $boot_drive_with_dev, as grub currently supports only 8 drives..."
#      continue
#    fi
  echo "INFO: Installing grub on device $boot_drive_with_dev"
  chroot_exec grub-install --no-floppy $boot_drive_with_dev
  if [ $? -ne 0 ]; then
    echo "ERROR: Failed to install grub on device $boot_drive_with_dev" 1>&2
    exit 1
  fi
done

### Get the kernel to install
### TODO: Put this into a wrapper-script
ymc_install_package dnsutils
kernel_to_install=$(dig $(hostname -s).linux.kernel txt +short | sed -r 's/"//g')

echo "INFO: Installing '$kernel_to_install' kernel..."
if [ "$kernel_to_install" == "debian-backports" ]; then
  chroot_exec apt-get --yes -t $FLIWI_DEBIAN_DISTRIBUTION-backports install "fliwi-linux-image-$arch"
else
  chroot_exec apt-get --yes install "fliwi-linux-image-$arch fliwi-init"
fi

echo "INFO: Installing Fliwi basic stack..."
chroot_exec apt-get --yes install "fliwi-init"

### We do not want a quiet boot...
sed -ri '/^GRUB_CMDLINE_LINUX_DEFAULT=.*/s/quiet//g' $target_dir/etc/default/grub

### We do not want graphical output, since this normaly stops existing bios
### serial redirection - and we do not want to deal with serial redirection
### in grub itself
sed -ri 's/^#?GRUB_TERMINAL=.*/GRUB_TERMINAL=console/g' $target_dir/etc/default/grub

### Enable the serial console in grub
## TODO: Make this more dynamic - currently this simply reuses given kernel parameters!

### Add possibly missing quotes
sed -ri 's/^GRUB_CMDLINE_LINUX=$/GRUB_CMDLINE_LINUX=""/' $target_dir/etc/default/grub

### Wash out possibly existing console-options
sed -ri '/^GRUB_CMDLINE_LINUX=.*/s/console=[^[:space:]"]*//g' $target_dir/etc/default/grub

### Add our own console-options
sed -ri 's/^GRUB_CMDLINE_LINUX="([^"]*)"/GRUB_CMDLINE_LINUX="\1 '"$ymc_cluster_console_string_grub"'"/' $target_dir/etc/default/grub

if [ -n "$ymc_cluster_clocksource" ]; then
  ### Persist the clocksource given in current kernel-params
  sed -ri 's/^GRUB_CMDLINE_LINUX="([^"]*)"/GRUB_CMDLINE_LINUX="\1 clocksource='"$ymc_cluster_clocksource"'"/' $target_dir/etc/default/grub
fi

if [ -n "$fliwi_rootdelay" ]; then
  ### Persist the rootdelay given in current kernel-params
  sed -ri 's/^GRUB_CMDLINE_LINUX="([^"]*)"/GRUB_CMDLINE_LINUX="\1 rootdelay='"$fliwi_rootdelay"'"/' $target_dir/etc/default/grub
fi

if [ $fliwi_no_kms -eq 1 ]; then
  sed -ri 's/^GRUB_CMDLINE_LINUX="([^"]*)"/GRUB_CMDLINE_LINUX="\1 nomodeset"/' $target_dir/etc/default/grub
fi

### Wash out multiple whitespaces
sed -ri '/^GRUB_CMDLINE_LINUX=.*/s/[[:space:]]+/ /g' $target_dir/etc/default/grub

### Wash out leading whitespaces
sed -ri 's/(^GRUB_CMDLINE_LINUX=")[[:space:]]*(.*)/\1\2/' $target_dir/etc/default/grub

### Wash out trailing whitespaces
sed -ri '/^GRUB_CMDLINE_LINUX=.*/s/[[:space:]]+"$/"/' $target_dir/etc/default/grub

### Enable the serial console for login
## TODO: Make this more dynamic - currently this simply reuses given kernel parameters!
if [ "$ymc_cluster_serial_console_infos" != '' ]; then
  ### inittab
  echo "" >> $target_dir/etc/inittab
  echo "###Added by $0 //start" >> $target_dir/etc/inittab

  ### securetty
  echo "" >> $target_dir/etc/securetty
  echo "###Added by $0 //start" >> $target_dir/etc/securetty

  for ymc_cluster_serial_console_info in $ymc_cluster_serial_console_infos
  do
    ymc_cluster_serial_console_info_washed=$(echo $ymc_cluster_serial_console_info | sed -r 's/(,[0-9]+).*/\1/')
    ymc_cluster_serial_console=$(echo $ymc_cluster_serial_console_info_washed | cut -d ',' -f 1)
    ymc_cluster_serial_console_num=$(echo $ymc_cluster_serial_console | sed -r 's/.*([0-9]+)$/\1/')
    ymc_cluster_serial_console_speed=$(echo $ymc_cluster_serial_console_info_washed |cut -d ',' -f 2)

    ### inittab
    echo "T$ymc_cluster_serial_console_num:23:respawn:/sbin/getty --noclear $serial_console_hw_flow_control_switch -L $ymc_cluster_serial_console $ymc_cluster_serial_console_speed vt100" >> $target_dir/etc/inittab

    ### securetty
    if [ $(grep -c -E -e "^$ymc_cluster_serial_console$" $target_dir/etc/securetty) -eq 0 ]; then
      echo "$ymc_cluster_serial_console" >> $target_dir/etc/securetty
    else
      echo "#SKIPPED, AS ALREADY FOUND ABOVE#$ymc_cluster_serial_console" >> $target_dir/etc/securetty
    fi
  done

  ### inittab
  echo "###Added by $0 //end" >> $target_dir/etc/inittab
  echo "" >> $target_dir/etc/inittab

  ### securetty
  echo "###Added by $0 //end" >> $target_dir/etc/securetty
  echo "" >> $target_dir/etc/securetty
fi


### Update grub, to recognize changes
echo "INFO: Updating grub..."
chroot_exec update-grub
if [ $? -ne 0 ]; then
  echo "ERROR: Failed to update grub" 1>&2
  exit 1
fi

#DEPRECATED#### Request a (new) password
#DEPRECATED#echo "INFO: Requesting a new password..."
#DEPRECATED#while [ ! -f "/boot/ymccluster/host.password" ] || [ "$(cat /boot/ymccluster/host.password)" == '' ]
#DEPRECATED#do
#DEPRECATED#  ymc-cluster-update-host-password
#DEPRECATED#  if [ $? -ne 0 ]; then
#DEPRECATED#    echo "INFO: ...Still waiting for a new password!"
#DEPRECATED#  else
#DEPRECATED#    echo "INFO: ...Password updated!"
#DEPRECATED#  fi
#DEPRECATED#  sleep 1
#DEPRECATED#done
#DEPRECATED#
#DEPRECATED#if [ -d "$target_dir/boot/ymccluster" ]; then
#DEPRECATED#  rm -rf $target_dir/boot/ymccluster
#DEPRECATED#elif [ -e "$target_dir/boot/ymccluster" ]; then
#DEPRECATED#  echo "ERROR: '$target_dir/boot/ymccluster' exists and is not a directory!" 1>&2
#DEPRECATED#  exit 1
#DEPRECATED#fi
#DEPRECATED#
#DEPRECATED#### Move the password we got to the chroot...
#DEPRECATED#mv /boot/ymccluster $target_dir/boot/ymccluster

### Remove the chroot-policy-flag
rm -f $target_dir/usr/sbin/policy-rc.d

echo "INFO: Stopping services in chroot..."
chroot $target_dir /etc/init.d/avahi-daemon stop
chroot $target_dir /etc/init.d/dbus stop
chroot $target_dir /etc/init.d/ntp stop
pids_to_kill=$(lsof $target_dir 2>/dev/null | cut -d ' ' -f 2 | sort | uniq | grep -v -E -e '^[ ]*$')
for pid_to_kill in $pids_to_kill
do
  chroot /mnt/install/root kill $pid_to_kill 2>/dev/null
  chroot /mnt/install/root kill -9 $pid_to_kill 2>/dev/null
  kill $pid_to_kill 2>/dev/null
  kill -9 $pid_to_kill 2>/dev/null
done

echo "INFO: Unmounting /boot in chroot..."
chroot_exec umount /boot

echo "INFO: Unmounting /dev/pts in chroot..."
chroot $target_dir umount /dev/pts

echo "INFO: Unmounting /sys in chroot..."
chroot $target_dir umount /sys

echo "INFO: Unmounting /proc in chroot..."
chroot $target_dir umount /proc

echo "INFO: Unmounting /dev in chroot..."
umount $target_dir/dev

echo "INFO: Unmounting chroot..."
umount $target_dir

### Stop lvm
echo "INFO: Stopping lvm-volumes..."
vgchange -a n

if [ "$force_one_device" = '' ]; then
  ### Stop SW-Raids
  echo "INFO: Stopping all created SW-Raids"
  mdadm --stop --scan

  ### Start Boot-Raid in order to rebuild it
  echo "INFO: Starting SW-Raid used for the boot-partition..."
  mdadm --assemble --run /dev/md0 $boot_drives_with_devnum

  ### Wait for the Boot-Raid to be synced...
  echo "INFO: Waiting for the SW-Raid used for the boot-partition to be synced..."
  #while [ $(mdadm --detail /dev/md0 2>/dev/null | grep -c -E -e 'State : (clean|active)$') -lt 1 ]
  min_runs=0
  while [ $min_runs -lt 10 ]
  do
    status=$(cat /proc/mdstat  | grep resync)
    if [ "$status" != '' ]; then
      echo -n $status
      echo -n -e '\r'
    else
      min_runs=$(expr $min_runs + 1)
      echo -n "Please wait...   ["$(expr 10 - $min_runs)"]"
      echo -n "                                                            "
      echo -n -e '\r'
    fi
    sleep 1
  done
  echo "INFO: SW-Raid used for the boot-partition is now in sync"

  if [ $ymc_cluster_noreboot -eq 1 ]; then
    ### Start any other SW-Raid-Device if 'noreboot' has been given
    echo "INFO: Starting all SW-Raid-Devices"
    mdadm --assemble --run --scan --config=partitions
  fi
fi

### System should be installed by now
echo "INFO: Base system installed!"

if [ $ymc_cluster_noreboot -ne 1 ]; then
  ### Reboot if necessary...
  echo "INFO: Rebooting system..."
  /sbin/reboot
else
  echo "INFO: Not rebooting system, as 'noreboot' has been given"
fi


exit 0
