1#!/bin/sh 2#- 3# Copyright (c) 2011 Nathan Whitehorn 4# Copyright (c) 2013-2018 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############################################################ GLOBALS 37 38# 39# Strings that should be moved to an i18n file and loaded with f_include_lang() 40# 41hline_arrows_tab_enter="Press arrows, TAB or ENTER" 42hline_arrows_tab_space_enter="Press arrows, TAB, SPACE or ENTER" 43msg_abort="Abort" 44msg_an_installation_step_has_been_aborted="An installation step has been aborted. Would you like\nto restart the installation or exit the installer?" 45msg_auto_ufs="Auto (UFS)" 46msg_auto_ufs_desc="Guided UFS Disk Setup" 47msg_auto_ufs_help="Menu options help choose which disk to setup using UFS and standard partitions" 48msg_auto_zfs="Auto (ZFS)" 49msg_auto_zfs_desc="Guided Root-on-ZFS" 50msg_auto_zfs_help="To use ZFS with less than 8GB RAM, see https://wiki.freebsd.org/ZFSTuningGuide" 51msg_exit="Exit" 52msg_freebsd_installer="FreeBSD Installer" 53msg_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?" 54msg_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?" 55msg_manual="Manual" 56msg_manual_desc="Manual Disk Setup (experts)" 57msg_manual_help="Create customized partitions from menu options" 58msg_no="NO" 59msg_restart="Restart" 60msg_shell="Shell" 61msg_shell_desc="Open a shell and partition by hand" 62msg_shell_help="Create customized partitions using command-line utilities" 63msg_yes="YES" 64 65############################################################ FUNCTIONS 66 67# error [$msg] 68# 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. 72# 73error() 74{ 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" 79 80 [ "$DISTDIR_IS_UNIONFS" ] && umount -f "$BSDINSTALL_DISTDIR" 81 [ -f "$PATH_FSTAB" ] && bsdinstall umount 82 83 local height width 84 f_dialog_buttonbox_size height width \ 85 "$title" "$btitle" "$prompt" "$hline" 86 87 if $DIALOG \ 88 --title "$title" \ 89 --backtitle "$btitle" \ 90 --hline "$hline" \ 91 --no-label "$msg_exit" \ 92 --yes-label "$msg_restart" \ 93 --yesno "$prompt" $height $width 94 then 95 exec $0 96 # NOTREACHED 97 fi 98 exit 1 99} 100 101# dialog_workaround 102# 103# Ask the user if they wish to apply a workaround 104# 105dialog_workaround() 106{ 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" 112 113 local height=8 width=50 prefix=" " 114 local plen=${#prefix} list= line= 115 local max_width=$(( $width - 3 - $plen )) 116 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" 121 format="$passed_msg" 122 else 123 yes=yes no=no defaultno=defaultno 124 extra_args="--cr-wrap" 125 format="$passed_msg" 126 fi 127 128 # Add height for Xdialog(1) 129 [ "$USE_XDIALOG" ] && height=$(( $height + $height / 5 + 3 )) 130 131 prompt=$( printf "$format" ) 132 f_dprintf "%s: Workaround prompt" "$0" 133 $DIALOG \ 134 --title "$title" \ 135 --backtitle "$btitle" \ 136 --hline "$hline" \ 137 --$yes-label "$msg_yes" \ 138 --$no-label "$msg_no" \ 139 $extra_args \ 140 --yesno "$prompt" $height $width 141} 142 143############################################################ MAIN 144 145f_dprintf "Began Installation at %s" "$( date )" 146 147rm -rf $BSDINSTALL_TMPETC 148mkdir $BSDINSTALL_TMPETC 149 150trap true SIGINT # This section is optional 151bsdinstall keymap 152 153trap error SIGINT # Catch cntrl-C here 154bsdinstall hostname || error "Set hostname failed" 155 156export DISTRIBUTIONS="base.txz kernel.txz" 157if [ -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')" 160 161 exec 3>&1 162 EXTRA_DISTS=$( eval dialog \ 163 --backtitle \"FreeBSD Installer\" \ 164 --title \"Distribution Select\" --nocancel --separate-output \ 165 --checklist \"Choose optional system components to install:\" \ 166 0 0 0 $DISTMENU \ 167 2>&1 1>&3 ) 168 for dist in $EXTRA_DISTS; do 169 export DISTRIBUTIONS="$DISTRIBUTIONS $dist.txz" 170 done 171fi 172 173LOCAL_DISTRIBUTIONS="MANIFEST" 174FETCH_DISTRIBUTIONS="" 175for dist in $DISTRIBUTIONS; do 176 if [ ! -f $BSDINSTALL_DISTDIR/$dist ]; then 177 FETCH_DISTRIBUTIONS="$FETCH_DISTRIBUTIONS $dist" 178 else 179 LOCAL_DISTRIBUTIONS="$LOCAL_DISTRIBUTIONS $dist" 180 fi 181done 182LOCAL_DISTRIBUTIONS=`echo $LOCAL_DISTRIBUTIONS` # Trim white space 183FETCH_DISTRIBUTIONS=`echo $FETCH_DISTRIBUTIONS` # Trim white space 184 185if [ -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 188 NETCONFIG_DONE=yes 189fi 190 191if [ -n "$FETCH_DISTRIBUTIONS" ]; then 192 exec 3>&1 193 BSDINSTALL_DISTSITE=$(`dirname $0`/mirrorselect 2>&1 1>&3) 194 MIRROR_BUTTON=$? 195 exec 3>&- 196 test $MIRROR_BUTTON -eq 0 || error "No mirror selected" 197 export BSDINSTALL_DISTSITE 198fi 199 200rm -f $PATH_FSTAB 201touch $PATH_FSTAB 202 203# 204# Try to detect known broken platforms and apply their workarounds 205# 206 207if 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" 218 219 # 220 # Laptop Models 221 # 222 case "$sys_maker" in 223 "LENOVO") 224 case "$sys_version" in 225 "ThinkPad X220"|"ThinkPad T420"|"ThinkPad T520"|"ThinkPad W520"|"ThinkPad X1") 226 dialog_workaround "$msg_lenovo_fix" 227 retval=$? 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 232 fi 233 ;; 234 esac 235 ;; 236 "Dell Inc.") 237 case "$sys_model" in 238 "Latitude E6330"|"Latitude E7440"|"Latitude E7240"|"Precision Tower 5810") 239 dialog_workaround "$msg_gpt_active_fix" 240 retval=$? 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 245 fi 246 ;; 247 esac 248 ;; 249 "Hewlett-Packard") 250 case "$sys_model" in 251 "HP ProBook 4330s") 252 dialog_workaround "$msg_gpt_active_fix" 253 retval=$? 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 258 fi 259 ;; 260 esac 261 ;; 262 esac 263 # 264 # Motherboard Models 265 # 266 case "$sys_mb_maker" in 267 "Intel Corporation") 268 case "$sys_mb_product" in 269 "DP965LT"|"D510MO") 270 dialog_workaround "$msg_gpt_active_fix" 271 retval=$? 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 276 fi 277 ;; 278 esac 279 ;; 280 "Acer") 281 case "$sys_mb_product" in 282 "Veriton M6630G") 283 dialog_workaround "$msg_gpt_active_fix" 284 retval=$? 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 289 fi 290 ;; 291 esac 292 ;; 293 esac 294fi 295 296PMODES=" 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' 300" # END-QUOTE 301 302CURARCH=$( uname -m ) 303case $CURARCH in 304 amd64|arm64|i386) # Booting ZFS Supported 305 PMODES=" 306 '$msg_auto_zfs' '$msg_auto_zfs_desc' '$msg_auto_zfs_help' 307 $PMODES 308 " # END-QUOTE 309 ;; 310 *) # Booting ZFS Unsupported 311 ;; 312esac 313 314exec 3>&1 315PARTMODE=`echo $PMODES | xargs dialog --backtitle "FreeBSD Installer" \ 316 --title "Partitioning" \ 317 --item-help \ 318 --menu "How would you like to partition your disk?" \ 319 0 0 0 2>&1 1>&3` || exit 1 320exec 3>&- 321 322case "$PARTMODE" in 323"$msg_auto_zfs") # ZFS 324 bsdinstall zfsboot || error "ZFS setup failed" 325 bsdinstall mount || error "Failed to mount filesystem" 326 ;; 327"$msg_auto_ufs") # Guided UFS 328 bsdinstall autopart || error "Partitioning error" 329 bsdinstall mount || error "Failed to mount filesystem" 330 ;; 331"$msg_shell") # Shell 332 clear 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'." 334 sh 2>&1 335 ;; 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" 340 else 341 bsdinstall partedit || error "Partitioning error" 342 fi 343 bsdinstall mount || error "Failed to mount filesystem" 344 ;; 345*) 346 error "Unknown partitioning mode" 347 ;; 348esac 349 350if [ ! -z "$FETCH_DISTRIBUTIONS" ]; then 351 ALL_DISTRIBUTIONS="$DISTRIBUTIONS" 352 WANT_DEBUG= 353 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" 357 358 export DISTRIBUTIONS="$FETCH_DISTRIBUTIONS" 359 # Try to use any existing distfiles 360 if [ -d $BSDINSTALL_DISTDIR ]; then 361 DISTDIR_IS_UNIONFS=1 362 mount_nullfs -o union "$BSDINSTALL_FETCHDEST" "$BSDINSTALL_DISTDIR" 363 else 364 export DISTRIBUTIONS="$FETCH_DISTRIBUTIONS" 365 export BSDINSTALL_DISTDIR="$BSDINSTALL_FETCHDEST" 366 fi 367 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 373 *-dbg.*) 374 [ -e $BSDINSTALL_DISTDIR/$_DISTRIBUTION ] \ 375 && continue 376 WANT_DEBUG=1 377 DEBUG_LIST="\n$DEBUG_LIST\n$_DISTRIBUTION" 378 ;; 379 *) 380 ;; 381 esac 382 done 383 384 # Fetch the distributions. 385 bsdinstall distfetch 386 rc=$? 387 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" 401 fi 402 error "$msg" 403 fi 404 export DISTRIBUTIONS="$ALL_DISTRIBUTIONS" 405fi 406 407if [ ! -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 413 DISTDIR_IS_UNIONFS=1 414 mount_nullfs -o union "$BSDINSTALL_FETCHDEST" "$BSDINSTALL_DISTDIR" 415 export BSDINSTALL_DISTDIR="$BSDINSTALL_FETCHDEST" 416 fi 417 env DISTRIBUTIONS="$LOCAL_DISTRIBUTIONS" \ 418 BSDINSTALL_DISTSITE="file:///usr/freebsd-dist" \ 419 bsdinstall distfetch || \ 420 error "Failed to fetch distribution from local media" 421fi 422 423bsdinstall checksum || error "Distribution checksum failed" 424bsdinstall distextract || error "Distribution extract failed" 425 426# Set up boot loader 427bsdinstall bootconfig || error "Failed to configure bootloader" 428 429bsdinstall rootpass || error "Could not set root password" 430 431trap true SIGINT # This section is optional 432if [ "$NETCONFIG_DONE" != yes ]; then 433 bsdinstall netconfig # Don't check for errors -- the user may cancel 434fi 435bsdinstall time 436bsdinstall services 437bsdinstall hardening 438 439dialog --backtitle "FreeBSD Installer" --title "Add User Accounts" --yesno \ 440 "Would you like to add users to the installed system now?" 0 0 && \ 441 bsdinstall adduser 442 443finalconfig() { 444 exec 3>&1 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) 457 exec 3>&- 458 459 case "$REVISIT" in 460 "Add User") 461 bsdinstall adduser 462 finalconfig 463 ;; 464 "Root Password") 465 bsdinstall rootpass 466 finalconfig 467 ;; 468 "Hostname") 469 bsdinstall hostname 470 finalconfig 471 ;; 472 "Network") 473 bsdinstall netconfig 474 finalconfig 475 ;; 476 "Services") 477 bsdinstall services 478 finalconfig 479 ;; 480 "System Hardening") 481 bsdinstall hardening 482 finalconfig 483 ;; 484 "Time Zone") 485 bsdinstall time 486 finalconfig 487 ;; 488 "Handbook") 489 bsdinstall docsinstall 490 finalconfig 491 ;; 492 esac 493} 494 495# Allow user to change his mind 496finalconfig 497 498trap error SIGINT # SIGINT is bad again 499bsdinstall config || error "Failed to save config" 500 501if [ -n "$DISTDIR_IS_UNIONFS" ]; then 502 umount -f $BSDINSTALL_DISTDIR 503fi 504 505if [ ! -z "$BSDINSTALL_FETCHDEST" ]; then 506 rm -rf "$BSDINSTALL_FETCHDEST" 507fi 508 509dialog --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 512if [ $? -eq 0 ]; then 513 clear 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 517fi 518 519bsdinstall entropy 520bsdinstall umount 521 522f_dprintf "Installation Completed at %s" "$( date )" 523 524################################################################################ 525# END 526################################################################################ 527