diff --git a/.cargo/config.toml b/.cargo/config.toml index f714b6d..8149ba4 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,5 +1,5 @@ -# Les cibles musl embarquent leur CRT (self-contained) : rust-lld suffit pour -# lier un binaire statique, y compris en compilation croisée depuis arm64. +# musl targets ship their own CRT (self-contained): rust-lld is enough to link +# a static binary, including when cross-compiling from arm64. [target.x86_64-unknown-linux-musl] linker = "rust-lld" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c007afc..a51bc74 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: targets: x86_64-unknown-linux-musl - uses: Swatinem/rust-cache@v2 - run: cargo build --release --target x86_64-unknown-linux-musl - - name: Vérifier que le binaire est statique + - name: Check that the binary is static run: | bin=target/x86_64-unknown-linux-musl/release/envprobe file "$bin" @@ -51,25 +51,25 @@ jobs: with: name: envprobe-x86_64-linux-musl - run: chmod +x envprobe - - name: Utilisateur normal + - name: Normal user run: ./envprobe | tee user.txt - name: Root run: sudo ./envprobe | tee root.txt - - name: La sortie diffère selon les privilèges + - name: Output differs with privileges run: | ! diff -q user.txt root.txt - grep -E '^ CAP_BPF +non' user.txt - grep -E '^ CAP_BPF +oui' root.txt - - name: Conteneurs Docker par défaut + grep -E '^ CAP_BPF +no' user.txt + grep -E '^ CAP_BPF +yes' root.txt + - name: Default Docker containers run: | for image in debian:12 alpine:3.20 rockylinux:9; do echo "::group::$image" docker run --rm -v "$PWD/envprobe:/envprobe:ro" "$image" /envprobe | tee "docker-${image%%:*}.txt" grep -E '^ container +docker' "docker-${image%%:*}.txt" - grep -E '^ seccomp +filtre' "docker-${image%%:*}.txt" + grep -E '^ seccomp +filter' "docker-${image%%:*}.txt" echo "::endgroup::" done - - name: Rapports JSON et diff hôte / Alpine + - name: JSON reports and host / Alpine diff run: | ./envprobe --json > host.json sudo ./envprobe --json > host-root.json @@ -85,8 +85,8 @@ jobs: grep -q '^\[libc\]' diff.txt grep -q '^\[shell\]' diff.txt grep -q '^\[packages\]' diff.txt - # Même noyau : la release ne change pas. La config peut manquer dans - # le conteneur (/boot absent), d'où la vérification sur release seule. + # Same kernel: the release does not change. The config can be missing in + # the container (no /boot), hence the check on release only. ! grep -qE '^[-+] release ' diff.txt - uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/matrix.yml b/.github/workflows/matrix.yml index d72dce9..a2cd488 100644 --- a/.github/workflows/matrix.yml +++ b/.github/workflows/matrix.yml @@ -1,7 +1,7 @@ -name: Matrice +name: Matrix -# Dogfooding : distroproof lance envprobe dans des VM de chaque distro cible -# (distroproof.toml) et publie un résumé Markdown sur la PR. +# Dogfooding: distroproof runs envprobe in VMs of each target distro +# (distroproof.toml) and posts a Markdown summary on the PR. on: pull_request: @@ -21,7 +21,7 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Activer KVM + - name: Enable KVM run: | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' \ | sudo tee /etc/udev/rules.d/99-kvm4all.rules @@ -29,7 +29,7 @@ jobs: sudo udevadm trigger --name-match=kvm ls -l /dev/kvm - - name: Installer QEMU et OVMF + - name: Install QEMU and OVMF run: | sudo apt-get update sudo apt-get install -y --no-install-recommends qemu-system-x86 qemu-utils ovmf @@ -40,8 +40,8 @@ jobs: - uses: Swatinem/rust-cache@v2 - run: cargo build --release --target x86_64-unknown-linux-musl - # Images cloud et noyaux extraits : renouvelés chaque semaine pour - # suivre les mises à jour des distros. + # Cloud images and extracted kernels: renewed every week to follow + # distro updates. - id: week run: echo "week=$(date +%G-%V)" >> "$GITHUB_OUTPUT" - uses: actions/cache@v4 @@ -50,18 +50,18 @@ jobs: key: distroproof-images-${{ steps.week.outputs.week }}-${{ hashFiles('distroproof.toml') }} restore-keys: distroproof-images- - - name: Lancer la matrice + - name: Run the matrix run: | set +e target/x86_64-unknown-linux-musl/release/distroproof up --no-tui --jobs 3 \ --json matrix.json --junit junit.xml --markdown summary.md echo "code=$?" >> "$GITHUB_ENV" - - name: Résumé + - name: Summary if: always() run: cat summary.md >> "$GITHUB_STEP_SUMMARY" - - name: Commentaire de PR + - name: PR comment if: always() && github.event_name == 'pull_request' continue-on-error: true env: @@ -79,5 +79,5 @@ jobs: junit.xml summary.md - - name: Code de sortie de la matrice + - name: Matrix exit code run: exit "$code" diff --git a/Cargo.toml b/Cargo.toml index cd6c762..f2339bd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ members = ["crates/envprobe-core", "crates/envprobe", "crates/distroproof"] version = "0.1.0" edition = "2021" license = "MIT OR Apache-2.0" -repository = "https://github.com/moha-bekh/distroproof" +repository = "https://github.com/devutils-org/distroproof" [workspace.dependencies] envprobe-core = { path = "crates/envprobe-core" } @@ -25,7 +25,7 @@ toml = "1" tui-term = "0.3" vt100 = "0.16" -# Le hachage des images (plusieurs centaines de Mio) reste rapide en debug. +# Keeps image hashing (several hundred MiB) fast in debug builds. [profile.dev.package.sha2] opt-level = 3 diff --git a/README.md b/README.md index e59db85..b0d9e8f 100644 --- a/README.md +++ b/README.md @@ -1,72 +1,71 @@ # distroproof -[![CI](https://github.com/moha-bekh/distroproof/actions/workflows/ci.yml/badge.svg)](https://github.com/moha-bekh/distroproof/actions/workflows/ci.yml) +[![CI](https://github.com/devutils-org/distroproof/actions/workflows/ci.yml/badge.svg)](https://github.com/devutils-org/distroproof/actions/workflows/ci.yml) -> distroless retire la distro de ton image. distroproof vérifie que ton -> programme tient sur toutes les distros. +> distroless takes the distro out of your image. distroproof checks that your +> program holds up on every distro. -Un programme qui marche sur ta machine peut casser ailleurs : musl au lieu de -glibc, noyau RHEL 4.18, BTF absent, `perf_event_paranoid` à 3, lockdown actif… -distroproof décrit précisément un environnement Linux (userspace et noyau), -lance ton programme dans des VM qui tournent avec le **vrai noyau** de chaque -distro cible, puis relie chaque échec à la différence d'environnement qui -l'explique. +A program that works on your machine can break elsewhere: musl instead of +glibc, a RHEL 4.18 kernel, no BTF, `perf_event_paranoid` set to 3, lockdown +enabled… distroproof describes a Linux environment precisely (userspace and +kernel), runs your program in VMs booted on the **real kernel** of each target +distro, then ties every failure to the environment difference that explains +it. -Toutes les phases du POC sont implémentées : la sonde `envprobe` (utilisable -seule) et l'orchestrateur `distroproof` (VM, matrice, rapport, TUI). +Every phase of the POC is implemented: the `envprobe` probe (usable on its +own) and the `distroproof` orchestrator (VMs, matrix, report, TUI). -## Avancement +## Status -| Phase | Contenu | État | +| Phase | Scope | Status | | --- | --- | --- | -| 0 | Workspace, binaire statique musl, CI | ✅ | -| 1 | Sonde `envprobe` : 18 catégories (kernel, BPF, perf, LSM, libc…) | ✅ | -| 2 | Rapport JSON versionné, schéma publié, `envprobe diff` | ✅ | -| 3 | VM QEMU/KVM avec noyau et rootfs de distro | ✅ | -| 4 | Matrice déclarative `distroproof.toml` | ✅ | -| 5 | Rapport de matrice, corrélation des échecs, JUnit / Markdown | ✅ | -| 6 | TUI de monitoring | ✅ | - -Détail et critères de sortie : [docs/ROADMAP.md](docs/ROADMAP.md). Démo de bout en bout -sur de vraies VM : [`scripts/demo.sh`](scripts/demo.sh) et +| 0 | Workspace, static musl binary, CI | ✅ | +| 1 | `envprobe` probe: 18 categories (kernel, BPF, perf, LSM, libc…) | ✅ | +| 2 | Versioned JSON report, published schema, `envprobe diff` | ✅ | +| 3 | QEMU/KVM VMs with the distro's kernel and rootfs | ✅ | +| 4 | Declarative matrix in `distroproof.toml` | ✅ | +| 5 | Matrix report, failure correlation, JUnit / Markdown | ✅ | +| 6 | Monitoring TUI | ✅ | + +Details and exit criteria: [docs/ROADMAP.md](docs/ROADMAP.md). End-to-end +demo on real VMs: [`scripts/demo.sh`](scripts/demo.sh) and [docs/how-to-use/demo.md](docs/how-to-use/demo.md). ## Crates -| Crate | Rôle | +| Crate | Role | | --- | --- | -| `envprobe-core` | Bibliothèque des sondes, modèle du rapport, diff | -| `envprobe` | CLI de la sonde | -| `distroproof` | Orchestrateur de VM, matrice, rapport et TUI | +| `envprobe-core` | Probe library, report model, diff | +| `envprobe` | Probe CLI | +| `distroproof` | VM orchestrator, matrix, report and TUI | ## envprobe -`envprobe` liste tout ce qui peut changer le comportement d'un programme -userspace ou kernel-facing : +`envprobe` lists everything that can change how a userspace or kernel-facing +program behaves: -- **Identité** : distro, famille, arch, virtualisation, conteneur. -- **Noyau** : release, cmdline, config (`CONFIG_BPF*`, `KPROBES`, `DEBUG_INFO_BTF`…), modules. -- **Sécurité et privilèges** : sysctls, LSM, SELinux, AppArmor, lockdown, Secure Boot, - capabilities, seccomp, user namespace. -- **BPF et perf** : types de programmes, types de maps et helpers, sondés par de - vrais appels `bpf()` ; `perf_event_open` logiciel et matériel, PMU ; tracefs, kallsyms, BTF. -- **Userspace** : libc et sa version, bibliothèques courantes, FHS (merged-usr, - multiarch), `/bin/sh`, coreutils, init, gestionnaire de paquets, cgroups, XDG. +- **Identity**: distro, family, arch, virtualization, container. +- **Kernel**: release, cmdline, config (`CONFIG_BPF*`, `KPROBES`, `DEBUG_INFO_BTF`…), modules. +- **Security and privileges**: sysctls, LSM, SELinux, AppArmor, lockdown, Secure Boot, + capabilities, seccomp, user namespaces. +- **BPF and perf**: program types, map types and helpers, probed with real + `bpf()` calls; software and hardware `perf_event_open`, PMU; tracefs, kallsyms, BTF. +- **Userspace**: libc and its version, common libraries, FHS (merged-usr, + multiarch), `/bin/sh`, coreutils, init, package manager, cgroups, XDG. -Les fonctionnalités sont sondées directement, jamais déduites d'un numéro de -version, car les noyaux RHEL rétroportent beaucoup. La sonde est en lecture -seule et ne plante jamais : une information absente ou refusée apparaît avec -sa raison. +Features are probed directly, never inferred from a version number, because +RHEL kernels backport a lot. The probe is read-only and never crashes: missing +or denied information shows up with its reason. ```sh -envprobe # résumé lisible -envprobe --json # rapport complet -envprobe --json --section kernel,bpf # sections choisies -envprobe diff a.json b.json # différences, code de sortie 1 s'il y en a -envprobe schema # schéma JSON du rapport +envprobe # human-readable summary +envprobe --json # full report +envprobe --json --section kernel,bpf # selected sections +envprobe diff a.json b.json # differences, exit code 1 if any +envprobe schema # JSON schema of the report ``` -Extrait d'un diff entre un hôte Arch et un rootfs Alpine (même noyau) : +Excerpt of a diff between an Arch host and an Alpine rootfs (same kernel): ```text [libc] @@ -84,84 +83,83 @@ Extrait d'un diff entre un hôte Arch et un rootfs Alpine (même noyau) : + managers apk ``` -### Format du rapport +### Report format -Chaque entrée porte un statut : +Each entry carries a status: -- `ok` : la valeur. -- `unavailable` : information absente, avec la raison (fichier absent, syscall inexistant…). -- `denied` : accès refusé (EPERM, EACCES, seccomp…). +- `ok`: the value. +- `unavailable`: information missing, with the reason (file absent, syscall not implemented…). +- `denied`: access refused (EPERM, EACCES, seccomp…). -Le champ `privileged` signale les résultats qui changent selon les droits du -processus. Le format est versionné (`schema_version`) et son schéma est publié -dans [`schema/envprobe-report.schema.json`](schema/envprobe-report.schema.json). +The `privileged` field flags results that depend on the process's privileges. +The format is versioned (`schema_version`) and its schema is published in +[`schema/envprobe-report.schema.json`](schema/envprobe-report.schema.json). -### Sonder une autre distro sans VM +### Probing another distro without a VM -Pour comparer l'userspace d'une autre distro sans VM ni Docker (le noyau reste -celui de l'hôte) : +To compare another distro's userspace without a VM or Docker (the kernel stays +the host's): ```sh -scripts/probe-rootfs.sh --json +scripts/probe-rootfs.sh --json ``` -Le script lance la sonde dans des namespaces user, mount et pid, sans root. +The script runs the probe in user, mount and pid namespaces, without root. ## distroproof -`distroproof` démarre de vraies VM QEMU/KVM sur les images cloud officielles -de chaque distro : c'est **le noyau de la distro** qui tourne (4.18 sur -Rocky 8, 5.14 sur Rocky 9…), pas celui de l'hôte. +`distroproof` boots real QEMU/KVM VMs from each distro's official cloud +images: it is **the distro's kernel** that runs (4.18 on Rocky 8, 5.14 on +Rocky 9…), not the host's. ```sh distroproof run --target rocky-8 -- envprobe --json > rocky8.json -distroproof up # matrice de distroproof.toml -distroproof check # valide le fichier sans lancer de VM -distroproof images # catalogue et état du cache +distroproof up # matrix from distroproof.toml +distroproof check # validate the file without starting VMs +distroproof images # catalog and cache status distroproof report matrix.json --format markdown ``` -Prérequis sur l'hôte : `qemu-system-x86_64`, `qemu-img`, `curl`, KVM -(`/dev/kvm`, repli automatique sur TCG sinon) et OVMF (`edk2-ovmf`, `ovmf`) -pour les images qui ne démarrent qu'en UEFI. Les binaires se choisissent avec `DISTROPROOF_QEMU`, -`DISTROPROOF_QEMU_IMG`, `DISTROPROOF_OVMF_CODE` et `DISTROPROOF_OVMF_VARS`. +Host requirements: `qemu-system-x86_64`, `qemu-img`, `curl`, KVM (`/dev/kvm`, +automatic fallback to TCG otherwise) and OVMF (`edk2-ovmf`, `ovmf`) for images +that only boot with UEFI. Binaries can be chosen with `DISTROPROOF_QEMU`, +`DISTROPROOF_QEMU_IMG`, `DISTROPROOF_OVMF_CODE` and `DISTROPROOF_OVMF_VARS`. -### Cibles +### Targets -| Image | Noyau observé | Remarque | +| Image | Observed kernel | Notes | | --- | --- | --- | -| `debian-10`, `debian-11`, `debian-12`, `debian-13` | 4.19, 5.10, 6.1, 6.12 | 4.19 sans BTF ; 13 démarre en UEFI | -| `ubuntu-18.04`, `ubuntu-20.04`, `ubuntu-22.04`, `ubuntu-24.04` | 4.15, 5.4, 5.15, 6.8 | 4.15 sans BTF | -| `rocky-8`, `rocky-9` | 4.18, 5.14 | noyaux RHEL avec backports ; 9 démarre en UEFI | -| `fedora-latest` | 6.19 (Fedora 44) | dernière release, résolue en ligne | +| `debian-10`, `debian-11`, `debian-12`, `debian-13` | 4.19, 5.10, 6.1, 6.12 | 4.19 without BTF; 13 boots with UEFI | +| `ubuntu-18.04`, `ubuntu-20.04`, `ubuntu-22.04`, `ubuntu-24.04` | 4.15, 5.4, 5.15, 6.8 | 4.15 without BTF | +| `rocky-8`, `rocky-9` | 4.18, 5.14 | RHEL kernels with backports; 9 boots with UEFI | +| `fedora-latest` | 6.19 (Fedora 44) | latest release, resolved online | | `arch` | rolling | | | `alpine` | 6.18 `virt` | musl, busybox | -Les images sont téléchargées une fois, vérifiées contre le checksum publié -par la distro et gardées dans `$XDG_CACHE_HOME/distroproof/images`. Chaque -exécution travaille sur un overlay qcow2 jetable, supprimé à la fin, même -après un timeout ou un Ctrl+C ; QEMU meurt avec distroproof. - -### Fonctionnement - -- QEMU démarre en pause (`-S`), distroproof se connecte à son socket QMP et - aux deux ports série (console sur ttyS0, canal de l'agent sur ttyS1), puis - lance la VM. -- cloud-init (seed NoCloud écrit en Rust) extrait un disque payload (archive - tar brute : agent, `envprobe` statique, répertoire de travail) et lance - l'agent. Celui-ci applique les sysctls, crée l'utilisateur de test, lance - `envprobe` puis la commande, et relaie stdout et stderr ligne à ligne. -- Les sorties complètes, les codes de retour et le rapport sont écrits sur un - disque de sortie (tar brut), puis la VM s'éteint. Pas de 9p ni de virtiofs, - absents des noyaux RHEL. -- Au premier boot, l'agent extrait aussi noyau et initramfs : les exécutions - suivantes bootent en direct (`-kernel`), en 6 à 13 s, et peuvent modifier - la ligne de commande du noyau. -- L'orchestrateur n'écrit jamais dans le terminal : il émet des événements - typés (`Booting`, `Output`, `Metrics`, `Finished`…) que la sortie texte, - la sortie JSON (`--progress json`) et la TUI consomment. - -### Matrice : `distroproof.toml` +Images are downloaded once, verified against the checksum published by the +distro and kept in `$XDG_CACHE_HOME/distroproof/images`. Each run works on a +throwaway qcow2 overlay that is deleted at the end, even after a timeout or a +Ctrl+C; QEMU dies with distroproof. + +### How it works + +- QEMU starts paused (`-S`); distroproof connects to its QMP socket and to the + two serial ports (console on ttyS0, agent channel on ttyS1), then starts the + VM. +- cloud-init (NoCloud seed written in Rust) extracts a payload disk (raw tar + archive: agent, static `envprobe`, working directory) and starts the agent. + The agent applies the sysctls, creates the test user, runs `envprobe` then + the command, and relays stdout and stderr line by line. +- Full outputs, exit codes and the report are written to an output disk (raw + tar), then the VM shuts down. No 9p or virtiofs, which RHEL kernels lack. +- On first boot, the agent also extracts the kernel and initramfs: later runs + boot directly (`-kernel`) in 6 to 13 s and can change the kernel command + line. +- The orchestrator never writes to the terminal: it emits typed events + (`Booting`, `Output`, `Metrics`, `Finished`…) consumed by the text output, + the JSON output (`--progress json`) and the TUI. + +### Matrix: `distroproof.toml` ```toml [defaults] @@ -187,64 +185,64 @@ kernel_cmdline = "lockdown=confidentiality" name = "debian-nopmu" image = "debian-12" pmu = false # -cpu host,pmu=off -caps = ["perfmon", "bpf"] # capabilities de l'utilisateur de test +caps = ["perfmon", "bpf"] # capabilities of the test user [run] -setup = "./scripts/install-deps.sh" # en root, avant la sonde -command = "./target/release/montool --selftest" -as_user = "test" # ou "root" -# exclude = [".git", "target"] # copié dans /distroproof/work -# include = ["target/release/montool"] +setup = "./scripts/install-deps.sh" # as root, before the probe +command = "./target/release/mytool --selftest" +as_user = "test" # or "root" +# exclude = [".git", "target"] # copied to /distroproof/work +# include = ["target/release/mytool"] ``` -Une erreur (clé inconnue, image inexistante, durée invalide…) est signalée -avec sa ligne et sa colonne, sans lancer de VM. `distroproof up` lance les -cibles en parallèle (`--jobs`), joint à chaque résultat le rapport `envprobe` -pris juste avant la commande, puis : +Errors (unknown key, nonexistent image, invalid duration…) are reported with +their line and column, without starting any VM. `distroproof up` runs the +targets in parallel (`--jobs`), attaches to each result the `envprobe` report +taken right before the command, then: -- affiche le tableau cibles × résultat, avec durée, temps de boot, noyau et - extrait de stderr ; -- compare chaque cible en échec à la cible réussie la plus proche et désigne - la différence suspecte (BTF absent, paranoid à 3, musl…) ; -- écrit si demandé `--json`, `--junit` (CI) et `--markdown` (commentaire de PR). +- prints the targets × result table, with duration, boot time, kernel and a + stderr excerpt; +- compares each failed target with the closest successful one and points out + the suspicious difference (missing BTF, paranoid set to 3, musl…); +- writes `--json`, `--junit` (CI) and `--markdown` (PR comment) on request. ```text -[ubuntu-18.04] échec (code 1) - comparée à ubuntu-22.04 : 65 différences significatives - cause probable : btf.vmlinux : présent, 5286152 octets → indisponible (/sys/kernel/btf/vmlinux absent) - aussi : kernel.CONFIG_DEBUG_INFO_BTF : y → absente de la config +[ubuntu-18.04] failed (code 1) + compared with ubuntu-22.04: 65 significant differences + probable cause: btf.vmlinux: present, 5286152 bytes → unavailable (/sys/kernel/btf/vmlinux missing) + also: kernel.CONFIG_DEBUG_INFO_BTF: y → not in the config ``` -Exemples : [`distroproof.toml`](distroproof.toml) (dogfooding d'envprobe sur -10 cibles, lancé en CI par [`matrix.yml`](.github/workflows/matrix.yml)) et -[`examples/require-btf`](examples/require-btf) (échec volontaire sans BTF). +Examples: [`distroproof.toml`](distroproof.toml) (envprobe dogfooding on 10 +targets, run in CI by [`matrix.yml`](.github/workflows/matrix.yml)) and +[`examples/require-btf`](examples/require-btf) (deliberate failure without BTF). ### TUI -Dans un terminal, `distroproof up` ouvre une TUI (`--no-tui` pour la sortie -texte, automatique sans TTY) : une carte par cible avec état, temps de boot, -jauges CPU et mémoire et graphe Braille ; logs série en direct avec -recherche ; rapport `envprobe` replié par section et diff contre une autre -cible ; console série interactive. Avec `--hold`, chaque VM reste allumée -après la commande avec un shell root sur la console. +In a terminal, `distroproof up` opens a TUI (`--no-tui` for text output, +automatic without a TTY): one card per target with state, boot time, CPU and +memory gauges and a Braille graph; live serial logs with search; `envprobe` +report folded by section and diff against another target; interactive serial +console. With `--hold`, each VM stays up after the command with a root shell +on the console. -| Touche | Action | +| Key | Action | | --- | --- | -| `hjkl`, flèches | sélection, défilement | -| `espace`, `r`, `x` | pause / reprise (QMP), relance, kill | -| `c`, `i`, `Ctrl+]` | ouvrir la console, saisir, sortir | -| `/`, `n`, `N` | recherche dans les logs | -| `p` | épingler le panneau sur la cible sélectionnée | -| `d`, `D` | diff du rapport contre une autre cible | -| `D L R C` | vue dashboard, logs, rapport, console du panneau | -| `Ctrl+W` `s` `v` `q` `hjkl` `<>+-` | tiling : découper, fermer, focus, taille | -| `1`…`9` | workspaces (un par fichier avec plusieurs `-f`) | -| `f` | filtre : toutes, en cours, échecs, terminées | -| `:` ou `Ctrl+P` | palette de commandes | -| `?`, `q` | aide, quitter | - -Couleurs dans `$XDG_CONFIG_HOME/distroproof/theme.toml` (true color, repli -256 couleurs) : +| `hjkl`, arrows | selection, scrolling | +| `space`, `r`, `x` | pause / resume (QMP), restart, kill | +| `c`, `i`, `Ctrl+]` | open the console, type, leave | +| `/`, `n`, `N` | search the logs | +| `p` | pin the pane to the selected target | +| `d`, `D` | diff the report against another target | +| `D L R C` | pane view: dashboard, logs, report, console | +| `Ctrl+W` `s` `v` `q` `hjkl` `<>+-` | tiling: split, close, focus, resize | +| `1`…`9` | workspaces (one per file with several `-f`) | +| `f` | filter: all, running, failed, finished | +| `:` or `Ctrl+P` | command palette | +| `?`, `q` | help, quit | + +Colors live in `$XDG_CONFIG_HOME/distroproof/theme.toml` (true color, 256-color +fallback): ```toml [colors] @@ -260,13 +258,15 @@ rustup target add x86_64-unknown-linux-musl cargo build --release --target x86_64-unknown-linux-musl ``` -Les binaires sont statiques : `envprobe` tourne tel quel dans n'importe quelle -VM ou conteneur x86_64, et `distroproof` trouve l'`envprobe` posé à côté de lui. L'édition de liens passe par `rust-lld` (voir -`.cargo/config.toml`), ce qui permet aussi de compiler depuis arm64 vers x86_64. +The binaries are static: `envprobe` runs as is in any x86_64 VM or container, +and `distroproof` finds the `envprobe` sitting next to it. Linking goes +through `rust-lld` (see `.cargo/config.toml`), which also allows building for +x86_64 from arm64. -Tests : `cargo test --workspace`. Pour régénérer le schéma après un changement -du modèle : `UPDATE_SCHEMA=1 cargo test -p envprobe-core --test reports`. +Tests: `cargo test --workspace`. To regenerate the schema after changing the +model: `UPDATE_SCHEMA=1 cargo test -p envprobe-core --test reports`. -## Licence +## License -Au choix, sous [MIT](LICENSE-MIT) ou [Apache 2.0](LICENSE-APACHE). +Licensed under either [MIT](LICENSE-MIT) or [Apache 2.0](LICENSE-APACHE), at +your option. diff --git a/crates/distroproof/Cargo.toml b/crates/distroproof/Cargo.toml index 9b0e807..43863da 100644 --- a/crates/distroproof/Cargo.toml +++ b/crates/distroproof/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "distroproof" -description = "Lance un programme dans une matrice de VM de distros" +description = "Runs a program across a matrix of distro VMs" version.workspace = true edition.workspace = true license.workspace = true diff --git a/crates/distroproof/src/agent.sh b/crates/distroproof/src/agent.sh index 1adb661..59594d7 100644 --- a/crates/distroproof/src/agent.sh +++ b/crates/distroproof/src/agent.sh @@ -1,18 +1,18 @@ #!/bin/sh -# Agent invité de distroproof, lancé en root par cloud-init (runcmd) depuis le -# disque payload extrait dans /distroproof. +# distroproof guest agent, run as root by cloud-init (runcmd) from the payload +# disk extracted into /distroproof. # -# Canal vers l'hôte : /dev/ttyS1, une ligne par message. -# @ READY agent démarré -# @ STAGE <étape> début d'étape (setup, probe, command, kernel) -# @ EXIT <étape> fin d'étape -# @ WARN problème non bloquant (sysctl refusé…) -# @ DONE disque de sortie écrit, extinction imminente -# > stdout de l'étape en cours -# ! stderr de l'étape en cours +# Channel to the host: /dev/ttyS1, one line per message. +# @ READY agent started +# @ STAGE stage start (setup, probe, command, kernel) +# @ EXIT stage end +# @ WARN non-blocking problem (sysctl refused…) +# @ DONE output disk written, shutting down soon +# > stdout of the current stage +# ! stderr of the current stage # -# Les sorties complètes, les codes de retour et le rapport envprobe sont -# écrits dans une archive tar sur le disque de sortie (série dp-output). +# Full outputs, exit codes and the envprobe report are written to a tar +# archive on the output disk (serial dp-output). set -u D=/distroproof OUT=$D/out @@ -28,8 +28,8 @@ warn() { say WARN "$*"; echo "$*" >>"$OUT/warnings"; } mkdir -p "$OUT" say READY "$(cut -d' ' -f1 /proc/uptime)" -# Paramètres de la tâche : DP_USER, DP_CAPS, DP_PROBE, DP_EXTRACT_KERNEL, -# DP_SETUP, DP_COMMAND (1 si job/setup.sh, job/command.sh existent). +# Job parameters: DP_USER, DP_CAPS, DP_PROBE, DP_EXTRACT_KERNEL, +# DP_SETUP, DP_COMMAND (1 if job/setup.sh, job/command.sh exist). . $D/job/env disk() { @@ -48,8 +48,8 @@ relay() { done } -# run <étape> : sorties copiées dans $OUT/<étape>.{out,err} -# et relayées ligne à ligne sur le canal. +# run : outputs copied to $OUT/.{out,err} +# and relayed line by line on the channel. run() { stage=$1 shift @@ -68,19 +68,19 @@ run() { return $rc } -# Utilisateur de test. as_user