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_exit="Exit" 45msg_freebsd_installer="FreeBSD Installer" 46msg_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?" 47msg_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?" 48msg_an_installation_step_has_been_aborted="An installation step has been aborted. Would you like\nto restart the installation or exit the installer?" 49msg_no="NO" 50msg_restart="Restart" 51msg_yes="YES" 52 53############################################################ FUNCTIONS 54 55# error [$msg] 56# 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. 60# 61error() 62{ 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" 67 68 [ "$DISTDIR_IS_UNIONFS" ] && umount -f "$BSDINSTALL_DISTDIR" 69 [ -f "$PATH_FSTAB" ] && bsdinstall umount 70 71 local height width 72 f_dialog_buttonbox_size height width \ 73 "$title" "$btitle" "$prompt" "$hline" 74 75 if $DIALOG \ 76 --title "$title" \ 77 --backtitle "$btitle" \ 78 --hline "$hline" \ 79 --no-label "$msg_exit" \ 80 --yes-label "$msg_restart" \ 81 --yesno "$prompt" $height $width 82 then 83 exec $0 84 # NOTREACHED 85 fi 86 exit 1 87} 88 89# dialog_workaround 90# 91# Ask the user if they wish to apply a workaround 92# 93dialog_workaround() 94{ 95 local passed_msg="$1" 96 local title="$DIALOG_TITLE" 97 local btitle="$DIALOG_BACKTITLE" 98 local prompt # Calculated below 99 local hline="$hline_arrows_tab_enter" 100 101 local height=8 width=50 prefix=" " 102 local plen=${#prefix} list= line= 103 local max_width=$(( $width - 3 - $plen )) 104 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" 109 format="$passed_msg" 110 else 111 yes=yes no=no defaultno=defaultno 112 extra_args="--cr-wrap" 113 format="$passed_msg" 114 fi 115 116 # Add height for Xdialog(1) 117 [ "$USE_XDIALOG" ] && height=$(( $height + $height / 5 + 3 )) 118 119 prompt=$( printf "$format" ) 120 f_dprintf "%s: Workaround prompt" "$0" 121 $DIALOG \ 122 --title "$title" \ 123 --backtitle "$btitle" \ 124 --hline "$hline" \ 125 --$yes-label "$msg_yes" \ 126 --$no-label "$msg_no" \ 127 $extra_args \ 128 --yesno "$prompt" $height $width 129} 130 131############################################################ MAIN 132 133f_dprintf "Began Installation at %s" "$( date )" 134 135rm -rf $BSDINSTALL_TMPETC 136mkdir $BSDINSTALL_TMPETC 137 138trap true SIGINT # This section is optional 139bsdinstall keymap 140 141trap error SIGINT # Catch cntrl-C here 142bsdinstall hostname || error "Set hostname failed" 143 144export DISTRIBUTIONS="base.txz kernel.txz" 145if [ -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')" 148 149 exec 3>&1 150 EXTRA_DISTS=$( eval dialog \ 151 --backtitle \"FreeBSD Installer\" \ 152 --title \"Distribution Select\" --nocancel --separate-output \ 153 --checklist \"Choose optional system components to install:\" \ 154 0 0 0 $DISTMENU \ 155 2>&1 1>&3 ) 156 for dist in $EXTRA_DISTS; do 157 export DISTRIBUTIONS="$DISTRIBUTIONS $dist.txz" 158 done 159fi 160 161LOCAL_DISTRIBUTIONS="MANIFEST" 162FETCH_DISTRIBUTIONS="" 163for dist in $DISTRIBUTIONS; do 164 if [ ! -f $BSDINSTALL_DISTDIR/$dist ]; then 165 FETCH_DISTRIBUTIONS="$FETCH_DISTRIBUTIONS $dist" 166 else 167 LOCAL_DISTRIBUTIONS="$LOCAL_DISTRIBUTIONS $dist" 168 fi 169done 170LOCAL_DISTRIBUTIONS=`echo $LOCAL_DISTRIBUTIONS` # Trim white space 171FETCH_DISTRIBUTIONS=`echo $FETCH_DISTRIBUTIONS` # Trim white space 172 173if [ -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 176 NETCONFIG_DONE=yes 177fi 178 179if [ -n "$FETCH_DISTRIBUTIONS" ]; then 180 exec 3>&1 181 BSDINSTALL_DISTSITE=$(`dirname $0`/mirrorselect 2>&1 1>&3) 182 MIRROR_BUTTON=$? 183 exec 3>&- 184 test $MIRROR_BUTTON -eq 0 || error "No mirror selected" 185 export BSDINSTALL_DISTSITE 186fi 187 188rm -f $PATH_FSTAB 189touch $PATH_FSTAB 190 191# 192# Try to detect known broken platforms and apply their workarounds 193# 194 195if 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" 206 207 # 208 # Laptop Models 209 # 210 case "$sys_maker" in 211 "LENOVO") 212 case "$sys_version" in 213 "ThinkPad X220"|"ThinkPad T420"|"ThinkPad T520"|"ThinkPad W520"|"ThinkPad X1") 214 dialog_workaround "$msg_lenovo_fix" 215 retval=$? 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 220 fi 221 ;; 222 esac 223 ;; 224 "Dell Inc.") 225 case "$sys_model" in 226 "Latitude E6330"|"Latitude E7440"|"Latitude E7240"|"Precision Tower 5810") 227 dialog_workaround "$msg_gpt_active_fix" 228 retval=$? 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 233 fi 234 ;; 235 esac 236 ;; 237 "Hewlett-Packard") 238 case "$sys_model" in 239 "HP ProBook 4330s") 240 dialog_workaround "$msg_gpt_active_fix" 241 retval=$? 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 246 fi 247 ;; 248 esac 249 ;; 250 esac 251 # 252 # Motherboard Models 253 # 254 case "$sys_mb_maker" in 255 "Intel Corporation") 256 case "$sys_mb_product" in 257 "DP965LT"|"D510MO") 258 dialog_workaround "$msg_gpt_active_fix" 259 retval=$? 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 264 fi 265 ;; 266 esac 267 ;; 268 "Acer") 269 case "$sys_mb_product" in 270 "Veriton M6630G") 271 dialog_workaround "$msg_gpt_active_fix" 272 retval=$? 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 277 fi 278 ;; 279 esac 280 ;; 281 esac 282fi 283 284PMODES="\ 285\"Auto (UFS)\" \"Guided Disk Setup\" \ 286Manual \"Manual Disk Setup (experts)\" \ 287Shell \"Open a shell and partition by hand\"" 288 289CURARCH=$( uname -m ) 290case $CURARCH in 291 amd64|arm64|i386) # Booting ZFS Supported 292 PMODES="$PMODES \"Auto (ZFS)\" \"Guided Root-on-ZFS\"" 293 ;; 294 *) # Booting ZFS Unspported 295 ;; 296esac 297 298exec 3>&1 299PARTMODE=`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 303exec 3>&- 304 305case "$PARTMODE" in 306"Auto (UFS)") # Guided 307 bsdinstall autopart || error "Partitioning error" 308 bsdinstall mount || error "Failed to mount filesystem" 309 ;; 310"Shell") # Shell 311 clear 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'." 313 sh 2>&1 314 ;; 315"Manual") # Manual 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" 319 else 320 bsdinstall partedit || error "Partitioning error" 321 fi 322 bsdinstall mount || error "Failed to mount filesystem" 323 ;; 324"Auto (ZFS)") # ZFS 325 bsdinstall zfsboot || error "ZFS setup failed" 326 bsdinstall mount || error "Failed to mount filesystem" 327 ;; 328*) 329 error "Unknown partitioning mode" 330 ;; 331esac 332 333if [ ! -z "$FETCH_DISTRIBUTIONS" ]; then 334 ALL_DISTRIBUTIONS="$DISTRIBUTIONS" 335 WANT_DEBUG= 336 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" 340 341 export DISTRIBUTIONS="$FETCH_DISTRIBUTIONS" 342 # Try to use any existing distfiles 343 if [ -d $BSDINSTALL_DISTDIR ]; then 344 DISTDIR_IS_UNIONFS=1 345 mount_nullfs -o union "$BSDINSTALL_FETCHDEST" "$BSDINSTALL_DISTDIR" 346 else 347 export DISTRIBUTIONS="$FETCH_DISTRIBUTIONS" 348 export BSDINSTALL_DISTDIR="$BSDINSTALL_FETCHDEST" 349 fi 350 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 356 *-dbg.*) 357 [ -e $BSDINSTALL_DISTDIR/$_DISTRIBUTION ] \ 358 && continue 359 WANT_DEBUG=1 360 DEBUG_LIST="\n$DEBUG_LIST\n$_DISTRIBUTION" 361 ;; 362 *) 363 ;; 364 esac 365 done 366 367 # Fetch the distributions. 368 bsdinstall distfetch 369 rc=$? 370 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" 384 fi 385 error "$msg" 386 fi 387 export DISTRIBUTIONS="$ALL_DISTRIBUTIONS" 388fi 389 390if [ ! -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 396 DISTDIR_IS_UNIONFS=1 397 mount_nullfs -o union "$BSDINSTALL_FETCHDEST" "$BSDINSTALL_DISTDIR" 398 export BSDINSTALL_DISTDIR="$BSDINSTALL_FETCHDEST" 399 fi 400 env DISTRIBUTIONS="$LOCAL_DISTRIBUTIONS" \ 401 BSDINSTALL_DISTSITE="file:///usr/freebsd-dist" \ 402 bsdinstall distfetch || \ 403 error "Failed to fetch distribution from local media" 404fi 405 406bsdinstall checksum || error "Distribution checksum failed" 407bsdinstall distextract || error "Distribution extract failed" 408 409# Set up boot loader 410bsdinstall bootconfig || error "Failed to configure bootloader" 411 412bsdinstall rootpass || error "Could not set root password" 413 414trap true SIGINT # This section is optional 415if [ "$NETCONFIG_DONE" != yes ]; then 416 bsdinstall netconfig # Don't check for errors -- the user may cancel 417fi 418bsdinstall time 419bsdinstall services 420bsdinstall hardening 421 422dialog --backtitle "FreeBSD Installer" --title "Add User Accounts" --yesno \ 423 "Would you like to add users to the installed system now?" 0 0 && \ 424 bsdinstall adduser 425 426finalconfig() { 427 exec 3>&1 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) 440 exec 3>&- 441 442 case "$REVISIT" in 443 "Add User") 444 bsdinstall adduser 445 finalconfig 446 ;; 447 "Root Password") 448 bsdinstall rootpass 449 finalconfig 450 ;; 451 "Hostname") 452 bsdinstall hostname 453 finalconfig 454 ;; 455 "Network") 456 bsdinstall netconfig 457 finalconfig 458 ;; 459 "Services") 460 bsdinstall services 461 finalconfig 462 ;; 463 "System Hardening") 464 bsdinstall hardening 465 finalconfig 466 ;; 467 "Time Zone") 468 bsdinstall time 469 finalconfig 470 ;; 471 "Handbook") 472 bsdinstall docsinstall 473 finalconfig 474 ;; 475 esac 476} 477 478# Allow user to change his mind 479finalconfig 480 481trap error SIGINT # SIGINT is bad again 482bsdinstall config || error "Failed to save config" 483 484if [ -n "$DISTDIR_IS_UNIONFS" ]; then 485 umount -f $BSDINSTALL_DISTDIR 486fi 487 488if [ ! -z "$BSDINSTALL_FETCHDEST" ]; then 489 rm -rf "$BSDINSTALL_FETCHDEST" 490fi 491 492dialog --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 495if [ $? -eq 0 ]; then 496 clear 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 500fi 501 502bsdinstall entropy 503bsdinstall umount 504 505f_dprintf "Installation Completed at %s" "$( date )" 506 507################################################################################ 508# END 509################################################################################ 510