From 00cee67f023bcad75747f4aa62e42a9c916c3cf0 Mon Sep 17 00:00:00 2001 From: Daniel Allaire Date: Sat, 5 Sep 2026 16:33:26 -0400 Subject: [PATCH] depot hors site : trois pieges payes en une manoeuvre MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. ansible -e cle=valeur DECOUPE SUR LES BLANCS — c est ainsi qu on passe plusieurs variables. Un chemin avec une espace y perd tout ce qui suit le premier blanc, et l erreur parle d un repertoire introuvable au nom tronque. Passage en JSON. Le depot avait deja appris ca pour le clonage de VM ; la lecon ne s etait pas propagee. Quatrieme fois. 2. /srv/restic est en 0711 — traversable, NON listable, pour qu un locataire n apprenne pas qui d autre depose ici. La consequence tombe sur rsync : opendir Permission denied, un message qui accuse un droit sans dire lequel. --rsync-path=sudo rsync fait lire la SOURCE en root. 3. rsync_opts ne protege pas ses elements : le shell coupait --rsync-path=sudo rsync en deux. Guillemets internes. Resultat mesure : COPIE FIDELE, 233 fichiers, 95,7 Mo, empreintes identiques une a une — comparees entre la source et la copie, pas supposees. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on --- Makefile | 8 +++++++- playbooks/maintenance/depot-hors-site.yml | 24 ++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index c5c5485..fdcae8d 100644 --- a/Makefile +++ b/Makefile @@ -583,8 +583,14 @@ depot-hors-site: ## Copie le depot de sauvegarde du site HORS du site — VERS=< @if [ -z "$(VERS)" ]; then \ printf 'Refus: relancer avec VERS=.\n'; \ printf 'Ex. make depot-hors-site VERS=/media/danallaire/setops-coffre\n'; exit 2; fi + @# EN JSON, PAS EN `-e cle=valeur` (2026-09-05). La forme `cle=valeur` DECOUPE SUR + @# LES BLANCS — c'est ainsi qu'on passe plusieurs variables d'un coup. Un chemin + @# contenant une espace y perd donc tout ce qui suit le premier blanc, et l'erreur + @# parle d'un repertoire introuvable au nom tronque : « /media/danallaire/Cle ». + @# Le depot avait deja appris ca pour le clonage de VM ; la lecon ne s'etait pas + @# propagee ici. Quatrieme fois que ce piege est paye. ansible-playbook -i scripts/site_inventaire.py \ - playbooks/maintenance/depot-hors-site.yml -e vers="$(VERS)" + playbooks/maintenance/depot-hors-site.yml -e '{"vers": "$(VERS)"}' .PHONY: depot-hors-site cles-compagnons: ## Depose le script de restauration sur une cle DEJA faite — VERS= diff --git a/playbooks/maintenance/depot-hors-site.yml b/playbooks/maintenance/depot-hors-site.yml index b4c917e..7343c3f 100644 --- a/playbooks/maintenance/depot-hors-site.yml +++ b/playbooks/maintenance/depot-hors-site.yml @@ -87,6 +87,19 @@ register: taille_source changed_when: false + # RSYNC LIT LA SOURCE EN ROOT, ET C'EST LA GARDE QUI L'EXIGE. + # + # `/srv/restic` est en 0711 : traversable, NON LISTABLE. C'est voulu — un locataire + # atteint son propre depot sans pouvoir apprendre qui d'autre depose ici. La liste + # des voisins est deja une information. + # + # La consequence tombe ici : le compte `ansible` ne peut pas ENUMERER la racine, et + # rsync echoue sur `opendir "/srv/restic/." failed: Permission denied`. Le message + # accuse un droit sans dire lequel, et on cherche du cote du compte alors que c'est + # la politique du repertoire. + # + # `--rsync-path=sudo rsync` fait lire la SOURCE en root, sans que la copie locale + # ait besoin de privileges. `become: false` reste donc juste pour le cote poste. - name: Copier vers la destination ansible.posix.synchronize: src: "{{ racine }}/" @@ -94,14 +107,23 @@ mode: pull archive: true delete: true + rsync_opts: + # Les guillemets INTERNES sont necessaires : `rsync_opts` ne protege pas ses + # elements, et le shell local coupait `--rsync-path=sudo rsync` en deux. + - "--rsync-path='sudo rsync'" become: false + # LE CHEMIN EST ENTRE GUILLEMETS, ET CE N'EST PAS DU ZELE. Ce depot vit sous + # « Espace Chezlepro » et les supports de l'exploitant portent des noms avec des + # blancs. Un chemin nu atteignant un shell se coupe au premier espace, et l'erreur + # parle d'un fichier introuvable au nom tronque — ce qui n'oriente vers rien. + # Quatrieme fois que ce depot paie ce piege. - name: Empreinte de ce qui est arrive ansible.builtin.shell: executable: /bin/bash cmd: >- set -o pipefail; - find {{ vers }}/depot-du-site -type f -print0 | sort -z | + find "{{ vers }}/depot-du-site" -type f -print0 | sort -z | xargs -0 sha256sum | sed 's| {{ vers }}/depot-du-site/| |' delegate_to: localhost become: false