On Fri, Apr 19, 2013 at 10:16:54AM +1000, Vincent McIntyre wrote: > > Hokay. Below is a very rough patch.
v2 has a couple of the rough edges knocked off... diff --git a/debian/grub-installer.templates b/debian/grub-installer.templates index 888a656..ad840ce 100644 --- a/debian/grub-installer.templates +++ b/debian/grub-installer.templates @@ -86,6 +86,20 @@ _Description: Device for boot loader installation: drive; - "/dev/fd0" will install GRUB to a floppy. +Template: grub-installer/choose_bootdev +Type: select +# :sl2: +_Description: Select disk for boot loader installation: + You need to make the newly installed system bootable, by installing + the GRUB boot loader on a bootable device. The usual way to do this is to + install GRUB on the master boot record of your first hard drive. If you + prefer, you can install GRUB elsewhere on the drive, or to another drive, + or even to a floppy. + . + Select a disk from the list. GRUB will be installed to the master boot + record of that disk. If you want to install GRUB somewhere other than the + master boot record of the listed disks, select 'Enter device manually'. + Template: grub-installer/password Type: password # :sl2: diff --git a/grub-installer b/grub-installer index f01eda1..9ccd775 100755 --- a/grub-installer +++ b/grub-installer @@ -217,6 +217,37 @@ devices_to_ids() echo "$ids" } + +# Produce a comma-separated list of '/dev/X (id)' strings suitable for debconf. +# If you give an argument, that <device> should be the only one returned. +# Examples: +# echo $(device_list) +# /dev/sda (ata-SAMSUNG_SSD_PM810_2.5__7mm_128GB_S0NRNEABC02304), /dev/sdb (ata-WDC_WD2002FAEX-007BA0_WD-WMAY05111513) +# echo $(device_list /dev/sdb) +# /dev/sdb (ata-WDC_WD2002FAEX-007BA0_WD-WMAY05111513) +device_list() +{ + local arg id path dev disk + arg="$1" + + [ -d /dev/disk/by-id ] || return + # /dev/disk/by-id has multiple links for the same physical disk. + # Sorting the output on only one column gives just one disk,path pair + # for each of the physical disks + cached_devices="$( + for path in /dev/disk/by-id/*; do + [ -e "$path" ] || continue + id="$(echo "$path" | sed -e 's+^.*/++')" + dev="$(readlink -f "$path")" + disk="$(device_to_disk "$dev")" + [ -n "$arg" ] && dev="$arg" + [ "$dev" = "$disk" ] && printf '%s (%s)\n' "$disk" "$id" + done | \ + sort -k1,1 -s -u | awk '{printf "%s, ", $0}' | sed -e 's/ ,$//' + )" + echo "$cached_devices" +} + rootfs=$(findfs /) bootfs=$(findfs /boot) [ -n "$bootfs" ] || bootfs="$rootfs" @@ -590,6 +621,56 @@ esac db_progress STEP 1 db_progress INFO grub-installer/progress/step_bootdev +select_bootdev() { + local manual_entry bootdev_choices default_choice chosen result + + result="" + default_choice="$1" + + manual_entry="Enter device manually" + bootdev_choices="$(device_list)" + bootdev_choices="$manual_entry, $bootdev_choices" + log "Bootdev Choices: '$bootdev_choices'" + + # not clear if we need to do this inside this function + #db_fset grub-installer/choose_bootdev seen false + + db_subst grub-installer/choose_bootdev choices "$bootdev_choices" + # set initial selection + if [ -n "$default_choice" ] ; then + chosen="$(device_list $default_choice)" + if [ -n "$chosen" ] ;then + db_set grub-installer/choose_bootdev "$chosen" + fi + fi + + # what priority - critical, or high? + db_input high grub-installer/choose_bootdev || true + if ! db_go; then + log "Returning to menu" + db_progress STOP + exit 10 + fi + if [ "$RET" = "$manual_entry" ] ; then + result="" + else + result="(echo "$RET" | cut -d' ' -f1)" + fi + + echo "$result" +} + +# make sure this question is displayed at least once +db_fset grub-installer/choose_bootdev seen false + +if [ "$bootdev" != "dummy" ] && [ ! "$frdev" ]; then + # check for a preseeded value + db_get grub-installer/bootdev || true + if [ -n "$RET" ] ; then + bootdev="$RET" + fi +fi + while : ; do if [ "$state" = 1 ]; then db_input high $q || true @@ -600,8 +681,17 @@ while : ; do fi db_get $q if [ "$RET" = true ]; then - bootdev="$default_bootdev" - break + # default_bootdev can be guessed incorrectly. + # If the user supplied a value for bootdev, + # ask them to resolve any conflict. + if [ "$bootdev" != "$default_bootdev" ] ; then + bootdev="$(select_bootdev "$bootdev")" + fi + if [ -e "$bootdev" ] ; then + break + else + state=2 + fi else # Exit to menu if /boot is on SATA RAID/multipath; we # don't support device selection in that case @@ -612,7 +702,13 @@ while : ; do state=2 fi elif [ "$state" = 2 ]; then - db_input critical grub-installer/bootdev || true + + # this won't necessarily display a question + bootdev="$(select_bootdev "$bootdev")" + + if [ ! -e "$bootdev" ]; then + db_input critical grub-installer/bootdev || true + fi if ! db_go; then if [ "$q" ]; then state=1 -- To UNSUBSCRIBE, email to debian-boot-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: http://lists.debian.org/20130419014148.gc21...@mayhem.atnf.csiro.au