Commit 7e5b029
0
plików
+0
dodanych
-0
usuniętych
@@ -1,409 +0,0 @@
1
-# pag – PaganOS Package Manager
2
-
3
-[](https://git.paganlinux.eu/pag)
4
-[](https://paganlinux.eu)
5
-
6
-Package manager for [PaganOS](https://paganlinux.eu). Atomic installation
7
-(staging → rename), GPG signature verification with fingerprint pinning,
8
-per-file SHA256, full transaction rollback, hooks and triggers, and support for
9
-immutable systems with deployments.
10
-
11
-Diagrams in this README are rendered with Mermaid – supported by the
12
-`git.paganlinux.eu` portal (and GitHub/Gitea).
13
-
14
-```bash
15
-pag --version # client version (e.g. pag 3.3.20)
16
-pag # full help (command list)
17
-pag --help # same as above
18
-```
19
-
20
-
21
-## Table of contents
22
-
23
-- [Quick start](#quick-start)
24
-- [How it works](#how-it-works)
25
- - [`pag install` flow](#pag-install-flow)
26
- - [Trust chain](#trust-chain)
27
- - [Immutable system](#immutable-system)
28
- - [Rollback](#rollback)
29
-- [Commands](#commands)
30
-- [Environment variables](#environment-variables)
31
-- [Paths and files](#paths-and-files)
32
-- [Package format](#package-format)
33
-- [Hooks and triggers](#hooks-and-triggers)
34
-- [`/etc` configuration – `.pacnew` / `.pacsave`](#etc-configuration--pacnew--pacsave)
35
-- [Examples](#examples)
36
-- [Troubleshooting](#troubleshooting)
37
-- [Install and update](#install-and-update)
38
-- [License](#license)
39
-
40
-
41
-## Quick start
42
-
43
-```bash
44
-# Refresh repository indexes (and see what is pending an update)
45
-sudo pag sync
46
-
47
-# Install / remove
48
-sudo pag install firefox gimp
49
-sudo pag remove gimp
50
-
51
-# Update packages only…
52
-sudo pag update
53
-# …or the whole system: packages + kernel / initramfs / GRUB
54
-sudo pag upgrade
55
-
56
-# Verify the integrity of all files
57
-sudo pag verify --deep
58
-```
59
-
60
-
61
-## How it works
62
-
63
-### `pag install` flow
64
-
65
-```mermaid
66
-graph TD
67
- A["pag install pkg"] --> B["Dependency resolution (DFS + provides)"]
68
- B --> C{"Missing dependencies?"}
69
- C -->|yes| C1["Error – abort"]
70
- C -->|no| D["ABI verification (so-name)"]
71
- D --> E["Pre-flight: free space + RW mount"]
72
- E --> F["flock + database snapshot"]
73
- F --> G["Parallel package download"]
74
- G --> H["GPG + package SHA256 verification"]
75
- H --> I["Staging: extract + per-file sums"]
76
- I --> J["Atomic rename of files into the system"]
77
- J --> K["pre/post-install hooks"]
78
- K --> L["Write to SQLite + transaction history"]
79
- L --> M{"PAG_IMMUTABLE=1?"}
80
- M -->|yes| N["New deployment + GRUB entries"]
81
- M -->|no| O["ldconfig + triggers"]
82
- H -->|error| R["Rollback of the whole transaction"]
83
- I -->|error| R
84
- J -->|error| R
85
- R --> S["Restore database and files"]
86
-```
87
-
88
-Key properties:
89
-
90
-- **Atomicity** – files first go to staging on the same partition as `/`, then
91
- are moved with `rename()` (no half-install).
92
-- **Transactionality** – if any package fails, the whole transaction is rolled
93
- back (`installed.json`, files, backups).
94
-- **File sharing** – a file owned by two packages is not removed when one of
95
- them is removed (only the database entry is removed).
96
-
97
-### Trust chain
98
-
99
-```mermaid
100
-graph TD
101
- A["repo.json + repo.json.asc"] --> B["GPG: VALIDSIG line"]
102
- B --> C["Repo fingerprint pinning (TOFU → pin)"]
103
- C --> D["Package index"]
104
- D --> E["package .pag + .asc"]
105
- E --> F["GPG: signature matches repo pin"]
106
- F --> G["Whole-package SHA256"]
107
- G --> H["Safe extraction (anti-traversal)"]
108
- H --> I["sums.json: per-file SHA256"]
109
- I --> J["Strip SUID bit"]
110
- J --> K["Install"]
111
- F -->|"missing / bad signature"| X["Reject package"]
112
- G -->|"SHA256 mismatch"| X
113
- H -->|"traversal / symlink escape"| X
114
-```
115
-
116
-- First use of a key = **TOFU**, afterwards the fingerprint is **pinned**
117
- (`pag key-trust` / `pag key-untrust`).
118
-- Verification is **fail-closed**: missing/bad signature = no installation
119
- (override only with `PAG_INSECURE=1`, build/dev only).
120
-- `pag self-update` goes through the same path: GPG → SHA256 → syntax check →
121
- atomic client replacement.
122
-
123
-### Immutable system
124
-
125
-With `PAG_IMMUTABLE=1`, installation does not mutate `/`; it creates a new
126
-deployment. Rollback is just switching the `active` symlink.
127
-
128
-```mermaid
129
-graph TD
130
- R["/"] --> D["/.deployments"]
131
- D --> A["active → 20260723T120000"]
132
- D --> D1["20260723T120000 (new)"]
133
- D --> D2["20260722T090000 (previous)"]
134
- D1 --> U["usr/ bin/ lib/ – system"]
135
- D1 --> S1["var → /var"]
136
- D1 --> S2["etc → /etc"]
137
- D1 --> S3["home → /home"]
138
- D1 --> S4["boot → /boot"]
139
- D2 -.->|"deploy-rollback"| A
140
-```
141
-
142
-- `/var`, `/etc`, `/home`, `/boot` (and other `SHARED_PATHS`) are **shared**
143
- between deployments – they are not duplicated.
144
-- `/boot` shares the kernel and initramfs, saving space per deployment.
145
-- Rollback from the bootloader: each deployment has its own GRUB entry
146
- (`pag grub-update`).
147
-
148
-### Rollback
149
-
150
-```mermaid
151
-graph TD
152
- T["Transaction"] --> OK{"Success?"}
153
- OK -->|yes| H["History + snapshot + file journal"]
154
- OK -->|no| RB["Automatic transaction rollback"]
155
- H --> R["pag rollback"]
156
- R --> R1["Restore installed.json from snapshot"]
157
- R --> R2["Remove new files from the journal"]
158
- R --> R3["Restore overwritten files from backup"]
159
- R --> R4["Clean up empty directories"]
160
- RB --> R1
161
- RB --> R2
162
- RB --> R3
163
-```
164
-
165
-`pag history` shows recent transactions (including executed hooks), and
166
-`pag rollback` reverts the **last successful** transaction with a snapshot.
167
-
168
-
169
-## Commands
170
-
171
-### BASICS
172
-
173
-| Command | Description |
174
-|---|---|
175
-| `pag install <pkg>...` | Install packages (together with dependencies) |
176
-| `pag install -f <pkg>...` | **Force reinstall** (even the same version) – restores files, empty directories and hooks |
177
-| `pag remove <pkg>...` | Remove packages |
178
-| `pag update` | Update **packages** to newer versions |
179
-| `pag sync` | Refresh repository indexes + show how many packages await update |
180
-| `pag upgrade` | **System** update: packages + kernel / initramfs / GRUB |
181
-| `pag list` | List packages available in the repository |
182
-| `pag list --installed` | List installed packages |
183
-| `pag search <query>` | Search packages in the repo (+ Flathub) |
184
-| `pag info <pkg>` | Package details (version, dependencies, size, signature) |
185
-| `pag files <pkg>` | List files owned by a package |
186
-| `pag verify` | Verify the integrity of installed files |
187
-| `pag verify --deep` | Full per-file SHA256 verification |
188
-| `pag clean` | Clear the download cache |
189
-| `pag stats` | System statistics (package count, size, cache…) |
190
-| `pag download <pkg>...` | Download packages to cache (offline mode) |
191
-
192
-**Smart search:** `pag <name>` (any unknown command) searches the repo and
193
-Flathub and suggests names – e.g. `pag firefox` will find the package.
194
-
195
-### SECURITY / GPG KEYS
196
-
197
-| Command | Description |
198
-|---|---|
199
-| `pag key-add <url\|file>` | Import a repository GPG key |
200
-| `pag key-list` | List trusted keys |
201
-| `pag key-remove <id>` | Remove a key |
202
-| `pag key-trust <repo>` | Pin the repo key fingerprint (TOFU disabled) |
203
-| `pag key-untrust <repo>` | Forget the fingerprint (back to TOFU) |
204
-| `pag key-trusted` | List pinned repo fingerprints |
205
-
206
-### ADVANCED
207
-
208
-| Command | Description |
209
-|---|---|
210
-| `pag why <pkg>` | Why a package is installed (who depends on it) |
211
-| `pag autoremove` | Remove orphaned dependencies |
212
-| `pag remove-orphans` | Remove orphaned dependencies (alias) |
213
-| `pag pin <pkg> [version]` | Pin a package to a version (block updates) |
214
-| `pag unpin <pkg>` | Unpin |
215
-| `pag pinned` | List pinned packages |
216
-| `pag history` | Transaction history |
217
-| `pag rollback` | Revert the **last** transaction (restore files from backup) |
218
-| `pag repo-add <url> [name]` | Add a repository (drop-in in `/etc/pag/repos/`) |
219
-| `pag repo-list` | List configured repositories |
220
-| `pag sbom export [spdx\|cyclonedx]` | Export an SBOM manifest of all installed components |
221
-| `pag self-update` | Update the `pag` client itself (GPG signature + SHA256 + syntax, atomically) |
222
-
223
-### FLATPAK
224
-
225
-| Command | Description |
226
-|---|---|
227
-| `pag flatpak [<query>]` | Search and install from Flathub |
228
-| `pag flatpak search <query>` | Search Flathub |
229
-| `pag flatpak install <id>` | Install a flatpak |
230
-| `pag flatpak remove <id>` | Remove a flatpak |
231
-| `pag flatpak list` | List installed flatpaks |
232
-| `pag flatpak update` | Update all flatpaks |
233
-| `pag flatpak info <id>` | Flatpak details |
234
-
235
-> Installation as root forces the **system** scope (`--system`), so the
236
-> application is visible to all users, not just root.
237
-
238
-### IMMUTABLE SYSTEM (`PAG_IMMUTABLE=1`)
239
-
240
-| Command | Description |
241
-|---|---|
242
-| `pag deploy-list` | List deployments |
243
-| `pag deploy-rollback` | Switch to the previous deployment |
244
-| `pag deploy-cleanup [N]` | Remove old deployments (keep N, default 3) |
245
-| `pag initramfs-update` | Rebuild initramfs |
246
-| `pag grub-update` | Regenerate GRUB entries for all deployments |
247
-
248
-
249
-## Environment variables
250
-
251
-| Variable | Meaning |
252
-|---|---|
253
-| `PAG_ROOT` | Alternative operation root (tests/chroot); default `/` |
254
-| `PAG_IMMUTABLE=1` | Immutable mode – installation creates a new deployment |
255
-| `PAG_YES=1` | Automatic confirmation (same as `-y` / `--yes`) |
256
-| `PAG_INSECURE=1` | Disables the HTTPS requirement and fail-closed GPG (**build/dev only!**) |
257
-| `PAG_NO_HOOKS=1` | Skip hooks and triggers |
258
-| `PAG_HOOK_TIMEOUT` | Hook timeout in seconds (default `60`) |
259
-| `PAG_LANG_DIR` | Directory with translation files (`pl.json`, `en.json`) |
260
-| `PAG_LANG_NO_FILES=1` | Ignore translation files (export built-ins) |
261
-| `PAG_ROOT_DEVICE` / `PAG_GRUB_ROOT` | Explicit `root=` for GRUB (ISO/IMG build) |
262
-| `PAG_IN_CHROOT=1` | Force chroot mode when detecting the root device |
263
-
264
-
265
-## Paths and files
266
-
267
-| Path | Purpose |
268
-|---|---|
269
-| `/var/lib/pag/` | State database: `installed.json`, `files.db`, `world`, `pinned.json`, `history.json`, `pag.lock`, `hooks/` |
270
-| `/var/lib/pag/files.db` | SQLite: file owners + SHA256 sums |
271
-| `/var/cache/pag/` | Downloaded package cache |
272
-| `/var/cache/pag/repos/` | Repository index cache (JSON + ETag + timestamp) |
273
-| `/etc/pag/repos.conf` and `/etc/pag/repos/*.conf` | Repositories (drop-in) |
274
-| `/etc/pag/trusted.json` | Pinned repo key fingerprints |
275
-| `/etc/pag/gpg/` | Isolated GPG keyring |
276
-| `/etc/pag/triggers/*.json` | Custom triggers |
277
-| `/etc/pag/lang/`, `/usr/share/pag/lang/` | Translations (files override built-ins) |
278
-| `/var/log/pag/audit.log` | Audit: hooks, self-update |
279
-| `/.pag_staging` | Staging (same partition as `/` – no `EXDEV`) |
280
-| `/.deployments/` | Deployments (immutable mode) |
281
-
282
-
283
-## Package format
284
-
285
-A `.pag` package is an archive containing:
286
-
287
-```
288
-metadata.json – name, version, release, dependencies, provides/requires (so-name)
289
-data.tar.xz – system files + sums.json (per-file SHA256)
290
-hooks/ – optional: pre-install, post-install, pre-remove, post-remove
291
-```
292
-
293
-Installation is **verified per file** against `sums.json`, and extraction is
294
-protected against *directory traversal* and escape via malicious symlinks.
295
-
296
-
297
-## Hooks and triggers
298
-
299
-**Hooks** run as `root` (like apt/pacman), in a restricted environment:
300
-
301
-- `pre-install`, `post-install`, `pre-remove`, `post-remove`
302
-- clean env: `PATH`, `HOME=/root`, `LANG/LC_ALL=C.UTF-8`, `PKG_NAME`,
303
- `PKG_VERSION`, `PKG_ACTION`, `PKG_HOOK_API=1`
304
-- timeout (`PAG_HOOK_TIMEOUT`), optional disable (`PAG_NO_HOOKS=1`), entries in
305
- `/var/log/pag/audit.log` and in the transaction history
306
-
307
-You install code you trust – hooks have full privileges.
308
-
309
-**Triggers** run **once per transaction**, when matching paths were touched
310
-(only if the given binary exists):
311
-
312
-| Trigger | Paths | Command |
313
-|---|---|---|
314
-| `font-cache` | `/usr/share/fonts/`, `/usr/local/share/fonts/` | `fc-cache -fs` |
315
-| `glib-schemas` | `/usr/share/glib-2.0/schemas/` | `glib-compile-schemas …` |
316
-| `desktop-database` | `/usr/share/applications/` | `update-desktop-database -q …` |
317
-| `mime-database` | `/usr/share/mime/` | `update-mime-database …` |
318
-
319
-You can add your own triggers as `/etc/pag/triggers/*.json`.
320
-
321
-
322
-## `/etc` configuration – `.pacnew` / `.pacsave`
323
-
324
-The `/etc` directory is shared between deployments (it is not reverted by
325
-`deploy-rollback`). To avoid losing user changes:
326
-
327
-- **Updating** a configuration file that the user modified: the new version is
328
- written as `<file>.pacnew`, and the user's file **is kept**.
329
-- **Removing** a package with a modified configuration file: the file becomes
330
- `<file>.pacsave` instead of being deleted.
331
-
332
-The comparison uses the SHA256 sum recorded at install time.
333
-
334
-
335
-## Examples
336
-
337
-```bash
338
-# Install and updates
339
-sudo pag install firefox gimp
340
-sudo pag update # packages only
341
-sudo pag upgrade # packages + kernel/initramfs/GRUB
342
-sudo pag sync # refresh indexes + update info
343
-
344
-# Repair a package (missing files/directories, e.g. /etc/pulse/default.pa.d)
345
-sudo pag install -f pulseaudio
346
-
347
-# Application icons after installing an icon theme (cache built automatically)
348
-sudo pag install papirus-icon-theme
349
-
350
-# Security
351
-sudo pag key-add https://repo.paganlinux.eu/stable/paganos.asc
352
-sudo pag key-trust https://repo.paganlinux.eu/stable/
353
-sudo pag verify --deep
354
-
355
-# Dependencies and package provenance
356
-sudo pag why libjpeg-turbo
357
-sudo pag autoremove
358
-
359
-# SBOM for audit / compliance
360
-sudo pag sbom export cyclonedx > sbom.json
361
-
362
-# Revert the last transaction
363
-sudo pag rollback
364
-```
365
-
366
-
367
-## Troubleshooting
368
-
369
-| Symptom | Solution |
370
-|---|---|
371
-| "Another pag instance is running" | Another `pag` process is active (`flock` lock). Wait or check `pgrep -af pag`. |
372
-| "Cannot refresh the index" | The repo cache is read-only for a regular user – run as root: `sudo pag sync`. |
373
-| "Invalid signature / missing signature" | Import the key: `sudo pag key-add <url>`, then verify `sudo pag key-trusted`. |
374
-| Missing files/directories after install | `sudo pag install -f <pkg>` (restores files, empty directories and hooks). |
375
-| System does not boot after `grub-update` | Set the root device explicitly: `PAG_ROOT_DEVICE=/dev/sda2 sudo pag grub-update`. |
376
-| Flatpak app not visible in the menu | Add `/var/lib/flatpak/exports/share` to `XDG_DATA_DIRS` and log in again. |
377
-
378
-
379
-## Install and update
380
-
381
-```bash
382
-# On a running PaganOS, pag is in the base repository:
383
-sudo pag install pag # install from the repository
384
-sudo pag self-update # update the client itself (signed)
385
-
386
-# pag is also managed by the package manager – after a new version is
387
-# published in the repo:
388
-sudo pag update
389
-sudo pag upgrade
390
-```
391
-
392
-
393
-## License
394
-
395
-PaganOS / pag – an open source project. See the distribution repository for
396
-details.