function install_bootloader {

    # We need to run partprobe to ensure all partitions are visible
    partprobe $target_disk

    # root partition is always the last partition of the disk
    readonly root_part=$(ls $target_disk* | tr " " "\n" | tail -n1)
    readonly root_part_mount=/mnt/rootfs

    mkdir -p $root_part_mount
    mkdir -p $root_part_mount/dev
    mkdir -p $root_part_mount/sys
    mkdir -p $root_part_mount/proc

    mount $root_part $root_part_mount 2>&1
    if [ $? != "0" ]; then
        echo "Failed to mount root partition $root_part on $root_part_mount"
        return 1
    fi


    mount -o bind /dev $root_part_mount/dev
    mount -o bind /sys $root_part_mount/sys
    mount -o bind /proc $root_part_mount/proc

    # If boot mode is uefi, then mount the system partition in /boot/efi.
    # Grub expects the efi system partition to be mounted here.
    if [ "$IRONIC_BOOT_MODE" = "uefi" ]; then

        # efi system partition is labelled as "efi-part" by Ironic.
        # lsblk output looks like this:
        #   NAME="sda1" LABEL="efi-part"
        readonly efi_system_part=$(lsblk -Pio NAME,LABEL $target_disk | \
                                   awk -F'"' '/"efi-part"/{print $2}')
        readonly efi_system_part_dev_file="/dev/$efi_system_part"
        readonly efi_system_part_mount="$root_part_mount/boot/efi"
        mkdir -p $efi_system_part_mount
        mount $efi_system_part_dev_file $efi_system_part_mount 2>&1
        if [ $? != "0" ]; then
            echo "Failed to mount efi system partition \
                  $efi_system_part_dev_file on $efi_system_part_mount"
            return 1
        fi
    fi

    # TODO(lucasagomes): Add extlinux as a fallback
    # Find grub version
    V=
    if [ -x $root_part_mount/usr/sbin/grub2-install ]; then
        V=2
    fi

    # Install grub
    ret=1
    if chroot $root_part_mount /bin/bash -c "/usr/sbin/grub$V-install ${target_disk}"; then
        echo "Generating the grub configuration file"

        # tell GRUB2 to preload its "lvm" module to gain LVM booting on direct-attached disks
        if [ "$V" = "2" ]; then
            echo "GRUB_PRELOAD_MODULES=lvm" >> $root_part_mount/etc/default/grub
        fi

        chroot $root_part_mount /bin/bash -c "/usr/sbin/grub$V-mkconfig -o /boot/grub$V/grub.cfg"
        ret=$?
    fi

    # If we had mounted efi system partition, umount it.
    if [ "$IRONIC_BOOT_MODE" = "uefi" ]; then
        umount $efi_system_part_mount
    fi

    umount $root_part_mount/dev
    umount $root_part_mount/sys
    umount $root_part_mount/proc
    umount $root_part_mount

    if [ $ret != "0" ]; then
        echo "Installing grub bootloader failed"
    fi
    return $ret
}

function do_vendor_passthru_and_wait {

    local data=$1
    local vendor_passhru_name=$2

    eval curl -i -X POST \
         "$TOKEN_HEADER" \
         "-H 'Accept: application/json'" \
         "-H 'Content-Type: application/json'" \
         -d "$data" \
         "$IRONIC_API_URL/v1/nodes/$DEPLOYMENT_ID/vendor_passthru/$vendor_passhru_name"

    echo "Waiting for notice of complete"
    nc -l -p 10000
}


readonly IRONIC_API_URL=$(get_kernel_parameter ironic_api_url)
readonly IRONIC_BOOT_OPTION=$(get_kernel_parameter boot_option)
readonly IRONIC_BOOT_MODE=$(get_kernel_parameter boot_mode)
readonly ROOT_DEVICE=$(get_kernel_parameter root_device)

if [ -z "$ISCSI_TARGET_IQN" ]; then
  err_msg "iscsi_target_iqn is not defined"
  troubleshoot
fi

target_disk=
if [[ $ROOT_DEVICE ]]; then
    target_disk="$(get_root_device)"
else
    t=0
    while ! target_disk=$(find_disk "$DISK"); do
      if [ $t -eq 60 ]; then
        break
      fi
      t=$(($t + 1))
      sleep 1
    done
fi

if [ -z "$target_disk" ]; then
  err_msg "Could not find disk to use."
  troubleshoot
fi

echo "start iSCSI target on $target_disk"
start_iscsi_target "$ISCSI_TARGET_IQN" "$target_disk" ALL
if [ $? -ne 0 ]; then
  err_msg "Failed to start iscsi target."
  troubleshoot
fi

if [ "$BOOT_METHOD" = "$VMEDIA_BOOT_TAG" ]; then
  TOKEN_FILE="$VMEDIA_DIR/token"
  if [ -f "$TOKEN_FILE" ]; then
    TOKEN_HEADER="-H 'X-Auth-Token: $(cat $TOKEN_FILE)'"
  else TOKEN_HEADER=""
  fi
else
  TOKEN_FILE=token-$DEPLOYMENT_ID

  # Allow multiple versions of the tftp client
  if tftp -r $TOKEN_FILE -g $BOOT_SERVER || tftp $BOOT_SERVER -c get $TOKEN_FILE; then
      TOKEN_HEADER="-H 'X-Auth-Token: $(cat $TOKEN_FILE)'"
  else
      TOKEN_HEADER=""
  fi
fi

echo "Requesting Ironic API to deploy image"
deploy_data="'{\"address\":\"$BOOT_IP_ADDRESS\",\"key\":\"$DEPLOYMENT_KEY\",\"iqn\":\"$ISCSI_TARGET_IQN\",\"error\":\"$FIRST_ERR_MSG\"}'"
do_vendor_passthru_and_wait "$deploy_data" "pass_deploy_info"

echo "Stopping iSCSI target on $target_disk"
stop_iscsi_target

# If localboot is set, install a bootloader
if [ "$IRONIC_BOOT_OPTION" = "local" ]; then
    echo "Installing bootloader"

    error_msg=$(install_bootloader)
    if [ $? -eq 0 ]; then
        status=SUCCEEDED
    else
        status=FAILED
    fi

    echo "Requesting Ironic API to complete the deploy"
    bootloader_install_data="'{\"address\":\"$BOOT_IP_ADDRESS\",\"status\":\"$status\",\"key\":\"$DEPLOYMENT_KEY\",\"error\":\"$error_msg\"}'"
    do_vendor_passthru_and_wait "$bootloader_install_data" "pass_bootloader_install_info"
fi
