arch.sh 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. #!/bin/bash -e
  2. #
  3. # Author: Casey DeLorme
  4. #
  5. # Description: fully automate installation and config after `arch-chroot`,
  6. # providing the user with a fully configured desktop environment and many
  7. # bells and whistles for developers.
  8. #
  9. # Dependencies: requires `base` and `base-devel` be installed with `pacstrap`,
  10. # and runs as root. Expects `username`, `password`, and `root_password` to be
  11. # supplied.
  12. # verify required variables
  13. while [ -z "$root_password" ]; do read -p "please enter a root password: " -s root_password && echo ""; done
  14. while [ -z "$username" ]; do read -p "please enter your username: " username; done
  15. while [ -z "$password" ]; do read -p "please enter your password: " -s password && echo ""; done
  16. # print all that transpires henceforth
  17. [ -n "$DEBUG" ] && set -x
  18. # initial time configuration
  19. ln -sf /usr/share/zoneinfo/America/New_York /etc/localtime
  20. hwclock -w --utc
  21. # setup locale
  22. sed -i "/^en_US.UTF-8/d" /etc/locale.gen
  23. sed -i "/^ja_JP.UTF-8/d" /etc/locale.gen
  24. echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
  25. echo "ja_JP.UTF-8 UTF-8" >> /etc/locale.gen
  26. locale-gen
  27. echo "LANG=en_US.UTF-8" > /etc/locale.conf
  28. # setup hostname
  29. echo "${hostname:-arch}" > /etc/hostname
  30. echo "127.0.0.1 localhost" > /etc/hosts
  31. echo "::1 localhost" >> /etc/hosts
  32. echo "127.0.1.1 $(cat /etc/hostname).localdomain $(cat /etc/hostname)" >> /etc/hosts
  33. # set default virtualconsole font
  34. setfont koi8u_8x16
  35. echo "FONT=koi8u_8x16" > /etc/vconsole.conf
  36. # enable multilib
  37. sed -i "/\[multilib\]/,/Include/"'s/^#//' /etc/pacman.conf
  38. # rebuild gpg keys
  39. rm -rf /etc/pacman.d/gnupg
  40. pacman-key --init
  41. pacman-key --populate archlinux
  42. # add sublime text source
  43. curl -O https://download.sublimetext.com/sublimehq-pub.gpg && pacman-key --add sublimehq-pub.gpg && pacman-key --lsign-key 8A8F901A && rm sublimehq-pub.gpg
  44. [ $(grep -c "sublime-text" /etc/pacman.conf) -eq 0 ] && echo -e "\n[sublime-text]\nServer = https://download.sublimetext.com/arch/stable/x86_64" | tee -a /etc/pacman.conf
  45. # Core tools
  46. export PACKAGES="linux linux-headers linux-firmware base-devel mkinitcpio sudo bash-completion man-db tmux gvim dkms dmidecode at bc cronie lm_sensors lshw stress"
  47. # Conditional CPU unicode
  48. [ $(grep -c "Intel" /proc/cpuinfo) -gt 0 ] && PACKAGES="${PACKAGES} intel-ucode"
  49. [ $(grep -c "AMD" /proc/cpuinfo) -gt 0 ] && PACKAGES="${PACKAGES} amd-ucode"
  50. # Conditional laptop packages
  51. if [ -e /sys/class/power_supply/BAT0 ]; then
  52. PACKAGES="${PACKAGES} xf86-input-synaptics acpid acpilight tlp"
  53. sed -i "s/panel_items = LTSC/panel_items = LTSBC/g" /srv/arch-desktop/install/etc/skel/.config/tint2/tint2rc
  54. fi
  55. # Storage
  56. PACKAGES="${PACKAGES} btrfs-progs smartmontools usbutils gvfs gvfs-mtp gvfs-afc android-udev parted postgresql transmission-cli python-pip python-setuptools"
  57. # Compression
  58. PACKAGES="${PACKAGES} cryptsetup lzop unzip p7zip xz unrar unace lrzip arj innoextract"
  59. # networking packages
  60. PACKAGES="${PACKAGES} nftables iptables dnsmasq rsync dhcpcd inetutils net-tools openssh sshfs ntp wget curl wireless_tools bluez bluez-utils oath-toolkit openconnect openvpn ethtool pptpclient"
  61. # conditional networking packages
  62. [ -d "/sys/class/net/${active_network_device}/wireless" ] && PACKAGES="${PACKAGES} connman wpa_supplicant iwd"
  63. # programming packages
  64. PACKAGES="${PACKAGES} pkgfile pkgconf bison gcc gcc-libs cmake ccache ncurses xmlstarlet jq git mercurial subversion bzr patchelf packer vagrant libvirt qemu libguestfs virt-install edk2-ovmf"
  65. # multimedia dependencies
  66. PACKAGES="${PACKAGES} mesa lib32-mesa dbus polkit giflib lib32-giflib mpg123 lib32-mpg123 v4l-utils lib32-v4l-utils lame libwebp libid3tag libvorbis vorbis-tools faac x264 x265 libpng12 lib32-libpng12 pulseaudio libpulse lib32-libpulse openal lib32-openal opencl-icd-loader lib32-opencl-icd-loader libva lib32-libva gst-plugins-base-libs lib32-gst-plugins-base-libs graphicsmagick imagemagick joyutils evtest libexif ffmpeg lxsession yt-dlp wine-staging winetricks fcitx5 fcitx5-mozc fcitx5-configtool fcitx5-gtk fcitx5-qt"
  67. # GUI theme
  68. PACKAGES="${PACKAGES} gnome-themes-extra gnome-icon-theme arc-gtk-theme"
  69. # Xorg dependencies
  70. PACKAGES="${PACKAGES} xorg-server xorg-server-devel xorg-xinit xorg-xinput xorg-xdpyinfo xorg-xprop xdotool xsel arandr "
  71. # openbox Environment
  72. PACKAGES="${PACKAGES} openbox gtk3 lib32-gtk3 feh hsetroot archlinux-xdg-menu picom pavucontrol pasystray xdg-utils xdg-user-dirs tint2 conky pcmanfm-gtk3 gmrun gtk-engines gtk-engine-murrine lxappearance ffmpegthumbnailer tumbler libva-mesa-driver lib32-libva-mesa-driver lib32-mesa-vdpau vulkan-tools vulkan-icd-loader lib32-vulkan-icd-loader "
  73. # fonts
  74. PACKAGES="${PACKAGES} fontconfig ttf-bitstream-vera ttf-droid ttf-dejavu ttf-liberation ttf-hanazono ttf-font-awesome"
  75. # GUI software
  76. PACKAGES="${PACKAGES} rxvt-unicode urxvt-perls xarchiver gparted psensor hardinfo steam discord mpv openshot gimp krita firefox obs-studio dia mednafen mame ppsspp lutris sublime-text evince viewnior virt-manager virtualbox virtualbox-host-modules-arch"
  77. # conditional GPU packages
  78. if [ $(lspci | grep -i "vga" | grep -ci "amd") -gt 0 ]; then
  79. PACKAGES="$PACKAGES xf86-video-amdgpu vulkan-radeon lib32-vulkan-radeon mesa-vdpau"
  80. # update modules to load
  81. [ $(grep -c "amd" /etc/mkinitcpio.conf) -eq 0 ] && sed -i 's/MODULES=(\(.*\))/MODULES=(\1 amdgpu radeon)/' /etc/mkinitcpio.conf
  82. fi
  83. if [ $(lspci | grep -i "vga" | grep -ci "intel") -gt 0 ]; then
  84. PACKAGES="$PACKAGES xf86-video-intel vulkan-intel lib32-vulkan-intel mesa-vdpau"
  85. # update modules to load
  86. [ $(grep -c "amd" /etc/mkinitcpio.conf) -eq 0 ] && sed -i 's/MODULES=(\(.*\))/MODULES=(\1 i915)/' /etc/mkinitcpio.conf
  87. fi
  88. if [ $(lspci | grep -i "vga" | grep -ci "nvidia") -gt 0 ]; then
  89. PACKAGES="$PACKAGES nvidia-dkms libglvnd lib32-libglvnd opencl-nvidia lib32-opencl-nvidia xf86-video-nouveau nvidia-utils lib32-nvidia-utils mesa-vdpau nvidia-settings"
  90. # update modules to load
  91. [ $(grep -c "nvidia" /etc/mkinitcpio.conf) -eq 0 ] && sed -i 's/MODULES=(\(.*\))/MODULES=(\1 nvidia nvidia_modeset nvidia_uvm nvidia_drm)/' /etc/mkinitcpio.conf
  92. # automatic mkinitcpio updates in pacman.d
  93. echo -e "[Trigger]\nOperation=Install\nOperation=Upgrade\nOperation=Remove\nType=Package\nTarget=nvidia\n\n[Action]\nDepends=mkinitcpio\nWhen=PostTransaction\nExec=/usr/bin/mkinitcpio -P" > /etc/pacman.d/hooks/nvidia.hook
  94. fi
  95. # install all packages
  96. pacman -Syu --noconfirm $PACKAGES
  97. # install base configuration files from repository
  98. [ -d /srv/arch-desktop/install ] || git clone https://git.caseydelorme.com/cdelorme/arch-desktop /srv/arch-desktop
  99. rsync -Pav /srv/arch-desktop/install/ /
  100. mkdir -p /etc/skel/.config/pulse
  101. mkdir -p /etc/skel/{desktop,downloads,public,public/templates,documents,music,pictures,videos,git}
  102. sed "/module-suspend-on-idle/d" /etc/pulse/default.pa > /etc/skel/.config/pulse/default.pa
  103. # @note: we may want to avoid disabling this on laptops
  104. sed -i "/module-switch-on-port-available/d" /etc/skel/.config/pulse/default.pa
  105. rsync -Pav /etc/skel/ "$(getent passwd root | cut -d: -f6)/"
  106. sed -i "/ssh-add/d" "$(getent passwd root | cut -d: -f6)/.bashrc"
  107. # install protontricks
  108. python3 -m pip install protontricks
  109. # enable ccache and optimize cores for AUR
  110. sed -i 's/!ccache/ccache/' /etc/makepkg.conf
  111. sed -i 's/^#MAKEFLAGS.*/MAKEFLAGS="-j$(($(nproc) + 1)) -l$(nproc)"/' /etc/makepkg.conf
  112. # create a user to install aur packages
  113. export aur_username=$(head /dev/urandom | tr -dc a-z | head -c 13 ; echo '')
  114. useradd -r -m -s /bin/bash $aur_username
  115. echo "${aur_username} ALL= NOPASSWD: /usr/bin/pacman" > /etc/sudoers.d/${aur_username}
  116. # install xcursor-chameleon-skyblue
  117. sudo -u $aur_username git clone https://aur.archlinux.org/xcursor-chameleon-skyblue.git /home/${aur_username}/xcursor-chameleon-skyblue
  118. (cd /home/${aur_username}/xcursor-chameleon-skyblue && sudo -u ${aur_username} makepkg -rcsi --noconfirm)
  119. # install numix-icon-theme
  120. sudo -u $aur_username git clone https://aur.archlinux.org/numix-icon-theme-git.git /home/${aur_username}/numix-icon-theme-git
  121. (cd /home/${aur_username}/numix-icon-theme-git && sudo -u ${aur_username} makepkg -rcsi --noconfirm)
  122. # cleanup aur user
  123. rm -rf /etc/sudoers.d/${aur_username}
  124. userdel -fr $aur_username
  125. unset $aur_username
  126. # install gifduration
  127. if ! which gifduration &> /dev/null; then
  128. curl -Lfs https://raw.githubusercontent.com/alimony/gifduration-script/master/gifduration.py > /usr/local/bin/gifduration
  129. chmod a+rx /usr/local/bin/gifduration
  130. fi
  131. # install 64bit flash projector
  132. if ! which flashplayer &> /dev/null; then
  133. curl -Lfs "https://fpdownload.macromedia.com/pub/flashplayer/updaters/32/flash_player_sa_linux.x86_64.tar.gz" > /tmp/flash.tar.gz
  134. tar -xf /tmp/flash.tar.gz -C /usr/local/bin flashplayer
  135. fi
  136. # install urxvt perl enhancement for font resize support
  137. [ ! -f /usr/lib/urxvt/perl/font ] && curl -Lfs "https://raw.githubusercontent.com/noah/urxvt-font/master/font" > /usr/lib/urxvt/perl/font
  138. # create sudo group and add to sudoers
  139. groupadd -fr sudo
  140. [ ! -f /etc/sudoers.d/sudo ] && echo '%sudo ALL=(ALL) ALL' > /etc/sudoers.d/sudo
  141. # update font cache
  142. fc-cache -fr
  143. # secure ssh by disabling root access and only accepting ssh keys
  144. sed -i "/^#\?PermitRootLogin/d" /etc/ssh/sshd_config
  145. sed -i "/^#\?PasswordAuthentication/d" /etc/ssh/sshd_config
  146. sed -i "/^#\?X11Forwarding/d" /etc/ssh/sshd_config
  147. echo "PermitRootLogin no" >> /etc/ssh/sshd_config
  148. echo "PasswordAuthentication no" >> /etc/ssh/sshd_config
  149. echo "X11Forwarding yes" >> /etc/ssh/sshd_config
  150. # set journald size
  151. sed -i '/^SystemMaxUse/d' /etc/systemd/journald.conf
  152. echo "SystemMaxUse=2G" >> /etc/systemd/journald.conf
  153. # set root password
  154. printf "${root_password}\n${root_password}\n" | passwd
  155. # initialize postgres database
  156. su - postgres -c "initdb --locale en_US.UTF-8 -D '/var/lib/postgres/data'"
  157. # create configuration to fix transmission errors
  158. echo "net.core.rmem_max = 4194304" > /etc/sysctl.d/transmission.conf
  159. echo "net.core.wmem_max = 1048576" >> /etc/sysctl.d/transmission.conf
  160. # check whether username and password are not empty
  161. if [[ -n "$username" && -n "$password" ]]; then
  162. # create user if not exists, else (re)-install dot-files
  163. if ! id $username &> /dev/null; then
  164. useradd -m -s /bin/bash $username
  165. echo "${username}:${password}" | chpasswd -c SHA256
  166. else
  167. [ $EUID -ne 0 ] && rsync -Pav /etc/skel/ "$(getent passwd $username | cut -d: -f6)/"
  168. fi
  169. # add user to standard groups
  170. usermod -aG users,sudo,adm,input,audio,video,disk,storage,lp,vboxusers $username
  171. # generate postgres user and user database
  172. systemctl start postgresql
  173. su postgres -c "cd && createuser -ds $username" 2> /dev/null && su $username -c "cd && createdb"
  174. # load xdg-user-dirs
  175. su $username -c "cd && xdg-user-dirs-update"
  176. update-desktop-database
  177. # generate default (passwordless) ed25519 ssh key if none exists
  178. su $username -c "cd; if [ ! -f ~/.ssh/id_ed25519 ]; then ssh-keygen -q -t ed25519 -N '' -f ~/.ssh/id_ed25519 && cd && chmod 600 ~/.ssh/id_ed25519 && chmod 600 ~/.ssh/id_ed25519.pub; fi"
  179. # install gvm loading from ~/.bash_profile, and the latest go version
  180. su $username -c "if [ ! -d ~/.gvm ]; then GVM_NO_UPDATE_PROFILE=1 bash < <(curl -Ls https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer 2> /dev/null); fi"
  181. su $username -c 'grep "gvm" ~/.bash_profile &> /dev/null || echo -e "\n# load gvm\n! which gvm &> /dev/null && . ~/.gvm/scripts/gvm" >> ~/.bash_profile'
  182. su $username -c ". ~/.gvm/scripts/gvm && gvm install go1.17.6 -B && gvm use go1.17.6 --default"
  183. # configure user-space transmission
  184. if [ ! -f "/etc/systemd/system/transmission.service.d/local.conf" ]; then
  185. su $username -c "cd && mkdir -p ~/transmission/{done,incomplete}"
  186. su $username -c 'cd && tmp=$(mktemp) && jq ".[\"download-dir\"] = \"${HOME}/transmission/done\"" $HOME/.config/transmission-daemon/settings.json | jq ".[\"incomplete-dir\"] = \"${HOME}/transmission/incomplete\"" | jq ".[\"watch-dir\"] = \"$(xdg-user-dir DOWNLOAD)\"" > $tmp && mv $tmp $HOME/.config/transmission-daemon/settings.json'
  187. fi
  188. fi
  189. # symlink shceduled maintenance tasks
  190. ln -sf /usr/local/bin/system-updates /etc/cron.daily/system-updates
  191. ln -sf /usr/local/bin/disk-maintenance /etc/cron.weekly/disk-maintenance
  192. # symlink override vi to vim
  193. ln -sf /usr/bin/vim /usr/local/bin/vi
  194. # enable services for next reboot
  195. which connman &> /dev/null && systemctl enable connman
  196. which acpid &> /dev/null && systemctl enable acpid
  197. which tlp &> /dev/null && systemctl enable tlp
  198. systemctl enable postgresql
  199. systemctl enable bluetooth
  200. systemctl enable nftables
  201. systemctl enable libvirtd
  202. systemctl enable dnsmasq
  203. systemctl enable cronie
  204. systemctl enable ntpd
  205. systemctl enable sshd
  206. # attempt to enable dhcp on active network devices on reboot
  207. export active_network_device=$(ip addr | awk '/state UP/ {print $2}' | sed 's/.$//')
  208. [ ! -d "/sys/class/net/${active_network_device}/wireless" ] && (systemctl enable dhcpcd@${active_network_device} || echo "failed to enable dhcp service")
  209. # (re)build vmlinux image
  210. mkinitcpio -p linux
  211. # install the bootloader
  212. bootctl install
  213. # create boot loader entry
  214. echo "title arch" > /boot/loader/entries/arch.conf
  215. echo "linux vmlinuz-linux" >> /boot/loader/entries/arch.conf
  216. [ -f /boot/intel-ucode.img ] && echo "initrd /intel-ucode.img" >> /boot/loader/entries/arch.conf
  217. [ -f /boot/amd-ucode.img ] && echo "initrd /amd-ucode.img" >> /boot/loader/entries/arch.conf
  218. echo "initrd /initramfs-linux.img" >> /boot/loader/entries/arch.conf
  219. export boot_options="options root=PARTUUID=$(blkid -s PARTUUID -o value $(mount | grep ' / '|cut -d' ' -f 1)) rw quiet loglevel=3"
  220. [ "$enable_hibernation" = "y" ] && [ -n "$resume_uuid" ] && boot_options="${boot_options} resume=UUID=${resume_uuid}"
  221. [[ $(lspci | grep -i " vga" | grep -ci " nvidia") -gt 0 && $(grep -c "nvidia" /boot/loader/entires/arch.conf) -eq 0 ]] && boot_options="${boot_options} nvidia-dkm.modeset=1"
  222. echo "$boot_options" >> /boot/loader/entries/arch.conf
  223. # set boot loader entry as default
  224. sed -i '/^default/d' /boot/loader/loader.conf
  225. echo "default arch.conf" >> /boot/loader/loader.conf
  226. # check boot loader configuration
  227. bootctl status
  228. # cleanup pacman cache to minimize image
  229. yes | pacman -Scc
  230. sync