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