Reinstalling Arch Linux

I have been using Arch Linux on my "mobile workstation" (that is, the ASUS Zephyrus M16 2021 mentioned on my GitHub readme page) for a while, and switched to Ubuntu in order to work on ROS2 projects half a year ago. However, I still miss the ease of SOTA configuration back in Arch. Some days ago, I tried to boot into my old Arch installation but found the GPG keyring had expired during the gap. Although this can be fixed by some manual operations, I eventually decided to reinstall the system. This will also give me a chance to try out some new ideas on the system.

niri screenshot

Installation

I basically just followed the steps on nakanomikuorg/arch-guide. This guide is in Chinese and not very diverged from the official installation guide.

Partitioning

The guide suggests using Btrfs subvolumes to separate and , which is a good idea. Although I don't do snapshots and rollbacks as the guide does, the advantage of making subvolumes is at least obvious in this reinstallation. The old subvolume, named , can be simply -ed to a new name (actually it can be left as is, but I want to make it clear that it's the old one), and so the old subvolume. In addition to these two, I also created subvolumes for and , for easier management of package cache and logs. If Nix is to be installed in the future, I will also create a subvolume for .

One thing I think the guide is wrong with is mounting the ESP to . Arch Linux stores all kernel images and initramfs in . If one has multiple distributions installed, they will definitely conflict with each other. I mounted the ESP to instead. And frankly speaking, with rEFInd pre-installed, the ESP is not even necessary to be mounted, but I did it for using Unified Kernel Images (UKI).

I also omitted the swap partition. I have 40GB (8GB soldered, 32GB SODIMM) of RAM, and I don't think I will ever use a swap. If I do, I will use a swap file instead.

mount -o subvol=/@,compress=zstd /dev/nvmexn1pn /mnt
mount -o subvol=/@home,compress=zstd --mkdir /dev/nvmexn1pn /mnt/home
mount --mkdir /dev/nvmexn1pn /mnt/efi

Bootloader

As mentioned above, I use rEFInd as my bootloader. I can just copy my old to the new installation, and it will work. But I wanted to try out the UKI, so I followed the instructions on the ArchWiki page.

The UKI is a kernel image that also is an EFI executable. It packs the kernel image and kernel modules into a single file, and can be booted directly by the UEFI firmware. As a result, things like secure boot and TPM-based integrity verification can be easily implemented.

In the case that suitable kernel parameters are presenting, switching to UKI is as simple as removing some in , since mkinitcpio will pick up the parameters from the current boot if is not present. For long-term use, creating is still necessary. After UKI is generated, either by or by reinstalling some packages like , new options will be added to rEFInd's boot menu, and one can even set the default boot option in BIOS to be the UKI.

Post-installation

I use as my AUR helper, but it is not in the official repository. I added the repository to the pacman configuration, but the official CN wiki page did not mention (it is in the news feed, though) a recent change in the GPG trust chain that makes the package not installable. A workaround is to manually trust the key by executing .

Configuration

I have been using Home Manager (a Nix project) to manage my dotfiles, but I'm not very satisfied with it. I hated that I needed to wait for a minute for my configuration to land on the ground, while the program I configuring actually supported hot reloading. I'm looking for a new solution.

Shell

I ended up installing as my shell. The concept of is to encourage users to write functions. That's why they have a dedicated command to edit functions.

Window Manager

I tried out the new window manager. It's a tiling window manager written in Rust. Its concept is very unique: workspaces are infinite on the horizontal axis, and windows are arranged in columns. It is still in its early stages, but I think it's fun to play with.

can be used to find out the keycodes of the keys on the keyboard. I used it to find out the keycodes of the ROG keys on my laptop and configured them to launch the provided by asus-linux.org.

Keyboard Remapping

I used Karabiner Elements to remap the key to and when pressed alone and held, respectively. Turns out that wez/evremap (notice that this is the "Wez" in "WezTerm") is one of the best choices for this task on Linux. It's a daemon that listens to the and pops out a virtual device. In contrast to used in the last section, here we need to find out key codes under the libinput format, which can be done by .

Status Bar

Since there are no preconfigured bars with integration with yet, I went for , which I haven't had a chance to try out. It is themed with Sass, which Catppuccin happens to have support for, so I just grab the palette from there.

Handy Web Apps

The Telegram desktop client is a heavy Qt application, I don't want to install it for now. IME support on is not clear yet. Telegram Web is the web version of Telegram. My RIME is a web app that works as a RIME input method. I simply pinned them to the Firefox tab bar, along with the , which will be introduced in the next section.

System-wide Proxy

As long as I'm living in Mainland China, the importance of a system-wide proxy is not to be mentioned. To take a bite of the goose, I went for , which is a proxy tool that filters traffic using eBPF. When the policy is set to , will create an asymmetric NAT, that bypasses the proxy stack, making it faster than any other solutions using redirection or TUN. What's more, can handle proxy subscriptions too (only format is supported at the moment).

Just like , itself is a lightweight daemon that does not provide a GUI. Luckily the project officially provides an integration solution called . It's a unified daemon that also serves a web API and GUI. One doesn't need to install separately, as it's already included in , and both are provided in repository.

Since only supports subscriptions, a converter is often needed. Sub-Store has supported hosted deployments (in contrast to parasitizing in scripting support of some MitM proxy tools). One can deploy their own with the following :

version: "3.8"
services:
  sub-store:
    image: xream/sub-store:latest # This is the official image
    container_name: sub-store
    restart: always
    volumes:
      - data:/opt/app/data
    environment:
      - SUB_STORE_FRONTEND_BACKEND_PATH=/2cXaAxRGfddmGz2yx1wA # Change this

      # If you want to update the subscription regularly
      # - "SUB_STORE_CRON=55 23 * * *" # using crond
      # - "SUB_STORE_BACKEND_CRON=55 23 * * *" # using node-cron

      # If you have notification webhooks, like Bark
      # - "SUB_STORE_PUSH_SERVICE=https://api.day.app/XXXXXXXXXXXX/[推送标题]/[推送内容]?group=SubStore&autoCopy=1&isArchive=1&sound=shake&level=timeSensitive&icon=https%3A%2F%2Fraw.githubusercontent.com%2F58xinian%2Ficon%2Fmaster%2FSub-Store1.png"
    ports:
      - 127.0.0.1:3001:3001 # Only expose to localhost
    stdin_open: true
    tty: true
volumes:
  data:

Then you can open in your browser to manage your subscriptions. However, I found that the container will cause the powering off procedure to stall for a while, so I would like to host it elsewhere.

Written on 2024/03/02