archInstall.sh 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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 "Hostname: " HOSTNAME
  36. read -p "Username: " USERNAME
  37. PASSWORD=$(openssl passwd -6) || exit $?
  38. printf "Generate ssh key\n"
  39. ssh-keygen -f /tmp/id_ed25519 -t ed25519 -C "${USERNAME}@${HOSTNAME}" -q || exit $?
  40. SSH_PUB=$(cat /tmp/id_ed25519.pub)
  41. SSH_PRIV=$(cat /tmp/id_ed25519)
  42. LOGFILE="archInstall.$(date +%Y%m%d-%H%M%S).log"
  43. printf "Installing arch on ${DISK}\n" | tee -a $LOGFILE
  44. BLOCK_INFO=$(lsblk -n --output PATH,TYPE)
  45. printf "$BLOCK_INFO" | grep -e " disk$" | grep -e "^${DISK} " > /dev/null 2>&1
  46. if (( $? > 0 )); then
  47. printf "${DISK} does not seem to be a disk\n" | tee -a $LOGFILE
  48. exit 2
  49. fi
  50. if (( $(printf "$BLOCK_INFO" | grep -e " part$" | wc -l) > 0 )); then
  51. printf "${DISK} already has several partitions\n" | tee -a $LOGFILE
  52. read -p "Do you really wish to continue and erase all partitions? [N/y] " CONTINUE
  53. if [[ ! $CONTINUE =~ ^[yY]$ ]]; then
  54. printf "Exiting due to user input\n" | tee -a $LOGFILE
  55. exit 0
  56. fi
  57. fi
  58. printf "Loading keymap\n" | tee -a $LOGFILE
  59. loadkeys sv-latin1 || exit $?
  60. printf "Creating partitions\n" | tee -a $LOGFILE
  61. (
  62. echo o # New partition table
  63. echo n # New partition
  64. echo p # Primary partition
  65. echo 1 # Partition number
  66. echo # First sector (use default)
  67. echo +300M # Last sector
  68. echo n # New partition
  69. echo p # Primary partition
  70. echo 2 # Partition number
  71. echo # First sector (use default)
  72. echo # Last sector (use default)
  73. echo w # Write changes
  74. ) | fdisk -W always ${DISK} >> $LOGFILE 2>&1 || exit $?
  75. BOOTPART="${DISK}1"
  76. BTRFSPART="${DISK}2"
  77. printf "Creating filesystems\n" | tee -a $LOGFILE
  78. mkfs.fat ${BOOTPART} >> $LOGFILE 2>&1 || exit $?
  79. mkfs.btrfs ${BTRFSPART} >> $LOGFILE 2>&1 || exit $?
  80. printf "Mounting btrfs partition\n" | tee -a $LOGFILE
  81. mount ${BTRFSPART} /mnt >> $LOGFILE 2>&1 || exit $?
  82. printf "Creating btrfs subvolumes\n" | tee -a $LOGFILE
  83. btrfs subvolume create /mnt/@root >> $LOGFILE 2>&1 || exit $?
  84. btrfs subvolume create /mnt/@home >> $LOGFILE 2>&1 || exit $?
  85. btrfs subvolume create /mnt/@log >> $LOGFILE 2>&1 || exit $?
  86. btrfs subvolume create /mnt/@swap >> $LOGFILE 2>&1 || exit $?
  87. printf "Unmounting btrfs partition\n" | tee -a $LOGFILE
  88. umount /mnt >> $LOGFILE 2>&1
  89. printf "Mounting root\n" | tee -a $LOGFILE
  90. mount -o defaults,relatime,compress=zstd,subvol=@root ${BTRFSPART} /mnt >> $LOGFILE 2>&1 || exit $?
  91. printf "Creating mount directories\n" | tee -a $LOGFILE
  92. mkdir -p /mnt/boot/efi /mnt/home /mnt/var/log /mnt/swap >> $LOGFILE 2>&1 || exit $?
  93. printf "Mounting volumes\n" | tee -a $LOGFILE
  94. mount ${BOOTPART} /mnt/boot/efi >> $LOGFILE 2>&1 || exit $?
  95. mount ${BTRFSPART} -o defaults,relatime,compress=zstd,subvol=@home /mnt/home >> $LOGFILE 2>&1 || exit $?
  96. mount ${BTRFSPART} -o defaults,relatime,compress=zstd,subvol=@log /mnt/var/log >> $LOGFILE 2>&1 || exit $?
  97. mount ${BTRFSPART} -o defaults,relatime,compress=zstd,subvol=@swap /mnt/swap >> $LOGFILE 2>&1 || exit $?
  98. printf "Creating swap file\n" | tee -a $LOGFILE
  99. btrfs filesystem mkswapfile --size 8G /mnt/swap/swapfile >> $LOGFILE 2>&1 || exit $?
  100. swapon /mnt/swap/swapfile
  101. PACSTRAPPKGS="base base-devel linux linux-firmware btrfs-progs grub efibootmgr networkmanager sudo sed git ansible"
  102. printf "Checking CPU manufacturer\n" | tee -a $LOGFILE
  103. CPU=$(lscpu | grep "^Vendor ID:" | awk '{ print $3 }')
  104. if [[ ! -z $CPU ]]; then
  105. if [[ "$CPU" == "GenuineIntel" ]]; then
  106. PACSTRAPPKGS="${PACSTRAPPKGS} intel-ucode"
  107. elif [[ "$CPU" == "AuthencticAMD" ]]; then
  108. PACSTRAPPKGS="${PACSTRAPPKGS} amd-ucode"
  109. fi
  110. fi
  111. printf "Installing base system\n" | tee -a $LOGFILE
  112. pacstrap -K /mnt ${PACSTRAPPKGS} >> $LOGFILE 2>&1 || exit $?
  113. printf "Generate fstab\n" | tee -a $LOGFILE
  114. genfstab -U /mnt >> /mnt/etc/fstab || exit $?
  115. }
  116. function chrootStep {
  117. checkVariables
  118. printf "Setting up time\n"
  119. ln -sf /usr/share/zoneinfo/Europe/Stockholm /etc/localtime || exit $?
  120. hwclock --systohc || exit $?
  121. printf "Setting up locale\n"
  122. sed -i -e 's/^#\(en_US.UTF-8\)/\1/' /etc/locale.gen || exit $?
  123. sed -i -e 's/^#\(sv_SE.UTF-8\)/\1/' /etc/locale.gen || exit $?
  124. locale-gen >&2 || exit $?
  125. echo "LANG=en_US.UTF-8" > /etc/locale.conf
  126. echo "LC_TIME=sv_SE.UTF-8" >> /etc/locale.conf
  127. echo "KEYMAP=sv-latin1" > /etc/vconsole.conf
  128. printf "Setting hostname to $HOSTNAME\n"
  129. echo "$HOSTNAME" > /etc/hostname
  130. printf "Add wheel to sudoers\n"
  131. echo "%wheel ALL=(ALL) ALL" > /etc/sudoers.d/wheel
  132. sed -i -e 's/^#\(%wheel ALL=(ALL) ALL\)/\1/' /etc/sudoers || exit $?
  133. printf "Creating user\n" | tee -a $LOGFILE
  134. useradd -m $USERNAME -G wheel >&2 || exit $?
  135. echo "${USERNAME}:${PASSWORD}" | chpasswd -e >&2 || exit $?
  136. printf "Add user ssh key" | tee -a $LOGFILE
  137. (umask 066; mkdir /home/${USERNAME}/.ssh)
  138. (umask 066; echo "${SSH_PRIV}" > /home/${USERNAME}/.ssh/id_ed25519)
  139. (umask 022; echo "${SSH_PUB}" > /home/${USERNAME}/.ssh/id_ed25519.pub)
  140. chown -R ${USERNAME}:${USERNAME} /home/${USERNAME}/.ssh
  141. printf "Setting temporary root password\n"
  142. echo "root:root" | chpasswd >&2 || exit $?
  143. printf "Starting and enabling NetworkManager\n"
  144. systemctl enable NetworkManager >&2 || exit $?
  145. systemctl start NetworkManager >&2 || exit $?
  146. printf "Installing GRUB\n"
  147. grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB >&2 || exit $?
  148. grub-mkconfig -o /boot/grub/grub.cfg >&2 || exit $?
  149. printf "Exiting chroot\n"
  150. exit
  151. }
  152. function postChrootStep {
  153. printf "Cleanup\n" | tee -a $LOGFILE
  154. cp $LOGFILE /mnt/$LOGFILE
  155. cd /
  156. swapoff /mnt/swap/swapfile
  157. umount -R /mnt
  158. }
  159. if [[ $1 == "chroot" ]]; then
  160. chrootStep
  161. exit
  162. fi
  163. # Run preChroot operations
  164. preChrootStep
  165. # Run chroot operations
  166. printf "Adding install script to mount directory\n" | tee -a $LOGFILE
  167. cp $0 /mnt/
  168. printf "Chrooting arch\n" | tee -a $LOGFILE
  169. DISK="${DISK}" \
  170. HOSTNAME="${HOSTNAME}" \
  171. USERNAME="${USERNAME}" \
  172. PASSWORD="${PASSWORD}" \
  173. SSH_PUB="${SSH_PUB}" \
  174. SSH_PRIV="${SSH_PRIV}" \
  175. arch-chroot /mnt /$(basename $0) chroot 2>> $LOGFILE | tee -a $LOGFILE
  176. if (( ${PIPESTATUS[0]} > 0 )); then
  177. exit ${PIPESTATUS[0]}
  178. fi
  179. # Run postchroot operations
  180. postChrootStep
  181. printf "Base installation completed, logfile at $LOGFILE.\nReboot and proceed with goodies.\nRemember to change/deactivate root login\n" | tee -a $LOGFILE