depot hors site : sortir du site ce que le site garde pour tout le monde
Some checks are pending
verifier / verifier (push) Waiting to run
Some checks are pending
verifier / verifier (push) Waiting to run
Le depot heberge la racine de l AC, la forge du genome, et l etat de CHAQUE locataire — 109 Mo sur une seule machine, dans un seul batiment. C est le probleme du filet range dans la flotte qu il protege, un etage plus haut. On emporte AUSSI les depots des locataires : si le site brule, ils perdent leurs sauvegardes avec lui, et eux ne peuvent rien y faire. Ils ont depose chez l hebergeur, c est a l hebergeur de tenir cette promesse. La copie est OPAQUE — chiffree cote client, illisible par qui la porte. C est ce qui permet de la deposer chez un pair sans lui demander autre chose que de la disponibilite. L empreinte est prise A LA SOURCE avant la copie, puis recalculee sur la copie et comparee une a une. Sans ca on rentre chez soi avec un repertoire. Un pipe sans pipefail masque l echec de tout ce qui n est pas le dernier maillon : ici sed, qui reussit toujours. Une empreinte vide des deux cotes aurait passe la comparaison. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
This commit is contained in:
parent
dcbb57db69
commit
9a823a5ea2
2 changed files with 144 additions and 0 deletions
12
Makefile
12
Makefile
|
|
@ -575,6 +575,18 @@ cles-exporter: ## Sort les cles du poste, chiffrees et relues — VERS=<repertoi
|
|||
python3 scripts/exporter_cles.py --vers "$(VERS)"
|
||||
|
||||
.PHONY: cles-recenser cles-exporter
|
||||
depot-hors-site: ## Copie le depot de sauvegarde du site HORS du site — VERS=<repertoire>
|
||||
@# Le depot heberge la racine de l'AC, la forge du genome, et l'etat de CHAQUE
|
||||
@# locataire — sur une seule machine, dans un seul batiment. La copie est opaque
|
||||
@# (chiffree cote client) : elle se depose chez un pair sans rien lui demander
|
||||
@# d'autre que de la disponibilite.
|
||||
@if [ -z "$(VERS)" ]; then \
|
||||
printf 'Refus: relancer avec VERS=<repertoire de destination>.\n'; \
|
||||
printf 'Ex. make depot-hors-site VERS=/media/danallaire/setops-coffre\n'; exit 2; fi
|
||||
ansible-playbook -i scripts/site_inventaire.py \
|
||||
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=<repertoire>
|
||||
@# POUR UNE CLE EXISTANTE. L'archive n'est pas refaite : ni phrase de passe redemandee,
|
||||
@# ni risque d'ecraser ce qui est deja verifie.
|
||||
|
|
|
|||
132
playbooks/maintenance/depot-hors-site.yml
Normal file
132
playbooks/maintenance/depot-hors-site.yml
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
---
|
||||
# SORTIR LES SAUVEGARDES DU SITE, DU SITE.
|
||||
#
|
||||
# Le depot du site heberge trois choses irremplacables : la racine de son autorite de
|
||||
# certification, la forge du genome, et l'etat de CHAQUE locataire. Tout cela vit sur une
|
||||
# seule machine, dans un seul batiment. C'est le probleme du filet range dans la flotte
|
||||
# qu'il protege — celui qu'on a mis deux jours a fermer pour Chezlepro — un etage plus haut.
|
||||
#
|
||||
# POURQUOI ON EMPORTE AUSSI LES DEPOTS DES LOCATAIRES. Si le site brule, les locataires
|
||||
# perdent leurs sauvegardes avec lui, et EUX NE PEUVENT RIEN Y FAIRE : ils ont depose chez
|
||||
# l'hebergeur, c'est a l'hebergeur de tenir cette promesse. 109 Mo au total — la question
|
||||
# du volume ne se pose pas.
|
||||
#
|
||||
# CE QUE LE PORTEUR DE LA COPIE PEUT EN FAIRE : rien. Les depots sont chiffres par restic
|
||||
# COTE CLIENT, avec des mots de passe qui vivent dans les voutes de chacun. Cette copie
|
||||
# est un bloc opaque — c'est ce qui permet de la deposer chez un pair sans lui demander
|
||||
# autre chose que de la disponibilite.
|
||||
#
|
||||
# ansible-playbook -i scripts/site_inventaire.py \
|
||||
# playbooks/maintenance/depot-hors-site.yml -e vers=/media/…/setops-coffre
|
||||
- name: Copier le depot du site hors du site
|
||||
hosts: serveur_backup_site
|
||||
gather_facts: false
|
||||
become: true
|
||||
|
||||
vars:
|
||||
racine: "{{ serveur_backup_site_parent | default('/srv/restic') }}"
|
||||
|
||||
pre_tasks:
|
||||
- name: Exiger une destination
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- vers is defined
|
||||
- vers | length > 0
|
||||
fail_msg: >-
|
||||
`-e vers=<repertoire>` requis. Viser un support amovible ou une machine tierce.
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
|
||||
# UNE COPIE DANS L'INFRASTRUCTURE NE PROTEGE DE RIEN — elle boucle. Meme raisonnement
|
||||
# que pour les cles : un coffre range dans ce qu'il protege n'est pas un coffre.
|
||||
- name: Refuser une destination interne
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- not (vers is search('/srv/restic'))
|
||||
- not (vers is search('Espace Chezlepro'))
|
||||
fail_msg: >-
|
||||
{{ vers }} est DANS l'infrastructure. Une copie qui partage le sort de
|
||||
l'original ne protege de rien.
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
|
||||
- name: La destination existe-t-elle ?
|
||||
ansible.builtin.stat:
|
||||
path: "{{ vers }}"
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
register: dest_etat
|
||||
|
||||
- name: Exiger une destination reelle
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- dest_etat.stat.exists
|
||||
- dest_etat.stat.isdir
|
||||
fail_msg: "{{ vers }} n'existe pas ou n'est pas un repertoire. Support monte ?"
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
|
||||
tasks:
|
||||
# L'EMPREINTE EST PRISE A LA SOURCE, AVANT LA COPIE. La comparer apres coup a une
|
||||
# empreinte calculee sur la copie est la seule facon de savoir qu'on a emporte ce
|
||||
# qu'on croit avoir emporte. Sans ca, on rentre chez soi avec un repertoire.
|
||||
- name: Empreinte de ce qui est a la source
|
||||
ansible.builtin.shell:
|
||||
executable: /bin/bash
|
||||
cmd: >-
|
||||
set -o pipefail;
|
||||
find {{ racine }} -type f -print0 | sort -z |
|
||||
xargs -0 sha256sum | sed 's| {{ racine }}/| |'
|
||||
register: empreinte_source
|
||||
changed_when: false
|
||||
|
||||
- name: Combien, et quelle taille
|
||||
ansible.builtin.shell:
|
||||
executable: /bin/bash
|
||||
cmd: "set -o pipefail; du -sb {{ racine }} | cut -f1"
|
||||
register: taille_source
|
||||
changed_when: false
|
||||
|
||||
- name: Copier vers la destination
|
||||
ansible.posix.synchronize:
|
||||
src: "{{ racine }}/"
|
||||
dest: "{{ vers }}/depot-du-site/"
|
||||
mode: pull
|
||||
archive: true
|
||||
delete: true
|
||||
become: false
|
||||
|
||||
- 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 |
|
||||
xargs -0 sha256sum | sed 's| {{ vers }}/depot-du-site/| |'
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
register: empreinte_copie
|
||||
changed_when: false
|
||||
|
||||
- name: Exiger une copie fidele
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- empreinte_source.stdout == empreinte_copie.stdout
|
||||
fail_msg: >-
|
||||
LA COPIE DIFFERE DE LA SOURCE.
|
||||
Source : {{ empreinte_source.stdout_lines | length }} fichier(s).
|
||||
Copie : {{ empreinte_copie.stdout_lines | length }} fichier(s).
|
||||
Ne pas s'en servir : une copie qu'on croit fidele et qui ne l'est pas est pire
|
||||
qu'aucune copie.
|
||||
success_msg: >-
|
||||
COPIE FIDELE : {{ empreinte_source.stdout_lines | length }} fichier(s),
|
||||
{{ (taille_source.stdout | int / 1048576) | round(1) }} Mo, empreintes
|
||||
identiques une a une.
|
||||
|
||||
- name: Ce qu'il reste a faire, et qui n'est pas facultatif
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "La copie est OPAQUE : chiffree cote client, illisible par qui la porte."
|
||||
- "Elle ne vaut que si elle vit AILLEURS que le site — un tiroir a cote du"
|
||||
- "serveur ne protege que du disque, pas de l'incendie ni du vol."
|
||||
- "A refaire quand l'etat change. `restic` ne recopie que les differences."
|
||||
Loading…
Reference in a new issue