#!/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=$1Lines 1–500 of 1652. Load more
#!/bin/bash set -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_DIR export GENTOO_INSTALL_REPO_SCRIPT_ACTIVE=true # shellcheck source=./scripts/utils.sh source "$GENTOO_INSTALL_REPO_DIR/scripts/utils.sh" # Remember actual config file path CONFIG_FILE="$(realpath "${1-"gentoo.conf"}" 2>/dev/null)" RELA_CONFIG_FILE="$(realpath --relative-to="$(pwd)" "$CONFIG_FILE" 2>/dev/null)" # Check if help is requested while [[ $# -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 shift done check_wanted_programs dialog ncurses=ncursesw6-config # Determine whether EFI is available HAS_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 << EOF function 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_keymaps get_all_timezones readarray -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_config fi process_config ################################################ # Menu helpers and constants # $1: exit code function 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