5.6 KiB
5.6 KiB
pacman
The package manager as a module (novox/hq to-be 42 Phase 1, ADR 0207, research 027). It holds the
node-package-manager seat, which has no verbs yet. Every module that declares a package depends on
that seat (ADR 0207).
What it owns
- The
pacmanpackage. A component's own package belongs to the module that holds its seat (ADR 0207). /etc/pacman.conf, whole. A block cannot be added to[options]by appending: anything added at the end of the file lands in the last repository's section. So the module owns the file:- The repositories are the union of what the four machines had enabled on 2026-10-04:
core,extraandmultilib. All four had all three. - The options are the distribution's defaults, plus
Color,ParallelDownloads = 5,VerbosePkgLists, andDownloadUser = alpm(pacman 7; thealpmuser exists on all four). - The manifest test runs
pacman-confon the rendered file and checks the repository list and the options as pacman reads them. It skips that check wherepacman-confis absent. - The host keeps the machine's previous file once, the first time it writes over it (ADR 0102).
- The repositories are the union of what the four machines had enabled on 2026-10-04:
- Mirrors. The
reflectorpackage,/etc/xdg/reflector/reflector.confwritten whole (https, Belgium, the Netherlands, Luxembourg, Germany, France, the 20 most recently synced, sorted by rate, saved to/etc/pacman.d/mirrorlist), andreflector.timerrunning and enabled. The mirror list stays reflector's to write, not the mesh's. - Cache cleaning. The
pacman-contribpackage andpaccache.timerrunning and enabled. Each week it keeps the last three versions of each package. - The weekly upgrade (ADR 0477 clause 5, issue 1574).
mesh-pacman-weekly-upgrade.timerand its oneshot service, placed whole in/etc/systemd/system. The timer fires every Saturday at 04:00 in the node's local time, the same moment on every node (no random delay), and isPersistent=true: a node that was off or asleep then upgrades at its next start. The service runs/usr/bin/pacman -Syu --noconfirm, the same argumentspacman_upgradestarts (UpgradeArgsin the code; a manifest test holds the two together). No other moment upgrades but a handpacman_upgrade, and the mesh restarts no machine for an upgrade: a new kernel waits for the next restart.- The outcome is the module's health. The timer's resource asks
pacman_upgrade_health: unhealthy, naming the exit and the lasterror:line of the journal, when the last weekly upgrade failed; healthy while it runs, after it passed, and before it ever ran. The controller raises the module's condition for the node from it. A failed service stays failed until the next run, so the condition stands until an upgrade passes, a handpacman_upgradedoes not clear it. A restart of the machine forgets the failed state (the service manager's), so it is the condition raised before it that keeps the record.
- The outcome is the module's health. The timer's resource asks
What it improves
- Mirrors were generated once and never again: in 2022, 2023 and 2024, and on one machine by its
hosting provider's installer. The list is now refreshed weekly. The timer's first run is at the
next weekly boundary;
pacman_mirrorswithrefresh: trueruns it at once. - Package caches were never cleaned. One workstation held 48 GB, of which paccache would free 33 GB.
- Every machine has the same options. Only one had parallel downloads.
What it leaves found
/etc/pacman.d/mirrorlist, which reflector rewrites, and the stalemirrorlist.pacnew,.bak,.originaland similar copies beside it./etc/pacman.d/hooks, the keyring, and the AUR helper. Packages from outside the repositories are research 027 question 1.
Tools
| tool | answers | |
|---|---|---|
pacman_search |
r | pacman -Ss: repository, name, version, groups, installed and at which version, description |
pacman_info |
r | -Qi, or -Si when not installed, with lists as lists |
pacman_installed |
r | every package with version, explicit or dependency, foreign; filters and totals |
pacman_owns |
r | which package owns a path, or owned: false |
pacman_files |
r | what a package placed, bounded |
pacman_updates |
r | checkupdates: what a full upgrade would change, never setting up a partial upgrade |
pacman_upgrade |
a | starts pacman -Syu --noconfirm (sudo -n) as a transient unit that outlives the call; answers the unit and the news since the last upgrade; given the unit, how it went |
pacman_orphans |
r | pacman -Qdt |
pacman_remove_orphans |
a | pacman -Rs on named orphans, or all of them, as a unit of its own; a name that is not an orphan is refused |
pacman_cache |
r/a | size, interrupted downloads, what paccache would free keeping N; clean: true removes them |
pacman_history |
r | /var/log/pacman.log: installs, upgrades, downgrades, reinstalls and removals since a day, and the last full upgrade |
pacman_mirrors |
r/a | the list, its generator and age, reflector's options, timer and last run; refresh: true starts reflector |
pacman_foreign |
r | pacman -Qm |
pacman_news |
r | the distribution's news since the last full upgrade (or a day), over https; no network is reachable: false |
pacman_config |
r | pacman-conf: options, repositories, and whether /etc/pacman.conf is the module's |
A transaction never runs as the tool's own child. An upgrade takes longer than the 20 s a call may
take, and a pacman killed mid-transaction leaves a half-upgraded machine and a lock. So a transaction
runs as a transient unit (systemd-run, named mesh-pacman-…), and its log is read from the journal.