406 lines
9.9 KiB
Bash
Executable File
406 lines
9.9 KiB
Bash
Executable File
#!/usr/bin/bash
|
|
|
|
# BEGIN: Helper Functions
|
|
|
|
get_disks () {
|
|
local -a FOUND_DISKS
|
|
local -n OUTPUT_VAR="${1:?"get_disks: No variable was passed through"}"
|
|
|
|
if ls /dev/?d? >/dev/null 2>&1; then
|
|
FOUND_DISKS+=( /dev/?d? )
|
|
fi
|
|
|
|
if ls /dev/nvmen? >/dev/null 2>&1 ; then
|
|
FOUND_DISKS+=( /dev/nvmen? )
|
|
fi
|
|
OUTPUT_VAR=( ${FOUND_DISKS[@]} )
|
|
}
|
|
|
|
get_choices () {
|
|
local PROMPT="$1"
|
|
local -n OUTPUT_VAR="$2"
|
|
shift 2
|
|
local -a OPTIONS=( $@ )
|
|
|
|
select item in ${OPTIONS[@]} quit; do
|
|
case $item in
|
|
quit)
|
|
return 0
|
|
;;
|
|
?)
|
|
continue
|
|
;;
|
|
*)
|
|
if [[ "$item" ]]; then
|
|
OUTPUT_VAR+=( "$item" )
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
|
|
}
|
|
|
|
get_choice () {
|
|
local PROMPT="$1"
|
|
local -n OUTPUT_VAR="$2"
|
|
shift 2
|
|
local -a OPTIONS=( $@ )
|
|
|
|
select item in ${OPTIONS[@]} quit; do
|
|
case $item in
|
|
quit)
|
|
return 0
|
|
;;
|
|
?)
|
|
continue
|
|
;;
|
|
|
|
*)
|
|
if [[ "$item" ]]; then
|
|
OUTPUT_VAR="$item"
|
|
return 0
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
|
|
}
|
|
|
|
get_yes_no () {
|
|
local PROMPT="${1:?"get_yes_no: Prompt was not provided"} "
|
|
local CHOICE_REGEX='(y|n|yes|no)'
|
|
local ANSWER
|
|
while true; do
|
|
read -p "$PROMPT" ANSWER
|
|
ANSWER="${ANSWER,,}"
|
|
|
|
if [[ "$ANSWER" =~ ^$CHOICE_REGEX$ ]]; then
|
|
case $ANSWER in
|
|
y | yes)
|
|
return 0
|
|
;;
|
|
n | no)
|
|
return 1
|
|
;;
|
|
esac
|
|
else
|
|
echo "$ANSWER is not acceptible, please try again"
|
|
fi
|
|
done
|
|
}
|
|
|
|
get_answer () {
|
|
local PROMPT="${1:?"get_answer: Prompt was not provided"}"
|
|
local -n OUTER_VAR="${2:?"get_answer: Return variable not provided"}"
|
|
local ANSWER
|
|
|
|
while true; do
|
|
read -p "$PROMPT" ANSWER
|
|
|
|
if get_yes_no "Are you sure $ANSWER is what you want? (y/n): "; then
|
|
OUTER_VAR="$ANSWER"
|
|
return
|
|
fi
|
|
done
|
|
|
|
}
|
|
|
|
# END: Helper Functions
|
|
|
|
# BEGIN: Variables
|
|
|
|
HOSTNAME=""
|
|
get_answer "What is the hostname of this machine?: " HOSTNAME
|
|
|
|
BOOT_METHOD=""
|
|
get_choice "What is your boot method?: " BOOT_METHOD BIOS EFI
|
|
|
|
DISK=""
|
|
declare -a DISKS
|
|
get_disks DISKS
|
|
get_choice "Which disk are you wanting to use? : " DISK "${DISKS[@]}"
|
|
|
|
# If the disk is a nvme drive
|
|
if [[ "$DISK" =~ ^/dev/nvmen[0-9]$ ]]; then
|
|
DISK_BASE=${DISK}p
|
|
else
|
|
DISK_BASE="${DISK}"
|
|
fi
|
|
|
|
case $BOOT_METHOD in
|
|
EFI)
|
|
EFI_PARTITION=${DISK_BASE}1
|
|
SWAP_PARTITION=${DISK_BASE}2
|
|
ROOT_PARTITION=${DISK_BASE}3
|
|
;;
|
|
|
|
BIOS)
|
|
SWAP_PARTITION=${DISK_BASE}1
|
|
ROOT_PARTITION=${DISK_BASE}2
|
|
;;
|
|
|
|
esac
|
|
## New Login creds for your new user and the root user
|
|
ROOT_PASSWORD=""
|
|
get_answer "What do you want the root password to be? : " ROOT_PASSWORD
|
|
|
|
NEW_USER=""
|
|
get_answer "What other user do you want to configure on the system? : " NEW_USER
|
|
|
|
NEW_PASSWORD=""
|
|
get_answer "What do you want the password for $NEW_USER to be? : " NEW_PASSWORD
|
|
|
|
|
|
declare -a TIMEZONES=( $( timedatectl list-timezones ) )
|
|
TIMEZONE_INFO=""
|
|
get_choice "What is your timezone? : " TIMEZONE_INFO ${TIMEZONES[@]}
|
|
|
|
declare -a LOCALES=( $( localectl list-locales ) )
|
|
LOCALE=""
|
|
get_choice "What is your locale? : " LOCALE ${LOCALES[@]}
|
|
|
|
## Commands to create disks un-interactively with fdisk
|
|
## will clean up comments later with grep command
|
|
FORMAT_DISK_COMMANDS_BIOS="
|
|
# Create MBR partition table
|
|
o
|
|
|
|
# Create Swap Partition
|
|
n
|
|
# Create Primary partition (which is technically the default anyway)
|
|
p
|
|
# Press Enter to select default partition number
|
|
|
|
# Press Enter to select default starting sector
|
|
|
|
# Allocate 8GiB for swap partition
|
|
+8GiB
|
|
# Set the type to Linux Swap (82)
|
|
t
|
|
# Press Enter to select the last partition
|
|
|
|
# Set to type 82
|
|
82
|
|
|
|
# Create Root Partition
|
|
n
|
|
# Set as Primary (default)
|
|
p
|
|
# Press Enter to select default partition number
|
|
|
|
# Press Enter to select default starting sector
|
|
|
|
# Press Enter to allocate rest of disk to root partition
|
|
|
|
# Sync changes to disk
|
|
w
|
|
"
|
|
FORMAT_DISK_COMMANDS_EFI="
|
|
# Create GPT partition table
|
|
g
|
|
|
|
# Create efi partition
|
|
n
|
|
# Enter to select default partition number
|
|
|
|
# Enter to select default first sector
|
|
|
|
# Allocate only 500 MiB for the efi partition
|
|
+500MiB
|
|
|
|
# Set partition type
|
|
t
|
|
# Set partition type to efi (1)
|
|
1
|
|
|
|
# Create Swap Partition
|
|
n
|
|
# Enter to select default partition number
|
|
|
|
# Enter to select default first sector
|
|
|
|
# Allocate 8 GiB to swap partition
|
|
+8GiB
|
|
|
|
## Set partition type to Linux Swap (19)
|
|
t
|
|
### Enter to select default (last) partition (2)
|
|
|
|
### Set Type to swap (19)
|
|
19
|
|
|
|
# Create root partition (doing single partition format)
|
|
n
|
|
# Enter to select default partition number
|
|
|
|
# Enter to select default first sector
|
|
|
|
# Press Enter to allocate remaining disk to your final partition
|
|
|
|
# No need to set partition type
|
|
# Write changes to disk
|
|
w
|
|
"
|
|
|
|
## Declaring a "named" variable allows me to access the correct commands without a conditional
|
|
declare -n FORMAT_DISK_COMMANDS="FORMAT_DISK_COMMANDS_${BOOT_METHOD}"
|
|
|
|
|
|
# END: Variables
|
|
|
|
|
|
# BEGIN: Work
|
|
|
|
## BEGIN: Pre-Chroot Work
|
|
### Format Disk
|
|
#### For this example I will be using a sata disk (/dev/sda)
|
|
COMMANDS="$(echo -e "$FORMAT_DISK_COMMANDS" | grep -v \#)"
|
|
|
|
fdisk $DISK <<< "$COMMANDS"
|
|
|
|
### Format EFI Partition
|
|
#### The efi partition (mounted at /boot/efi) Needs to be formatted as fat32
|
|
[[ "$BOOT_METHOD" == "EFI" ]] && mkfs.fat -F32 $EFI_PARTITION
|
|
|
|
### Format SWAP partition
|
|
mkswap $SWAP_PARTITION
|
|
### Activate swap partition
|
|
swapon $SWAP_PARTITION
|
|
|
|
### Format Root Partition
|
|
#### We will be formatting it with ext4 because that's the default for most use-cases, especially when new linux users are concerned
|
|
mkfs.ext4 $ROOT_PARTITION
|
|
|
|
### Mounting the root partition to begin setting up the partitions where they need to be
|
|
mount $ROOT_PARTITION /mnt
|
|
### Calling the --mkdir flag for mount to create the necessary directories so that it can mount
|
|
[[ "$BOOT_METHOD" == "EFI" ]] && mount $EFI_PARTITION --mkdir /mnt/boot/efi
|
|
|
|
### Using pacstrap to install the necessities to be able to get a chroot env
|
|
: "
|
|
base:
|
|
This is a meta-package. One that will handle installing many of the necessary programs to have a basic install of arch to chroot into
|
|
|
|
|
|
linux:
|
|
This is the actual kernel being installed. It will install the kernel & kernel-modules necessary to boot
|
|
|
|
|
|
linux-headers:
|
|
This is many other family of distros (Debian, RedHat, etc) would name linux-dev || linux-devel
|
|
|
|
This is a package that contains all of the kernel's header files for compiling modules for your distrobutions kernel.
|
|
|
|
|
|
linux-firmware:
|
|
This is another meta package that contains just about all of the firmware drivers you system may need. It is just a dump of firmware, not all of them will be needed for your system.
|
|
|
|
sudo:
|
|
A program needed for privelege escalation. Basically to provide a user of an admin group (most often wheel in most distrobutions) to be able to execute binaries that require root level permissions in you system.
|
|
|
|
Installing it here because it is not installed by default. An alternative is doas, a utility to perform the same funciton.
|
|
"
|
|
pacman -Sy archlinux-keyring
|
|
pacman-key --init
|
|
pacman-key --populate archlinux
|
|
pacstrap /mnt base linux linux-headers linux-firmware sudo
|
|
|
|
## Setting up fstab
|
|
genfstab -U /mnt > /mnt/etc/fstab
|
|
|
|
INSTALL_SYSTEM="
|
|
# Setting the hostname of your machine
|
|
echo '$HOSTNAME' > /etc/hostname
|
|
|
|
# Setting timezone of the machine
|
|
ln -sf /usr/share/zoneinfo/$TIMEZONE_INFO /etc/localtime
|
|
|
|
# Setting LOCALE of machine (uncommenting the entry)
|
|
cp /etc/locale.gen{,-bak}
|
|
sed -i s'/\#$LOCALE/$LOCALE/' /etc/locale.gen
|
|
# Generate local
|
|
locale-gen
|
|
## Configure locale.conf
|
|
echo 'LANG=$LOCALE' > /etc/locale.conf
|
|
|
|
# Install and Enable Networking Systems
|
|
##
|
|
#networkmanager:
|
|
#This is the system that will handle all networking for your system, allowing you to setup profiles and otherwise automatically configure your network as needed.
|
|
#
|
|
#wpa_supplicant:
|
|
#This is the service/program that will manage supplication (aka wireless handshakes) between your device and your Access Point/Router
|
|
##
|
|
|
|
## Installing networking packages
|
|
pacman -S --noconfirm networkmanager wpa_supplicant
|
|
## Enabling systemd services
|
|
systemctl enable wpa_supplicant NetworkManager
|
|
|
|
## Installing bootloader
|
|
#grub:
|
|
#Grub is a bootloader. A program that helps you boot into an installed system
|
|
#
|
|
#It is what actually load your kernel and init-system via your install's specific efi file located somewhere in (/boo/efi/EFI)
|
|
#
|
|
#
|
|
#efibootmgr:
|
|
#Is a tool that is used to edit boot manager settings (primarily to delete and move boot options around)
|
|
|
|
### Do bootloader install
|
|
`
|
|
case "${BOOT_METHOD,,}" in
|
|
efi)
|
|
echo "pacman -S --noconfirm grub efibootmgr"
|
|
echo "grub-install --target=x86_64-efi --bootloader-id=GRUB --efi-directory=/boot/efi $DISK"
|
|
;;
|
|
bios)
|
|
echo "pacman -S --noconfirm grub"
|
|
echo "grub-install --target=i386-pc --boot-directory=/boot $DISK"
|
|
;;
|
|
esac
|
|
`
|
|
## Create grub config
|
|
grub-mkconfig -o /boot/grub/grub.cfg
|
|
|
|
## gnome:
|
|
# This is the gnome desktop enviorment. It's the default choice for most distros by default (due to fewer release cycles, meaning distro maintainers don't have to work as much to maintain it for their distro).
|
|
#
|
|
# There are other choices:
|
|
# - KDE/Plasma
|
|
# - xfce4
|
|
# - lxde
|
|
# ...
|
|
#
|
|
#KDE is usually the next choice for those wanting to have a very easy to use and integrated desktop with a lot of customizability.
|
|
#
|
|
## gdm \"Gnome Desktop Manager\":
|
|
# This is the default desktop manager (login screen) for gnome. This just handles the login screen and starting up your desktop session & windowing system based off of your choices.
|
|
|
|
## Install desktop env
|
|
pacman -S --noconfirm gnome
|
|
|
|
## Enable desktop manager/login-screen
|
|
systemctl enable gdm
|
|
|
|
## Setting root password
|
|
echo -e '$ROOT_PASSWORD\n$ROOT_PASSWORD\n' | passwd
|
|
## Creating new user and setting password
|
|
useradd -m $NEW_USER
|
|
echo -e '$NEW_PASSWORD\n$NEW_PASSWORD\n' | passwd $NEW_USER
|
|
|
|
## Adding new user to wheel group to be able to use sudo
|
|
usermod -aG wheel $NEW_USER
|
|
|
|
## Setting up wheel group in sudoers
|
|
# I am doing it this way because it's not a good idea to edit /etc/sudoers non-interactively, as you can break sudo for all other users except root.
|
|
#
|
|
# sudo will load all definitions from /etc/sudoers.d/ and won't break if there is an error in the extra files (unlike if you edit /etc/sudoers directly)
|
|
|
|
echo '%wheel ALL=(ALL:ALL) ALL' > /etc/sudoers.d/wheel
|
|
"
|
|
|
|
arch-chroot /mnt /bin/bash <<< "$INSTALL_SYSTEM"
|
|
|
|
# END: Work
|