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"
44 msg_an_installation_step_has_been_aborted="An installation step has been aborted. Would you like\nto restart the installation or exit the installer?"
45 msg_auto_ufs="Auto (UFS)"
46 msg_auto_ufs_desc="Guided UFS Disk Setup"
47 msg_auto_ufs_help="Menu options help choose which disk to setup using UFS and standard partitions"
48 msg_auto_zfs="Auto (ZFS)"
49 msg_auto_zfs_desc="Guided Root-on-ZFS"
50 msg_auto_zfs_help="To use ZFS with less than 8GB RAM, see https://wiki.freebsd.org/ZFSTuningGuide"
52 msg_freebsd_installer="FreeBSD Installer"
53 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?"
54 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?"
56 msg_manual_desc="Manual Disk Setup (experts)"
57 msg_manual_help="Create customized partitions from menu options"
61 msg_shell_desc="Open a shell and partition by hand"
62 msg_shell_help="Create customized partitions using command-line utilities"
65 ############################################################ FUNCTIONS
69 # Display generic error message when a script fails. An optional message
70 # argument can preceed the generic message. User is given the choice of
71 # restarting the installer or exiting.
75 local title="$msg_abort"
76 local btitle="$msg_freebsd_installer"
77 local prompt="${1:+$1\n\n}$msg_an_installation_step_has_been_aborted"
78 local hline="$hline_arrows_tab_space_enter"
80 [ "$DISTDIR_IS_UNIONFS" ] && umount -f "$BSDINSTALL_DISTDIR"
81 [ -f "$PATH_FSTAB" ] && bsdinstall umount
84 f_dialog_buttonbox_size height width \
85 "$title" "$btitle" "$prompt" "$hline"
89 --backtitle "$btitle" \
91 --no-label "$msg_exit" \
92 --yes-label "$msg_restart" \
93 --yesno "$prompt" $height $width
103 # Ask the user if they wish to apply a workaround
107 local passed_msg="$1"
108 local title="$DIALOG_TITLE"
109 local btitle="$DIALOG_BACKTITLE"
110 local prompt # Calculated below
111 local hline="$hline_arrows_tab_enter"
113 local height=8 width=50 prefix=" "
114 local plen=${#prefix} list= line=
115 local max_width=$(( $width - 3 - $plen ))
117 local yes no defaultno extra_args format
118 if [ "$USE_XDIALOG" ]; then
119 yes=ok no=cancel defaultno=default-no
120 extra_args="--wrap --left"
123 yes=yes no=no defaultno=defaultno
124 extra_args="--cr-wrap"
128 # Add height for Xdialog(1)
129 [ "$USE_XDIALOG" ] && height=$(( $height + $height / 5 + 3 ))
131 prompt=$( printf "$format" )
132 f_dprintf "%s: Workaround prompt" "$0"
135 --backtitle "$btitle" \
137 --$yes-label "$msg_yes" \
138 --$no-label "$msg_no" \
140 --yesno "$prompt" $height $width
143 ############################################################ MAIN
145 f_dprintf "Began Installation at %s" "$( date )"
147 rm -rf $BSDINSTALL_TMPETC
148 mkdir $BSDINSTALL_TMPETC
150 trap true SIGINT # This section is optional
153 trap error SIGINT # Catch cntrl-C here
154 bsdinstall hostname || error "Set hostname failed"
156 export DISTRIBUTIONS="base.txz kernel.txz"
157 if [ -f $BSDINSTALL_DISTDIR/MANIFEST ]; then
158 DISTMENU=`awk -F'\t' '!/^(kernel\.txz|base\.txz)/{print $1,$5,$6}' $BSDINSTALL_DISTDIR/MANIFEST`
159 DISTMENU="$(echo ${DISTMENU} | sed -E 's/\.txz//g')"
162 EXTRA_DISTS=$( eval dialog \
163 --backtitle \"FreeBSD Installer\" \
164 --title \"Distribution Select\" --nocancel --separate-output \
165 --checklist \"Choose optional system components to install:\" \
168 for dist in $EXTRA_DISTS; do
169 export DISTRIBUTIONS="$DISTRIBUTIONS $dist.txz"
173 LOCAL_DISTRIBUTIONS="MANIFEST"
174 FETCH_DISTRIBUTIONS=""
175 for dist in $DISTRIBUTIONS; do
176 if [ ! -f $BSDINSTALL_DISTDIR/$dist ]; then
177 FETCH_DISTRIBUTIONS="$FETCH_DISTRIBUTIONS $dist"
179 LOCAL_DISTRIBUTIONS="$LOCAL_DISTRIBUTIONS $dist"
182 LOCAL_DISTRIBUTIONS=`echo $LOCAL_DISTRIBUTIONS` # Trim white space
183 FETCH_DISTRIBUTIONS=`echo $FETCH_DISTRIBUTIONS` # Trim white space
185 if [ -n "$FETCH_DISTRIBUTIONS" -a -n "$BSDINSTALL_CONFIGCURRENT" ]; then
186 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
187 bsdinstall netconfig || error
191 if [ -n "$FETCH_DISTRIBUTIONS" ]; then
193 BSDINSTALL_DISTSITE=$(`dirname $0`/mirrorselect 2>&1 1>&3)
196 test $MIRROR_BUTTON -eq 0 || error "No mirror selected"
197 export BSDINSTALL_DISTSITE
204 # Try to detect known broken platforms and apply their workarounds
207 if f_interactive; then
208 sys_maker=$( kenv -q smbios.system.maker )
209 f_dprintf "smbios.system.maker=[%s]" "$sys_maker"
210 sys_model=$( kenv -q smbios.system.product )
211 f_dprintf "smbios.system.product=[%s]" "$sys_model"
212 sys_version=$( kenv -q smbios.system.version )
213 f_dprintf "smbios.system.version=[%s]" "$sys_version"
214 sys_mb_maker=$( kenv -q smbios.planar.maker )
215 f_dprintf "smbios.planar.maker=[%s]" "$sys_mb_maker"
216 sys_mb_product=$( kenv -q smbios.planar.product )
217 f_dprintf "smbios.planar.product=[%s]" "$sys_mb_product"
224 case "$sys_version" in
225 "ThinkPad X220"|"ThinkPad T420"|"ThinkPad T520"|"ThinkPad W520"|"ThinkPad X1")
226 dialog_workaround "$msg_lenovo_fix"
228 f_dprintf "lenovofix_prompt=[%s]" "$retval"
229 if [ $retval -eq $DIALOG_OK ]; then
230 export ZFSBOOT_PARTITION_SCHEME="GPT + Lenovo Fix"
231 export WORKAROUND_LENOVO=1
238 "Latitude E6330"|"Latitude E7440"|"Latitude E7240"|"Precision Tower 5810")
239 dialog_workaround "$msg_gpt_active_fix"
241 f_dprintf "gpt_active_fix_prompt=[%s]" "$retval"
242 if [ $retval -eq $DIALOG_OK ]; then
243 export ZFSBOOT_PARTITION_SCHEME="GPT + Active"
244 export WORKAROUND_GPTACTIVE=1
252 dialog_workaround "$msg_gpt_active_fix"
254 f_dprintf "gpt_active_fix_prompt=[%s]" "$retval"
255 if [ $retval -eq $DIALOG_OK ]; then
256 export ZFSBOOT_PARTITION_SCHEME="GPT + Active"
257 export WORKAROUND_GPTACTIVE=1
266 case "$sys_mb_maker" in
268 case "$sys_mb_product" in
270 dialog_workaround "$msg_gpt_active_fix"
272 f_dprintf "gpt_active_fix_prompt=[%s]" "$retval"
273 if [ $retval -eq $DIALOG_OK ]; then
274 export ZFSBOOT_PARTITION_SCHEME="GPT + Active"
275 export WORKAROUND_GPTACTIVE=1
281 case "$sys_mb_product" in
283 dialog_workaround "$msg_gpt_active_fix"
285 f_dprintf "gpt_active_fix_prompt=[%s]" "$retval"
286 if [ $retval -eq $DIALOG_OK ]; then
287 export ZFSBOOT_PARTITION_SCHEME="GPT + Active"
288 export WORKAROUND_GPTACTIVE=1
297 '$msg_auto_ufs' '$msg_auto_ufs_desc' '$msg_auto_ufs_help'
298 '$msg_manual' '$msg_manual_desc' '$msg_manual_help'
299 '$msg_shell' '$msg_shell_desc' '$msg_shell_help'
302 CURARCH=$( uname -m )
304 amd64|arm64|i386) # Booting ZFS Supported
306 '$msg_auto_zfs' '$msg_auto_zfs_desc' '$msg_auto_zfs_help'
310 *) # Booting ZFS Unsupported
315 PARTMODE=`echo $PMODES | xargs dialog --backtitle "FreeBSD Installer" \
316 --title "Partitioning" \
318 --menu "How would you like to partition your disk?" \
319 0 0 0 2>&1 1>&3` || exit 1
323 "$msg_auto_zfs") # ZFS
324 bsdinstall zfsboot || error "ZFS setup failed"
325 bsdinstall mount || error "Failed to mount filesystem"
327 "$msg_auto_ufs") # Guided UFS
328 bsdinstall autopart || error "Partitioning error"
329 bsdinstall mount || error "Failed to mount filesystem"
331 "$msg_shell") # Shell
333 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'."
336 "$msg_manual") # Manual
337 if f_isset debugFile; then
338 # Give partedit the path to our logfile so it can append
339 BSDINSTALL_LOG="${debugFile#+}" bsdinstall partedit || error "Partitioning error"
341 bsdinstall partedit || error "Partitioning error"
343 bsdinstall mount || error "Failed to mount filesystem"
346 error "Unknown partitioning mode"
350 if [ ! -z "$FETCH_DISTRIBUTIONS" ]; then
351 ALL_DISTRIBUTIONS="$DISTRIBUTIONS"
354 # Download to a directory in the new system as scratch space
355 BSDINSTALL_FETCHDEST="$BSDINSTALL_CHROOT/usr/freebsd-dist"
356 mkdir -p "$BSDINSTALL_FETCHDEST" || error "Could not create directory $BSDINSTALL_FETCHDEST"
358 export DISTRIBUTIONS="$FETCH_DISTRIBUTIONS"
359 # Try to use any existing distfiles
360 if [ -d $BSDINSTALL_DISTDIR ]; then
362 mount_nullfs -o union "$BSDINSTALL_FETCHDEST" "$BSDINSTALL_DISTDIR"
364 export DISTRIBUTIONS="$FETCH_DISTRIBUTIONS"
365 export BSDINSTALL_DISTDIR="$BSDINSTALL_FETCHDEST"
368 export FTP_PASSIVE_MODE=YES
369 # Iterate through the distribution list and set a flag if debugging
370 # distributions have been selected.
371 for _DISTRIBUTION in $DISTRIBUTIONS; do
372 case $_DISTRIBUTION in
374 [ -e $BSDINSTALL_DISTDIR/$_DISTRIBUTION ] \
377 DEBUG_LIST="\n$DEBUG_LIST\n$_DISTRIBUTION"
384 # Fetch the distributions.
388 if [ $rc -ne 0 ]; then
389 # If unable to fetch the remote distributions, recommend
390 # deselecting the debugging distributions, and retrying the
391 # installation, since failure to fetch *-dbg.txz should not
392 # be considered a fatal installation error.
393 msg="Failed to fetch remote distribution"
394 if [ ! -z "$WANT_DEBUG" ]; then
395 # Trim leading and trailing newlines.
396 DEBUG_LIST="${DEBUG_LIST%%\n}"
397 DEBUG_LIST="${DEBUG_LIST##\n}"
398 msg="$msg\n\nPlease deselect the following distributions"
399 msg="$msg and retry the installation:"
400 msg="$msg\n$DEBUG_LIST"
404 export DISTRIBUTIONS="$ALL_DISTRIBUTIONS"
407 if [ ! -z "$LOCAL_DISTRIBUTIONS" ]; then
408 # Download to a directory in the new system as scratch space
409 BSDINSTALL_FETCHDEST="$BSDINSTALL_CHROOT/usr/freebsd-dist"
410 mkdir -p "$BSDINSTALL_FETCHDEST" || error "Could not create directory $BSDINSTALL_FETCHDEST"
411 # Try to use any existing distfiles
412 if [ -d $BSDINSTALL_DISTDIR ]; then
414 mount_nullfs -o union "$BSDINSTALL_FETCHDEST" "$BSDINSTALL_DISTDIR"
415 export BSDINSTALL_DISTDIR="$BSDINSTALL_FETCHDEST"
417 env DISTRIBUTIONS="$LOCAL_DISTRIBUTIONS" \
418 BSDINSTALL_DISTSITE="file:///usr/freebsd-dist" \
419 bsdinstall distfetch || \
420 error "Failed to fetch distribution from local media"
423 bsdinstall checksum || error "Distribution checksum failed"
424 bsdinstall distextract || error "Distribution extract failed"
427 bsdinstall bootconfig || error "Failed to configure bootloader"
429 bsdinstall rootpass || error "Could not set root password"
431 trap true SIGINT # This section is optional
432 if [ "$NETCONFIG_DONE" != yes ]; then
433 bsdinstall netconfig # Don't check for errors -- the user may cancel
439 dialog --backtitle "FreeBSD Installer" --title "Add User Accounts" --yesno \
440 "Would you like to add users to the installed system now?" 0 0 && \
445 REVISIT=$(dialog --backtitle "FreeBSD Installer" \
446 --title "Final Configuration" --no-cancel --menu \
447 "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 \
448 "Exit" "Apply configuration and exit installer" \
449 "Add User" "Add a user to the system" \
450 "Root Password" "Change root password" \
451 "Hostname" "Set system hostname" \
452 "Network" "Networking configuration" \
453 "Services" "Set daemons to run on startup" \
454 "System Hardening" "Set security options" \
455 "Time Zone" "Set system timezone" \
456 "Handbook" "Install FreeBSD Handbook (requires network)" 2>&1 1>&3)
489 bsdinstall docsinstall
495 # Allow user to change his mind
498 trap error SIGINT # SIGINT is bad again
499 bsdinstall config || error "Failed to save config"
501 if [ -n "$DISTDIR_IS_UNIONFS" ]; then
502 umount -f $BSDINSTALL_DISTDIR
505 if [ ! -z "$BSDINSTALL_FETCHDEST" ]; then
506 rm -rf "$BSDINSTALL_FETCHDEST"
509 dialog --backtitle "FreeBSD Installer" --title "Manual Configuration" \
510 --default-button no --yesno \
511 "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
512 if [ $? -eq 0 ]; then
514 echo This shell is operating in a chroot in the new system. \
515 When finished making configuration changes, type \"exit\".
516 chroot "$BSDINSTALL_CHROOT" /bin/sh 2>&1
522 f_dprintf "Installation Completed at %s" "$( date )"
524 ################################################################################
526 ################################################################################