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_passthru_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_passthru_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