Arch Linux re-installation journal for my Z16 AMD ThinkPad
I took the opportunity presented by having to bring my Lenovo Z16 AMD Gen1 ThinkPad to Advice in Surat Thani for repair due to a faulty motherboard to document the re-installation process on my blog for friends and other GNOME / Arch users. In fact, I maintain a similar changelog for all of my/our Arch Linux computers and try to keep their configurations as consistent and reproducible as possible over time.
The setup described in this article is my secondary computer. My primary system, the custom Ryzen 9 3900X studio PC (see Gear), is nearly identical, though. The main difference is that it also has a large collection of audio plugins installed, which I have, so far, chosen to leave off my laptop this time. 🫣😜
Some parts of this guide will be redacted, some are somewhat incomplete (e.g. restored XY from backup) while others may appear in an order or fashion that might not always be easy to comprehend/follow. Be that as it may, I am happy to answer questions and am already looking forward to hearing what you think of my approach to configuring my system, and learning from you how I might do a better job at it in the future. 🤓️
Installed base system
- Installed Arch Linux with
linuxandlinux-ltskernels, as well asplymouth - Set static hostname to
<HOSTNAME> - Enabled SSH daemon in the GNOME Settings app
- Added
GNOME_SHELL_SLOWDOWN_FACTOR=0.3to/etc/environmentto make GNOME Shell animations more snappy:
sudo tee -a /etc/environment > /dev/null <<'EOF'
# Make GNOME Shell animations more snappy
GNOME_SHELL_SLOWDOWN_FACTOR=0.3
EOF
- Extended /etc/hosts with
sudo tee -a /etc/hosts > /dev/null <<'EOF'
# Computers
<HOST_1_IP> <HOSTNAME>
<HOST_2_IP> <HOSTNAME>
<HOST_3_IP> <HOSTNAME>
<HOST_4_IP> <HOSTNAME>
# NAS
<NAS_IP> <NAS_HOST>
# Raspberry Pi
<PI_1_IP> <HOSTNAME>
<PI_2_IP> <HOSTNAME>
EOF
Configured avahi/systemd-resolved
- Ran
sudo nano /etc/systemd/resolved.confand changed:
MulticastDNS=no
LLMNR=no
- Set unique static hostname by running
sudo hostnamectl hostname <HOSTNAME> - Finished avahi/systemd-resolved configuration by running
sudo systemctl restart systemd-resolved && sudo systemctl restart avahi-daemon - Verified avahi/systemd-resolved configuration by running
sudo ss -ulpn 'sport = 5353'(only avahi-daemon owns 5353),resolvectl status | grep -i mdns(mDNS not in Current Scopes), andjournalctl -u avahi-daemon -f(no host name conflicts)
Installed base packages
- Installed pacman packages with
sudo pacman -S adw-gtk-theme base-devel bind btop cava cmake cpupower dosfstools fastfetch ffmpegthumbnailer flatpak git gnome-firmware gnome-sound-recorder gst-libav gst-plugins-ugly gulp hunspell-de hyphen-de hyphen-en inxi iwd less libgda6 logrotate mediainfo mpc mpd nano-syntax-highlighting networkmanager-openvpn nmap nodejs noto-fonts-cjk npm nvm openvpn pacman-contrib patchelf php php-gd radeontop realtime-privileges rsync seahorse showmethekey speedtest-cli tree usbutils whois wireless_tools wol xcb-imdkit xcb-util-wm xorg-server xorg-xinit yarn zenity zip zsh - Installed yay with
git clone https://aur.archlinux.org/yay.git && cd yay && makepkg -si && yay --version && cd../ && rm -rf yay, and installed yay packages withsudo yay -S blackbox-terminal linkchecker symfony-cli unimatrix-git - Installed Flatpak packages with
flatpak install app.drey.KeyRack app.zen_browser.zen art.fatdawlf.Piccolo be.alexandervanhee.gradia ca.desrt.dconf-editor com.belmoussaoui.Decoder com.github.huluti.Curtail com.github.johnfactotum.Foliate com.github.tchx84.Flatseal com.jeffser.Alpaca com.mattjakeman.ExtensionManager com.obsproject.Studio com.rafaelmardojai.Blanket com.rafaelmardojai.SharePreview com.rafaelmardojai.WebfontKitGenerator com.valvesoftware.Steam com.vixalien.sticky de.haeckerfelix.Fragments de.haeckerfelix.Shortwave de.wwwtech.gitte dev.geopjr.Tuba hu.irl.cameractrls io.github.dimtpap.coppwr io.github.dp0sk.Crosspipe io.github.fabrialberio.pinapp io.github.flattool.Ignition io.github.flattool.Warehouse io.github.gaheldev.Millisecond io.github.htkhiem.Euphonica io.github.idevecore.Valuta io.github.jorchube.monitorets io.github.kolunmi.Bazaar io.github.mrvladus.List io.github.nate_xyz.Chromatic io.github.nozwock.Packet io.github.quodlibet.QuodLibet io.github.sitraorg.sitra io.github.sigmasd.stimulator io.github.sitraorg.sitra io.github.v81d.Wattage io.gitlab.adhami3310.Impression io.gitlab.elescoute.password io.gitlab.liferooter.TextPieces io.gitlab.news_flash.NewsFlash io.gitlab.theevilskeleton.Upscaler it.mijorus.gearlever me.dusansimic.DynamicWallpaper me.fouquet.Stencil net.codelogistics.webapps net.nokyan.Resources net.sonobus.SonoBus no.bragefuglseth.Keypunch org.ardour.Ardour org.audacityteam.Audacity org.blender.Blender org.darktable.Darktable org.filezillaproject.Filezilla org.gabmus.swatch org.gimp.GIMP org.gnome.Builder org.gnome.DejaDup org.gnome.Fractal org.gnome.Papers org.gnome.Podcasts org.gnome.Showtime org.gnome.World.PikaBackup org.gnome.design.Lorem org.gnome.gitlab.somas.Apostrophe org.gnome.meld org.gtk.Gtk3theme.adw-gtk3 org.gtk.Gtk3theme.adw-gtk3-dark org.inkscape.Inkscape org.libreoffice.LibreOffice org.mixxx.Mixxx org.mozilla.firefox org.mozilla.thunderbird org.nickvision.tagger org.nickvision.tubeconverter org.pipewire.Helvum org.pitivi.Pitivi org.signal.Signal org.soundconverter.SoundConverter page.codeberg.censor.Censor page.tesk.Refine re.sonny.OhMySVG - Ran
flatpak config --set languages 'de;en'andflatpak config languages --set "en;de"so Flatpak apps get the right dictionaries - Made Flatpak theme aware with
sudo flatpak override --filesystem=xdg-data/themes && gsettings set org.gnome.desktop.interface gtk-theme 'adw-gtk3' && gsettings set org.gnome.desktop.interface color-scheme 'default' && gsettings set org.gnome.desktop.interface gtk-theme 'adw-gtk3-dark' && gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark' - Installed Lightworks as the official Flatpak and authenticated it
- Installed Bitwig Studio as the official Flatpak and authenticated it
- Installed Studio Pro 8 as the official Flatpak and authenticated it
Configured personal files, dotfiles, and wallpaper
- Cloned
Git repository - Symlinked Dynamic Wallpapers from the
Git repository to the user paths with
ln -s ~/Sites/<PERSONAL_GIT_REPOSITORY>/dynamic-wallpapers/circles-16-9-amadeus-paulussen.xml \
~/.local/share/gnome-background-properties/circles-16-9-amadeus-paulussen.xml
ln -s ~/Sites/<PERSONAL_GIT_REPOSITORY>/dynamic-wallpapers/circles-16-10-amadeus-paulussen.xml \
~/.local/share/gnome-background-properties/circles-16-10-amadeus-paulussen.xml
- Symlinked nautilus scripts, Templates, fonts, and MPD playlists from
to respective user paths with
ln -s ~/Sites/<PERSONAL_GIT_REPOSITORY>/scripts/nautilus ~/.local/share/nautilus/scripts
ln -s ~/Sites/<PERSONAL_GIT_REPOSITORY>/templates ~/Templates
ln -s ~/Sites/<PERSONAL_GIT_REPOSITORY>/fonts ~/.fonts
ln -s ~/Sites/<PERSONAL_GIT_REPOSITORY>/avatar ~/Pictures/avatar
ln -s ~/Sites/<PERSONAL_GIT_REPOSITORY>/playlists ~/.local/share/mpd/playlists
Configured CLI
- Installed oh-my-zsh with the official installation script
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" - Added personal settings to ~/.zshrc with
cat >> ~/.zshrc <<'EOF'
# PATH & directories
export PATH="$PATH:~/Sites/<PERSONAL_GIT_REPOSITORY>/scripts/"
export CDPATH="~/Sites/"
# Default applications
export EDITOR="nano"
# Aliases
alias gnome-builder="flatpak run org.gnome.Builder"
# Startup
logo-fastfetch.sh
EOF
- Created custom nanorc configuration with
cat > ~/.nanorc <<'EOF'
include "/usr/share/nano/*.nanorc"
set tabsize 4
set softwrap
set tabstospaces
set whitespace "·→"
EOF
- Configured Blackbox Terminal with
dconf load /com/raggesilver/BlackBox/ <<'EOF'
[/]
floating-controls=true
floating-controls-hover-area=uint32 20
font='Adwaita Mono 11'
headerbar-drag-area=false
remember-window-size=true
show-headerbar=false
terminal-padding=(uint32 10, uint32 10, uint32 10, uint32 10)
was-maximized=false
window-height=uint32 1128
window-width=uint32 930
EOF
- Set Black Box terminal to launch upon login in the Ignition app
- Enabled asterisks for password input with
sudo install -Dm440 /dev/stdin /etc/sudoers.d/pwfeedback <<'EOF'
Defaults pwfeedback
EOF
sudo visudo -c
- Configured ufw with
sudo systemctl enable ufw.service
sudo ufw enable
sudo ufw logging off
# SSH for LAN only
sudo ufw allow from <LAN_SUBNET> to any port 22 proto tcp
# Network printer / IPP
sudo ufw allow from <LAN_SUBNET> to any port 631 proto tcp
# mDNS / Bonjour
sudo ufw allow in proto udp to 224.0.0.251 port 5353
sudo ufw allow out proto udp from any to 224.0.0.251 port 5353
sudo ufw reload
sudo chmod 600 /etc/ufw/*.rules
Configured SMB mount and automount setup
- Created basic SMB mount directories for
SMB shares with sudo mkdir -p /mnt/smb/<NAS_NAME>/{amadeus,backup,shared} && sudo chown -R amadeus:amadeus /mnt/smb - Setup
~/.smbcredentials
sudo tee ~/.smbcredentials > /dev/null <<'EOF'
username=*****
password=*****
EOF
- Added mount systemd service for backup SMB share with
sudo tee /etc/systemd/system/mnt-smb-<NAS_NAME>-backup.mount > /dev/null <<'EOF'
[Unit]
Description=Mount SMB <NAS_NAME>/backup
After=network-online.target
Wants=network-online.target
[Mount]
What=//<NAS_HOST>/backup
Where=/mnt/smb/<NAS_NAME>/backup
Type=cifs
Options=credentials=~/.smbcredentials,vers=3.0,uid=amadeus,gid=amadeus,iocharset=utf8,actimeo=2,nofail,noserverino,cache=none,_netdev
TimeoutSec=30
EOF
- Added automount systemd service for backup SMB share with
sudo tee /etc/systemd/system/mnt-smb-<NAS_NAME>-backup.automount > /dev/null <<'EOF'
[Unit]
Description=Automount SMB <NAS_NAME>/backup
[Automount]
Where=/mnt/smb/<NAS_NAME>/backup
TimeoutIdleSec=600
[Install]
WantedBy=multi-user.target
EOF
- Added mount systemd service for amadeus SMB share with
sudo tee /etc/systemd/system/mnt-smb-<NAS_NAME>-amadeus.mount > /dev/null <<'EOF'
[Unit]
Description=Mount SMB <NAS_NAME>/amadeus
After=network-online.target
Wants=network-online.target
[Mount]
What=//<NAS_HOST>/amadeus
Where=/mnt/smb/<NAS_NAME>/amadeus
Type=cifs
Options=credentials=~/.smbcredentials,vers=3.0,uid=amadeus,gid=amadeus,iocharset=utf8,actimeo=2,nofail,noserverino,cache=none,_netdev
TimeoutSec=30
EOF
- Added automount systemd service for amadeus SMB share with
sudo tee /etc/systemd/system/mnt-smb-<NAS_NAME>-amadeus.automount > /dev/null <<'EOF'
[Unit]
Description=Automount SMB <NAS_NAME>/amadeus
[Automount]
Where=/mnt/smb/<NAS_NAME>/amadeus
TimeoutIdleSec=600
[Install]
WantedBy=multi-user.target
EOF
- Added mount systemd service for shared SMB share with
sudo tee /etc/systemd/system/mnt-smb-<NAS_NAME>-shared.mount > /dev/null <<'EOF'
[Unit]
Description=Mount SMB <NAS_NAME>/shared
After=network-online.target
Wants=network-online.target
[Mount]
What=//<NAS_HOST>/shared
Where=/mnt/smb/<NAS_NAME>/shared
Type=cifs
Options=credentials=~/.smbcredentials,vers=3.0,uid=amadeus,gid=amadeus,iocharset=utf8,actimeo=2,nofail,noserverino,cache=none,_netdev
TimeoutSec=30
EOF
- Added automount systemd service for shared SMB share with
sudo tee /etc/systemd/system/mnt-smb-<NAS_NAME>-shared.automount > /dev/null <<'EOF'
[Unit]
Description=Automount SMB <NAS_NAME>/shared
[Automount]
Where=/mnt/smb/<NAS_NAME>/shared
TimeoutIdleSec=600
[Install]
WantedBy=multi-user.target
EOF
- Finished the automount setup with
sudo systemctl daemon-reload && sudo systemctl enable --now mnt-smb-<NAS_NAME>-backup.automount mnt-smb-<NAS_NAME>-amadeus.automount mnt-smb-<NAS_NAME>-shared.automount - Verified the automount setup with
systemctl status 'mnt-smb-<NAS_NAME>-*.automount'and triggers like:
ls /mnt/smb/<NAS_NAME>/*
systemctl status mnt-smb-<NAS_NAME>-*.mount
- Added a network dispatcher to the SMB mount/automount setup
sudo tee /etc/NetworkManager/dispatcher.d/50-smb-<NAS_NAME> > /dev/null <<'EOF'
#!/bin/bash
ACTION="$2"
AUTOMOUNTS="mnt-smb-<NAS_NAME>-backup.automount mnt-smb-<NAS_NAME>-amadeus.automount mnt-smb-<NAS_NAME>-shared.automount"
MOUNTS="mnt-smb-<NAS_NAME>-backup.mount mnt-smb-<NAS_NAME>-amadeus.mount mnt-smb-<NAS_NAME>-shared.mount"
probe_nas() {
for i in 1 2 3 4 5; do
if timeout 2 bash -c '</dev/tcp/<NAS_HOST>/445' 2>/dev/null; then
return 0
fi
sleep 2
done
return 1
}
case "$ACTION" in
up|connectivity-change)
if probe_nas; then
systemctl start $AUTOMOUNTS
fi
# no "else stop" — a failed probe means "don't start yet",
# not "tear down what's already running"
;;
down)
systemctl stop $AUTOMOUNTS $MOUNTS 2>/dev/null
;;
esac
EOF
- Ran
sudo chmod 755 /etc/NetworkManager/dispatcher.d/50-smb-<NAS_NAME> && sudo chown root:root /etc/NetworkManager/dispatcher.d/50-smb-<NAS_NAME>
Configured pro audio
- Added my user to the realtime, and audio groups with
sudo usermod -aG audio,realtime amadeus - Disabled SMT with
echo forceoff | sudo tee /sys/devices/system/cpu/smt/control - Added threadirqs to reduce IRQ-induced audio latency jitter with
sudo sed -i 's/$/ threadirqs/' /etc/kernel/cmdlineandsudo mkinitcpio -P - Reloaded udev rules with
sudo udevadm control --reload-rules
sudo udevadm trigger
- Set swappiness with
sudo tee /etc/sysctl.d/99-swappiness.conf >/dev/null <<'EOF'
vm.swappiness = 10
EOF
- Reloaded system-wide kernel parameters with
sudo sysctl --system
Setup accounts, credentials, and peripherals
- Setup Bitwarden
- Setup public key authentication with GitLab and Cyon
- Setup Online Accounts in GNOME Settings
- Calendars
- Contacts
- Added printer with
sudo lpadmin -p HL-L2460DN -E -v ipp://<PRINTER_IP>/ipp/print -m everywhereand made it the default printer withlpoptions -d HL-L2460DN