arch.sh 14 KB

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