3 # Copyright (c) 2011 Nathan Whitehorn
4 # Copyright (c) 2013-2018 Devin Teske
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
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.
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
30 ############################################################ INCLUDES
32 BSDCFG_SHARE="/usr/share/bsdconfig"
33 . $BSDCFG_SHARE/common.subr || exit 1
34 f_include $BSDCFG_SHARE/dialog.subr
36 ############################################################ GLOBALS
39 # Strings that should be moved to an i18n file and loaded with f_include_lang()
41 hline_arrows_tab_enter="Press arrows, TAB or ENTER"
42 hline_arrows_tab_space_enter="Press arrows, TAB, SPACE or ENTER"
45 msg_freebsd_installer="FreeBSD Installer"
46 msg_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?"
47 msg_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?"
48 msg_an_installation_step_has_been_aborted="An installation step has been aborted. Would you like\nto restart the installation or exit the installer?"
53 ############################################################ FUNCTIONS
57 # Display generic error message when a script fails. An optional message
58 # argument can preceed the generic message. User is given the choice of
59 # restarting the installer or exiting.
63 local title="$msg_abort"
64 local btitle="$msg_freebsd_installer"
65 local prompt="${1:+$1\n\n}$msg_an_installation_step_has_been_aborted"
66 local hline="$hline_arrows_tab_space_enter"
68 [ "$DISTDIR_IS_UNIONFS" ] && umount -f "$BSDINSTALL_DISTDIR"
69 [ -f "$PATH_FSTAB" ] && bsdinstall umount
72 f_dialog_buttonbox_size height width \
73 "$title" "$btitle" "$prompt" "$hline"
77 --backtitle "$btitle" \
79 --no-label "$msg_exit" \
80 --yes-label "$msg_restart" \
81 --yesno "$prompt" $height $width
91 # Ask the user if they wish to apply a workaround
96 local title="$DIALOG_TITLE"
97 local btitle="$DIALOG_BACKTITLE"
98 local prompt # Calculated below
99 local hline="$hline_arrows_tab_enter"
101 local height=8 width=50 prefix=" "
102 local plen=${#prefix} list= line=
103 local max_width=$(( $width - 3 - $plen ))
105 local yes no defaultno extra_args format
106 if [ "$USE_XDIALOG" ]; then
107 yes=ok no=cancel defaultno=default-no
108 extra_args="--wrap --left"
111 yes=yes no=no defaultno=defaultno
112 extra_args="--cr-wrap"
116 # Add height for Xdialog(1)
117 [ "$USE_XDIALOG" ] && height=$(( $height + $height / 5 + 3 ))
119 prompt=$( printf "$format" )
120 f_dprintf "%s: Workaround prompt" "$0"
123 --backtitle "$btitle" \
125 --$yes-label "$msg_yes" \
126 --$no-label "$msg_no" \
128 --yesno "$prompt" $height $width
131 ############################################################ MAIN
133 f_dprintf "Began Installation at %s" "$( date )"
135 rm -rf $BSDINSTALL_TMPETC
136 mkdir $BSDINSTALL_TMPETC
138 trap true SIGINT # This section is optional
141 trap error SIGINT # Catch cntrl-C here
142 bsdinstall hostname || error "Set hostname failed"
144 export DISTRIBUTIONS="base.txz kernel.txz"
145 if [ -f $BSDINSTALL_DISTDIR/MANIFEST ]; then
146 DISTMENU=`awk -F'\t' '!/^(kernel\.txz|base\.txz)/{print $1,$5,$6}' $BSDINSTALL_DISTDIR/MANIFEST`
147 DISTMENU="$(echo ${DISTMENU} | sed -E 's/\.txz//g')"
150 EXTRA_DISTS=$( eval dialog \
151 --backtitle \"FreeBSD Installer\" \
152 --title \"Distribution Select\" --nocancel --separate-output \
153 --checklist \"Choose optional system components to install:\" \
156 for dist in $EXTRA_DISTS; do
157 export DISTRIBUTIONS="$DISTRIBUTIONS $dist.txz"
161 LOCAL_DISTRIBUTIONS="MANIFEST"
162 FETCH_DISTRIBUTIONS=""
163 for dist in $DISTRIBUTIONS; do
164 if [ ! -f $BSDINSTALL_DISTDIR/$dist ]; then
165 FETCH_DISTRIBUTIONS="$FETCH_DISTRIBUTIONS $dist"
167 LOCAL_DISTRIBUTIONS="$LOCAL_DISTRIBUTIONS $dist"
170 LOCAL_DISTRIBUTIONS=`echo $LOCAL_DISTRIBUTIONS` # Trim white space
171 FETCH_DISTRIBUTIONS=`echo $FETCH_DISTRIBUTIONS` # Trim white space
173 if [ -n "$FETCH_DISTRIBUTIONS" -a -n "$BSDINSTALL_CONFIGCURRENT" ]; then
174 dialog --backtitle "FreeBSD Installer" --title "Network Installation" --msgbox "Some installation files were not 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
175 bsdinstall netconfig || error
179 if [ -n "$FETCH_DISTRIBUTIONS" ]; then
181 BSDINSTALL_DISTSITE=$(`dirname $0`/mirrorselect 2>&1 1>&3)
184 test $MIRROR_BUTTON -eq 0 || error "No mirror selected"
185 export BSDINSTALL_DISTSITE
192 # Try to detect known broken platforms and apply their workarounds
195 if f_interactive; then
196 sys_maker=$( kenv -q smbios.system.maker )
197 f_dprintf "smbios.system.maker=[%s]" "$sys_maker"
198 sys_model=$( kenv -q smbios.system.product )
199 f_dprintf "smbios.system.product=[%s]" "$sys_model"
200 sys_version=$( kenv -q smbios.system.version )
201 f_dprintf "smbios.system.version=[%s]" "$sys_version"
202 sys_mb_maker=$( kenv -q smbios.planar.maker )
203 f_dprintf "smbios.planar.maker=[%s]" "$sys_mb_maker"
204 sys_mb_product=$( kenv -q smbios.planar.product )
205 f_dprintf "smbios.planar.product=[%s]" "$sys_mb_product"
212 case "$sys_version" in
213 "ThinkPad X220"|"ThinkPad T420"|"ThinkPad T520"|"ThinkPad W520"|"ThinkPad X1")
214 dialog_workaround "$msg_lenovo_fix"
216 f_dprintf "lenovofix_prompt=[%s]" "$retval"
217 if [ $retval -eq $DIALOG_OK ]; then
218 export ZFSBOOT_PARTITION_SCHEME="GPT + Lenovo Fix"
219 export WORKAROUND_LENOVO=1
226 "Latitude E6330"|"Latitude E7440"|"Latitude E7240"|"Precision Tower 5810")
227 dialog_workaround "$msg_gpt_active_fix"
229 f_dprintf "gpt_active_fix_prompt=[%s]" "$retval"
230 if [ $retval -eq $DIALOG_OK ]; then
231 export ZFSBOOT_PARTITION_SCHEME="GPT + Active"
232 export WORKAROUND_GPTACTIVE=1
240 dialog_workaround "$msg_gpt_active_fix"
242 f_dprintf "gpt_active_fix_prompt=[%s]" "$retval"
243 if [ $retval -eq $DIALOG_OK ]; then
244 export ZFSBOOT_PARTITION_SCHEME="GPT + Active"
245 export WORKAROUND_GPTACTIVE=1
254 case "$sys_mb_maker" in
256 case "$sys_mb_product" in
258 dialog_workaround "$msg_gpt_active_fix"
260 f_dprintf "gpt_active_fix_prompt=[%s]" "$retval"
261 if [ $retval -eq $DIALOG_OK ]; then
262 export ZFSBOOT_PARTITION_SCHEME="GPT + Active"
263 export WORKAROUND_GPTACTIVE=1
269 case "$sys_mb_product" in
271 dialog_workaround "$msg_gpt_active_fix"
273 f_dprintf "gpt_active_fix_prompt=[%s]" "$retval"
274 if [ $retval -eq $DIALOG_OK ]; then
275 export ZFSBOOT_PARTITION_SCHEME="GPT + Active"
276 export WORKAROUND_GPTACTIVE=1
285 \"Auto (UFS)\" \"Guided Disk Setup\" \
286 Manual \"Manual Disk Setup (experts)\" \
287 Shell \"Open a shell and partition by hand\""
289 CURARCH=$( uname -m )
291 amd64|arm64|i386) # Booting ZFS Supported
292 PMODES="$PMODES \"Auto (ZFS)\" \"Guided Root-on-ZFS\""
294 *) # Booting ZFS Unspported
299 PARTMODE=`echo $PMODES | xargs dialog --backtitle "FreeBSD Installer" \
300 --title "Partitioning" \
301 --menu "How would you like to partition your disk?" \
302 0 0 0 2>&1 1>&3` || exit 1
306 "Auto (UFS)") # Guided
307 bsdinstall autopart || error "Partitioning error"
308 bsdinstall mount || error "Failed to mount filesystem"
312 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'."
316 if f_isset debugFile; then
317 # Give partedit the path to our logfile so it can append
318 BSDINSTALL_LOG="${debugFile#+}" bsdinstall partedit || error "Partitioning error"
320 bsdinstall partedit || error "Partitioning error"
322 bsdinstall mount || error "Failed to mount filesystem"
325 bsdinstall zfsboot || error "ZFS setup failed"
326 bsdinstall mount || error "Failed to mount filesystem"
329 error "Unknown partitioning mode"
333 if [ ! -z "$FETCH_DISTRIBUTIONS" ]; then
334 ALL_DISTRIBUTIONS="$DISTRIBUTIONS"
337 # Download to a directory in the new system as scratch space
338 BSDINSTALL_FETCHDEST="$BSDINSTALL_CHROOT/usr/freebsd-dist"
339 mkdir -p "$BSDINSTALL_FETCHDEST" || error "Could not create directory $BSDINSTALL_FETCHDEST"
341 export DISTRIBUTIONS="$FETCH_DISTRIBUTIONS"
342 # Try to use any existing distfiles
343 if [ -d $BSDINSTALL_DISTDIR ]; then
345 mount_nullfs -o union "$BSDINSTALL_FETCHDEST" "$BSDINSTALL_DISTDIR"
347 export DISTRIBUTIONS="$FETCH_DISTRIBUTIONS"
348 export BSDINSTALL_DISTDIR="$BSDINSTALL_FETCHDEST"
351 export FTP_PASSIVE_MODE=YES
352 # Iterate through the distribution list and set a flag if debugging
353 # distributions have been selected.
354 for _DISTRIBUTION in $DISTRIBUTIONS; do
355 case $_DISTRIBUTION in
357 [ -e $BSDINSTALL_DISTDIR/$_DISTRIBUTION ] \
360 DEBUG_LIST="\n$DEBUG_LIST\n$_DISTRIBUTION"
367 # Fetch the distributions.
371 if [ $rc -ne 0 ]; then
372 # If unable to fetch the remote distributions, recommend
373 # deselecting the debugging distributions, and retrying the
374 # installation, since failure to fetch *-dbg.txz should not
375 # be considered a fatal installation error.
376 msg="Failed to fetch remote distribution"
377 if [ ! -z "$WANT_DEBUG" ]; then
378 # Trim leading and trailing newlines.
379 DEBUG_LIST="${DEBUG_LIST%%\n}"
380 DEBUG_LIST="${DEBUG_LIST##\n}"
381 msg="$msg\n\nPlease deselect the following distributions"
382 msg="$msg and retry the installation:"
383 msg="$msg\n$DEBUG_LIST"
387 export DISTRIBUTIONS="$ALL_DISTRIBUTIONS"
390 if [ ! -z "$LOCAL_DISTRIBUTIONS" ]; then
391 # Download to a directory in the new system as scratch space
392 BSDINSTALL_FETCHDEST="$BSDINSTALL_CHROOT/usr/freebsd-dist"
393 mkdir -p "$BSDINSTALL_FETCHDEST" || error "Could not create directory $BSDINSTALL_FETCHDEST"
394 # Try to use any existing distfiles
395 if [ -d $BSDINSTALL_DISTDIR ]; then
397 mount_nullfs -o union "$BSDINSTALL_FETCHDEST" "$BSDINSTALL_DISTDIR"
398 export BSDINSTALL_DISTDIR="$BSDINSTALL_FETCHDEST"
400 env DISTRIBUTIONS="$LOCAL_DISTRIBUTIONS" \
401 BSDINSTALL_DISTSITE="file:///usr/freebsd-dist" \
402 bsdinstall distfetch || \
403 error "Failed to fetch distribution from local media"
406 bsdinstall checksum || error "Distribution checksum failed"
407 bsdinstall distextract || error "Distribution extract failed"
410 bsdinstall bootconfig || error "Failed to configure bootloader"
412 bsdinstall rootpass || error "Could not set root password"
414 trap true SIGINT # This section is optional
415 if [ "$NETCONFIG_DONE" != yes ]; then
416 bsdinstall netconfig # Don't check for errors -- the user may cancel
422 dialog --backtitle "FreeBSD Installer" --title "Add User Accounts" --yesno \
423 "Would you like to add users to the installed system now?" 0 0 && \
428 REVISIT=$(dialog --backtitle "FreeBSD Installer" \
429 --title "Final Configuration" --no-cancel --menu \
430 "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 \
431 "Exit" "Apply configuration and exit installer" \
432 "Add User" "Add a user to the system" \
433 "Root Password" "Change root password" \
434 "Hostname" "Set system hostname" \
435 "Network" "Networking configuration" \
436 "Services" "Set daemons to run on startup" \
437 "System Hardening" "Set security options" \
438 "Time Zone" "Set system timezone" \
439 "Handbook" "Install FreeBSD Handbook (requires network)" 2>&1 1>&3)
472 bsdinstall docsinstall
478 # Allow user to change his mind
481 trap error SIGINT # SIGINT is bad again
482 bsdinstall config || error "Failed to save config"
484 if [ -n "$DISTDIR_IS_UNIONFS" ]; then
485 umount -f $BSDINSTALL_DISTDIR
488 if [ ! -z "$BSDINSTALL_FETCHDEST" ]; then
489 rm -rf "$BSDINSTALL_FETCHDEST"
492 dialog --backtitle "FreeBSD Installer" --title "Manual Configuration" \
493 --default-button no --yesno \
494 "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
495 if [ $? -eq 0 ]; then
497 echo This shell is operating in a chroot in the new system. \
498 When finished making configuration changes, type \"exit\".
499 chroot "$BSDINSTALL_CHROOT" /bin/sh 2>&1
505 f_dprintf "Installation Completed at %s" "$( date )"
507 ################################################################################
509 ################################################################################