← pag

Commit b4263ae

2
plików
+409
dodanych
-410
usuniętych
@@ -0,0 +1,409 @@
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 +
22 +## Table of contents
23 +
24 +- [Quick start](#quick-start)
25 +- [How it works](#how-it-works)
26 + - [`pag install` flow](#pag-install-flow)
27 + - [Trust chain](#trust-chain)
28 + - [Immutable system](#immutable-system)
29 + - [Rollback](#rollback)
30 +- [Commands](#commands)
31 +- [Environment variables](#environment-variables)
32 +- [Paths and files](#paths-and-files)
33 +- [Package format](#package-format)
34 +- [Hooks and triggers](#hooks-and-triggers)
35 +- [`/etc` configuration – `.pacnew` / `.pacsave`](#etc-configuration--pacnew--pacsave)
36 +- [Examples](#examples)
37 +- [Troubleshooting](#troubleshooting)
38 +- [Install and update](#install-and-update)
39 +- [License](#license)
40 +
41 +---
42 +
43 +## Quick start
44 +
45 +```bash
46 +# Refresh repository indexes (and see what is pending an update)
47 +sudo pag sync
48 +
49 +# Install / remove
50 +sudo pag install firefox gimp
51 +sudo pag remove gimp
52 +
53 +# Update packages only…
54 +sudo pag update
55 +# …or the whole system: packages + kernel / initramfs / GRUB
56 +sudo pag upgrade
57 +
58 +# Verify the integrity of all files
59 +sudo pag verify --deep
60 +```
61 +
62 +---
63 +
64 +## How it works
65 +
66 +### `pag install` flow
67 +
68 +```mermaid
69 +graph TD
70 + A["pag install pkg"] --> B["Dependency resolution (DFS + provides)"]
71 + B --> C{"Missing dependencies?"}
72 + C -->|yes| C1["Error – abort"]
73 + C -->|no| D["ABI verification (so-name)"]
74 + D --> E["Pre-flight: free space + RW mount"]
75 + E --> F["flock + database snapshot"]
76 + F --> G["Parallel package download"]
77 + G --> H["GPG + package SHA256 verification"]
78 + H --> I["Staging: extract + per-file sums"]
79 + I --> J["Atomic rename of files into the system"]
80 + J --> K["pre/post-install hooks"]
81 + K --> L["Write to SQLite + transaction history"]
82 + L --> M{"PAG_IMMUTABLE=1?"}
83 + M -->|yes| N["New deployment + GRUB entries"]
84 + M -->|no| O["ldconfig + triggers"]
85 + H -->|error| R["Rollback of the whole transaction"]
86 + I -->|error| R
87 + J -->|error| R
88 + R --> S["Restore database and files"]
89 +```
90 +
91 +Key properties:
92 +
93 +- **Atomicity** – files first go to staging on the same partition as `/`, then
94 + are moved with `rename()` (no half-install).
95 +- **Transactionality** – if any package fails, the whole transaction is rolled
96 + back (`installed.json`, files, backups).
97 +- **File sharing** – a file owned by two packages is not removed when one of
98 + them is removed (only the database entry is removed).
99 +
100 +### Trust chain
101 +
102 +```mermaid
103 +graph TD
104 + A["repo.json + repo.json.asc"] --> B["GPG: VALIDSIG line"]
105 + B --> C["Repo fingerprint pinning (TOFU → pin)"]
106 + C --> D["Package index"]
107 + D --> E["package .pag + .asc"]
108 + E --> F["GPG: signature matches repo pin"]
109 + F --> G["Whole-package SHA256"]
110 + G --> H["Safe extraction (anti-traversal)"]
111 + H --> I["sums.json: per-file SHA256"]
112 + I --> J["Strip SUID bit"]
113 + J --> K["Install"]
114 + F -->|"missing / bad signature"| X["Reject package"]
115 + G -->|"SHA256 mismatch"| X
116 + H -->|"traversal / symlink escape"| X
117 +```
118 +
119 +- First use of a key = **TOFU**, afterwards the fingerprint is **pinned**
120 + (`pag key-trust` / `pag key-untrust`).
121 +- Verification is **fail-closed**: missing/bad signature = no installation
122 + (override only with `PAG_INSECURE=1`, build/dev only).
123 +- `pag self-update` goes through the same path: GPG → SHA256 → syntax check →
124 + atomic client replacement.
125 +
126 +### Immutable system
127 +
128 +With `PAG_IMMUTABLE=1`, installation does not mutate `/`; it creates a new
129 +deployment. Rollback is just switching the `active` symlink.
130 +
131 +```mermaid
132 +graph TD
133 + R["/"] --> D["/.deployments"]
134 + D --> A["active → 20260723T120000"]
135 + D --> D1["20260723T120000 (new)"]
136 + D --> D2["20260722T090000 (previous)"]
137 + D1 --> U["usr/ bin/ lib/ – system"]
138 + D1 --> S1["var → /var"]
139 + D1 --> S2["etc → /etc"]
140 + D1 --> S3["home → /home"]
141 + D1 --> S4["boot → /boot"]
142 + D2 -.->|"deploy-rollback"| A
143 +```
144 +
145 +- `/var`, `/etc`, `/home`, `/boot` (and other `SHARED_PATHS`) are **shared**
146 + between deployments – they are not duplicated.
147 +- `/boot` shares the kernel and initramfs, saving space per deployment.
148 +- Rollback from the bootloader: each deployment has its own GRUB entry
149 + (`pag grub-update`).
150 +
151 +### Rollback
152 +
153 +```mermaid
154 +graph TD
155 + T["Transaction"] --> OK{"Success?"}
156 + OK -->|yes| H["History + snapshot + file journal"]
157 + OK -->|no| RB["Automatic transaction rollback"]
158 + H --> R["pag rollback"]
159 + R --> R1["Restore installed.json from snapshot"]
160 + R --> R2["Remove new files from the journal"]
161 + R --> R3["Restore overwritten files from backup"]
162 + R --> R4["Clean up empty directories"]
163 + RB --> R1
164 + RB --> R2
165 + RB --> R3
166 +```
167 +
168 +`pag history` shows recent transactions (including executed hooks), and
169 +`pag rollback` reverts the **last successful** transaction with a snapshot.
170 +
171 +---
172 +
173 +## Commands
174 +
175 +### BASICS
176 +
177 +| Command | Description |
178 +|---|---|
179 +| `pag install <pkg>...` | Install packages (together with dependencies) |
180 +| `pag install -f <pkg>...` | **Force reinstall** (even the same version) – restores files, empty directories and hooks |
181 +| `pag remove <pkg>...` | Remove packages |
182 +| `pag update` | Update **packages** to newer versions |
183 +| `pag sync` | Refresh repository indexes + show how many packages await update |
184 +| `pag upgrade` | **System** update: packages + kernel / initramfs / GRUB |
185 +| `pag list` | List packages available in the repository |
186 +| `pag list --installed` | List installed packages |
187 +| `pag search <query>` | Search packages in the repo (+ Flathub) |
188 +| `pag info <pkg>` | Package details (version, dependencies, size, signature) |
189 +| `pag files <pkg>` | List files owned by a package |
190 +| `pag verify` | Verify the integrity of installed files |
191 +| `pag verify --deep` | Full per-file SHA256 verification |
192 +| `pag clean` | Clear the download cache |
193 +| `pag stats` | System statistics (package count, size, cache…) |
194 +| `pag download <pkg>...` | Download packages to cache (offline mode) |
195 +
196 +**Smart search:** `pag <name>` (any unknown command) searches the repo and
197 +Flathub and suggests names – e.g. `pag firefox` will find the package.
198 +
199 +### SECURITY / GPG KEYS
200 +
201 +| Command | Description |
202 +|---|---|
203 +| `pag key-add <url\|file>` | Import a repository GPG key |
204 +| `pag key-list` | List trusted keys |
205 +| `pag key-remove <id>` | Remove a key |
206 +| `pag key-trust <repo>` | Pin the repo key fingerprint (TOFU disabled) |
207 +| `pag key-untrust <repo>` | Forget the fingerprint (back to TOFU) |
208 +| `pag key-trusted` | List pinned repo fingerprints |
209 +
210 +### ADVANCED
211 +
212 +| Command | Description |
213 +|---|---|
214 +| `pag why <pkg>` | Why a package is installed (who depends on it) |
215 +| `pag autoremove` | Remove orphaned dependencies |
216 +| `pag remove-orphans` | Remove orphaned dependencies (alias) |
217 +| `pag pin <pkg> [version]` | Pin a package to a version (block updates) |
218 +| `pag unpin <pkg>` | Unpin |
219 +| `pag pinned` | List pinned packages |
220 +| `pag history` | Transaction history |
221 +| `pag rollback` | Revert the **last** transaction (restore files from backup) |
222 +| `pag repo-add <url> [name]` | Add a repository (drop-in in `/etc/pag/repos/`) |
223 +| `pag repo-list` | List configured repositories |
224 +| `pag sbom export [spdx\|cyclonedx]` | Export an SBOM manifest of all installed components |
225 +| `pag self-update` | Update the `pag` client itself (GPG signature + SHA256 + syntax, atomically) |
226 +
227 +### FLATPAK
228 +
229 +| Command | Description |
230 +|---|---|
231 +| `pag flatpak [<query>]` | Search and install from Flathub |
232 +| `pag flatpak search <query>` | Search Flathub |
233 +| `pag flatpak install <id>` | Install a flatpak |
234 +| `pag flatpak remove <id>` | Remove a flatpak |
235 +| `pag flatpak list` | List installed flatpaks |
236 +| `pag flatpak update` | Update all flatpaks |
237 +| `pag flatpak info <id>` | Flatpak details |
238 +
239 +> Installation as root forces the **system** scope (`--system`), so the
240 +> application is visible to all users, not just root.
241 +
242 +### IMMUTABLE SYSTEM (`PAG_IMMUTABLE=1`)
243 +
244 +| Command | Description |
245 +|---|---|
246 +| `pag deploy-list` | List deployments |
247 +| `pag deploy-rollback` | Switch to the previous deployment |
248 +| `pag deploy-cleanup [N]` | Remove old deployments (keep N, default 3) |
249 +| `pag initramfs-update` | Rebuild initramfs |
250 +| `pag grub-update` | Regenerate GRUB entries for all deployments |
251 +
252 +---
253 +
254 +## Environment variables
255 +
256 +| Variable | Meaning |
257 +|---|---|
258 +| `PAG_ROOT` | Alternative operation root (tests/chroot); default `/` |
259 +| `PAG_IMMUTABLE=1` | Immutable mode – installation creates a new deployment |
260 +| `PAG_YES=1` | Automatic confirmation (same as `-y` / `--yes`) |
261 +| `PAG_INSECURE=1` | Disables the HTTPS requirement and fail-closed GPG (**build/dev only!**) |
262 +| `PAG_NO_HOOKS=1` | Skip hooks and triggers |
263 +| `PAG_HOOK_TIMEOUT` | Hook timeout in seconds (default `60`) |
264 +| `PAG_LANG_DIR` | Directory with translation files (`pl.json`, `en.json`) |
265 +| `PAG_LANG_NO_FILES=1` | Ignore translation files (export built-ins) |
266 +| `PAG_ROOT_DEVICE` / `PAG_GRUB_ROOT` | Explicit `root=` for GRUB (ISO/IMG build) |
267 +| `PAG_IN_CHROOT=1` | Force chroot mode when detecting the root device |
268 +
269 +---
270 +
271 +## Paths and files
272 +
273 +| Path | Purpose |
274 +|---|---|
275 +| `/var/lib/pag/` | State database: `installed.json`, `files.db`, `world`, `pinned.json`, `history.json`, `pag.lock`, `hooks/` |
276 +| `/var/lib/pag/files.db` | SQLite: file owners + SHA256 sums |
277 +| `/var/cache/pag/` | Downloaded package cache |
278 +| `/var/cache/pag/repos/` | Repository index cache (JSON + ETag + timestamp) |
279 +| `/etc/pag/repos.conf` and `/etc/pag/repos/*.conf` | Repositories (drop-in) |
280 +| `/etc/pag/trusted.json` | Pinned repo key fingerprints |
281 +| `/etc/pag/gpg/` | Isolated GPG keyring |
282 +| `/etc/pag/triggers/*.json` | Custom triggers |
283 +| `/etc/pag/lang/`, `/usr/share/pag/lang/` | Translations (files override built-ins) |
284 +| `/var/log/pag/audit.log` | Audit: hooks, self-update |
285 +| `/.pag_staging` | Staging (same partition as `/` – no `EXDEV`) |
286 +| `/.deployments/` | Deployments (immutable mode) |
287 +
288 +---
289 +
290 +## Package format
291 +
292 +A `.pag` package is an archive containing:
293 +
294 +```
295 +metadata.json – name, version, release, dependencies, provides/requires (so-name)
296 +data.tar.xz – system files + sums.json (per-file SHA256)
297 +hooks/ – optional: pre-install, post-install, pre-remove, post-remove
298 +```
299 +
300 +Installation is **verified per file** against `sums.json`, and extraction is
301 +protected against *directory traversal* and escape via malicious symlinks.
302 +
303 +---
304 +
305 +## Hooks and triggers
306 +
307 +**Hooks** run as `root` (like apt/pacman), in a restricted environment:
308 +
309 +- `pre-install`, `post-install`, `pre-remove`, `post-remove`
310 +- clean env: `PATH`, `HOME=/root`, `LANG/LC_ALL=C.UTF-8`, `PKG_NAME`,
311 + `PKG_VERSION`, `PKG_ACTION`, `PKG_HOOK_API=1`
312 +- timeout (`PAG_HOOK_TIMEOUT`), optional disable (`PAG_NO_HOOKS=1`), entries in
313 + `/var/log/pag/audit.log` and in the transaction history
314 +
315 +You install code you trust – hooks have full privileges.
316 +
317 +**Triggers** run **once per transaction**, when matching paths were touched
318 +(only if the given binary exists):
319 +
320 +| Trigger | Paths | Command |
321 +|---|---|---|
322 +| `font-cache` | `/usr/share/fonts/`, `/usr/local/share/fonts/` | `fc-cache -fs` |
323 +| `glib-schemas` | `/usr/share/glib-2.0/schemas/` | `glib-compile-schemas …` |
324 +| `desktop-database` | `/usr/share/applications/` | `update-desktop-database -q …` |
325 +| `mime-database` | `/usr/share/mime/` | `update-mime-database …` |
326 +
327 +You can add your own triggers as `/etc/pag/triggers/*.json`.
328 +
329 +---
330 +
331 +## `/etc` configuration – `.pacnew` / `.pacsave`
332 +
333 +The `/etc` directory is shared between deployments (it is not reverted by
334 +`deploy-rollback`). To avoid losing user changes:
335 +
336 +- **Updating** a configuration file that the user modified: the new version is
337 + written as `<file>.pacnew`, and the user's file **is kept**.
338 +- **Removing** a package with a modified configuration file: the file becomes
339 + `<file>.pacsave` instead of being deleted.
340 +
341 +The comparison uses the SHA256 sum recorded at install time.
342 +
343 +---
344 +
345 +## Examples
346 +
347 +```bash
348 +# Install and updates
349 +sudo pag install firefox gimp
350 +sudo pag update # packages only
351 +sudo pag upgrade # packages + kernel/initramfs/GRUB
352 +sudo pag sync # refresh indexes + update info
353 +
354 +# Repair a package (missing files/directories, e.g. /etc/pulse/default.pa.d)
355 +sudo pag install -f pulseaudio
356 +
357 +# Application icons after installing an icon theme (cache built automatically)
358 +sudo pag install papirus-icon-theme
359 +
360 +# Security
361 +sudo pag key-add https://repo.paganlinux.eu/stable/paganos.asc
362 +sudo pag key-trust https://repo.paganlinux.eu/stable/
363 +sudo pag verify --deep
364 +
365 +# Dependencies and package provenance
366 +sudo pag why libjpeg-turbo
367 +sudo pag autoremove
368 +
369 +# SBOM for audit / compliance
370 +sudo pag sbom export cyclonedx > sbom.json
371 +
372 +# Revert the last transaction
373 +sudo pag rollback
374 +```
375 +
376 +---
377 +
378 +## Troubleshooting
379 +
380 +| Symptom | Solution |
381 +|---|---|
382 +| "Another pag instance is running" | Another `pag` process is active (`flock` lock). Wait or check `pgrep -af pag`. |
383 +| "Cannot refresh the index" | The repo cache is read-only for a regular user – run as root: `sudo pag sync`. |
384 +| "Invalid signature / missing signature" | Import the key: `sudo pag key-add <url>`, then verify `sudo pag key-trusted`. |
385 +| Missing files/directories after install | `sudo pag install -f <pkg>` (restores files, empty directories and hooks). |
386 +| System does not boot after `grub-update` | Set the root device explicitly: `PAG_ROOT_DEVICE=/dev/sda2 sudo pag grub-update`. |
387 +| Flatpak app not visible in the menu | Add `/var/lib/flatpak/exports/share` to `XDG_DATA_DIRS` and log in again. |
388 +
389 +---
390 +
391 +## Install and update
392 +
393 +```bash
394 +# On a running PaganOS, pag is in the base repository:
395 +sudo pag install pag # install from the repository
396 +sudo pag self-update # update the client itself (signed)
397 +
398 +# pag is also managed by the package manager – after a new version is
399 +# published in the repo:
400 +sudo pag update
401 +sudo pag upgrade
402 +```
403 +
404 +---
405 +
406 +## License
407 +
408 +PaganOS / pag – an open source project. See the distribution repository for
409 +details.
0 410 deleted file mode 100644
@@ -1,410 +0,0 @@
1 -# pag – PaganOS Package Manager
2 -
3 -[![Wersja](https://img.shields.io/badge/pag-3.3.20-blue)](https://git.paganlinux.eu/pag)
4 -[![Platforma](https://img.shields.io/badge/PaganOS-Linux-success)](https://paganlinux.eu)
5 -
6 -Menedżer pakietów dla [PaganOS](https://paganlinux.eu). Instalacja atomowa
7 -(staging → rename), weryfikacja podpisów GPG z pinningiem fingerprintu, SHA256
8 -per-plik, pełny rollback transakcji, hooki i triggery oraz wsparcie systemów
9 -immutable z wdrożeniami (deployments).
10 -
11 -Diagramy w tym README renderuje Mermaid – obsługiwany przez portal
12 -`git.paganlinux.eu` (oraz GitHub/Gitea).
13 -
14 -```bash
15 -pag --version # wersja klienta (np. pag 3.3.20)
16 -pag # pełna pomoc (lista komend)
17 -pag --help # to samo co wyżej
18 -```
19 -
20 -
21 -## Spis treści
22 -
23 -- [Szybki start](#szybki-start)
24 -- [Jak to działa](#jak-to-działa)
25 - - [Przepływ `pag install`](#przepływ-pag-install)
26 - - [Łańcuch zaufania](#łańcuch-zaufania)
27 - - [System immutable](#system-immutable)
28 - - [Rollback](#rollback)
29 -- [Komendy](#komendy)
30 -- [Zmienne środowiskowe](#zmienne-środowiskowe)
31 -- [Ścieżki i pliki](#ścieżki-i-pliki)
32 -- [Format pakietu](#format-pakietu)
33 -- [Hooki i triggery](#hooki-i-triggery)
34 -- [Konfiguracja `/etc` – `.pacnew` / `.pacsave`](#konfiguracja-etc--pacnew--pacsave)
35 -- [Przykłady](#przykłady)
36 -- [Diagnostyka](#diagnostyka)
37 -- [Instalacja i aktualizacja](#instalacja-i-aktualizacja)
38 -- [Licencja](#licencja)
39 -
40 -
41 -## Szybki start
42 -
43 -```bash
44 -# Odśwież indeksy repozytoriów (i zobacz, co czeka na aktualizację)
45 -sudo pag sync
46 -
47 -# Instaluj / usuwaj
48 -sudo pag install firefox gimp
49 -sudo pag remove gimp
50 -
51 -# Aktualizuj same pakiety…
52 -sudo pag update
53 -# …albo cały system: pakiety + kernel / initramfs / GRUB
54 -sudo pag upgrade
55 -
56 -# Sprawdź integralność wszystkich plików
57 -sudo pag verify --deep
58 -```
59 -
60 -
61 -## Jak to działa
62 -
63 -### Przepływ `pag install`
64 -
65 -```mermaid
66 -graph TD
67 - A["pag install pkg"] --> B["Rozwiązanie zależności (DFS + provides)"]
68 - B --> C{"Brakujące zależności?"}
69 - C -->|tak| C1["Błąd – przerwij"]
70 - C -->|nie| D["Weryfikacja ABI (so-name)"]
71 - D --> E["Pre-flight: wolne miejsce + montowanie RW"]
72 - E --> F["Blokada flock + migawka bazy"]
73 - F --> G["Równoległe pobieranie paczek"]
74 - G --> H["Weryfikacja GPG + SHA256 paczki"]
75 - H --> I["Staging: rozpakowanie + sumy per-plik"]
76 - I --> J["Atomowy rename plików do systemu"]
77 - J --> K["Hooki pre/post-install"]
78 - K --> L["Zapis do SQLite + historia transakcji"]
79 - L --> M{"PAG_IMMUTABLE=1?"}
80 - M -->|tak| N["Nowy deployment + wpisy GRUB"]
81 - M -->|nie| O["ldconfig + triggery"]
82 - H -->|błąd| R["Rollback całej transakcji"]
83 - I -->|błąd| R
84 - J -->|błąd| R
85 - R --> S["Przywrócenie bazy i plików"]
86 -```
87 -
88 -Kluczowe własności:
89 -
90 -- **Atomowość** – pliki trafiają najpierw do staging na tej samej partycji co
91 - `/`, potem są przenoszone `rename()` (bez pół-instalacji).
92 -- **Transakcyjność** – jeśli którykolwiek pakiet zawiedzie, cała transakcja jest
93 - cofana (`installed.json`, pliki, backupy).
94 -- **Współdzielenie plików** – plik należący do dwóch pakietów nie jest usuwany
95 - przy usunięciu jednego z nich (usuwany jest tylko wpis w bazie).
96 -
97 -### Łańcuch zaufania
98 -
99 -```mermaid
100 -graph TD
101 - A["repo.json + repo.json.asc"] --> B["GPG: linia VALIDSIG"]
102 - B --> C["Pinning fingerprintu repo (TOFU → pin)"]
103 - C --> D["Indeks pakietów"]
104 - D --> E["pakiet .pag + .asc"]
105 - E --> F["GPG: podpis zgodny z pinem repo"]
106 - F --> G["SHA256 całej paczki"]
107 - G --> H["Bezpieczne rozpakowanie (anty-traversal)"]
108 - H --> I["sums.json: SHA256 per plik"]
109 - I --> J["Zdjęcie bitu SUID"]
110 - J --> K["Instalacja"]
111 - F -->|"brak / zły podpis"| X["Odrzuć paczkę"]
112 - G -->|"niezgodny SHA256"| X
113 - H -->|"traversal / escape przez symlink"| X
114 -```
115 -
116 -- Pierwsze użycie klucza = **TOFU**, potem fingerprint jest **przypinany**
117 - (`pag key-trust` / `pag key-untrust`).
118 -- Weryfikacja jest **fail-closed**: brak/zły podpis = brak instalacji
119 - (obejście tylko przez `PAG_INSECURE=1`, wyłącznie build/dev).
120 -- `pag self-update` przechodzi tę samą ścieżkę: GPG → SHA256 → kontrola
121 - składni → atomowa podmiana klienta.
122 -
123 -### System immutable
124 -
125 -Przy `PAG_IMMUTABLE=1` instalacja nie mutuje `/`, lecz tworzy nowy deployment;
126 -rollback to przełączenie symlinku `active`.
127 -
128 -```mermaid
129 -graph TD
130 - R["/"] --> D["/.deployments"]
131 - D --> A["active → 20260723T120000"]
132 - D --> D1["20260723T120000 (nowy)"]
133 - D --> D2["20260722T090000 (poprzedni)"]
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` (i inne z listy `SHARED_PATHS`) są
143 - **współdzielone** między deploymentami – nie duplikują się.
144 -- `/boot` współdzieli jądro i initramfs, oszczędzając miejsce na każdym
145 - deploymentcie.
146 -- Rollback z poziomu bootloadera: każdy deployment ma własny wpis GRUB
147 - (`pag grub-update`).
148 -
149 -### Rollback
150 -
151 -```mermaid
152 -graph TD
153 - T["Transakcja"] --> OK{"Sukces?"}
154 - OK -->|tak| H["Historia + migawka + journal plików"]
155 - OK -->|nie| RB["Automatyczny rollback transakcji"]
156 - H --> R["pag rollback"]
157 - R --> R1["Przywróć installed.json z migawki"]
158 - R --> R2["Usuń nowe pliki z journalu"]
159 - R --> R3["Przywróć nadpisane pliki z backupu"]
160 - R --> R4["Posprzątaj puste katalogi"]
161 - RB --> R1
162 - RB --> R2
163 - RB --> R3
164 -```
165 -
166 -`pag history` pokazuje ostatnie transakcje (wraz z wykonanymi hookami), a
167 -`pag rollback` cofa **ostatnią udaną** transakcję z migawką.
168 -
169 -
170 -## Komendy
171 -
172 -### PODSTAWY
173 -
174 -| Komenda | Opis |
175 -|---|---|
176 -| `pag install <pkg>...` | Instaluje pakiety (razem z zależnościami) |
177 -| `pag install -f <pkg>...` | **Wymusza reinstalację** (nawet tej samej wersji) – odtwarza pliki, puste katalogi i hooki |
178 -| `pag remove <pkg>...` | Usuwa pakiety |
179 -| `pag update` | Aktualizuje **pakiety** do nowszych wersji |
180 -| `pag sync` | Odświeża indeksy repozytoriów + pokazuje, ile pakietów czeka na aktualizację |
181 -| `pag upgrade` | Aktualizacja **systemu**: pakiety + kernel / initramfs / GRUB |
182 -| `pag list` | Lista pakietów dostępnych w repozytorium |
183 -| `pag list --installed` | Lista zainstalowanych pakietów |
184 -| `pag search <query>` | Szukaj pakietów w repo (+ Flathub) |
185 -| `pag info <pkg>` | Szczegóły pakietu (wersja, zależności, rozmiar, podpis) |
186 -| `pag files <pkg>` | Lista plików należących do pakietu |
187 -| `pag verify` | Weryfikacja integralności zainstalowanych plików |
188 -| `pag verify --deep` | Pełna weryfikacja SHA256 per-plik |
189 -| `pag clean` | Czyści cache pobierania |
190 -| `pag stats` | Statystyki systemu (liczba pakietów, rozmiar, cache…) |
191 -| `pag download <pkg>...` | Pobiera pakiety do cache (tryb offline) |
192 -
193 -**Smart search:** `pag <nazwa>` (dowolna nieznana komenda) przeszukuje repo
194 -i Flathub oraz podpowiada nazwy – np. `pag firefox` znajdzie pakiet.
195 -
196 -### BEZPIECZEŃSTWO / KLUCZE GPG
197 -
198 -| Komenda | Opis |
199 -|---|---|
200 -| `pag key-add <url\|plik>` | Importuje klucz GPG repozytorium |
201 -| `pag key-list` | Lista zaufanych kluczy |
202 -| `pag key-remove <id>` | Usuwa klucz |
203 -| `pag key-trust <repo>` | Przypina fingerprint klucza repo (TOFU wyłączone) |
204 -| `pag key-untrust <repo>` | Zapomina fingerprint (powrót do TOFU) |
205 -| `pag key-trusted` | Lista przypiętych fingerprintów repo |
206 -
207 -### ZAAWANSOWANE
208 -
209 -| Komenda | Opis |
210 -|---|---|
211 -| `pag why <pkg>` | Dlaczego pakiet jest zainstalowany (kto go zależy) |
212 -| `pag autoremove` | Usuwa osierocone zależności |
213 -| `pag remove-orphans` | Usuwa osierocone zależności (alias) |
214 -| `pag pin <pkg> [wersja]` | Przypina pakiet do wersji (blokada aktualizacji) |
215 -| `pag unpin <pkg>` | Zdejmuje przypięcie |
216 -| `pag pinned` | Lista przypiętych pakietów |
217 -| `pag history` | Historia transakcji |
218 -| `pag rollback` | Cofa **ostatnią** transakcję (przywraca pliki z backupu) |
219 -| `pag repo-add <url> [nazwa]` | Dodaje repozytorium (drop-in w `/etc/pag/repos/`) |
220 -| `pag repo-list` | Lista skonfigurowanych repozytoriów |
221 -| `pag sbom export [spdx\|cyclonedx]` | Eksportuje manifest SBOM wszystkich zainstalowanych komponentów |
222 -| `pag self-update` | Aktualizuje samego klienta `pag` (podpis GPG + SHA256 + składnia, atomowo) |
223 -
224 -### FLATPAK
225 -
226 -| Komenda | Opis |
227 -|---|---|
228 -| `pag flatpak [<query>]` | Szukaj i instaluj z Flathub |
229 -| `pag flatpak search <query>` | Szukaj na Flathub |
230 -| `pag flatpak install <id>` | Instaluje flatpak |
231 -| `pag flatpak remove <id>` | Usuwa flatpak |
232 -| `pag flatpak list` | Lista zainstalowanych flatpaków |
233 -| `pag flatpak update` | Aktualizuje wszystkie flatpaki |
234 -| `pag flatpak info <id>` | Szczegóły flatpaka |
235 -
236 -> Instalacja jako root wymusza zakres **systemowy** (`--system`), dzięki czemu
237 -> aplikacja jest widoczna dla wszystkich użytkowników, a nie tylko dla roota.
238 -
239 -### SYSTEM IMMUTABLE (`PAG_IMMUTABLE=1`)
240 -
241 -| Komenda | Opis |
242 -|---|---|
243 -| `pag deploy-list` | Lista wdrożeń (deployments) |
244 -| `pag deploy-rollback` | Przełącza na poprzednie wdrożenie |
245 -| `pag deploy-cleanup [N]` | Usuwa stare wdrożenia (zachowuje N, domyślnie 3) |
246 -| `pag initramfs-update` | Przebudowuje initramfs |
247 -| `pag grub-update` | Regeneruje wpisy GRUB dla wszystkich wdrożeń |
248 -
249 -
250 -## Zmienne środowiskowe
251 -
252 -| Zmienna | Znaczenie |
253 -|---|---|
254 -| `PAG_ROOT` | Alternatywny root operacji (testy/chroot); domyślnie `/` |
255 -| `PAG_IMMUTABLE=1` | Tryb immutable – instalacja tworzy nowy deployment |
256 -| `PAG_YES=1` | Automatyczne potwierdzenie (to samo co `-y` / `--yes`) |
257 -| `PAG_INSECURE=1` | Wyłącza wymóg HTTPS i fail-closed GPG (**tylko build/dev!**) |
258 -| `PAG_NO_HOOKS=1` | Pomija hooki i triggery |
259 -| `PAG_HOOK_TIMEOUT` | Timeout hooka w sekundach (domyślnie `60`) |
260 -| `PAG_LANG_DIR` | Katalog z plikami tłumaczeń (`pl.json`, `en.json`) |
261 -| `PAG_LANG_NO_FILES=1` | Ignoruje pliki tłumaczeń (eksport wbudowanych) |
262 -| `PAG_ROOT_DEVICE` / `PAG_GRUB_ROOT` | Jawny `root=` dla GRUB (build ISO/IMG) |
263 -| `PAG_IN_CHROOT=1` | Wymusza tryb chroot przy wykrywaniu urządzenia root |
264 -
265 -
266 -## Ścieżki i pliki
267 -
268 -| Ścieżka | Przeznaczenie |
269 -|---|---|
270 -| `/var/lib/pag/` | Baza stanu: `installed.json`, `files.db`, `world`, `pinned.json`, `history.json`, `pag.lock`, `hooks/` |
271 -| `/var/lib/pag/files.db` | SQLite: właściciele plików + sumy SHA256 |
272 -| `/var/cache/pag/` | Cache pobranych pakietów |
273 -| `/var/cache/pag/repos/` | Cache indeksów repozytoriów (JSON + ETag + znacznik czasu) |
274 -| `/etc/pag/repos.conf` i `/etc/pag/repos/*.conf` | Repozytoria (drop-in) |
275 -| `/etc/pag/trusted.json` | Przypięte fingerprinty kluczy repo |
276 -| `/etc/pag/gpg/` | Izolowany keyring GPG |
277 -| `/etc/pag/triggers/*.json` | Własne triggery |
278 -| `/etc/pag/lang/`, `/usr/share/pag/lang/` | Tłumaczenia (pliki nadpisują wbudowane) |
279 -| `/var/log/pag/audit.log` | Audyt: hooki, self-update |
280 -| `/.pag_staging` | Staging (ta sama partycja co `/` – brak `EXDEV`) |
281 -| `/.deployments/` | Wdrożenia (tryb immutable) |
282 -
283 -
284 -## Format pakietu
285 -
286 -Pakiet `.pag` to archiwum zawierające:
287 -
288 -```
289 -metadata.json – nazwa, wersja, release, zależności, provides/requires (so-name)
290 -data.tar.xz – pliki systemu + sums.json (SHA256 per plik)
291 -hooks/ – opcjonalne: pre-install, post-install, pre-remove, post-remove
292 -```
293 -
294 -Instalacja jest **weryfikowana per-plik** względem `sums.json`, a rozpakowanie
295 -chroni przed *directory traversal* i ucieczką przez złośliwe symlinki.
296 -
297 -
298 -## Hooki i triggery
299 -
300 -**Hooki** uruchamiane są jako `root` (jak w apt/pacman), w ograniczonym
301 -środowisku:
302 -
303 -- `pre-install`, `post-install`, `pre-remove`, `post-remove`
304 -- czyste env: `PATH`, `HOME=/root`, `LANG/LC_ALL=C.UTF-8`, `PKG_NAME`,
305 - `PKG_VERSION`, `PKG_ACTION`, `PKG_HOOK_API=1`
306 -- timeout (`PAG_HOOK_TIMEOUT`), możliwość wyłączenia (`PAG_NO_HOOKS=1`),
307 - wpisy w `/var/log/pag/audit.log` i w historii transakcji
308 -
309 -Instalujesz kod, któremu ufasz – hooki mają pełne uprawnienia.
310 -
311 -**Triggery** uruchamiane są **raz na transakcję**, gdy dotknięto pasujących
312 -ścieżek (tylko jeśli dana binarka istnieje):
313 -
314 -| Trigger | Ścieżki | Komenda |
315 -|---|---|---|
316 -| `font-cache` | `/usr/share/fonts/`, `/usr/local/share/fonts/` | `fc-cache -fs` |
317 -| `glib-schemas` | `/usr/share/glib-2.0/schemas/` | `glib-compile-schemas …` |
318 -| `desktop-database` | `/usr/share/applications/` | `update-desktop-database -q …` |
319 -| `mime-database` | `/usr/share/mime/` | `update-mime-database …` |
320 -
321 -Własne triggery dodasz jako `/etc/pag/triggers/*.json`.
322 -
323 -
324 -## Konfiguracja `/etc` – `.pacnew` / `.pacsave`
325 -
326 -Katalog `/etc` jest współdzielony między wdrożeniami (nie cofa się przy
327 -`deploy-rollback`). Aby nie tracić zmian użytkownika:
328 -
329 -- **Aktualizacja** pliku konfiguracyjnego, który użytkownik zmodyfikował:
330 - nowa wersja trafia jako `<plik>.pacnew`, a plik użytkownika **zostaje**.
331 -- **Usunięcie** pakietu ze zmodyfikowanym plikiem konfiguracyjnym: plik trafia
332 - jako `<plik>.pacsave` zamiast zostać skasowany.
333 -
334 -Porównanie odbywa się względem sumy SHA256 z chwili instalacji.
335 -
336 -
337 -## Przykłady
338 -
339 -```bash
340 -# Instalacja i aktualizacje
341 -sudo pag install firefox gimp
342 -sudo pag update # same pakiety
343 -sudo pag upgrade # pakiety + kernel/initramfs/GRUB
344 -sudo pag sync # odśwież indeksy + info o aktualizacjach
345 -
346 -# Naprawa pakietu (brakujące pliki/katalogi, np. /etc/pulse/default.pa.d)
347 -sudo pag install -f pulseaudio
348 -
349 -# Ikony aplikacji po instalacji motywu (cache budowany automatycznie)
350 -sudo pag install papirus-icon-theme
351 -
352 -# Bezpieczeństwo
353 -sudo pag key-add https://repo.paganlinux.eu/stable/paganos.asc
354 -sudo pag key-trust https://repo.paganlinux.eu/stable/
355 -sudo pag verify --deep
356 -
357 -# Zależności i pochodzenie pakietów
358 -sudo pag why libjpeg-turbo
359 -sudo pag autoremove
360 -
361 -# SBOM dla audytu / compliance
362 -sudo pag sbom export cyclonedx > sbom.json
363 -
364 -# Cofnij ostatnią transakcję
365 -sudo pag rollback
366 -```
367 -
368 -
369 -## Diagnostyka
370 -
371 -| Objaw | Rozwiązanie |
372 -|---|---|
373 -| „Inna instancja pag jest uruchomiona” | Działa inny proces `pag` (blokada `flock`). Poczekaj lub sprawdź `pgrep -af pag`. |
374 -| „Nie można odświeżyć indeksu” | Cache repo jest tylko-do-odczytu dla zwykłego usera – uruchom jako root: `sudo pag sync`. |
375 -| „Nieprawidłowy podpis / brak podpisu” | Zaimportuj klucz: `sudo pag key-add <url>`, potem zweryfikuj `sudo pag key-trusted`. |
376 -| Brakujące pliki/katalogi po instalacji | `sudo pag install -f <pkg>` (odtwarza pliki, puste katalogi i hooki). |
377 -| System nie bootuje po `grub-update` | Ustaw jawnie urządzenie root: `PAG_ROOT_DEVICE=/dev/sda2 sudo pag grub-update`. |
378 -| Aplikacja z Flathuba niewidoczna w menu | Dodaj `/var/lib/flatpak/exports/share` do `XDG_DATA_DIRS` i zaloguj się ponownie. |
379 -
380 -
381 -## Instalacja i aktualizacja
382 -
383 -```bash
384 -# Na działającym PaganOS pag jest w repo bazowym:
385 -sudo pag install pag # instalacja z repozytorium
386 -sudo pag self-update # aktualizacja samego klienta (podpisana)
387 -
388 -# pag jest też zarządzany przez menedżera pakietów – po publikacji nowej
389 -# wersji w repo:
390 -sudo pag update
391 -sudo pag upgrade
392 -```
393 -
394 -
395 -## Licencja
396 -
397 -PaganOS / pag – projekt open source. Szczegóły w repozytorium dystrybucji.