← pag

Commit 7e5b029

0
plików
+0
dodanych
-0
usuniętych
@@ -1,409 +0,0 @@
1 -# pag – PaganOS Package Manager
2 -
3 -[![Version](https://img.shields.io/badge/pag-3.3.20-blue)](https://git.paganlinux.eu/pag)
4 -[![Platform](https://img.shields.io/badge/PaganOS-Linux-success)](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.