# shellcheck source=./scripts/protection.sh source "$GENTOO_INSTALL_REPO_DIR/scripts/protection.sh" || exit 1 ################################################ # Functions function install_stage3() { [[ $# == 0 ]] || die "Too many arguments" prepare_installation_environment apply_disk_configuration download_stage3 extract_stage3 } function configure_base_system() { einfo "Generating locales" echo "$LOCALES" > /etc/locale.gen \ || die "Could not write /etc/locale.gen" locale-gen \ || die "Could not generate locales" if [[ $SYSTEMD == "true" ]]; then einfo "Setting machine-id" systemd-machine-id-setup \ || die "Could not setup systemd machine id" # Set hostname einfo "Selecting hostname" echo "$HOSTNAME" > /etc/hostname \ || die "Could not write /etc/hostname" # Set keymap einfo "Selecting keymap" echo "KEYMAP=$KEYMAP" > /etc/vconsole.conf \ || die "Could not write /etc/vconsole.conf" # Set locale einfo "Selecting locale" echo "LANG=$LOCALE" > /etc/locale.conf \ || die "Could not write /etc/locale.conf" einfo "Selecting timezone" ln -sfn "../usr/share/zoneinfo/$TIMEZONE" /etc/localtime \ || die "Could not change /etc/localtime link" else # Set hostname einfo "Selecting hostname" sed -i "/hostname=/c\\hostname=\"$HOSTNAME\"" /etc/conf.d/hostname \ || die "Could not sed replace in /etc/conf.d/hostname" # Set timezone einfo "Selecting timezone" echo "$TIMEZONE" > /etc/timezone \ || die "Could not write /etc/timezone" try emerge -v --config sys-libs/timezone-data # Set keymap einfo "Selecting keymap" sed -i "/keymap=/c\\keymap=\"$KEYMAP\"" /etc/conf.d/keymaps \ || die "Could not sed replace in /etc/conf.d/keymaps" # Set locale einfo "Selecting locale" try eselect locale set "$LOCALE" fi # Update environment env_update } function configure_portage() { # Prepare /etc/portage for autounmask mkdir_or_die 0755 "/etc/portage/package.use" touch_or_die 0644 "/etc/portage/package.use/zz-autounmask" mkdir_or_die 0755 "/etc/portage/package.keywords" touch_or_die 0644 "/etc/portage/package.keywords/zz-autounmask" if [[ $SELECT_MIRRORS == "true" ]]; then einfo "Temporarily installing mirrorselect" try emerge --verbose --oneshot app-portage/mirrorselect einfo "Selecting fastest portage mirrors" mirrorselect_params=("-s" "4" "-b" "10") [[ $SELECT_MIRRORS_LARGE_FILE == "true" ]] \ && mirrorselect_params+=("-D") try mirrorselect "${mirrorselect_params[@]}" einfo "Adding ~$GENTOO_ARCH to ACCEPT_KEYWORDS" echo "ACCEPT_KEYWORDS=\"~$GENTOO_ARCH\"" >> /etc/portage/make.conf \ || die "Could not modify /etc/portage/make.conf" fi } function install_sshd() { einfo "Installing sshd" install -m0600 -o root -g root "$GENTOO_INSTALL_REPO_DIR/contrib/sshd_config" /etc/ssh/sshd_config \ || die "Could not install /etc/ssh/sshd_config" enable_service sshd mkdir_or_die 0700 "/root/" mkdir_or_die 0700 "/root/.ssh" if [[ -n "$ROOT_SSH_AUTHORIZED_KEYS" ]]; then einfo "Adding authorized keys for root" touch_or_die 0600 "/root/.ssh/authorized_keys" echo "$ROOT_SSH_AUTHORIZED_KEYS" > "$ROOT_HOME/.ssh/authorized_keys" \ || die "Could not add ssh key to /root/.ssh/authorized_keys" fi } function generate_initramfs() { local output="$1" # Generate initramfs einfo "Generating initramfs" local modules=() [[ $USED_RAID == "true" ]] \ && modules+=("mdraid") [[ $USED_LUKS == "true" ]] \ && modules+=("crypt crypt-gpg") [[ $USED_BTRFS == "true" ]] \ && modules+=("btrfs") [[ $USED_ZFS == "true" ]] \ && modules+=("zfs") local kver kver="$(readlink /usr/src/linux)" \ || die "Could not figure out kernel version from /usr/src/linux symlink." kver="${kver#linux-}" # Generate initramfs try dracut \ --conf "/dev/null" \ --confdir "/dev/null" \ --kver "$kver" \ --no-compress \ --no-hostonly \ --ro-mnt \ --add "bash ${modules[*]}" \ --force \ "$output" } function get_cmdline() { local cmdline=("rd.vconsole.keymap=$KEYMAP_INITRAMFS") cmdline+=("${DISK_DRACUT_CMDLINE[@]}") if [[ $USED_ZFS != "true" ]]; then cmdline+=("root=UUID=$(get_blkid_uuid_for_id "$DISK_ID_ROOT")") fi echo -n "${cmdline[*]}" } function install_kernel_efi() { try emerge --verbose sys-boot/efibootmgr # Copy kernel to EFI local kernel_file kernel_file="$(find "/boot" -name "vmlinuz-*" -printf '%f\n' | sort -V | tail -n 1)" \ || die "Could not list newest kernel file" mkdir_or_die 0755 "/boot/efi/EFI" cp "/boot/$kernel_file" "/boot/efi/EFI/vmlinuz.efi" \ || die "Could not copy kernel to EFI partition" # Generate initramfs generate_initramfs "/boot/efi/EFI/initramfs.img" # Create boot entry einfo "Creating efi boot entry" local efipartdev efipartdev="$(resolve_device_by_id "$DISK_ID_EFI")" \ || die "Could not resolve device with id=$DISK_ID_EFI" local efipartnum="${efipartdev: -1}" local gptdev gptdev="$(resolve_device_by_id "${DISK_ID_PART_TO_GPT_ID[$DISK_ID_EFI]}")" \ || die "Could not resolve device with id=${DISK_ID_PART_TO_GPT_ID[$DISK_ID_EFI]}" try efibootmgr --verbose --create --disk "$gptdev" --part "$efipartnum" --label "gentoo" --loader '\EFI\vmlinuz.efi' --unicode 'initrd=\EFI\initramfs.img'" $(get_cmdline)" } function generate_syslinux_cfg() { cat < /boot/bios/syslinux/syslinux.cfg \ || die "Could save generated syslinux.cfg" # Install syslinux MBR record einfo "Copying syslinux MBR record" local gptdev gptdev="$(resolve_device_by_id "${DISK_ID_PART_TO_GPT_ID[$DISK_ID_BIOS]}")" \ || die "Could not resolve device with id=${DISK_ID_PART_TO_GPT_ID[$DISK_ID_BIOS]}" try dd bs=440 conv=notrunc count=1 if=/usr/share/syslinux/gptmbr.bin of="$gptdev" } function install_kernel() { # Install vanilla kernel einfo "Installing vanilla kernel and related tools" try emerge --verbose sys-kernel/dracut sys-kernel/gentoo-kernel-bin if [[ $IS_EFI == "true" ]]; then install_kernel_efi else install_kernel_bios fi } function add_fstab_entry() { printf '%-46s %-24s %-6s %-96s %s\n' "$1" "$2" "$3" "$4" "$5" >> /etc/fstab \ || die "Could not append entry to fstab" } function generate_fstab() { einfo "Generating fstab" install -m0644 -o root -g root "$GENTOO_INSTALL_REPO_DIR/contrib/fstab" /etc/fstab \ || die "Could not overwrite /etc/fstab" if [[ $USED_ZFS != "true" ]]; then add_fstab_entry "UUID=$(get_blkid_uuid_for_id "$DISK_ID_ROOT")" "/" "$DISK_ID_ROOT_TYPE" "$DISK_ID_ROOT_MOUNT_OPTS" "0 1" fi if [[ $IS_EFI == "true" ]]; then add_fstab_entry "UUID=$(get_blkid_uuid_for_id "$DISK_ID_EFI")" "/boot/efi" "vfat" "defaults,noatime,fmask=0177,dmask=0077,noexec,nodev,nosuid,discard" "0 2" else add_fstab_entry "UUID=$(get_blkid_uuid_for_id "$DISK_ID_BIOS")" "/boot/bios" "vfat" "defaults,noatime,fmask=0177,dmask=0077,noexec,nodev,nosuid,discard" "0 2" fi if [[ -v "DISK_ID_SWAP" ]]; then add_fstab_entry "UUID=$(get_blkid_uuid_for_id "$DISK_ID_SWAP")" "none" "swap" "defaults,discard" "0 0" fi } function main_install_gentoo_in_chroot() { [[ $# == 0 ]] || die "Too many arguments" # Remove the root password, making the account accessible for automated # tasks during the period of installation. einfo "Clearing root password" passwd -d root \ || die "Could not change root password" if [[ $IS_EFI == "true" ]]; then # Mount efi partition mount_efivars einfo "Mounting efi partition" mount_by_id "$DISK_ID_EFI" "/boot/efi" else # Mount bios partition einfo "Mounting bios partition" mount_by_id "$DISK_ID_BIOS" "/boot/bios" fi # Sync portage einfo "Syncing portage tree" try emerge-webrsync # Configure basic system things like timezone, locale, ... configure_base_system # Prepare portage environment configure_portage # Install git (for git portage overlays) einfo "Installing git" try emerge --verbose dev-vcs/git # Install mdadm if we used raid (needed for uuid resolving) if [[ $USED_RAID == "true" ]]; then einfo "Installing mdadm" try emerge --verbose sys-fs/mdadm fi # Install cryptsetup if we used luks if [[ $USED_LUKS == "true" ]]; then einfo "Installing cryptsetup" try emerge --verbose sys-fs/cryptsetup fi # Install btrfs-progs if we used btrfs if [[ $USED_BTRFS == "true" ]]; then einfo "Installing btrfs-progs" try emerge --verbose sys-fs/btrfs-progs fi # Install zfs kernel module and tools if we used zfs if [[ $USED_ZFS == "true" ]]; then einfo "Installing zfs" try emerge --verbose sys-fs/zfs sys-fs/zfs-kmod einfo "Enabling zfs services" if [[ $SYSTEMD == "true" ]]; then systemctl enable zfs.target || die "Could not enable zfs.target service" systemctl enable zfs-import-cache || die "Could not enable zfs-import-cache service" systemctl enable zfs-mount || die "Could not enable zfs-mount service" systemctl enable zfs-import.target || die "Could not enable zfs-import.target service" else rc-update add zfs-import boot || die "Could not add zfs-import to boot services" rc-update add zfs-mount boot || die "Could not add zfs-mount to boot services" rc-update add zfs-share default || die "Could not add zfs-share to default services" rc-update add zfs-zed default || die "Could not add zfs-zed to default services" fi fi # Install kernel and initramfs install_kernel # Generate a valid fstab file generate_fstab # Install gentoolkit einfo "Installing gentoolkit" try emerge --verbose app-portage/gentoolkit # Install and enable sshd if [[ $INSTALL_SSHD == "true" ]]; then install_sshd fi if [[ $SYSTEMD != "true" ]]; then # Install and enable dhcpcd einfo "Installing dhcpcd" try emerge --verbose net-misc/dhcpcd enable_service dhcpcd fi if [[ $SYSTEMD == "true" ]]; then # Enable systemd networking and dhcp enable_service systemd-networkd enable_service systemd-resolved echo -en "[Match]\nName=en*\n\n[Network]\nDHCP=yes" > /etc/systemd/network/20-wired-dhcp.network \ || die "Could not write dhcp network config to '/etc/systemd/network/20-wired-dhcp.network'" chown root:systemd-network /etc/systemd/network/20-wired-dhcp.network \ || die "Could not change owner of '/etc/systemd/network/20-wired-dhcp.network'" chmod 640 /etc/systemd/network/20-wired-dhcp.network \ || die "Could not change owner of '/etc/systemd/network/20-wired-dhcp.network'" fi # Install additional packages, if any. if [[ ${#ADDITIONAL_PACKAGES[@]} -gt 0 ]]; then einfo "Installing additional packages" # shellcheck disable=SC2086 try emerge --verbose --autounmask-continue=y -- "${ADDITIONAL_PACKAGES[@]}" fi if ask "Do you want to assign a root password now?"; then try passwd root einfo "Root password assigned" else try passwd -d root ewarn "Root password cleared, set one as soon as possible!" fi einfo "Gentoo installation complete." [[ $USED_LUKS == "true" ]] \ && einfo "A backup of your luks headers can be found at '$LUKS_HEADER_BACKUP_DIR', in case you want to have a backup." einfo "To chroot into the new system, simply execute the provided 'chroot' wrapper." einfo "Otherwise, you may now reboot your system." } function main_install() { [[ $# == 0 ]] || die "Too many arguments" gentoo_umount install_stage3 [[ $IS_EFI == "true" ]] \ && mount_efivars gentoo_chroot "$ROOT_MOUNTPOINT" "$GENTOO_INSTALL_REPO_BIND/install" __install_gentoo_in_chroot } function main_chroot() { # Skip if already mounted mountpoint -q -- "$1" \ || die "'$1' is not a mountpoint" gentoo_chroot "$@" }