archInstall.sh 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. #!/bin/bash
  2. function checkVariables {
  3. if [[ -z $DISK ]]; then
  4. printf "System drive (DISK) is not set\n"
  5. exit 99
  6. fi
  7. if [[ -z $HOSTNAME ]]; then
  8. printf "Hostname (HOSTNAME) is not set\n"
  9. exit 99
  10. fi
  11. if [[ -z $USERNAME ]]; then
  12. printf "Username (USERNAME) is not set\n"
  13. exit 99
  14. fi
  15. if [[ -z $PASSWORD ]]; then
  16. printf "Password (PASSWORD) is not set\n"
  17. exit 99
  18. fi
  19. }
  20. function preChrootStep {
  21. if [[ $(whoami) != "root" ]]; then
  22. printf "This script has to be run as root"
  23. exit 1
  24. fi
  25. if ! ls /sys/firmware/efi/efivars > /dev/null 2>&1; then
  26. printf "This script can only be run when booted in UEFI mode\n"
  27. exit 1
  28. fi
  29. if ! ping -c 1 archlinux.org > /dev/null 2>&1; then
  30. printf "Unable to ping archlinux.org, check internet connectivity\n"
  31. exit 1
  32. fi
  33. printf "Arch installation\n"
  34. read -p "System drive: " DISK
  35. read -p
  36. read -p "Hostname: " HOSTNAME
  37. read -p "Username: " USERNAME
  38. PASSWORD=$(openssl passwd -6) || exit $?
  39. LOGFILE="archInstall.$(date +%Y%m%d-%H%M%S).log"
  40. printf "Installing arch on ${DISK}\n" | tee -a $LOGFILE
  41. BLOCK_INFO=$(lsblk -n --output PATH,TYPE)
  42. printf "$BLOCK_INFO" | grep -e " disk$" | grep -e "^${DISK} " > /dev/null 2>&1
  43. if (( $? > 0 )); then
  44. printf "${DISK} does not seem to be a disk\n" | tee -a $LOGFILE
  45. exit 2
  46. fi
  47. if (( $(printf "$BLOCK_INFO" | grep -e " part$" | wc -l) > 0 )); then
  48. printf "${DISK} already has several partitions\n" | tee -a $LOGFILE
  49. read -p "Do you really wish to continue and erase all partitions? [N/y] " CONTINUE
  50. if [[ ! $CONTINUE =~ ^[yY]$ ]]; then
  51. printf "Exiting due to user input\n" | tee -a $LOGFILE
  52. exit 0
  53. fi
  54. fi
  55. printf "Loading keymap\n" | tee -a $LOGFILE
  56. loadkeys sv-latin1 || exit $?
  57. printf "Creating partitions\n" | tee -a $LOGFILE
  58. (
  59. echo g # New partition table
  60. echo n # New partition
  61. echo p # Primary partition
  62. echo 1 # Partition number
  63. echo # First sector (use default)
  64. echo +1024M # Last sector
  65. echo n # New partition
  66. echo p # Primary partition
  67. echo 2 # Partition number
  68. echo # First sector (use default)
  69. echo # Last sector (use default)
  70. echo t # Set type
  71. echo 1 # Select partition
  72. echo 1 # Set type EFI
  73. echo t # Select partition
  74. echo 2 # Selection partition
  75. echo 20 # Set type Linux file system
  76. echo w # Write changes
  77. ) | fdisk -W always ${DISK} >> $LOGFILE 2>&1 || exit $?
  78. BOOTPART="${DISK}p1"
  79. ROOTPART="${DISK}p2"
  80. printf "Creating LUKS2 container\n" | tee -a $LOGFILE
  81. cryptsetup luksFormat --type luks2 ${ROOTPART} >> $LOGFILE 2>&1 || exit $?
  82. printf "Decrypt LUKS2 container\n" | tee -a $LOGFILE
  83. cryptsetup open ${ROOTPART} cryptlvm >> $LOGFILE 2>&1 || exit $?
  84. printf "Setup LVM volumes\n" | tee -a $LOGFILE
  85. pvcreate /dev/mapper/cryptlvm >> $LOGFILE 2>&1 || exit $?
  86. vgcreate VolGroup1 /dev/mapper/cryptlvm >> $LOGFILE 2>&1 || exit $?
  87. lvcreate -l 100%FREE VolGroup1 -n root
  88. lvreduce -L -256M VolGroup1/root >> $LOGFILE 2>&1 || exit $?
  89. printf "Creating filesystems\n" | tee -a $LOGFILE
  90. mkfs.fat -F32 ${BOOTPART} >> $LOGFILE 2>&1 || exit $?
  91. mkfs.ext4 /dev/Volgroup1/root >> $LOGFILE 2>&1 || exit $?
  92. printf "Mount filesystems\n" | tee -a $LOGFILE
  93. mount /dev/VolGroup1/root /mnt
  94. mkdir -p /mnt/efi
  95. mount ${BOOTPART} /mnt/efi
  96. printf "Creating swap file\n" | tee -a $LOGFILE
  97. SWAPSIZE=$(free --giga | grep Mem: | awk '{printf "%dG", $2 * 1.5}')
  98. mkswap -U clear --size $SWAPSIZE --file /mnt/swapfile >> $LOGFILE 2>&1 || exit $?
  99. swapon /mnt/swapfile >> $LOGFILE 2>&1 || exit $?
  100. PACSTRAPPKGS="base linux linux-firmware linux-headers networkmanager efibootmgr vim sudo sed git"
  101. printf "Checking CPU manufacturer\n" | tee -a $LOGFILE
  102. CPU=$(lscpu | grep "^Vendor ID:" | awk '{ print $3 }')
  103. if [[ ! -z $CPU ]]; then
  104. if [[ "$CPU" == "GenuineIntel" ]]; then
  105. PACSTRAPPKGS="${PACSTRAPPKGS} intel-ucode"
  106. elif [[ "$CPU" == "AuthencticAMD" ]]; then
  107. PACSTRAPPKGS="${PACSTRAPPKGS} amd-ucode"
  108. fi
  109. fi
  110. printf "Installing base system\n" | tee -a $LOGFILE
  111. pacstrap -K /mnt ${PACSTRAPPKGS} >> $LOGFILE 2>&1 || exit $?
  112. printf "Generate fstab\n" | tee -a $LOGFILE
  113. genfstab -U /mnt >> /mnt/etc/fstab || exit $?
  114. }
  115. function chrootStep {
  116. checkVariables
  117. printf "Setting up time\n" | tee -a $LOGFILE
  118. ln -sf /usr/share/zoneinfo/Europe/Stockholm /etc/localtime || exit $?
  119. hwclock --systohc || exit $?
  120. printf "Setting up locale\n" | tee -a $LOGFILE
  121. sed -i -e 's/^#\(en_US.UTF-8\)/\1/' /etc/locale.gen || exit $?
  122. sed -i -e 's/^#\(sv_SE.UTF-8\)/\1/' /etc/locale.gen || exit $?
  123. locale-gen >&2 || exit $?
  124. echo "LANG=en_US.UTF-8" > /etc/locale.conf
  125. echo "LC_TIME=sv_SE.UTF-8" >> /etc/locale.conf
  126. echo "KEYMAP=sv-latin1" > /etc/vconsole.conf
  127. printf "Setting hostname to $HOSTNAME\n"
  128. echo "$HOSTNAME" > /etc/hostname
  129. printf "Add wheel to sudoers\n"
  130. echo "%wheel ALL=(ALL) ALL" > /etc/sudoers.d/wheel
  131. sed -i -e 's/^#\(%wheel ALL=(ALL) ALL\)/\1/' /etc/sudoers || exit $?
  132. printf "Creating user\n" | tee -a $LOGFILE
  133. useradd -m $USERNAME -G wheel >&2 || exit $?
  134. echo "${USERNAME}:${PASSWORD}" | chpasswd -e >&2 || exit $?
  135. printf "Setting temporary root password\n" | tee -a $LOGFILE
  136. echo "root:root" | chpasswd >&2 || exit $?
  137. printf "Starting and enabling NetworkManager\n" | tee -a $LOGFILE
  138. systemctl enable NetworkManager >&2 || exit $?
  139. systemctl start NetworkManager >&2 || exit $?
  140. printf "Add decryption kernel options\n" | tee -a $LOGFILE
  141. LUKSUUID=$(blkid | grep ${ROOTPART} | sed -E 's/^.*\bUUID\b="(\S+)".*$/\1/') || exit $?
  142. mkdir -p /etc/cmdline.d >&2 || exit $?
  143. echo "rd.luks.name=${LUKSUUID}=cryptlvm root=/dev/VolGroup1/root rw rootfstype=ext4 rd.shell=0 rd.emergency=reboot" > /etc/cmdline.d/root.conf
  144. printf "Add LUKS related hooks to mkinitcpio.conf" | tee -a $LOGFILE
  145. for OPT in systemd keyboard sd-vconsole sd-encrypt lvm2; do
  146. sed -i -E '/^HOOKS=.*\b'$OPT'\b/!/s/^(.*)\)$/\1 '$OPT'\)/' /etc/mkinitcpio.conf >&2 || exit $?
  147. done
  148. printf "Rebuild kernel\n" | tee -a $LOGFILE
  149. mkinitcpio -p linux 2>&1 || exit $?
  150. printf "Install bootloader (systemd)\n" | tee -a $LOGFILE
  151. bootctl install
  152. printf "Exiting chroot\n" | tee -a $LOGFILE
  153. exit
  154. }
  155. function postChrootStep {
  156. printf "Cleanup\n" | tee -a $LOGFILE
  157. cp $LOGFILE /mnt/$LOGFILE
  158. cd /
  159. swapoff /mnt/swapfile
  160. umount -R /mnt
  161. }
  162. if [[ $1 == "chroot" ]]; then
  163. chrootStep
  164. exit
  165. fi
  166. # Run preChroot operations
  167. preChrootStep
  168. # Run chroot operations
  169. printf "Adding install script to mount directory\n" | tee -a $LOGFILE
  170. cp $0 /mnt/
  171. printf "Chrooting arch\n" | tee -a $LOGFILE
  172. DISK="${DISK}" \
  173. HOSTNAME="${HOSTNAME}" \
  174. USERNAME="${USERNAME}" \
  175. PASSWORD="${PASSWORD}" \
  176. SSH_PUB="${SSH_PUB}" \
  177. SSH_PRIV="${SSH_PRIV}" \
  178. arch-chroot /mnt /$(basename $0) chroot 2>> $LOGFILE | tee -a $LOGFILE
  179. if (( ${PIPESTATUS[0]} > 0 )); then
  180. exit ${PIPESTATUS[0]}
  181. fi
  182. # Run postchroot operations
  183. postChrootStep
  184. printf "Base installation completed, logfile at $LOGFILE.\nReboot and proceed with goodies.\nRemember to change/deactivate root login\n" | tee -a $LOGFILE