xref: /freebsd/usr.sbin/bsdinstall/scripts/auto (revision 39ee7a7a6bdd1557b1c3532abf60d139798ac88b)
1#!/bin/sh
2#-
3# Copyright (c) 2011 Nathan Whitehorn
4# Copyright (c) 2013 Devin Teske
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26# SUCH DAMAGE.
27#
28# $FreeBSD$
29#
30############################################################ INCLUDES
31
32BSDCFG_SHARE="/usr/share/bsdconfig"
33. $BSDCFG_SHARE/common.subr || exit 1
34f_include $BSDCFG_SHARE/dialog.subr
35
36############################################################ FUNCTIONS
37
38error() {
39	local msg
40	if [ -n "$1" ]; then
41		msg="$1\n\n"
42	fi
43	test -n "$DISTDIR_IS_UNIONFS" && umount -f $BSDINSTALL_DISTDIR
44	test -f $PATH_FSTAB && bsdinstall umount
45	dialog --backtitle "FreeBSD Installer" --title "Abort" \
46	    --no-label "Exit" --yes-label "Restart" --yesno \
47	    "${msg}An installation step has been aborted. Would you like to restart the installation or exit the installer?" 0 0
48	if [ $? -ne 0 ]; then
49		exit 1
50	else
51		exec $0
52	fi
53}
54
55hline_arrows_tab_enter="Press arrows, TAB or ENTER"
56msg_gpt_active_fix="Your hardware is known to have issues booting in CSM/Legacy/BIOS mode from GPT partitions that are not set active. Would you like the installer to apply this workaround for you?"
57msg_lenovo_fix="Your model of Lenovo is known to have a BIOS bug that prevents it booting from GPT partitions without UEFI. Would you like the installer to apply a workaround for you?"
58msg_no="NO"
59msg_yes="YES"
60
61# dialog_workaround
62#
63# Ask the user if they wish to apply a workaround
64#
65dialog_workaround()
66{
67	local passed_msg="$1"
68	local title="$DIALOG_TITLE"
69	local btitle="$DIALOG_BACKTITLE"
70	local prompt # Calculated below
71	local hline="$hline_arrows_tab_enter"
72
73	local height=8 width=50 prefix="   "
74	local plen=${#prefix} list= line=
75	local max_width=$(( $width - 3 - $plen ))
76
77	local yes no defaultno extra_args format
78	if [ "$USE_XDIALOG" ]; then
79		yes=ok no=cancel defaultno=default-no
80		extra_args="--wrap --left"
81		format="$passed_msg"
82	else
83		yes=yes no=no defaultno=defaultno
84		extra_args="--cr-wrap"
85		format="$passed_msg"
86	fi
87
88	# Add height for Xdialog(1)
89	[ "$USE_XDIALOG" ] && height=$(( $height + $height / 5 + 3 ))
90
91	prompt=$( printf "$format" )
92	f_dprintf "%s: Workaround prompt" "$0"
93	$DIALOG \
94		--title "$title"        \
95		--backtitle "$btitle"   \
96		--hline "$hline"        \
97		--$yes-label "$msg_yes" \
98		--$no-label "$msg_no"   \
99		$extra_args             \
100		--yesno "$prompt" $height $width
101}
102
103############################################################ MAIN
104
105f_dprintf "Began Installation at %s" "$( date )"
106
107rm -rf $BSDINSTALL_TMPETC
108mkdir $BSDINSTALL_TMPETC
109
110trap true SIGINT	# This section is optional
111bsdinstall keymap
112
113trap error SIGINT	# Catch cntrl-C here
114bsdinstall hostname || error "Set hostname failed"
115
116export DISTRIBUTIONS="base.txz kernel.txz"
117if [ -f $BSDINSTALL_DISTDIR/MANIFEST ]; then
118	DISTMENU=`awk -F'\t' '!/^(kernel|base)/{print $4,$5,$6}' $BSDINSTALL_DISTDIR/MANIFEST`
119
120	exec 3>&1
121	EXTRA_DISTS=$( eval dialog \
122	    --backtitle \"FreeBSD Installer\" \
123	    --title \"Distribution Select\" --nocancel --separate-output \
124	    --checklist \"Choose optional system components to install:\" \
125	    0 0 0 $DISTMENU \
126	2>&1 1>&3 )
127	for dist in $EXTRA_DISTS; do
128		export DISTRIBUTIONS="$DISTRIBUTIONS $dist.txz"
129	done
130fi
131
132FETCH_DISTRIBUTIONS=""
133for dist in $DISTRIBUTIONS; do
134	if [ ! -f $BSDINSTALL_DISTDIR/$dist ]; then
135		FETCH_DISTRIBUTIONS="$FETCH_DISTRIBUTIONS $dist"
136	fi
137done
138FETCH_DISTRIBUTIONS=`echo $FETCH_DISTRIBUTIONS`	# Trim white space
139
140if [ -n "$FETCH_DISTRIBUTIONS" -a -n "$BSDINSTALL_CONFIGCURRENT" ]; then
141	dialog --backtitle "FreeBSD Installer" --title "Network Installation" --msgbox "No installation files were found on the boot volume. The next few screens will allow you to configure networking so that they can be downloaded from the Internet." 0 0
142	bsdinstall netconfig || error
143	NETCONFIG_DONE=yes
144fi
145
146if [ -n "$FETCH_DISTRIBUTIONS" ]; then
147	exec 3>&1
148	BSDINSTALL_DISTSITE=$(`dirname $0`/mirrorselect 2>&1 1>&3)
149	MIRROR_BUTTON=$?
150	exec 3>&-
151	test $MIRROR_BUTTON -eq 0 || error "No mirror selected"
152	export BSDINSTALL_DISTSITE
153fi
154
155rm -f $PATH_FSTAB
156touch $PATH_FSTAB
157
158#
159# Try to detect known broken platforms and apply their workarounds
160#
161
162if f_interactive; then
163	sys_maker=$( kenv -q smbios.system.maker )
164	f_dprintf "smbios.system.maker=[%s]" "$sys_maker"
165	sys_model=$( kenv -q smbios.system.product )
166	f_dprintf "smbios.system.product=[%s]" "$sys_model"
167	sys_version=$( kenv -q smbios.system.version )
168	f_dprintf "smbios.system.version=[%s]" "$sys_version"
169	sys_mb_maker=$( kenv -q smbios.planar.maker )
170	f_dprintf "smbios.planar.maker=[%s]" "$sys_mb_maker"
171	sys_mb_product=$( kenv -q smbios.planar.product )
172	f_dprintf "smbios.planar.product=[%s]" "$sys_mb_product"
173
174	#
175	# Laptop Models
176	#
177	case "$sys_maker" in
178	"LENOVO")
179		case "$sys_version" in
180		"ThinkPad X220"|"ThinkPad T420"|"ThinkPad T520")
181			dialog_workaround "$msg_lenovo_fix"
182			retval=$?
183			f_dprintf "lenovofix_prompt=[%s]" "$retval"
184			if [ $retval -eq $DIALOG_OK ]; then
185				export ZFSBOOT_PARTITION_SCHEME="GPT + Lenovo Fix"
186				export WORKAROUND_LENOVO=1
187			fi
188			;;
189		esac
190		;;
191	"Dell Inc.")
192		case "$sys_model" in
193		"Latitude E7440"|"Latitude E7240")
194			dialog_workaround "$msg_gpt_active_fix"
195			retval=$?
196			f_dprintf "gpt_active_fix_prompt=[%s]" "$retval"
197			if [ $retval -eq $DIALOG_OK ]; then
198				export ZFSBOOT_PARTITION_SCHEME="GPT + Active"
199				export WORKAROUND_GPTACTIVE=1
200			fi
201			;;
202		esac
203		;;
204	"Hewlett-Packard")
205		case "$sys_model" in
206		"HP ProBook 4330s")
207			dialog_workaround "$msg_gpt_active_fix"
208			retval=$?
209			f_dprintf "gpt_active_fix_prompt=[%s]" "$retval"
210			if [ $retval -eq $DIALOG_OK ]; then
211				export ZFSBOOT_PARTITION_SCHEME="GPT + Active"
212				export WORKAROUND_GPTACTIVE=1
213			fi
214			;;
215		esac
216		;;
217	esac
218	#
219	# Motherboard Models
220	#
221	case "$sys_mb_maker" in
222	"Intel Corporation")
223		case "$sys_mb_product" in
224		"DP965LT"|"D510MO")
225			dialog_workaround "$msg_gpt_active_fix"
226			retval=$?
227			f_dprintf "gpt_active_fix_prompt=[%s]" "$retval"
228			if [ $retval -eq $DIALOG_OK ]; then
229				export ZFSBOOT_PARTITION_SCHEME="GPT + Active"
230				export WORKAROUND_GPTACTIVE=1
231			fi
232			;;
233		esac
234		;;
235	"Acer")
236		case "$sys_mb_product" in
237		"Veriton M6630G")
238			dialog_workaround "$msg_gpt_active_fix"
239			retval=$?
240			f_dprintf "gpt_active_fix_prompt=[%s]" "$retval"
241			if [ $retval -eq $DIALOG_OK ]; then
242				export ZFSBOOT_PARTITION_SCHEME="GPT + Active"
243				export WORKAROUND_GPTACTIVE=1
244			fi
245			;;
246		esac
247		;;
248	esac
249fi
250
251PMODES="\
252\"Auto (UFS)\" \"Guided Disk Setup\" \
253Manual \"Manual Disk Setup (experts)\" \
254Shell \"Open a shell and partition by hand\""
255
256CURARCH=$( uname -m )
257case $CURARCH in
258	amd64|i386)	# Booting ZFS Supported
259		PMODES="$PMODES \"Auto (ZFS)\" \"Guided Root-on-ZFS\""
260		;;
261	*)		# Booting ZFS Unspported
262		;;
263esac
264
265exec 3>&1
266PARTMODE=`echo $PMODES | xargs dialog --backtitle "FreeBSD Installer" \
267	--title "Partitioning" \
268	--menu "How would you like to partition your disk?" \
269	0 0 0 2>&1 1>&3` || exit 1
270exec 3>&-
271
272case "$PARTMODE" in
273"Auto (UFS)")	# Guided
274	bsdinstall autopart || error "Partitioning error"
275	bsdinstall mount || error "Failed to mount filesystem"
276	;;
277"Shell")	# Shell
278	clear
279	echo "Use this shell to set up partitions for the new system. When finished, mount the system at $BSDINSTALL_CHROOT and place an fstab file for the new system at $PATH_FSTAB. Then type 'exit'. You can also enter the partition editor at any time by entering 'bsdinstall partedit'."
280	sh 2>&1
281	;;
282"Manual")	# Manual
283	if f_isset debugFile; then
284		# Give partedit the path to our logfile so it can append
285		BSDINSTALL_LOG="${debugFile#+}" bsdinstall partedit || error "Partitioning error"
286	else
287		bsdinstall partedit || error "Partitioning error"
288	fi
289	bsdinstall mount || error "Failed to mount filesystem"
290	;;
291"Auto (ZFS)")	# ZFS
292	bsdinstall zfsboot || error "ZFS setup failed"
293	bsdinstall mount || error "Failed to mount filesystem"
294	;;
295*)
296	error "Unknown partitioning mode"
297	;;
298esac
299
300if [ ! -z "$FETCH_DISTRIBUTIONS" ]; then
301	ALL_DISTRIBUTIONS="$DISTRIBUTIONS"
302
303	# Download to a directory in the new system as scratch space
304	BSDINSTALL_FETCHDEST="$BSDINSTALL_CHROOT/usr/freebsd-dist"
305	mkdir -p "$BSDINSTALL_FETCHDEST" || error "Could not create directory $BSDINSTALL_FETCHDEST"
306
307	export DISTRIBUTIONS="$FETCH_DISTRIBUTIONS"
308	# Try to use any existing distfiles
309	if [ -d $BSDINSTALL_DISTDIR ]; then
310		DISTDIR_IS_UNIONFS=1
311		mount_nullfs -o union "$BSDINSTALL_FETCHDEST" "$BSDINSTALL_DISTDIR"
312	else
313		export DISTRIBUTIONS="$ALL_DISTRIBUTIONS"
314		export BSDINSTALL_DISTDIR="$BSDINSTALL_FETCHDEST"
315	fi
316
317	export FTP_PASSIVE_MODE=YES
318	bsdinstall distfetch || error "Failed to fetch distribution"
319	export DISTRIBUTIONS="$ALL_DISTRIBUTIONS"
320fi
321
322bsdinstall checksum || error "Distribution checksum failed"
323bsdinstall distextract || error "Distribution extract failed"
324bsdinstall rootpass || error "Could not set root password"
325
326trap true SIGINT	# This section is optional
327if [ "$NETCONFIG_DONE" != yes ]; then
328	bsdinstall netconfig	# Don't check for errors -- the user may cancel
329fi
330bsdinstall time
331bsdinstall services
332
333dialog --backtitle "FreeBSD Installer" --title "Add User Accounts" --yesno \
334    "Would you like to add users to the installed system now?" 0 0 && \
335    bsdinstall adduser
336
337finalconfig() {
338	exec 3>&1
339	REVISIT=$(dialog --backtitle "FreeBSD Installer" \
340	    --title "Final Configuration" --no-cancel --menu \
341	    "Setup of your FreeBSD system is nearly complete. You can now modify your configuration choices. After this screen, you will have an opportunity to make more complex changes using a shell." 0 0 0 \
342		"Exit" "Apply configuration and exit installer" \
343		"Add User" "Add a user to the system" \
344		"Root Password" "Change root password" \
345		"Hostname" "Set system hostname" \
346		"Network" "Networking configuration" \
347		"Services" "Set daemons to run on startup" \
348		"Time Zone" "Set system timezone" \
349		"Handbook" "Install FreeBSD Handbook (requires network)" 2>&1 1>&3)
350	exec 3>&-
351
352	case "$REVISIT" in
353	"Add User")
354		bsdinstall adduser
355		finalconfig
356		;;
357	"Root Password")
358		bsdinstall rootpass
359		finalconfig
360		;;
361	"Hostname")
362		bsdinstall hostname
363		finalconfig
364		;;
365	"Network")
366		bsdinstall netconfig
367		finalconfig
368		;;
369	"Services")
370		bsdinstall services
371		finalconfig
372		;;
373	"Time Zone")
374		bsdinstall time
375		finalconfig
376		;;
377	"Handbook")
378		bsdinstall docsinstall
379		finalconfig
380		;;
381	esac
382}
383
384# Allow user to change his mind
385finalconfig
386
387trap error SIGINT	# SIGINT is bad again
388bsdinstall config  || error "Failed to save config"
389
390if [ ! -z "$BSDINSTALL_FETCHDEST" ]; then
391	[ "$BSDINSTALL_FETCHDEST" != "$BSDINSTALL_DISTDIR" ] && \
392	    umount "$BSDINSTALL_DISTDIR"
393	rm -rf "$BSDINSTALL_FETCHDEST"
394fi
395
396dialog --backtitle "FreeBSD Installer" --title "Manual Configuration" \
397    --default-button no --yesno \
398   "The installation is now finished. Before exiting the installer, would you like to open a shell in the new system to make any final manual modifications?" 0 0
399if [ $? -eq 0 ]; then
400	clear
401	mount -t devfs devfs "$BSDINSTALL_CHROOT/dev"
402	echo This shell is operating in a chroot in the new system. \
403	    When finished making configuration changes, type \"exit\".
404	chroot "$BSDINSTALL_CHROOT" /bin/sh 2>&1
405fi
406
407bsdinstall entropy
408bsdinstall umount
409
410f_dprintf "Installation Completed at %s" "$( date )"
411
412################################################################################
413# END
414################################################################################
415