The Problem
A lot of us forum people probably know of this scenario:
- User is unfamiliar with
.pacnewfiles - User follows distro instructions and merges
/etc/pacnew.conf.pacnewinto/etc/pacman.conf - But there’s a twist! The user merged the files incorrectly or just copied the pacnew file to the pacman configuration file without merging.
- Their system breaks because the garuda, multilib and chaotic-aur repos are no longer enabled.
Over the time, we’ve shipped tools like garuda-health that can automatically recover systems from such a state, but it’s not ideal.
The core problem comes down to this: Garuda Linux applies configuration changes on top of configuration files that Arch Linux ships. When a package is then updated, a .pacnew file is created without any of the custom Garuda Linux configuration changes.
The average user in many cases simply also does not have the knowledge about why certain config settings have been set by the Garuda Linux team/community and might therefore not know if any individual change should be merged or kept.
The Solution
The solution comes down to this: Intercept any new .pacnew files and apply Garuda Linux configurations to them automatically. Then, when merging, the user does not have to worry about preserving the Garuda Linux specific configs and instead only has to worry about their own configuration changes (which they will be much more familiar with and therefore less likely to make mistakes).
In addition, we are also able to detect when configuration files have remained unchanged by the user and automatically merge the pacnew file for them (but this will not take effect retroactively, the benefit of this will only be seen on new systems).
It’s a little more complicated than that, but that’s the basic gist.
Regex knows no limits
All this is implemented using a Python-based regex replacement system that allows for very dynamic and pretty bulletproof changes to the config files. Using a sqlite3 database, the agent is aware of changes that were previously made and will not apply those same changes again, preventing the agent from accidentally setting a setting that the user explicitly disabled earlier, for example.
Here is what the configuration files ingested by garuda-config-agent look like:
# Which file is being edited?
targetFile: "/etc/pacman.conf"
# A system that was grandfathered in from before garuda-config-agent
# existed will receive this "order" by default.
legacyPatchLevel: 4
pipeline:
# The order signals first of all which order the operations are called in,
# but also prevents an operation from being executed twice.
- order: 0
# operation or revert. Operations are always performed,
# Reverts are only performed on "not new" files to undo a previous operation
type: operation
# The regex pattern
pattern: "^#Color"
# What to replace it with
substitution: "Color"
- order: 1
type: operation
pattern: "^#VerbosePkgLists"
substitution: |-
VerbosePkgLists
ILoveCandy
# Add garuda repo
- order: 2
type: operation
# More complicated regex patterns allow making sure only one single
# Garuda repo exists, for example.
pattern: '(\[options\](?:(?!\n\[garuda\])[\s\S])*?)(^\[(?!options\]|garuda\]).*?\])'
substitution: |-
\1
[garuda]
Include = /etc/pacman.d/chaotic-mirrorlist
\2
# Enable multilib
- order: 3
type: operation
# Multiline patterns are supported natively
pattern: |-
^#\[multilib\]
#Include = /etc/pacman.d/mirrorlist
substitution: |-
[multilib]
Include = /etc/pacman.d/mirrorlist
# Add chaotic-aur
- order: 4
type: operation
# Only add new chaotic-aur repo if no other chaotic-aur repo exists
# in the rest of the file.
pattern: |-
(\[multilib\]\s+Include = /etc/pacman.d/mirrorlist)(?!\s*\[chaotic-aur\])
substitution: |-
\1
[chaotic-aur]
Include = /etc/pacman.d/chaotic-mirrorlist
I need YOU to help test
garuda-config-agent will be shipping in the next ISO refresh (and also the next distro release) as well as being automatically installed on existing systems.
You can install garuda-config-agent like so:
garuda-update -- garuda-config-agent
Then you could for example force the creation of a pacnew file as a test:
sudo touch /etc/pacman.conf.pacnew
sudo pacman -S pacman
Which should show some output along the lines of
( 1/11) Updating configurations with garuda-config-agent...
Pacnew file detected for /etc/pacman.conf. Applying pipeline...
[0] Applying operation...
[1] Applying operation...
[2] Applying operation...
[3] Applying operation...
[4] Applying operation...
Updated /etc/pacman.conf.pacnew
Afterward, the /etc/pacman.conf.pacnew file should contain the default Garuda Linux configuration changes.
You can see which configuration files are currently supported here:
That should be all non-edition specific files, I believe, but there are probably some more I have missed.
Go wild
I need you all to find things I have not thought of! Thanks!