xref: /freebsd/usr.sbin/bsdinstall/scripts/auto (revision f4b37ed0f8b307b1f3f0f630ca725d68f1dff30d)
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	esac
205	#
206	# Motherboard Models
207	#
208	case "$sys_mb_maker" in
209	"Intel Corporation")
210		case "$sys_mb_product" in
211		"DP965LT")
212			dialog_workaround "$msg_gpt_active_fix"
213			retval=$?
214			f_dprintf "gpt_active_fix_prompt=[%s]" "$retval"
215			if [ $retval -eq $DIALOG_OK ]; then
216				export ZFSBOOT_PARTITION_SCHEME="GPT + Active"
217				export WORKAROUND_GPTACTIVE=1
218			fi
219			;;
220		esac
221		;;
222	esac
223fi
224
225PMODES="\
226\"Auto (UFS)\" \"Guided Disk Setup\" \
227Manual \"Manual Disk Setup (experts)\" \
228Shell \"Open a shell and partition by hand\""
229
230CURARCH=$( uname -m )
231case $CURARCH in
232	amd64|i386)	# Booting ZFS Supported
233		PMODES="$PMODES \"Auto (ZFS)\" \"Guided Root-on-ZFS\""
234		;;
235	*)		# Booting ZFS Unspported
236		;;
237esac
238
239exec 3>&1
240PARTMODE=`echo $PMODES | xargs dialog --backtitle "FreeBSD Installer" \
241	--title "Partitioning" \
242	--menu "How would you like to partition your disk?" \
243	0 0 0 2>&1 1>&3` || exit 1
244exec 3>&-
245
246case "$PARTMODE" in
247"Auto (UFS)")	# Guided
248	bsdinstall autopart || error "Partitioning error"
249	bsdinstall mount || error "Failed to mount filesystem"
250	;;
251"Shell")	# Shell
252	clear
253	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'."
254	sh 2>&1
255	;;
256"Manual")	# Manual
257	if f_isset debugFile; then
258		# Give partedit the path to our logfile so it can append
259		BSDINSTALL_LOG="${debugFile#+}" bsdinstall partedit || error "Partitioning error"
260	else
261		bsdinstall partedit || error "Partitioning error"
262	fi
263	bsdinstall mount || error "Failed to mount filesystem"
264	;;
265"Auto (ZFS)")	# ZFS
266	bsdinstall zfsboot || error "ZFS setup failed"
267	bsdinstall mount || error "Failed to mount filesystem"
268	;;
269*)
270	error "Unknown partitioning mode"
271	;;
272esac
273
274if [ ! -z "$FETCH_DISTRIBUTIONS" ]; then
275	ALL_DISTRIBUTIONS="$DISTRIBUTIONS"
276
277	# Download to a directory in the new system as scratch space
278	BSDINSTALL_FETCHDEST="$BSDINSTALL_CHROOT/usr/freebsd-dist"
279	mkdir -p "$BSDINSTALL_FETCHDEST" || error "Could not create directory $BSDINSTALL_FETCHDEST"
280
281	export DISTRIBUTIONS="$FETCH_DISTRIBUTIONS"
282	# Try to use any existing distfiles
283	if [ -d $BSDINSTALL_DISTDIR ]; then
284		DISTDIR_IS_UNIONFS=1
285		mount_nullfs -o union "$BSDINSTALL_FETCHDEST" "$BSDINSTALL_DISTDIR"
286	else
287		export DISTRIBUTIONS="MANIFEST $ALL_DISTRIBUTIONS"
288		export BSDINSTALL_DISTDIR="$BSDINSTALL_FETCHDEST"
289	fi
290
291	export FTP_PASSIVE_MODE=YES
292	bsdinstall distfetch || error "Failed to fetch distribution"
293	export DISTRIBUTIONS="$ALL_DISTRIBUTIONS"
294fi
295
296bsdinstall checksum || error "Distribution checksum failed"
297bsdinstall distextract || error "Distribution extract failed"
298bsdinstall rootpass || error "Could not set root password"
299
300trap true SIGINT	# This section is optional
301if [ "$NETCONFIG_DONE" != yes ]; then
302	bsdinstall netconfig	# Don't check for errors -- the user may cancel
303fi
304bsdinstall time
305bsdinstall services
306
307dialog --backtitle "FreeBSD Installer" --title "Add User Accounts" --yesno \
308    "Would you like to add users to the installed system now?" 0 0 && \
309    bsdinstall adduser
310
311finalconfig() {
312	exec 3>&1
313	REVISIT=$(dialog --backtitle "FreeBSD Installer" \
314	    --title "Final Configuration" --no-cancel --menu \
315	    "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 \
316		"Exit" "Apply configuration and exit installer" \
317		"Add User" "Add a user to the system" \
318		"Root Password" "Change root password" \
319		"Hostname" "Set system hostname" \
320		"Network" "Networking configuration" \
321		"Services" "Set daemons to run on startup" \
322		"Time Zone" "Set system timezone" \
323		"Handbook" "Install FreeBSD Handbook (requires network)" 2>&1 1>&3)
324	exec 3>&-
325
326	case "$REVISIT" in
327	"Add User")
328		bsdinstall adduser
329		finalconfig
330		;;
331	"Root Password")
332		bsdinstall rootpass
333		finalconfig
334		;;
335	"Hostname")
336		bsdinstall hostname
337		finalconfig
338		;;
339	"Network")
340		bsdinstall netconfig
341		finalconfig
342		;;
343	"Services")
344		bsdinstall services
345		finalconfig
346		;;
347	"Time Zone")
348		bsdinstall time
349		finalconfig
350		;;
351	"Handbook")
352		bsdinstall docsinstall
353		finalconfig
354		;;
355	esac
356}
357
358# Allow user to change his mind
359finalconfig
360
361trap error SIGINT	# SIGINT is bad again
362bsdinstall config  || error "Failed to save config"
363
364if [ ! -z "$BSDINSTALL_FETCHDEST" ]; then
365	[ "$BSDINSTALL_FETCHDEST" != "$BSDINSTALL_DISTDIR" ] && \
366	    umount "$BSDINSTALL_DISTDIR"
367	rm -rf "$BSDINSTALL_FETCHDEST"
368fi
369
370dialog --backtitle "FreeBSD Installer" --title "Manual Configuration" \
371    --default-button no --yesno \
372   "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
373if [ $? -eq 0 ]; then
374	clear
375	mount -t devfs devfs "$BSDINSTALL_CHROOT/dev"
376	echo This shell is operating in a chroot in the new system. \
377	    When finished making configuration changes, type \"exit\".
378	chroot "$BSDINSTALL_CHROOT" /bin/sh 2>&1
379fi
380
381bsdinstall entropy
382bsdinstall umount
383
384f_dprintf "Installation Completed at %s" "$( date )"
385
386################################################################################
387# END
388################################################################################
389