9.0 KiB
9.0 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 mesh's machines had enabled on 2026-10-04:
core,extraandmultilib. All had all three. - The options are the distribution's defaults, plus
Color,ParallelDownloads = 5,VerbosePkgLists, andDownloadUser = alpm(pacman 7; thealpmuser exists on every machine). - 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 mesh's 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 package view on the bus (ADR 0507). A process of its own, the keeper (
pacman-tools keeper, accountpacman-keeper, its own bus account), keeps the node's packages in the stateinstalledand what an upgrade would change inupdates, written only on change: at its start, whenever pacman's database lock is released (an inotify watch), when reflector rewrites the mirror list, and once a day. Each change of the packages ispackage.changed. A list over the bus's cap on a value is not written: the key keeps its last value and<node>.not-currentsays the size and since when, which the health says too.pacman_packages,pacman_updates,pacman_installedandpacman_foreignanswer every node from these states, and what no module declares from the controller'sdeclared-packages, without asking a machine. - Upgrades as runs, one node at a time (ADR 0508). Every full upgrade and every rollback is a run in the
state
runsat<node>.<run>, written at each step and emitted as it: the package record taken and read back (records, keptrecord-days), the DKMS gate before the transaction (a kernel an installed DKMS module's ownLinux-MaximumorBUILD_EXCLUSIVE_KERNELexcludes is held with its headers,upgrade.kernel-held), the transaction as a unit of its own, its end, and the after-upgrade check (.pacnew/.pacsavefiles, the news since the previous upgrade, units newly failed, a restart needed, processes still mapping a replaced file by unit and executable, DKMS modules not built for an installed kernel). pacman's log is read once intorunsas history.- The round. The nodes upgrade in the order of the mesh-level key
upgrade-order(a trusted list,predefined.json; the module's config value of the same name falls back to it). On Saturday at 04:00 local time the first node of the order opens the week's round inrounds; each node's keeper watchesroundsandrunsand starts its own run when the node before it passed its after-upgrade check. A failed run or check stops the round there; only the operator passes a node (pacman_roundwithpassand a reason asks on the operator's channel, and the round goes on only on the operator's Approve). With no order set no round opens. - Acts are asks.
pacman_upgradeandpacman_rollbackwithapplywrite an ask inasksat<node>.<id>, which that node's keeper alone takes. - The root helper (ADR 0510). The keeper never runs as root. The acts that need root go through a second
process of the same build,
pacman-root(pacman-tools root), running as root with no bus account, on a unix socket in${dir:state}/root/that only the keeper's account may open, the peer's account checked on every connection. It serves four verbs and refuses everything else: start a run's full upgrade as the unitmesh-pacman-upgrade-<run>(leaving out held packages), start a rollback's unit with the plan in the request (packages from the cache or the Arch Linux Archive, the dated repository's file found by name), read which processes map a replaced file, and read a transaction unit's journal. No sudo rule is placed. - The health is read from the bus. The keeper's health check (
pacman_upgrade_health) is unhealthy while noupgrade-orderis set; while the node's latest run was refused, failed or did not pass its check (until a later run passes); while its transaction goes on past two hours (hung, said and not killed); while a kernel is held; and while the round stands still at this node or at the node it waits for, naming it and since when. A node that slept through a run is judged by what the bus holds, not by a unit's age (issue 1579). The weekly timer of ADR 0477 §5 and its service are dropped from the manifest, so the node-engine removes them.
- The round. The nodes upgrade in the order of the mesh-level key
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, from installed on the bus |
pacman_packages |
r | every node's packages from the bus: one package everywhere, differing versions, packages on some nodes only, each node's explicit packages no module declares, foreign apart, nodes not current |
pacman_owns |
r | which package owns a path, or owned: false |
pacman_files |
r | what a package placed, bounded |
pacman_updates |
r | what a full upgrade would change, for one node or all, from updates on the bus |
pacman_upgrade |
a | asks a node's keeper for a full upgrade as a run (an ask in asks); answers the ask and the news since the last upgrade; given a transaction unit, how it goes |
pacman_upgrade_health |
r | the keeper's health check, read from the bus (see the health above) |
pacman_upgrades |
r | every run of every node from runs: narrowed to a node and days, or one run whole |
pacman_round |
r/a | where every node stands in the newest rounds; pass with a reason asks the operator to let a round go on past a node |
pacman_rollback |
r/a | what returning a node to a run's record would change, each package with its source; apply asks the node's keeper to run it |
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 | the foreign packages, from installed on the bus |
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. A
run's transaction is started by the root helper; removing orphans and cleaning the cache still go through
sudo -n from the tools bundle.