Skip to content

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.

PathPurpose
/usr/share/libalpm/scripts/garuda-config-agentThe agent script. The package installs it from the Python script of the same name.
/usr/share/libalpm/hooks/50-garuda-config-agent-pre.hookRuns pre before a transaction that installs or upgrades files in etc/.
/usr/share/libalpm/hooks/000-garuda-config-agent-post.hookRuns post after an upgrade that touches files in etc/.
/usr/share/libalpm/hooks/000-garuda-config-agent-postinst.hookRuns postinst after an install that touches files in etc/.
/etc/garuda/garuda-config-agent/*.yamlThe settings files. Each file describes one target file.
/etc/garuda/garuda-config-agent/configs.dbThe 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.

The pacman hooks pass the changed files to the agent through standard input. The agent works in three modes.

  • pre runs before the transaction. It stores a SHA-256 hash of each changed target file and of its .pacnew file, for files that a YAML file manages. It also stores the list of changed files that exist at that point. postinst uses this list to find the new files.
  • post runs 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.
  • postinst runs after an install. It works like post, 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 order value. A step runs only when its order is higher than the last order that was applied to the file. On an incremental run, only new steps run.
  • A step with a check regex is skipped when the regex matches the current file content. Use check to avoid applying a change twice.
  • Each step replaces the pattern with the substitution using 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.

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 .pacnew hash.
  • If the .pacnew file was changed by the user, or new steps were added, the pipeline runs on the .pacnew file.
  • If the main file is still original and autoMerge is enabled, the agent moves the .pacnew file over the main file.
  • If autoDelete is enabled, the agent deletes the .pacnew file and does not merge it.
  • A file with isBackupFile set to false is re-run from the first step when someone changed it outside the agent.

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.

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.

/etc/garuda/garuda-config-agent/example.yaml
targetFile: "/etc/example.conf"
legacyPatchLevel: 0
isBackupFile: true
autoMerge: true
autoDelete: false
pipeline:
- order: 0
type: operation
check: "^Setting="
pattern: "^#Setting="
substitution: "Setting="
KeyDefaultMeaning
targetFilenoneThe file in /etc that the file manages. Required.
pipelinenoneThe list of steps. Required unless autoDelete is set.
order0The position of a step. Steps run in ascending order.
typenoneoperation applies the substitution. revert runs only on incremental runs, never on a full run. All shipped files use operation.
patternnoneThe regex to replace. Required.
substitutionnoneThe replacement text. Required.
checknoneA regex. When it matches the file, the step is skipped.
legacyPatchLevel-1The start level for systems with the legacy flag.
isBackupFiletrueWhen false, changes made outside the agent cause a full re-run.
autoMergetrueMoves the .pacnew file over an unchanged main file.
autoDeletefalseDeletes the .pacnew file. Takes precedence over autoMerge.

The package garuda-common-settings installs eight files into /etc/garuda/garuda-config-agent/.

Target: /etc/default/btrfsmaintenance. Legacy level: 6.

OrderSettingChanges to
0BTRFS_DEFRAG_PATHSauto
1BTRFS_DEFRAG_PERIODweekly
2BTRFS_BALANCE_MOUNTPOINTSauto
3BTRFS_SCRUB_MOUNTPOINTSauto
4BTRFS_SCRUB_PERIODweekly
5BTRFS_TRIM_PERIODweekly
6BTRFS_TRIM_MOUNTPOINTSauto

Target: /etc/security/faillock.conf. Legacy level: 0.

OrderSettingChanges
0denyA commented # deny = ... line becomes deny = 10. Skipped when an active deny = line exists.

Target: /etc/default/grub. Legacy level: 3. autoMerge is false, so a .pacnew file is never merged over this file.

OrderSettingChanges
0GRUB_DISABLE_RECOVERYThe line GRUB_DISABLE_RECOVERY=true is commented out, which enables the recovery entry.
1GRUB_DISABLE_OS_PROBERThe commented line #GRUB_DISABLE_OS_PROBER=false is enabled, only when no GRUB_DISABLE_OS_PROBER line exists.
2GRUB_THEMEThe commented placeholder #GRUB_THEME=... becomes the Garuda theme path, only when no GRUB_THEME line exists.
3GRUB_DISTRIBUTOR"Arch" becomes "Garuda".
4GRUB_DISABLE_UEFI_FIRMWAREAppends GRUB_DISABLE_UEFI_FIRMWARE=true when the line is missing.
5GRUB_DISABLE_BOOTNEXTAppends 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.

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.

Target: /etc/nsswitch.conf. Legacy level: 0.

OrderSettingChanges
0hostsAdds mdns_minimal [NOTFOUND=return] after mymachines when mdns_minimal is missing.

Target: /etc/pacman.conf. Legacy level: 4.

OrderSettingChanges
0ColorEnables the Color option.
1VerbosePkgListsEnables 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].

Target: /etc/paru.conf. Legacy level: 0. Enables the BottomUp option.

Target: /etc/updatedb.conf. Legacy level: 0. Adds /.snapshots to PRUNEPATHS, so the locate index does not scan Snapper snapshots.

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.

  • The package garuda-config-agent is installed by garuda-common-settings as 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 .pacnew files.
  • The autoDelete option was added to delete .pacnew files automatically. The autoMerge option was added to disable merging for certain files.
  • The check option was added so that a step is skipped when its change is already present.
  • The markoriginal mode 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.