# Développement

> HTML: https://remote.ivjn.us/docs/fr/development/

Ce document explique comment compiler et tester ce dépôt, puis lancer exchange localement. Les étapes de déploiement, les champs du protocole et les détails d'installation par plateforme restent décrits dans les documents spécialisés liés en fin de page.

## Chaîne d'outils

L'espace de travail utilise Rust 2021 et exige **Rust 1.88 ou ultérieur**. La version figure dans le champ `rust-version` du `Cargo.toml` à la racine.

## Espace de travail et exécutables

L’espace de travail Rust comprend neuf membres : huit dans `crates/` et le SDK d’extensions dans `sdk/extend/rust`. Les types du protocole sont définis uniquement dans `crates/proto` ; `exchange`, `agent` et `cli` dépendent tous de cette crate. Ne dupliquez pas les structures de messages dans un composant.

| crate | Chemin | Résultat |
|---|---|---|
| `proto` | `crates/proto` | Bibliothèque. Messages de contrôle, trames binaires et structures partagées sont définis uniquement ici |
| `exchange` | `crates/exchange` | Exécutable `exchange` (même nom que le paquet) |
| `agent` | `crates/agent` | Exécutable `remote-agent` |
| `cli` | `crates/cli` | Exécutable `remote-cli` |
| `updater` | `crates/updater` | Bibliothèque de mise à jour automatique pour `remote-agent` et `remote-cli` |
| `telemetry` | `crates/telemetry` | Bibliothèque de remontée des erreurs et journaux partagée par les trois composants |
| `tls-client` | `crates/tls-client` | Politique TLS rustls commune aux clients et connexions proxy facultatives |
| `worker-proto` | `crates/worker-proto` | Validation du protocole et hachage des identifiants de Workers Exchange |
| `remote-extend-sdk` | `sdk/extend/rust` | Bibliothèque de trames et contrats des fournisseurs d’extensions |

Le point d'entrée d'`exchange` est `crates/exchange/src/main.rs`. Sans table `[[bin]]` distincte, `cargo build -p exchange` produit donc `exchange`. Les `Cargo.toml` d'`agent` et de `cli` nomment leurs exécutables `remote-agent` et `remote-cli`.

La table des connexions sépare les responsabilités :

- `crates/exchange/src/hub.rs` gère les appareils en ligne, le remplacement des anciennes connexions lors des reconnexions et les identifiants de génération (epoch).
- `crates/exchange/src/hub/session_table.rs` traduit les identifiants de session entre opérateurs et appareils.
- `crates/exchange/src/hub/outbound.rs` gère la file d'envoi bornée de chaque connexion.

## Compilation

Exécutez les commandes à la racine du dépôt.

Le profil de publication (`opt-level = 2`, LTO en mode thin, déroulement de pile conservé) compile le serveur, la ligne de commande et l'agent :

```bash
cargo build --release
```

Les exécutables se trouvent dans :

- `target/release/exchange`
- `target/release/remote-cli`
- `target/release/remote-agent`

`release` conserve le déroulement de pile, car exchange est un processus persistant à connexions multiples. Si une tâche de connexion panique, tokio peut ainsi arrêter cette seule tâche sans interrompre les sessions des autres appareils dans le même processus.

L'appareil dispose aussi d'un profil privilégiant la taille (`opt-level = "z"`, LTO, `panic = "abort"`, `strip`, `codegen-units = 1`) :

```bash
cargo build -p agent --no-default-features --profile release-small
```

Le résultat est `target/release-small/remote-agent`. procd, systemd ou une tâche planifiée relance l'agent après un plantage ; `panic = "abort"` permet donc ici de réduire sa taille.

La base de données n'intervient pas dans la compilation. `crates/exchange/src/db.rs` utilise les requêtes sqlx à l'exécution, sans macro `query!` : `cargo build` fonctionne sans base de données.

## Tests

```bash
cargo test --workspace
```

Windows n'exécute pas les tests qui dépendent d'Unix `/bin/sh` (ou de `/bin/ash` sur OpenWrt) et des PTY. Le module de tests de `crates/agent/src/pty.rs` est protégé par `#[cfg(all(test, unix))]` et n'est pas compilé hors Unix. L'implémentation PTY essaie successivement `/bin/ash` et `/bin/sh`. Les chemins de groupes de processus et de signaux Unix dans `exec.rs` ne sont compilés que sous Unix ; sous Windows, les tests de commandes utilisent PowerShell sans appeler `/bin/sh`. Après modification des chemins Unix d'`exec.rs` ou `pty.rs`, relancez `cargo test --workspace` sous Linux : le résultat Windows seul ne suffit pas.

Pour cibler une crate, utilisez par exemple `cargo test -p proto` ou `cargo test -p exchange -- hub::`.

## Lancer exchange localement

Préparez PostgreSQL, puis placez la chaîne de connexion dans `DATABASE_URL`. Cette variable correspond à `--database-url` d'`exchange` (voir `crates/exchange/src/config.rs`). Au démarrage, `db::connect` exécute les migrations intégrées à la compilation :

```rust
sqlx::migrate!("../../migrations")
```

Les migrations sont dans `migrations/` à la racine et s'exécutent automatiquement au démarrage, sans sqlx-cli.

Les opérations d’audit nécessitent aussi une clé de chiffrement. Les exemples ci-dessous génèrent une clé de test locale. Conservez-la en lieu sûr et réutilisez-la aux démarrages suivants ; une nouvelle clé à chaque démarrage empêche de déchiffrer les détails d’audit existants.

```bash
export DATABASE_URL='postgres://luci:luci@127.0.0.1:5432/luci'
export AUDIT_ENCRYPTION_KEY="$(python -c 'import base64, secrets; print(base64.b64encode(secrets.token_bytes(32)).decode())')"
cargo run -p exchange -- --listen 127.0.0.1:8080
```

Sous PowerShell, définissez la variable avant le lancement :

```powershell
$env:DATABASE_URL = "postgres://luci:luci@127.0.0.1:5432/luci"
$env:AUDIT_ENCRYPTION_KEY = python -c "import base64, secrets; print(base64.b64encode(secrets.token_bytes(32)).decode())"
cargo run -p exchange -- --listen 127.0.0.1:8080
```

Si l'exécutable de publication est déjà compilé, remplacez `cargo run -p exchange --` par `./target/release/exchange`. L'adresse d'écoute par défaut est `0.0.0.0:8080` ; pour le débogage local, liez-la explicitement à `127.0.0.1`.

Lorsqu'aucun compte opérateur actif n'existe dans la base, le démarrage crée un administrateur et affiche son jeton dans les journaux de ce démarrage uniquement. Le texte en clair n'apparaît qu'une fois. Le déploiement complet, le proxy inverse et les comptes sont décrits dans `docs/deployment.md` du dépôt. Cette page contient des adresses de serveur et n'est pas publiée sur ce site.

## Contrôles avant commit

Exécutez ces contrôles à la racine du dépôt. Pour Rust, commencez par les tests ciblés du crate, puis vérifiez le workspace. Si le formatage détecte des écarts existants sans rapport avec la modification, formatez uniquement les fichiers modifiés. Android, l’extension de navigateur et la console mobile nécessitent aussi leurs propres compilations et tests ; les tests Rust ne couvrent pas ces interfaces.

```sh
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
```

## Maintenir la documentation

Vérifiez le comportement de l’implémentation avant de modifier les guides dans `docs/`. Les articles du site possèdent une source de référence dans `website/docs/<topic>.md` et neuf traductions dans `website/docs/content/<locale>/<topic>.md`. Alignez commandes, champs, exemples et niveaux de titres. Générez les pages et index de recherche avec le script plutôt que de modifier uniquement le HTML. Exécutez les commandes suivantes à la racine avec Python 3.11+, markdown-it-py et Node.js installés :

```sh
python -m pip install markdown-it-py
python scripts/build-docs.py
python scripts/build-docs.py --check
python scripts/test-docs.py
python scripts/test-docs-markdown.py
node scripts/test-docs-locale.js
python scripts/test-build-docs.py
python scripts/test-site-seo.py
```

Le contrôle de génération compare aussi chaque fichier produit octet par octet et échoue si une sortie manque ou est périmée, sans écrire de fichier. La CI le lance avant toute régénération.

Les contrôles valident les traductions complètes, exemples, titres, liens, ancres et routes linguistiques. Commitez les pages générées avec leurs sources. La génération ne modifie que les fichiers locaux ; le déploiement du site et la publication des téléchargements sont des opérations séparées.

## Documents associés

- [Notes techniques](/docs/fr/architecture.md) : connexions sortantes, traduction des sessions, epoch, files bornées et stockage des jetons.
- [Utilisation](/docs/fr/getting-started.md) : connexion, ajout d'appareil, lancement de l'agent, commandes et shell.
- Guide de déploiement dans `docs/deployment.md` du dépôt (adresses de serveur, non publié sur ce site).
- [Protocole réseau](/docs/fr/websocket-protocol.md)
- [Déploiement multiplateforme](/docs/fr/platform-installation.md)
