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 156bsddialog --backtitle "$OSNAME Installer" --title "Select Installation Type" \ 157 --yes-label "Traditional" --no-label "Packages (Experimental)" --yesno \ 158 "Would you like to install the base system using traditional distribution sets or packages (experimental)?" 0 0 159if [ $? -eq 1 ]; then 160 PKGBASE=yes 161fi 162 163if [ "$PKGBASE" == yes ]; then 164 bsddialog --backtitle "$OSNAME Installer" --title "Network Installation" \ 165 --msgbox "Installation of base system packages currently requires internet access. The next few screens will allow you to configure networking." 0 0 166 bsdinstall netconfig || error 167 NETCONFIG_DONE=yes 168else 169 export DISTRIBUTIONS="${DISTRIBUTIONS:-base.txz kernel.txz}" 170 if [ -f $BSDINSTALL_DISTDIR/MANIFEST ]; then 171 DISTMENU=`awk -F'\t' '!/^(kernel\.txz|base\.txz)/{print $1,$5,$6}' $BSDINSTALL_DISTDIR/MANIFEST` 172 DISTMENU="$(echo ${DISTMENU} | sed -E 's/\.txz//g')" 173 174 if [ -n "$DISTMENU" ]; then 175 exec 5>&1 176 EXTRA_DISTS=$( eval bsddialog \ 177 --backtitle \"$OSNAME Installer\" \ 178 --title \"Distribution Select\" --nocancel --separate-output \ 179 --checklist \"Choose optional system components to install:\" \ 180 0 0 0 $DISTMENU \ 181 2>&1 1>&5 ) 182 for dist in $EXTRA_DISTS; do 183 export DISTRIBUTIONS="$DISTRIBUTIONS $dist.txz" 184 done 185 fi 186 fi 187 188 FETCH_DISTRIBUTIONS="" 189 for dist in $DISTRIBUTIONS; do 190 if [ ! -f $BSDINSTALL_DISTDIR/$dist ]; then 191 FETCH_DISTRIBUTIONS="$FETCH_DISTRIBUTIONS $dist" 192 fi 193 done 194 195 if [ -n "$FETCH_DISTRIBUTIONS" -a -n "$BSDINSTALL_CONFIGCURRENT" ]; then 196 bsddialog --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 197 bsdinstall netconfig || error 198 NETCONFIG_DONE=yes 199 fi 200fi 201 202rm -f $PATH_FSTAB 203touch $PATH_FSTAB 204 205[ -f /usr/libexec/bsdinstall/local.pre-partition ] && f_dprintf "Running local.pre-partition" && sh /usr/libexec/bsdinstall/local.pre-partition "$BSDINSTALL_CHROOT" 206 207# 208# Try to detect known broken platforms and apply their workarounds 209# 210 211if f_interactive; then 212 sys_maker=$( kenv -q smbios.system.maker ) 213 f_dprintf "smbios.system.maker=[%s]" "$sys_maker" 214 sys_model=$( kenv -q smbios.system.product ) 215 f_dprintf "smbios.system.product=[%s]" "$sys_model" 216 sys_version=$( kenv -q smbios.system.version ) 217 f_dprintf "smbios.system.version=[%s]" "$sys_version" 218 sys_mb_maker=$( kenv -q smbios.planar.maker ) 219 f_dprintf "smbios.planar.maker=[%s]" "$sys_mb_maker" 220 sys_mb_product=$( kenv -q smbios.planar.product ) 221 f_dprintf "smbios.planar.product=[%s]" "$sys_mb_product" 222 223 # 224 # Laptop Models 225 # 226 case "$sys_maker" in 227 "LENOVO") 228 case "$sys_version" in 229 "ThinkPad X220"|"ThinkPad T420"|"ThinkPad T520"|"ThinkPad W520"|"ThinkPad X1") 230 dialog_workaround "$msg_lenovo_fix" 231 retval=$? 232 f_dprintf "lenovofix_prompt=[%s]" "$retval" 233 if [ $retval -eq $DIALOG_OK ]; then 234 export ZFSBOOT_PARTITION_SCHEME="GPT + Lenovo Fix" 235 export WORKAROUND_LENOVO=1 236 fi 237 ;; 238 esac 239 ;; 240 "Dell Inc.") 241 case "$sys_model" in 242 "Latitude E6330"|"Latitude E7440"|"Latitude E7240"|"Precision Tower 5810") 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 "Hewlett-Packard") 254 case "$sys_model" in 255 "HP ProBook 4330s") 256 dialog_workaround "$msg_gpt_active_fix" 257 retval=$? 258 f_dprintf "gpt_active_fix_prompt=[%s]" "$retval" 259 if [ $retval -eq $DIALOG_OK ]; then 260 export ZFSBOOT_PARTITION_SCHEME="GPT + Active" 261 export WORKAROUND_GPTACTIVE=1 262 fi 263 ;; 264 esac 265 ;; 266 esac 267 # 268 # Motherboard Models 269 # 270 case "$sys_mb_maker" in 271 "Intel Corporation") 272 case "$sys_mb_product" in 273 "DP965LT"|"D510MO") 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 "Acer") 285 case "$sys_mb_product" in 286 "Veriton M6630G") 287 dialog_workaround "$msg_gpt_active_fix" 288 retval=$? 289 f_dprintf "gpt_active_fix_prompt=[%s]" "$retval" 290 if [ $retval -eq $DIALOG_OK ]; then 291 export ZFSBOOT_PARTITION_SCHEME="GPT + Active" 292 export WORKAROUND_GPTACTIVE=1 293 fi 294 ;; 295 esac 296 ;; 297 esac 298fi 299 300PMODES=" 301 '$msg_auto_ufs' '$msg_auto_ufs_desc' '$msg_auto_ufs_help' 302 '$msg_manual' '$msg_manual_desc' '$msg_manual_help' 303 '$msg_shell' '$msg_shell_desc' '$msg_shell_help' 304" # END-QUOTE 305 306CURARCH=$( uname -m ) 307case $CURARCH in 308 amd64|arm64|i386|riscv) # Booting ZFS Supported 309 PMODES=" 310 '$msg_auto_zfs' '$msg_auto_zfs_desc' '$msg_auto_zfs_help' 311 $PMODES 312 " # END-QUOTE 313 ;; 314 *) # Booting ZFS Unsupported 315 ;; 316esac 317 318exec 5>&1 319PARTMODE=`echo $PMODES | xargs -o bsddialog --backtitle "$OSNAME Installer" \ 320 --title "Partitioning" \ 321 --item-help \ 322 --menu "How would you like to partition your disk?" \ 323 0 0 0 2>&1 1>&5` || exit 1 324exec 5>&- 325 326case "$PARTMODE" in 327"$msg_auto_zfs") # ZFS 328 bsdinstall zfsboot || error "ZFS setup failed" 329 bsdinstall mount || error "Failed to mount filesystem" 330 ;; 331"$msg_auto_ufs") # Guided UFS 332 bsdinstall autopart || error "Partitioning error" 333 bsdinstall mount || error "Failed to mount filesystem" 334 ;; 335"$msg_shell") # Shell 336 clear 337 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'." 338 sh 2>&1 339 ;; 340"$msg_manual") # Manual 341 if f_isset debugFile; then 342 # Give partedit the path to our logfile so it can append 343 BSDINSTALL_LOG="${debugFile#+}" bsdinstall partedit || error "Partitioning error" 344 else 345 bsdinstall partedit || error "Partitioning error" 346 fi 347 bsdinstall mount || error "Failed to mount filesystem" 348 ;; 349*) 350 error "Unknown partitioning mode" 351 ;; 352esac 353 354[ -f /usr/libexec/bsdinstall/local.pre-fetch ] && f_dprintf "Running local.pre-fetch" && sh /usr/libexec/bsdinstall/local.pre-fetch "$BSDINSTALL_CHROOT" 355 356if [ "$PKGBASE" == yes ]; then 357 bsdinstall pkgbase || error "Installation of base system packages failed" 358else 359 if [ -n "$FETCH_DISTRIBUTIONS" ]; then 360 exec 5>&1 361 export BSDINSTALL_DISTDIR=$(`dirname $0`/fetchmissingdists 2>&1 1>&5) 362 FETCH_RESULT=$? 363 exec 5>&- 364 365 [ $FETCH_RESULT -ne 0 ] && error "Could not fetch remote distributions" 366 fi 367 bsdinstall checksum || error "Distribution checksum failed" 368 bsdinstall distextract || error "Distribution extract failed" 369fi 370 371# Set up boot loader 372bsdinstall bootconfig || error "Failed to configure bootloader" 373 374[ -f /usr/libexec/bsdinstall/local.pre-configure ] && f_dprintf "Running local.pre-configure" && sh /usr/libexec/bsdinstall/local.pre-configure "$BSDINSTALL_CHROOT" 375 376bsdinstall rootpass || error "Could not set root password" 377 378trap true SIGINT # This section is optional 379if [ "$NETCONFIG_DONE" != yes ]; then 380 bsdinstall netconfig # Don't check for errors -- the user may cancel 381fi 382[ -z "$BSDINSTALL_SKIP_TIME" ] && bsdinstall time 383[ -z "$BSDINSTALL_SKIP_SERVICES" ] && bsdinstall services 384[ -z "$BSDINSTALL_SKIP_HARDENING" ] && bsdinstall hardening 385[ -z "$BSDINSTALL_SKIP_FIRMWARE" ] && bsdinstall firmware 386 387[ -z "$BSDINSTALL_SKIP_USERS" ] && bsddialog --backtitle "$OSNAME Installer" \ 388 --title "Add User Accounts" --yesno \ 389 "Would you like to add users to the installed system now?" 0 0 && \ 390 bsdinstall adduser 391 392# Allow user to change his mind 393[ -z "$BSDINSTALL_SKIP_FINALCONFIG" ] && bsdinstall finalconfig 394 395trap error SIGINT # SIGINT is bad again 396bsdinstall config || error "Failed to save config" 397 398if [ ! -z "$BSDINSTALL_FETCHDEST" ]; then 399 rm -rf "$BSDINSTALL_FETCHDEST" 400fi 401 402[ -f /usr/libexec/bsdinstall/local.post-configure ] && f_dprintf "Running local.post-configure" && sh /usr/libexec/bsdinstall/local.post-configure "$BSDINSTALL_CHROOT" 403 404if [ -z "$BSDINSTALL_SKIP_MANUAL" ]; then 405 bsddialog --backtitle "$OSNAME Installer" --title "Manual Configuration" \ 406 --default-no --yesno \ 407 "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 408 if [ $? -eq 0 ]; then 409 clear 410 echo This shell is operating in a chroot in the new system. \ 411 When finished making configuration changes, type \"exit\". 412 chroot "$BSDINSTALL_CHROOT" /bin/sh 2>&1 413 fi 414fi 415 416bsdinstall entropy 417bsdinstall umount 418 419f_dprintf "Installation Completed at %s" "$( date )" 420 421################################################################################ 422# END 423################################################################################ 424