xref: /netbsd/distrib/miniroot/install.sh (revision 3123085e)
1#!/bin/sh
2#	$NetBSD: install.sh,v 1.22 2000/04/11 08:26:34 pk Exp $
3#
4# Copyright (c) 1996 The NetBSD Foundation, Inc.
5# All rights reserved.
6#
7# This code is derived from software contributed to The NetBSD Foundation
8# by Jason R. Thorpe.
9#
10# Redistribution and use in source and binary forms, with or without
11# modification, are permitted provided that the following conditions
12# are met:
13# 1. Redistributions of source code must retain the above copyright
14#    notice, this list of conditions and the following disclaimer.
15# 2. Redistributions in binary form must reproduce the above copyright
16#    notice, this list of conditions and the following disclaimer in the
17#    documentation and/or other materials provided with the distribution.
18# 3. All advertising materials mentioning features or use of this software
19#    must display the following acknowledgement:
20#        This product includes software developed by the NetBSD
21#        Foundation, Inc. and its contributors.
22# 4. Neither the name of The NetBSD Foundation nor the names of its
23#    contributors may be used to endorse or promote products derived
24#    from this software without specific prior written permission.
25#
26# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36# POSSIBILITY OF SUCH DAMAGE.
37#
38
39#	NetBSD installation script.
40#	In a perfect world, this would be a nice C program, with a reasonable
41#	user interface.
42
43FILESYSTEMS="/tmp/filesystems"		# used thoughout
44FQDN=""					# domain name
45
46trap "umount /tmp > /dev/null 2>&1" 0
47
48MODE="install"
49
50# include machine-dependent functions
51# The following functions must be provided:
52#	md_copy_kernel()	- copy a kernel to the installed disk
53#	md_get_diskdevs()	- return available disk devices
54#	md_get_cddevs()		- return available CD-ROM devices
55#	md_get_ifdevs()		- return available network interfaces
56#	md_get_partition_range() - return range of valid partition letters
57#	md_installboot()	- install boot-blocks on disk
58#	md_labeldisk()		- put label on a disk
59#	md_prep_disklabel()	- label the root disk
60#	md_welcome_banner()	- display friendly message
61#	md_not_going_to_install() - display friendly message
62#	md_congrats()		- display friendly message
63#	md_native_fstype()	- native filesystem type for disk installs
64#	md_native_fsopts()	- native filesystem options for disk installs
65#	md_makerootwritable()	- make root writable (at least /tmp)
66
67# we need to make sure .'s below work if this directory is not in $PATH
68# dirname may not be available but expr is
69Mydir=`expr $0 : '^\(.*\)/[^/]*$'`
70Mydir=`cd ${Mydir:-.}; pwd`
71
72# this is the most likely place to find the binary sets
73# so save them having to type it in
74Default_sets_dir=$Mydir/../../binary/sets
75
76# include machine dependent subroutines
77. $Mydir/install.md
78
79# include common subroutines
80. $Mydir/install.sub
81
82# which sets?
83THESETS="$ALLSETS $MDSETS"
84
85# Good {morning,afternoon,evening,night}.
86md_welcome_banner
87echo -n "Proceed with installation? [n] "
88getresp "n"
89case "$resp" in
90	y*|Y*)
91		echo	"Cool!  Let's get to it..."
92		;;
93	*)
94		md_not_going_to_install
95		exit
96		;;
97esac
98
99# XXX Work around vnode aliasing bug (thanks for the tip, Chris...)
100ls -l /dev > /dev/null 2>&1
101
102# Deal with terminal issues
103md_set_term
104
105# Get timezone info
106get_timezone
107
108# Make sure we can write files (at least in /tmp)
109# This might make an MFS mount on /tmp, or it may
110# just re-mount the root with read-write enabled.
111md_makerootwritable
112
113# Install the shadowed disktab file; lets us write to it for temporary
114# purposes without mounting the miniroot read-write.
115cp /etc/disktab.shadow /tmp/disktab.shadow
116
117while [ "X${ROOTDISK}" = "X" ]; do
118	getrootdisk
119done
120
121# Deal with disklabels, including editing the root disklabel
122# and labeling additional disks.  This is machine-dependent since
123# some platforms may not be able to provide this functionality.
124md_prep_disklabel ${ROOTDISK}
125
126# Assume partition 'a' of $ROOTDISK is for the root filesystem.  Loop and
127# get the rest.
128# XXX ASSUMES THAT THE USER DOESN'T PROVIDE BOGUS INPUT.
129cat << \__get_filesystems_1
130
131You will now have the opportunity to enter filesystem information.
132You will be prompted for device name and mount point (full path,
133including the prepending '/' character).
134
135Note that these do not have to be in any particular order.  You will
136be given the opportunity to edit the resulting 'fstab' file before
137any of the filesystems are mounted.  At that time you will be able
138to resolve any filesystem order dependencies.
139
140__get_filesystems_1
141
142echo	"The following will be used for the root filesystem:"
143echo	"	${ROOTDISK}a	/"
144
145echo	"${ROOTDISK}a	/" > ${FILESYSTEMS}
146
147resp="X"	# force at least one iteration
148while [ "X$resp" != X"done" ]; do
149	echo	""
150	echo -n	"Device name? [RETURN if you already entered all devices] "
151	getresp "done"
152	case "$resp" in
153	done)
154		;;
155
156	*)
157		_device_name=`basename $resp`
158
159		# force at least one iteration
160		_first_char="X"
161		while [ "X${_first_char}" != X"/" ]; do
162			echo -n "Mount point? "
163			getresp ""
164			_mount_point=$resp
165			if [ "X${_mount_point}" = X"/" ]; then
166				# Invalid response; no multiple roots
167				_first_char="X"
168			else
169				_first_char=`firstchar ${_mount_point}`
170			fi
171		done
172		echo "${_device_name}	${_mount_point}" >> ${FILESYSTEMS}
173		resp="X"	# force loop to repeat
174		;;
175	esac
176done
177
178# configure swap
179resp=""		# force at least one iteration
180while [ "X${resp}" = X"" ]; do
181	echo -n	"Ok to configure ${ROOTDISK}b as a swap device? [] "
182	getresp ""
183	case "$resp" in
184	y*|Y*)
185		echo "${ROOTDISK}b	swap" >> ${FILESYSTEMS}
186		;;
187	n*|N*)
188		;;
189	*)	;;
190	esac
191done
192
193
194echo	""
195echo	"You have configured the following devices and mount points:"
196echo	""
197cat ${FILESYSTEMS}
198echo	""
199echo	"Filesystems will now be created on these devices.  If you made any"
200echo -n	"mistakes, you may edit this now.  Edit? [n] "
201getresp "n"
202case "$resp" in
203	y*|Y*)
204		${EDITOR} ${FILESYSTEMS}
205		;;
206	*)
207		;;
208esac
209
210# Loop though the file, place filesystems on each device.
211echo	"Creating filesystems..."
212(
213	while read _device_name _mp; do
214		if [ "$_mp" != "swap" ]; then
215			newfs /dev/r${_device_name}
216			echo ""
217		fi
218	done
219) < ${FILESYSTEMS}
220
221# Get network configuration information, and store it for placement in the
222# root filesystem later.
223cat << \__network_config_1
224You will now be given the opportunity to configure the network.  This will
225be useful if you need to transfer the installation sets via FTP or NFS.
226Even if you choose not to transfer installation sets that way, this
227information will be preserved and copied into the new root filesystem.
228
229Note, enter all symbolic host names WITHOUT the domain name appended.
230I.e. use 'hostname' NOT 'hostname.domain.name'.
231
232__network_config_1
233echo -n	"Configure the network? [y] "
234getresp "y"
235case "$resp" in
236	y*|Y*)
237		resp=""		# force at least one iteration
238		if [ -f /etc/myname ]; then
239			resp=`cat /etc/myname`
240		fi
241		echo -n "Enter system hostname: [$resp] "
242		while [ "X${resp}" = X"" ]; do
243			getresp "$resp"
244		done
245		hostname $resp
246		echo $resp > /tmp/myname
247
248		echo -n "Enter DNS domain name: "
249		getresp "none"
250		if [ "X${resp}" != X"none" ]; then
251			FQDN=$resp
252		fi
253
254		configurenetwork
255
256		echo -n "Enter IP address of default route: [none] "
257		getresp "none"
258		if [ "X${resp}" != X"none" ]; then
259			route delete default > /dev/null 2>&1
260			if route add default $resp > /dev/null ; then
261				echo $resp > /tmp/mygate
262			fi
263		fi
264
265		resp="none"
266		if [ X${FQDN} != X ]; then
267			echo -n	"Enter IP address of primary nameserver: [none] "
268			getresp "none"
269		fi
270		if [ "X${resp}" != X"none" ]; then
271			echo "domain $FQDN" > /tmp/resolv.conf
272			echo "nameserver $resp" >> /tmp/resolv.conf
273			echo "search $FQDN" >> /tmp/resolv.conf
274
275			echo -n "Would you like to use the nameserver now? [y] "
276			getresp "y"
277			case "$resp" in
278				y*|Y*)
279					cp /tmp/resolv.conf \
280					    /tmp/resolv.conf.shadow
281					;;
282
283				*)
284					;;
285			esac
286		fi
287
288		echo ""
289		echo "The host table is as follows:"
290		echo ""
291		cat /tmp/hosts
292		echo ""
293		echo "You may want to edit the host table in the event that"
294		echo "you need to mount an NFS server."
295		echo -n "Would you like to edit the host table? [n] "
296		getresp "n"
297		case "$resp" in
298			y*|Y*)
299				${EDITOR} /tmp/hosts
300				;;
301
302			*)
303				;;
304		esac
305
306		cat << \__network_config_2
307
308You will now be given the opportunity to escape to the command shell to
309do any additional network configuration you may need.  This may include
310adding additional routes, if needed.  In addition, you might take this
311opportunity to redo the default route in the event that it failed above.
312If you do change the default route, and wish for that change to carry over
313to the installed system, execute the following command at the shell
314prompt:
315
316	echo <ip_address_of_gateway> > /tmp/mygate
317
318where <ip_address_of_gateway> is the IP address of the default router.
319
320__network_config_2
321		echo -n "Escape to shell? [n] "
322		getresp "n"
323		case "$resp" in
324			y*|Y*)
325				echo "Type 'exit' to return to install."
326				sh
327				;;
328
329			*)
330				;;
331		esac
332		;;
333	*)
334		;;
335esac
336
337# Now that the network has been configured, it is safe to configure the
338# fstab.
339(
340	while read _dev _mp; do
341		if [ "$_mp" = "/" ]; then
342			echo /dev/$_dev $_mp ffs rw 1 1
343		elif [ "$_mp" = "swap" ]; then
344			echo /dev/$_dev none swap sw 0 0
345		else
346			echo /dev/$_dev $_mp ffs rw 1 2
347		fi
348	done
349) < ${FILESYSTEMS} > /tmp/fstab
350
351echo	"The fstab is configured as follows:"
352echo	""
353cat /tmp/fstab
354cat << \__fstab_config_1
355
356You may wish to edit the fstab.  For example, you may need to resolve
357dependencies in the order which the filesystems are mounted.  You may
358also wish to take this opportunity to place NFS mounts in the fstab.
359This would be especially useful if you plan to keep '/usr' on an NFS
360server.
361
362__fstab_config_1
363echo -n	"Edit the fstab? [n] "
364getresp "n"
365case "$resp" in
366	y*|Y*)
367		${EDITOR} /tmp/fstab
368		;;
369
370	*)
371		;;
372esac
373
374echo ""
375munge_fstab /tmp/fstab /tmp/fstab.shadow
376mount_fs /tmp/fstab.shadow
377
378mount | while read line; do
379	set -- $line
380	if [ "$2" = "/" -a "$3" = "nfs" ]; then
381		echo "You appear to be running diskless."
382		echo -n	"Are the install sets on one of your currently mounted filesystems? [n] "
383		getresp "n"
384		case "$resp" in
385			y*|Y*)
386				get_localdir
387				;;
388			*)
389				;;
390		esac
391	fi
392done
393
394install_sets
395
396# Copy in configuration information and make devices in target root.
397(
398	cd /tmp
399	for file in fstab ifconfig.* hosts myname mygate resolv.conf; do
400		if [ -f $file ]; then
401			echo -n "Copying $file..."
402			cp $file /mnt/etc/$file
403			echo "done."
404		fi
405	done
406
407	# Enable rc.conf
408	if [ -e /mnt/etc/rc.conf ]; then
409		cp /mnt/etc/rc.conf /tmp
410		sed 's/^rc_configured=NO/rc_configured=YES/' /tmp/rc.conf \
411			> /mnt/etc/rc.conf
412	fi
413
414	# If no zoneinfo on the installfs, give them a second chance
415	if [ ! -e /usr/share/zoneinfo ]; then
416		get_timezone
417	fi
418	if [ ! -e /mnt/usr/share/zoneinfo ]; then
419		echo "Cannot install timezone link..."
420	else
421		echo -n "Installing timezone link..."
422		rm -f /mnt/etc/localtime
423		ln -s /usr/share/zoneinfo/$TZ /mnt/etc/localtime
424		echo "done."
425	fi
426	if [ ! -x /mnt/dev/MAKEDEV ]; then
427		echo "No /dev/MAKEDEV installed, something is wrong here..."
428	else
429		echo -n "Making devices..."
430		pid=`twiddle`
431		cd /mnt/dev
432		sh MAKEDEV all
433		kill $pid
434		echo "done."
435	fi
436	md_copy_kernel
437
438	md_installboot ${ROOTDISK}
439)
440
441unmount_fs /tmp/fstab.shadow
442
443# Pat on the back.
444md_congrats
445
446# ALL DONE!
447exit 0
448