arch.sh 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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 inetutils 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 patchelf libpng12 lib32-libpng12 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 arandr feh hsetroot openbox archlinux-xdg-menu picom xarchiver innoextract pavucontrol pasystray 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 evince viewnior virtualbox-host-modules-arch virtualbox vagrant python-pip python-setuptools sublime-text stress lxsession yt-dlp
  47. # install base configuration files from repository
  48. [ -d /srv/arch-desktop/install ] || git clone https://git.caseydelorme.com/cdelorme/arch-desktop /srv/arch-desktop
  49. rsync -Pav /srv/arch-desktop/install/ /
  50. mkdir -p /etc/skel/.config/pulse
  51. mkdir -p /etc/skel/{desktop,downloads,public,public/templates,documents,music,pictures,videos,git}
  52. sed "/module-suspend-on-idle/d" /etc/pulse/default.pa > /etc/skel/.config/pulse/default.pa
  53. # @note: we may want to avoid disabling this on laptops
  54. sed -i "/module-switch-on-port-available/d" /etc/skel/.config/pulse/default.pa
  55. rsync -Pav /etc/skel/ "$(getent passwd root | cut -d: -f6)/"
  56. sed -i "/ssh-add/d" "$(getent passwd root | cut -d: -f6)/.bashrc"
  57. # if the active network device is wireless install connman
  58. [ -d "/sys/class/net/${active_network_device}/wireless" ] && pacman -Syu connman wpa_supplicant openvpn ethtool iwd pptpclient && systemctl enable connman
  59. # install protontricks
  60. python3 -m pip install protontricks
  61. # enable ccache and optimize cores for AUR
  62. sed -i 's/!ccache/ccache/' /etc/makepkg.conf
  63. sed -i 's/^#MAKEFLAGS.*/MAKEFLAGS="-j$(($(nproc) + 1)) -l$(nproc)"/' /etc/makepkg.conf
  64. # install CPU unicode based on model
  65. [ $(grep -c "Intel" /proc/cpuinfo) -gt 0 ] && pacman -Syu --noconfirm intel-ucode
  66. [ $(grep -c "AMD" /proc/cpuinfo) -gt 0 ] && pacman -Syu --noconfirm amd-ucode
  67. # install GPU related packages
  68. if [ $(lspci | grep -i "vga" | grep -ci "amd") -gt 0 ]; then
  69. pacman -Syu --noconfirm xf86-video-amdgpu vulkan-radeon lib32-vulkan-radeon libva-mesa-driver lib32-libva-mesa-driver mesa-vdpau lib32-mesa-vdpau vulkan-tools vulkan-icd-loader lib32-vulkan-icd-loader
  70. # update modules to load
  71. [ $(grep -c "amd" /etc/mkinitcpio.conf) -eq 0 ] && sed -i 's/MODULES=(\(.*\))/MODULES=(\1 amdgpu radeon)/' /etc/mkinitcpio.conf
  72. elif [ $(lspci | grep -i "vga" | grep -ci "intel") -gt 0 ]; then
  73. pacman -Syu --noconfirm xf86-video-intel vulkan-intel lib32-vulkan-intel libva-mesa-driver lib32-libva-mesa-driver mesa-vdpau lib32-mesa-vdpau vulkan-tools vulkan-icd-loader lib32-vulkan-icd-loader
  74. # update modules to load
  75. [ $(grep -c "amd" /etc/mkinitcpio.conf) -eq 0 ] && sed -i 's/MODULES=(\(.*\))/MODULES=(\1 i915)/' /etc/mkinitcpio.conf
  76. elif [ $(lspci | grep -i "vga" | grep -ci "nvidia") -gt 0 ]; then
  77. pacman -Syu --noconfirm nvidia-dkms libglvnd lib32-libglvnd opencl-nvidia lib32-opencl-nvidia xf86-video-nouveau nvidia-utils lib32-nvidia-utils libva-mesa-driver lib32-libva-mesa-driver mesa-vdpau lib32-mesa-vdpau vulkan-tools vulkan-icd-loader lib32-vulkan-icd-loader nvidia-settings
  78. # update modules to load
  79. [ $(grep -c "nvidia" /etc/mkinitcpio.conf) -eq 0 ] && sed -i 's/MODULES=(\(.*\))/MODULES=(\1 nvidia nvidia_modeset nvidia_uvm nvidia_drm)/' /etc/mkinitcpio.conf
  80. # automatic mkinitcpio updates in pacman.d
  81. 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
  82. fi
  83. # install packages dependent on gpu packages
  84. pacman -Syu --noconfirm firefox obs-studio dia mednafen mame ppsspp lutris wine-staging winetricks steam discord
  85. # install laptop packages and optimize system configuration
  86. # @note: alternatively if `/sys/class/power_supply/BAT0` exists, we have a battery, probably laptop
  87. export chassistype=$(dmidecode --string chassis-type)
  88. if [[ "$chassistype" = "Laptop" || "$chassistype" = "Portable" || "$chassistype" = "Notebook" || "$chassistype" = "Sub Notebook" ]]; then
  89. pacman -Syu --noconfirm xf86-input-synaptics acpid hdparm sdparm acpilight connman wpa_supplicant openvpn ethtool iwd pptpclient tlp
  90. sed "s/panel_items = LTSC/panel_items = LTSBC/g" /etc/skel/.config/tint2/tint2rc > /etc/skel/.config/tint2/tint2rc
  91. systemctl enable connman
  92. systemctl enable acpid
  93. fi
  94. # create a user to install aur packages
  95. export aur_username=$(head /dev/urandom | tr -dc a-z | head -c 13 ; echo '')
  96. useradd -r -m -s /bin/bash $aur_username
  97. echo "${aur_username} ALL= NOPASSWD: /usr/bin/pacman" > /etc/sudoers.d/${aur_username}
  98. # install xcursor-chameleon-skyblue
  99. sudo -u $aur_username git clone https://aur.archlinux.org/xcursor-chameleon-skyblue.git /home/${aur_username}/xcursor-chameleon-skyblue
  100. (cd /home/${aur_username}/xcursor-chameleon-skyblue && sudo -u ${aur_username} makepkg -rcsi --noconfirm)
  101. # install numix-icon-theme
  102. sudo -u $aur_username git clone https://aur.archlinux.org/numix-icon-theme-git.git /home/${aur_username}/numix-icon-theme-git
  103. (cd /home/${aur_username}/numix-icon-theme-git && sudo -u ${aur_username} makepkg -rcsi --noconfirm)
  104. # cleanup aur user
  105. rm -rf /etc/sudoers.d/${aur_username}
  106. userdel -fr $aur_username
  107. unset $aur_username
  108. # install gifduration
  109. if ! which gifduration &> /dev/null; then
  110. curl -Lfs https://raw.githubusercontent.com/alimony/gifduration-script/master/gifduration.py > /usr/local/bin/gifduration
  111. chmod a+rx /usr/local/bin/gifduration
  112. fi
  113. # install packer
  114. if ! which packer &> /dev/null; then
  115. curl -Lfs "https://releases.hashicorp.com/packer/1.3.5/packer_1.3.5_linux_amd64.zip" > /tmp/packer.zip
  116. unzip /tmp/packer.zip -d /usr/local/bin/
  117. fi
  118. # install 64bit flash projector
  119. if ! which flashplayer &> /dev/null; then
  120. curl -Lfs "https://fpdownload.macromedia.com/pub/flashplayer/updaters/32/flash_player_sa_linux.x86_64.tar.gz" > /tmp/flash.tar.gz
  121. tar -xf /tmp/flash.tar.gz -C /usr/local/bin flashplayer
  122. fi
  123. # install urxvt perl enhancement for font resize support
  124. [ ! -f /usr/lib/urxvt/perl/font ] && curl -Lfs "https://raw.githubusercontent.com/noah/urxvt-font/master/font" > /usr/lib/urxvt/perl/font
  125. # create sudo group and add to sudoers
  126. groupadd -fr sudo
  127. [ ! -f /etc/sudoers.d/sudo ] && echo '%sudo ALL=(ALL) ALL' > /etc/sudoers.d/sudo
  128. # update font cache
  129. fc-cache -fr
  130. # secure ssh by disabling root access and only accepting ssh keys
  131. sed -i "/^#\?PermitRootLogin/d" /etc/ssh/sshd_config
  132. sed -i "/^#\?PasswordAuthentication/d" /etc/ssh/sshd_config
  133. sed -i "/^#\?X11Forwarding/d" /etc/ssh/sshd_config
  134. echo "PermitRootLogin no" >> /etc/ssh/sshd_config
  135. echo "PasswordAuthentication no" >> /etc/ssh/sshd_config
  136. echo "X11Forwarding yes" >> /etc/ssh/sshd_config
  137. # set journald size
  138. sed -i '/^SystemMaxUse/d' /etc/systemd/journald.conf
  139. echo "SystemMaxUse=2G" >> /etc/systemd/journald.conf
  140. # set root password
  141. printf "${root_password}\n${root_password}\n" | passwd
  142. # initialize postgres database
  143. su - postgres -c "initdb --locale en_US.UTF-8 -D '/var/lib/postgres/data'"
  144. # create configuration to fix transmission errors
  145. echo "net.core.rmem_max = 4194304" > /etc/sysctl.d/transmission.conf
  146. echo "net.core.wmem_max = 1048576" >> /etc/sysctl.d/transmission.conf
  147. # check whether username and password are not empty
  148. if [[ -n "$username" && -n "$password" ]]; then
  149. # create user if not exists, else (re)-install dot-files
  150. if ! id $username &> /dev/null; then
  151. useradd -m -s /bin/bash $username
  152. echo "${username}:${password}" | chpasswd -c SHA256
  153. else
  154. [ $EUID -ne 0 ] && rsync -Pav /etc/skel/ "$(getent passwd $username | cut -d: -f6)/"
  155. fi
  156. # add user to standard groups
  157. usermod -aG users,sudo,adm,input,audio,video,disk,storage,lp,vboxusers $username
  158. # generate postgres user and user database
  159. systemctl start postgresql
  160. su postgres -c "cd && createuser -ds $username" 2> /dev/null && su $username -c "cd && createdb"
  161. # load xdg-user-dirs
  162. su $username -c "cd && xdg-user-dirs-update"
  163. update-desktop-database
  164. # generate default (passwordless) ed25519 ssh key if none exists
  165. 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"
  166. # install gvm loading from ~/.bash_profile, and the latest go version
  167. 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"
  168. su $username -c 'grep "gvm" ~/.bash_profile &> /dev/null || echo -e "\n# load gvm\n! which gvm &> /dev/null && . ~/.gvm/scripts/gvm" >> ~/.bash_profile'
  169. su $username -c ". ~/.gvm/scripts/gvm && gvm install go1.17.3 -B && gvm use go1.17.3 --default"
  170. # setup user-space transmission
  171. if [ ! -f "/etc/systemd/system/transmission.service.d/local.conf" ]; then
  172. su $username -c "cd && mkdir -p ~/transmission/{done,incomplete}"
  173. 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'
  174. mkdir -p /etc/systemd/system/transmission.service.d
  175. echo "[Service]" > "/etc/systemd/system/transmission.service.d/local.conf"
  176. echo "User=${username}" >> "/etc/systemd/system/transmission.service.d/local.conf"
  177. systemctl daemon-reload
  178. fi
  179. fi
  180. # symlink shceduled maintenance tasks
  181. ln -sf /usr/local/bin/system-updates /etc/cron.daily/system-updates
  182. ln -sf /usr/local/bin/disk-maintenance /etc/cron.weekly/disk-maintenance
  183. # symlink override vi to vim
  184. ln -sf /usr/bin/vim /usr/local/bin/vi
  185. # enable services for next reboot
  186. systemctl enable iptables
  187. systemctl enable ntpd
  188. systemctl enable sshd
  189. systemctl enable bluetooth
  190. systemctl enable transmission
  191. systemctl enable postgresql
  192. systemctl enable cronie
  193. # try to enable wired connections on reboot
  194. export active_network_device=$(ip addr | awk '/state UP/ {print $2}' | sed 's/.$//')
  195. [ ! -d "/sys/class/net/${active_network_device}/wireless" ] && (systemctl enable dhcpcd@${active_network_device} || echo "failed to enable dhcp service")
  196. # build the init module
  197. mkinitcpio -p linux || echo "mkinitcpio failed?"
  198. # install the bootloader
  199. bootctl install
  200. # create boot loader entry
  201. echo "title arch" > /boot/loader/entries/arch.conf
  202. echo "linux vmlinuz-linux" >> /boot/loader/entries/arch.conf
  203. [ -f /boot/intel-ucode.img ] && echo "initrd /intel-ucode.img" >> /boot/loader/entries/arch.conf
  204. [ -f /boot/amd-ucode.img ] && echo "initrd /amd-ucode.img" >> /boot/loader/entries/arch.conf
  205. echo "initrd /initramfs-linux.img" >> /boot/loader/entries/arch.conf
  206. echo "options root=PARTUUID=$(blkid -s PARTUUID -o value $(mount | grep ' / '|cut -d' ' -f 1)) rw" >> /boot/loader/entries/arch.conf
  207. [[ $(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
  208. # set boot loader entry as default
  209. sed -i '/^default/d' /boot/loader/loader.conf
  210. echo "default arch" >> /boot/loader/loader.conf
  211. # check boot loader configuration
  212. bootctl status