Bug#564441: new version of the proposed patch
Hello,
I've updated my patch to follow suggestions from F. Pop, and tested
it at my level. Perhaps some enhancements could be added for a better
usability.
If you call the Debian Installer with default debconf level, it
automatically scans all devices and select the first detected ISO
(*but*, on the contrary of old iso-scan behaviour, it scans all
available disks before to select first ISO). If we call Debian Installer
with 'medium' level (debconf/priority=medium), we can choose which
device to scan, then select an ISO among detected ones.
There are some areas where I'm not sure the proposed patch is fully ok :
- the templates are definitely not best written texts
- about suggestions from F. Pop, I didn't know how to handle 'preseed',
as I don't know how it works
- then looking at the second pass for ISOs in sub-directories, I wonder
if I had to give also the top-directories' detected ISO ; I left them
in the final list, but perhaps it isn't the best choice.
with regards,
Fred.
diff -Naur iso-scan-1.28ref/debian/iso-scan.postinst iso-scan-1.28+testiso2/debian/iso-scan.postinst
--- iso-scan-1.28ref/debian/iso-scan.postinst 2009-01-10 01:25:38.000000000 +0100
+++ iso-scan-1.28+testiso2/debian/iso-scan.postinst 2010-01-28 21:23:22.000000000 +0100
@@ -2,13 +2,8 @@
. /usr/share/debconf/confmodule
set -e
-ISO_COUNT=0
-ISO_MOUNT_COUNT=0
-MOUNTABLE_DEVS_COUNT=0
-TOPLEVEL_DIRS_COUNT=0
-
log () {
- logger -t iso-scan "$@"
+ logger -t iso-scan "$@"
}
mount_device () {
@@ -17,12 +12,12 @@
db_progress INFO iso-scan/progress_mount
mount -t auto -o ro $dev_to_mount /hd-media 2>/dev/null
}
-
+
is_debian_iso () {
test -e /cdrom/.disk/info
}
-register_cd () {
+analyze_cd () {
# Make sure that the iso is usable for the architecture. If so,
# set the suite and codename to the suite/codename that is on the CD.
# This assumes that there will be no more than one distribution on
@@ -33,17 +28,14 @@
for dir in $(cat /etc/default-release) $(ls -1 /cdrom/dists/); do
relfile=/cdrom/dists/$dir/Release
if [ -e $relfile ] &&
- egrep -q 'Architectures:.* '$(udpkg --print-architecture)'( |$)' $relfile
- then
+ egrep -q 'Architectures:.* '$(udpkg --print-architecture)'( |$)' $relfile
+ then
suite=$(sed -n 's/^Suite: *//p' $relfile)
+ version=$(sed -n 's/^Version: *//p' $relfile)
codename=$(sed -n 's/^Codename: *//p' $relfile)
log "Detected ISO with '$suite' ($codename) distribution"
- db_set cdrom/suite $suite
- db_set cdrom/codename $codename
- db_subst iso-scan/success SUITE $suite
description=`sed -n 's/^Description: *//p' $relfile`
- db_subst iso-scan/success DESCRIPTION $description
return 0
fi
@@ -53,179 +45,339 @@
}
# Try to mount a file as an iso, and see if it's a Debian cd.
-try_iso () {
+add_usable_iso () {
iso_to_try=$1
iso_device=$2
- if mount -t iso9660 -o loop,ro,exec $iso_to_try /cdrom 2>/dev/null; then
- ISO_MOUNT_COUNT=$(expr $ISO_MOUNT_COUNT + 1)
- if is_debian_iso; then
- if register_cd $iso_to_try $iso_device; then
- # This could be more sophisticated, and try
- # to deal with multiple Debian ISO's. For
- # now, once we've got a Debian ISO, any
- # Debian ISO, we're done.
- db_progress STOP
- db_subst iso-scan/success FILENAME $iso_to_try
- db_set iso-scan/filename $iso_to_try
- db_subst iso-scan/success DEVICE $iso_device
- db_input medium iso-scan/success || true
- db_go || true
-
- anna-install apt-mirror-setup || true
- if [ ! -e /cdrom/.disk/base_installable ]; then
- log "Base system not installable from CD image, requesting choose-mirror"
- anna-install choose-mirror || true
- else
- anna-install apt-cdrom-setup || true
- # Install <codename>-support udeb (if available).
- db_get cdrom/codename
- anna-install $RET-support || true
- fi
- exit 0
+ if ! mount -t iso9660 -o loop,ro,exec $iso_to_try /cdrom 2>/dev/null; then
+ log "Failed mounting $iso_to_try (from $iso_device) as an ISO image"
+ return
+ fi
+ ISO_MOUNT_COUNT=$(expr $ISO_MOUNT_COUNT + 1)
+
+ if is_debian_iso; then
+ if analyze_cd; then
+ log "Debian ISO $iso_to_try usable."
+ isodesc="[$(echo $iso_device | sed -e 's?^/dev/??')]"
+ isodesc="$isodesc $iso_to_try ($suite - ${version:-?})"
+ # comma is used to separate possible ISO
+ isodesc=$(echo "$isodesc" | sed -e 's/,/ /g')
+ if [ -z "$ISOS_FOUND" ]; then
+ ISOS_FOUND="$isodesc"
else
- log "Debian ISO not usable, skipping"
+ ISOS_FOUND="$ISOS_FOUND, $isodesc"
fi
else
- log "Not a Debian ISO"
- umount /cdrom
+ log "Debian ISO not usable, skipping"
fi
else
- log "Failed mounting $iso_to_try"
+ log "$iso_to_try not a Debian ISO"
fi
-}
-
-# Try to unmount anything that was previously mounted.
-umount /cdrom 2>/dev/null || true
-umount /hd-media 2>/dev/null || true
-
-# Hopefully this will find the drive.
-hw-detect iso-scan/detect_progress_title || true
-
-# Load up every filesystem known to man. The drive could have anything.
-FS="ext2 ext3 ext4 reiserfs fat vfat xfs jfs iso9660 hfsplus hfs ntfs"
-for fs in $FS; do
- modprobe $fs >/dev/null 2>&1 || true
-done
-modprobe loop >/dev/null || true
-mkdir /cdrom 2>/dev/null || true
-mkdir /hd-media 2>/dev/null || true
+ umount -d /cdrom
+}
-log "First pass: Look for ISOs near top-level of each filesystem."
-DEVS="$(list-devices partition; list-devices disk; list-devices maybe-usb-floppy)"
-# Repeat twice if necessary, to accomodate devices that need some
-# time to initialise, like USB devices.
-for i in 1 2; do
- DEV_COUNT=0
- for dev in $DEVS; do
- DEV_COUNT=$(expr $DEV_COUNT + 1)
- done
+# scan a list of devices for available Debian ISO
+scan_device_for_isos()
+{
+ look_subdirs=$1
+ devs=$2
- db_progress START 0 $DEV_COUNT iso-scan/progress_title
+ if [ "$look_subdirs" = 1 ]; then
+ db_progress START 0 $TOPLEVEL_DIRS_COUNT iso-scan/progress_title
+ devlist=$MOUNTABLE_DEVS
+ else
+ dev_count=0
+ for dev in $devs; do
+ dev_count=$(expr $dev_count + 1)
+ done
+ db_progress start 0 $dev_count iso-scan/progress_title
+ devlist=$devs
+ fi
- for dev in $DEVS; do
+ for dev in $devlist; do
if ! mount_device $dev; then
- log "Waiting for $dev to possibly get ready.."
- sleep 3
- if ! mount_device $dev; then
+ if [ "$look_subdirs" = 0 ]; then
+ log "Waiting for $dev to possibly get ready.."
+ sleep 3
+ if ! mount_device $dev; then
+ db_progress STEP 1
+ continue
+ fi
+ else
continue
fi
fi
db_subst iso-scan/progress_scan DRIVE $dev
- log "Mounted $dev for first pass"
- MOUNTABLE_DEVS="$MOUNTABLE_DEVS $dev"
- MOUNTABLE_DEVS_COUNT=$(expr $MOUNTABLE_DEVS_COUNT + 1)
+ if [ "$look_subdirs" = 1 ]; then
+ log "Mounted $dev for second pass"
+ else
+ log "Mounted $dev for first pass"
+ MOUNTABLE_DEVS="$MOUNTABLE_DEVS $dev"
+ MOUNTABLE_DEVS_COUNT=$(expr $MOUNTABLE_DEVS_COUNT + 1)
+ fi
+
cd /hd-media
for dir in . *; do
- if [ -d "$dir" ]; then
- if [ "$dir" != "." ]; then
- TOPLEVEL_DIRS_COUNT=$(expr $TOPLEVEL_DIRS_COUNT + 1)
- fi
- db_subst iso-scan/progress_scan DIRECTORY "$dir/"
- db_progress INFO iso-scan/progress_scan
- for iso in $dir/*.iso $dir/*.ISO; do
- if [ -e $iso ]; then
- log "Found ISO $iso on $dev"
- ISO_COUNT=$(expr $ISO_COUNT + 1)
- try_iso $iso $dev
- fi
- done
+ if [ ! -d "$dir" ] || [ "$dir" = . -a "$look_subdirs" = 1 ]; then
+ continue
+ fi
+
+ db_subst iso-scan/progress_scan DIRECTORY "$dir/"
+ db_progress INFO iso-scan/progress_scan
+
+ if [ "$look_subdirs" = 1 ]; then
+ isolist=$(find $dir 2>/dev/null | grep -i '\.iso$' || true)
+ else
+ isolist="$dir/*.iso $dir/*.ISO"
+ TOPLEVEL_DIRS_COUNT=$(expr $TOPLEVEL_DIRS_COUNT + 1)
+ fi
+ for iso in $isolist; do
+ if [ ! -e $iso ]; then continue; fi
+
+ log "Found ISO $iso on $dev"
+ ISO_COUNT=$(expr $ISO_COUNT + 1)
+ add_usable_iso $iso $dev
+ done
+ if [ "$look_subdirs" = 1 ]; then
+ db_progress STEP 1
fi
done
cd /
- umount /hd-media
+ umount -d /hd-media # -d option let loop used to mount ISO image to be also
+ # released, else we can't umount /hd-media!
- # It's possible that the ISO was written right to the front of a
- # device, and not to a filesystem. (Hey, we may even be spinning
- # a real CD here, though that would be pretty weird..)
- try_iso $dev $dev
+ if [ $look_subdirs = 0 ]; then
+ # It's possible that the ISO was written right
+ # to the front of a device, and not to a filesystem.
+ # (Hey, we may even be spinning a real CD here,
+ # though that would be pretty weird..)
+ add_usable_iso $dev $dev
- db_progress STEP 1
+ db_progress STEP 1
+ fi
done
db_progress STOP
+}
- OLDDEVS="$DEVS"
- DEVS="$(list-devices partition; list-devices disk; list-devices maybe-usb-floppy)"
- if [ "$OLDDEVS" != "$DEVS" ]; then
- # Give USB time to settle, make sure all devices are seen
- # this time though.
- sleep 5
+# Mount selected ISO as Installer image
+use_this_iso () {
+ iso_to_try=$1
+ iso_device=$2
+
+ mount -t auto -o ro $iso_device /hd-media 2>/dev/null
+ cd /hd-media
+ mount -t iso9660 -o loop,ro,exec $iso_to_try /cdrom 2>/dev/null
+
+ analyze_cd
+
+ db_subst iso-scan/success FILENAME $iso_to_try
+ db_set iso-scan/filename $iso_to_try
+ db_subst iso-scan/success DEVICE $iso_device
+ db_input medium iso-scan/success || true
+ db_go || true
+
+ anna-install apt-mirror-setup || true
+ if [ ! -e /cdrom/.disk/base_installable ]; then
+ log "Base system not installable from CD image, requesting choose-mirror"
+ anna-install choose-mirror || true
else
- break
+ anna-install apt-cdrom-setup || true
+
+ # Install <codename>-support udeb (if available).
+ db_get cdrom/codename
+ anna-install $RET-support || true
fi
-done
+ exit 0
+}
-if [ "$MOUNTABLE_DEVS_COUNT" != 0 ]; then
- # Ask about the more expensive second pass.
- db_subst iso-scan/ask_second_pass NUM_FILESYSTEMS $MOUNTABLE_DEVS_COUNT
- db_subst iso-scan/ask_second_pass NUM_DIRS $TOPLEVEL_DIRS_COUNT
- db_input critical iso-scan/ask_second_pass || true
- db_go || true
+#--------------------
+# Main program
- db_get iso-scan/ask_second_pass
- if [ "$RET" = true ]; then
- db_progress START 0 $TOPLEVEL_DIRS_COUNT iso-scan/progress_title
- log "Second pass: Search whole filesystems for ISOs."
- # To save time, only ones we mounted successfully before.
- for dev in $MOUNTABLE_DEVS; do
- if mount_device $dev; then
- db_subst iso-scan/progress_scan DRIVE $dev
- log "Mounted $dev for second pass"
- cd /hd-media
- for dir in *; do
- if [ -d "$dir" ]; then
- db_subst iso-scan/progress_scan DIRECTORY "$dir/"
- db_progress INFO iso-scan/progress_scan
- for iso in $(find $dir 2>/dev/null | grep -i '\.iso$'); do
- log "Found ISO $iso on $dev"
- ISO_COUNT=$(expr $ISO_COUNT + 1)
- try_iso $iso $dev
- done
- db_progress STEP 1
- fi
- done
- cd /
- umount /hd-media
+# iso-scan is divided in following stages :
+# 1/ get list of devices (no debconf question)
+# 2 and 3/ select a device (or all detected ones)
+# 4 and 5/ parse selected devices looking for Debian ISOs and let choose one
+
+# This conf script is capable of backing up
+db_capb backup
+
+STATE=1
+SELECTED_ISO=
+while [ "$STATE" -ge 1 -a "$STATE" -le 5 ]; do
+ NEXT_STATE_OK=
+ NEXT_STATE_CANCEL=
+ case "$STATE" in
+ 1) # get list of devices
+
+ # Try to unmount anything that was previously mounted.
+ umount -d /cdrom 2>/dev/null || true
+ umount -d /hd-media 2>/dev/null || true
+
+ # Hopefully this will find the drive.
+ hw-detect iso-scan/detect_progress_title || true
+
+ # Load up every filesystem known to man. The drive could have anything.
+ FS="ext2 ext3 ext4 reiserfs fat vfat xfs jfs iso9660 hfsplus hfs ntfs"
+ for fs in $FS; do
+ modprobe $fs >/dev/null 2>&1 || true
+ done
+ modprobe loop >/dev/null || true
+
+ mkdir /cdrom 2>/dev/null || true
+ mkdir /hd-media 2>/dev/null || true
+
+ DEVS="$(list-devices partition; list-devices disk; list-devices maybe-usb-floppy)"
+ log "devices found: '$DEVS'"
+ go=0 # no debconf question
+ ;;
+
+ 2) # ask user to select a device (all by default) :
+ list_devices=$(for dev in $DEVS; do echo -n "$dev, "; done)
+ db_clear
+ db_subst shared/ask_device DEVICES_LIST $list_devices
+ db_subst shared/ask_device PURPOSE "to search for install ISO(s)"
+ db_subst shared/ask_device USED_FOR "you know it contains the installer ISO"
+ db_input medium shared/ask_device || true
+ go=1
+ ;;
+
+ 3) # manually specify a device ?
+ db_get shared/ask_device
+ if [ "$RET" = "<specify device manually>" ]; then
+ log "let user specify device"
+ db_input critical shared/enter_device || true
+ go=1
+ else
+ go=0
+ fi
+ ;;
+
+ 4) # parse selected device(s) and search for install ISO(s) [first pass]
+ db_get shared/ask_device
+ if [ "$RET" = "<specify device manually>" ]; then
+ db_get shared/enter_device
+ fi
+ selected_devices=$RET
+ if [ "$selected_devices" = '<all detected devices>' ]; then
+ selected_devices=$DEVS
+ fi
+ log "selected_device(s)='$selected_devices'"
+
+ ISOS_FOUND=
+ MOUNTABLE_DEVS=
+ ISO_COUNT=0
+ ISO_MOUNT_COUNT=0
+ TOPLEVEL_DIRS_COUNT=0
+ MOUNTABLE_DEVS_COUNT=0
+ scan_device_for_isos 0 "$selected_devices"
+ log "ISOS_FOUND='$ISOS_FOUND'"
+
+ if [ -z "$ISOS_FOUND" ]; then
+ # no ISO found :
+ log "MOUNTABLE_DEVS_COUNT='$MOUNTABLE_DEVS_COUNT'"
+ if [ $MOUNTABLE_DEVS_COUNT -gt 0 ]; then
+ # ask for a second pass if possible
+ db_input critical iso-scan/ask_second_pass || true
+ go=1
+ NEXT_STATE_CANCEL=2
+ else
+ # go back to select another device
+ db_input critical iso-scan/no-isos || true
+ go=1
+ NEXT_STATE_OK=2
fi
- done
+ else # one or multiple ISO(s) found : ask which one we'll use
+ db_clear
+ db_subst iso-scan/ask_which_iso ISOS_LIST "$ISOS_FOUND, <search more>"
+ db_subst iso-scan/ask_which_iso SECOND_PASS ", or ask for a more thorough search (beware, it may take a long time)."
+ db_input medium iso-scan/ask_which_iso || true
+ go=1
+ NEXT_STATE_CANCEL=2
+ fi
+ ;;
- db_progress STOP
+ 5) # get selected ISO, or do a second pass if requested
+ secpass=1
+ if [ -z "$ISOS_FOUND" ]; then
+ db_get iso-scan/ask_second_pass
+ if [ "$RET" != true ]; then
+ # don't want a second pass : return to select another device
+ go=0
+ secpass=0
+ NEXT_STATE_OK=2
+ fi
+ else
+ db_get iso-scan/ask_which_iso
+ if [ "$RET" != "<search more>" ]; then
+ # selected an ISO : don't go for a second pass
+ go=0
+ secpass=0
+ fi
+ fi
+
+ if [ $secpass = 1 ]; then
+ ### should I reset ISO found, or get them to present it a second time with
+ ### new ones found ?
+ scan_device_for_isos 1 "$selected_devices"
+ log "ISOS_FOUND (2nd pass)='$ISOS_FOUND'"
+
+ if [ -z "$ISOS_FOUND" ]; then
+ # Failure. Display the best message we can about what happened.
+ if [ "$ISO_COUNT" = 0 ]; then
+ db_input critical iso-scan/no-isos || true
+ elif [ "$ISO_MOUNT_COUNT" != "$ISO_COUNT" ]; then
+ db_input critical iso-scan/bad-isos || true
+ else
+ db_input critical iso-scan/other-isos || true
+ fi
+ log "Failing with ISO_COUNT = $ISO_COUNT, MOUNTABLE_DEVS_COUNT = $MOUNTABLE_DEVS_COUNT, ISO_MOUNT_COUNT = $ISO_MOUNT_COUNT"
+ go=1
+ NEXT_STATE_CANCEL=2
+ NEXT_STATE_OK=0
+
+ else
+ # one or multiple ISO(s) found : ask which one we'll use
+ db_clear
+ db_subst iso-scan/ask_which_iso ISOS_LIST "$ISOS_FOUND"
+ db_subst iso-scan/ask_which_iso SECOND_PASS "."
+ if echo "$ISOS_FOUND" | grep -q ', '; then
+ dc_level=high
+ else
+ dc_level=medium
+ fi
+ db_input $dc_level iso-scan/ask_which_iso || true
+ go=1
+ NEXT_STATE_CANCEL=2
+ fi
+ fi
+ ;;
+ esac
+
+ # possibly tell debconf to give its template and then go next state
+ if [ -z "$NEXT_STATE_OK" ]; then NEXT_STATE_OK=$(( $STATE + 1)); fi
+ if [ -z "$NEXT_STATE_CANCEL" ]; then NEXT_STATE_CANCEL=$(($STATE - 1)); fi
+ if [ "$go" = 0 ] || db_go; then
+ STATE=$NEXT_STATE_OK
+ else
+ STATE=$NEXT_STATE_CANCEL
fi
-fi
+done
-# Failure. Display the best message we can about what happened.
-# Let them know the second pass failed too.
-if [ "$ISO_COUNT" = 0 ]; then
- db_input critical iso-scan/no-isos || true
-elif [ "$ISO_MOUNT_COUNT" != "$ISO_COUNT" ]; then
- db_input critical iso-scan/bad-isos || true
-else
- db_input critical iso-scan/other-isos || true
+if [ "$STATE" = 0 ]; then
+ # can't go back first question, so exit
+ exit 1
fi
-db_go || true
-log "Failing with ISO_COUNT = $ISO_COUNT, MOUNTABLE_DEVS_COUNT = $MOUNTABLE_DEVS_COUNT, ISO_MOUNT_COUNT = $ISO_MOUNT_COUNT"
-exit 1
+
+# get selected ISO
+db_get iso-scan/ask_which_iso
+SELECTED_ISO=$RET
+
+device=/dev/$(echo "$SELECTED_ISO" | sed -e 's/\[\(.*\)\] .*/\1/')
+iso=$(echo "$SELECTED_ISO" | sed -e 's/\[.*\] \(.*\) (.*/\1/')
+log "Selected ISO: $iso on $device"
+
+use_this_iso $iso $device
diff -Naur iso-scan-1.28ref/debian/iso-scan.templates iso-scan-1.28+testiso2/debian/iso-scan.templates
--- iso-scan-1.28ref/debian/iso-scan.templates 2009-02-25 08:32:12.000000000 +0100
+++ iso-scan-1.28+testiso2/debian/iso-scan.templates 2010-01-28 21:18:44.000000000 +0100
@@ -53,8 +53,8 @@
it may have a bad filename (not ending in ".iso"), or it may be on a
file system that could not be mounted.
.
- You'll have to use an alternative installation method, or try again
- after you've fixed the ISO image.
+ You'll have to use an alternative installation method, select another device
+ to look for ISO image, or try again after you've fixed it.
Template: iso-scan/bad-isos
Type: error
@@ -63,18 +63,18 @@
While one or more possible ISO images were found, they could not be mounted.
The ISO image you downloaded may be corrupt.
.
- You'll have to use an alternative installation method, or try again
- after you've fixed the ISO image.
+ You'll have to use an alternative installation method, select another device
+ to look for ISO image, or try again after you've fixed it.
Template: iso-scan/other-isos
Type: error
# :sl3:
_Description: No installer ISO image found
While one or more possible ISO images were found, they did not look like
- valid installer ISO images.
+ valid installer ISO images.
.
- You'll have to use an alternative installation method, or try again
- after you've fixed the ISO image.
+ You'll have to use an alternative installation method, select another device
+ to look for ISO image, or try again after you've fixed it.
Template: iso-scan/success
Type: note
@@ -87,3 +87,34 @@
Type: text
Description: for internal use only
For use by other parts of d-i, such as base-installer
+
+Template: shared/ask_device
+Type: select
+Choices: <all detected devices>, ${DEVICES_LIST}<specify device manually>
+Default: all
+^Description: Select a detected device / partition ${PURPOSE}
+ You can select the device ${USED_FOR}, specify manually a device
+ not detected, or go back to rescan list of devices,
+ useful for slow USB devices for example.
+
+Template: shared/enter_device
+Type: string
+^Description: Type the device name
+
+Template: iso-scan/ask_which_iso
+Type: select
+Choices: ${ISOS_LIST}
+^Description: Select an ISO file from ones found on selected device(s).
+ One or multiple ISO files have been detected on selected device(s),
+ select one you want to use${SECOND_PASS}.
+
+Template: iso-scan/ask_right_iso
+Type: boolean
+Default: true
+# :sl3:
+^Description: Is ISO file ${FILENAME} the right image for installation?
+ The ISO file ${FILENAME} on ${DEVICE} (${SUITE}, code ${CODENAME},
+ self-described as '${DESCRIPTION}') will be used as the
+ installation ISO image.
+ If you have multiple ISO files on the same installer drive,
+ you may select here which one you want to use now.
Reply to: