3.9 KiB
Vault DIR « Spark » — exclusions par vault et lecture seule déclarable
Objectif
Permettre d'exposer dans ObsiGate des répertoires techniques (code du
service d'agents, workspaces du compagnon, coquilles d'exécuteurs) sous un
vault DIR monté en lecture seule — le vault « Spark » — sans jamais
rendre visibles leurs zones sensibles (profils et clés des exécuteurs,
.home des workspaces, .venv, etc.).
Avant ce chantier, deux manques le bloquaient proprement :
- Les exclusions n'existaient qu'au niveau de l'indexeur (
IGNORED_DIRS, global) : la navigation et la lecture montraient le disque tel quel. - La lecture seule d'un vault n'était ni déclarable ni affichée : les
menus contextuels proposaient renommer / déplacer / supprimer, qui
échouaient ensuite côté serveur (montage
:ro).
Contrat de configuration (vaults DIR seulement)
Lues par load_vault_config() (backend/indexer.py, boucle DIR_N),
rangées dans le dict config du vault ; les vaults VAULT ne sont pas
touchés et les défauts (vide / faux) conservent le comportement actuel :
| Variable | Forme | Effet |
|---|---|---|
DIR_N_READONLY |
true / false |
Mutations refusées en 403 read_only ; readonly: true exposé par /api/vaults ; l'UI masque les actions d'écriture |
DIR_N_IGNORED_DIRS |
.home,.venv |
Noms de dossiers cachés à toute profondeur, en plus du global |
DIR_N_IGNORED_PATHS |
Executeurs/*/data,Executeurs/*/.env |
Motifs fnmatch sur le chemin relatif POSIX ; un dossier qui matche cache tout son sous-arbre |
Exemple visé pour le vault Spark :
DIR_1_NAME=Spark
DIR_1_PATH=/vaults/Spark
DIR_1_READONLY=true
DIR_1_IGNORED_DIRS=.home,.venv,__pycache__,node_modules,.git
DIR_1_IGNORED_PATHS=Executeurs/*/data,Executeurs/*/.env,*/compagnon.json
(le montage lui-même — volume :ro, arborescence assemblée sur l'hôte —
relève de la configuration de déploiement, pas d'ObsiGate.)
Implémentation
- Helper central :
chemin_exclu(vault_name, rel_path)etchemin_exclu_dans_config(config, rel_path)dansbackend/services/vaults.py— segment présent dansignoredDirs, ou fnmatch du chemin ou d'un de ses préfixes contreignoredPaths. Tolérant si vault / config absents.vault_readonly(vault_name)au même endroit. - Navigation :
browse_directoryfiltre les items exclus (et leurs compteurs d'enfants) ; naviguer directement dans un chemin exclu répond 404.list_all_filesetlist_pathsfiltrent aussi. - Lecture : un chemin exclu est indiscernable d'un chemin inexistant
(404, sans détail sur la règle) —
read_raw_file/read_file_text(backend/services/files.py), routeGET /api/file/{vault}et route de téléchargement (backend/routers/files_read.py). - Indexation : le scan (
_scan_vault, qui reçoit levault_cfg) élague les dossiers exclus et saute les fichiers exclus, en plus du globalIGNORED_DIRSinchangé. - Lecture seule :
_ensure_writable(root, vault_name)dansbackend/services/mutations.pyrefuse d'abord sur la déclaration (DIR_N_READONLY), avant le garde filesystem existant — toutes les mutations du service (créer, éditer, renommer, déplacer, supprimer, upload, xlsx/csv) passent par ce point. - API / UI :
VaultInfo.readonly(backend/schemas.py) rempli parlist_accessible_vaults; côté frontend,vaultIsReadonly(nom)dansfrontend/js/sidebar.jsalimenteContextMenuManager,attachTreeItemActionButtonetattachTreeItemLongPresspour le vault et ses dossiers / fichiers (aucun autre fichier JS touché).
Tests
tests/test_spark_vault_dir.py : parsing des trois variables, helper
chemin_exclu (noms et motifs), navigation filtrée, lectures exclues en
404 (vue fichier, raw, téléchargement), fichier non exclu lisible,
indexation filtrée, mutation refusée en 403 sur vault readonly et
/api/vaults exposant readonly=true.