05764de6e7
On some systems, it can take longer than 10 seconds for the root disk to be detected. Because enterprise hardware. Increase the wait time to 60 seconds so we don't incorrectly fail due to a missing root device. Change-Id: I4f67ef0295af8f2ae783fe3aea347b41987c6a66
174 lines
5.2 KiB
Text
174 lines
5.2 KiB
Text
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
|