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

[RFC] Support for using multiple CDs during installation



Attached patches to apt-setup and pkgsel make it possible to scan multiple 
CD/DVDs from a set during apt-setup and use them during pkgsel.

The patches have been tested and work. I've done several successful desktop 
installations using CD1 plus CD2.
However, the patches are still a bit rough and there are some issues that 
need discussion.

The main issue with the current patches is the new dialogs. Comments on them 
and suggestions for improvement are welcome.

If those are fixed, the patches could be considered for inclusion even 
though there are some remaining issues (see below). I'm unsure myself 
whether any of these issues is serious enough to prevent inclusion.

Changes by the patch
--------------------
Scanning for extra CDs is only supported:
- if the installation CD is a full CD or DVD
- if the installation method is not hd-media

The apt-setup generator 50cdrom has been moved to 40cdrom; a new generator 
41cdset was added to allow scanning of additional CDs. The generator for 
mirror sources run after that.

When base-config was integrated into D-I, we had find a way to make tasksel 
install from CD images for hd-media installations. This was solved by bind 
mounting the CD into target and telling apt-cdrom not to mount/unmount CDs.
In the patch for apt-setup this is reverted: apt-cdrom is allowed to mount
CDs again. Note that base-installation is not changed in any way.

For CD changing by apt-cdrom in /target to be possible, the installation CD 
has to be unmounted in the D-I environment. While it is unmounted, no udeb
installations are possible.
Both in apt-setup (after scanning additional CDs) and in pkgsel (after 
tasksel) the installation CD is mounted again so other installation steps 
do not break.

Remaining issues
----------------
After the change to the 2nd CD in pkgsel, the progress bar starts at 0 again 
instead of continuing from its old position.

The prompt for CD changing works during pkgsel, but apparently not for a 
normal apt-install. During initial tests, installation of grub failed 
because CD2 was still mounted and I never got the prompt to change CDs.
This is worked around by making sure CD1 is installed again, but if any 
packages from other CDs are needed for whatever reason _after_ pkgsel, the 
installation will hang for the same reason.
I've not really looked yet at why this does not work.

The mechanism to mount the CD again for the D-I environment is somewhat 
fragile, for two reasons:
- installation of extra udebs is now not possible during pkgsel; this is
  not a serious limitation as in practice this is probably not needed
- if a CD change is needed to install a package _after_ pkgsel, this will
  fail because the CD is mounted in the D-I environment (the CD drive is
  locked)
It would be much better if anna or udpkg could detect that the CD is not 
mounted and ask for it to be mounted when needed and then automatically 
unmount it again after use so not to interfere with CD changing in /target.

During my tests, the first mount of a CD after changing it would 
consistently fail. This is probably a bug in VirtualBox.
I've added a workaround for this to make working on this a bit easier, but 
that should probably be removed.

Cheers,
FJP

commit ef6fc9ba670e14ed9d886dbf137ef54c46bdd27b
Author: Frans Pop <fjp@debian.org>
Date:   Mon Oct 22 12:48:22 2007 +0200

    Initial proof-of-concept implementation of support for CD sets

diff --git a/packages/apt-setup/debian/apt-cdrom-setup.install b/packages/apt-setup/debian/apt-cdrom-setup.install
index 7604090..584b985 100644
--- a/packages/apt-setup/debian/apt-cdrom-setup.install
+++ b/packages/apt-setup/debian/apt-cdrom-setup.install
@@ -1 +1,3 @@
-generators/50cdrom usr/lib/apt-setup/generators
+load-install-cd    /usr/bin
+generators/40cdrom usr/lib/apt-setup/generators
+generators/41cdset usr/lib/apt-setup/generators
diff --git a/packages/apt-setup/debian/apt-cdrom-setup.templates b/packages/apt-setup/debian/apt-cdrom-setup.templates
index 430267b..95cab60 100644
--- a/packages/apt-setup/debian/apt-cdrom-setup.templates
+++ b/packages/apt-setup/debian/apt-cdrom-setup.templates
@@ -8,6 +8,37 @@ _Description: apt configuration problem
  An attempt to configure apt to install additional packages from the CD
  failed.
 
+Template: apt-setup/cdrom/set-first
+Type: boolean
+Default: false
+_Description: Scan additional CDs or DVDs?
+ If you have additional CDs or DVDs available from the same set as the
+ installation CD, you can now scan these. This will allow packages to be
+ installed from those CD/DVDs during the next step of the installation.
+ .
+ Please insert the new CD or DVD before you make your selection.
+
+Template: apt-setup/cdrom/set-next
+Type: boolean
+Default: false
+_Description: Scan another CD or DVD?
+ Please insert the new CD or DVD before you make your selection.
+
+Template: apt-setup/cdrom/set-failed
+Type: boolean
+Default: false
+_Description: Scan another CD or DVD?
+ An attempt to configure apt to install additional packages from the CD
+ failed.
+ .
+ Do you wish to try again?
+
+Template: apt-setup/cdrom/load-cd1
+Type: text
+_Description: Insert the original installation CD/DVD.
+ Please reinsert the first CD or DVD of your set in the drive before
+ you continue.
+
 Template: finish-install/progress/apt-cdrom-setup
 Type: text
 # finish-install progress bar item
diff --git a/packages/apt-setup/debian/changelog b/packages/apt-setup/debian/changelog
index 45ec35d..1182e12 100644
--- a/packages/apt-setup/debian/changelog
+++ b/packages/apt-setup/debian/changelog
@@ -2,6 +2,7 @@ apt-setup (1:0.30) UNRELEASED; urgency=low
 
   * apt-setup-verify: 'apt-get update' does not actually verify CD/DVD
     sources, so skip those.
+  * Initial proof-of-concept implementation of support for CD sets.
 
  -- Frans Pop <fjp@debian.org>  Wed, 24 Oct 2007 16:30:45 +0200
 
diff --git a/packages/apt-setup/generators/40cdrom b/packages/apt-setup/generators/40cdrom
new file mode 100755
index 0000000..9579d9e
--- /dev/null
+++ b/packages/apt-setup/generators/40cdrom
@@ -0,0 +1,29 @@
+#!/bin/sh
+set -e
+
+. /usr/share/debconf/confmodule
+
+file="$1"
+
+logoutput=""
+if [ "$CATCHLOG" ]; then
+	logoutput="log-output -t apt-setup"
+fi
+
+chroot=
+if [ "$ROOT" ]; then
+	chroot=chroot
+fi
+
+tmp=$($chroot $ROOT tempfile)
+# apt-cdrom can be interactive, avoid that
+$logoutput $chroot $ROOT apt-cdrom add \
+	-o Dir::Etc::SourceList=$tmp \
+	</dev/null
+cat $ROOT$tmp >> $file
+rm -f $ROOT$tmp $ROOT$tmp~
+
+if ! apt-setup-verify $file; then
+	db_input critical apt-setup/cdrom/failed || true
+	db_go || exit 10
+fi
diff --git a/packages/apt-setup/generators/41cdset b/packages/apt-setup/generators/41cdset
new file mode 100755
index 0000000..f353bcb
--- /dev/null
+++ b/packages/apt-setup/generators/41cdset
@@ -0,0 +1,70 @@
+#!/bin/sh
+set -e
+
+. /usr/share/debconf/confmodule
+
+file="$1"
+
+if [ ! -e /cdrom/.disk/cd_type ] || [ -d /hd-media ]; then
+	exit 0
+fi
+# Should probably also fail for KDE/XFce/multi-arch CDs (or prompt that
+# 1st CD/DVD of the set needs to be loaded as well)
+cd_type=$(cat /cdrom/.disk/cd_type)
+if [ "$cd_type" != full_cd ] && [ "$cd_type" != dvd ]; then
+	exit 0
+fi
+
+logoutput=""
+if [ "$CATCHLOG" ]; then
+	logoutput="log-output -t apt-setup"
+fi
+
+chroot=
+if [ "$ROOT" ]; then
+	chroot=chroot
+
+	# Let apt-cdrom do its own mounting (was disabled in base-installer)
+	rm -f $ROOT/etc/apt/apt.conf.d/00NoMountCDROM
+
+	# Save identification of installation CD
+	$logoutput --pass-stdout $chroot $ROOT \
+		apt-cdrom ident | grep "^Identifying" | cut -d" " -f2 \
+		>/var/lib/install-cd.id
+
+	# We can only change CDs if current CD is unmounted
+	$logoutput umount /cdrom || true
+	$logoutput $chroot $ROOT umount /cdrom || true
+fi
+
+tmp=$($chroot $ROOT tempfile)
+
+db_input high apt-setup/cdrom/set-first || true
+db_go || exit 10
+db_get apt-setup/cdrom/set-first
+while [ "$RET" = true ]; do
+	# The first mount of an image can fail (at least in VirtualBox)
+	$logoutput $chroot $ROOT mount /cdrom && \
+		$logoutput $chroot $ROOT umount /cdrom || true
+
+	# apt-cdrom can be interactive, avoid that
+	$logoutput $chroot $ROOT apt-cdrom add \
+		-o Dir::Etc::SourceList=$tmp \
+		</dev/null
+	cat $ROOT$tmp >> $file
+	rm -f $ROOT$tmp $ROOT$tmp~
+
+	if apt-setup-verify $file; then
+		template=apt-setup/cdrom/set-next
+	else
+		template=apt-setup/cdrom/set-failed
+	fi
+	db_input critical $template || true
+	db_go || exit 10
+	db_get $template
+done
+
+# Make sure the installation CD is loaded again
+if [ "$ROOT" ]; then
+	load-install-cd "$ROOT"
+fi
diff --git a/packages/apt-setup/generators/50cdrom b/packages/apt-setup/generators/50cdrom
deleted file mode 100755
index 9579d9e..0000000
--- a/packages/apt-setup/generators/50cdrom
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/sh
-set -e
-
-. /usr/share/debconf/confmodule
-
-file="$1"
-
-logoutput=""
-if [ "$CATCHLOG" ]; then
-	logoutput="log-output -t apt-setup"
-fi
-
-chroot=
-if [ "$ROOT" ]; then
-	chroot=chroot
-fi
-
-tmp=$($chroot $ROOT tempfile)
-# apt-cdrom can be interactive, avoid that
-$logoutput $chroot $ROOT apt-cdrom add \
-	-o Dir::Etc::SourceList=$tmp \
-	</dev/null
-cat $ROOT$tmp >> $file
-rm -f $ROOT$tmp $ROOT$tmp~
-
-if ! apt-setup-verify $file; then
-	db_input critical apt-setup/cdrom/failed || true
-	db_go || exit 10
-fi
diff --git a/packages/apt-setup/load-install-cd b/packages/apt-setup/load-install-cd
new file mode 100755
index 0000000..7c013b5
--- /dev/null
+++ b/packages/apt-setup/load-install-cd
@@ -0,0 +1,36 @@
+#!/bin/sh
+set -e
+
+. /usr/share/debconf/confmodule
+
+ROOT="$1"
+[ "$ROOT" ] || exit 1
+
+[ -e /var/lib/install-cd.id ] || exit 0
+
+logoutput="log-output -t load-install-cd"
+
+check_id() {
+	# The first mount of an image can fail (at least in VirtualBox)
+	$logoutput chroot $ROOT mount /cdrom && \
+		$logoutput chroot $ROOT umount /cdrom || true
+
+	cd_id=$($logoutput --pass-stdout chroot $ROOT \
+		apt-cdrom ident | grep "^Identifying" | cut -d" " -f2)
+
+	# apt-cdrom ident leaves CD mounted
+	$logoutput chroot $ROOT umount /cdrom || true
+
+	if [ "$cd_id" = "$(cat /var/lib/install-cd.id)" ]; then
+		return 0
+	fi
+	return 1
+}
+
+while ! check_id; do
+	db_input high apt-setup/cdrom/load-cd1 || true
+	db_go || exit 10
+done
+
+db_get cdrom-detect/cdrom_device
+$logoutput mount -t iso9660 -o ro,exec $RET /cdrom
commit 87cd345af288c233174f9a6bfe6db46056dd8fde
Author: Frans Pop <fjp@debian.org>
Date:   Wed Oct 24 14:18:10 2007 +0200

    Allow CD/DVD changing during package installation

diff --git a/packages/pkgsel/debian/changelog b/packages/pkgsel/debian/changelog
index 787222d..67f5a9f 100644
--- a/packages/pkgsel/debian/changelog
+++ b/packages/pkgsel/debian/changelog
@@ -1,3 +1,9 @@
+pkgsel (0.16) UNRELEASED; urgency=low
+
+  * Allow CD/DVD changing during package installation.
+
+ -- Frans Pop <fjp@debian.org>  Wed, 24 Oct 2007 13:07:23 +0200
+
 pkgsel (0.15) unstable; urgency=low
 
   [ Frans Pop ]
diff --git a/packages/pkgsel/debian/postinst b/packages/pkgsel/debian/postinst
index 9286248..b7969b2 100755
--- a/packages/pkgsel/debian/postinst
+++ b/packages/pkgsel/debian/postinst
@@ -19,6 +19,18 @@ cleanup () {
 	done
 }
 
+load_cd1() {
+	if [ "$MULTICD" ]; then
+		load-install-cd "/target" || true
+	fi
+}
+
+# Check if we have multiple CDs listed in sources.list
+MULTICD=""
+if [ $(grep "^deb cdrom:" /target/etc/apt/sources.list | wc -l) -gt 1 ]; then
+	MULTICD=1
+fi
+
 db_progress START 0 100 debian-installer/pkgsel/title
 db_progress INFO pkgsel/progress/init
 
@@ -39,6 +51,12 @@ config=$(chroot /target debconf-apt-progress --config| sed "s/$/;/")
 
 db_progress STEP 1
 
+# Unmount the installation CD to allow CD changing; as it may be needed
+# again after pkgsel, make sure it is reloaded before exiting
+if [ "$MULTICD" ]; then
+	umount /cdrom
+fi
+
 # Install popularity-contest but remove it if the user decides not to
 # participate.
 if in-target sh -c "$config debconf-apt-progress --from 1 --to 5 --logstderr -- apt-get -o APT::Install-Recommends=false -q -y -f install popularity-contest"; then
@@ -67,6 +85,7 @@ if [ "$ret" != 0 ]; then
 		log "cleanup failed"
 	fi
 	db_progress STOP
+	load_cd1
 	exit $ret
 fi
 
@@ -86,6 +105,7 @@ if [ "$RET" ]; then
 			log "cleanup failed"
 		fi
 		db_progress STOP
+		load_cd1
 		exit $ret
 	fi
 fi
@@ -106,3 +126,5 @@ fi
 
 db_progress STEP 3
 db_progress STOP
+
+load_cd1

Attachment: signature.asc
Description: This is a digitally signed message part.


Reply to: