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