arch.sh 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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 "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. # update and install all packages
  46. pacman -Syu --noconfirm sudo bash-completion man-db tmux vim linux-firmware linux-headers dkms smartmontools cryptsetup usbutils btrfs-progs gvfs gvfs-mtp gvfs-afc android-udev dmidecode parted pkgfile pkgconf bison gcc gcc-libs cmake ccache ncurses xmlstarlet jq at bc cronie iptables rsync dhcpcd net-tools openssh sshfs ntp wget curl wireless_tools bluez bluez-utils lzop unzip p7zip xz unrar unace lrzip arj git mercurial subversion bzr postgresql mesa lib32-mesa dbus polkit xorg-server xorg-server-devel xorg-xinit xorg-xinput xorg-xdpyinfo xorg-xprop xdotool xsel pulseaudio libpulse lib32-libpulse openal lib32-openal giflib lib32-giflib mpg123 lib32-mpg123 v4l-utils lib32-v4l-utils opencl-icd-loader lib32-opencl-icd-loader libva lib32-libva gtk3 lib32-gtk3 gst-plugins-base-libs lib32-gst-plugins-base-libs vulkan-tools vulkan-icd-loader lib32-vulkan-icd-loader arandr feh hsetroot openbox archlinux-xdg-menu picom xarchiver innoextract pavucontrol pasystray python2-xdg xdg-utils xdg-user-dirs tint2 conky pcmanfm gmrun rxvt-unicode urxvt-perls gnome-themes-extra gnome-icon-theme arc-gtk-theme gtk-engines gtk-engine-murrine lxappearance graphicsmagick imagemagick lame libwebp libid3tag libvorbis vorbis-tools faac x264 x265 libexif ffmpeg ffmpegthumbnailer tumbler joyutils evtest lm_sensors lshw gparted psensor gparted hardinfo fontconfig ttf-bitstream-vera ttf-droid ttf-dejavu ttf-liberation ttf-hanazono mpv openshot gimp krita transmission-cli discord evince viewnior virtualbox-host-modules-arch virtualbox vagrant obs-studio dia mednafen mame ppsspp lutris steam wine-staging python-pip python-setuptools winetricks sublime-text
  47. # if the active network device is wireless install connman
  48. [ -d "/sys/class/net/${active_network_device}/wireless" ] && pacman -Syu connman wpa_supplicant openvpn ethtool iwd pptpclient && systemctl enable connman
  49. # install protontricks
  50. python3 -m pip install protontricks
  51. # enable ccache and optimize cores for AUR
  52. sed -i 's/!ccache/ccache/' /etc/makepkg.conf
  53. sed -i 's/^#MAKEFLAGS.*/MAKEFLAGS="-j$(($(nproc) + 1)) -l$(nproc)"/' /etc/makepkg.conf
  54. # install CPU unicode based on model
  55. [ $(grep -c "Intel" /proc/cpuinfo) -gt 0 ] && pacman -Syu --noconfirm intel-ucode
  56. [ $(grep -c "AMD" /proc/cpuinfo) -gt 0 ] && pacman -Syu --noconfirm amd-ucode
  57. # install nvidia related packages
  58. if [ $(lspci | grep -i " vga" | grep -ci " nvidia") -gt 0 ]; then
  59. pacman -Syu --noconfirm nvidia-dkms libglvnd nvidia-utils opencl-nvidia lib32-libglvnd lib32-nvidia-utils lib32-opencl-nvidia nvidia-settings
  60. # update modules to load
  61. [ $(grep -c "nvidia" /etc/mkinitcpio.conf) -eq 0 ] && sed -i 's/MODULES=(\(.*\))/MODULES=(\1 nvidia nvidia_modeset nvidia_uvm nvidia_drm)/' /etc/mkinitcpio.conf
  62. # automatic updates in pacman.d
  63. 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
  64. fi
  65. # install AMD/Radeon related packages
  66. if [ $(lspci | grep -i "vga" | grep -ci "amd") -gt 0 ]; then
  67. pacman -Syu --noconfirm xf86-video-amdgpu vulkan-radeon lib32-vulkan-radeon libva-mesa-driver lib32-libva-mesa-driver mesa-vdpau lib32-mesa-vdpau amdvlk lib32-amdvlk
  68. # update modules to load
  69. [ $(grep -c "amd" /etc/mkinitcpio.conf) -eq 0 ] && sed -i 's/MODULES=(\(.*\))/MODULES=(\1 amdgpu radeon)/' /etc/mkinitcpio.conf
  70. fi
  71. # create a user to install aur packages
  72. export aur_username=$(head /dev/urandom | tr -dc a-z | head -c 13 ; echo '')
  73. useradd -r -m -s /bin/bash $aur_username
  74. echo "${aur_username} ALL= NOPASSWD: /usr/bin/pacman" > /etc/sudoers.d/${aur_username}
  75. # install laptop packages and optimize system configuration
  76. export chassistype=$(dmidecode --string chassis-type)
  77. if [[ "$chassistype" = "Laptop" || "$chassistype" = "Portable" || "$chassistype" = "Notebook" || "$chassistype" = "Sub Notebook" ]]; then
  78. pacman -Syu --noconfirm xf86-input-synaptics acpid hdparm sdparm acpilight connman wpa_supplicant openvpn ethtool iwd pptpclient tlp
  79. systemctl enable connman
  80. systemctl enable acpid
  81. fi
  82. # install xcursor-chameleon-skyblue
  83. sudo -u $aur_username git clone https://aur.archlinux.org/xcursor-chameleon-skyblue.git /home/${aur_username}/xcursor-chameleon-skyblue
  84. (cd /home/${aur_username}/xcursor-chameleon-skyblue && sudo -u ${aur_username} makepkg -rcsi --noconfirm)
  85. # install numix-icon-theme
  86. sudo -u $aur_username git clone https://aur.archlinux.org/numix-icon-theme-git.git /home/${aur_username}/numix-icon-theme-git
  87. (cd /home/${aur_username}/numix-icon-theme-git && sudo -u ${aur_username} makepkg -rcsi --noconfirm)
  88. # install google-chrome (google-chrome-stable)
  89. sudo -u $aur_username git clone https://aur.archlinux.org/google-chrome.git /home/${aur_username}/google-chrome
  90. (cd /home/${aur_username}/google-chrome && sudo -u ${aur_username} makepkg -rcsi --noconfirm)
  91. # cleanup aur user
  92. rm -rf /etc/sudoers.d/${aur_username}
  93. userdel -fr $aur_username
  94. unset $aur_username
  95. # install youtube-dl
  96. if ! which youtube-dl &> /dev/null; then
  97. curl -Lfs https://yt-dl.org/latest/youtube-dl > /usr/local/bin/youtube-dl
  98. chmod a+rx /usr/local/bin/youtube-dl
  99. fi
  100. # install gifduration
  101. if ! which gifduration &> /dev/null; then
  102. curl -Lfs https://raw.githubusercontent.com/alimony/gifduration-script/master/gifduration.py > /usr/local/bin/gifduration
  103. chmod a+rx /usr/local/bin/gifduration
  104. fi
  105. # install prime95
  106. if ! which mprime &> /dev/null; then
  107. curl -Lfs "http://www.mersenne.org/ftp_root/gimps/p95v294b8.linux64.tar.gz" > /tmp/prime.tar.gz
  108. mkdir -p /usr/local/src/prime/
  109. tar -xf /tmp/prime.tar.gz -C /usr/local/src/prime
  110. ln -sf /usr/local/src/prime/mprime /usr/local/bin/
  111. fi
  112. # install packer
  113. if ! which packer &> /dev/null; then
  114. curl -Lfs "https://releases.hashicorp.com/packer/1.3.5/packer_1.3.5_linux_amd64.zip" > /tmp/packer.zip
  115. unzip /tmp/packer.zip -d /usr/local/bin/
  116. fi
  117. # install 64bit flash projector
  118. if ! which flashplayer &> /dev/null; then
  119. curl -Lfs "https://fpdownload.macromedia.com/pub/flashplayer/updaters/32/flash_player_sa_linux.x86_64.tar.gz" > /tmp/flash.tar.gz
  120. tar -xf /tmp/flash.tar.gz -C /usr/local/bin flashplayer
  121. fi
  122. # install urxvt perl enhancement for font resize support
  123. [ ! -f /usr/lib/urxvt/perl/font ] && curl -Lfs "https://raw.githubusercontent.com/noah/urxvt-font/master/font" > /usr/lib/urxvt/perl/font
  124. # create sudo group and add to sudoers
  125. groupadd -fr sudo
  126. [ ! -f /etc/sudoers.d/sudo ] && echo '%sudo ALL=(ALL) ALL' > /etc/sudoers.d/sudo
  127. # install base configuration files from repository
  128. [ -d /srv/arch-desktop/install ] || git clone https://git.caseydelorme.com/cdelorme/arch-desktop /srv/arch-desktop
  129. rsync -Pav /srv/arch-desktop/install/ /
  130. ln -sf .Xdefaults /etc/skel/.Xresources
  131. mkdir -p /etc/skel/.config/pulse
  132. sed "/module-suspend-on-idle/d" /etc/pulse/default.pa > /etc/skel/.config/pulse/default.pa
  133. # @note: we may want to avoid disabling this on laptops
  134. sed "/module-switch-on-port-available/d" /etc/pulse/default.pa > /etc/skel/.config/pulse/default.pa
  135. rsync -Pav /etc/skel/ $(getent passwd root | cut -d: -f6)/
  136. # update font cache
  137. fc-cache -fr
  138. # secure ssh by disabling root access and only accepting ssh keys
  139. sed -i "/^#\?PermitRootLogin/d" /etc/ssh/sshd_config
  140. sed -i "/^#\?PasswordAuthentication/d" /etc/ssh/sshd_config
  141. sed -i "/^#\?X11Forwarding/d" /etc/ssh/sshd_config
  142. echo "PermitRootLogin no" >> /etc/ssh/sshd_config
  143. echo "PasswordAuthentication no" >> /etc/ssh/sshd_config
  144. echo "X11Forwarding yes" >> /etc/ssh/sshd_config
  145. # set journald size
  146. sed -i '/^SystemMaxUse/d' /etc/systemd/journald.conf
  147. echo "SystemMaxUse=2G" >> /etc/systemd/journald.conf
  148. # set root password
  149. printf "${root_password}\n${root_password}\n" | passwd
  150. # after 4 bad logins lock an account for 10 minutes; or one minute for root
  151. sed -i -re 's/^(auth\s*required\s*pam_tally2.so).*/\1 deny=4 even_deny_root unlock_time=600 root_unlock_time=60 onerr=fail file=\/var\/log\/tallylog/g' /etc/pam.d/system-login
  152. # initialize postgres database
  153. su - postgres -c "initdb --locale en_US.UTF-8 -D '/var/lib/postgres/data'"
  154. # create configuration to fix transmission errors
  155. echo "net.core.rmem_max = 4194304" > /etc/sysctl.d/transmission.conf
  156. echo "net.core.wmem_max = 1048576" >> /etc/sysctl.d/transmission.conf
  157. # check whether username and password are not empty
  158. if [[ -n "$username" && -n "$password" ]]; then
  159. # create user if not exists, else (re)-install dot-files
  160. if ! id $username &> /dev/null; then
  161. useradd -m -s /bin/bash $username
  162. echo "${username}:${password}" | chpasswd -c SHA256
  163. else
  164. [ $EUID -ne 0 ] && rsync -Pav /etc/skel/ $(getent passwd $username | cut -d: -f6)/
  165. fi
  166. # add user to standard groups
  167. usermod -aG users,sudo,adm,input,audio,video,disk,storage,lp,vboxusers $username
  168. # generate postgres user and user database
  169. systemctl start postgresql
  170. su postgres -c "cd && createuser -ds $username" 2> /dev/null && su $username -c "cd && createdb"
  171. # configure and generate xdg-user-dirs
  172. su $username -c "cd && mkdir -p ~/{desktop,downloads,public,documents,music,pictures,videos,git} && xdg-user-dirs-update"
  173. update-desktop-database
  174. # generate default (passwordless) ed25519 ssh key if none exists
  175. 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"
  176. # @note: during arch installation systemd will ignore chroot start for user
  177. # so we have to take the manual route of generating the target symlink.
  178. su $username -c 'cd; mkdir $HOME/.config/systemd/user/default.target.wants; ln -fs $HOME/.config/systemd/user/ssh-agent.service $HOME/.config/systemd/user/default.target.wants/ssh-agent.service'
  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.12 -B && gvm use go1.12 --default"
  183. # setup 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. mkdir -p /etc/systemd/system/transmission.service.d
  188. echo "[Service]" > "/etc/systemd/system/transmission.service.d/local.conf"
  189. echo "User=${username}" >> "/etc/systemd/system/transmission.service.d/local.conf"
  190. systemctl daemon-reload
  191. fi
  192. fi
  193. # symlink shceduled maintenance tasks
  194. ln -sf /usr/local/bin/system-updates /etc/cron.daily/
  195. ln -sf /usr/local/bin/disk-maintenance /etc/cron.weekly/
  196. # symlink override vi to vim
  197. ln -sf /usr/bin/vim /usr/local/bin/vi
  198. # enable services for next reboot
  199. systemctl enable iptables
  200. systemctl enable ntpd
  201. systemctl enable sshd
  202. systemctl enable bluetooth
  203. systemctl enable transmission
  204. systemctl enable postgresql
  205. systemctl enable cronie
  206. # try to enable wired connections 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. # build the init module
  210. mkinitcpio -p linux || echo "mkinitcpio failed?"
  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. echo "options root=PARTUUID=$(blkid -s PARTUUID -o value $(mount | grep ' / '|cut -d' ' -f 1)) rw" >> /boot/loader/entries/arch.conf
  220. [[ $(lspci | grep -i " vga" | grep -ci " nvidia") -gt 0 && $(grep -c "nvidia" /boot/loader/entires/arch.conf) -eq 0 ]] && sed -i 's/rw/rw nvidia-dkm.modeset=1/' /boot/loader/entires/arch.conf
  221. # set boot loader entry as default
  222. sed -i '/^default/d' /boot/loader/loader.conf
  223. echo "default arch" >> /boot/loader/loader.conf
  224. # check boot loader configuration
  225. bootctl status
  226. echo "instalation complete, please exit, umount -R /mnt, and reboot..."