| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- #!/bin/bash
- function checkVariables {
- if [[ -z $DISK ]]; then
- printf "System drive (DISK) is not set\n"
- exit 99
- fi
- if [[ -z $HOSTNAME ]]; then
- printf "Hostname (HOSTNAME) is not set\n"
- exit 99
- fi
- if [[ -z $USERNAME ]]; then
- printf "Username (USERNAME) is not set\n"
- exit 99
- fi
- if [[ -z $PASSWORD ]]; then
- printf "Password (PASSWORD) is not set\n"
- exit 99
- fi
- }
- function preChrootStep {
- if [[ $(whoami) != "root" ]]; then
- printf "This script has to be run as root"
- exit 1
- fi
- if ! ls /sys/firmware/efi/efivars > /dev/null 2>&1; then
- printf "This script can only be run when booted in UEFI mode\n"
- exit 1
- fi
- if ! ping -c 1 archlinux.org > /dev/null 2>&1; then
- printf "Unable to ping archlinux.org, check internet connectivity\n"
- exit 1
- fi
- printf "Arch installation\n"
- read -p "System drive: " DISK
- read -p "Hostname: " HOSTNAME
- read -p "Username: " USERNAME
- PASSWORD=$(openssl passwd -6) || exit $?
- LOGFILE="archInstall.$(date +%Y%m%d-%H%M%S).log"
- printf "Installing arch on ${DISK}\n" | tee -a $LOGFILE
- BLOCK_INFO=$(lsblk -n --output PATH,TYPE)
- printf "$BLOCK_INFO" | grep -e " disk$" | grep -e "^${DISK} " > /dev/null 2>&1
- if (( $? > 0 )); then
- printf "${DISK} does not seem to be a disk\n" | tee -a $LOGFILE
- exit 2
- fi
- if (( $(printf "$BLOCK_INFO" | grep -e " part$" | wc -l) > 0 )); then
- printf "${DISK} already has several partitions\n" | tee -a $LOGFILE
- read -p "Do you really wish to continue and erase all partitions? [N/y] " CONTINUE
- if [[ ! $CONTINUE =~ ^[yY]$ ]]; then
- printf "Exiting due to user input\n" | tee -a $LOGFILE
- exit 0
- fi
- fi
- printf "Loading keymap\n" | tee -a $LOGFILE
- loadkeys sv-latin1 || exit $?
- printf "Creating partitions\n" | tee -a $LOGFILE
- (
- echo g # New partition table
- echo n # New partition
- echo p # Primary partition
- echo 1 # Partition number
- echo # First sector (use default)
- echo +1024M # Last sector
- echo n # New partition
- echo p # Primary partition
- echo 2 # Partition number
- echo # First sector (use default)
- echo # Last sector (use default)
- echo t # Set type
- echo 1 # Select partition
- echo 1 # Set type EFI
- echo t # Select partition
- echo 2 # Selection partition
- echo 20 # Set type Linux file system
- echo w # Write changes
- ) | fdisk -W always ${DISK} >> $LOGFILE 2>&1 || exit $?
- BOOTPART="${DISK}p1"
- ROOTPART="${DISK}p2"
- printf "Creating LUKS2 container\n" | tee -a $LOGFILE
- cryptsetup luksFormat --type luks2 ${ROOTPART} 2>&1 | tee -a $LOGFILE || exit $?
- printf "Decrypt LUKS2 container\n" | tee -a $LOGFILE
- cryptsetup open ${ROOTPART} cryptlvm 2>&1 | tee -a $LOGFILE || exit $?
- printf "Setup LVM volumes\n" | tee -a $LOGFILE
- pvcreate /dev/mapper/cryptlvm >> $LOGFILE 2>&1 || exit $?
- vgcreate VolGroup1 /dev/mapper/cryptlvm >> $LOGFILE 2>&1 || exit $?
- lvcreate -l 100%FREE VolGroup1 -n root
- lvreduce -L -256M VolGroup1/root >> $LOGFILE 2>&1 || exit $?
- printf "Creating filesystems\n" | tee -a $LOGFILE
- mkfs.fat -F32 ${BOOTPART} >> $LOGFILE 2>&1 || exit $?
- mkfs.ext4 /dev/VolGroup1/root >> $LOGFILE 2>&1 || exit $?
- printf "Mount filesystems\n" | tee -a $LOGFILE
- mount /dev/VolGroup1/root /mnt
- mkdir -p /mnt/efi
- mount ${BOOTPART} /mnt/efi
- printf "Creating swap file\n" | tee -a $LOGFILE
- SWAPSIZE=$(free --giga | grep Mem: | awk '{printf "%dG", $2 * 1.5}')
- mkswap -U clear --size $SWAPSIZE --file /mnt/swapfile >> $LOGFILE 2>&1 || exit $?
- swapon /mnt/swapfile >> $LOGFILE 2>&1 || exit $?
- PACSTRAPPKGS="base linux linux-firmware linux-headers networkmanager efibootmgr vim sudo sed git lvm2 iwd systemd-ukify"
- printf "Checking CPU manufacturer\n" | tee -a $LOGFILE
- CPU=$(lscpu | grep "^Vendor ID:" | awk '{ print $3 }')
- if [[ ! -z $CPU ]]; then
- if [[ "$CPU" == "GenuineIntel" ]]; then
- PACSTRAPPKGS="${PACSTRAPPKGS} intel-ucode"
- elif [[ "$CPU" == "AuthencticAMD" ]]; then
- PACSTRAPPKGS="${PACSTRAPPKGS} amd-ucode"
- fi
- fi
- printf "Installing base system\n" | tee -a $LOGFILE
- pacstrap -K /mnt ${PACSTRAPPKGS} >> $LOGFILE 2>&1 || exit $?
- printf "Generate fstab\n" | tee -a $LOGFILE
- genfstab -U /mnt >> /mnt/etc/fstab || exit $?
- }
- function chrootStep {
- checkVariables
- printf "Setting up time\n" | tee -a $LOGFILE
- ln -sf /usr/share/zoneinfo/Europe/Stockholm /etc/localtime || exit $?
- hwclock --systohc || exit $?
- printf "Setting up locale\n" | tee -a $LOGFILE
- sed -i -e 's/^#\(en_US.UTF-8\)/\1/' /etc/locale.gen || exit $?
- sed -i -e 's/^#\(sv_SE.UTF-8\)/\1/' /etc/locale.gen || exit $?
- locale-gen >&2 || exit $?
- echo "LANG=en_US.UTF-8" > /etc/locale.conf
- echo "LC_TIME=sv_SE.UTF-8" >> /etc/locale.conf
- echo "KEYMAP=sv-latin1" > /etc/vconsole.conf
- printf "Setting hostname to $HOSTNAME\n"
- echo "$HOSTNAME" > /etc/hostname
- echo "127.0.0.1 localhost" >> /etc/hosts
- echo "::1 localhost" >> /etc/hosts
- echo "127.0.1.1 $HOSTNAME" >> /etc/hosts
- printf "Add wheel to sudoers\n"
- echo "%wheel ALL=(ALL) ALL" > /etc/sudoers.d/wheel
- sed -i -e 's/^#\(%wheel ALL=(ALL) ALL\)/\1/' /etc/sudoers || exit $?
- printf "Creating user\n" | tee -a $LOGFILE
- useradd -m $USERNAME -G wheel >&2 || exit $?
- echo "${USERNAME}:${PASSWORD}" | chpasswd -e >&2 || exit $?
- printf "Setting temporary root password\n" | tee -a $LOGFILE
- echo "root:root" | chpasswd >&2 || exit $?
- printf "Starting and enabling NetworkManager\n" | tee -a $LOGFILE
- systemctl enable NetworkManager >&2 || exit $?
- systemctl start NetworkManager >&2 || exit $?
- printf "Add decryption kernel options for UKI images\n" | tee -a $LOGFILE
- LUKSUUID=$(blkid | grep "${ROOTPART}" | sed -E 's/^.*\bUUID\b="(\S+)".*$/\1/') || exit $?
- mkdir -p /etc/cmdline.d >&2 || exit $?
- echo "rd.luks.name=${LUKSUUID}=cryptlvm root=/dev/VolGroup1/root rw rootfstype=ext4 rd.shell=0 rd.emergency=reboot" > /etc/cmdline.d/root.conf
- printf "Add LUKS related hooks to mkinitcpio.conf" | tee -a $LOGFILE
- for OPT in systemd keyboard sd-vconsole sd-encrypt lvm2; do
- sed -i -E '/^HOOKS=.*\b'$OPT'\b/!s/^(HOOKS=.*)\)$/\1 '$OPT'\)/' /etc/mkinitcpio.conf >&2 || exit $?
- done
- printf "Configure to build UKI images when updated\n" | tee -a $LOGFILE
- sed -i -E -e 's/^(default_image|fallback_image)/#\1/' -e 's/^#(default_uki|default_options|fallback_uki)/\1/' /etc/mkinitcpio.d/linux.preset >&2 || exit $?
- printf "Rebuild kernel\n" | tee -a $LOGFILE
- mkinitcpio -p linux 2>&1 || exit $?
- printf "Install bootloader (systemd-boot)\n" | tee -a $LOGFILE
- bootctl install
-
- printf "Exiting chroot\n" | tee -a $LOGFILE
- exit
- }
- function postChrootStep {
- printf "Cleanup\n" | tee -a $LOGFILE
- cp $LOGFILE /mnt/$LOGFILE
- cd /
- swapoff /mnt/swapfile
- umount -R /mnt
- }
- if [[ $1 == "chroot" ]]; then
- chrootStep
- exit
- fi
- # Run preChroot operations
- preChrootStep
- # Run chroot operations
- printf "Adding install script to mount directory\n" | tee -a $LOGFILE
- cp $0 /mnt/
- printf "Chrooting arch\n" | tee -a $LOGFILE
- DISK="${DISK}" \
- HOSTNAME="${HOSTNAME}" \
- USERNAME="${USERNAME}" \
- PASSWORD="${PASSWORD}" \
- ROOTPART="${ROOTPART}" \
- arch-chroot /mnt /$(basename $0) chroot 2>> $LOGFILE | tee -a $LOGFILE
- if (( ${PIPESTATUS[0]} > 0 )); then
- exit ${PIPESTATUS[0]}
- fi
- # Run postchroot operations
- postChrootStep
- printf "Base installation completed, logfile at $LOGFILE.\nReboot and proceed with goodies.\nRemember to change/deactivate root login\n" | tee -a $LOGFILE
|