├── misc ├── zol.conf ├── zbmconfig.yaml ├── 60-ukify ├── greetd-run └── libviss ├── images └── tuiscreenshot.png ├── modules ├── xtools ├── amdgpu_unlock ├── noto-fonts ├── module.sig_enforce ├── sof-firmware ├── init_on_free ├── raise_vm.max_map_count ├── tlp ├── apcupsd ├── chrony ├── esync ├── socklog ├── flatpak ├── usbguard ├── wifi-firmware ├── kernel_lockdown ├── cpu-ucode ├── net.ipv4.conf.all.rp_filter ├── harden_proc ├── nftables └── virt ├── LICENSE ├── setup ├── installer ├── chroot ├── desktop ├── disk └── base ├── README.md └── viss /misc/zol.conf: -------------------------------------------------------------------------------- 1 | nofsck="yes" 2 | add_dracutmodules+=" zfs " 3 | omit_dracutmodules+=" btrfs " 4 | -------------------------------------------------------------------------------- /images/tuiscreenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkrruumm/void-install-script/HEAD/images/tuiscreenshot.png -------------------------------------------------------------------------------- /modules/xtools: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | title=xtools 3 | description="- Installs xtools package for working with xbps" 4 | status=on 5 | 6 | main() { 7 | commandFailure="Installing xtools package has failed." && 8 | install xtools 9 | 10 | return 0 11 | } 12 | -------------------------------------------------------------------------------- /misc/zbmconfig.yaml: -------------------------------------------------------------------------------- 1 | Global: 2 | ManageImages: true 3 | BootMountPoint: /boot/efi 4 | Components: 5 | Enabled: false 6 | EFI: 7 | ImageDir: /boot/efi/EFI/boot/ 8 | Versions: false 9 | Enabled: true 10 | Kernel: 11 | Prefix: bootx64 12 | CommandLine: quiet loglevel=0 13 | -------------------------------------------------------------------------------- /modules/amdgpu_unlock: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | title=amdgpu_unlock 3 | description="- Enables amdgpu overclocking" 4 | status=off 5 | 6 | main() { 7 | commandFailure="Enabling amdgpu overclocking has failed." 8 | setKernelParam "amdgpu.ppfeaturemask=0xffffffff" 9 | 10 | return 0 11 | } 12 | -------------------------------------------------------------------------------- /modules/noto-fonts: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | title=noto-fonts 3 | description="- Noto TTF fonts typically used by websites" 4 | status=off 5 | 6 | main() { 7 | commandFailure="Noto TTF fonts installation has failed." && 8 | install noto-fonts-ttf noto-fonts-cjk 9 | 10 | return 0 11 | } 12 | -------------------------------------------------------------------------------- /modules/module.sig_enforce: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | title=module.sig_enforce 3 | description="- Enables module.sig_enforce kernel parameter" 4 | status=off 5 | 6 | main() { 7 | commandFailure="Enabling module.sig_enforce has failed." 8 | setKernelParam "module.sig_enforce=1" 9 | 10 | return 0 11 | } 12 | -------------------------------------------------------------------------------- /modules/sof-firmware: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | title=sof-firmware 3 | description="- Sound Open Firmware and topology binaries (Audio support for modern laptops)" 4 | status=off 5 | 6 | main() { 7 | commandFailure="SOF Firmware installation has failed." && 8 | install sof-firmware 9 | 10 | return 0 11 | } 12 | -------------------------------------------------------------------------------- /modules/init_on_free: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | [ "$filesystem" == "zfs" ] && return 1 4 | 5 | title=init_on_free 6 | description="- Enables init_on_free kernel parameter" 7 | status=off 8 | 9 | main() { 10 | commandFailure="Enabling init_on_free has failed." 11 | setKernelParam "init_on_free=1" 12 | 13 | return 0 14 | } 15 | -------------------------------------------------------------------------------- /modules/raise_vm.max_map_count: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | title=raise_vm.max_map_count 3 | description="- Raises vm.max_map_count to 1048576" 4 | status=off 5 | 6 | main() { 7 | echo "vm.max_map_count=1048576" >> /mnt/etc/sysctl.conf || 8 | { commandFailure="Raising vm.max_map_count has failed." ; die ; } 9 | 10 | return 0 11 | } 12 | -------------------------------------------------------------------------------- /modules/tlp: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | title=tlp 3 | description="- Advanced power management" 4 | status=off 5 | 6 | main() { 7 | commandFailure="tlp installation has failed." && 8 | install tlp 9 | 10 | commandFailure="Enabling tlp has failed." && 11 | system "ln -s /etc/sv/tlp /var/service" 12 | 13 | return 0 14 | } 15 | -------------------------------------------------------------------------------- /modules/apcupsd: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | title=apcupsd 3 | description="- APC UPS Daemon" 4 | status=off 5 | 6 | main() { 7 | commandFailure="apcupsd installation has failed." && 8 | install apcupsd 9 | 10 | commandFailure="Enabling apcupsd has failed." && 11 | system "ln -s /etc/sv/apcupsd /var/service" 12 | 13 | return 0 14 | } 15 | -------------------------------------------------------------------------------- /modules/chrony: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | title=chrony 3 | description="- Chrony NTP Daemon" 4 | status=on 5 | 6 | main() { 7 | commandFailure="Chrony installation has failed." && 8 | install chrony 9 | 10 | commandFailure="Enabling chronyd has failed." && 11 | system "ln -s /etc/sv/chronyd /var/service" 12 | 13 | return 0 14 | } 15 | -------------------------------------------------------------------------------- /misc/60-ukify: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | PKGNAME="$1" 6 | VERSION="$2" 7 | 8 | [ -x /usr/bin/ukify ] || exit 0 9 | 10 | ukify build \ 11 | --linux="${ROOTDIR}/boot/vmlinuz-${VERSION}" \ 12 | --initrd="${ROOTDIR}/boot/initramfs-${VERSION}.img" \ 13 | --output="${ROOTDIR}/boot/efi/EFI/boot/bootx64.efi" \ 14 | --uname="${VERSION}" \ 15 | --cmdline="loglevel=4" 16 | -------------------------------------------------------------------------------- /modules/esync: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Don't populate unless a user actually exists 4 | [ -z "$username" ] && return 1 5 | 6 | title=esync 7 | description="- Enables esync by raising ulimit" 8 | status=off 9 | 10 | main() { 11 | echo "$username hard nofile 524288" >> /mnt/etc/security/limits.conf || 12 | { commandFailure="Enabling esync has failed." ; die ; } 13 | 14 | return 0 15 | } 16 | -------------------------------------------------------------------------------- /modules/socklog: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | title=socklog 3 | description="- Enables system logging" 4 | status=on 5 | 6 | main() { 7 | commandFailure="Socklog installation has failed." && 8 | install socklog-void 9 | 10 | commandFailure="Enabling socklog has failed." && 11 | system "ln -s /etc/sv/socklog-unix /var/service && ln -s /etc/sv/nanoklogd /var/service" 12 | 13 | return 0 14 | } 15 | -------------------------------------------------------------------------------- /misc/greetd-run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This file is executed by greetd, the purpose of which is 4 | # to set a bunch of env vars and then launch the WM 5 | export XDG_SESSION_TYPE=wayland 6 | export XDG_SESSION_DESKTOP=sway 7 | export XDG_CURRENT_DESKTOP=sway 8 | 9 | export MOZ_ENABLE_WAYLAND=1 10 | export QT_QPA_PLATFORM=wayland 11 | export SDL_VIDEODRIVER=wayland 12 | export _JAVA_AWT_WM_NONREPARENTING=1 13 | 14 | -------------------------------------------------------------------------------- /modules/flatpak: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | title=flatpak 3 | description="- Includes Flathub repository" 4 | status=off 5 | 6 | main() { 7 | commandFailure="Flatpak installation has failed." && 8 | install flatpak 9 | 10 | commandFailure="Adding flatpak repository has failed." && 11 | system "flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo" 12 | 13 | return 0 14 | } 15 | -------------------------------------------------------------------------------- /modules/usbguard: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | title=usbguard 3 | description="- Installs and enables usbguard, allows current devices" 4 | status=off 5 | 6 | main() { 7 | commandFailure="Installing usbguard has failed." && 8 | install usbguard 9 | 10 | commandFailure="Configuring usbguard has failed." && 11 | system "usbguard generate-policy > /etc/usbguard/rules.conf" 12 | 13 | commandFailure="Enabling usbguard has failed." && 14 | system "ln -s /etc/sv/usbguard /var/service" 15 | 16 | return 0 17 | } 18 | -------------------------------------------------------------------------------- /modules/wifi-firmware: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | title=wifi-firmware 3 | description="- Wifi firmware and utilities" 4 | status=on 5 | 6 | # If this is toggled off, and the user is using the regular base metapackage, 7 | # the packages will be removed from the system. 8 | # If the user has defined their own basesystem, install if enabled: 9 | main() { 10 | [ "$basesystem" != "base-system" ] && 11 | { commandFailure="Wifi firmware and utility installation has failed." ; install iw wpa_supplicant wifi-firmware ; } 12 | 13 | return 0 14 | } 15 | -------------------------------------------------------------------------------- /modules/kernel_lockdown: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | [ "$filesystem" == "zfs" ] && return 1 4 | 5 | title=kernel_lockdown 6 | description="- Provides a choice to set the kernel lockdown mode" 7 | status=off 8 | 9 | main() { 10 | lockdown=$(drawDialog --no-cancel --title "Kernel Lockdown Mode" --menu "" 0 0 0 "integrity" "- Userland modifying the running kernel is disabled." "confidentiality" "- Extracting confidential information from the kernel is also disabled." "None" "") 11 | 12 | commandFailure="Enabling kernel lockdown mode has failed." 13 | setKernelParam "lockdown=$lockdown" 14 | 15 | return 0 16 | } 17 | -------------------------------------------------------------------------------- /modules/cpu-ucode: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | title=cpu-ucode 3 | description="- Installs CPU microcode for Intel or AMD" 4 | status=off 5 | 6 | main() { 7 | commandFailure="Installing CPU microcode package has failed." 8 | if lscpu | grep "GenuineIntel" ; then 9 | install void-repo-nonfree 10 | xmirror -s "$repository" -r /mnt || die 11 | install intel-ucode 12 | system 'xbps-reconfigure -f linux"$(find /boot -name vmlinuz\* | tr -d "/boot/vmlinuz-" | cut -f1,2 -d".")"' 13 | elif lscpu | grep "AuthenticAMD" ; then 14 | # This package should already be installed as a dep. of linux-base, but just incase something changes: 15 | install linux-firmware-amd 16 | fi 17 | 18 | return 0 19 | } 20 | -------------------------------------------------------------------------------- /modules/net.ipv4.conf.all.rp_filter: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | title=net.ipv4.conf.all.rp_filter 3 | description="- Provides a choice to set the net.ipv4.conf.all.rp_filter value" 4 | status=off 5 | 6 | main() { 7 | rpfilter=$(drawDialog --no-cancel --title "net.ipv4.conf.all.rp_filter" --menu "" 0 0 0 "Strict" "" "Loose" "" "None" "") 8 | 9 | commandFailure="Setting net.ipv4.conf.all.rp_filter has failed." 10 | if [ "$rpfilter" == "Loose" ]; then 11 | echo "net.ipv4.conf.default.rp_filter = 2" >> /mnt/etc/sysctl.conf || die 12 | echo "net.ipv4.conf.all.rp_filter = 2" >> /mnt/etc/sysctl.conf || die 13 | elif [ "$rpfilter" == "Strict" ]; then 14 | echo "net.ipv4.conf.default.rp_filter = 1" >> /mnt/etc/sysctl.conf || die 15 | echo "net.ipv4.conf.all.rp_filter = 1" >> /mnt/etc/sysctl.conf || die 16 | fi 17 | 18 | return 0 19 | } 20 | 21 | -------------------------------------------------------------------------------- /modules/harden_proc: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | title=harden_proc 3 | description="- Hardens /proc by setting hidepid=2 and gid=proc" 4 | status=off 5 | 6 | main() { 7 | echo "mount -o remount,rw,nosuid,nodev,noexec,relatime,hidepid=2,gid=proc /proc" >> /mnt/etc/rc.local || 8 | { commandFailure="Modifying rc for hideproc has failed." ; die ; } 9 | 10 | commandFailure="Creating group for proc users has failed." && 11 | system "groupadd proc" 12 | 13 | if [ -n "$username" ]; then 14 | commandFailure="Adding user to proc group has failed." && 15 | system "usermod -aG proc $username" 16 | fi 17 | 18 | # Required for certain things the installer may deploy to function out of the box. 19 | if grep "polkitd" /mnt/etc/passwd ; then 20 | commandFailure="Adding polkit user to proc group has failed." && 21 | system "usermod -aG proc polkitd" 22 | fi 23 | 24 | if grep "gdm" /mnt/etc/passwd ; then 25 | commandFailure="Adding gdm user to proc group has failed." && 26 | system "usermod -aG proc gdm" 27 | fi 28 | 29 | return 0 30 | } 31 | -------------------------------------------------------------------------------- /modules/nftables: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | title=nftables 3 | description="- Includes a default firewall config" 4 | status=on 5 | 6 | main() { 7 | commandFailure="nftables installation has failed." && 8 | install nftables 9 | 10 | commandFailure="Configuring nftables firewall has failed." 11 | 12 | echo -e '#!/usr/sbin/nft -f \n' >> /mnt/etc/nftables.conf || die 13 | echo -e 'flush ruleset \n' >> /mnt/etc/nftables.conf || die 14 | 15 | # Create table 16 | system "nft add table inet filter" 17 | 18 | # Input chain 19 | system "nft add chain inet filter input '{type filter hook input priority 0; policy drop;}' && 20 | nft add rule inet filter input ct state invalid drop && 21 | nft add rule inet filter input ct state { established, related } accept && 22 | nft add rule inet filter input iif "lo" accept && 23 | nft add rule inet filter input iif != "lo" ip daddr 127.0.0.1/8 drop && 24 | nft add rule inet filter input iif != "lo" ip6 daddr ::1 drop" 25 | 26 | # Output chain 27 | system "nft add chain inet filter output '{type filter hook output priority 0; policy accept;}'" 28 | 29 | # Forward chain 30 | system "nft add chain inet filter forward '{type filter hook forward priority 0; policy drop;}'" 31 | 32 | # Save config 33 | commandFailure="Saving nftables config has failed." && 34 | system "nft list ruleset >> /etc/nftables.conf" 35 | 36 | commandFailure="Enabling nftables has failed." && 37 | system "ln -s /etc/sv/nftables /var/service" 38 | 39 | return 0 40 | } 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) $CURRENTYEAR, krum 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /setup/installer: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Basic checks and setup before the installer reaches configuration 3 | 4 | echo "Running basic checks..." 5 | 6 | [ "$USER" != root ] && 7 | echo -e "${RED}Please execute this script as root.${NC}" && exit 1 8 | 9 | dependencies=("$(pwd)/modules" \ 10 | "setup/base" \ 11 | "setup/desktop" \ 12 | "setup/disk" \ 13 | "setup/chroot" \ 14 | "misc/greetd-run" \ 15 | "misc/60-ukify" \ 16 | "misc/zbmconfig.yaml" \ 17 | "misc/zol.conf") 18 | 19 | for i in ${dependencies[@]}; do 20 | [ -e "$i" ] || 21 | { commandFailure="$i appears to be missing. This could be because it is incorrectly named, or it does not exist." ; die ; } 22 | done 23 | 24 | [ -n "$modulesDialogArray" ] && 25 | unset modulesDialogArray 26 | 27 | [ -e "/sys/firmware/efi" ] || 28 | { commandFailure="This script only supports UEFI systems, but it appears we have booted as BIOS." ; die ; } 29 | 30 | [ "$(uname -m)" != "x86_64" ] && 31 | { commandFailure="This systems CPU architecture is not currently supported by this installer." ; die ; } 32 | 33 | # if the host doesn't have zfs utils, don't populate 34 | # TODO: this needs better verification in the future. 35 | which zfs &>/dev/null || 36 | zfspossible=no 37 | 38 | echo "Finding out what libc is being used..." 39 | if ldd --version | grep GNU ; then 40 | libc="glibc" 41 | else 42 | libc="musl" 43 | fi 44 | 45 | echo "Testing for network connectivity..." 46 | ping -c 1 gnu.org &>/dev/null && ping -c 1 fsf.org &>/dev/null || 47 | { commandFailure="Network check has failed. Please make sure you are connected to the internet." ; die ; } 48 | 49 | commandFailure="Dependency installation has failed." 50 | xbps-install -Suy xbps || die 51 | xbps-install -Suy dialog bc || die 52 | 53 | # it doesn't matter if these fail, do not || die 54 | dialog --create-rc ~/.dialogrc 55 | # i find the default blue background of dialog to be a little bit irritating, changing colors here. 56 | sed -i -e 's/screen_color = (CYAN,BLUE,ON)/screen_color = (BLACK,BLACK,ON)/g' ~/.dialogrc 57 | sed -i -e 's/title_color = (BLUE,WHITE,ON)/title_color = (BLACK,WHITE,ON)/g' ~/.dialogrc 58 | 59 | return 0 60 | -------------------------------------------------------------------------------- /modules/virt: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | title=virt 3 | description="- Installs and configures qemu and libvirt" 4 | status=off 5 | 6 | main() { 7 | # netcat is installed here along with everything else because 8 | # machines using this box remotely via virt-manager require it, 9 | # such as in the context of using void on a virtualization server 10 | commandFailure="Installing qemu and libvirt has failed." && 11 | install qemu libvirt virtiofsd polkit dbus netcat 12 | 13 | commandFailure="Modifying qemu and libvirt configs has failed." 14 | sed -i -e 's/#unix_sock_group = "libvirt"/unix_sock_group = "libvirt"/g' /mnt/etc/libvirt/libvirtd.conf || die 15 | sed -i -e 's/#unix_sock_rw_perms = "0770"/unix_sock_rw_perms = "0770"/g' /mnt/etc/libvirt/libvirtd.conf || die 16 | 17 | if [ -n "$username" ]; then 18 | sed -i -e 's/#user = "libvirt"/user = "'$username'"/g' /mnt/etc/libvirt/qemu.conf || die 19 | sed -i -e 's/#group = "libvirt"/group = "'$username'"/g' /mnt/etc/libvirt/qemu.conf || die 20 | 21 | commandFailure="Adding user to libvirt group has failed." && 22 | system "usermod -aG libvirt $username" 23 | fi 24 | 25 | commandFailure="Enabling virt services has failed." 26 | system "ln -s /etc/sv/libvirtd /var/service" 27 | system "ln -s /etc/sv/virtlogd /var/service" 28 | system "ln -s /etc/sv/virtlockd /var/service" 29 | 30 | # dbus and polkitd may or may not be installed by other things, recheck 31 | # this will fail if /var/service/dbus is checked as opposed to the default runsvdir 32 | [ ! -e /mnt/etc/runit/runsvdir/default/dbus ] && 33 | { commandFailure="Enabling dbus service has failed." ; system "ln -s /etc/sv/dbus /var/service" ; } 34 | 35 | # allow proc access to polkitd for hardened proc module 36 | # if not already done by the harden proc module 37 | # regular chroot is being used here because the system wrapper will die on non-0 exit 38 | grep "gid=proc /proc" /mnt/etc/rc.local && ! chroot /mnt /bin/bash -c "groups polkitd | grep proc" && 39 | { commandFailure="Adding polkitd user to proc group has failed." ; system "usermod -aG proc polkitd" ; } 40 | 41 | return 0 42 | } 43 | -------------------------------------------------------------------------------- /misc/libviss: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # void-install-script general library for things that are expected to be used multiple times 3 | 4 | RED='\033[0;31m' 5 | GREEN='\033[0;32m' 6 | YELLOW='\e[1;33m' 7 | NC='\033[0m' 8 | 9 | die() { 10 | echo -e "${RED}$commandFailure${NC}\nInstallation will not proceed." && exit 1 11 | } 12 | 13 | drawDialog() { 14 | dialog --stdout --cancel-label "Skip" --no-mouse --backtitle "https://github.com/kkrruumm/void-install-script" "$@" 15 | } 16 | 17 | diskCalculator() { 18 | diskOperand=$(echo $sizeInput | sed 's/G//g') 19 | diskFloat=$(echo $diskFloat - $diskOperand | bc) 20 | diskAvailable=$(echo $diskFloat - 0.5 | bc) 21 | diskAvailable+="G" 22 | 23 | if [ "$diskFloat" -lt 0 ]; then 24 | clear 25 | echo -e "${RED}Used disk space cannot exceed the maximum capacity of the chosen disk. Have you over-provisioned your disk? ${NC}\n" 26 | read -p "Press Enter to start disk configuration again." > /etc/doas.conf || die 134 | fi 135 | fi 136 | 137 | # Create users home directories, such as ~/Downloads 138 | case "$desktop" in 139 | sway|swayfx|wayfire|i3|niri|river) 140 | su "$username" -c 'xdg-user-dirs-update' || 141 | { commandFailure="Executing xdg-user-dirs-update has failed." ; die ; } 142 | ;; 143 | esac 144 | 145 | clear 146 | rootPassword 147 | fi 148 | -------------------------------------------------------------------------------- /setup/desktop: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | [ -n "$graphicsArray" ] && 4 | commandFailure="Graphics driver installation has failed." 5 | 6 | for i in "${graphicsArray[@]}" 7 | do 8 | case $i in 9 | amd) 10 | install mesa-dri vulkan-loader mesa-vulkan-radeon mesa-vaapi mesa-vdpau 11 | ;; 12 | 13 | amd-32bit) 14 | install void-repo-multilib 15 | xmirror -s "$repository" -r /mnt || die 16 | install libgcc-32bit libstdc++-32bit libdrm-32bit libglvnd-32bit mesa-dri-32bit 17 | ;; 18 | 19 | nvidia) 20 | install void-repo-nonfree 21 | xmirror -s "$repository" -r /mnt || die 22 | install nvidia 23 | 24 | # Enable mode setting for wayland compositors 25 | # This default should change to drm enabled with more recent nvidia drivers, expect this to be removed in the future. 26 | setKernelParam "nvidia_drm.modeset=1" 27 | ;; 28 | 29 | nvidia-32bit) 30 | install void-repo-multilib-nonfree void-repo-multilib 31 | xmirror -s "$repository" -r /mnt || die 32 | install nvidia-libs-32bit 33 | ;; 34 | 35 | intel) 36 | install mesa-dri vulkan-loader mesa-vulkan-intel intel-video-accel 37 | ;; 38 | 39 | intel-32bit) 40 | install void-repo-multilib 41 | xmirror -s "$repository" -r /mnt || die 42 | install libgcc-32bit libstdc++-32bit libdrm-32bit libglvnd-32bit mesa-dri-32bit 43 | ;; 44 | 45 | nvidia-nouveau) 46 | install mesa-dri mesa-nouveau-dri 47 | ;; 48 | 49 | nvidia-nouveau-32bit) 50 | install void-repo-multilib 51 | xmirror -s "$repository" -r /mnt || die 52 | install libgcc-32bit libstdc++-32bit libdrm-32bit libglvnd-32bit mesa-dri-32bit mesa-nouveau-dri-32bit 53 | ;; 54 | 55 | *) 56 | echo "Continuing without graphics drivers..." 57 | ;; 58 | 59 | esac 60 | done 61 | 62 | [ -n "$network" ] && [ "$network" != "none" ] && 63 | commandFailure="DHCP client setup has failed." 64 | 65 | case "$network" in 66 | NetworkManager) 67 | install NetworkManager 68 | system "ln -s /etc/sv/NetworkManager /var/service" 69 | ;; 70 | dhcpcd) 71 | system "ln -s /etc/sv/dhcpcd /var/service" 72 | ;; 73 | esac 74 | 75 | setup_greetd() { 76 | install greetd 77 | system "ln -s /etc/sv/greetd /var/service" 78 | cp misc/greetd-run /mnt/usr/local/bin/"${desktop}"-run || die 79 | sed -i 's,command = "agreety --cmd /bin/sh",command = "agreety --cmd '"${desktop}"'-run",' /mnt/etc/greetd/config.toml || die 80 | 81 | # this defaults to 'sway' only because it applies to both sway and swayfx 82 | if [ "$desktop" != 'sway' ] && [ "$desktop" != 'swayfx' ]; then 83 | sed -i "s/sway/${desktop}/g" /mnt/usr/local/bin/"${desktop}"-run || die 84 | fi 85 | 86 | system "chown root:root /usr/local/bin/${desktop}-run" 87 | system "chmod 755 /usr/local/bin/${desktop}-run" 88 | system "chmod +x /usr/local/bin/${desktop}-run" 89 | } 90 | 91 | [ -n "$desktop" ] && [ "$desktop" != "none" ] && 92 | commandFailure="GUI installation has failed" 93 | 94 | case "$desktop" in 95 | gnome) 96 | install gnome-core gnome-console gnome-tweaks gnome-browser-connector gnome-text-editor xdg-user-dirs xorg-minimal xorg-video-drivers 97 | system "ln -s /etc/sv/gdm /var/service" 98 | ;; 99 | kde) 100 | install kde-plasma kde-baseapps xdg-user-dirs xorg-minimal xorg-video-drivers 101 | system "ln -s /etc/sv/sddm /var/service" 102 | ;; 103 | xfce) 104 | install xfce4 xfce4-pulseaudio-plugin lightdm lightdm-gtk3-greeter xorg-minimal xdg-user-dirs xorg-fonts xorg-video-drivers 105 | 106 | [ "$network" == "NetworkManager" ] && 107 | install network-manager-applet 108 | 109 | system "ln -s /etc/sv/lightdm /var/service" 110 | ;; 111 | sway) 112 | install sway elogind polkit polkit-elogind foot xorg-fonts xdg-desktop-portal-wlr xdg-user-dirs 113 | 114 | [ "$network" == "NetworkManager" ] && 115 | install network-manager-applet 116 | 117 | system "ln -s /etc/sv/polkitd /var/service" 118 | 119 | if [ "$greetd" == "Yes" ]; then 120 | setup_greetd 121 | echo 'exec dbus-run-session sway "$@"' >> /mnt/usr/local/bin/"${desktop}"-run || die 122 | fi 123 | ;; 124 | swayfx) 125 | install swayfx elogind polkit polkit-elogind foot xorg-fonts xdg-desktop-portal-wlr xdg-user-dirs 126 | 127 | [ "$network" == "NetworkManager" ] && 128 | install network-manager-applet 129 | 130 | system "ln -s /etc/sv/polkitd /var/service" 131 | 132 | if [ "$greetd" == "Yes" ]; then 133 | setup_greetd 134 | echo 'exec dbus-run-session sway "$@"' >> /mnt/usr/local/bin/"${desktop}"-run || die 135 | fi 136 | ;; 137 | river) 138 | install river elogind polkit polkit-elogind foot xorg-fonts xdg-desktop-portal-wlr xdg-user-dirs 139 | 140 | [ "$network" == "NetworkManager" ] && 141 | install network-manager-applet 142 | 143 | system "ln -s /etc/sv/polkitd /var/service" 144 | 145 | if [ "$greetd" == "Yes" ]; then 146 | setup_greetd 147 | echo 'exec dbus-run-session river "$@"' >> /mnt/usr/local/bin/"${desktop}"-run || die 148 | fi 149 | ;; 150 | i3) 151 | install i3 xorg-minimal xinit xterm xorg-fonts xorg-video-drivers xdg-user-dirs 152 | 153 | [ "$network" == "NetworkManager" ] && 154 | install network-manager-applet 155 | 156 | if [ "$lightdm" == "Yes" ]; then 157 | install lightdm lightdm-gtk3-greeter 158 | system "ln -s /etc/sv/lightdm /var/service" 159 | fi 160 | ;; 161 | niri) 162 | install niri elogind polkit polkit-elogind alacritty fuzzel xorg-fonts xdg-desktop-portal-gtk xdg-desktop-portal-gnome xdg-user-dirs 163 | 164 | [ "$network" == "NetworkManager" ] && 165 | install network-manager-applet 166 | 167 | system "ln -s /etc/sv/polkitd /var/service" 168 | 169 | if [ "$greetd" == "Yes" ]; then 170 | setup_greetd 171 | echo 'exec dbus-run-session niri --session "$@"' >> /mnt/usr/local/bin/"${desktop}"-run || die 172 | fi 173 | ;; 174 | wayfire) 175 | install wayfire elogind polkit polkit-elogind alacritty xorg-fonts xdg-desktop-portal-wlr xdg-user-dirs 176 | 177 | [ "$network" == "NetworkManager" ] && 178 | install network-manager-applet 179 | 180 | system "ln -s /etc/sv/polkitd /var/service" 181 | 182 | if [ "$greetd" == "Yes" ]; then 183 | setup_greetd 184 | echo 'exec dbus-run-session wayfire "$@"' >> /mnt/usr/local/bin/"${desktop}"-run || die 185 | fi 186 | ;; 187 | mate) 188 | install mate mate-terminal lightdm lightdm-gtk3-greeter xorg-minimal xdg-user-dirs xorg-fonts xorg-video-drivers 189 | 190 | [ "$network" == "NetworkManager" ] && 191 | install network-manager-applet 192 | 193 | system "ln -s /etc/sv/lightdm /var/service" 194 | ;; 195 | esac 196 | 197 | [ -n "$audio" ] && [ "$audio" != "none" ] && 198 | commandFailure="Audio server installation has failed." 199 | 200 | case "$audio" in 201 | pipewire) 202 | install pipewire alsa-pipewire wireplumber 203 | mkdir -p /mnt/etc/alsa/conf.d || die 204 | mkdir -p /mnt/etc/pipewire/pipewire.conf.d || die 205 | 206 | # this is now required to start pipewire and its session manager 'wireplumber' in an appropriate order, this should achieve a desireable result system-wide 207 | system "ln -s /usr/share/examples/wireplumber/10-wireplumber.conf /etc/pipewire/pipewire.conf.d/" 208 | system "ln -s /usr/share/examples/pipewire/20-pipewire-pulse.conf /etc/pipewire/pipewire.conf.d/" 209 | 210 | # enable pipewire and pipewire-pulse autostart 211 | if [ -e "/usr/share/applications/pipewire.desktop" ] && [ -e "/etc/xdg/autostart/" ]; then 212 | system "ln -s /usr/share/applications/pipewire.desktop /etc/xdg/autostart/pipewire.desktop" 213 | system "ln -s /usr/share/applications/pipewire-pulse.desktop /etc/xdg/autostart/pipewire-pulse.desktop" 214 | fi 215 | 216 | # alsa configuration 217 | system "ln -s /usr/share/alsa/alsa.conf.d/50-pipewire.conf /etc/alsa/conf.d" 218 | system "ln -s /usr/share/alsa/alsa.conf.d/99-pipewire-default.conf /etc/alsa/conf.d" 219 | ;; 220 | pulseaudio) 221 | install pulseaudio alsa-plugins-pulseaudio 222 | ;; 223 | esac 224 | 225 | return 0 226 | -------------------------------------------------------------------------------- /setup/disk: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Running setupdisk..." 4 | 5 | [ "$filesystem" == "zfs" ] && 6 | { commandFailure="Running zgenhostid has failed." ; zgenhostid -f 0x00bab10c || die ; } 7 | 8 | if [ -n "$wipedisk" ] && [ "$wipedisk" -gt 0 ]; then 9 | shred --verbose --random-source=/dev/urandom -n"$wipedisk" --zero "$diskInput" || 10 | { commandFailure="Disk erase has failed." ; die ; } 11 | fi 12 | 13 | deviceVG=$(pvdisplay $diskInput* | grep "VG Name" | while read c1 c2; do echo $c2; done | sed 's/Name //g') 14 | 15 | if [ -n "$deviceVG" ]; then 16 | commandFailure="VG destruction has failed." 17 | vgchange -a n "$deviceVG" || die 18 | vgremove "$deviceVG" || die 19 | fi 20 | 21 | commandFailure="Disk pre-install wipe has failed." 22 | scanpartitions="$diskInput?*" # We only want child partitions, not the parent drive 23 | for i in $scanpartitions 24 | do 25 | wipefs --all -f "$i" 26 | done 27 | 28 | sfdisk --delete "$diskInput" 29 | 30 | # 'echo ;' here is equivalent to pressing enter in fdisk 31 | ( 32 | echo g; # gpt table 33 | echo n; echo ; echo ; echo +500M; # ESP 34 | [ "$lvm" == "No" ] && [ "$swapStyle" == "partition" ] && echo n; echo ; echo ; echo +"$swapSize"; 35 | if [ "$filesystem" == "zfs" ] || [ "$filesystem" == "btrfs" ] || [ "$lvm" == "Yes" ] || [ "$rootSize" == "full" ]; then 36 | echo n; echo ; echo ; echo ; 37 | fi 38 | [ "$lvm" == "No" ] && [ "$rootSize" != "full" ] && echo n; echo ; echo ; echo +"$rootSize"; 39 | [ "$lvm" == "No" ] && [ "$encryption" == "No" ] && [ "$homeSize" != "full" ] && echo n; echo ; echo ; echo +"$homeSize"; 40 | [ "$lvm" == "No" ] && [ "$encryption" == "No" ] && [ "$homeSize" == "full" ] && echo n; echo ; echo ; echo ; 41 | echo w; 42 | ) | fdisk -w always "$diskInput" || 43 | { commandFailure="Writing partition table to disk has failed." ; die ; } 44 | 45 | # if idvar is unset, the following will set partition variables to, for example, sda1 instead of sdap1 (or more appropriately, nvme0n1p1 or likewise) 46 | # if you see this and can think of a less stupid name for this variable, feel free to make a PR 47 | if [[ "$diskInput" == /dev/nvme* ]] || [[ "$diskInput" == /dev/mmcblk* ]]; then 48 | idvar="p" 49 | fi 50 | 51 | esp="$diskInput""$idvar"1 52 | 53 | [ "$lvm" == "Yes" ] && 54 | root="$diskInput""$idvar"2 55 | 56 | [ "$filesystem" == "btrfs" ] && 57 | root="$diskInput""$idvar"2 58 | 59 | if [ "$lvm" == "No" ] && [ "$swapStyle" == "partition" ]; then 60 | root="$diskInput""$idvar"3 61 | else 62 | root="$diskInput""$idvar"2 63 | fi 64 | 65 | [ "$lvm" == "No" ] && [ "$swapStyle" == "partition" ] && 66 | swap="$diskInput""$idvar"2 67 | 68 | [ "$lvm" == "No" ] && [ -n "$homeSize" ] && [ "$encryption" == "No" ] && [ -n "$swap" ] && 69 | home="$diskInput""$idvar"4 70 | 71 | [ "$lvm" == "No" ] && [ -n "$homeSize" ] && [ "$encryption" == "No" ] && [ -z "$swap" ] && 72 | home="$diskInput""$idvar"3 73 | 74 | mkfs.vfat "$esp" || 75 | { commandFailure="Formatting ESP as vfat has failed." ; die ; } 76 | 77 | if [ "$encryption" == "Yes" ] && [ "$filesystem" != "zfs" ]; then 78 | 79 | [ -z "$hash" ] && 80 | hash="sha512" 81 | 82 | [ -z "$keysize" ] && 83 | keysize="512" 84 | 85 | [ -z "$itertime" ] && 86 | itertime="10000" 87 | 88 | clear 89 | echo -e "${YELLOW}Enter your encryption passphrase here.${NC}" 90 | commandFailure="Encrypting partition has failed." 91 | case "$bootloader" in 92 | grub) 93 | while : ; do 94 | cryptsetup luksFormat --type luks1 --batch-mode --verify-passphrase --hash "$hash" --key-size "$keysize" --iter-time "$itertime" --pbkdf pbkdf2 --use-urandom "$root" 95 | [ "$?" -eq 0 ] && break 96 | done 97 | ;; 98 | *) 99 | while : ; do 100 | cryptsetup luksFormat --type luks2 --batch-mode --verify-passphrase --hash "$hash" --key-size "$keysize" --iter-time "$itertime" --pbkdf argon2id --use-urandom "$root" 101 | [ "$?" -eq 0 ] && break 102 | done 103 | ;; 104 | esac 105 | 106 | echo -e "${YELLOW}Opening new encrypted partition...${NC}" 107 | while : ; do 108 | cryptsetup luksOpen "$root" void 109 | [ "$?" -eq 0 ] && break 110 | done 111 | 112 | if [ "$lvm" == "Yes" ]; then 113 | vgcreate void /dev/mapper/void || 114 | { commandFailure="Creating volume group has failed." ; die ; } 115 | fi 116 | 117 | else 118 | if [ "$lvm" == "Yes" ]; then 119 | commandFailure="Creating volume group has failed." 120 | pvcreate "$root" || die 121 | vgcreate void "$root" || die 122 | fi 123 | fi 124 | 125 | if [ "$filesystem" == "btrfs" ]; then 126 | case "$encryption" in 127 | Yes) 128 | mkfs.btrfs -L Void /dev/mapper/void || die 129 | mount -o "$btrfsopts" /dev/mapper/void /mnt || die 130 | ;; 131 | No) 132 | mkfs.btrfs -L Void "$root" || die 133 | mount -o "$btrfsopts" "$root" /mnt || die 134 | ;; 135 | esac 136 | 137 | btrfs su cr /mnt/@ || die 138 | 139 | [ "$createHome" == "Yes" ] && 140 | { btrfs su cr /mnt/@home || die ; } 141 | 142 | btrfs su cr /mnt/@snapshots || die 143 | 144 | [ "$swapStyle" == "swapfile" ] && 145 | { btrfs su cr /mnt/@swap || die ; } 146 | 147 | btrfs su cr /mnt/@var || die 148 | 149 | umount /mnt || die 150 | elif [ "$filesystem" == "zfs" ]; then 151 | commandFailure="Creating zpool has failed." 152 | 153 | if [ "$encryption" == "Yes" ] ; then 154 | 155 | # attempting to calculate this based on time is a fruitless endeavour 156 | # default to 1 mil unless otherwise specified by the user 157 | [ -z "$zfsiters" ] && 158 | zfsiters="1000000" 159 | 160 | clear 161 | while [ -z "$zfscryptpass" ] ; do 162 | echo -e "${YELLOW}Enter your encryption passphrase here: (Minimum 8 characters)${NC}" 163 | read -s zfscryptpass 164 | 165 | echo -e "${YELLOW}Enter your encryption passphrase again to confirm:${NC}" 166 | read -s zfscryptpassconfirm 167 | 168 | if [ "${#zfscryptpass}" -lt 8 ]; then 169 | echo -e "${RED}Passphrase must be at least 8 characters in length. Try again.${NC}" 170 | unset zfscryptpass zfscryptpassconfirm 171 | fi 172 | 173 | if [ "$zfscryptpass" != "$zfscryptpassconfirm" ] ; then 174 | echo -e "${RED}Passphrases do not match. Try again.${NC}" 175 | unset zfscryptpass zfscryptpassconfirm 176 | fi 177 | done 178 | 179 | commandFailure="Creating zroot.key has failed." 180 | echo "$zfscryptpass" > /etc/zfs/zroot.key || die 181 | chmod 000 /etc/zfs/zroot.key || die 182 | 183 | # best to explicitly discard these 184 | unset zfscryptpass zfscryptpassconfirm 185 | 186 | echo "Creating encrypted zpool..." 187 | fi 188 | 189 | # https://docs.zfsbootmenu.org/en/v3.0.x/guides/void-linux/uefi.html#create-the-zpool 190 | partVar=$(blkid -o value -s PARTUUID "$root") 191 | if [ "$encryption" == "Yes" ]; then 192 | zpool create -f -o ashift=12 \ 193 | -O compression="$compressionType" \ 194 | -O acltype=posixacl \ 195 | -O xattr=sa \ 196 | -O relatime=on \ 197 | -O encryption=aes-256-gcm \ 198 | -O keylocation=file:///etc/zfs/zroot.key \ 199 | -O keyformat=passphrase \ 200 | -O pbkdf2iters="$zfsiters" \ 201 | -o autotrim=on \ 202 | -o compatibility=openzfs-2.1-linux \ 203 | -m none zroot /dev/disk/by-partuuid/"$partVar" || 204 | { commandFailure="Creating zpool has failed." ; die ; } 205 | else 206 | zpool create -f -o ashift=12 \ 207 | -O compression="$compressionType" \ 208 | -O acltype=posixacl \ 209 | -O xattr=sa \ 210 | -O relatime=on \ 211 | -o autotrim=on \ 212 | -o compatibility=openzfs-2.1-linux \ 213 | -m none zroot /dev/disk/by-partuuid/"$partVar" || 214 | { commandFailure="Creating zpool has failed." ; die ; } 215 | fi 216 | 217 | echo -e "${YELLOW}Enter your encryption passphrase to unlock zroot:${NC}" 218 | 219 | commandFailure="Creating ZFS filesystems has failed." 220 | zfs create -o mountpoint=none zroot/ROOT || die 221 | zfs create -o mountpoint=/ -o canmount=noauto zroot/ROOT/void || die 222 | 223 | [ "$createHome" == "Yes" ] && 224 | { zfs create -o mountpoint=/home zroot/home || die ; } 225 | 226 | commandFailure="Re-importing zpool has failed." 227 | zpool export zroot || die 228 | zpool import -N -R /mnt zroot || die 229 | 230 | [ "$encryption" == "Yes" ] && 231 | { zfs load-key -L prompt zroot || die ; } 232 | 233 | zfs mount zroot/ROOT/void || die 234 | zfs mount -a || die 235 | 236 | # Cache file, see https://docs.voidlinux.org/installation/guides/zfs.html 237 | commandFailure="Creating ZFS pool cache file has failed." 238 | mkdir -p /mnt/etc/zfs || die 239 | zpool set cachefile=/mnt/etc/zfs/zpool.cache zroot || die 240 | 241 | udevadm trigger || die 242 | fi 243 | 244 | if [ "$swapStyle" == "partition" ]; then 245 | commandFailure="Creating swap partition has failed." 246 | if [ "$lvm" == "Yes" ]; then 247 | lvcreate --name swap -L "$swapSize" void || die 248 | mkswap /dev/void/swap || die 249 | else 250 | mkswap "$swap" || die 251 | fi 252 | fi 253 | 254 | if [ "$rootSize" == "full" ] && [ "$lvm" == "Yes" ]; then 255 | lvcreate --name root -l 100%FREE void || 256 | { commandFailure="Creating root LV has failed." ; die ; } 257 | elif [ "$rootSize" != "full" ] && [ "$lvm" == "Yes" ]; then 258 | lvcreate --name root -L "$rootSize" void || 259 | { commandFailure="Creating root LV has failed." ; die ; } 260 | fi 261 | 262 | [ "$lvm" == "Yes" ] && 263 | case "$filesystem" in 264 | xfs) mkfs.xfs /dev/void/root || die ;; 265 | ext4) mkfs.ext4 /dev/void/root || die ;; 266 | esac 267 | 268 | if [ "$lvm" == "No" ] && [ "$encryption" == "Yes" ]; then 269 | case "$filesystem" in 270 | xfs) mkfs.xfs /dev/mapper/void || die ;; 271 | ext4) mkfs.ext4 /dev/mapper/void || die ;; 272 | esac 273 | elif [ "$lvm" == "No" ] && [ "$encryption" == "No" ]; then 274 | case "$filesystem" in 275 | xfs) mkfs.xfs "$root" || die ;; 276 | ext4) mkfs.ext4 "$root" || die ;; 277 | esac 278 | fi 279 | 280 | if [ -n "$homeSize" ] && [ "$lvm" == "Yes" ]; then 281 | commandFailure="Creating home LV has failed." 282 | if [ -n "$homeSize" ]; then 283 | if [ "$homeSize" == "full" ]; then 284 | lvcreate --name home -l 100%FREE void || die 285 | else 286 | lvcreate --name home -L "$homeSize" void || die 287 | fi 288 | 289 | case "$filesystem" in 290 | xfs) mkfs.xfs /dev/void/home || die ;; 291 | ext4) mkfs.ext4 /dev/void/home || die ;; 292 | esac 293 | fi 294 | elif [ -n "$home" ] && [ "$lvm" == "No" ]; then 295 | commandFailure="Formatting home partition has failed." 296 | case "$filesystem" in 297 | xfs) mkfs.xfs "$home" || die ;; 298 | ext4) mkfs.ext4 "$home" || die ;; 299 | esac 300 | fi 301 | 302 | commandFailure="Mounting partitions has failed." 303 | [ "$lvm" == "Yes" ] && 304 | { mount /dev/void/root /mnt || die ; } 305 | 306 | [ "$lvm" == "No" ] && [ "$encryption" == "Yes" ] && [ "$filesystem" != "zfs" ] && 307 | { mount /dev/mapper/void /mnt || die ; } 308 | 309 | [ "$lvm" == "No" ] && [ "$encryption" == "No" ] && [ "$filesystem" != "zfs" ] && 310 | { mount "$root" /mnt || die ; } 311 | 312 | [ "$lvm" == "No" ] && [ -n "$home" ] && [ "$filesystem" != "btrfs" ] && [ "$filesystem" != "zfs" ] && 313 | { mkdir /mnt/home ; mount "$home" /mnt/home || die ; } 314 | 315 | [ "$lvm" == "Yes" ] && [ -e "/dev/mapper/void-home" ] && 316 | { mkdir /mnt/home ; mount /dev/mapper/void-home /mnt/home || die ; } 317 | 318 | if [ "$filesystem" == "btrfs" ]; then 319 | case "$encryption" in 320 | Yes) 321 | mount -o "$btrfsopts",subvol=@ /dev/mapper/void /mnt || die 322 | 323 | mkdir /mnt/.snapshots || die 324 | 325 | [ "$createHome" == "Yes" ] && 326 | { mkdir /mnt/home ; mount -o "$btrfsopts",subvol=@home /dev/mapper/void /mnt/home || die ; } 327 | 328 | mount -o "$btrfsopts",subvol=@snapshots /dev/mapper/void /mnt/.snapshots || die 329 | 330 | [ "$swapStyle" == "swapfile" ] && 331 | { mkdir /mnt/swap ; mount -o rw,nodatacow,compress=none,subvol=@swap /dev/mapper/void /mnt/swap || die ; } 332 | 333 | mkdir -p /mnt/var ; mount -o "$btrfsopts",nodatacow,subvol=@var /dev/mapper/void /mnt/var || die 334 | ;; 335 | No) 336 | mount -o "$btrfsopts",subvol=@ "$root" /mnt || die 337 | 338 | mkdir /mnt/.snapshots || die 339 | 340 | [ "$createHome" == "Yes" ] && 341 | { mkdir /mnt/home ; mount -o "$btrfsopts",subvol=@home "$root" /mnt/home || die ; } 342 | 343 | mount -o "$btrfsopts",subvol=@snapshots "$root" /mnt/.snapshots || die 344 | 345 | [ "$swapStyle" == "swapfile" ] && 346 | { mkdir /mnt/swap ; mount -o rw,nodatacow,compress=none,subvol=@swap "$root" /mnt/swap || die ; } 347 | 348 | mkdir -p /mnt/var ; mount -o "$btrfsopts",nodatacow,subvol=@var "$root" /mnt/var || die 349 | ;; 350 | esac 351 | 352 | for i in root tmp srv ; 353 | do 354 | btrfs su cr /mnt/"$i" || 355 | { commandFailure="Spawning btrfs subvol /mnt/$i has failed." ; die ; } 356 | done 357 | 358 | mkdir /mnt/usr || die 359 | btrfs su cr /mnt/usr/local || die 360 | 361 | [ "$bootloader" == "grub" ] && 362 | { mkdir -p /mnt/boot/grub ; btrfs su cr /mnt/boot/grub/x86_64-efi || die ; } 363 | fi 364 | 365 | # TODO: xchroot can deal with mounting these. 366 | for dir in dev proc sys run; do mkdir -p /mnt/$dir ; mount --rbind /$dir /mnt/$dir ; mount --make-rslave /mnt/$dir ; done || die 367 | 368 | mkdir -p /mnt/boot/efi || die 369 | mount "$esp" /mnt/boot/efi || die 370 | 371 | return 0 372 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # void-install-script 2 | TUI Shell script installer for Void Linux 3 | 4 | This installer was primarily created to serve as an installer with encryption support while also having general installation options one would want, with sane defaults. 5 | 6 | The overall goal of this installer is to deploy a system that is ready to use as soon as the installer exits. 7 | 8 | At the moment, this installer does not have stable releases. The most recent commit should be considered the most recent stable release. Of course, if you run into bugs, please create an issue. (Or, if you're inclined, create a pull request to fix it.) 9 | 10 | This script is not officially supported. Any issues should be filed here as opposed to any official Void Linux support area- if you're not sure if the issue you're facing stems from this installer, it would be best to create an issue on this repository before asking in the Void IRC or making a post on the subreddit. 11 | 12 | ![TUI Image](https://github.com/kkrruumm/void-install-script/blob/main/images/tuiscreenshot.png) 13 | 14 | # Features 15 | ``` 16 | -Option to add user-created modules to be executed by the installer, see modules notes 17 | -Included modules do various things, a few included ones: 18 | --Option to enable system logging with socklog 19 | --Option to install wifi firmware and basic utilities 20 | --Option to install Flatpak with Flathub repository 21 | --Option to install and preconfigure qemu and libvirt 22 | --Option to install nftables with a default firewall config 23 | --Various security related modules 24 | 25 | -Option to choose between grub, zfsbootmenu (with zfs only), and UKI to boot the system 26 | -Option to choose between dracut and tinyramfs (without zfs) initramfs generators 27 | 28 | -Option to encrypt installation disk 29 | --With UKI setup, encryption will encrypt both /boot and / using luks2 30 | --With grub setup, encryption will encrypt both /boot and / using luks1 31 | 32 | -Option to pre-install and pre-configure the following: 33 | --Graphics drivers (amd, nvidia, intel, nvidia-nouveau, none) 34 | --Networking (dhcpcd, NetworkManager, none) 35 | --Audio server (pipewire, pulseaudio, none) 36 | 37 | --DE or WM (gnome, i3, kde, mate, niri, river, sway, swayfx, wayfire, xfce, none) 38 | ---With i3, there is an option to install lightdm 39 | ---With sway, swayfx, wayfire, and niri there is an option to install greetd 40 | 41 | --Or, choose to do none of these and install a bare-minimum system 42 | 43 | -Option to choose between xfs, ext4, zfs, and btrfs filesystems 44 | 45 | -Option to choose between LVM and a traditional install 46 | -Option to choose between zram, swap partition, and normal swapfile 47 | -Option to securely erase the installation disk with shred 48 | -Option to choose between doas or sudo 49 | -Option to choose your repository mirror 50 | -Option to choose between linux, linux-lts, and linux-mainline kernels 51 | -Configure partitions in the installer for home, swap, and root with LVM 52 | -Support for both glibc and musl 53 | -User creation and basic configuration 54 | -Custom post_install functionality 55 | ``` 56 | 57 | # Instructions 58 | 59 | 1. Boot into a Void Linux live medium 60 | 2. Login as `anon` with password `voidlinux` 61 | 3. Run the following commands: 62 | - `sudo xbps-install -Su` 63 | - `sudo xbps-install -S git` 64 | - `git clone https://github.com/kkrruumm/void-install-script.git` 65 | - `cd void-install-script` 66 | - `sudo ./viss` 67 | 4. Follow on-screen steps 68 | 5. Done. 69 | 70 | # UKI notes 71 | 72 | UKI setup *will* provide full-disk-encryption as both / and /boot will be encrypted with luks2. 73 | 74 | Do keep in mind potential security issues regarding weaker key derivation functions, such as pbkdf2 which is used with luks1, rather than argon2id with luks2. 75 | 76 | UKIs *can* both be a bit touchy on some (non entirely UEFI standards compliant) motherboards, though this doesn't seem to be much of a problem as long as we "trick" boards into not deleting the boot entry. 77 | 78 | The default UKI location is ``/boot/efi/EFI/boot/bootx64.efi``, and it is recommended to leave it in this location so as to not have to regenerate the boot entry with efibootmgr, but also to maintain compatibility with spotty UEFI implementations. 79 | 80 | With UKIs, kernel parameters are set in ``/etc/kernel.d/post-install/60-ukify``, to update these, modify this file and run a reconfigure on your kernel. 81 | 82 | # Modules notes 83 | 84 | A barebones "module" system has been added to the installer to make adding misc features simpler and more organized. 85 | 86 | To create a module, create a file in the 'modules' directory that comes with this installer, its name should be the title of your module. 87 | 88 | Then, add at minimum the 3 required variables and 1 required function to this file. 89 | If any of the 3 required variables or the 1 required function are missing, the installer will not import the module. 90 | 91 | Example module file contents: 92 | 93 | ``` 94 | title=nameofmymodule 95 | description="- This module does XYZ" 96 | status=off 97 | 98 | main() { 99 | # Do cool stuff here 100 | } 101 | ``` 102 | 103 | The title variable here will both be the name of the entry in the TUI, but also the name of the file the installer will look for. 104 | 105 | The description variable will be the extra information given to the user in the TUI along with the option and can be left empty, but must exist. 106 | 107 | The status variable tells the installer whether or not the module should be enabled or disabled by default, valid values are on/off. 108 | 109 | Inside of the main() function, you're free to add any commands you'd like to be executed, and you can access all variables set by the primary install script. 110 | 111 | If the module script requires a certain value that may or may not be set by the user, you may check if this variable is set at the top of the module file, and return 1 if it is not. If a module returns 1, it will not be shown in the modules menu. The esync module is an example of this as it requires a username in order to function. 112 | 113 | If your module changes kernel parameters, and you make use of the setKernelParam wrapper function, the installer will automatically run ``update-grub`` or rebuild the UKI once all of the modules have run. 114 | 115 | That's it! 116 | 117 | Feel free to check out some of the installers included modules for further example. 118 | 119 | # Hidden installer options 120 | 121 | There are a few options that aren't exposed directly to the user because they can potentially be dangerous, but can be changed by creating a file that sets these variables and adding it as a flag when executing the installer. 122 | 123 | This feature is also how one may define a `post_install` function to run whatever commands they like as the final thing the installer does. 124 | 125 | Example: 126 | ``` 127 | ./viss /path/to/file 128 | ``` 129 | 130 | Such file would contain any or all of the following options, and the following examples are set to their default values: 131 | 132 | ``` 133 | acpi="true" 134 | intel_pstate="true" 135 | hash="sha512" 136 | keysize="512" 137 | itertime="10000" 138 | zfsiters="1000000" 139 | basesystem="base-system" # Define base system packages instead of using metapackage 140 | initrdhostonly="false" 141 | 142 | post_install() { 143 | # do post-install stuff here 144 | } 145 | ``` 146 | 147 | If none of these variables are set in the file, or no file is provided, the above defaults will be used. 148 | 149 | - The toggle for ACPI can be set to false if you are facing ACPI related issues. This will set the `acpi=off` kernel parameter on the new install. Do not change this setting unless absolutely necessary. 150 | 151 | - The toggle for `intel_pstate` can be set to false if you would like to disable intels power management. This is particularly useful on laptops to gain access to the "ondemand" governor and otherwise. This will set the `intel_pstate=disable` kernel parameter on the new install. 152 | 153 | - `hash`, `keysize`, and `itertime` are all variables that change the LUKS settings for encrypted installations. 154 | 155 | I do not recommend changing hash and keysize from their default values unless you are absolutely certain you would like to. Research this before changing values. 156 | 157 | itertime is a bit less strict. As a TL;DR, the higher this value is, the longer brute-forcing this drive should take. 158 | 159 | The value here will equal the amount of time it takes to unlock the drive in milliseconds calculated for the system this is ran on. If this drive is then put into a system with a faster CPU, it will unlock quicker. 160 | 161 | The LUKS default is "2000", or 2 seconds. The default in this installer has been raised with systems that have slower CPUs (and users that are more security conscious) in mind. 162 | 163 | The fips140 compliant value here would be 600000 according to owasp, though this would result in a 10 minute disk unlock time. 164 | 165 | - `zfsiters` sets the specific amount of iterations for the pbkdf2 kdf used by ZFS, as ZFS does not have a built in way to calculate this based on the amount of time the user would like to wait. Raise or lower as desired, with the same implications as itertime with LUKS. 166 | 167 | - `initrdhostonly` will instruct the initramfs generator to generate a host-specific initramfs image when set to `true`. 168 | 169 | - The `post_install` function may be defined if the user would like to run custom commands once installation has completed. 170 | 171 | This function does not need to be defined, but if it is, this will be the last task the installer handles. This function has access to all of the variables defined by the installer, and has access to wrapper commands such as `system`, `install`, and `setKernelParam`. 172 | 173 | A cool thing that could be done with this file (and as part of this post_install function) is switching based on which device the installer is being run on, do see [my file](https://github.com/kkrruumm/void-basesystem) for an example of this. 174 | 175 | Outside of options that are potentially dangerous, "random" features that do not fit elsewhere can be added via this. 176 | 177 | # zfs notes 178 | 179 | ZFS support in this installer is considered highly experimental, and testing is needed. The deployed setup is likely to change over time. 180 | 181 | If you would like to use ZFS, grab the [hrmpf](https://github.com/leahneukirchen/hrmpf/releases) ISO as detailed in the Void Linux [documentation](https://docs.voidlinux.org/installation/guides/zfs.html#installation-media), which includes the necessary things to deploy ZFS by default. Alternatively, one may build a Void Linux ISO manually that includes ZFS. 182 | 183 | This installer is tested against the latest hrmpf image, and is the expected and recommended ISO to use when deploying ZFS. 184 | 185 | For the time being, the only supported boot setup with ZFS is via [zfsbootmenu](https://github.com/zbm-dev/zfsbootmenu). 186 | 187 | The only supported encryption setup is via ZFS native encryption, as zbm is currently unable to handle luks in this context by default. However, there are some [implications](https://forums.truenas.com/t/truenas-zfs-encryption-deduplication-for-home-server/13589/3) with ZFS native encryption the user should be aware of. 188 | 189 | By default, the installer will bump the default amount of pbkdf iterations to 1,000,000 from 350,000. This is a specific amount of iterations due to ZFS' lack of ability to calculate based on the amount of time the user desires to wait, as opposed to something like LUKS. 190 | 191 | The only supported swap method out of the box via this installer is zram due to ZFS [limitations](https://github.com/openzfs/zfs/issues/7734). 192 | 193 | # btrfs notes 194 | 195 | Do note that btrfs support in this installer is still considered experimental, meaning the deployed setup is likely to change over time. 196 | 197 | Currently, the btrfs option will deploy a "typical" btrfs setup, with the following subvolumes: 198 | 199 | - `@` - root 200 | - `@home` - created if the user chooses to split off home 201 | - `@snapshots` - mounted at `/.snapshots` 202 | - `@swap` - created to disable compression as it seems like the `+m` attribute is currently non functional, mounted at `/swap` 203 | - `@var` - copy-on-write disabled 204 | 205 | A few other subvolumes are created, because the contents of which typically are undesired as part of snapshots and/or their contents should persist through rollbacks: 206 | 207 | - `/root` 208 | - `/tmp` 209 | - `/srv` 210 | - `/usr/local` 211 | - `/boot/grub/x86_64-efi` - only if grub is the chosen bootloader 212 | 213 | To some extent, this script tries to mirror the OpenSUSE btrfs setup, which is detailed [here](https://en.opensuse.org/SDB:BTRFS). 214 | 215 | # Wrappers 216 | 217 | There are wrapper functions for a handful of things, such as ``install`` and ``system``. 218 | 219 | ``system command`` will run "command" on the new install via chroot for enabling services or otherwise, rather than repetitively entering full chroot commands. This wrapper does not need to ``|| die``, as this is handled in the function that is called, however, ``commandFailure`` must be set before ``system command`` is run if the command should provide a specific output on command failure. 220 | 221 | ``install package`` will install "package" on the new install, and also does not need to ``|| die``, as this is handled in the ``install`` function, and also must have ``commandFailure`` set before the command is run if it should return a specific output on command failure. 222 | 223 | ``setKernelParam "parameter"`` will add ``parameter`` to the new installations kernel parameters, does not need to ``|| die``, and also must have ``commandFailure`` set before the command is run if it should return a specific output on command failure. 224 | 225 | All of the current and future wrapper functions will be located in ``misc/libviss``. 226 | 227 | # Misc notes 228 | 229 | This installer only supports x86_64-efi. I currently have no plans to support anything else. 230 | 231 | If you have found this script useful, do star this repository! 232 | 233 | # Contributing 234 | 235 | The best way to contribute to this would be to create a pull request adding the feature you would like. 236 | 237 | If you would like a change to be made to the script, a request/suggestion in the issues tracker is also a wonderful place to start. 238 | 239 | There *are* a few things to keep in mind- 240 | 241 | - No tab characters. Using 4 spaces in place of tab characters is appropriate. 242 | - Try to follow the scripting and formatting style of the script in general, in order to keep things consistent. 243 | - Contribute with the mindset that although something may be merged, it also may be mercilessly edited/modified/removed later. 244 | 245 | # TODO 246 | - Add manual partitioning 247 | - Split security modules into their own menu 248 | - Add more bootloader choices such as limine and systemd-boot 249 | - You tell me, or, open a PR adding what you want. 250 | -------------------------------------------------------------------------------- /setup/base: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | commandFailure="Copying XBPS keys has failed." 4 | mkdir -p /mnt/var/db/xbps/keys || die 5 | cp /var/db/xbps/keys/* /mnt/var/db/xbps/keys || die 6 | 7 | commandFailure="Base system installation has failed." 8 | 9 | case "$basesystem" in 10 | base-system) 11 | XBPS_ARCH=$ARCH install base-system 12 | 13 | [ "$lvm" == "Yes" ] && 14 | install lvm2 15 | 16 | # Forcing zfs native crypt for the time being. 17 | [ "$filesystem" != "zfs" ] && 18 | { [ "$encryption" == "Yes" ] && install cryptsetup ; } 19 | 20 | if [ "$kernel" != "linux" ] ; then 21 | echo "ignorepkg=linux" >> /mnt/etc/xbps.d/ignore.conf || die 22 | install "$kernel" 23 | system "xbps-remove -ROoy linux" 24 | 25 | # having any kernel around except for the target will confuse setup/chroot 26 | # when it goes to find the kernel to reconfigure when building a UKI 27 | system "vkpurge rm all" # use vkpurge to clean up /boot 28 | fi 29 | 30 | if [ "$su" != "sudo" ]; then 31 | echo "ignorepkg=sudo" >> /mnt/etc/xbps.d/ignore.conf || die 32 | system "xbps-remove -ROoy sudo" 33 | fi 34 | 35 | if [ "$initrd" != "dracut" ]; then 36 | echo "ignorepkg=dracut" >> /mnt/etc/xbps.d/ignore.conf || die 37 | system "xbps-remove -ROoy dracut" 38 | 39 | install "$initrd" 40 | else 41 | install binutils # allow dracut to strip the initramfs 42 | fi 43 | 44 | [ "$su" == "doas" ] && 45 | install opendoas 46 | 47 | if [[ ! ${modules[@]} =~ "wifi-firmware" ]]; then 48 | echo "ignorepkg=wifi-firmware" >> /mnt/etc/xbps.d/ignore.conf || die 49 | echo "ignorepkg=iw" >> /mnt/etc/xbps.d/ignore.conf || die 50 | echo "ignorepkg=wpa_supplicant" >> /mnt/etc/xbps.d/ignore.conf || die 51 | 52 | system "xbps-remove -ROoy wifi-firmware iw wpa_supplicant" 53 | fi 54 | ;; 55 | *) 56 | XBPS_ARCH=$ARCH install $basesystem 57 | 58 | install "$kernel" 59 | 60 | [ "$filesystem" != "zfs" ] && 61 | { [ "$encryption" == "Yes" ] && install cryptsetup ; } 62 | 63 | [ "$lvm" == "Yes" ] && 64 | install lvm2 65 | 66 | case "$su" in 67 | sudo) install sudo ;; 68 | doas) install opendoas ;; 69 | esac 70 | 71 | # despite defining a custom basesystem, dracut is likely 72 | # to be pulled in as a dependency, ignore it and remove 73 | # if it exists: 74 | if [ "$initrd" != "dracut" ]; then 75 | echo "ignorepkg=dracut" >> /mnt/etc/xbps.d/ignore.conf || die 76 | system "xbps-remove -ROoy dracut" 77 | fi 78 | 79 | install "$initrd" 80 | 81 | [ "$initrd" == "dracut" ] && 82 | install binutils # allow dracut to strip the initramfs 83 | 84 | install dosfstools 85 | 86 | # zfsbootmenu will automatically pull in zfs 87 | case "$filesystem" in 88 | xfs) install xfsprogs ;; 89 | ext4) install e2fsprogs ;; 90 | btrfs) install btrfs-progs ;; 91 | esac 92 | ;; 93 | esac 94 | 95 | # clean up any packages in xbps cache that were removed by above 96 | system "xbps-remove -ROO" 97 | 98 | [ -n "$bootloader" ] && [ "$bootloader" != "none" ] && 99 | commandFailure="Bootloader package installation has failed" 100 | 101 | case "$bootloader" in 102 | uki) install efibootmgr ukify systemd-boot-efistub ;; 103 | grub) install grub-x86_64-efi ;; 104 | zfsbootmenu) install zfsbootmenu systemd-boot-efistub efibootmgr ;; 105 | esac 106 | 107 | if [ "$bootloader" == "zfsbootmenu" ]; then 108 | commandFailure="Copying hostid to the new install has failed." 109 | cp /etc/hostid /mnt/etc || die 110 | 111 | [ "$encryption" == "Yes" ] && 112 | { commandFailure="Copying zroot key to the new install has failed." ; cp /etc/zfs/zroot.key /mnt/etc/zfs || die ; } 113 | fi 114 | 115 | commandFailure="Creating $kernel virtualpkg has failed." 116 | case "$kernel" in 117 | linux-lts) echo "virtualpkg=linux-headers:linux-lts-headers" >> /mnt/etc/xbps.d/headers.conf || die ;; 118 | linux-mainline) echo "virtualpkg=linux-headers:linux-mainline-headers" >> /mnt/etc/xbps.d/headers.conf || die ;; 119 | esac 120 | 121 | if [ "$repository" != "https://repo-default.voidlinux.org/current" ] && [ "$repository" != "https://repo-default.voidlinux.org/current/musl" ]; then 122 | xmirror -s "$repository" -r /mnt || 123 | { commandFailure="Repository configuration has failed." ; die ; } 124 | fi 125 | 126 | commandFailure="Confuring fstab has failed." 127 | partVar=$(blkid -o value -s UUID "$esp") 128 | echo "UUID=$partVar /boot/efi vfat defaults 0 0" >> /mnt/etc/fstab || die 129 | 130 | [ "$lvm" == "Yes" ] && 131 | { echo "/dev/void/root / $filesystem defaults 0 0" >> /mnt/etc/fstab || die ; } 132 | 133 | [ "$lvm" == "No" ] && [ "$encryption" == "Yes" ] && [ "$filesystem" != "btrfs" ] && [ "$filesystem" != "zfs" ] && 134 | { partVar=$(blkid -o value -s UUID /dev/mapper/void) ; echo "UUID=$partVar / $filesystem defaults 0 0" >> /mnt/etc/fstab || die ; } 135 | 136 | if [ "$filesystem" == "btrfs" ]; then 137 | case "$encryption" in 138 | Yes) 139 | partVar=$(blkid -o value -s UUID /dev/mapper/void) 140 | echo "UUID=$partVar / $filesystem $btrfsopts,subvol=@ 0 1" >> /mnt/etc/fstab || die 141 | 142 | [ "$createHome" == "Yes" ] && 143 | { echo "UUID=$partVar /home $filesystem $btrfsopts,subvol=@home 0 2" >> /mnt/etc/fstab || die ; } 144 | 145 | echo "UUID=$partVar /.snapshots $filesystem $btrfsopts,subvol=@snapshots 0 2" >> /mnt/etc/fstab || die 146 | 147 | [ -n "$swapSize" ] && [ "$swapStyle" == "swapfile" ] && 148 | { echo "UUID=$partVar /swap $filesystem rw,nodatacow,compress=none,subvol=@swap 0 0" >> /mnt/etc/fstab || die ; } 149 | 150 | echo "UUID=$partVar /var $filesystem $btrfsopts,nodatacow,subvol=@var 0 2" >> /mnt/etc/fstab || die 151 | ;; 152 | No) 153 | partVar=$(blkid -o value -s UUID "$root") 154 | echo "UUID=$partVar / $filesystem $btrfsopts,subvol=@ 0 1" >> /mnt/etc/fstab || die 155 | 156 | [ "$createHome" == "Yes" ] && 157 | { echo "UUID=$partVar /home $filesystem $btrfsopts,subvol=@home 0 2" >> /mnt/etc/fstab || die ; } 158 | 159 | echo "UUID=$partVar /.snapshots $filesystem $btrfsopts,subvol=@snapshots 0 2" >> /mnt/etc/fstab || die 160 | 161 | [ -n "$swapSize" ] && [ "$swapStyle" == "swapfile" ] && 162 | { echo "UUID=$partVar /swap $filesystem rw,nodatacow,compress=none,subvol=@swap 0 0" >> /mnt/etc/fstab || die ; } 163 | 164 | echo "UUID=$partVar /var $filesystem $btrfsopts,nodatacow,subvol=@var 0 2" >> /mnt/etc/fstab || die 165 | ;; 166 | esac 167 | fi 168 | 169 | [ "$lvm" == "No" ] && [ "$encryption" == "No" ] && [ "$filesystem" != "btrfs" ] && [ "$filesystem" != "zfs" ] && 170 | { partVar=$(blkid -o value -s UUID "$root") ; echo "UUID=$partVar / $filesystem defaults 0 0" >> /mnt/etc/fstab || die ; } 171 | 172 | [ -n "$swapSize" ] && [ "$swapStyle" == "partition" ] && [ "$lvm" == "Yes" ] && 173 | { echo "/dev/void/swap swap swap defaults 0 0" >> /mnt/etc/fstab || die ; } 174 | 175 | [ -n "$swapSize" ] && [ "$swapStyle" == "partition" ] && [ "$lvm" == "No" ] && [ "$filesystem" != "zfs" ] && 176 | { partVar=$(blkid -o value -s UUID "$swap") ; echo "UUID=$partVar swap swap defaults 0 0" >> /mnt/etc/fstab || die ; } 177 | 178 | [ -n "$swapSize" ] && [ "$swapStyle" == "swapfile" ] && [ "$filesystem" != "btrfs" ] && 179 | { echo "/var/swapfile swap swap defaults 0 0" >> /mnt/etc/fstab || die ; } 180 | 181 | [ -n "$swapSize" ] && [ "$swapStyle" == "swapfile" ] && [ "$filesystem" == "btrfs" ] && 182 | { echo "/swap/swapfile none swap defaults 0 0" >> /mnt/etc/fstab || die ; } 183 | 184 | [ "$separateHomePossible" != "No" ] && [ -n "$homeSize" ] && [ "$lvm" == "Yes" ] && 185 | { echo "/dev/void/home /home $filesystem defaults 0 0" >> /mnt/etc/fstab || die ; } 186 | 187 | [ -n "$homeSize" ] && [ "$lvm" == "No" ] && [ "$filesystem" != "zfs" ] && 188 | { partVar=$(blkid -o value -s UUID "$home") ; echo "UUID=$partVar /home $filesystem defaults 0 0" >> /mnt/etc/fstab || die ; } 189 | 190 | if [ "$initrd" == "dracut" ]; then 191 | case "$bootloader" in 192 | uki) 193 | commandFailure="Configuring ukify kernel hook has failed." 194 | cp "$(pwd)/misc/60-ukify" /mnt/etc/kernel.d/post-install/60-ukify || die 195 | chmod 744 /mnt/etc/kernel.d/post-install/60-ukify || die 196 | 197 | commandFailure="Configuring uki base kernel parameters has failed." 198 | partVar=$(blkid -o value -s UUID "$root") 199 | [ "$lvm" == "Yes" ] && [ "$encryption" == "Yes" ] && 200 | setKernelParam "rd.luks.uuid=$partVar root=/dev/void/root rootfstype=$filesystem rw" 201 | 202 | [ "$lvm" == "Yes" ] && [ "$encryption" == "No" ] && 203 | setKernelParam "rd.lvm.vg=void root=/dev/void/root rootfstype=$filesystem rw" 204 | 205 | if [ "$lvm" == "No" ] && [ "$encryption" == "No" ]; then 206 | setKernelParam "root=UUID=$partVar rootfstype=$filesystem rw" 207 | elif [ "$lvm" == "No" ] && [ "$encryption" == "Yes" ]; then 208 | setKernelParam "rd.luks.uuid=$partVar rd.luks.name=$partVar=void-root root=/dev/mapper/void-root rootfstype=$filesystem rw" 209 | fi 210 | 211 | [ "$filesystem" == "btrfs" ] && 212 | setKernelParam "rootflags=subvol=@" 213 | ;; 214 | grub) 215 | commandFailure="Configuring grub base config has failed." 216 | if [ "$encryption" == "Yes" ]; then 217 | partVar=$(blkid -o value -s UUID "$root") 218 | [ "$lvm" == "Yes" ] && 219 | setKernelParam "rd.lvm.vg=void rd.luks.uuid=$partVar" 220 | 221 | [ "$lvm" == "No" ] && 222 | setKernelParam "rd.luks.uuid=$partVar" 223 | 224 | echo "GRUB_ENABLE_CRYPTODISK=y" >> /mnt/etc/default/grub || die 225 | 226 | echo "void UUID=$partVar /boot/volume.key luks" >> /mnt/etc/crypttab || die 227 | echo 'install_items+=" /boot/volume.key /etc/crypttab "' >> /mnt/etc/dracut.conf.d/10-crypt.conf || die 228 | fi 229 | ;; 230 | zfsbootmenu) 231 | commandFailure="Configuring zfsbootmenu has failed." 232 | zfs set org.zfsbootmenu:commandline="loglevel=4" zroot/ROOT || die 233 | [ "$encryption" == "Yes" ] && 234 | { zfs set org.zfsbootmenu:keysource="zroot/ROOT/void" zroot || die ; } 235 | 236 | commandFailure="Configuring dracut for ZFS has failed." 237 | cp "misc/zol.conf" /mnt/etc/dracut.conf.d/zol.conf || die 238 | 239 | [ "$encryption" == "Yes" ] && 240 | { echo 'install_items+=" /etc/zfs/zroot.key "' >> /mnt/etc/dracut.conf.d/zol.conf || die ; } 241 | 242 | commandFailure="Copying zbm config to new system has failed." 243 | cp "misc/zbmconfig.yaml" /mnt/etc/zfsbootmenu/config.yaml || die 244 | ;; 245 | esac 246 | 247 | [ "$initrdhostonly" == "true" ] && 248 | { echo 'hostonly="yes"' >> /mnt/etc/dracut.conf || die ; } 249 | 250 | elif [ "$initrd" == "tinyramfs" ]; then 251 | case "$bootloader" in 252 | uki) 253 | commandFailure="Configuring ukify kernel hook has failed." 254 | cp "$(pwd)/misc/60-ukify" /mnt/etc/kernel.d/post-install/60-ukify || die 255 | chmod 744 /mnt/etc/kernel.d/post-install/60-ukify || die 256 | ;; 257 | grub) 258 | commandFailure="Configuring grub base config has failed." 259 | echo "GRUB_ENABLE_CRYPTODISK=y" >> /mnt/etc/default/grub || die 260 | ;; 261 | esac 262 | 263 | # making an exception to the "style" of this script given how 264 | # spammed this path is here 265 | trfsconfig="/mnt/etc/tinyramfs/config" 266 | 267 | commandFailure="Editing tinyramfs config has failed." 268 | partVar=$(blkid -o value -s UUID "$root") 269 | sed -i '/root=/d' "$trfsconfig" || die 270 | if [ "$encryption" == "Yes" ]; then 271 | echo 'luks_name=void' >> "$trfsconfig" || die 272 | sed -i 's/hooks="eudev"/hooks="eudev,luks"/g' "$trfsconfig" || die 273 | echo "luks_root=UUID=${partVar}" >> "$trfsconfig" || die 274 | partVar=$(blkid -o value -s UUID /dev/mapper/void) 275 | 276 | # the order hooks are included in is also the order they will be executed in, 277 | # lvm must come *after* luks so tinyramfs will unlock before 278 | # attempting to activate the "void" volume group 279 | [ "$lvm" == "Yes" ] && 280 | { sed -i 's/hooks="eudev,luks"/hooks="eudev,luks,lvm"/g' "$trfsconfig" || die ; } 281 | 282 | # eliminate the need to enter passphrase twice 283 | # once /boot has been decrypted 284 | [ "$bootloader" == "grub" ] && 285 | { echo 'luks_key=/boot/volume.key' >> "$trfsconfig" || die ; } 286 | else 287 | [ "$lvm" == "Yes" ] && 288 | { sed -i 's/hooks="eudev"/hooks="eudev,lvm"/g' "$trfsconfig" || die ; } 289 | fi 290 | 291 | if [ "$lvm" == "Yes" ]; then 292 | echo 'root=/dev/void/root' >> "$trfsconfig" || die 293 | else 294 | echo "root=UUID=${partVar}" >> "$trfsconfig" || die 295 | fi 296 | 297 | [ "$filesystem" == "btrfs" ] && 298 | { echo 'root_opts="'$btrfsopts',subvol=@"' >> "$trfsconfig" ; } 299 | 300 | [ "$filesystem" != "ext4" ] && 301 | { sed -i "s/root_type=ext4/root_type=${filesystem}/g" "$trfsconfig" || die ; } 302 | 303 | [ "$initrdhostonly" == "true" ] && 304 | { echo 'hostonly=true' >> "$trfsconfig" || die ; } 305 | 306 | unset trfsconfig 307 | fi 308 | 309 | [ "$acpi" == "false" ] && 310 | { commandFailure="Disabling acpi has failed." ; setKernelParam "acpi=off" ; } 311 | 312 | [ "$intel_pstate" == "false" ] && 313 | { commandFailure="Disabling intel_pstate has failed." ; setKernelParam "intel_pstate=disable" ; } 314 | 315 | if [ "$libc" == "glibc" ]; then 316 | commandFailure="Locale configuration has failed." 317 | echo "$locale" > /mnt/etc/locale.conf || die 318 | echo "$libclocale" >> /mnt/etc/default/libc-locales || die 319 | fi 320 | 321 | echo "$hostname" > /mnt/etc/hostname || 322 | { commandFailure="Hostname configuration has failed." ; die ; } 323 | 324 | # Configure non-partition methods of swapping 325 | # I feel like this isn't really the place for this- 326 | # but neither is setup-disk or otherwise really, so: 327 | case "$swapStyle" in 328 | zram) 329 | commandFailure="Configuring zram has failed." 330 | echo "zram" >> /mnt/etc/modules-load.d/zram.conf || die 331 | echo "zramctl /dev/zram0 --algorithm lz4 --size $swapSize" >> /mnt/etc/rc.local || die 332 | echo "mkswap -U clear /dev/zram0" >> /mnt/etc/rc.local || die 333 | echo "swapon --discard --priority 100 /dev/zram0" >> /mnt/etc/rc.local || die 334 | ;; 335 | swapfile) 336 | if [ "$filesystem" != "btrfs" ]; then 337 | commandFailure="Configuring swapfile has failed." 338 | swapSize=$(echo "$swapSize" | sed 's/G//g') 339 | echo "Creating swapfile..." 340 | dd if=/dev/zero of=/mnt/var/swapfile bs=1024M count="$swapSize" status=progress || die 341 | chmod 600 /mnt/var/swapfile || die # root only. 342 | mkswap /mnt/var/swapfile || die 343 | else 344 | btrfs filesystem mkswapfile --size "$swapSize" --uuid clear /mnt/swap/swapfile || die 345 | swapon /mnt/swap/swapfile || die 346 | fi 347 | ;; 348 | esac 349 | 350 | return 0 351 | -------------------------------------------------------------------------------- /viss: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script is an "orchestrator" for the other scripts that exist in the "setup" directory, and is only responsible for setting values and displaying the TUI. 4 | # This keeps the installer cleaner and easier to manipulate. 5 | 6 | # Source installer library 7 | . "$(pwd)/misc/libviss" || 8 | { echo "$(pwd)/lib/libvis not found. Cannot continue." ; exit 1 ; } 9 | 10 | # Source basic installer setup script 11 | . "$(pwd)/setup/installer" || 12 | { commandFailure="$(pwd)/setup/installer not found. Cannot continue." ; die ; } 13 | 14 | # Source hidden settings file, if there is one. 15 | if [ "$#" == "1" ]; then 16 | . "$1" || 17 | { commandFailure="Sourcing hidden options file has failed." ; die ; } 18 | fi 19 | 20 | # Default to voids base-system unless otherwise defined in the hidden settings file 21 | [ -z "$basesystem" ] && 22 | basesystem="base-system" 23 | 24 | drawDialog --msgbox "Welcome!\n\nThis is primarily a guided installer, but at any moment you may press the 'Map' button to jump around the installer in a non-linear way, or to go back and change settings.\n\nYou may use your TAB key, arrow keys, and Enter/Return to navigate this TUI.\n\nPressing Enter now will begin the installation process, but no changes will be made to the disk until you confirm your installation settings." 0 0 25 | 26 | # Each section of the installer will have its own function, so the user can go back to a specific spot to change something. 27 | diskConfig() { 28 | local diskList=$(lsblk -d -o NAME,SIZE -n -e7) 29 | local diskIndicator=$(lsblk -o NAME,SIZE,TYPE -e7) 30 | 31 | if diskInput=$(drawDialog --begin 2 2 --title "Available Disks" --infobox "$diskIndicator" 0 0 --and-widget --title "Partitioner" --menu "The disk you choose will not be modified until you confirm your installation options.\n\nPlease choose the disk you would like to partition and install Void Linux to:" 0 0 0 $diskList) ; then 32 | diskInput="/dev/$diskInput" 33 | else 34 | exit 0 35 | fi 36 | 37 | diskSize=$(lsblk --output SIZE -n -d "$diskInput") 38 | diskFloat=$(echo "$diskSize" | sed 's/G//g') 39 | diskAvailable=$(echo "$diskFloat" - 0.5 | bc) 40 | diskAvailable+="G" 41 | 42 | local diskIndicator=$(partitionerOutput) 43 | 44 | if drawDialog --title "Partitioner - Encryption" --extra-button --extra-label "Map" --yesno "Should this installation be encrypted?" 0 0 ; then 45 | encryption="Yes" 46 | drawDialog --title "Partitioner - Wipe Disk" --yesno "Would you like to securely wipe the selected disk before setup?\n\nThis can take quite a long time depending on how many passes you choose.\n\nBe aware that doing this on an SSD is likely a bad idea." 0 0 && 47 | wipedisk=$(drawDialog --title "Partitioner - Wipe Disk" --inputbox "How many passes would you like to do on this disk?\n\nSane values include 1-3. The more passes you choose, the longer this will take." 0 0) 48 | else 49 | [ "$?" == "3" ] && dungeonmap 50 | encryption="No" 51 | fi 52 | 53 | if [ "$zfspossible" != "no" ] ; then 54 | filesystem=$(drawDialog --no-cancel --title "Partitioner - Filesystem" --extra-button --extra-label "Map" --menu "If you are unsure, choose 'ext4'" 0 0 0 "ext4" "" "xfs" "" "btrfs" "(Experimental)" "zfs" "(Experimental)") 55 | else 56 | filesystem=$(drawDialog --no-cancel --title "Partitioner - Filesystem" --extra-button --extra-label "Map" --menu "If you are unsure, choose 'ext4'" 0 0 0 "ext4" "" "xfs" "" "btrfs" "(Experimental)") 57 | fi 58 | [ "$?" == "3" ] && dungeonmap 59 | 60 | if [ "$filesystem" != "btrfs" ] && [ "$filesystem" != "zfs" ]; then 61 | if drawDialog --title "Partitioner - LVM" --extra-button --extra-label "Map" --yesno "Would you like to use LVM?" 0 0 ; then 62 | lvm="Yes" 63 | else 64 | [ "$?" == "3" ] && dungeonmap 65 | lvm="No" 66 | fi 67 | else 68 | lvm="No" 69 | 70 | if [ "$filesystem" == "btrfs" ] ; then 71 | compressionType=$(drawDialog --no-cancel --title "Partitioner - Filesystem" --extra-button --extra-label "Map" --menu "What style of compression would you like to use with btrfs?" 0 0 0 "zstd" "" "lzo" "" "zlib" "" "none" "") 72 | else 73 | compressionType=$(drawDialog --no-cancel --title "Partitioner - Filesystem" --extra-button --extra-label "Map" --menu "What style of compression would you like to use with zfs?" 0 0 0 "zstd" "" "lz4" "" "gzip" "") 74 | fi 75 | 76 | [ "$filesystem" == "btrfs" ] && 77 | if [ "$compressionType" == "None" ]; then 78 | btrfsopts="rw,noatime,nocompress,discard=async" 79 | else 80 | btrfsopts="rw,noatime,compress=$compressionType,discard=async" 81 | fi 82 | fi 83 | 84 | if drawDialog --title "Disk Details" --extra-button --extra-label "Map" --no-cancel --title "Partitioner - Swap" --yesno "Would you like to use swap?" 0 0 ; then 85 | if [ "$lvm" == "Yes" ] || [ "$encryption" == "No" ] && [ "$filesystem" != "btrfs" ] && [ "$filesystem" != "zfs" ]; then 86 | swapStyle=$(drawDialog --begin 2 2 --title "Disk Details" --infobox "$diskIndicator" 0 0 --and-widget --no-cancel --title "Partitioner - Swap" --menu "What style of swap would you like to use?\n\nIf you are unsure, 'swapfile' is recommended." 0 0 0 "swapfile" "- On-filesystem swapfile" "zram" "- RAM in your RAM, but smaller" "partition" "- Traditional swap partition" "none" "") 87 | elif [ "$filesystem" == "zfs" ] ; then 88 | swapStyle=$(drawDialog --begin 2 2 --title "Disk Details" --infobox "$diskIndicator" 0 0 --and-widget --no-cancel --title "Partitioner - Swap" --menu "What style of swap would you like to use?\n\nDue to filesystem limitations, zram is the available choice." 0 0 0 "zram" "- RAM in your RAM, but smaller" "none" "") 89 | else 90 | swapStyle=$(drawDialog --begin 2 2 --title "Disk Details" --infobox "$diskIndicator" 0 0 --and-widget --no-cancel --title "Partitioner - Swap" --menu "What style of swap would you like to use?\n\nIf you are unsure, 'swapfile' is recommended." 0 0 0 "swapfile" "- On-filesystem swapfile" "zram" "- RAM in your RAM, but smaller" "none" "") 91 | fi 92 | else 93 | [ "$?" == "3" ] && dungeonmap 94 | fi 95 | 96 | case "$swapStyle" in 97 | swapfile) swapSize=$(drawDialog --begin 2 2 --title "Disk Details" --infobox "$diskIndicator" 0 0 --and-widget --no-cancel --title "Partitioner - Swap" --inputbox "How large would you like your swapfile to be?\n(Example: '4G')" 0 0) ;; 98 | zram) swapSize=$(drawDialog --begin 2 2 --title "Disk Details" --infobox "$diskIndicator" 0 0 --and-widget --no-cancel --title "Partitioner - Swap" --inputbox "How large would you like your compressed ramdisk to be?\n(Example: '4G')" 0 0) ;; 99 | partition) 100 | swapSize=$(drawDialog --begin 2 2 --title "Disk Details" --infobox "$diskIndicator" 0 0 --and-widget --no-cancel --title "Partitioner - Swap" --inputbox "How large would you like your swap partition to be?\n(Example: '4G')" 0 0) 101 | local sizeInput=$swapSize && diskCalculator && local diskIndicator=$(partitionerOutput) 102 | ;; 103 | esac 104 | 105 | if [ "$filesystem" != "btrfs" ] && [ "$filesystem" != "zfs" ]; then 106 | rootSize=$(drawDialog --begin 2 2 --title "Disk Details" --infobox "$diskIndicator" 0 0 --and-widget --no-cancel --title "Partitioner - Root" --extra-button --extra-label "Map" --inputbox "If you would like to limit the size of your root filesystem, such as to have a separate home partition, you can enter a value such as '50G' here.\n\nOtherwise, if you would like your root partition to take up the entire drive, leave this empty and press OK." 0 0) 107 | [ "$?" == "3" ] && dungeonmap 108 | [ -z "$rootSize" ] && rootSize="full" 109 | else 110 | rootSize="full" 111 | fi 112 | 113 | if [ "$filesystem" == "btrfs" ] || [ "$filesystem" == "zfs" ]; then 114 | local separateHomePossible="Yes" 115 | elif [ "$rootSize" == "full" ]; then 116 | local separateHomePossible="No" 117 | elif [ "$lvm" == "No" ] && [ "$encryption" == "Yes" ]; then 118 | local separateHomePossible="No" 119 | else 120 | local sizeInput=$rootSize && diskCalculator && local diskIndicator=$(partitionerOutput) 121 | fi 122 | 123 | [ "$separateHomePossible" != "No" ] && 124 | if drawDialog --title "Partitioner - Home" --extra-button --extra-label "Map" --yesno "Would you like to have a separate home volume?\n\nIf using btrfs or zfs, creating a separate home is recommended." 0 0 ; then 125 | if [ "$filesystem" != "btrfs" ] && [ "$filesystem" != "zfs" ]; then 126 | homeSize=$(drawDialog --begin 2 2 --title "Disk Details" --infobox "$diskIndicator" 0 0 --and-widget --no-cancel --title "Partitioner - Home" --inputbox "How large would you like your home partition to be?\n(Example: '100G')\n\nIf you would like the home partition to take up the rest of your disk, leave this empty and press OK." 0 0) 127 | [ -z "$homeSize" ] && homeSize="full" 128 | else 129 | createHome="Yes" 130 | fi 131 | else 132 | [ "$?" == "3" ] && dungeonmap 133 | [ "$filesystem" == "btrfs" ] && 134 | createHome="No" 135 | fi 136 | 137 | suConfig 138 | } 139 | 140 | suConfig() { 141 | su=$(drawDialog --no-cancel --title "SU Choice" --extra-button --extra-label "Map" --menu "If you are unsure, choose 'sudo'" 0 0 0 "sudo" "" "doas" "" "none" "") 142 | [ "$?" == "3" ] && dungeonmap 143 | 144 | kernelConfig 145 | } 146 | 147 | kernelConfig() { 148 | if [ "$filesystem" != "zfs" ]; then 149 | kernel=$(drawDialog --no-cancel --title "Kernel Choice" --extra-button --extra-label "Map" --menu "If you are unsure, choose 'linux'" 0 0 0 "linux" "- Normal Void kernel" "linux-lts" "- Older LTS kernel" "linux-mainline" "- Bleeding edge kernel") 150 | else 151 | kernel=$(drawDialog --no-cancel --title "Kernel Choice" --extra-button --extra-label "Map" --menu "If you are unsure, choose 'linux'" 0 0 0 "linux" "- Normal Void kernel" "linux-lts" "- Older LTS kernel") 152 | fi 153 | [ "$?" == "3" ] && dungeonmap 154 | 155 | bootloaderConfig 156 | } 157 | 158 | bootloaderConfig() { 159 | [ "$filesystem" == "zfs" ] && 160 | { bootloader=zfsbootmenu && hostnameConfig ; } 161 | 162 | bootloader=$(drawDialog --no-cancel --title "Bootloader choice" --extra-button --extra-label "Map" --menu "If you are unsure, choose 'grub'" 0 0 0 "grub" "- Traditional bootloader" "uki" "- Unified Kernel Image" "none" "- Installs no bootloader (Advanced)") 163 | [ "$?" == "3" ] && dungeonmap 164 | 165 | initrdConfig 166 | } 167 | 168 | initrdConfig() { 169 | [ "$filesystem" == "zfs" ] && 170 | { initrd="dracut" && hostnameConfig ; } 171 | # TODO: need to test tinyramfs with zfs 172 | # TODO: is mkinitcpio worthwhile to include? 173 | 174 | initrd=$(drawDialog --no-cancel --title "Initramfs choice" --extra-button --extra-label "Map" --menu "If you are unsure, choose 'dracut'" 0 0 0 "dracut" "- Default Void initramfs generator" "tinyramfs" "- Small POSIX Shell initramfs generator") 175 | [ "$?" == "3" ] && dungeonmap 176 | 177 | hostnameConfig 178 | } 179 | 180 | hostnameConfig() { 181 | hostname=$(drawDialog --no-cancel --title "System Hostname" --extra-button --extra-label "Map" --inputbox "Set your system hostname." 0 0) 182 | [ "$?" == "3" ] && dungeonmap 183 | 184 | userConfig 185 | } 186 | 187 | userConfig() { 188 | username=$(drawDialog --title "Create User" --extra-button --extra-label "Map" --inputbox "What would you like your username to be?\n\nIf you do not want to create a user here, choose 'Skip'\n\nYou will be asked to set a password later." 0 0) 189 | [ "$?" == "3" ] && dungeonmap 190 | 191 | timezoneConfig 192 | } 193 | 194 | timezoneConfig() { 195 | # Most of this timezone section is taken from the normal Void installer. 196 | local areas=(Africa America Antarctica Arctic Asia Atlantic Australia Europe Indian Pacific) 197 | if area=$(IFS='|'; drawDialog --no-cancel --title "Set Timezone" --menu "" 0 0 0 $(printf '%s||' "${areas[@]}")) ; then 198 | read -a locations -d '\n' < <(find /usr/share/zoneinfo/$area -type f -printf '%P\n' | sort) || echo "Disregard exit code" 199 | local location=$(IFS='|'; drawDialog --no-cancel --title "Set Timezone" --menu "" 0 0 0 $(printf '%s||' "${locations[@]//_/ }")) 200 | fi 201 | local location=$(echo $location | tr ' ' '_') 202 | timezone="$area/$location" 203 | 204 | localeConfig 205 | } 206 | 207 | localeConfig() { 208 | 209 | [ "$libc" == "musl" ] && 210 | repositoryConfig 211 | 212 | # This line is also taken from the normal Void installer. 213 | local localeList=$(grep -E '\.UTF-8' /etc/default/libc-locales | awk '{print $1}' | sed -e 's/^#//') 214 | 215 | for i in $localeList 216 | do 217 | # We don't need to specify an item here, only a tag and print it to stdout 218 | local tmp+=("$i" $(printf '\u200b')) # Use a zero width unicode character for the item 219 | done 220 | 221 | local localeChoice=$(drawDialog --no-cancel --title "Locale Selection" --menu "Please choose your system locale." 0 0 0 ${tmp[@]}) 222 | locale="LANG=$localeChoice" 223 | libclocale="$localeChoice UTF-8" 224 | 225 | repositoryConfig 226 | } 227 | 228 | repositoryConfig() { 229 | if drawDialog --title "Repository Mirror" --extra-button --extra-label "Map" --yesno "Would you like to set your repo mirror?\n\nIf not, repo-default will be used." 0 0 ; then 230 | xmirror 231 | repository=$(cat /etc/xbps.d/*-repository-main.conf | sed 's/repository=//g') 232 | else 233 | [ "$?" == "3" ] && dungeonmap 234 | [ "$libc" == "glibc" ] && repository="https://repo-default.voidlinux.org/current" 235 | [ "$libc" == "musl" ] && repository="https://repo-default.voidlinux.org/current/musl" 236 | fi 237 | 238 | [ "$libc" == "glibc" ] && ARCH="x86_64" 239 | [ "$libc" == "musl" ] && ARCH="x86_64-musl" 240 | 241 | graphicsConfig 242 | } 243 | 244 | graphicsConfig() { 245 | if [ "$libc" == "glibc" ]; then 246 | graphics=$(drawDialog --title 'Graphics Drivers' --extra-button --extra-label "Map" --checklist 'Select graphics drivers, or choose 'Skip' if you would like to skip:' 0 0 0 'intel' '' 'off' 'intel-32bit' '' 'off' 'amd' '' 'off' 'amd-32bit' '' 'off' 'nvidia' '- Proprietary driver' 'off' 'nvidia-32bit' '' 'off' 'nvidia-nouveau' '- Nvidia Nouveau driver (experimental)' 'off' 'nvidia-nouveau-32bit' '' 'off') 247 | [ "$?" == "3" ] && dungeonmap 248 | fi 249 | 250 | if [ "$libc" == "musl" ]; then 251 | graphics=$(drawDialog --title 'Graphics Drivers' --extra-button --extra-label "Map" --checklist 'Select graphics drivers, or choose 'Skip' if you would like to skip: ' 0 0 0 'intel' '' 'off' 'amd' '' 'off' 'nvidia-nouveau' '- Nvidia Nouveau driver (experimental)' 'off') 252 | [ "$?" == "3" ] && dungeonmap 253 | fi 254 | 255 | [ -n "$graphics" ] && 256 | IFS=" " read -r -a graphicsArray <<< "$graphics" 257 | 258 | networkConfig 259 | } 260 | 261 | networkConfig() { 262 | network=$(drawDialog --no-cancel --title "Networking - DHCP client" --extra-button --extra-label "Map" --menu "If you are unsure, choose 'NetworkManager'\n\nIf 'none' is chosen, dhcpcd will still be included but not enabled." 0 0 0 "NetworkManager" "" "dhcpcd" "" "none" "") 263 | [ "$?" == "3" ] && dungeonmap 264 | 265 | audioConfig 266 | } 267 | 268 | audioConfig() { 269 | audio=$(drawDialog --no-cancel --title "Audio Server" --extra-button --extra-label "Map" --menu "If you are unsure, 'pipewire' is recommended." 0 0 0 "pipewire" "" "pulseaudio" "" "none" "") 270 | [ "$?" == "3" ] && dungeonmap 271 | 272 | desktopConfig 273 | } 274 | 275 | desktopConfig() { 276 | desktop=$(drawDialog --no-cancel --title "Desktop Environment" --extra-button --extra-label "Map" --menu "" 0 0 0 "gnome" "" "i3" "" "kde" "" "mate" "" "niri" "" "river" "" "sway" "" "swayfx" "" "wayfire" "" "xfce" "" "none" "") 277 | [ "$?" == "3" ] && dungeonmap 278 | 279 | case "$desktop" in 280 | sway|swayfx|wayfire|niri|river) drawDialog --title "" --extra-button --extra-label "Map" --yesno "Would you like to install greetd with $desktop?" 0 0 && greetd="Yes" ;; 281 | i3) drawDialog --title "" --extra-button --extra-label "Map" --yesno "Would you like to install lightdm with $desktop?" 0 0 && lightdm="Yes" ;; 282 | esac 283 | 284 | modulesConfig 285 | } 286 | 287 | modulesConfig() { 288 | # Unset to prevent duplicates 289 | [ -n "$modules" ] && 290 | unset modulesDialogArray 291 | 292 | read -a modulesList -d '\n' < <(ls modules/ | sort) 293 | 294 | for i in "${modulesList[@]}" 295 | do 296 | if [ -e "modules/$i" ] && checkModule ; then 297 | local modulesDialogArray+=("'$title' '$description' '$status'") 298 | fi 299 | done 300 | 301 | # Using dash here as a simple solution to it misbehaving when ran with bash 302 | modules=( $(sh -c "dialog --stdout --title 'Extra Options' --extra-button --extra-label "Map" --no-mouse --backtitle "https://github.com/kkrruumm/void-install-script" --checklist 'Enable or disable extra install options: ' 0 0 0 $(echo "${modulesDialogArray[@]}")") ) 303 | [ "$?" == "3" ] && dungeonmap 304 | 305 | confirm 306 | } 307 | 308 | confirm() { 309 | 310 | # Unset to prevent duplicates 311 | [ -n "$settings" ] && 312 | unset settings 313 | 314 | # Construct confirm menu 315 | # I know this is a fucking mess, but it's better than the previous in-line logic. 316 | [ "$basesystem" != "base-system" ] && 317 | settings="Base system: custom\n" 318 | 319 | settings+="Repo mirror: $repository\n" 320 | settings+="Bootloader: $bootloader\n" 321 | settings+="Kernel: $kernel\n" 322 | settings+="Initramfs: $initrd\n" 323 | settings+="Target disk: $diskInput\n" 324 | settings+="Encryption: $encryption\n" 325 | 326 | if [ "$encryption" == "Yes" ] && [ -n "$wipedisk" ]; then 327 | settings+="Disk wipe passes: $wipedisk\n" 328 | elif [ "$encryption" == "Yes" ]; then 329 | settings+="Disk wipe passes: none\n" 330 | fi 331 | 332 | [ "$filesystem" != "btrfs" ] && 333 | settings+="LVM: $lvm\n" 334 | 335 | settings+="Filesystem: $filesystem\n" 336 | 337 | [ -n "$compressionType" ] && 338 | settings+="Filesystem compression: $compressionType\n" 339 | 340 | if [ -n "$swapStyle" ]; then 341 | settings+="Swap style: $swapStyle\n" 342 | settings+="Swap size: $swapSize\n" 343 | else 344 | settings+="Swap style: none\n" 345 | fi 346 | 347 | settings+="Root size: $rootSize\n" 348 | 349 | if [ "$filesystem" != "btrfs" ]; then 350 | [ -n "$homeSize" ] && 351 | settings+="Home size: $homeSize\n" 352 | else 353 | settings+="Create split home: $createHome\n" 354 | fi 355 | 356 | settings+="Hostname: $hostname\n" 357 | settings+="Timezone: $timezone\n" 358 | 359 | [ "$libc" == "glibc" ] && 360 | settings+="Locale: $locale\n" 361 | 362 | [ -n "$username" ] && 363 | settings+="User: $username\n" 364 | 365 | [ -n "$desktop" ] && 366 | settings+="DE/WM: $desktop\n" 367 | 368 | [ -n "$network" ] && 369 | settings+="DHCP client: $network\n" 370 | 371 | [ -n "$audio" ] && 372 | settings+="Audio server: $audio\n" 373 | 374 | [ -n "$graphics" ] && 375 | settings+="Graphics drivers: $graphics\n" 376 | 377 | [ "$desktop" == "i3" ] && [ -n "$lightdm" ] && 378 | settings+="Install lightdm with i3?: $lightdm\n" 379 | 380 | for i in sway swayfx niri wayfire 381 | do 382 | if [ "$desktop" == "$i" ]; then 383 | [ -z "$greetd" ] && greetd="No" 384 | settings+="Install greetd with $desktop?: $greetd\n" 385 | break 386 | fi 387 | done 388 | 389 | [ -n "$modules" ] && 390 | settings+="Enabled modules: ${modules[@]}\n" 391 | 392 | drawDialog --yes-label "Install" --no-label "Exit" --extra-button --extra-label "Map" --title "Installation Overview" --yesno "Selecting 'Install' here will DESTROY ALL DATA on the chosen disk and install with the options below. \n\n 393 | $settings\n 394 | To change any of these settings, choose 'Map'." 0 0 395 | 396 | case $? in 397 | 0) 398 | _install 399 | ;; 400 | 1) 401 | exit 0 402 | ;; 403 | 3) 404 | dungeonmap 405 | ;; 406 | esac 407 | } 408 | 409 | dungeonmap() { 410 | waypoint=$(drawDialog --no-cancel --title "Dungeon Map" --menu "Choose a section to jump to:" 0 0 0 "Disk" "" "SU" "" "Kernel" "" "Bootloader" "" "Initramfs" "" "Hostname" "" "User" "" "Timezone" "" "Locale" "" "Repository" "" "Graphics" "" "Network" "" "Audio" "" "Desktop" "" "Modules" "" "Overview" "") 411 | 412 | case "$waypoint" in 413 | Disk) diskConfig ;; 414 | SU) suConfig ;; 415 | Kernel) kernelConfig ;; 416 | Bootloader) bootloaderConfig ;; 417 | Initramfs) initrdConfig ;; 418 | Hostname) hostnameConfig ;; 419 | User) userConfig ;; 420 | Timezone) timezoneConfig ;; 421 | Locale) localeConfig ;; 422 | Repository) repositoryConfig ;; 423 | Graphics) graphicsConfig ;; 424 | Network) networkConfig ;; 425 | Audio) audioConfig ;; 426 | Desktop) desktopConfig ;; 427 | Modules) modulesConfig ;; 428 | Overview) confirm ;; 429 | esac 430 | } 431 | 432 | _install() { 433 | . "$(pwd)"/setup/disk 434 | . "$(pwd)"/setup/base 435 | . "$(pwd)"/setup/desktop 436 | 437 | commandFailure="System chroot has failed." 438 | cp /etc/resolv.conf /mnt/etc/resolv.conf || die 439 | 440 | syschrootVarPairs=("bootloader $bootloader" \ 441 | "su $su" \ 442 | "timezone $timezone" \ 443 | "encryption $encryption" \ 444 | "diskInput $diskInput" \ 445 | "username $username" \ 446 | "desktop $desktop" \ 447 | "root $root") 448 | 449 | for i in "${syschrootVarPairs[@]}" 450 | do 451 | set -- $i || die 452 | echo "$1='$2'" >> /mnt/tmp/installerOptions || die 453 | done 454 | 455 | cp -f "$(pwd)"/misc/libviss /mnt/tmp/libviss || die 456 | cp -f "$(pwd)"/setup/chroot /mnt/tmp/chroot || die 457 | system "/bin/bash /tmp/chroot" 458 | 459 | clear 460 | 461 | [ -n "$modules" ] && 462 | for i in ${modules[@]} 463 | do 464 | . "modules/$i" || 465 | { commandFailure="Executing $i module has failed." ; die ; } 466 | main 467 | done 468 | 469 | declare -F post_install > /dev/null && 470 | { commandFailure="Executing user-defined post_install function has failed." ; post_install ; } 471 | 472 | [ "$kernelparam_update" == "true" ] && 473 | case "$bootloader" in 474 | grub) system 'update-grub' ;; 475 | uki) system 'xbps-reconfigure -f linux"$(find /boot -name vmlinuz\* | tr -d "/boot/vmlinuz-" | cut -f1,2 -d".")"' ;; 476 | esac 477 | 478 | clear 479 | 480 | if drawDialog --title "Installation Complete" --yes-label "Reboot" --extra-button --extra-label "Chroot" --no-label "Exit" --yesno "The installation has finished.\n\nIf you would like to make changes before rebooting, you may select 'Chroot' to chroot into the new system.\n\nOtherwise, you may choose 'Reboot' to reboot the system now.\n\nYou may also choose 'Exit' to drop back into the void-live shell.\n\nTotal installer runtime: ${SECONDS} seconds." 0 0 ; then 481 | reboot now 482 | else 483 | [ "$?" == "3" ] && 484 | { clear && xchroot /mnt 'bin/bash' ; } 485 | fi 486 | 487 | exit 0 488 | } 489 | 490 | diskConfig 491 | --------------------------------------------------------------------------------