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\.txz|base\.txz)/{print $1,$5,$6}' $BSDINSTALL_DISTDIR/MANIFEST` 119 DISTMENU="$(echo ${DISTMENU} | sed -E 's/\.txz//g')" 120 121 exec 3>&1 122 EXTRA_DISTS=$( eval dialog \ 123 --backtitle \"FreeBSD Installer\" \ 124 --title \"Distribution Select\" --nocancel --separate-output \ 125 --checklist \"Choose optional system components to install:\" \ 126 0 0 0 $DISTMENU \ 127 2>&1 1>&3 ) 128 for dist in $EXTRA_DISTS; do 129 export DISTRIBUTIONS="$DISTRIBUTIONS $dist.txz" 130 done 131fi 132 133LOCAL_DISTRIBUTIONS="MANIFEST" 134FETCH_DISTRIBUTIONS="" 135for dist in $DISTRIBUTIONS; do 136 if [ ! -f $BSDINSTALL_DISTDIR/$dist ]; then 137 FETCH_DISTRIBUTIONS="$FETCH_DISTRIBUTIONS $dist" 138 else 139 LOCAL_DISTRIBUTIONS="$LOCAL_DISTRIBUTIONS $dist" 140 fi 141done 142LOCAL_DISTRIBUTIONS=`echo $LOCAL_DISTRIBUTIONS` # Trim white space 143FETCH_DISTRIBUTIONS=`echo $FETCH_DISTRIBUTIONS` # Trim white space 144 145if [ -n "$FETCH_DISTRIBUTIONS" -a -n "$BSDINSTALL_CONFIGCURRENT" ]; then 146 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 147 bsdinstall netconfig || error 148 NETCONFIG_DONE=yes 149fi 150 151if [ -n "$FETCH_DISTRIBUTIONS" ]; then 152 exec 3>&1 153 BSDINSTALL_DISTSITE=$(`dirname $0`/mirrorselect 2>&1 1>&3) 154 MIRROR_BUTTON=$? 155 exec 3>&- 156 test $MIRROR_BUTTON -eq 0 || error "No mirror selected" 157 export BSDINSTALL_DISTSITE 158fi 159 160rm -f $PATH_FSTAB 161touch $PATH_FSTAB 162 163# 164# Try to detect known broken platforms and apply their workarounds 165# 166 167if f_interactive; then 168 sys_maker=$( kenv -q smbios.system.maker ) 169 f_dprintf "smbios.system.maker=[%s]" "$sys_maker" 170 sys_model=$( kenv -q smbios.system.product ) 171 f_dprintf "smbios.system.product=[%s]" "$sys_model" 172 sys_version=$( kenv -q smbios.system.version ) 173 f_dprintf "smbios.system.version=[%s]" "$sys_version" 174 sys_mb_maker=$( kenv -q smbios.planar.maker ) 175 f_dprintf "smbios.planar.maker=[%s]" "$sys_mb_maker" 176 sys_mb_product=$( kenv -q smbios.planar.product ) 177 f_dprintf "smbios.planar.product=[%s]" "$sys_mb_product" 178 179 # 180 # Laptop Models 181 # 182 case "$sys_maker" in 183 "LENOVO") 184 case "$sys_version" in 185 "ThinkPad X220"|"ThinkPad T420"|"ThinkPad T520"|"ThinkPad W520") 186 dialog_workaround "$msg_lenovo_fix" 187 retval=$? 188 f_dprintf "lenovofix_prompt=[%s]" "$retval" 189 if [ $retval -eq $DIALOG_OK ]; then 190 export ZFSBOOT_PARTITION_SCHEME="GPT + Lenovo Fix" 191 export WORKAROUND_LENOVO=1 192 fi 193 ;; 194 esac 195 ;; 196 "Dell Inc.") 197 case "$sys_model" in 198 "Latitude E6330"|"Latitude E7440"|"Latitude E7240"|"Precision Tower 5810") 199 dialog_workaround "$msg_gpt_active_fix" 200 retval=$? 201 f_dprintf "gpt_active_fix_prompt=[%s]" "$retval" 202 if [ $retval -eq $DIALOG_OK ]; then 203 export ZFSBOOT_PARTITION_SCHEME="GPT + Active" 204 export WORKAROUND_GPTACTIVE=1 205 fi 206 ;; 207 esac 208 ;; 209 "Hewlett-Packard") 210 case "$sys_model" in 211 "HP ProBook 4330s") 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 223 # 224 # Motherboard Models 225 # 226 case "$sys_mb_maker" in 227 "Intel Corporation") 228 case "$sys_mb_product" in 229 "DP965LT"|"D510MO") 230 dialog_workaround "$msg_gpt_active_fix" 231 retval=$? 232 f_dprintf "gpt_active_fix_prompt=[%s]" "$retval" 233 if [ $retval -eq $DIALOG_OK ]; then 234 export ZFSBOOT_PARTITION_SCHEME="GPT + Active" 235 export WORKAROUND_GPTACTIVE=1 236 fi 237 ;; 238 esac 239 ;; 240 "Acer") 241 case "$sys_mb_product" in 242 "Veriton M6630G") 243 dialog_workaround "$msg_gpt_active_fix" 244 retval=$? 245 f_dprintf "gpt_active_fix_prompt=[%s]" "$retval" 246 if [ $retval -eq $DIALOG_OK ]; then 247 export ZFSBOOT_PARTITION_SCHEME="GPT + Active" 248 export WORKAROUND_GPTACTIVE=1 249 fi 250 ;; 251 esac 252 ;; 253 esac 254fi 255 256PMODES="\ 257\"Auto (UFS)\" \"Guided Disk Setup\" \ 258Manual \"Manual Disk Setup (experts)\" \ 259Shell \"Open a shell and partition by hand\"" 260 261CURARCH=$( uname -m ) 262case $CURARCH in 263 amd64|i386) # Booting ZFS Supported 264 PMODES="$PMODES \"Auto (ZFS)\" \"Guided Root-on-ZFS\"" 265 ;; 266 *) # Booting ZFS Unspported 267 ;; 268esac 269 270exec 3>&1 271PARTMODE=`echo $PMODES | xargs dialog --backtitle "FreeBSD Installer" \ 272 --title "Partitioning" \ 273 --menu "How would you like to partition your disk?" \ 274 0 0 0 2>&1 1>&3` || exit 1 275exec 3>&- 276 277case "$PARTMODE" in 278"Auto (UFS)") # Guided 279 bsdinstall autopart || error "Partitioning error" 280 bsdinstall mount || error "Failed to mount filesystem" 281 ;; 282"Shell") # Shell 283 clear 284 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'." 285 sh 2>&1 286 ;; 287"Manual") # Manual 288 if f_isset debugFile; then 289 # Give partedit the path to our logfile so it can append 290 BSDINSTALL_LOG="${debugFile#+}" bsdinstall partedit || error "Partitioning error" 291 else 292 bsdinstall partedit || error "Partitioning error" 293 fi 294 bsdinstall mount || error "Failed to mount filesystem" 295 ;; 296"Auto (ZFS)") # ZFS 297 bsdinstall zfsboot || error "ZFS setup failed" 298 bsdinstall mount || error "Failed to mount filesystem" 299 ;; 300*) 301 error "Unknown partitioning mode" 302 ;; 303esac 304 305if [ ! -z "$FETCH_DISTRIBUTIONS" ]; then 306 ALL_DISTRIBUTIONS="$DISTRIBUTIONS" 307 WANT_DEBUG= 308 309 # Download to a directory in the new system as scratch space 310 BSDINSTALL_FETCHDEST="$BSDINSTALL_CHROOT/usr/freebsd-dist" 311 mkdir -p "$BSDINSTALL_FETCHDEST" || error "Could not create directory $BSDINSTALL_FETCHDEST" 312 313 export DISTRIBUTIONS="$FETCH_DISTRIBUTIONS" 314 # Try to use any existing distfiles 315 if [ -d $BSDINSTALL_DISTDIR ]; then 316 DISTDIR_IS_UNIONFS=1 317 mount_nullfs -o union "$BSDINSTALL_FETCHDEST" "$BSDINSTALL_DISTDIR" 318 else 319 export DISTRIBUTIONS="$FETCH_DISTRIBUTIONS" 320 export BSDINSTALL_DISTDIR="$BSDINSTALL_FETCHDEST" 321 fi 322 323 export FTP_PASSIVE_MODE=YES 324 # Iterate through the distribution list and set a flag if debugging 325 # distributions have been selected. 326 for _DISTRIBUTION in $DISTRIBUTIONS; do 327 case $_DISTRIBUTION in 328 *-dbg.*) 329 [ -e $BSDINSTALL_DISTDIR/$_DISTRIBUTION ] \ 330 && continue 331 WANT_DEBUG=1 332 DEBUG_LIST="\n$DEBUG_LIST\n$_DISTRIBUTION" 333 ;; 334 *) 335 ;; 336 esac 337 done 338 339 # Fetch the distributions. 340 bsdinstall distfetch 341 rc=$? 342 343 if [ $rc -ne 0 ]; then 344 # If unable to fetch the remote distributions, recommend 345 # deselecting the debugging distributions, and retrying the 346 # installation, since failure to fetch *-dbg.txz should not 347 # be considered a fatal installation error. 348 msg="Failed to fetch remote distribution" 349 if [ ! -z "$WANT_DEBUG" ]; then 350 # Trim leading and trailing newlines. 351 DEBUG_LIST="${DEBUG_LIST%%\n}" 352 DEBUG_LIST="${DEBUG_LIST##\n}" 353 msg="$msg\n\nPlease deselect the following distributions" 354 msg="$msg and retry the installation:" 355 msg="$msg\n$DEBUG_LIST" 356 fi 357 error "$msg" 358 fi 359 export DISTRIBUTIONS="$ALL_DISTRIBUTIONS" 360fi 361 362if [ ! -z "$LOCAL_DISTRIBUTIONS" ]; then 363 # Download to a directory in the new system as scratch space 364 BSDINSTALL_FETCHDEST="$BSDINSTALL_CHROOT/usr/freebsd-dist" 365 mkdir -p "$BSDINSTALL_FETCHDEST" || error "Could not create directory $BSDINSTALL_FETCHDEST" 366 # Try to use any existing distfiles 367 if [ -d $BSDINSTALL_DISTDIR ]; then 368 DISTDIR_IS_UNIONFS=1 369 mount_nullfs -o union "$BSDINSTALL_FETCHDEST" "$BSDINSTALL_DISTDIR" 370 export BSDINSTALL_DISTDIR="$BSDINSTALL_FETCHDEST" 371 fi 372 env DISTRIBUTIONS="$LOCAL_DISTRIBUTIONS" \ 373 BSDINSTALL_DISTSITE="file:///usr/freebsd-dist" \ 374 bsdinstall distfetch || \ 375 error "Failed to fetch distribution from local media" 376fi 377 378bsdinstall checksum || error "Distribution checksum failed" 379bsdinstall distextract || error "Distribution extract failed" 380bsdinstall rootpass || error "Could not set root password" 381 382trap true SIGINT # This section is optional 383if [ "$NETCONFIG_DONE" != yes ]; then 384 bsdinstall netconfig # Don't check for errors -- the user may cancel 385fi 386bsdinstall time 387bsdinstall services 388bsdinstall hardening 389 390dialog --backtitle "FreeBSD Installer" --title "Add User Accounts" --yesno \ 391 "Would you like to add users to the installed system now?" 0 0 && \ 392 bsdinstall adduser 393 394finalconfig() { 395 exec 3>&1 396 REVISIT=$(dialog --backtitle "FreeBSD Installer" \ 397 --title "Final Configuration" --no-cancel --menu \ 398 "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 \ 399 "Exit" "Apply configuration and exit installer" \ 400 "Add User" "Add a user to the system" \ 401 "Root Password" "Change root password" \ 402 "Hostname" "Set system hostname" \ 403 "Network" "Networking configuration" \ 404 "Services" "Set daemons to run on startup" \ 405 "System Hardening" "Set security options" \ 406 "Time Zone" "Set system timezone" \ 407 "Handbook" "Install FreeBSD Handbook (requires network)" 2>&1 1>&3) 408 exec 3>&- 409 410 case "$REVISIT" in 411 "Add User") 412 bsdinstall adduser 413 finalconfig 414 ;; 415 "Root Password") 416 bsdinstall rootpass 417 finalconfig 418 ;; 419 "Hostname") 420 bsdinstall hostname 421 finalconfig 422 ;; 423 "Network") 424 bsdinstall netconfig 425 finalconfig 426 ;; 427 "Services") 428 bsdinstall services 429 finalconfig 430 ;; 431 "System Hardening") 432 bsdinstall hardening 433 finalconfig 434 ;; 435 "Time Zone") 436 bsdinstall time 437 finalconfig 438 ;; 439 "Handbook") 440 bsdinstall docsinstall 441 finalconfig 442 ;; 443 esac 444} 445 446# Allow user to change his mind 447finalconfig 448 449trap error SIGINT # SIGINT is bad again 450bsdinstall config || error "Failed to save config" 451 452if [ ! -z "$BSDINSTALL_FETCHDEST" ]; then 453 [ "$BSDINSTALL_FETCHDEST" != "$BSDINSTALL_DISTDIR" ] && \ 454 umount "$BSDINSTALL_DISTDIR" 455 rm -rf "$BSDINSTALL_FETCHDEST" 456fi 457 458dialog --backtitle "FreeBSD Installer" --title "Manual Configuration" \ 459 --default-button no --yesno \ 460 "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 461if [ $? -eq 0 ]; then 462 clear 463 mount -t devfs devfs "$BSDINSTALL_CHROOT/dev" 464 echo This shell is operating in a chroot in the new system. \ 465 When finished making configuration changes, type \"exit\". 466 chroot "$BSDINSTALL_CHROOT" /bin/sh 2>&1 467fi 468 469bsdinstall entropy 470bsdinstall umount 471 472f_dprintf "Installation Completed at %s" "$( date )" 473 474################################################################################ 475# END 476################################################################################ 477