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# 29############################################################ INCLUDES 30 31BSDCFG_SHARE="/usr/share/bsdconfig" 32. $BSDCFG_SHARE/common.subr || exit 1 33f_include $BSDCFG_SHARE/dialog.subr 34 35############################################################ GLOBALS 36 37# 38# Strings that should be moved to an i18n file and loaded with f_include_lang() 39# 40hline_arrows_tab_enter="Press arrows, TAB or ENTER" 41hline_arrows_tab_space_enter="Press arrows, TAB, SPACE or ENTER" 42msg_abort="Abort" 43msg_an_installation_step_has_been_aborted="An installation step has been aborted. Would you like\nto restart the installation or exit the installer?" 44msg_auto_ufs="Auto (UFS)" 45msg_auto_ufs_desc="Guided UFS Disk Setup" 46msg_auto_ufs_help="Menu options help choose which disk to setup using UFS and standard partitions" 47msg_auto_zfs="Auto (ZFS)" 48msg_auto_zfs_desc="Guided Root-on-ZFS" 49msg_auto_zfs_help="To use ZFS with less than 8GB RAM, see https://wiki.freebsd.org/ZFSTuningGuide" 50msg_exit="Exit" 51msg_freebsd_installer="$OSNAME Installer" 52msg_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?" 53msg_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?" 54msg_manual="Manual" 55msg_manual_desc="Manual Disk Setup (experts)" 56msg_manual_help="Create customized partitions from menu options" 57msg_no="NO" 58msg_restart="Restart" 59msg_shell="Shell" 60msg_shell_desc="Open a shell and partition by hand" 61msg_shell_help="Create customized partitions using command-line utilities" 62msg_yes="YES" 63 64############################################################ FUNCTIONS 65 66# error [$msg] 67# 68# Display generic error message when a script fails. An optional message 69# argument can preceed the generic message. User is given the choice of 70# restarting the installer or exiting. 71# 72error() 73{ 74 local title="$msg_abort" 75 local btitle="$msg_freebsd_installer" 76 local prompt="${1:+$1\n\n}$msg_an_installation_step_has_been_aborted" 77 local hline="$hline_arrows_tab_space_enter" 78 79 [ -f "$PATH_FSTAB" ] && bsdinstall umount 80 81 local height width 82 f_dialog_buttonbox_size height width \ 83 "$title" "$btitle" "$prompt" "$hline" 84 85 if $DIALOG \ 86 --title "$title" \ 87 --backtitle "$btitle" \ 88 --hline "$hline" \ 89 --no-label "$msg_exit" \ 90 --yes-label "$msg_restart" \ 91 --yesno "$prompt" $height $width 92 then 93 exec $0 94 # NOTREACHED 95 fi 96 exit 1 97} 98 99# dialog_workaround 100# 101# Ask the user if they wish to apply a workaround 102# 103dialog_workaround() 104{ 105 local passed_msg="$1" 106 local title="$DIALOG_TITLE" 107 local btitle="$DIALOG_BACKTITLE" 108 local prompt # Calculated below 109 local hline="$hline_arrows_tab_enter" 110 111 local height=8 width=50 prefix=" " 112 local plen=${#prefix} list= line= 113 local max_width=$(( $width - 3 - $plen )) 114 115 local yes no defaultno extra_args format 116 if [ "$USE_XDIALOG" ]; then 117 yes=ok no=cancel defaultno=default-no 118 extra_args="--wrap --left" 119 format="$passed_msg" 120 else 121 yes=yes no=no defaultno=defaultno 122 extra_args="--cr-wrap" 123 format="$passed_msg" 124 fi 125 126 # Add height for Xdialog(1) 127 [ "$USE_XDIALOG" ] && height=$(( $height + $height / 5 + 3 )) 128 129 prompt=$( printf "$format" ) 130 f_dprintf "%s: Workaround prompt" "$0" 131 $DIALOG \ 132 --title "$title" \ 133 --backtitle "$btitle" \ 134 --hline "$hline" \ 135 --$yes-label "$msg_yes" \ 136 --$no-label "$msg_no" \ 137 $extra_args \ 138 --yesno "$prompt" $height $width 139} 140 141############################################################ MAIN 142 143f_dprintf "Began Installation at %s" "$( date )" 144 145rm -rf $BSDINSTALL_TMPETC 146mkdir $BSDINSTALL_TMPETC 147 148[ -f /usr/libexec/bsdinstall/local.pre-everything ] && f_dprintf "Running local.pre-everything" && sh /usr/libexec/bsdinstall/local.pre-everything "$BSDINSTALL_CHROOT" 149 150trap true SIGINT # This section is optional 151[ -z "$BSDINSTALL_SKIP_KEYMAP" ] && bsdinstall keymap 152 153trap error SIGINT # Catch cntrl-C here 154if [ -z "$BSDINSTALL_SKIP_HOSTNAME" ]; then bsdinstall hostname || error "Set hostname failed"; fi 155 156export DISTRIBUTIONS="${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 if [ -n "$DISTMENU" ]; then 162 exec 3>&1 163 EXTRA_DISTS=$( eval dialog \ 164 --backtitle \"$OSNAME Installer\" \ 165 --title \"Distribution Select\" --nocancel --separate-output \ 166 --checklist \"Choose optional system components to install:\" \ 167 0 0 0 $DISTMENU \ 168 2>&1 1>&3 ) 169 for dist in $EXTRA_DISTS; do 170 export DISTRIBUTIONS="$DISTRIBUTIONS $dist.txz" 171 done 172 fi 173fi 174 175FETCH_DISTRIBUTIONS="" 176for dist in $DISTRIBUTIONS; do 177 if [ ! -f $BSDINSTALL_DISTDIR/$dist ]; then 178 FETCH_DISTRIBUTIONS="$FETCH_DISTRIBUTIONS $dist" 179 fi 180done 181 182if [ -n "$FETCH_DISTRIBUTIONS" -a -n "$BSDINSTALL_CONFIGCURRENT" ]; then 183 dialog --backtitle "$OSNAME 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 184 bsdinstall netconfig || error 185 NETCONFIG_DONE=yes 186fi 187 188rm -f $PATH_FSTAB 189touch $PATH_FSTAB 190 191[ -f /usr/libexec/bsdinstall/local.pre-partition ] && f_dprintf "Running local.pre-partition" && sh /usr/libexec/bsdinstall/local.pre-partition "$BSDINSTALL_CHROOT" 192 193# 194# Try to detect known broken platforms and apply their workarounds 195# 196 197if f_interactive; then 198 sys_maker=$( kenv -q smbios.system.maker ) 199 f_dprintf "smbios.system.maker=[%s]" "$sys_maker" 200 sys_model=$( kenv -q smbios.system.product ) 201 f_dprintf "smbios.system.product=[%s]" "$sys_model" 202 sys_version=$( kenv -q smbios.system.version ) 203 f_dprintf "smbios.system.version=[%s]" "$sys_version" 204 sys_mb_maker=$( kenv -q smbios.planar.maker ) 205 f_dprintf "smbios.planar.maker=[%s]" "$sys_mb_maker" 206 sys_mb_product=$( kenv -q smbios.planar.product ) 207 f_dprintf "smbios.planar.product=[%s]" "$sys_mb_product" 208 209 # 210 # Laptop Models 211 # 212 case "$sys_maker" in 213 "LENOVO") 214 case "$sys_version" in 215 "ThinkPad X220"|"ThinkPad T420"|"ThinkPad T520"|"ThinkPad W520"|"ThinkPad X1") 216 dialog_workaround "$msg_lenovo_fix" 217 retval=$? 218 f_dprintf "lenovofix_prompt=[%s]" "$retval" 219 if [ $retval -eq $DIALOG_OK ]; then 220 export ZFSBOOT_PARTITION_SCHEME="GPT + Lenovo Fix" 221 export WORKAROUND_LENOVO=1 222 fi 223 ;; 224 esac 225 ;; 226 "Dell Inc.") 227 case "$sys_model" in 228 "Latitude E6330"|"Latitude E7440"|"Latitude E7240"|"Precision Tower 5810") 229 dialog_workaround "$msg_gpt_active_fix" 230 retval=$? 231 f_dprintf "gpt_active_fix_prompt=[%s]" "$retval" 232 if [ $retval -eq $DIALOG_OK ]; then 233 export ZFSBOOT_PARTITION_SCHEME="GPT + Active" 234 export WORKAROUND_GPTACTIVE=1 235 fi 236 ;; 237 esac 238 ;; 239 "Hewlett-Packard") 240 case "$sys_model" in 241 "HP ProBook 4330s") 242 dialog_workaround "$msg_gpt_active_fix" 243 retval=$? 244 f_dprintf "gpt_active_fix_prompt=[%s]" "$retval" 245 if [ $retval -eq $DIALOG_OK ]; then 246 export ZFSBOOT_PARTITION_SCHEME="GPT + Active" 247 export WORKAROUND_GPTACTIVE=1 248 fi 249 ;; 250 esac 251 ;; 252 esac 253 # 254 # Motherboard Models 255 # 256 case "$sys_mb_maker" in 257 "Intel Corporation") 258 case "$sys_mb_product" in 259 "DP965LT"|"D510MO") 260 dialog_workaround "$msg_gpt_active_fix" 261 retval=$? 262 f_dprintf "gpt_active_fix_prompt=[%s]" "$retval" 263 if [ $retval -eq $DIALOG_OK ]; then 264 export ZFSBOOT_PARTITION_SCHEME="GPT + Active" 265 export WORKAROUND_GPTACTIVE=1 266 fi 267 ;; 268 esac 269 ;; 270 "Acer") 271 case "$sys_mb_product" in 272 "Veriton M6630G") 273 dialog_workaround "$msg_gpt_active_fix" 274 retval=$? 275 f_dprintf "gpt_active_fix_prompt=[%s]" "$retval" 276 if [ $retval -eq $DIALOG_OK ]; then 277 export ZFSBOOT_PARTITION_SCHEME="GPT + Active" 278 export WORKAROUND_GPTACTIVE=1 279 fi 280 ;; 281 esac 282 ;; 283 esac 284fi 285 286PMODES=" 287 '$msg_auto_ufs' '$msg_auto_ufs_desc' '$msg_auto_ufs_help' 288 '$msg_manual' '$msg_manual_desc' '$msg_manual_help' 289 '$msg_shell' '$msg_shell_desc' '$msg_shell_help' 290" # END-QUOTE 291 292CURARCH=$( uname -m ) 293case $CURARCH in 294 amd64|arm64|i386|riscv) # Booting ZFS Supported 295 PMODES=" 296 '$msg_auto_zfs' '$msg_auto_zfs_desc' '$msg_auto_zfs_help' 297 $PMODES 298 " # END-QUOTE 299 ;; 300 *) # Booting ZFS Unsupported 301 ;; 302esac 303 304exec 3>&1 305PARTMODE=`echo $PMODES | xargs dialog --backtitle "$OSNAME Installer" \ 306 --title "Partitioning" \ 307 --item-help \ 308 --menu "How would you like to partition your disk?" \ 309 0 0 0 2>&1 1>&3` || exit 1 310exec 3>&- 311 312case "$PARTMODE" in 313"$msg_auto_zfs") # ZFS 314 bsdinstall zfsboot || error "ZFS setup failed" 315 bsdinstall mount || error "Failed to mount filesystem" 316 ;; 317"$msg_auto_ufs") # Guided UFS 318 bsdinstall autopart || error "Partitioning error" 319 bsdinstall mount || error "Failed to mount filesystem" 320 ;; 321"$msg_shell") # Shell 322 clear 323 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'." 324 sh 2>&1 325 ;; 326"$msg_manual") # Manual 327 if f_isset debugFile; then 328 # Give partedit the path to our logfile so it can append 329 BSDINSTALL_LOG="${debugFile#+}" bsdinstall partedit || error "Partitioning error" 330 else 331 bsdinstall partedit || error "Partitioning error" 332 fi 333 bsdinstall mount || error "Failed to mount filesystem" 334 ;; 335*) 336 error "Unknown partitioning mode" 337 ;; 338esac 339 340[ -f /usr/libexec/bsdinstall/local.pre-fetch ] && f_dprintf "Running local.pre-fetch" && sh /usr/libexec/bsdinstall/local.pre-fetch "$BSDINSTALL_CHROOT" 341 342if [ -n "$FETCH_DISTRIBUTIONS" ]; then 343 exec 3>&1 344 export BSDINSTALL_DISTDIR=$(`dirname $0`/fetchmissingdists 2>&1 1>&3) 345 FETCH_RESULT=$? 346 exec 3>&- 347 348 [ $FETCH_RESULT -ne 0 ] && error "Could not fetch remote distributions" 349fi 350bsdinstall checksum || error "Distribution checksum failed" 351bsdinstall distextract || error "Distribution extract failed" 352 353# Set up boot loader 354bsdinstall bootconfig || error "Failed to configure bootloader" 355 356[ -f /usr/libexec/bsdinstall/local.pre-configure ] && f_dprintf "Running local.pre-configure" && sh /usr/libexec/bsdinstall/local.pre-configure "$BSDINSTALL_CHROOT" 357 358bsdinstall rootpass || error "Could not set root password" 359 360trap true SIGINT # This section is optional 361if [ "$NETCONFIG_DONE" != yes ]; then 362 bsdinstall netconfig # Don't check for errors -- the user may cancel 363fi 364[ -z "$BSDINSTALL_SKIP_TIME" ] && bsdinstall time 365[ -z "$BSDINSTALL_SKIP_SERVICES" ] && bsdinstall services 366[ -z "$BSDINSTALL_SKIP_HARDENING" ] && bsdinstall hardening 367 368[ -z "$BSDINSTALL_SKIP_USERS" ] && dialog --backtitle "$OSNAME Installer" \ 369 --title "Add User Accounts" --yesno \ 370 "Would you like to add users to the installed system now?" 0 0 && \ 371 bsdinstall adduser 372 373finalconfig() { 374 exec 3>&1 375 REVISIT=$(dialog --backtitle "$OSNAME Installer" \ 376 --title "Final Configuration" --no-cancel --menu \ 377 "Setup of your $OSNAME 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 \ 378 "Exit" "Apply configuration and exit installer" \ 379 "Add User" "Add a user to the system" \ 380 "Root Password" "Change root password" \ 381 "Hostname" "Set system hostname" \ 382 "Network" "Networking configuration" \ 383 "Services" "Set daemons to run on startup" \ 384 "System Hardening" "Set security options" \ 385 "Time Zone" "Set system timezone" \ 386 "Handbook" "Install $OSNAME Handbook (requires network)" 2>&1 1>&3) 387 exec 3>&- 388 389 case "$REVISIT" in 390 "Add User") 391 bsdinstall adduser 392 finalconfig 393 ;; 394 "Root Password") 395 bsdinstall rootpass 396 finalconfig 397 ;; 398 "Hostname") 399 bsdinstall hostname 400 finalconfig 401 ;; 402 "Network") 403 bsdinstall netconfig 404 finalconfig 405 ;; 406 "Services") 407 bsdinstall services 408 finalconfig 409 ;; 410 "System Hardening") 411 bsdinstall hardening 412 finalconfig 413 ;; 414 "Time Zone") 415 bsdinstall time 416 finalconfig 417 ;; 418 "Handbook") 419 bsdinstall docsinstall 420 finalconfig 421 ;; 422 esac 423} 424 425# Allow user to change his mind 426[ -z "$BSDINSTALL_SKIP_FINALCONFIG" ] && finalconfig 427 428trap error SIGINT # SIGINT is bad again 429bsdinstall config || error "Failed to save config" 430 431if [ ! -z "$BSDINSTALL_FETCHDEST" ]; then 432 rm -rf "$BSDINSTALL_FETCHDEST" 433fi 434 435[ -f /usr/libexec/bsdinstall/local.post-configure ] && f_dprintf "Running local.post-configure" && sh /usr/libexec/bsdinstall/local.post-configure "$BSDINSTALL_CHROOT" 436 437if [ -z "$BSDINSTALL_SKIP_MANUAL" ]; then 438 dialog --backtitle "$OSNAME Installer" --title "Manual Configuration" \ 439 --default-button no --yesno \ 440 "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 441 if [ $? -eq 0 ]; then 442 clear 443 echo This shell is operating in a chroot in the new system. \ 444 When finished making configuration changes, type \"exit\". 445 chroot "$BSDINSTALL_CHROOT" /bin/sh 2>&1 446 fi 447fi 448 449bsdinstall entropy 450bsdinstall umount 451 452f_dprintf "Installation Completed at %s" "$( date )" 453 454################################################################################ 455# END 456################################################################################ 457