494 lines
15 KiB
Bash
Executable file
494 lines
15 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set -uo pipefail
|
|
trap 's=$?; echo "$0: Error on line "$LINENO": $BASH_COMMAND"; exit $s' ERR
|
|
|
|
PRESERVE_ENV=AUR_PAGER,PACKAGER,EDITOR
|
|
|
|
if [[ $EUID != 0 ]]; then
|
|
echo 'Elevating privileges'
|
|
exec sudo --preserve-env="${PRESERVE_ENV}" "$0" "$@"
|
|
fi
|
|
|
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
|
|
|
|
# Initialize AUR repo
|
|
if [[ ! -d /var/cache/pacman/aur ]]; then
|
|
install -m755 -d /var/cache/pacman/aur
|
|
repo-add /var/cache/pacman/aur/aur.db.tar.zst
|
|
fi
|
|
|
|
# Configure pacman
|
|
install -pm644 "$DIR/etc/pacman/pacman.conf" /etc/pacman.conf
|
|
install -pm644 -Dt /etc/pacman.d/conf.d \
|
|
"$DIR/etc/pacman/00-global-options.conf" \
|
|
"$DIR/etc/pacman/50-core-repositories.conf" \
|
|
"$DIR/etc/pacman/55-multilib-repository.conf" \
|
|
"$DIR/etc/pacman/60-aurutils-repository.conf" \
|
|
"$DIR/etc/pacman/99-options.conf"
|
|
|
|
# Remove packages one by one because pacman doesn't handle uninstalled packages
|
|
# gracefully
|
|
packages_to_remove=(
|
|
)
|
|
|
|
for pkg in "${packages_to_remove[@]}"; do
|
|
pacman --noconfirm -Rs "$pkg" || true
|
|
done
|
|
|
|
packages=(
|
|
# Basic packages & system tools
|
|
base
|
|
dracut # Build initrd & unified EFI images
|
|
linux-firmware
|
|
intel-ucode
|
|
linux
|
|
lsb-release
|
|
sudo
|
|
zram-generator # swap on compressed RAM, mostly to support systemd-oomd
|
|
sbctl # Manage secure boot binaries and sign binaries
|
|
plymouth # Splash screen at boot
|
|
# File systems
|
|
ntfs-3g
|
|
exfatprogs
|
|
btrfs-progs
|
|
sshfs
|
|
# Hardware tools
|
|
fwupd # Firmware updates
|
|
usbutils # for lsusb
|
|
# System monitoring
|
|
htop
|
|
lsof
|
|
# Power management
|
|
powertop
|
|
power-profiles-daemon
|
|
# Networking
|
|
firewalld
|
|
# DNS-SD, mostly for printers, i.e. CUPS. Service discovery is handled by Avahi,
|
|
# name resolution by systemd-resolved.
|
|
avahi
|
|
# Arch tools & infrastructure
|
|
pacman-contrib # paccache, checkupdates, pacsearch, and others
|
|
reflector # Weekly mirrorlist updates
|
|
kernel-modules-hook # Keep kernel modules on kernel updates
|
|
pkgfile
|
|
# Build packages
|
|
base-devel
|
|
namcap
|
|
aurpublish # Publish AUR packages from Git subtrees
|
|
# Dotfiles manager
|
|
chezmoi
|
|
# Terminal, shell & tools
|
|
man-db
|
|
man-pages
|
|
bash-completion
|
|
code
|
|
neovim
|
|
exa # Better ls (with git support)
|
|
nnn # Command line file manager (also a good pager for aurutils)
|
|
rsync
|
|
curl
|
|
p7zip
|
|
zip
|
|
# Document processing and rendering
|
|
pandoc
|
|
mdcat
|
|
asciidoctor
|
|
zathura # Lightweight document viewer
|
|
# Spellchecking
|
|
hunspell
|
|
hunspell-de
|
|
hunspell-en_gb
|
|
hunspell-en_us
|
|
# Git and related tools
|
|
git
|
|
git-filter-repo
|
|
tea # CLI for gitea servers
|
|
tig # Curses git interfaces
|
|
# Bash tools
|
|
shellcheck
|
|
shfmt
|
|
# Other development tools
|
|
jq # Process JSON on command line
|
|
ansible-core
|
|
ansible
|
|
ansible-lint
|
|
# Desktop tools
|
|
wl-clipboard
|
|
dconf-editor
|
|
# Desktop services
|
|
xdg-user-dirs
|
|
xdg-utils
|
|
xdg-desktop-portal
|
|
pcsclite # Smartcard daemon, for e-ID
|
|
libfido2
|
|
cups
|
|
bluez
|
|
sane
|
|
pipewire-pulse # Pipewire-based pulse-audio, replaces pulseaudio
|
|
wireplumber # Recommended pipewire session & policy manager
|
|
playerctl
|
|
qt5-wayland # neccessary for nextcloud-client
|
|
firefox # Browser
|
|
firefox-i18n-de
|
|
firefox-dark-reader
|
|
firefox-ublock-origin
|
|
vlc # Video player
|
|
pipewire-jack # required by vlc
|
|
inkscape # Vector graphics
|
|
gimp # Pixel graphics
|
|
darktable
|
|
libreoffice-fresh
|
|
libreoffice-fresh-de
|
|
lollypop # Music player
|
|
#xournalpp # Handwriting tool
|
|
#signal-desktop # Secure mobile messenger
|
|
# Fonts & themes
|
|
qgnomeplatform-qt5
|
|
# Fallback font with huge coverage and colored emojis
|
|
noto-fonts
|
|
noto-fonts-extra
|
|
noto-fonts-cjk
|
|
noto-fonts-emoji
|
|
# Microsoft compatibility fonts
|
|
ttf-liberation
|
|
ttf-caladea
|
|
ttf-carlito
|
|
ttf-cascadia-code
|
|
# Gnome
|
|
gdm
|
|
gnome-characters
|
|
gnome-keyring
|
|
gnome-screenshot
|
|
gnome-maps
|
|
gnome-clocks
|
|
gnome-weather
|
|
gnome-calendar
|
|
gnome-terminal
|
|
gnome-shell
|
|
gnome-shell-extensions
|
|
gnome-shell-extension-appindicator
|
|
gnome-remote-desktop
|
|
gnome-system-monitor
|
|
gnome-control-center
|
|
gnome-tweaks
|
|
gnome-calculator
|
|
gnome-backgrounds
|
|
gnome-themes-extra # For adwaita-dark
|
|
xdg-desktop-portal-gnome # Desktop portals
|
|
xdg-user-dirs-gtk
|
|
evolution
|
|
file-roller
|
|
yelp # Online help system
|
|
nautilus
|
|
python-nautilus
|
|
gvfs-afc
|
|
gvfs-goa
|
|
gvfs-gphoto2
|
|
gvfs-mtp
|
|
gvfs-nfs
|
|
gvfs-smb
|
|
sushi # Previewer for nautilus
|
|
evince # Document viewer
|
|
eog # Image viewer
|
|
simple-scan
|
|
seahorse # Credential manager
|
|
baobab # Disk space analyser
|
|
# Multimedia for gnome
|
|
gst-plugins-good
|
|
gst-plugins-bad
|
|
gst-plugins-ugly
|
|
bitwarden # Password manager
|
|
yubikey-touch-detector
|
|
nextcloud-client
|
|
element-desktop # Matrix client
|
|
tailscale
|
|
flatpak
|
|
)
|
|
|
|
optdeps=(
|
|
# pipewire
|
|
pipewire-pulse wireplumber
|
|
# linux: wireless frequency policies (provided as crda)
|
|
wireless-regdb
|
|
# pipewire: zeroconf support
|
|
pipewire-zeroconf
|
|
# poppler: data files
|
|
poppler-data
|
|
# dracut:
|
|
binutils # --uefi
|
|
elfutils # stripping
|
|
sbsigntools # efi signing
|
|
tpm2-tools # tpm2-tss
|
|
# zathura: PDF support
|
|
zathura-pdf-mupdf
|
|
# libva: intel drivers
|
|
intel-media-driver
|
|
# gnome-shell-extension-appindicator: GTK3 apps
|
|
libappindicator-gtk3
|
|
# aurutils: chroot support
|
|
devtools
|
|
# zim: spell checking
|
|
gtkspell3
|
|
# inkscape: optimized SVGs
|
|
scour
|
|
# gnome-shell: Screen recording
|
|
gst-plugin-pipewire
|
|
# gnome-control-center: Applications
|
|
malcontent
|
|
# nextcloud-client: integration with Nautilus
|
|
python-nautilus
|
|
)
|
|
|
|
pacman -Syu --noconfirm --needed "${packages[@]}"
|
|
pacman -S --noconfirm --needed --asdeps "${optdeps[@]}"
|
|
pacman -D --noconfirm --asdeps "${optdeps[@]}"
|
|
|
|
# Currently dracut is missing an optdepends on tpm2-tools, see
|
|
# https://bugs.archlinux.org/task/73229
|
|
pacman -D --asexplicit tpm2-tools
|
|
|
|
services=(
|
|
# Core system services
|
|
systemd-boot-update.service # Update boot loader automatically
|
|
systemd-homed.service # homed for user management and home areas
|
|
systemd-oomd.service # Userspace OOM killer
|
|
systemd-timesyncd.service # Time sync
|
|
systemd-resolved.service # DNS resolution
|
|
# Other system services
|
|
firewalld.service # Firewall
|
|
linux-modules-cleanup.service # kernel-modules-hook
|
|
# Timers
|
|
fstrim.timer # Periodically trim file systems…
|
|
"btrfs-scrub@$(systemd-escape -p /).timer" # scrub root filesystem…
|
|
paccache.timer # clean pacman cache…
|
|
pkgfile-update.timer # update pkgfile list…
|
|
fwupd-refresh.timer # check for firmware updates…
|
|
reflector.timer # and update the mirrorlist.
|
|
# Desktop services
|
|
gdm.service # Desktop manager
|
|
power-profiles-daemon.service # Power profile management
|
|
NetworkManager.service # Network manager for desktops
|
|
avahi-daemon.service # Local network service discovery (for WLAN printers)
|
|
cups.service # Printing
|
|
bluetooth.service # Bluetooth
|
|
pcscd.socket # Smartcards, mostly eID
|
|
tailscaled.service
|
|
)
|
|
|
|
if [[ -n "${SUDO_USER:-}" ]]; then
|
|
# Scrub home directory of my user account
|
|
services+=("btrfs-scrub@$(systemd-escape -p "/home/${SUDO_USER}").timer")
|
|
fi
|
|
|
|
systemctl enable "${services[@]}"
|
|
|
|
# See /usr/share/factory/etc/nsswitch.conf for the Arch Linux factory defaults.
|
|
# We add mdns hostnames (from Avahi) and libvirtd names, and also shuffle things around
|
|
# to follow the recommendations in nss-resolve(8) which Arch Linux deliberately doesn't
|
|
# do by default, see e.g. https://bugs.archlinux.org/task/57852
|
|
NSS_HOSTS=(
|
|
# Resolves containers managed by systemd-machined
|
|
mymachines
|
|
# Resolve everything else with systemd-resolved and bail out if resolved
|
|
# doesn't find hostname. Everything after this stanza is just fallback in
|
|
# case resolved is down
|
|
resolve '[!UNAVAIL=return]'
|
|
# Resolve hosts from /etc/hosts (systemd-resolved handles /etc/hosts as well
|
|
# so this comes after resolve)
|
|
files
|
|
# Resolves gethostname(), i.e. /etc/hostname
|
|
myhostname
|
|
# Resolves from DNS
|
|
dns
|
|
)
|
|
sed -i '/^hosts: /s/^hosts: .*/'"hosts: ${NSS_HOSTS[*]}/" /etc/nsswitch.conf
|
|
|
|
# Bootloader and initrd configuration
|
|
install -pm644 "$DIR/etc/dracut.conf" /etc/dracut.conf.d/50-custom.conf
|
|
install -pm644 "$DIR/etc/loader.conf" /efi/loader/loader.conf
|
|
if [[ ! -f /usr/share/secureboot/keys/db/db.pem ]]; then
|
|
sbctl create-keys
|
|
sbctl enroll-keys
|
|
fi
|
|
if [[ -f /usr/share/secureboot/keys/db/db.key ]] && [[ -f /usr/share/secureboot/keys/db/db.pem ]]; then
|
|
install -pm644 "$DIR/etc/dracut-sbctl.conf" /etc/dracut.conf.d/90-sbctl-signing.conf
|
|
else
|
|
rm -f /etc/dracut.conf.d/90-sbctl-signing.conf
|
|
fi
|
|
|
|
# System configuration
|
|
install -pm644 "$DIR/etc/faillock.conf" /etc/security/faillock.conf
|
|
install -pm644 "$DIR/etc/modprobe.conf" /etc/modprobe.d/modprobe.conf
|
|
|
|
# sudo configuration
|
|
install -dm750 /etc/sudoers.d/
|
|
install -pm600 -t/etc/sudoers.d "$DIR"/etc/sudoers.d/*
|
|
|
|
# Systemd configuration
|
|
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
|
|
install -Dpm644 "$DIR/etc/systemd/system.conf" /etc/systemd/system.conf.d/50-custom.conf
|
|
install -Dpm644 "$DIR/etc/systemd/timesyncd.conf" /etc/systemd/timesyncd.conf.d/50-custom.conf
|
|
install -Dpm644 "$DIR/etc/systemd/resolved.conf" /etc/systemd/resolved.conf.d/50-custom.conf
|
|
install -Dpm644 "$DIR/etc/systemd/zram-generator.conf" /etc/systemd/zram-generator.conf
|
|
install -Dpm644 "$DIR/etc/systemd/oomd.conf" /etc/systemd/oomd.conf.d/oomd.conf
|
|
install -Dpm644 "$DIR/etc/systemd/root-slice-oomd.conf" /etc/systemd/system/-.slice.d/50-oomd.conf
|
|
install -Dpm644 "$DIR/etc/systemd/user-service-oomd.conf" /etc/systemd/system/user@.service.d/50-oomd.conf
|
|
|
|
# Services configuration
|
|
install -Dpm644 "$DIR/etc/networkmanager-mdns.conf" /etc/NetworkManager/conf.d/50-mdns.conf
|
|
install -Dpm644 "$DIR/etc/iwd/main.conf" /etc/iwd/main.conf
|
|
install -Dpm644 "$DIR/etc/reflector.conf" /etc/xdg/reflector/reflector.conf
|
|
install -Dpm644 "$DIR/etc/bluetooth.conf" /etc/bluetooth/main.conf
|
|
install -Dpm644 "$DIR/etc/snapper-root.conf" /etc/snapper/configs/root
|
|
install -Dpm644 "$DIR/etc/firefox/policies.json" /etc/firefox/policies/policies.json
|
|
|
|
# Global font configuration
|
|
for file in 10-hinting-slight 10-sub-pixel-rgb 11-lcdfilter-default; do
|
|
ln -sf /usr/share/fontconfig/conf.avail/$file.conf /etc/fonts/conf.d/$file.conf
|
|
done
|
|
|
|
# Locale settings
|
|
localectl set-locale de_DE.UTF-8
|
|
# --no-convert stops localectl from trying to apply the text console layout to
|
|
# X11/Wayland and vice versa
|
|
localectl set-keymap --no-convert de
|
|
localectl set-x11-keymap --no-convert de pc105
|
|
|
|
# GDM dconf profile, for global GDM configuration, see
|
|
# https://help.gnome.org/admin/system-admin-guide/stable/login-banner.html.en
|
|
install -Dpm644 "$DIR/etc/gdm-profile" /etc/dconf/profile/gdm
|
|
|
|
# Start firewalld and configure it
|
|
systemctl start firewalld.service
|
|
firewall-cmd --permanent --zone=home \
|
|
--add-service=upnp-client \
|
|
--add-service=rdp \
|
|
--add-service=ssh \
|
|
--add-service gsconnect
|
|
# Don't allow incoming SSH connections on public networks (this is a weird default imho)
|
|
firewall-cmd --permanent --zone=public --remove-service=ssh
|
|
firewall-cmd --reload
|
|
|
|
# Setup secure boot
|
|
if command -v sbctl > /dev/null && [[ -f /usr/share/secureboot/keys/db/db.key ]]; then
|
|
# Generate signed bootloader image
|
|
if ! sbctl list-files | grep -q /usr/lib/systemd/boot/efi/systemd-bootx64.efi; then
|
|
sbctl sign -s -o /usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed /usr/lib/systemd/boot/efi/systemd-bootx64.efi
|
|
bootctl update --graceful
|
|
fi
|
|
|
|
# Generate signed firmware updater
|
|
if ! sbctl list-files | grep -q /usr/lib/fwupd/efi/fwupdx64.efi; then
|
|
sbctl sign -s -o /usr/lib/fwupd/efi/fwupdx64.efi.signed /usr/lib/fwupd/efi/fwupdx64.efi
|
|
fi
|
|
|
|
sbctl sign-all
|
|
sbctl verify # Safety check
|
|
fi
|
|
|
|
# Install or update, and then configure the bootloader.
|
|
# Do this AFTER signing the boot loader with sbctl, see above, to make sure we
|
|
# install the signed loader.
|
|
if ! [[ -e /efi/EFI/BOOT/BOOTX64.EFI ]]; then
|
|
bootctl install
|
|
else
|
|
bootctl update --graceful
|
|
fi
|
|
|
|
# Allow myself to build AUR packages
|
|
if [[ -n "${SUDO_USER:-}" && "$(stat -c '%U' /var/cache/pacman/aur)" != "$SUDO_USER" ]]; then
|
|
chown -R "$SUDO_USER:$SUDO_USER" /var/cache/pacman/aur
|
|
fi
|
|
|
|
# Bootstrap aurutils
|
|
if [[ -n "${SUDO_USER:-}" ]] && ! command -v aur &>/dev/null; then
|
|
sudo -u "$SUDO_USER" bash <<'EOF'
|
|
set -xeuo pipefail
|
|
BDIR="$(mktemp -d --tmpdir aurutils.XXXXXXXX)"
|
|
echo "Building in $BDIR"
|
|
cd "$BDIR"
|
|
git clone --depth=1 "https://aur.archlinux.org/aurutils.git"
|
|
cd aurutils
|
|
makepkg --noconfirm --nocheck -rsi
|
|
EOF
|
|
fi
|
|
|
|
# Configure aurutils
|
|
if [[ ! -e "/etc/aurutils/pacman-aur.conf" ]]; then
|
|
install -Dpm644 /usr/share/devtools/pacman-extra.conf "/etc/aurutils/pacman-aur.conf"
|
|
cat <<EOF >>"/etc/aurutils/pacman-aur.conf"
|
|
# aurutils repo
|
|
[aur]
|
|
SigLevel = Optional TrustAll
|
|
Server = file:///var/cache/pacman/aur
|
|
EOF
|
|
fi
|
|
|
|
aur chroot --create
|
|
|
|
aur_packages=(
|
|
# AUR helper
|
|
aurutils
|
|
networkmanager-iwd
|
|
# iwd GUI
|
|
iwgtk
|
|
# Login settings
|
|
gdm-settings
|
|
# Gnome extensions
|
|
gnome-shell-extension-arch-update # Indicator for system update
|
|
gnome-shell-extension-gsconnect # Connect phone and desktop system
|
|
gnome-shell-extension-dash-to-dock # Move the dash out of the overview transforming it in a dock
|
|
gnome-shell-extension-clipboard-history # Searchable history panel of clipboard
|
|
gnome-shell-extension-bluetooth-quick-connect
|
|
gnome-shell-extension-quick-settings-tweaks-git
|
|
gnome-shell-extension-nightthemeswitcher
|
|
gnome-shell-extension-tiling-assistant
|
|
gnome-shell-extension-alphabetical-grid-extension-git # Restore the alphabetical ordering of the app grid
|
|
# Firefox extensions
|
|
firefox-extension-bitwarden
|
|
newsflash
|
|
# Dracut hook to build kernel images for systemd boot
|
|
dracut-hook-uefi
|
|
# Additional fonts
|
|
otf-vollkorn # My favorite serif font for documents
|
|
ttf-fira-go # A nice font for presentations
|
|
# Additional tools
|
|
git-gone
|
|
dnscontrol-bin
|
|
qtscrcpy # Android screen display
|
|
)
|
|
|
|
aur_optdeps=(
|
|
# plymouth: truetype fonts
|
|
ttf-dejavu cantarell-fonts
|
|
)
|
|
|
|
if [[ -n "${SUDO_USER:-}" ]]; then
|
|
# Build AUR packages and install them
|
|
if [[ ${#aur_packages} -gt 0 ]]; then
|
|
sudo -u "$SUDO_USER" --preserve-env="${PRESERVE_ENV}" \
|
|
nice aur sync -daur -cRT "${aur_packages[@]}" "${aur_optdeps[@]}"
|
|
pacman --needed -Syu "${aur_packages[@]}"
|
|
fi
|
|
if [[ ${#aur_optdeps[@]} -gt 0 ]]; then
|
|
pacman --needed -S --asdeps "${aur_optdeps[@]}"
|
|
pacman -D --asdeps "${aur_optdeps[@]}"
|
|
fi
|
|
|
|
remove_from_repo=()
|
|
if [[ ${#remove_from_repo[@]} -gt 0 ]]; then
|
|
for pkg in "${remove_from_repo[@]}"; do
|
|
rm -f "/var/cache/pacman/aur/${pkg}-"*.pkg.tar.*
|
|
done
|
|
sudo -u "$SUDO_USER" repo-remove /var/cache/pacman/aur/aur.db.tar.zst "${remove_from_repo[@]}" || true
|
|
fi
|
|
fi
|
|
|
|
# Upgrade flatpak packages
|
|
echo Updating flatpak packages...
|
|
flatpak update --noninteractive --assumeyes
|
|
|
|
# Set plymouth theme
|
|
if command -v plymouth-set-default-theme > /dev/null; then
|
|
plymouth-set-default-theme bgrt
|
|
fi
|