From f90deda0152c72c6d6ef01d9e504e5d4dfcf118a Mon Sep 17 00:00:00 2001
From: Mike Hibler <mike@flux.utah.edu>
Date: Sat, 17 Aug 2002 01:15:56 +0000
Subject: [PATCH] <cdrom> is the CD-ROM filesystem that winds up in the .iso   
      (~stoller/dga.cdrom) <image> is the disk filesystem that winds up
 imagezipped         (pc16's disk) <floppy> is the floppy image for the CD-ROM
         (~stoller/dga.cdrom/floppies/boot.flp) ===========

<cdrom>/etc/rc.cdroot:
        Add "-c 16" to mount_mfs commands to get rid of warning message.

<cdrom>/usr/site/sbin/register.pl
        Added "showprogress" which, when set, will do more verbose
        output from wget and imageunzip.  Added more "be patient" messages,
        they now use a common string.  Warn about kernel messages when
        creating tmp filesystem.  Use installed emulab.net, not Leigh's
        development tree.  Get "Dance with Netbed" prompt off same line
        as "starting local daemons..."

<cdrom>/usr/site/sbin/waipconfig.pl
        Change WhichRawDisk to use non-'r' special files, there is no
        distinct raw device interface anymore.  Also add ATAPI RAID to
        the list to try.  Default netmask to 255.255.255.0.
        Split-off initial install path some so that we can introduce
        prompts which don't time out (like, "are you sure you want to
        do this?").  rawbootdisk becomes netbed_disk in the rc.conf.local,
        also add and writeout netbsd_IP for use in the register.pl
        script (which doesn't use it yet).

<image>/etc/ntp.conf:
        Change "remote peers" (servers) to utah.ron and mit.ron

<image>/var:
        Cleaned out logfiles and other cruft.  Logfiles had a little too
        much info in them for my tastes (hostnames, IPs, users...)

<floppy>/boot/loader:
        Fixed "Aborted" error message
---
 cdrom/waboot/emulabboot.sh |   4 +-
 cdrom/waboot/rc.emulab     |   4 +
 cdrom/waboot/register.pl   |  78 ++++++++++++----
 cdrom/waboot/register.sh   |   4 +-
 cdrom/waboot/waipconfig.pl | 181 ++++++++++++++++++++++++++-----------
 5 files changed, 196 insertions(+), 75 deletions(-)

diff --git a/cdrom/waboot/emulabboot.sh b/cdrom/waboot/emulabboot.sh
index 56d06f764e..289e0f79e0 100755
--- a/cdrom/waboot/emulabboot.sh
+++ b/cdrom/waboot/emulabboot.sh
@@ -15,12 +15,12 @@
 . /etc/rc.conf.local
 
 #
-# rawbootdisk is set in rc.conf.local by the CDROM boot image.
+# netbed_disk is set in rc.conf.local by the CDROM boot image.
 #
 case "$1" in
 start)
 	if [ -f /usr/site/sbin/tbbootconfig ]; then
-		/usr/site/sbin/tbbootconfig -c 1 $rawbootdisk
+		/usr/site/sbin/tbbootconfig -c 1 $netbed_disk
 
 		case $? in
 		0)
diff --git a/cdrom/waboot/rc.emulab b/cdrom/waboot/rc.emulab
index 7257a115ba..dca51b5428 100755
--- a/cdrom/waboot/rc.emulab
+++ b/cdrom/waboot/rc.emulab
@@ -28,6 +28,10 @@ EmulabCheckIPConfig()
 		case $? in
 	        0)
 		       ;;
+		-277)
+			echo 'Installation aborted'
+			exit 1
+			;;
 		*)
 			echo 'Error in testbed configuration program'
 			#reboot
diff --git a/cdrom/waboot/register.pl b/cdrom/waboot/register.pl
index d47676825e..745d481c0b 100755
--- a/cdrom/waboot/register.pl
+++ b/cdrom/waboot/register.pl
@@ -40,9 +40,9 @@ delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
 #
 # Locals
 #
-#my $WWW        = "https://www.emulab.net";
+my $WWW        = "https://www.emulab.net";
 #my $WWW        = "http://golden-gw.ballmoss.com:8080/~stoller/testbed";
-my $WWW         = "https://www.emulab.net/~stoller/www";
+#my $WWW         = "https://www.emulab.net/~stoller/www";
 my $etcdir	= "/etc";
 my $cdkeyfile	= "$etcdir/emulab.cdkey";
 my $setupconfig	= "$etcdir/emulab-setup.txt";
@@ -58,10 +58,13 @@ my $logfile     = "/tmp/register.log";
 my $needstore   = 0;
 my $fromscratch = 0;
 my $needumount  = 0;
+my $showprogress= 1;
 my $cdkey;
 my $privkey;
 my %slicesizes;
 	
+my $PATIENCEMSG  = "This could take several minutes, please be patient!\n";
+
 my %config = ( privkey        => undef,
 	       fdisk          => undef,
 	       slice1_image   => undef,
@@ -123,6 +126,7 @@ else {
 #
 # See if we want to continue. Useful for debugging.
 # 
+print "\n";
 if (! (Prompt("Dance with Netbed?", "Yes", 10) =~ /yes/i)) {
     exit(0);
 }
@@ -131,7 +135,9 @@ if (! (Prompt("Dance with Netbed?", "Yes", 10) =~ /yes/i)) {
 # Get the plain device names (ad0, rad0).
 #
 my $rawdevice   = substr($rawbootdisk, rindex($rawbootdisk, '/') + 1);
-my $blockdevice = substr($rawdevice, 1);
+# XXX no difference in block/raw anymore
+#my $blockdevice = substr($rawdevice, 1);
+my $blockdevice = $rawdevice;
 
 #
 # See if this is the first time. Look for the magic boot header.
@@ -178,6 +184,7 @@ if ($needstore) {
 	    if (!defined($fdisk));
 
 	print "Creating a temporary filesystem on slice 2 to hold images.\n";
+	print "    (ignore kernel generated \"no disk label\" messages.)\n";
 	
 	#
 	# First time through we need to lay down a DOS partition table.
@@ -306,9 +313,15 @@ for ($i = 1; $i <= 4; $i++) {
     # If told to load a local image from the CDROM, its really easy!
     # 
     if (! ($image =~ /^http:.*$/ || $image =~ /^ftp:.*$/)) {
-	print "Loading image for slice $i from $image. Be patient!\n";
-	
-	mysystem("imageunzip -s $i -d /$image $rawbootdisk");
+	print "Loading image for slice $i from $image.\n";
+	print $PATIENCEMSG;
+
+	if ($showprogress) {
+	    print "(Output indicates uncompressed bytes written to disk.)\n";
+	    system("imageunzip -o -s $i -d /$image $rawbootdisk");
+	} else {
+	    mysystem("imageunzip -s $i -d /$image $rawbootdisk");
+	}
 	fatal("Failed to lay down image /$image!")
 	    if ($?);
 	goto finished;
@@ -320,10 +333,14 @@ for ($i = 1; $i <= 4; $i++) {
     if ($image =~ /^http:.*$/ || $image =~ /^ftp:.*$/) {
       again:
 	print "Transferring image to temp storage for slice $i from:\n".
-	      "    $image \n".
-	      "    Please be patient! \n";
+	      "    $image \n";
+	print $PATIENCEMSG;
 	
-	mysystem("$wget -nv -O /mnt/image.ndz $image");
+	if ($showprogress) {
+	    system("$wget -O /mnt/image.ndz $image");
+	} else {
+	    mysystem("$wget -nv -O /mnt/image.ndz $image");
+	}
 	fatal("Failed to transfer image!")
 	    if ($?);
 
@@ -331,7 +348,9 @@ for ($i = 1; $i <= 4; $i++) {
 	# If an md5 hash was provided, compare it.
 	#
 	if (defined($hash)) {
-	    print "Checking MD5 hash of the image. Please be patient!\n";
+	    print "Checking MD5 hash of the image.\n";
+	    print $PATIENCEMSG;
+
 	    my $hval = `md5 -q /mnt/image.ndz`;
 	    chomp($hval);
 
@@ -343,9 +362,14 @@ for ($i = 1; $i <= 4; $i++) {
 	}
 
 	print "Writing image from temp storage to slice $i.\n";
-	print "This could take several minutes. Please be *very* patient!\n";
-	
-	mysystem("imageunzip -s $i -o /mnt/image.ndz $rawbootdisk");
+	print $PATIENCEMSG;
+
+	if ($showprogress) {
+	    print "(Output indicates uncompressed bytes written to disk.)\n";
+	    system("imageunzip -o -s $i /mnt/image.ndz $rawbootdisk");
+	} else {
+	    mysystem("imageunzip -s $i /mnt/image.ndz $rawbootdisk");
+	}
 	fatal("Failed to lay down image!")
 	    if ($?);
 
@@ -485,7 +509,8 @@ sub GetInstructions()
 	}
 	else {
 	    while (!defined($privkey)) {
-		$privkey = Prompt("Please enter you CD password?", undef);
+		$privkey = Prompt("Please enter your 16 character CD password",
+				  undef);
 	    }
 	}
 
@@ -708,8 +733,8 @@ sub MakeFS($$)
 	# If told to use a local image from the CDROM, its really easy!
 	# 
 	if (! ($tarball =~ /^http:.*$/ || $tarball =~ /^ftp:.*$/)) {
-	    print "Unpacking $tarball to $mntpoint.\n".
-		"    Please be patient!\n";
+	    print "Unpacking $tarball to $mntpoint.\n";
+	    print $PATIENCEMSG;
 	
 	    mysystem("tar -zxf /$tarball");
 	    fatal("Failed to untar /$tarball!")
@@ -720,14 +745,16 @@ sub MakeFS($$)
 	    # Transfer the image to the temp store and then unzip to the slice.
 	    #
 	    print "Transferring tarball for $mntpoint from:\n".
-	      "    $tarball\n".
-	      "    Please be patient! \n";
+		  "    $tarball\n";
+	    print $PATIENCEMSG;
 	
 	    mysystem("$wget -nv -O /mnt/slicex.tar.gz $tarball");
 	    fatal("Failed to transfer tarball!")
 		if ($?);
 
-	    print "Unpacking tarball. Please be patient!\n";
+	    print "Unpacking tarball.\n";
+	    print $PATIENCEMSG;
+
 	    mysystem("tar -zxf /mnt/slicex.tar.gz");
 	    fatal("Failed to untar /mnt/slicex.tar.gz!")
 		if ($?);
@@ -867,7 +894,18 @@ sub MountRoot()
 # 
 sub WriteConfigBlock()
 {
-    my $cmd = "$tbboot -f -d -w $softconfig -k 1 -c 0 ";
+    my $cmd;
+
+    # XXX for now hack, tbbootconfig doesn't know about 'bootdisk'
+    if (1) {
+	mysystem("grep -v bootdisk $softconfig > /tmp/softcfg");
+	fatal("Could not prepare $softconfig for writing!")
+	    if ($?);
+	$cmd = "$tbboot -f -d -w /tmp/softcfg -k 1 -c 0 ";
+    } else {
+	$cmd = "$tbboot -f -d -w $softconfig -k 1 -c 0 ";
+    }
+
     if (defined($config{privkey})) {
 	$cmd .= "-e $config{privkey} ";
     }
diff --git a/cdrom/waboot/register.sh b/cdrom/waboot/register.sh
index 90336b8c46..aeb354dc13 100755
--- a/cdrom/waboot/register.sh
+++ b/cdrom/waboot/register.sh
@@ -8,7 +8,7 @@
 #
 # This file goes in /usr/local/etc/rc.d on the CDROM.
 #
-# Get the rawdisk and pass that to the registration program. It does
+# Get the disk and pass that to the registration program. It does
 # all the actual work.
 # 
 
@@ -17,7 +17,7 @@
 case "$1" in
 start)
 	if [ -f /usr/site/sbin/register.pl ]; then
-		/usr/site/sbin/register.pl $rawbootdisk
+		/usr/site/sbin/register.pl $netbed_disk
 		exit $?
 	fi
 	;;
diff --git a/cdrom/waboot/waipconfig.pl b/cdrom/waboot/waipconfig.pl
index e6e55adba7..056bbfbb73 100755
--- a/cdrom/waboot/waipconfig.pl
+++ b/cdrom/waboot/waipconfig.pl
@@ -45,7 +45,7 @@ delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
 #
 # The raw disk device. 
 #
-my $defrawdisk	= "/dev/rad0";
+my $defrawdisk	= "/dev/ad0";
 my $rawbootdisk;
 my $etcdir	= "/etc";
 my $rcconflocal	= "$etcdir/rc.conf.local";
@@ -59,11 +59,12 @@ my $tbboot	= "tbbootconfig";
 #
 my %config = ( interface  => undef,
 	       hostname   => undef,
+	       domain     => undef,
 	       IP         => undef,
 	       netmask    => undef,
-	       domain     => undef,
 	       nameserver => undef,
 	       gateway    => undef,
+	       bootdisk   => undef,
 	     );
 
 # Must be root
@@ -84,29 +85,6 @@ if (@ARGV != 0) {
     usage();
 }
 
-print "\n";
-print "**************************************************************\n";
-print "*                                                            *\n";
-print "* Netbed installation CD.  This program will wipe your       *\n";
-print "* hard disk, and install a fresh Netbed image.               *\n";
-print "*                                                            *\n";
-print "* If this is not what you intended, please remove the CD and *\n";
-print "* reboot.                                                    *\n";
-print "*                                                            *\n";
-print "* Before you can install this CD, you must first go to       *\n";
-print "* www.emulab.net/cdromnewkey.php for a password.             *\n";
-print "*                                                            *\n";
-print "* Then, figure out what boot disk you want to use.           *\n";
-print "* Common disks are ad0 (1st IDE disk) and da0 (1st SCSI).    *\n";
-print "*                                                            *\n";
-print "**************************************************************\n";
-print "\n";
-
-#
-# Need a raw disk device.
-#
-$rawbootdisk = WhichRawDisk();
-
 BootFromCD();
 
 # Done!
@@ -115,18 +93,32 @@ exit(0);
 sub BootFromCD()
 {
     #
-    # On the CDROM, the order is to check for a hardwired config,
-    # and then a config stashed in the boot block. If neither is there,
-    # then prompt the user. Always give the user a chance to override the
-    # the current config. 
-    # 
-    if (CheckConfigFile() != 0 && CheckConfigBlock() != 0) {
+    # First check for a config file on the CD.
+    # If found, use that info.  bootdisk must be set.
+    #
+    if (CheckConfigFile() != 0 || !defined($config{'bootdisk'})) {
 	#
-	# Else no config found. Must wait until we get one.
-	# 
-	print "\nNo existing configuration was found!\n";
-	GetUserConfig();
+	# Give them multiple tries to find a disk with an existing
+	# configuration block.
+	#
+	while (1) {
+	    $rawbootdisk = WhichRawDisk();
+	    if (CheckConfigBlock() == 0) {
+		last;
+	    }
+	    print "No existing configuration was found on $rawbootdisk\n";
+	    if (Prompt("Try another disk for existing configuration?",
+		       "No", 10) =~ /no/i) {
+		#
+		# Don't want to try another disk,
+		# consider this a first time install.
+		#
+		GetNewConfig();
+		last;
+	    }
+	}
     }
+    $rawbootdisk = $config{'bootdisk'};
 
     #
     # Give the user a chance to override the normal operation, and specify
@@ -175,6 +167,56 @@ sub BootFromCD()
     return 0;
 }
 
+sub GetNewConfig()
+{
+    #
+    # First, an intimidating disclaimer
+    #
+    print "\n";
+    print "****************************************************************\n";
+    print "*                                                              *\n";
+    print "* Netbed installation CD (version 0.1).                        *\n";
+    print "*                                                              *\n";
+    print "* THIS PROGRAM WILL WIPE YOUR YOUR HARD DISK!                  *\n";
+    print "* It will then install a fresh Netbed image.                   *\n";
+    print "*                                                              *\n";
+    print "* If this is NOT what you intended, please type 'no' to the    *\n";
+    print "* prompt below and the machine will reboot (don't forget to    *\n";
+    print "* remove the CD).                                              *\n";
+    print "*                                                              *\n";
+    print "* Before you can install this CD, you must first go to         *\n";
+    print "* www.emulab.net/cdromnewkey.php for a password.               *\n";
+    print "*                                                              *\n";
+    print "* You must also know some basic characteristics of the machine *\n";
+    print "* you are installing on (disk device and network interface) as *\n";
+    print "* well as configuration of the local network (host and domain  *\n";
+    print "* name, IP address for machine, nameserver and gateway).       *\n";
+    print "*                                                              *\n";
+    print "****************************************************************\n";
+    print "\n";
+
+    if (Prompt("Continue with installation?", "No") =~ /no/i) {
+	exit(-277);
+    }
+
+    #
+    # All right, we gave them a chance.
+    # Here we should explain what the possible disk/network options are,
+    # preferably by going out and discovering what exists.
+    #
+
+    print "****************************************************************\n";
+    print "*                                                              *\n";
+    print "* The installation script attempts to intuit default values    *\n";
+    print "* for much of installation information.  In the process it may *\n";
+    print "* generate error messages from the kernel which may be safely  *\n";
+    print "* ignored.                                                     *\n";
+    print "*                                                              *\n";
+    print "****************************************************************\n";
+
+    GetUserConfig();
+}
+
 #
 # Prompt for the configuration from the user. Return -1 if something goes
 # wrong.
@@ -183,14 +225,18 @@ sub GetUserConfig()
 {
     print "Please enter the system configuration by hand\n";
     
+    $config{'bootdisk'}  = Prompt("System boot disk", $rawbootdisk);
     $config{'interface'} = Prompt("Network Interface", WhichInterface());
     $config{'hostname'}  = Prompt("Hostname (no domain)", $config{'hostname'});
     $config{'domain'}    = Prompt("Domain", $config{'domain'});
     $config{'IP'}        = Prompt("IP Address", $config{'IP'});
-    $config{'netmask'}   = Prompt("Netmask", $config{'netmask'});
-    $config{'nameserver'}= Prompt("Nameserver", $config{'nameserver'});
+    $config{'netmask'}   = Prompt("Netmask", WhichNetMask());
+    $config{'nameserver'}= Prompt("Nameserver IP", $config{'nameserver'});
     $config{'gateway'}   = Prompt("Gateway IP", $config{'gateway'});
 
+    # XXX
+    $rawbootdisk = $config{'bootdisk'};
+
     return 0;
 }
 
@@ -242,7 +288,12 @@ sub CheckConfigBlock()
     if ($?) {
 	return -1;
     }
-    return CheckConfigFile("/tmp/config.$$");
+    if (CheckConfigFile("/tmp/config.$$") == 0) {
+	# XXX bootdisk is not part of the on disk info
+	$config{'bootdisk'} = $rawbootdisk;
+	return 0;
+    }
+    return -1;
 }
 
 #
@@ -252,31 +303,57 @@ sub CheckConfigBlock()
 sub WhichInterface()
 {
     # XXX
-    if (defined($config{interface})) {
-	return $config{interface};
+    if (defined($config{'interface'})) {
+	return $config{'interface'};
     }
     my @allifaces = split(" ", `ifconfig -l`);
 		       
-    foreach my $guess ("fxp", "de", "tx", "vx", "wx", "em", "bge", "xl") {
-	foreach my $iface (@allifaces) {
-	    $iface =~ /([a-zA-z]*)(\d*)/;
-	    if ($1 eq $guess && $2 == 0) {
-		return $iface;
+    #
+    # Prefer the first interface found that is not "lo".
+    #
+    foreach my $iface (@allifaces) {
+	if ($iface =~ /([a-zA-z]+)(\d+)/) {
+	    if ($1 eq "lo") {
+		next;
+	    }
+
+	    # XXX check to make sure it has carrier
+	    if (`ifconfig $iface` =~ /.*no carrier/) {
+		next;
 	    }
+
+	    return $iface;
 	}
     }
+
     return "fxp0";
 }
 
+#
+# Which network mask. Make the standard class C guess and let the caller
+# spit that out in a prompt for verification.
+#
+sub WhichNetMask()
+{
+    # XXX
+    if (defined($config{'netmask'})) {
+	return $config{'netmask'};
+    }
+
+    return "255.255.255.0";
+}
+
 #
 # Which raw disk. Prompt if we cannot come up with a good guess.
+# Note: raw and block devices are one in the same now.
 #
 sub WhichRawDisk()
 {
     #
     # Search the drives until we find a valid header.
+    # Order is: IDE, SCSI, IDE RAID, SCSI RAID
     # 
-    foreach my $disk ("rad", "rda", "raacd") {
+    foreach my $disk ("ad", "da", "ar", "aacd") {
 	foreach my $drive (0) {
 	    my $guess = "/dev/${disk}${drive}";
 
@@ -286,7 +363,7 @@ sub WhichRawDisk()
 		# Allow for overiding the guess, with short timeout.
 		#
 		$rawbootdisk =
-		    Prompt("Which Raw Disk Device is the boot device?",
+		    Prompt("Which Disk Device is the boot device?",
 			   "$guess", 10);
 		goto gotone;
 	    }
@@ -297,7 +374,7 @@ sub WhichRawDisk()
     # Okay, no candidates. Lets find the first real disk. Use dd
     # to see if the drive is configured.
     #
-    foreach my $disk ("rad0", "rda0", "raacd0") {
+    foreach my $disk ("ad0", "da0", "ar0", "aacd0") {
 	my $guess = "/dev/${disk}";
 
 	system("dd if=$guess of=/dev/null bs=512 count=32 >/dev/null 2>&1");
@@ -306,7 +383,7 @@ sub WhichRawDisk()
 	    # Allow for overiding the guess, with short timeout.
 	    #
 	    $rawbootdisk =
-		Prompt("Which Raw Disk Device is the boot device?",
+		Prompt("Which Disk Device is the boot device?",
 		       "$guess", 10);
 	    goto gotone;
 	}
@@ -318,7 +395,7 @@ sub WhichRawDisk()
     # 
     while (!defined($rawbootdisk) || ! -e $rawbootdisk) {
 	$rawbootdisk = 
-	    Prompt("Which Raw Disk Device is the boot device?", $defrawdisk);
+	    Prompt("Which Disk Device is the boot device?", $defrawdisk);
     }
     return $rawbootdisk;
 }
@@ -381,7 +458,9 @@ sub WriteRCFiles()
     print CONFIG "ifconfig_$config{interface}=\"".
 	         "inet $config{IP} netmask $config{netmask}\"\n";
     print CONFIG "defaultrouter=\"$config{gateway}\"\n";
-    print CONFIG "rawbootdisk=\"$rawbootdisk\"\n";
+    print CONFIG "# Netbed info\n";
+    print CONFIG "netbed_disk=\"$rawbootdisk\"\n";
+    print CONFIG "netbed_IP=\"$config{IP}\"\n";
     print CONFIG "# EOF\n";
     close(CONFIG);
 
-- 
GitLab