diff options
| author | Craig Jennings <craigmartinjennings@gmail.com> | 2023-04-16 10:05:01 -0500 |
|---|---|---|
| committer | Craig Jennings <craigmartinjennings@gmail.com> | 2023-04-16 10:05:01 -0500 |
| commit | a9a804d293695710e6edf25cfe4b2c36fa21fe52 (patch) | |
| tree | 18394b21c2319819354bf5bc46a67a9bc61f4de8 | |
moving from sr.ht
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Vagrantfile | 71 | ||||
| -rwxr-xr-x | archsetup.sh | 891 | ||||
| -rw-r--r-- | post-install | 9 | ||||
| -rw-r--r-- | todo.org | 6 |
5 files changed, 978 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c1a0118 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.vagrant/ diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..f84a67a --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,71 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# All Vagrant configuration is done below. The "2" in Vagrant.configure +# configures the configuration version (we support older styles for +# backwards compatibility). Please don't change it unless you know what +# you're doing. +Vagrant.configure("2") do |config| + # The most common configuration options are documented and commented below. + # For a complete reference, please see the online documentation at + # https://docs.vagrantup.com. + + # Every Vagrant development environment requires a box. You can search for + # boxes at https://vagrantcloud.com/search. + config.vm.box = "archlinux/archlinux" + + # Disable automatic box update checking. If you disable this, then + # boxes will only be checked for updates when the user runs + # `vagrant box outdated`. This is not recommended. + # config.vm.box_check_update = false + + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine. In the example below, + # accessing "localhost:8080" will access port 80 on the guest machine. + # NOTE: This will enable public access to the opened port + # config.vm.network "forwarded_port", guest: 80, host: 8080 + + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine and only allow access + # via 127.0.0.1 to disable public access + # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1" + + # Create a private network, which allows host-only access to the machine + # using a specific IP. + # config.vm.network "private_network", ip: "192.168.33.10" + + # Create a public network, which generally matched to bridged network. + # Bridged networks make the machine appear as another physical device on + # your network. + config.vm.network "public_network", bridge: "enp2s0", type: "dhcp" + config.vm.hostname = "archlinux-base" + + # Share an additional folder to the guest VM. The first argument is + # the path on the host to the actual folder. The second argument is + # the path on the guest to mount the folder. And the optional third + # argument is a set of non-required options. + config.vm.synced_folder "~cjennings/code/archsetup/", "/vagrant_data" + + # Provider-specific configuration so you can fine-tune various + # backing providers for Vagrant. These expose provider-specific options. + # Example for VirtualBox: + # + config.vm.provider "virtualbox" do |vb| + # # Display the VirtualBox GUI when booting the machine + vb.gui = false + # + # # Customize the amount of memory on the VM: + vb.memory = "8192" + end + # + # View the documentation for the provider you are using for more + # information on available options. + + # Enable provisioning with a shell script. Additional provisioners such as + # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the + # documentation for more information about their specific syntax and use. + # config.vm.provision "shell", inline: <<-SHELL + # apt-get update + # apt-get install -y apache2 + # SHELL +end diff --git a/archsetup.sh b/archsetup.sh new file mode 100755 index 0000000..73a4f73 --- /dev/null +++ b/archsetup.sh @@ -0,0 +1,891 @@ +#!/bin/sh +# ArchSetup - Craig Jennings <craigmartinjennings@gmail.com> +# License: GNU GPLv3 + +# Commentary +: ' + +This script assumes the following of the base install +* btrfs for the root and home file system + I use the snapshot/recover feature of btrfs and install related tools. +* grub as the boot manager + required for grub-btrfs to display the rollback-to-snapshot menu. +* a network connection + though network-manager will be installed regardless + +This first installs and configures what I feel is essential +software for running my system. After essential software is +complete, it installs all non-essential applications within +an install loop. Essential software is hard-coded in this +script. Non-essential software is listed in a software.csv +text file. If the software.csv file is inaccessible, I can still +build a working (though less functional) desktop. + +Notes: +This script creates a tmpfs RAM disk for all compilation. + +I define two levels of errors: +* STOP: Issues that will halt forward progress, aborting this script. +* ERROR: Issues not serious enough to prevent the script from continuing. +Both are printed on screen and in the $logfile. +Stderr is also printed to the $logfile for all relevant info. + +Outstanding Tasks: + +' +# Code + +# uncomment to stop on any error +# set -e + +### Constants + +username="cjennings" +password="welcome" # change on first login. :) + +dwm_repo="https://git.cjennings.net/dwm.git" +dmenu_repo="https://git.cjennings.net/dmenu.git" +st_repo="https://git.cjennings.net/st.git" +dotfiles_repo="https://git.cjennings.net/dotfiles" +dotemacs_repo="https://git.cjennings.net/dotemacs.git" +dotfiles_home="/home/$username/.dotfiles" + +logfile="/var/log/archsetup-$(date +'%Y-%m-%d-%H-%M-%S').log" # logfile location +source_dir="/home/$username/.local/src" # aur/git source goes here +packages_before="/var/log/archsetup-preexisting-package-list.txt" +packages_after="/var/log/archsetup-post-install-package-list.txt" +archsetup_packages="/var/log/archsetup-installed-packages.txt" + +### Intro + +intro() { + printf "\n\nArchSetup launched @ %s\n" "$(date +'%D %T')"| tee -a "$logfile" + STARTTIME=$(date +%s) + errors_encountered=0 + + # begin with a clean logfile + [ -f "$logfile" ] && rm -f "$logfile" + touch "$logfile" + + # count the arch packages before install + pacman -Q > "$packages_before" || \ + error "crash" "generating pre-install package list" "$?" +} + +### General Functions +# Error +error () { + # $1 = type ERROR, noted but the script will continue to run. + # anything else will produce CRASH, which halts the script + # $2 = what was happening (e.g., "adding $username to group $groupname", etc.) + # $3 = the error code (i.e., "$?") + + errors_encountered=$((errors_encountered+1)) + case "$1" in + "error") + printf "ERROR: %s failed with error code %s @ %s\n" \ + "$2" "$3" "$(date +'%T')" | tee -a "$logfile" + return 1; + ;; + *) + printf "CRASH: %s failed with error code: %s @ %s. Script halted.\n" \ + "$2" "$3" "$(date +'%T')" | tee -a "$logfile" + exit 1; + ;; + esac +} + +# Display +display () { + # $1 = type (TITLE, ACTION) + # $2 = description (answers: "what are you trying to do?") + + case "$1" in + "title") + printf "\n##### %s\n" "$2" | tee -a "$logfile" + return 1; + ;; + "subtitle") + printf "\n%s\n" "$2" | tee -a "$logfile" + ;; + "task") + printf "...%s @ %s\n" "$2" "$(date +'%T')" | tee -a "$logfile" + return 1; + ;; + *) + printf "CRASH: display () called with incorrect arguments.\n" + printf "...called %s type, %s action @ %s\n" \ + "$1" "$2" "$(date +'%T')" | tee -a "$logfile" + exit 1; + ;; + esac + +} + +# Pacman Install + +pacman_install() { + action="installing $1 via pacman" && display "task" "$action" + if ! (pacman --noconfirm --needed -S "$1" >> "$logfile" 2>&1); then + action="retrying $1" && display "task" "$action" + if ! (pacman --noconfirm --needed -S "$1" >> "$logfile" 2>&1); then + action="retrying $1 once more" && display "task" "$action" + (pacman --noconfirm --needed -S "$1" >> "$logfile" 2>&1) || + error "error" "$action" "$?" + fi + fi + +} + +# Git Install +git_install() { + prog_name="$(basename "$1" .git)" + build_dir="$source_dir/$prog_name" + action="building & installing $prog_name from source" + display "task" "$action" + + if ! (sudo -u "$username" git clone --depth 1 "$1" "$build_dir" >> "$logfile" 2>&1); then + error "error" "cloning source code for $prog_name" "$?" + (cd "$build_dir" && sudo -u "$username" git pull --force origin master >> "$logfile" 2>&1) || \ + error "error" "pulling source code for $prog_name" "$?" + fi + + (cd "$build_dir" && make install >> "$logfile" 2>&1) || \ + error "error" "building $prog_name from source code" "$?" +} + +# Aur Install +aur_install() { + action="installing $1 via the AUR" && display "task" "$action" + if ! (sudo -u "$username" yay -S --noconfirm "$1" >> "$logfile" 2>&1); then + action="retrying $1" && display "task" "$action" + if ! (sudo -u "$username" yay -S --noconfirm "$1" >> "$logfile" 2>&1); then + action="retrying $1 once more" && display "task" "$action" + (sudo -u "$username" yay -S --noconfirm "$1" >> "$logfile" 2>&1) || + error "error" "$action" "$?" + fi + fi +} + +# Pip Install +pip_install() { + [ -x "$(command -v "pip")" ] || pacman_install python-pip + action="installing $1 via PIP" && display "task" "$action" + (yes | sudo -u "$username" pip install "$1" >> "$logfile" 2>&1) || \ + error "error" "$action" "$?" +} + +### Prerequisites + +prerequisites() { + # why these software packages are 'required' + # base_devel - required tools to compile + # ca_certificates - for validation of keyrings, etc. + # coreutils - comparing package lists + # curl - to transfer source code + # git - tools required to work with git source respositories + # go - required to build yay, the aur installer + # ntp - must communicate with other servers in ordered manner + # python - required for python pip installs + # stow - for placing the dotfiles + # tar - extract unix archives + # vi - should things go wrong, we'll need an editor + # zsh - we'll need a shell interpreter for yay; this is mine + + display "title" "Prerequisites" + + display "subtitle" "Bootstrapping" + + action="ensuring current Arch Linux keyring" && display "task" "$action" + (pacman -S --noconfirm archlinux-keyring) >> $logfile 2>&1 || \ + error "crash" "$action" "$?" + + display "task" "verifying Arch Linux keys" + (pacman-key --populate archlinux >> "$logfile" 2>&1) || \ + error "crash" "verifying Arch Linux keys" "$?" + + action="refreshing the package cache" && display "task" "$action" + (pacman -Syu --noconfirm >> "$logfile" 2>&1) || error "crash" "$action" "$?" + + display "subtitle" "Required Software" + + for software in base-devel ca-certificates coreutils curl git go ntp openssh \ + python stow tar vi zsh; do + pacman_install "$software" + done + + display "subtitle" "Environment Configuration" + + # sync the time on this machine + action="synchronizing system time" && display "task" "$action" + (ntpdate 0.us.pool.ntp.org >> "$logfile" 2>&1) || error "error" "$action" "$?" + + action="configuring compiler to use all processor cores" && display "task" "$action" + sed -i "s/-j2/-j$(nproc)/;s/^#MAKEFLAGS/MAKEFLAGS/" /etc/makepkg.conf >> "$logfile" 2>&1 + + # enable pacman concurrent downloads and color + action="enabling concurrent downloads" && display "task" "$action" + sed -i "s/^#ParallelDownloads.*$/ParallelDownloads = 5/;s/^#Color$/Color/" /etc/pacman.conf + + action="Package Mirrors" && display "subtitle" "$action" + pacman_install reflector + + action="configuring reflector" && display "task" "$action" + (printf ' + --connection-timeout 3 \ + --download-timeout 3 \ + --protocol https \ + --age 12 \ + --latest 20 \ + --score 10 \ + --fastest 5 \ + --sort score \ + --save /etc/pacman.d/mirrorlist + ' > /etc/xdg/reflector/reflector.conf >> "$logfile" 2>&1) || \ + error "error" "$action" "$?" + + action="updating repository mirrors" && display "task" "$action" + (reflector --connection-timeout 3 \ + --download-timeout 3 \ + --protocol https \ + --age 12 \ + --latest 20 \ + --score 10 \ + --fastest 5 \ + --sort score \ + --save /etc/pacman.d/mirrorlist > /dev/null 2>&1) + + action="enabling the reflector timer" && display "task" "$action" + (systemctl enable reflector.timer >> "$logfile" 2>&1) || \ + error "error" "$action" "$?" + + action="replacing sudoers file if new package version exists" && display "task" "$action" + [ -f /etc/sudoers.pacnew ] && cp /etc/sudoers.pacnew /etc/sudoers >> "$logfile" 2>&1 + + action="creating a directory to build/install software from git/AUR." + (mkdir -p $source_dir) || error "crash" "creating the directory $source_dir" + +} + +### Create User +create_user () { + display "title" "User Creation" + + display "task" "checking if user exists" + # halt if $username exists + ( id -u "$username" >/dev/null 2>&1; ) && \ + error "crash" "user '$username' already exists!" + + # create $username with home, group, shell, password + action="creating user and home directory" && display "task" "$action" + (useradd -m -G wheel -s /bin/zsh "$username" >> "$logfile" 2>&1) || \ + error "crash" "adding user '$username" "$?" + + display "task" "assigning the password" + echo "$username:$password" | chpasswd # any text is allowable! be careful! + + display "task" "configuring shell" + # zsh cache required: $username will install via yay; zsh will run those commands + mkdir -p "/home/$username/.cache/zsh/" | tee -a "$logfile" + + # give $username sudo nopasswd rights (required for aur installs) + display "task" "granting permissions" + (echo "%$username ALL=(ALL) NOPASSWD: ALL #ArchSetup" >> /etc/sudoers) \ + || error "error" "$action" "$?" + + # # mount as ramdisk to speed aur/git build/installs + # (sudo mount -t tmpfs -o size=4G archsetup $source_dir >> "$logfile" 2>&1) || \ + # error "crash" "mounting the RAM disk for archsetup" "$?" + + (chown -R "$username":wheel "$(dirname "$source_dir")" >> "$logfile" 2>&1) || \ + error "crash" "changing ownership of $source_dir" "$?" +} + +### User Customizations + +user_customizations() { + action="User Customizations" && display "title" "$action" + + action="cloning dotfiles" && display "task" "$action" + (git clone --depth 1 $dotfiles_repo "$dotfiles_home" \ + >> "$logfile" 2>&1) || error "error" "$action" "$?" + + action="moving dotfiles into place" && display "task" "$action" + (cd "$dotfiles_home" && stow --adopt * \ + >> "$logfile" 2>&1 ) || error "error" "$action" "$?" + + action="restoring dotfile versions" && display "task" "$action" + (cd "$dotfiles_home" && git restore . \ + >> "$logfile" 2>&1 ) || error "error" "$action" "$?" + + action="creating common directories" && display "task" "$action" + # Create default directories and grant permissions + { + mkdir -p -m 751 /home/$username/code + mkdir -p -m 751 /home/$username/documents + mkdir -p -m 751 /home/$username/downloads/torrents/complete + mkdir -p -m 751 /home/$username/downloads/torrents/incomplete + mkdir -p -m 751 /home/$username/downloads/torrents/files + mkdir -p -m 751 /home/$username/downloads/ebooks + mkdir -p -m 751 /home/$username/music + mkdir -p -m 751 /home/$username/projects + mkdir -p -m 751 /home/$username/pictures/screenshots + mkdir -p -m 751 /home/$username/videos + mkdir -p -m 751 /home/$username/vms + chown -R $username: /home/$username + + mkdir -p -m 751 /media/backup + mkdir -p -m 751 /media/remote0 + mkdir -p -m 751 /media/remote1 + mkdir -p -m 751 /media/remote2 + chown -R $username: /media + } >> "$logfile" 2>&1 + +} + +### AUR Installer +aur_installer () { + display "title" "AUR Installer" + + yay_repo="https://aur.archlinux.org/yay.git" + build_dir="$source_dir/yay" + + display "task" "fetching source code for yay" + if ! (sudo -u "$username" git clone --depth 1 "$yay_repo" "$build_dir" >> "$logfile" 2>&1); then + error "error" "cloning source code for Yay" + (sudo -u "$username" -D "$build_dir" git pull --force origin master >> "$logfile" 2>&1) || \ + error "crash" "changing directories to $build_dir and pulling source code" "$?" + fi + + action="packaging and installing yay"; display "task" "$action" + (cd "$build_dir" && sudo -u "$username" makepkg --noconfirm -si >> "$logfile" 2>&1) || \ + error "crash" "$action" "$?" +} + +### Essential Services +essential_services() { + display "title" "Essential Services" + + # Networking + + display "subtitle" "Networking" + pacman_install networkmanager + + # Secure Shell + + display "subtitle" "Secure Shell" + pacman_install openssh + action="enabling the openssh service to run at boot" && display "task" "$action" + systemctl enable sshd >> "$logfile" 2>&1 || error "error" "$action" "$?" + action="starting the openssh service" && display "task" "$action" + systemctl start sshd >> "$logfile" 2>&1 || error "error" "$action" "$?" + + # Firewall + + # deny by default, then allow the following: + # http/s : 80/tcp, 443/tcp + # tor : 9040,9050,9051,9053,9119/tcp + # email : IMAP, IMAPS + # mDNS printer discovery : 5353/udp + # ssh : ssh + # syncthing : 22000/tcp, 22000/udp, 21027/udp + # torrents : transmission + # calibre content server : 8080/tcp + + display "subtitle" "Firewall" + pacman_install ufw + + action="configuring ufw to deny by default" && display "task" "$action" + ufw default deny incoming >> "$logfile" 2>&1 || error "error" "$action" + + for protocol in \ + "80/tcp" "443/tcp" "9040,9050,9051,9053,9119/tcp" "IMAP" "IMAPS" "55353/udp" \ + "ssh" "22000/tcp" "22000/udp" "21027/udp" "transmission" "8080/tcp"; do + action="adding ufw rule to allow $protocol" && display "task" "$action" + (ufw allow $protocol >> "$logfile" 2>&1) || error "error" "$action" "$?" + done + + action="adding limits to protect from brute force attacks" && display "task" "$action" + (ufw limit 22/tcp >> "$logfile" 2>&1 && \ + ufw limit 443/tcp >> "$logfile" 2>&1) || \ + error "error" "action" + + action="enabling firewall service to launch on boot" && display "task" "$action" + systemctl enable ufw.service >> "$logfile" 2>&1 || error "error" "$action" "$?" + + action="starting firewall service" && display "task" "$action" + systemctl start ufw.service >> "$logfile" 2>&1 || error "error" "$action" "$?" + + # Service Discovery + + display "subtitle" "Network Service Discovery" + pacman_install avahi + + action="configuring avahi" && display "task" "$action" + systemctl disable systemd-resolved.service >> "$logfile" 2>&1 || error "error" "$action" "$?" + systemctl enable avahi-daemon.service >> "$logfile" 2>&1 || error "error" "$action" "$?" + + # Job Scheduling + + display "subtitle" "Job Scheduling" + pacman_install cronie + action="enabling cronie to launch at boot" && display "task" "$action" + systemctl enable cronie >> "$logfile" 2>&1 || error "error" "$action" "$?" +} + +### Desktop Environment +desktop_environment() { + display "title" "Desktop Environment" + + # Display Server + + action="Display Server Dependencies" && display "subtitle" "$action" + pacman_install libglvnd + + action="Display Server" && display "subtitle" "$action" + for software in xorg-server xorg-xinit xorg-xsetroot xf86-video-intel \ + xsel xorg-xbacklight xf86-input-libinput \ + xorg-xdpyinfo xorg-xprop xorg-xwininfo \ + xorg-xinput xorg-xkill ; do + pacman_install $software + done + + # Window Managers + + action="Window Manager Dependencies" && display "subtitle" "$action" + for software in coreutils fontconfig freetype2 glibc libx11 libxft libxinerama; do + pacman_install $software + done; + + action="Window Managers" && display "subtitle" "$action" + pacman_install hyprland + aur_install waybar-hyprland-fix + pacman_install xdg-desktop-portal-hyprland + aur_install foot + + git_install $dwm_repo + git_install $dmenu_repo + git_install $st_repo + pacman_install alacritty # my dwm's default terminal + aur_install pinentry-dmenu # password entry works with dmenu + + # Core Fonts + + action="Core Fonts" && display "subtitle" "$action" + pacman_install ttf-firacode-nerd + pacman_install ttf-hack-nerd + pacman_install noto-fonts-emoji + aur_install ttf-all-the-icons + + # File System Utilities + + action="File System Utilities" && display "subtitle" "$action" + pacman_install sshfs + pacman_install dosfstools + pacman_install exfat-utils + pacman_install testdisk + pacman_install ntfs-3g + pacman_install udisks2 + aur_install inxi + + # File Associations + + action="File/Application Associations" && display "subtitle" "$action" + pacman_install perl-file-mimeinfo + pacman_install xdg-utils + + # File Associations + + action="Authentication Tools" && display "subtitle" "$action" + pacman_install gnupg + pacman_install polkit + pacman_install gnome-keyring + + # ensure correct permissions on .gpg directory + # the colon means the user's group will have perms + [ -d /home/"$username"/.gnupg ] || mkdir /home/"$username"/.gnupg + chown -R "$username": /home/"$username"/.gnupg + find /home/"$username"/.gnupg -type f -exec chmod 600 {} \; + find /home/"$username"/.gnupg -type d -exec chmod 700 {} \; + + # Power Management + + action="Power Management" && display "subtitle" "$action" + pacman_install acpi + pacman_install powertop + + # Audio System + + action="Audio System" && display "subtitle" "$action" + for software in alsa-utils pipewire wireplumber pipewire-pulse \ + pipewire-docs pamixer pulsemixer ffmpeg; do + pacman_install $software + done; + # disable the pc speaker beep + rmmod pcspkr >> "$logfile" 2>&1 + echo "blacklist pcspkr" >/etc/modprobe.d/nobeep.conf >> "$logfile" 2>&1 + + # Keyboard Shortcut Manager + + action="Keyboard Shortcut Manager" && display "subtitle" "$action" + pacman_install sxhkd + + # Notifications + + action="Notification System" && display "subtitle" "$action" + pacman_install libnotify + pacman_install dunst + + # Bluetooth Devices + + action="Bluetooth System" && display "subtitle" "$action" + for software in bluez bluez-utils blueman; do + pacman_install $software + done + action="enabling bluetooth to launch at boot" && display "task" "$action" + systemctl enable bluetooth.service >> "$logfile" 2>&1 ||e || error "error" "$action" "$?" + + # Command Line Utilities + + action="Command Line Utilities" && display "subtitle" "$action" + for software in htop mc ncdu tmux fzf zip unzip atool wget detox \ + lsof usbutils speedtest-cli moreutils; do + pacman_install "$software" + done; + + for software in lf-git task-spooler rar; do + aur_install "$software" + done; + + pip_install glances + + # Help And Documentation + + action="Help and Documentation" && display "subtitle" "$action" + for software in man arch-wiki-docs arch-wiki-lite; do + pacman_install $software + done; + + aur_install cht.sh-git + pip_install tldr + + # Desktop Environment Utilities + + action="Desktop Environment Utilities" && display "subtitle" "$action" + + for software in brightnessctl network-manager-applet xclip bc nitrogen; do + pacman_install $software + done; + + aur_install colorpicker + + # Browser + + action="Browsers" && display "subtitle" "$action" + pacman_install firefox + # aur_install tor-browser + # currently getting errors with the key validation + + # Install Printing + + action="Print System" && display "subtitle" "$action" + for software in cups cups-pdf foomatic-db-engine foomatic-db-ppds foomatic-db-nonfree-ppds \ + gutenprint foomatic-db-gutenprint-ppds nss-mdns; do + pacman_install "$software" + done + action="enabling printing service to launch at boot" && display "task" "$action" + (systemctl enable cups.service >> "$logfile" 2>&1) || error "error" "$action" "$?" +} + +### Developer Workstation +developer_workstation () { + + action="Developer Workstation" && display "title" "$action" + + action="Programming Languages and Utilities" && display "subtitle" "$action" + pacman_install clang # C/C++ compiler + pacman_install cmake # make system + pacman_install gdb # the gnu debuffer + pacman_install splint # C programming static analysis + pacman_install valgrind # memory management utility + + pacman_install rust # Rust programming language + + pacman_install pyright # Python language server + + pacman_install shellcheck # Shell script linter + pacman_install shfmt # Shell script formatter + + pacman_install go-tools # Go language utilities + pacman_install gopls # Go language server + pacman_install delve # Go programming language debugger + pacman_install staticcheck # Go programming language linter + + pacman_install typescript # Typescript programming language + pacman_install npm # Node-js package manager + aur_install nvm # Node-js version manager + pacman_install jq # JSON processor + + pacman_install meld # Visual diff + pacman_install ripgrep # Fast grep utility + + action="Programming Editors" && display "subtitle" "$action" + pacman_install mg + pacman_install neovim + + action="Emacs and Dependencies" && display "subtitle" "$action" + pacman_install emacs + + # supporting utilities used by my emacs configuration + pacman_install aspell # spell check system + pacman_install aspell-en # spell check english files + aur_install multimarkdown # markdown conversion + pacman_install sdcv # stardict dictionary system + pacman_install fd # a faster find for dired/dirvish + pacman_install imagemagick # image previews for dired/dirvish + pacman_install mediainfo # generating media info in dired/dirvish + pacman_install ffmpegthumbnailer # video previews in dired/dirvish + aur_install mu # email indexer and utilities + aur_install isync # email sync + pip_install yt-dlp # video download + pacman_install mpv # video viewer + pip_install proselint # grammar checker + aur_install exercism # command line tool for exercism.io + + + action="setting up emacs configuration files" && display "task" "$action" + (sudo -u "$username" git clone $dotemacs_repo /home/$username/.emacs.d >> "$logfile" 2>&1) || \ + error "error" "$action" "$?" + + # DevOps Utilities + + action="installing devops virtualization and automation tools" && display "task" "$action" + pacman_install virtualbox >> "$logfile" 2>&1 || error "error" "$action" "$?" + pacman_install virtualbox-guest-iso >> "$logfile" 2>&1 || error "error" "$action" "$?" + pacman_install virtualbox-host-modules-arch >> "$logfile" 2>&1 || error "error" "$action" "$?" + pacman_install linux-headers >> "$logfile" 2>&1 || error "error" "$action" "$?" + action="adding user to vboxusers group" && display "task" "$action" + (gpasswd -a $username vboxusers >> "$logfile" 2>&1) || error "error" "$action" "$?" + pacman_install docker + pacman_install docker-compose + action="adding user to docker group" && display "task" "$action" + (gpasswd -a $username docker >> "$logfile" 2>&1) || error "error" "$action" "$?" + action="enabling docker service to launch on boot" && display "task" "$action" + systemctl enable docker.service >> "$logfile" 2>&1 || error "error" "$action" "$?" + pacman_install vagrant >> "$logfile" 2>&1 || error "error" "$action" "$?" + pip_install ansible >> "$logfile" 2>&1 || error "error" "$action" "$?" + +} + +### Supplemental Software + +supplemental_software() { + + display "title" "Supplemental Software" + + # pacman installs + pacman_install arandr # xrandr gui for monitor settings + pacman_install arch-install-scripts # for making arch installers + pacman_install archinstall # the archinstall python program + pacman_install aria2 # fast downloader + pacman_install dash # posix compliant /bin/sh + pacman_install docx2txt # recovers text from docx files + pacman_install entr # run arbitrary commands when files change + pacman_install faac # open source mpeg 3 and aac encoder + pacman_install faad2 # processes an aac stream + pacman_install filezilla # ftp gui + pacman_install gparted # disk partition utility + pacman_install gst-plugin-pipewire # gstreamer audio plugin for pipewire + pacman_install gst-plugins-base # gstreamer base audio plugins + pacman_install gst-plugins-good # gstreamer extra audio plugins + pacman_install gstreamer # pipeline based multimedia framework + pacman_install gucharmap # gui display of character maps + pacman_install gzip # compression tool + pacman_install handbrake # video transcoder + pacman_install libconfig # library for processing structured config files + pacman_install libmad # mpeg audio decoder + pacman_install libmpeg2 # library for decoding mpeg video streams + pacman_install maim # screenshot utility + pacman_install mediainfo # technical and tag information about media files + pacman_install mosh # alt SSH terminal with roaming and responsiveness support + pacman_install mpc # command line interface to mpd + pacman_install mpd # the music player daemon + pacman_install ncmpcpp # and mpd client to play music + pacman_install neofetch # cli system information tool + pacman_install odt2txt # converts from open document to text + pacman_install p7zip # p7zip compression tool + pacman_install pandoc # universal document converter + pacman_install perl-image-exiftool # reads/writes exif info for raw photo files + pacman_install pv # monitor progress of data through pipeline + pacman_install rclone # syncs files from gdrive, s3, dropbox, etc. + pacman_install smartmontools # monitors hard drives + pacman_install syncthing # sync utility + pacman_install texlive-most # latex + pacman_install transmission-cli # bittorrent client + pacman_install transmission-remote-gtk # bittorrent client + pacman_install unclutter # hides mouse cursor when not being used + pacman_install w3m # text based browser + pacman_install wavpack # audio compression format + pacman_install webkit2gtk # web content engine for GTK + pacman_install xdotool # command line xorg automation tool + pacman_install xz # general purpose data compression tool + pacman_install zathura # document viewer + pacman_install zathura-cb # zathura plugin for comics + pacman_install zathura-djvu # zathura plugin for djvu books + pacman_install zathura-pdf-mupdf # zathura plugin for pdf + pacman_install poppler-glib # poppler-glib document viewer library + pacman_install zlib # compression library + aur_install authy # two-factor authenticator + pip_install dtrx # extraction tool + aur_install hfsprogs # file system tools for Mac OS + aur_install mcomix # image viewer for comic books + aur_install nsxiv # image viewer + aur_install picom-jonaburg-git # xorg compositor with enhancements + aur_install plexamp-appimage # music player + aur_install topgrade # invokes upgrade procedures of various package maangers + aur_install tremc # curses interface for transmission + aur_install zsh-fast-syntax-highlighting-git # Optimized and extended zsh-syntax-highlighting + git_install https://github.com/clamiax/snore.git # sleep with feedback + pip_install ranger # terminal file manager + pip_install pydf # better display of available space on mounted filesystems + pip_install tidal-dl # tidal-dl: tidal as yt-dlp:youtube + pacman_install lxappearance # GTK+ theme switcher + + # nice fonts + pacman_install ttf-crimson-pro + pacman_install ttf-crimson-pro-variable + pacman_install ttf-sourcecodepro-nerd + pacman_install otf-cascadia-code-nerd + pacman_install ttf-go-nerd + pacman_install ttf-jetbrains-mono-nerd + pacman_install ttf-meslo-nerd + aur_install ttf-lato + + +} + +### Silent Boot + +silent_boot() { + + action="Silent Boot" && display "title" "$action" + + action="removing distro and date/time from initial screen" && display "task" "$action" + (cat /dev/null >/etc/issue) || error "error" "$action" "$?" + + action="preventing kernel messages on the console" && display "task" "$action" + (echo "kernel.printk = 3 3 3 3" >/etc/sysctl.d/20-quiet-printk.conf) || \ + error "error" "$action" "$?" + + action="delegating fsck messages from udev to systemd" && display "task" "$action" + sed -i "s/.*HOOKS=(base udev autodetect keyboard keymap modconf block filesystems fsck).*/HOOKS=(base systemd autodetect keyboard keymap modconf block filesystems fsck)/" /etc/mkinitcpio.conf || error "error" "running sed on mkinitcpio.conf to hide fsck messages" "$?" + mkinitcpio -P >> "$logfile" 2>&1 || error "error" "running mkinitcpio -P to silence fsck messages" "$?" + + action="instructing systemd to check filesystems" && display "task" "$action" + servicefile=/usr/lib/systemd/system/systemd-fsck-root.service + [ -f $servicefile ] && echo "StandardOutput=null" >>$servicefile && \ + echo "StandardError=journal+console" >>$servicefile + + servicefile=/usr/lib/systemd/system/systemd-fsck@.service + [ -f $servicefile ] && echo "StandardOutput=null" >>$servicefile && \ + echo "StandardError=journal+console" >>$servicefile + + action="removing hostname from login prompt" && display "task" "$action" + sed -i "s/--noclear/--nohostname --noclear/g" /usr/lib/systemd/system/getty@.service \ + || error "error" "$action" "$?" + + action="silencing the unneeded and chatty watchdog module" && display "task" "$action" + echo "blacklist iTCO_wdt" >/etc/modprobe.d/nowatchdog.conf || error "error" "$action" "$?" + + # on systemd boot, eliminate timeout and silence boot text + if [ -f /boot/loader/loader.conf ]; then + action="eliminating timeout and silencing boot test on systemd boot" && display "task" "$action" + echo "timeout=0" >/boot/loader/loader.conf + + # the file in this location was named based on the time of the install, so we must use find to identify it. + kernelfile=$(find /boot/loader/entries/ -name "*.conf") + # hush boot output via kernel parameters + sed -i "/.*options root=PARTUUID.*/ s/$/quiet rd.systemd.show_status=auto rd.udev.log_level=2 nvme.noacpi=1 mem_sleep_default=deep nowatchdog/" "$kernelfile" + fi + + # if grub, reset timeouts and adjust log levels + if [ -f /etc/default/grub ]; then + action="resetting timeouts and adjusting log levels on grub boot" && display "task" "$action" + sed -i "s/.*GRUB_TIMEOUT=.*/GRUB_TIMEOUT=2/g" /etc/default/grub + sed -i "s/.*GRUB_DEFAULT=.*/GRUB_DEFAULT=0/g" /etc/default/grub + sed -i "s/.*GRUB_RECORDFAIL_TIMEOUT=.*/GRUB_RECORDFAIL_TIMEOUT=$GRUB_TIMEOUT/g" /etc/default/grub + sed -i "s/.*GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT=\"rw quiet loglevel=2 rd.systemd.show_status=auto rd.udev.log_level=2 nvme.noacpi=1 mem_sleep_default=deep nowatchdog\"/g" /etc/default/grub + grub-mkconfig -o /boot/grub/grub.cfg >> "$logfile" 2>&1 || error "error" "" "$?" + fi +} + +### Configure Snapshots + +configure_snapshots() { + + # note that the order of these commands are important + action="Snapshots and Recovery" && display "title" "$action" + aur_install grub-btrfs + + action="configuring boot menu to display snapshots" && display "task" "$action" + (grub-mkconfig -o /boot/grub/grub.cfg >> "$logfile" 2>&1) || error "error" "$action" "$?" + + # install timeshift + autosnap + aur_install timeshift + aur_install timeshift-autosnap + + action="taking initial btrfs snapshot" && display "task" "$action" + (timeshift --btrfs --create --comments "ArchSetup initial snapshot on $(date +'%D %T')" >> \ + "$logfile" 2>&1) || error "error" "$action" "$?" + + action="enabling automatic snapshots in the boot menu" && display "task" "$action" + (systemctl enable --now grub-btrfs.path >> "$logfile" 2>&1) || error "error" "$action" "$?" + +} + +### Outro + +outro() { + + display "title" "Generating Statistics" + action="identifying newly installed packages" && display "task" "$action" + pacman -Q > "$packages_after" || error "error" "$action" "$?" + (comm -13 --nocheck-order "$packages_before" "$packages_after" > "$archsetup_packages") || \ + error "error" "$action" "$?" + + action="comparing timestamps" && display "task" "$action" + ENDTIME=$(date +%s) + totalsecs=$(($ENDTIME - $STARTTIME)) + mins=$(($totalsecs / 60)) + secs=$(($totalsecs % 60)) + + new_packages=$(cat $archsetup_packages | wc -l) + + printf "\n" + printf "Completion time : %s\n" "$(date +'%D %T')" | tee -a "$logfile" + printf "Elapsed time : %s minutes, %s seconds\n" $mins $secs | tee -a "$logfile" + printf "Errors encountered : %s\n" $errors_encountered | tee -a "$logfile" + printf "Log file location : %s\n" "$logfile" + printf "Packages installed : %s\n" "$new_packages" + printf "\n" + printf "Please reboot before working with your new workstation.\n\n" +} + +### Installation Steps + +intro # take start stats + +prerequisites # install software required to install software +create_user # create user in wheel with :nopasswd sudo +user_customizations # dotfiles +aur_installer # install yay +essential_services +desktop_environment +developer_workstation +supplemental_software +silent_boot # make booting less noisy +configure_snapshots # automatic snapshots added to grub menu for restoration + +outro # take end stats; show summary + +exit 0 diff --git a/post-install b/post-install new file mode 100644 index 0000000..1d8fb2d --- /dev/null +++ b/post-install @@ -0,0 +1,9 @@ +# post install tasks + +# to untracked files (else your status will be littered) +dotfiles config --local status.showUntrackedFiles no + +# to reset the remote for natural pushing/pulling +dotfiles remote remove origin +dotfiles remote add -t main -m main origin git@cjennings.net:dotfiles.git +dotfiles push --set-upstream origin main diff --git a/todo.org b/todo.org new file mode 100644 index 0000000..2e262a0 --- /dev/null +++ b/todo.org @@ -0,0 +1,6 @@ +* Work Items +** TODO take btrfs snapshot before starting installs +** TODO test +** TODO default image previewing in kitty/foot terminals for xorg/wayland +** TODO das keyboard wheel functionality not on hyprland +* Resolved |
