garuda-config-agent
garuda-config-agent applies Garuda Linux settings to system files in /etc during package transactions. It runs from pacman hooks, so the changes happen as part of garuda-update or any other pacman transaction. Each change is a set of regex replacements that the agent applies to a file, and the agent records what it applied so it does not repeat a change the user already reverted or changed.
Components
Section titled “Components”| Path | Purpose |
|---|---|
/usr/share/libalpm/scripts/garuda-config-agent | The agent script. The package installs it from the Python script of the same name. |
/usr/share/libalpm/hooks/50-garuda-config-agent-pre.hook | Runs pre before a transaction that installs or upgrades files in etc/. |
/usr/share/libalpm/hooks/000-garuda-config-agent-post.hook | Runs post after an upgrade that touches files in etc/. |
/usr/share/libalpm/hooks/000-garuda-config-agent-postinst.hook | Runs postinst after an install that touches files in etc/. |
/etc/garuda/garuda-config-agent/*.yaml | The settings files. Each file describes one target file. |
/etc/garuda/garuda-config-agent/configs.db | The SQLite database that stores the state of each target file. |
The package garuda-config-agent is listed as an important package in garuda-health. A missing package is reported as a HIGH issue.
How changes are applied
Section titled “How changes are applied”The pacman hooks pass the changed files to the agent through standard input. The agent works in three modes.
preruns before the transaction. It stores a SHA-256 hash of each changed target file and of its.pacnewfile, for files that a YAML file manages. It also stores the list of changed files that exist at that point.postinstuses this list to find the new files.postruns after an upgrade. It applies the pipeline to each target file that the transaction changed, and to the targets of YAML files that the transaction changed. A target file that has no database row yet gets one.postinstruns after an install. It works likepost, but it applies the full pipeline only to files that did not exist before the transaction.
markoriginal is a fourth mode. It marks every file in the database as original. The ISO build calls it so that the files in a fresh image count as unchanged.
For each pipeline, the agent does the following.
- It runs the steps in order of their
ordervalue. A step runs only when itsorderis higher than the last order that was applied to the file. On an incremental run, only new steps run. - A step with a
checkregex is skipped when the regex matches the current file content. Usecheckto avoid applying a change twice. - Each step replaces the
patternwith thesubstitutionusing regex replacement with multiline matching. A step with an invalid regex stops the pipeline for that file. - The file is written only when its content changed.
- A file whose pipeline failed keeps its old order, so the agent retries it on the next run.
Original and pacnew files
Section titled “Original and pacnew files”When a package upgrade writes a .pacnew file next to a file, the agent handles it as follows.
- A file counts as original while its content matches the hash the agent stored for it. A file counts as original again when its content matches the stored
.pacnewhash. - If the
.pacnewfile was changed by the user, or new steps were added, the pipeline runs on the.pacnewfile. - If the main file is still original and
autoMergeis enabled, the agent moves the.pacnewfile over the main file. - If
autoDeleteis enabled, the agent deletes the.pacnewfile and does not merge it. - A file with
isBackupFileset to false is re-run from the first step when someone changed it outside the agent.
Legacy systems
Section titled “Legacy systems”Systems that were already installed before the agent existed get a special start level. Migration 3.5.2-1 of garuda-migrations creates the flag file /etc/garuda/migrations/has_legacy_patches on an upgrade. When this flag exists, a new database row starts at the file’s legacyPatchLevel. Steps up to that level are treated as already applied, so only newer steps run. Without the flag, the full pipeline runs.
YAML format
Section titled “YAML format”Every *.yaml file in /etc/garuda/garuda-config-agent/ is read. The agent skips a file that has no targetFile, or that has no pipeline and no autoDelete. When two files name the same targetFile, the second one is skipped with a warning.
targetFile: "/etc/example.conf"legacyPatchLevel: 0isBackupFile: trueautoMerge: trueautoDelete: false
pipeline: - order: 0 type: operation check: "^Setting=" pattern: "^#Setting=" substitution: "Setting="| Key | Default | Meaning |
|---|---|---|
targetFile | none | The file in /etc that the file manages. Required. |
pipeline | none | The list of steps. Required unless autoDelete is set. |
order | 0 | The position of a step. Steps run in ascending order. |
type | none | operation applies the substitution. revert runs only on incremental runs, never on a full run. All shipped files use operation. |
pattern | none | The regex to replace. Required. |
substitution | none | The replacement text. Required. |
check | none | A regex. When it matches the file, the step is skipped. |
legacyPatchLevel | -1 | The start level for systems with the legacy flag. |
isBackupFile | true | When false, changes made outside the agent cause a full re-run. |
autoMerge | true | Moves the .pacnew file over an unchanged main file. |
autoDelete | false | Deletes the .pacnew file. Takes precedence over autoMerge. |
Shipped settings
Section titled “Shipped settings”The package garuda-common-settings installs eight files into /etc/garuda/garuda-config-agent/.
btrfsmaintenance.yaml
Section titled “btrfsmaintenance.yaml”Target: /etc/default/btrfsmaintenance. Legacy level: 6.
| Order | Setting | Changes to |
|---|---|---|
| 0 | BTRFS_DEFRAG_PATHS | auto |
| 1 | BTRFS_DEFRAG_PERIOD | weekly |
| 2 | BTRFS_BALANCE_MOUNTPOINTS | auto |
| 3 | BTRFS_SCRUB_MOUNTPOINTS | auto |
| 4 | BTRFS_SCRUB_PERIOD | weekly |
| 5 | BTRFS_TRIM_PERIOD | weekly |
| 6 | BTRFS_TRIM_MOUNTPOINTS | auto |
faillock.yaml
Section titled “faillock.yaml”Target: /etc/security/faillock.conf. Legacy level: 0.
| Order | Setting | Changes |
|---|---|---|
| 0 | deny | A commented # deny = ... line becomes deny = 10. Skipped when an active deny = line exists. |
grub.yaml
Section titled “grub.yaml”Target: /etc/default/grub. Legacy level: 3. autoMerge is false, so a .pacnew file is never merged over this file.
| Order | Setting | Changes |
|---|---|---|
| 0 | GRUB_DISABLE_RECOVERY | The line GRUB_DISABLE_RECOVERY=true is commented out, which enables the recovery entry. |
| 1 | GRUB_DISABLE_OS_PROBER | The commented line #GRUB_DISABLE_OS_PROBER=false is enabled, only when no GRUB_DISABLE_OS_PROBER line exists. |
| 2 | GRUB_THEME | The commented placeholder #GRUB_THEME=... becomes the Garuda theme path, only when no GRUB_THEME line exists. |
| 3 | GRUB_DISTRIBUTOR | "Arch" becomes "Garuda". |
| 4 | GRUB_DISABLE_UEFI_FIRMWARE | Appends GRUB_DISABLE_UEFI_FIRMWARE=true when the line is missing. |
| 5 | GRUB_DISABLE_BOOTNEXT | Appends GRUB_DISABLE_BOOTNEXT=true when the line is missing. |
Steps 4 and 5 are the auto-disable of new GRUB entries. The changelog for the upcoming release says the agent now disables the GRUB entries that were enabled automatically. The code does not describe which menu entries these two variables control. This is UNCONFIRMED.
locale-gen.yaml
Section titled “locale-gen.yaml”Target: /etc/locale.gen. This file has no pipeline. autoDelete is true, so the agent deletes the .pacnew file of /etc/locale.gen automatically. autoMerge is false.
nsswitch.yaml
Section titled “nsswitch.yaml”Target: /etc/nsswitch.conf. Legacy level: 0.
| Order | Setting | Changes |
|---|---|---|
| 0 | hosts | Adds mdns_minimal [NOTFOUND=return] after mymachines when mdns_minimal is missing. |
pacman.yaml
Section titled “pacman.yaml”Target: /etc/pacman.conf. Legacy level: 4.
| Order | Setting | Changes |
|---|---|---|
| 0 | Color | Enables the Color option. |
| 1 | VerbosePkgLists | Enables VerbosePkgLists and adds ILoveCandy. |
| 2 | [garuda] | Adds the [garuda] repository with Include = /etc/pacman.d/chaotic-mirrorlist before the first section after [options]. |
| 3 | [multilib] | Enables the [multilib] repository with its mirrorlist. |
| 4 | [chaotic-aur] | Adds the [chaotic-aur] repository after [multilib]. |
paru.yaml
Section titled “paru.yaml”Target: /etc/paru.conf. Legacy level: 0. Enables the BottomUp option.
updatedb.yaml
Section titled “updatedb.yaml”Target: /etc/updatedb.conf. Legacy level: 0. Adds /.snapshots to PRUNEPATHS, so the locate index does not scan Snapper snapshots.
Adding your own file
Section titled “Adding your own file”The agent reads every YAML file in the directory, not only the shipped ones. A new file works the same way as the shipped files, as long as its targetFile is not already used by another file.
Changes in recent releases
Section titled “Changes in recent releases”- The package
garuda-config-agentis installed bygaruda-common-settingsas a dependency. It is also listed as an important package in garuda-health. - The changelog entry “Prevent pacnew files from falling behind when updates to yaml files are pushed” describes the hook behavior for
.pacnewfiles. - The
autoDeleteoption was added to delete.pacnewfiles automatically. TheautoMergeoption was added to disable merging for certain files. - The
checkoption was added so that a step is skipped when its change is already present. - The
markoriginalmode was added for the ISO build. - The changelog for the upcoming release lists the auto-disable of new GRUB entries. It is not in a past release yet.