[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: