1652 lines · 57.4 KB · Text
RawDownload
#!/bin/bashset -uo pipefail  ################################################# Initialize script environment # Find the directory this script is stored in. (from: http://stackoverflow.com/questions/59895)function get_source_dir() {	local source="${BASH_SOURCE[0]}"	while [[ -h $source ]]; do		local tmp		tmp="$(cd -P "$(dirname "${source}")" && pwd)"		source="$(readlink "${source}")"		[[ $source != /* ]] && source="${tmp}/${source}"	done 	echo -n "$(realpath "$(dirname "${source}")")"} GENTOO_INSTALL_REPO_DIR="$(get_source_dir)"export GENTOO_INSTALL_REPO_DIRexport GENTOO_INSTALL_REPO_SCRIPT_ACTIVE=true # shellcheck source=./scripts/utils.shsource "$GENTOO_INSTALL_REPO_DIR/scripts/utils.sh" # Remember actual config file pathCONFIG_FILE="$(realpath "${1-"gentoo.conf"}" 2>/dev/null)"RELA_CONFIG_FILE="$(realpath --relative-to="$(pwd)" "$CONFIG_FILE" 2>/dev/null)" # Check if help is requestedwhile [[ $# -gt 0 ]]; do	case "$1" in		""|"help"|"--help"|"-help"|"-h")			echo "Usage: $0 [config]"			echo "Starts the gentoo configurator. If no file is given, it defaults to 'gentoo.conf'."			echo "If the file doesn't exist, the configurator loads default values, otherwise, the"			echo "the configuration is loaded into the configurator."			exit 0			;;	esac	shiftdone check_wanted_programs dialog ncurses=ncursesw6-config # Determine whether EFI is availableHAS_EFI_SUPPORT=$([[ -d /sys/firmware/efi ]] && echo -n "true" || echo -n "false")DEFAULT_BOOT_TYPE=$([[ $HAS_EFI_SUPPORT == true ]] && echo -n "efi" || echo -n "bios")EFI_UNSUPPORTED_MESSAGE_SHORT="Missing EFI support on this system!"EFI_UNSUPPORTED_MESSAGE="Apparently, your system does NOT support efi. Double-check before proceeding!" # Wrap dialog in two functions to prevent it from cluttering stderr.function dialog_wrapper() { dialog_out=$(command dialog --colors "$@" 3>&2 2>&1 1>&3 3>&-); }function dialog() { dialog_wrapper "$@" 2>&1; }  ################################################# Configuration helper functions function get_timezone() {	local file	if file="$(readlink /etc/localtime)"; then		# /etc/localtime is a symlink as expected		local timezone		timezone=${file#*zoneinfo/}		if [[ $timezone == "$file" ]]; then			# not pointing to expected location or not Region/City			echo "Europe/London"		else			echo "$timezone"		fi	else		# compare files by contents		find /usr/share/zoneinfo -type f -exec cmp -s {} /etc/localtime \; -print \			| sed -e 's,.*/zoneinfo/,,' \			| head -1	fi} function get_default_keymap() {	local keymap	keymap="$(grep KEYMAP /etc/vconsole.conf 2>/dev/null || echo "KEYMAP=us")"	keymap="${keymap#KEYMAP=}" 	local map	for map in "${ALL_KEYMAPS[@]}"; do		if [[ $map == "$keymap" ]]; then			echo -n "${keymap}"			return		fi	done 	# Fallback to us	echo -n "us"} function get_all_keymaps() {	ALL_KEYMAPS=()	local map	for map in $(find /usr/share/keymaps/ /usr/share/kbd/keymaps/ -type f -iname '*.map.gz' -printf "%f\n" 2>/dev/null | sort -u); do		ALL_KEYMAPS+=("${map%%.map.gz}")	done} function get_all_timezones() {	readarray -t ALL_TIMEZONES < <(find /usr/share/zoneinfo -type f -printf "%P\n" | sort -u)} function recalculate_locales() {	LOCALES=""	N_LOCALES=0 	local selected_index_list="$SELECTED_LOCALES"	local next_selected	next_selected="${selected_index_list%% *}"	selected_index_list="${selected_index_list#* }" 	local i=0	for item in "${SUPPORTED_LOCALES[@]}"; do		if [[ "$i" == "$next_selected" ]]; then			LOCALES="$LOCALES"$'\n'"$item"			next_selected="${selected_index_list%% *}"			selected_index_list="${selected_index_list#* }"			((++N_LOCALES))		fi		((++i))	done 	LOCALES="${LOCALES:1}"} function define_disk_configuration_function() {	cat << EOFfunction disk_configuration() {	$* ;}EOF} function define_swap() {	if [[ $PARTITIONING_USE_SWAP == "true" ]]; then		echo -n "${PARTITIONING_SWAP@Q}"	else		echo -n "false"	fi} function define_zfs_compression() {	if [[ $PARTITIONING_ZFS_USE_COMPRESSION != "false" ]]; then		echo -n "${PARTITIONING_ZFS_COMPRESSION@Q}"	else		echo -n "false"	fi} function define_disk_layout() {	local swapdev	case "$PARTITIONING_SCHEME" in		"classic_single_disk") define_disk_configuration_function "create_classic_single_disk_layout swap=$(define_swap) type=${PARTITIONING_BOOT_TYPE@Q} luks=${PARTITIONING_USE_LUKS@Q} root_fs=${PARTITIONING_ROOT_FS@Q}" "${PARTITIONING_DEVICE@Q}" ;;		"existing_partitions")			if [[ "$PARTITIONING_USE_SWAP" ]]; then				swapdev=${PARTITIONING_SWAP_DEVICE:-false}			else				swapdev=false			fi		    define_disk_configuration_function "create_existing_partitions_layout boot=${PARTITIONING_BOOT_DEVICE@Q} swap=${swapdev@Q} type=${PARTITIONING_BOOT_TYPE@Q}" "${PARTITIONING_DEVICE@Q}" ;;		"zfs_centric")         define_disk_configuration_function "create_zfs_centric_layout swap=$(define_swap) type=${PARTITIONING_BOOT_TYPE@Q} encrypt=${PARTITIONING_ZFS_USE_ENCRYPTION@Q} compress=$(define_zfs_compression) pool_type=${PARTITIONING_ZFS_POOL_TYPE@Q}" "${PARTITIONING_DEVICES[@]@Q}" ;;		"btrfs_centric")       define_disk_configuration_function "create_btrfs_centric_layout swap=$(define_swap) type=${PARTITIONING_BOOT_TYPE@Q} raid_type=${PARTITIONING_BTRFS_RAID_TYPE@Q} luks=${PARTITIONING_USE_LUKS@Q}" "${PARTITIONING_DEVICES[@]@Q}" ;;		"raid0_luks")          define_disk_configuration_function "create_raid0_luks_layout swap=$(define_swap) type=${PARTITIONING_BOOT_TYPE@Q} luks=${PARTITIONING_USE_LUKS@Q} root_fs=${PARTITIONING_ROOT_FS@Q}" "${PARTITIONING_DEVICES[@]@Q}" ;;		"raid1_luks")          define_disk_configuration_function "create_raid1_luks_layout swap=$(define_swap) type=${PARTITIONING_BOOT_TYPE@Q} luks=${PARTITIONING_USE_LUKS@Q} root_fs=${PARTITIONING_ROOT_FS@Q}" "${PARTITIONING_DEVICES[@]@Q}" ;;		"custom")			# Show current function declaration, trim trailing whitespace			declare -f disk_configuration \				| sed -e 's/\s*$//'			;;	esac} ALL_GENTOO_ARCHS=("x86" "amd64" "arm" "arm64")ALL_STAGE3_VARIANTS=(	"openrc"                              "openrc                             | Minimal OpenRC base (recommended)"	"desktop-openrc"                      "openrc-desktop                     | OpenRC, desktop profile, might have blockers"	"systemd"                             "systemd                            | Minimal systemd base (recommended)"	"systemd-mergedusr"                   "systemd-mergedusr                  | Minimal systemd base with merged filesystem layout"	"desktop-systemd"                     "systemd-desktop                    | systemd, desktop profile, might have blockers"	"nomultilib-openrc"                   "nomultilib-openrc                  | Minimal OpenRC base without 32bits support (Experimental)"	"nomultilib-systemd"                  "nomultilib-systemd                 | Minimal systemd base without 32bits support (Experimental)"	"nomultilib-systemd-mergedusr"        "nomultilib-systemd-mergedusr       | Minimal systemd base with merged filesystem layout and without 32bits support (Experimental)"	"x32-openrc"                          "x32-openrc                         | Minimal OpenRC base without 64bits support (Experimental)"	"x32-systemd"                         "x32-systemd                        | Minimal systemd base without 64bits support (Experimental)"	"x32-systemd-mergedusr"               "x32-systemd-mergedusr              | Minimal systemd base with merged filesystem layout and without 64bits support (Experimental)"	"llvm-openrc"                         "llvm-openrc                        | Minimal OpenRC base compiled with LLVM (Experimental)"	"llvm-systemd"                        "llvm-systemd                       | Minimal systemd base compiled with LLVM (Experimental)"	"llvm-systemd-mergedusr"              "llvm-systemd-mergedusr             | Minimal systemd base with merged filesystem layout compiled with LLVM (Experimental)"	"hardened-openrc"                     "hardened-openrc                    | Hardened OpenRC base (Experimental)"	"hardened-nomultilib-openrc"          "hardened-nomultilib-openrc         | Hardened OpenRC base without 32bits support (Experimental)"	"hardened-selinux-openrc"             "hardened-selinux-openrc            | Hardened OpenRC base with SELinux (Experimental)"	"hardened-nomultilib-selinux-openrc"  "hardened-nomultilib-selinux-openrc | Hardened OpenRC base with SELinux and without 32bits support (Experimental)"	"musl"                                "musl-openrc                        | Minimal OpenRC base using musl (Experimental)"	"musl-llvm"                           "musl-llvm-openrc                   | Minimal OpenRC base using musl compiled with LLVM (Experimental)"	"musl-hardened"                       "musl-hardened-openrc               | Hardened OpenRC base using musl (Experimental)") ALL_PARTITIONING_SCHEMES=(	"classic_single_disk" "Classic single disk layout (boot/efi, swap?, root)"	"existing_partitions" "Skip partitioning, use existing pre-formatted partitions"	"zfs_centric"         "ZFS centric (optional ZFS compression and encryption)"	"btrfs_centric"       "Btrfs centric (optional raid0/1 via btrfs)"	"raid0_luks"          "Raid0 (N>=2 disks) and luks for root"	"raid1_luks"          "Raid1 (N>=2 disks) and luks for root"	"custom"              "Custom (expert option; edit the config manually later)") PARTITIONING_BOOT_TYPES=(	"efi" "efi$([[ $HAS_EFI_SUPPORT == true ]] && echo -n "" || echo -n " (!! $EFI_UNSUPPORTED_MESSAGE_SHORT !!)")"	"bios" "bios")PARTITIONING_ROOT_FS_TYPES=("ext4" "btrfs")PARTITIONING_BTRFS_RAID_TYPES=("raid0" "raid1")PARTITIONING_ZFS_POOL_TYPES=("standard" "custom")PARTITIONING_ZFS_COMPRESSIONS=("on" "gzip" "lz4" "lzjb" "zle" "zstd" "zstd-fast") PORTAGE_SYNC_TYPES=("git" "rsync") function create_single_disk_layout() {	create_classic_single_disk_layout "$@"} function parse_swap() {	if [[ $1 == "false" ]]; then		PARTITIONING_USE_SWAP=false		PARTITIONING_SWAP=8GiB	else		PARTITIONING_USE_SWAP=true		PARTITIONING_SWAP="$1"	fi} function parse_zfs_compression() {	if [[ $1 == "false" ]]; then		PARTITIONING_ZFS_USE_COMPRESSION=false		PARTITIONING_ZFS_COMPRESSION=zstd	else		PARTITIONING_ZFS_USE_COMPRESSION=true		PARTITIONING_ZFS_COMPRESSION="$1"	fi} function create_classic_single_disk_layout() {	PARTITIONING_SCHEME="classic_single_disk" 	local known_arguments=('+swap' '?type' '?luks' '?root_fs')	local extra_arguments=()	declare -A arguments; parse_arguments "$@" 	PARTITIONING_DEVICE="${extra_arguments[0]}"	parse_swap "${arguments[swap]}"	PARTITIONING_BOOT_TYPE="${arguments[type]}"	PARTITIONING_USE_LUKS="${arguments[luks]:-false}"	PARTITIONING_ROOT_FS="${arguments[root_fs]:-ext4}"} function create_existing_partitions_layout() {	PARTITIONING_SCHEME="existing_partitions" 	local known_arguments=('+swap' '+boot' '?type')	local extra_arguments=()	declare -A arguments; parse_arguments "$@" 	PARTITIONING_DEVICE="${extra_arguments[0]}"	if [[ "${arguments[swap]}" == "false" ]]; then		PARTITIONING_USE_SWAP=false		PARTITIONING_SWAP_DEVICE=""	else		PARTITIONING_USE_SWAP=true		PARTITIONING_SWAP_DEVICE="${arguments[swap]}"	fi	PARTITIONING_BOOT_TYPE="${arguments[type]}"	PARTITIONING_BOOT_DEVICE="${arguments[boot]}"} function create_raid0_luks_layout() {	PARTITIONING_SCHEME="raid0_luks" 	local known_arguments=('+swap' '?type' '?luks' '?root_fs')	local extra_arguments=()	declare -A arguments; parse_arguments "$@" 	PARTITIONING_DEVICES=("${extra_arguments[@]}")	parse_swap "${arguments[swap]}"	PARTITIONING_BOOT_TYPE="${arguments[type]}"	PARTITIONING_USE_LUKS="${arguments[luks]:-true}"	PARTITIONING_ROOT_FS="${arguments[root_fs]:-ext4}"} function create_raid1_luks_layout() {	PARTITIONING_SCHEME="raid1_luks" 	local known_arguments=('+swap' '?type' '?luks' '?root_fs')	local extra_arguments=()	declare -A arguments; parse_arguments "$@" 	PARTITIONING_DEVICES=("${extra_arguments[@]}")	parse_swap "${arguments[swap]}"	PARTITIONING_BOOT_TYPE="${arguments[type]}"	PARTITIONING_USE_LUKS="${arguments[luks]:-true}"	PARTITIONING_ROOT_FS="${arguments[root_fs]:-ext4}"} function create_zfs_centric_layout() {	PARTITIONING_SCHEME="zfs_centric" 	local known_arguments=('+swap' '?type' '?pool_type' '?encrypt' '?compress')	local extra_arguments=()	declare -A arguments; parse_arguments "$@" 	PARTITIONING_DEVICES=("${extra_arguments[@]}")	parse_swap "${arguments[swap]}"	PARTITIONING_BOOT_TYPE="${arguments[type]}"	PARTITIONING_ZFS_POOL_TYPE="${arguments[pool_type]:-standard}"	PARTITIONING_ZFS_USE_ENCRYPTION="${arguments[encrypt]:-false}"	parse_zfs_compression "${arguments[compress]:-false}"} function create_btrfs_raid_layout() {	create_btrfs_centric_layout "$@"} function create_btrfs_centric_layout() {	PARTITIONING_SCHEME="btrfs_centric" 	# shellcheck disable=SC2034	local known_arguments=('+swap' '?type' '?raid_type' '?luks')	local extra_arguments=()	declare -A arguments; parse_arguments "$@" 	PARTITIONING_DEVICES=("${extra_arguments[@]}")	parse_swap "${arguments[swap]}"	PARTITIONING_BOOT_TYPE="${arguments[type]}"	PARTITIONING_USE_LUKS="${arguments[luks]:-false}"	PARTITIONING_BTRFS_RAID_TYPE="${arguments[raid_type]:-raid0}"}  ################################################# Configuration constants get_all_keymapsget_all_timezonesreadarray -t SUPPORTED_LOCALES < "$GENTOO_INSTALL_REPO_DIR/contrib/i18n_supported"readarray -t LOCALE_A < <(locale -a)  ################################################# Load/Default configuration function load_selected_locales() {	local sel_locales=()	local IFS=$'\n'	declare -A selected_by_name	for i in $LOCALES; do		selected_by_name["$i"]=true	done 	local i=0	for item in "${SUPPORTED_LOCALES[@]}"; do		[[ "${selected_by_name[$item]:-}" == true ]] \			&& sel_locales+=("$i")		((++i))	done 	local IFS=" "	SELECTED_LOCALES="${sel_locales[*]}"} function process_config() {	disk_configuration 	if [[ "$KEYMAP" == "$KEYMAP_INITRAMFS" ]]; then		KEYMAP_INITRAMFS_OTHER=false	else		KEYMAP_INITRAMFS_OTHER=true	fi 	load_selected_locales	recalculate_locales} function load_config() {	# First load defaults, then replace by sourcing config.	load_default_config 	# Fallback to custom partitioning scheme if it isn't set in the actual config	PARTITIONING_SCHEME="custom" 	# Load settings	# shellcheck disable=SC1090	source "$1" || die "Could not load given configuration." 	# After loading a config, no unsaved changes exist.	UNSAVED_CHANGES=false} function load_default_config() {	HOSTNAME="gentoo"	TIMEZONE="$(get_timezone)"	KEYMAP="$(get_default_keymap)"	KEYMAP_INITRAMFS="$KEYMAP"	LOCALES="C.UTF-8 UTF-8"	LOCALE="C.UTF-8" 	SYSTEMD_NETWORKD=true	SYSTEMD_NETWORKD_INTERFACE_NAME="en*"	SYSTEMD_NETWORKD_DHCP=true	SYSTEMD_NETWORKD_ADDRESSES=("192.168.1.100/32" "fd00::1/64")	SYSTEMD_NETWORKD_GATEWAY="192.168.1.1"	SYSTEMD_INITRAMFS_SSHD=false 	function disk_configuration() {		#create_zfs_centric_layout swap=8GiB type="$DEFAULT_BOOT_TYPE" encrypt=true compress=zstd pool_type=standard /dev/sdX		create_classic_single_disk_layout swap=8GiB type="$DEFAULT_BOOT_TYPE" luks=true root_fs=ext4 /dev/sdX	} 	STAGE3_VARIANT="systemd"	PORTAGE_SYNC_TYPE="git"	PORTAGE_GIT_FULL_HISTORY=false	PORTAGE_GIT_MIRROR="https://anongit.gentoo.org/git/repo/sync/gentoo.git" 	GENTOO_MIRROR="https://mirror.eu.oneandone.net/linux/distributions/gentoo/gentoo"	GENTOO_ARCH="amd64" 	USE_PORTAGE_TESTING=true	SELECT_MIRRORS=false	SELECT_MIRRORS_LARGE_FILE=false 	ADDITIONAL_PACKAGES=()	ENABLE_SSHD=true	ENABLE_BINPKG=false	ROOT_SSH_AUTHORIZED_KEYS=""	 	# All settings are unsaved.	UNSAVED_CHANGES=true} SAVE_AS_FILENAME="$RELA_CONFIG_FILE"if [[ -e "$CONFIG_FILE" ]]; then	load_config "$CONFIG_FILE"else	load_default_configfiprocess_config  ################################################# Menu helpers and constants # $1: exit codefunction clear_and_exit() {	dialog --clear	clear -x	exit "$1"} function ellipsis() {	local len="$1"	shift	local str="$*"	if [[ "${#str}" -gt "$len" ]]; then		echo "${str:0:$len}…"	else		echo "$str"	fi} function on_off_toggle() {	if [[ "${!1}" == true ]]; then		declare -g "$1"=false	else		declare -g "$1"=true	fi} function on_off_str() {	if [[ "$1" == true ]]; then		echo -n "$2"	else		echo -n "$3"	fi} function on_off_label() {	local prefix="${2:-}"	on_off_str "$1" "${prefix}[*]" "${prefix}[ ]"} function on_off_label_inverted() {	local var=$1

Lines 1–500 of 1652.